-
Notifications
You must be signed in to change notification settings - Fork 87
Faust Processor
- Browse the suggested Documentation and Resources.
- Use the Online IDE to develop and test code.
- Read Julius Smith's Audio Signal Processing in FAUST.
- Browse the Libraries.
- Read the Syntax Manual.
- Join the communities.
Let's start by looking at FAUST DSP files, which end in .dsp. For convenience, the standard library is always imported, so you don't need to import("stdfaust.lib"); Here's an example using a demo stereo reverb:
process = dm.zita_light;DSP_PATH = "C:/path/to/faust_reverb.dsp" # Must be absolute path
INPUT_AUDIO_PATH = "C:/path/to/piano.wav"
DURATION = 10.
faust_processor = engine.make_faust_processor("faust")
faust_processor.set_dsp(DSP_PATH) # You can do this anytime.
# Using compile() isn't necessary, but it's an early warning check.
faust_processor.compile() # throws a catchable Python Runtime Error for bad Faust code
print(faust_processor.get_parameters_description())
# You can set parameters by index or by address.
faust_processor.set_parameter("/Zita_Light/Dry/Wet_Mix", 1.)
faust_processor.set_parameter(0, 1.)
# Unlike VSTs, these parameters aren't necessarily 0-1 values.
# For example, if you program your FAUST code to have a 15000 kHz filter cutoff
# you can set it naturally:
# faust_processor.set_parameter(7, 15000)
print('val: ', faust_processor.get_parameter("/Zita_Light/Dry/Wet_Mix"))
print('val: ', faust_processor.get_parameter(0))
graph = [
(engine.make_playback_processor("piano", load_audio_file(INPUT_AUDIO_PATH)), []),
(faust_processor, ["piano"])
]
engine.load_graph(graph)
engine.render(DURATION)Here's an example that mixes two stereo inputs into one stereo output and applies a low-pass filter.
declare name "MyEffect";
import("stdfaust.lib");
myFilter = fi.lowpass(10, hslider("cutoff", 15000., 20, 20000, .01));
process = si.bus(4) :> sp.stereoize(myFilter);INPUT_AUDIO_PATH1 = "piano.wav"
INPUT_AUDIO_PATH2 = "vocals.wav"
DURATION = 10.
faust_processor = engine.make_faust_processor("faust")
faust_processor.set_dsp("C:/path/to/dsp_4_channels.dsp") # Must be absolute path
print(faust_processor.get_parameters_description())
faust_processor.set_parameter("/MyEffect/cutoff", 7000.0) # Change the cutoff frequency.
# or set automation like this
faust_processor.set_automation("/MyEffect/cutoff", 15000+5000*make_sine(2, DURATION))
graph = [
(engine.make_playback_processor("piano", load_audio_file(INPUT_AUDIO_PATH1)), []),
(engine.make_playback_processor("vocals", load_audio_file(INPUT_AUDIO_PATH2)), []),
(faust_processor, ["piano", "vocals"])
]
engine.load_graph(graph)
engine.render(DURATION)Polyphony is supported too. You simply need to provide DSP code that refers to correctly named parameters such as freq or note, gain, and gate. For more information, see the FAUST manual. In DawDreamer, you must set the number of voices on the processor to 1 or higher. The default (0) disables polyphony. Refer to tests/test_faust_poly*.py.
Faust code in DawDreamer can use the soundfile primitive. Normally soundfile is meant to load .wav files, but DawDreamer uses it to receive data from numpy arrays. Refer to tests/test_faust_soundfile.py which contains an example of loading 88 piano notes and playing them with polyphony.
soundfile_test.py
# suppose audio1, audio2, and audio3 are np.array shaped (Channels, Samples)
soundfiles = {
'mySound': [audio1, audio2, audio3]
}
faust_processor.set_soundfiles(soundfiles)soundfile_test.dsp
soundChoice = nentry("soundChoice", 0, 0, 2, 1); // choose between 0, 1, 2
process = soundChoice,_~+(1):soundfile("mySound",2):!,!,_,_;Note that soundfile("mySound",2) has 2 as a hint that the audio is stereo. It's unrelated to the Python side where mySound's dictionary value has 3 numpy arrays.