Quick Start
The goal of this section is to teach you how to use the basic elements of the Faust programming language in approximately two hours! While DSP algorithms can be easily written from scratch in Faust, we'll just show you here how to use existing elements implemented in the Faust libraries, connect them to each other, and implement basic user interfaces (UI) to control them.
One of the strength of Faust lies in its libraries that implement hundreds of functions. So you should be able to go a long way after reading this section, simply by using what's already out here.
This tutorial was written assuming that the reader is already familiar with basic concepts of computer music and programming.
More generally, at the end of this section:
- your Faust development environment should be up and running,
- you should know enough to write basic Faust programs,
- you should be able to use them on different platforms.
This tutorial was designed to be carried out in the Faust Online IDE. If you wish to do it locally, you'll have to install Faust on your system but this step is absolutely not required,
Making Sound
Write the following code in the Faust Online IDE:
and then click on the "run" button on the top left corner. Alternatively, you can also click on the "Try it Yourself" button of the window above if you're reading the online version of this documentation. You should now hear white noise, of course... ;)
stdfaust.lib
gives access to all the Faust libraries from a single point through a series of environments. For instance, we're using here the no
environment which stands for noise.lib
and the noise
function (which is the standard white noise generator of Faust). The Faust Libraries Documentation provides more details about this system.
The most fundamental element of any Faust code is the process
line, which gives access to the audio inputs and outputs of the target. This system is completely dynamic and since no.noise
has only one output and no input, the corresponding program will have a single output.
Let's statically change the gain of the output of no.noise
simply by multiplying it by a number between 0 and 1:
process = no.noise*0.5;
Thus, standard mathematical operations can be used in Faust just like in any other language.
We'll now connect the noise generator to a resonant lowpass filter (fi.resonlp
) by using the Faust sequential composition operator: :
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
process = no.noise : fi.resonlp(ctFreq,q,gain);
fi.resonlp
has four arguments (in order): cut-off frequency, q, gain and its input. Note that you can have a quick look of what the arguments of a function are simply by hovering it in the online IDE. Here, we're setting the first three arguments with fixed variables. Variables don't have a type in Faust and everything is considered as a signal. The Faust compiler takes care of making the right optimizations by choosing which variable is ran at audio rate, what their types are, etc. Thus, ctFreq
, q
and gain
could well be controlled by oscillators (i.e., signals running at audio rate) here.
Since the input of the filter is not specified as an argument here (but it could, of course), it automatically becomes an "implicit" input/argument of fi.resonlp
. The :
sequential composition operator can be used to connect two elements that have the same number of outputs and inputs. Since no.noise
has one output and fi.resonlp(ctFreq,q,gain)
has one implicit input, we can connect them together. This is essentially the same as writing something like:
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
process = fi.resonlp(ctFreq,q,gain,no.noise);
While this would work, it's kind of ugly and not very "Faustian", so we don't do it... ;)
At this point, you should be able to use and plug various elements of the Faust libraries together. The Faust libraries implement hundreds of functions and some of them have a very specialized use. Fortunately, the Faust libraries documentation contains a section on Standard Faust Libraries listing all the high level "standard" Faust functions organized by types. We recommend you to have a look at it now. As you do this, be aware that implicit signals in Faust can be explicitly represented with the _
character. Thus, when you see something like this in the libraries documentation:
_ : aFunction(a,b) : _
it means that this function has one implicit input, one implicit output and two parameters (a
and b
). On the other hand:
anotherFunction(a,b,c) : _,_
is a function that has three parameters, no implicit input and two outputs.
Just for "fun," try to rewrite the previous example running in the Faust online editor so that the process
line looks like this:
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
process = no.noise : _ : fi.resonlp(ctFreq,q,gain) : _;
Of course, this should not affect the result.
You probably noticed that we used the ,
Faust composition operator to express two signals in parallel. We can easily turn our filtered noise example into a stereo object using it:
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
process = no.noise : _ <: fi.resonlp(ctFreq,q,gain),fi.resonlp(ctFreq,q,gain);
or we could even write this in a cleaner way:
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
filter = fi.resonlp(ctFreq,q,gain);
process = no.noise <: filter,filter;
Note that this example allows us to have 2 separate filters for each channel. Since both filters currently have the same parameters, another way of writing this could be: process = no.noise : filter <: _,_;
.
You could think of the first form as a same noise signal splitted and then filtered on left and right channels, and the second form as the filtered noise then splitted on left and right channels. But the compiler understand that the same filtered noise will be produced on left and right channels in both cases. So the filtered noise signal can be computed only once and used on left and right channels. For the two progams, the compiler will actually generate the exact same optimized code ! This is a very powerful property of its semantically driven compilation model.
Since filter,filter
is considered here as a full expression, we cannot use the :
operator to connect no.noise
to the two filters in parallel because filter,filter
has two inputs (_,_ : filter,filter : _,_
) and no.noise
only has one output.
The <:
split composition operator used here takes n
signals and splits them into m
signals. The only rule is that m
has to be a multiple of n
.
The merge :>
composition operator can be used exactly the same way:
import("stdfaust.lib");
process = no.noise <: filter,filter :> _;
Here we split the signal of no.noise
into two signals that are connected to two filters in parallel. Finally, we merge the outputs of the filters into one signal. Note, that the previous expression could have been written as such too:
import("stdfaust.lib");
process = no.noise <: filter+filter;
Keep in mind that splitting a signal doesn't mean that its energy get spread in each copy, for example, in the expression:
the two _
both contain 1...
All right, it's now time to add a basic user interface to our Faust program to make things a bit more interactive.
Building a Simple User Interface
In this section, we'll add a simple user interface to the code that we wrote in the previous section:
import("stdfaust.lib");
ctFreq = 500;
q = 5;
gain = 1;
process = no.noise : fi.resonlp(ctFreq,q,gain);
Faust allows us to declare basic user interface (UI) elements to control the parameters of a Faust object. Since Faust can be used to make a wide range of elements ranging from standalone applications to audio plug-ins or API, the role of UI declarations differs a little in function of the target. For example, in the Faust Online Editor, a UI is a window with various kind of controllers (sliders, buttons, etc.). On the other hand, if you're using Faust to generate an audio engine using faust2api
, then UI elements declared in your Faust code will be the parameters visible to "the rest of the world" and controllable through the API.
An exhaustive list of the standard Faust UI elements is given in the corresponding section. Be aware that they not all supported by all the Faust targets. For example, you wont be able to declare vertical sliders if you're using the Faust Playground, etc.
In the current case, we'd like to control the ctFreq
, q
and gain
parameters of the previous program with horizontal sliders. To do this, we can write something like:
import("stdfaust.lib");
ctFreq = hslider("cutoffFrequency",500,50,10000,0.01);
q = hslider("q",5,1,30,0.1);
gain = hslider("gain",1,0,1,0.01);
process = no.noise : fi.resonlp(ctFreq,q,gain);
The first argument of hslider
is the name of the parameter as it will be displayed in the interface or used in the API (it can be different from the name of the variable associated with the UI element), the next one is the default value, then the min and max values and finally the step. To summarize: hslider("paramName",default,min,max,step)
.
Let's now add a "gate" button
to start and stop the sound (where gate
is just the name of the button):
import("stdfaust.lib");
ctFreq = hslider("[0]cutoffFrequency",500,50,10000,0.01);
q = hslider("[1]q",5,1,30,0.1);
gain = hslider("[2]gain",1,0,1,0.01);
t = button("[3]gate");
process = no.noise : fi.resonlp(ctFreq,q,gain)*t;
Note that we were able to order parameters in the interface by numbering them in the parameter name field using squared brackets.
Faust user interface elements run at control rate. Thus, you might have noticed that clicks are produced when moving sliders quickly. This problem can be easily solved by "smoothing" down the output of the sliders using the si.smoo
function:
import("stdfaust.lib");
ctFreq = hslider("[0]cutoffFrequency",500,50,10000,0.01) : si.smoo;
q = hslider("[1]q",5,1,30,0.1) : si.smoo;
gain = hslider("[2]gain",1,0,1,0.01) : si.smoo;
t = button("[3]gate") : si.smoo;
process = no.noise : fi.resonlp(ctFreq,q,gain)*t;
Note that we're also using si.smoo
on the output of the gate
button to apply a exponential envelope on its signal.
This is a very broad introduction to making user interface elements in Faust. You can do much more like creating groups, using knobs, different types of menus, etc. but at least you should be able to make Faust programs at this point that are controllable and sound good (or not ;) ).
Final Polishing
Some Faust functions already contain a built-in UI and are ready-to-be-used. These functions are all placed in demo.lib and are accessible through the dm.
environment.
As an example, let's add a reverb to our previous code by calling dm.zita_light
(high quality feedback delay network based reverb). Since this function has two implicit inputs, we also need to split the output of the filter (otherwise you will get an error because Faust wont know how to connect things):
import("stdfaust.lib");
ctFreq = hslider("[0]cutoffFrequency",500,50,10000,0.01) : si.smoo;
q = hslider("[1]q",5,1,30,0.1) : si.smoo;
gain = hslider("[2]gain",1,0,1,0.01) : si.smoo;
t = button("[3]gate") : si.smoo;
process = no.noise : fi.resonlp(ctFreq,q,gain)*t <: dm.zita_light;
Hopefully, you should see many more UI elements in your interface.
That's it folks! At this point you should be able to use Faust standard functions, connect them together and build a simple UI at the top of them.
Some Project Ideas
In this section, we present a couple of project ideas that you could try to implement using Faust standard functions. Also, feel free to check the /examples
folder of the Faust repository.
Additive Synthesizer
Make an additive synthesizer using os.osc
(sine wave oscillator):
import("stdfaust.lib");
// freqs and gains definitions go here
process =
os.osc(freq0)*gain0,
os.osc(freq2)*gain2
:> _ // merging signals here
<: dm.zita_light; // and then splitting them for stereo in
FM Synthesizer
Make a frequency modulation (FM) synthesizer using os.osc
(sine wave oscillator):
import("stdfaust.lib");
// carrierFreq, modulatorFreq and index definitions go here
process =
os.osc(carrierFreq+os.osc(modulatorFreq)*index)
<: dm.zita_light; // splitting signals for stereo in
Guitar Effect Chain
Make a guitar effect chain:
import("stdfaust.lib");
process =
dm.cubicnl_demo : // distortion
dm.wah4_demo <: // wah pedal
dm.phaser2_demo : // stereo phaser
dm.compressor_demo : // stereo compressor
dm.zita_light; // stereo reverb
Since we're only using functions from demo.lib
here, there's no need to define any UI since it is built-in in the functions that we're calling. Note that the mono output of dm.wah4_demo
is split to fit the stereo input of dm.phaser2_demo
. The last three effects have the same number of inputs and outputs (2x2) so no need to split or merge them.
String Physical Model Based On a Comb Filter
Make a string physical model based on a feedback comb filter:
import("stdfaust.lib");
// freq, res and gate definitions go here
string(frequency,resonance,trigger) = trigger : ba.impulsify : fi.fb_fcomb(1024,del,1,resonance)
with {
del = ma.SR/frequency;
};
process = string(freq,res,gate);
Sampling rate is defined in maths.lib
as SR
. We're using it here to compute the length of the delay of the comb filter. with{}
is a Faust primitive to attach local variables to a function. So in the current case, del
is a local variable of string
.


