Next  |  Prev  |  Top  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search

Generating a MIDI Synthesizer for PD

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):

The parameters freq and gain are set according to MIDI note-number and velocity, respectively, while the gate parameter is set to 1 on a MIDI ``note-on'' and back to zero upon ``note-off''. The abstraction midi-in.pd receives and decodes MIDI data in pd.

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.

In addition to converting the frequency and amplitude parameters to the standard names freq and gain, we have added a classic ADSR envelope generator20(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.

Figure 15: Listing of cpgrs.dsp--a FAUST program specifying a simple synth patch consisting of white noise through a constant-peak-gain resonator.

 
  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';
  };


Next  |  Prev  |  Top  |  JOS Index  |  JOS Pubs  |  JOS Home  |  Search

Download aspf.pdf
[Comment on this page via email]

``Audio Signal Processing in Faust'', by Julius O. Smith III.
Copyright © 2022-05-05 by Julius O. Smith III
Center for Computer Research in Music and Acoustics (CCRMA),   Stanford University
CCRMA