
Q-FAUST
=======

A Faust module for the Q programming language. Copyright (c) 2005-2006 by
Albert Graef, Johannes Gutenberg University Mainz, Germany. Distributed under
the GNU General Public License (GPL) Version 2 or later (see the accompanying
COPYING file for details).

This module lets you load and run Faust-generated signal processing modules in
Q. Faust (an acronym for Functional AUdio STreams) is a functional programming
language for real-time sound processing and synthesis developed at Grame
(Lyon, France, see http://www.grame.fr) and distributed as GPL'ed software. A
closer description of Faust can be found on its SourceForge-hosted website,
http://faudiostream.sf.net.

NOTE: This release needs Q 7.8 and Faust 0.9.6 or later. The examples require
Q-Audio (>=2.3) and Q-Midi to work.


USAGE
=====

Once Faust and this module have been installed as described in the INSTALL
file, you should be able to compile a Faust DSP to a shared module loadable by
Q-Faust as follows (Linux):

$ faust -a q.cpp -o mydsp.cpp mydsp.dsp
$ g++ -shared -o mydsp.so mydsp.cpp

NB: If you want to load several different DSPs in the same program, you have
to make sure that they all use distinct names for the "mydsp" class. This can
be achieved most easily by just redefining mydsp to whatever class name you
choose during the C++ compile stage, like so:

$ g++ -shared -Dmydsp=myclassname -o mydsp.so mydsp.cpp

Then fire up the Q interpreter with the faust module, and load the DSP as
follows:

==> import faust

==> def DSP = faust_init "mydsp" 48000

==> DSP
<<FaustDSP>>

The faust_init function loads the "mydsp.so" module (the .so suffix is
supplied automatically) and returns a FaustDSP object which can then be used
in subsequent operations. The second parameter of faust_init, 48000 in this
example, denotes the sample rate in Hz. This can be an arbitrary integer value
which is available to the hosted DSP (it's up to the DSP whether it actually
uses this value in some way).

The faust_info function can be used to determine the number of input/output
channels as well as the "UI" (a data structure describing the available
control variables) of the loaded DSP:

==> def (N,M,UI) = faust_info DSP

To actually run the DSP, you'll need some audio data, encoded using 32 bit
(i.e., single precision) floats as a byte string. Suppose you already have two
channels of audio data in the IN1 and IN2 variables and the DSP has 2 input
channels, then you would pass the data through the DSP as follows:

==> faust_compute DSP [IN1,IN2]

This will return another list of byte strings, containing the 32 bit float
samples produced by the DSP on its output channels, being fed with the given
input data.

Some DSPs (e.g., synthesizers) don't actually take any audio input, in this
case you just specify the number of samples to be generated instead:

==> faust_compute DSP 1024

Most DSPs also take additional control input. The control variables are listed
in the "UI" component of the faust_info return value. For instance, suppose
that there's a "Gain" parameter listed there, it might look as follows:

==> controls UI!0
hslider <<Ref>> ("Gain",1.0,0.0,10.0,0.1)

The second parameter of the hslider constructor indicates the arguments the
control was created with in the .dsp source file (see the Faust documentation
for more details on this). The first parameter is a reference which points to
the current value of the control variable. You can change this value with the
put function before invoking faust_compute the next time (changes of control
variables only take effect between different invokations of faust_compute):

==> def GAIN = control_ref (controls UI!0)

==> get GAIN
1.0

==> put GAIN 2.0
()

==> faust_compute DSP [IN1,IN2]

It is also possible to create copies of an existing DSP with the faust_clone
function, which is quite handy if multiple copies of the same DSP are needed,
a case which commonly arises when implementing polyphonic synthesizers:

==> def DSP2 = faust_clone DSP

When you're done with a DSP, you can invoke the faust_exit function to unload
it (this also happens automatically when a FaustDSP object is garbage-
collected):

==> faust_exit DSP

Ok, I hope that this is enough to get you started. Further examples can be
found in the examples subdirectory. Please send bug reports, patches, comments
and suggestions to: ag@muwiinfa.geschichte.uni-mainz.de.


ACKNOWLEDGEMENTS
================

Many thanks to Yann Olarey at Grame, the principal author of Faust!


Enjoy!
October 2007
Albert Graef
