Lab 1: Faust and Basic MIDI Control

Adding MIDI Support to a Faust Program

The goal of this first step is to add MIDI support to a simple synthesizer written in Faust. For this to work, you must use an up-to-date version of Google Chrome. Chrome is the only browser providing MIDI support so using a different one (e.g., Firefox) will not work. There are 3 MIDI interfaces in the MaxLab and one in studio E and D that you can use for this exercise. They all work with USB and some of them need to be powered with an external power supply (that you should find with them).

Say we have this simple synthesizer (feel free to copy this code and paste in the Faust online editor):

freq = hslider("freq",300,50,2000,0.01) : si.smoo;
gain = hslider("gain",0.8,0,1,0.01) : si.smoo;
process = os.sawtooth(freq)*gain;

Note the use of si.smoo on all its parameters to prevent clicking.

We would like to control freq and gain using a MIDI interface. To assign a specific MIDI controller (i.e., a knob, a slider, etc.) to a Faust parameter, a metadata must be used. MIDI controllers on a MIDI interface are numbered from 0 to 127. There’s a white tape on the interfaces in the MaxLab indicating which number is assigned to which controller. The interfaces in studio D and E are a bit fancier, and the ctrl number should be displayed on their screen when interacting with the controller.

Say we’d like to assign a knob whose number is 11 to freq and another knob with number 55 to gain, all we have to write is the following:

freq = hslider("freq[midi: ctrl 11]",300,50,2000,0.01) : si.smoo;
gain = hslider("gain[midi: ctrl 55]",0.8,0,1,0.01) : si.smoo;
process = os.sawtooth(freq)*gain;

Now try to assign knobs on of the interfaces available at CCRMA to freq and gain to see how this works. Note that the minimum value of the Faust parameter (i.e., 50 for freq) will be assigned to the lowest position of the knob and that its maximum value (i.e., 2000 for freq) to the highest position of the knob.

For further information on MIDI support in Faust, please refer to the corresponding section in the Faust documentation.

Exploring the Faust Libraries

Customizing a Function From the Libraries

The Faust distribution comes with a series of libraries implementing a wide range of synthesizers, audio effects, etc. The source code of the Faust libraries can be found in the Faust Libraries repository on GitHub: Also, the documentation of the Faust libraries is available on the Faust website:

Each .lib file contains the source code of a specific library.

All standard Faust libraries are accessible through a series of prefixes declared in stdfaust.lib. For example, to call the sine oscillator function (osc) declared in oscillators.lib, one might write:

process = osc(440);

and alternatively:

process = os.osc(440);

Some functions of the Faust libraries host their own user interface. Most of these functions are declared in demos.lib and physmodels.lib. For example, a ready-to-use clarinet physical model can be found physmodels.lib and called with just 2 lines of code:

process = pm.violin_ui;

Exploring the source code of physmodels.lib, the declaration of the violin_ui function can be easily found:

As an exercise, try to write your own version of violin_ui (i.e., my_violin_ui) where some of the parameters of the model are controlled using one of the MIDI interfaces available at CCRMA (hint: don’t forget to add pm when you call violinModel since you’ll be outside of physmodels.lib).


Adding Vibrato

Vibrato is a crucial esthetic feature when performing with some musical instruments in western music. Moreover, in the case of sound synthesis it can help make the harmonic content of a sound more “coherent” (effect of source segregation).

Vibrato can be implemented in Faust simply by modulating the pitch of the generated sound with a sine wave oscillator (e.g., pitch + osc(vibratoFreq)*vibratoAmp).

Try to modify the previous example by adding 2 user interface elements to control the frequency and the amplitude of the vibrato. The frequency shouldn’t exceed 10Hz and a good default value is 6Hz. Also, map these 2 new parameters to MIDI controllers on the interface.

Hint: don’t forget that a sine function has both positive and negative values.


Adding an Audio Effect

compressors.lib, misceffects.lib, phaflangers.lib, reverbs.lib, and vaeffects.lib contain a wide range of audio effects. Some of them have a demo version (with a built-in UI) that can be found in demos.lib. This table gives of an overview of the most standard audio effects available in the Faust libraries.

We’d like to “improve” our instrument from the previous step (violin with vibrato) with a phasor. A stereo phaser is available in demos.lib: Copy its code in your Faust program and rename it as we did for violin_ui (i.e., my_phaser2_demo). Connect the output of my_violin_ui to my_phaser2_demo. Since my_violin_ui has one output and my_phaser2_demo has 2 inputs (stereo), we must use the split operator:

process = my_violin_ui <: my_phaser2_demo;

Try to assign some of the parameters of the phaser to MIDI controllers on the interface that you’re using. Keep in mind that a Faust parameter can contain multiple metadata (i.e., speed = ctl_group(hslider("[1] Speed [unit:Hz] [style:knob][midi: ctrl 26]",0.5,0,10,0.001)))


Assignment (Due on Jan. 16, 2019)


  • Luigi Sambuy
  • Deepak Chandran
  • Adison Chang
  • Justin Cheung
  • Jason Choi
  • Jatin Chowdhury
  • Marina Barbara Cottrell
  • Cole DePasquale
  • Raul Gallo Dagir
  • Kim Kawczinski
  • Elisa Lupin-Jimenez
  • Lee Marom
  • Doug Turnbull McCausland
  • Matthew Molina
  • Camille Noufi
  • Salvador Perez
  • Austen Poteet
  • Andrea Stein
  • Michael Svolos
  • Arjun Tambe
  • Ye Akira Wang
  • Shenli Yuan
  • Austin Zambito-Valente