In this example we will see how to write a simple organ base on a sine oscillator described here. The polyphony and the MIDI control will be handled by the architecture file. We will only have to describe a single voice and adopt special conventions on widget’s names for the architecture file to know how to map incoming MIDI messages.

Organ Voice

Let start with the organ timbre, here obtained by combining three sine oscillators. The fundamental frequency will be controlled by the MIDI key:

timbre(freq) = osc(freq) + 0.5*osc(2.0*freq) + 0.25*osc(3.0*freq);

We need also an envelop signal that starts when a key is pressed. This envelop will be controlled by two signals : a gain corresponding to the MIDI velocity and an gate at 1 while a key is pressed. Smooth is a simple filter used to smooth the envelop signal:

envelop(gate, gain) = gate * gain : smooth(0.9995)
                    with { smooth(c) = * (1-c) : + ~ * (c) ; } ;

By combining timbre and envelop we have our organ voice :

voice(gate, gain, freq) = envelop(gate, gain) * timbre(freq);

Midi interface

By convention Faust architecture files with polyphonic MIDI capabilities expect to find a freq, a gain and a gate user interface parameter:

midigate	= button ("gate");                             	// MIDI keyon-keyoff
midifreq	= hslider("freq[unit:Hz]", 440, 20, 20000, 1); 	// MIDI keyon key
midigain	= hslider("gain", 0.5, 0, 10, 0.01);	       	// MIDI keyon velocity

Putting all together

All it remains is to connect our organ voice to the MIDI control and add a general volume:

process = voice(midigate, midigain, midifreq) * hslider("volume", 0, 0, 1, 0.01);

You can try the code on the online compiler by dragging this url or pasting the following lines

// Simple Organ
import("stdfaust.lib");

midigate	= button ("gate");                             	// MIDI keyon-keyoff
midifreq	= hslider("freq[unit:Hz]", 440, 20, 20000, 1); 	// MIDI keyon key
midigain	= hslider("gain", 0.5, 0, 10, 0.01);	       	// MIDI keyon velocity

process = voice(midigate, midigain, midifreq) * hslider("volume", 0, 0, 1, 0.01);

// Implementation

phasor(f)   = f/ma.SR : (+,1.0:fmod) ~ _ ;
osc(f)      = phasor(f) * 6.28318530718 : sin;

timbre(freq)= osc(freq) + 0.5*osc(2.0*freq) + 0.25*osc(3.0*freq);

envelop(gate, gain) = gate * gain : smooth(0.9995)
                with { smooth(c) = * (1-c) : + ~ * (c) ; } ;

voice(gate, gain, freq) = envelop(gate, gain) * timbre(freq);