The faust2puredata script has a -poly option for generating a MIDI synthesizer plugin for pd. The synth has eight voices and manages voice allocation when played from MIDI. For this to work, the FAUST program should be written to synthesize one voice using the following three standard synthesis parameters (which are driven from MIDI data in the pd plugin):
Let's make a simple 8-voiced MIDI synthesizer based on the example Faust program cpgrs.dsp (``Constant-Peak-Gain Resonator Synth'') listed in Fig.15 below.
> faust2puredata -poly cpgrs.dspThis creates the file cpgrs .pd_darwin in your working directory.
In addition to converting the frequency and amplitude parameters to the standard names freq and gain, we have added a classic ADSR envelope generator22(defined in FAUST's envelopes.lib file) which uses our new gate parameter, and which adds four new envelope parameters attack, decay, sustain, and release.
To see lower-level details of how the pd plugin is created, read the faust2puredata shell script, typically installed in /usr/local/bin/ from faust/tools/faust2appls/faust2puredata.
import("stdfaust.lib"); // define en.adsr, ma.SR, ma.PI declare name "Constant-Peak-Gain Resonator Synth"; declare author "Julius Smith"; declare version "1.0"; declare license "GPL"; /* Standard synth controls supported by faust2pd */ freq = nentry("freq", 440, 20, 20000, 1); // Hz gain = nentry("gain", 0.1, 0, 1, 0.01); // frac gate = button("gate"); // 0/1 /* User Controls */ bw = hslider("bandwidth (Hz)", 100, 20, 20000, 10); /* ADSR envelope parameters */ attack = hslider("attack", 0.01,0, 1, 0.001); // sec decay = hslider("decay", 0.3, 0, 1, 0.001); // sec sustain = hslider("sustain",0.5, 0, 1, 0.01); // frac release = hslider("release",0.2, 0, 1, 0.001); // sec /* Synth */ process = no.noise * env * gain : filter with { env = gate : vgroup("1-adsr", en.adsr(attack, decay, sustain, release)); filter = vgroup("2-filter", (firpart : + ~ feedback)); R = exp(0 - ma.PI * bw / ma.SR); // pole radius A = 2 * ma.PI * freq / ma.SR; // pole angle (radians) RR = R*R; firpart(x) = (x - x'') * (1-RR)/2; // time-domain coefficients ASSUMING ONE-SAMPLE FEEDBACK DELAY: feedback(v) = 0 + 2*R*cos(A)*v - RR*v'; }; |