A Word on TypesΒΆ

The type used for internal computations in Faust depends on the value of the FAUSTFLOAT macro passed to the compiler (a little bit like templating). So one need to read the value of this Macro to be able to build datatypes depending on it. In order to access it, we wrote the macro inside a string into the C architecture file dllarch.c.

Note

for the moment, only the float and double values are working. We assume that float is 32-bits floating-point numbers and double 64-bits floating point numbers. This might lead to portability issues

The next point is to declare (i.e. create ctypes objects representing) the signatures of the functions and datastructures used in the library. Functions signatures are relatively easy to declare, through ctypes CFUNCTYPE function. Struct datatypes are more complex to declare, as their type is represented in Python by a class inheritating from the ctypes Structure class. So we used a class factory (i.e. a function returning a class), whose argument enables us to make the class depend on FAUSTFLOAT type.

For instance, going back on our minimal example, if it is compiled with

$ gcc -DFAUSTFLOAT=double -fPIC -shared tests/dsp/minimal.c -o tests/dsp/minimal64.so

we will have float64 arrays

>>> dsp = Faust("../tests/dsp/minimal64.so")
>>> dsp.proc.FAUSTFLOAT
<class 'ctypes.c_double'>

Whereas with

$ gcc -DFAUSTFLOAT=float -fPIC -shared tests/dsp/minimal.c -o tests/dsp/minimal64.so

we will have float32 arrays (this is the default)

>>> dsp = Faust("../tests/dsp/minimal32.so")
>>> dsp.proc.FAUSTFLOAT
<class 'ctypes.c_float'>