$$TITLE$$
|
Billing Information
$$ADDRESSEDITOR$$ |
|
|
Other Order Information
$$CUSTOMFIELDS$$
|
|
|
Payment Information
$$INVOICEREFNRTEXT$$
$$INVOICENRTEXTBOX$$
Payment Amount:
$
$$AMOUNTTEXTBOX$$
Payment Method:
$$PAYMENTMETHODS$$
$$CREDITCARD$$
$$ECHECK$$
$$CUSTOMPAYMENTMETHODS$$
|
|
|
|
|
| $$CONTINUEBUTTON$$ |


| < Day Day Up > |
10.5. Setting Emacs VariablesNow we will get into ways to affect Emacs' behavior—not just its user interface. The easiest way to do so is by setting variables that control various things. We already saw examples of this like auto-save-interval in Chapter 2. To set the value of a variable, use the setq function in your .emacs, as in: (setq auto-save-interval 800) Although auto-save-interval takes an integer (number) value, many Emacs variables take true or false values, called Boolean in computer parlance. In Emacs Lisp, t is the true value, and nil is the false value, although in most cases, anything other than nil is taken to mean true. Emacs variables can take other types of values, and here is how to specify them:
A list of useful Emacs variables, grouped by category, appears in Appendix A, with descriptions and default values. Emacs has more than 2,500 variables—many more than are covered in Appendix A. If there is something about Emacs that you want to customize, a variable probably controls the feature (especially if what you want to change involves a number or a true-or-false condition). To find out whether any variables relate to what you want to do, you can use the apropos-variable command described in Chapter 14 to look for variables and their descriptions. Several Emacs variables can have different values for each buffer (local values, in Emacs parlance) as well as a default value. Such variables assume their default values in buffers where the local values are not specified. A common example is starting a new text document. The local value for the left-margin variable has not been set, so Emacs uses the default value for left-margin. You can change the local value in this buffer if you like. But start a new document in a new buffer and you'll find that left-margin is back to the default value—because the second buffer's local value has not been set. As you might expect, you can set both the default and local values of such variables. When you set the value of a variable such as left-margin or case-fold-search with setq, you are actually setting the local value. The way to set default values is to use setq-default instead of setq, as in: (setq-default left-margin 4) Unfortunately, there is no general way to tell whether a variable has just one global value or has default and local values (except, of course, by looking at the Lisp code for the mode). Therefore the best strategy is to use a plain setq, unless you find from experience that a particular variable doesn't seem to take on the value you setq it to—in which case you should use setq-default. For example, if you put the line: (setq case-fold-search nil) in your .emacs file, you will find that Emacs still ignores case differences in search commands as if this variable were still t; instead, you should use setq-default. |
| < Day Day Up > |


