I recently started toying around with Faust. Faust is a functional programming language specifically designed for audio manipulation. One of the many strengths of Faust is it’s compiler backends that allows the user to compile Faust code to almost any end target - including microcontrollers, JUCE/VST plugin projects, Pure Data, Max and SuperCollider - with the same Faust code. It even works in the browser.

Another fantastic strength is the library of building blocks it comes with - these are extremely high quality and reflect a lot of the new developments in DSP technology and research in recent years. For you as a user this means you have a really solid toolbox for creating sound patches.

For SuperCollider users this means that Faust is probably the quickest way to create highly effective custom plugins / UGens for SuperCollider.

faust2supercollider: Creating a SuperCollider plugin using Faust

If you download and install faust on your computer(most Linux distributions probably have it in their package managers), you get a ton of compilation tools for free. These are all prefixed faust2<target>.

For SuperCollider there is a specific tool called faust2supercollider, this takes a Faust file as an input and compiles it as a SuperCollider UGen. The UGen consists of two files: a compiled object and a .sc-file containing the sclang interface for it.

Let’s try a simple example. Create a file called Wah4.dsp (.dsp is the suffix for Faust-files) and put this code in it:

import("stdfaust.lib");

// Cutoff frequency argument
freq=vslider("cutoff",500,20.0,20000,1);

// Perform process on input sound
process= _: ve.wah4(freq) : _;

This imports the standard library for faust and then defines a parameter “cutoff” that we will use to control the cutoff frequency. Note that in Faust this is represented as a slider with a default value of 500 (hz), range from 20.0 to 20000.0 in steps of 1. When converting to a SuperCollider UGen, this will be interpreted as an argument for the UGen and show up as cutoff.

Now save the file and compile it to SuperCollider using the command line tool faust2supercollider:

faust2supercollider Wah4.dsp -noprefix

The -noprefix-flag here removes the standard Faust-prefix and just uses the base file name Wah4 as the name of our UGen.

On some systems (including MacOS) you may need to download the SuperCollider source code and put the path to it into an environment variable when running the faust compilation command, like so (thanks Johannes Burström for pointing out):

SUPERCOLLIDER_HEADERS=/path/to/supercollider_source/include faust2supercollider Wah4.dsp -noprefix

Test the plugin

If succesful, this process outputs a shared object and a SuperCollider class file. Copy these to your Extensions folder (this can be found by executing Platform.userExtensionDir in SuperCollider) and recompile the SuperCollider class library.

Now, test out your brand spanking new Wahwah-effect in a patch with a noise UGen modulating the cutoff frequency:

 
(
Ndef(\wahhhh, { |freq=150, amp=0.25| 
	var sig = Saw.ar(freq);
	var freq = LFNoise2.kr(10).exprange(25,2500);
	Wah4.ar(sig, freq) * amp;
}).play
)

That’s it. Now, all there’s left is to actually learn the faust programming language syntax, hehe.

The generated SuperCollider class

This is what the actual SuperCollider class interface for our new Wah effect looks like after being generated by faust2supercollider:

Wah4 : UGen {
  *ar { | in1, cutoff(500.0) |
      ^this.multiNew('audio', in1, cutoff)
  }

  *kr { | in1, cutoff(500.0) |
      ^this.multiNew('control', in1, cutoff)
  } 

  checkInputs {
    if (rate == 'audio', {
      1.do({|i|
        if (inputs.at(i).rate != 'audio', {
          ^(" input at index " + i + "(" + inputs.at(i) + 
            ") is not audio rate");
        });
      });
    });
    ^this.checkValidInputs
  }

  name { ^"Wah4" }


  info { ^"Generated with Faust" }
}

Generate only the C++ files for the SuperCollider plugin

If you want to see the C++ code that is generated from your faust-file you have several options. If you compile using the faust2supercollider tool, you can add -ks (short for keep source) as a flag to the command, or you may run the following command to only create the C++ source:

faust -a supercollider.cpp Wah4.dsp -o Wah4.cpp

This will result in a C++ file called Wah4.cpp.

This can be useful for several things - for me personally this is a nice way to see what happens behind the scenes when your faust-code is interpreted and compiled to SuperCollider friendly C++ classes (scroll down to the stuff with Faust_next to see the actual class used by SuperCollider).