Merkletree Fiddler
You can enter numbers directly into the form below to update the Merkle
tree, or you can mouse-over leaf nodes to show the inclusion proof
and click on them to show a consistency proof from a tree which
includes that leaf at its highest entry.


How to see a meteor shower over the UK this weekend
The Leonids will peak on Saturday night and Sunday
by Neil ShawA high-speed meteor shower will light up the skies over the UK this weekend as the Leonids reach their peak with up to 15 shooting stars every hour.
The Leonids are renowned for being bright and clear, in part thanks to the 44 miles per second speed of the debris as it smashes into the Earth's atmosphere.
A nearly full moon and the recent bad weather may make seeing the shower harder than in previous years, but anyone who can find a clear sky in a dark location should be in for a treat.
The shower will get busier through the evening on Saturday, peaking after midnight.
According to NASA you should look West to get the best view, with the far north of the country and the South East set to get the best views on Saturday and Sunday.
Half of the shower is expected to leave visible trails that will remain in the sky for several seconds, thanks to the composition of rocks from the Comet Tempel-Tuttle.
The Leonid shower appears to come from in the constellation Leo.
The best view is forecast to be in 2034 when 2,000 meteors an hour will crash across the sky.
If you miss the Leonids, the Geminids will be along in around a month with 120 meteors an hour.


Description
This project was part of my bachelor thesis at the University of Vienna. In collaboration with the Cooperated Systems (CoSy) department I built a simple, easily deployable and open (FLOSS) IoT device that students and academics can use for experiments.
Goal
The goal was to built a modular IoT Box that can be configured over the Internet. The user manages a cluster of boxes and pushes code for various use cases depending on his intents to the boxes. To achieve that the existing Seattle Testbed codebase will be used. This should solve issues like "cluster management", software updates and code pushing.
Visualization
After the boxes were built, it was necessary to visualize the data that was produced by them. The main purpose of this site is to do exactly that. Under the tab 'visualization' it is possible to show the current collected data and create diagrams with it. The user is also able to upload his own data set.