(maxmsp) Simple Additive Synth, patcher aesthetics…

I’ve uploaded a much-improved version of my simple additive synthesizer (2 oscillators). The patcher makes extensive use of send and receive objects, which function to both clean up the spaghetti tangle of patch cords, and provide a means for self-commenting code.

The core of the patcher is a two-oscillator additive synth, with function controls for amplitude envelopes.

MIDI input and other user interface controls, aside from the function editors, are located at the top of the patcher. A MIDI keyboard is used to supply the pitch (as a MIDI note number later converted to a frequency in Hz), and to trigger the attack and release sections of the envelopes. Note numbers from noteon messages are sent via stripnote to the s noteNumber object. noteNumber is received by both oscillator patches. Stripnote also passes the noteon velocity, which is sent to each function editor via s noteOn and used to bang (start) the function. Since each function editor makes use of a sustain point (indicated by the white halo around the dot), a next message is needed to move to the release portion of the envelope. All incoming velocities are sent from notein to the select object. Noteoff velocities of 0 are selected, and the resulting bang is sent via s noteOff to each function editor to trigger a next message. Notice how the send and receive objects are self-commenting the patcher? Since you have to label a send/receive destination, you can use a label that indicates what is being sent. I’ve color-coded all the send/receive objects so you can easily find the connections.

The ratio (multiplier) for the second oscillator frequency can be set with a float, sent via s partialRatio. Overall partial amplitude is addressed similarly via partialAmp. To the far right of the top portion there is also an input to set the overall time length of the function editors (via adrLength). Since the sustain will last as long as you hold down a key, this length only really applies to the attack, initial decay, and release times. The integer is sent to the setdomain $1 message, and the whole message is sent to each function editor.

There are two continuous controllers being used to set the detune amount, and the portamento time (portTime). The top integer of this portion can be used to tell ctlin to listen to a different controller number (119 and 120 work with my nanoKontrol). The cc input is scaled to an appropriate range (0. – 1. for detune, meaning a max of one half step; 0. – 1000. for portamento in ms), and then sent.

The first oscillator is very straightforward. noteNumber is converted from MIDI to frequency (Hz), packed with the current portamento time, and the message is sent on to line~ and eventually to the frequency input of a saw~. The function editor receives noteOn, noteOff, and adrLength messages. Its output is pairs of numbers in line~ format, sent to a line~, and then on to a *~ to control amplitude.

The second oscillator has the exact same function editor controls, but is more involved with regards to frequency. noteNumber and detune are added together and eventually sent to mtof. mtof can convert fractional MIDI note numbers to the appropriate microtune frequency. The detune amount is added to the note number, and the bang message is triggers the + operation when ever the detune amount changes. This allows you to update the partial frequency with detune information even while holding a note.

The detuned frequency is then sent to a multiplication object to be multiplied by the partial ratio. From there, the rest of the patcher is similar until you get to the extra *~ object for scaling the overall partial amplitude (since partials usually have less amplitude than fundamentals).

The output of both scaled saw~ objects are sent via an audio send object (send~) to the same receive~ destination, and then to gain~ object and ezdac~. It’s important to note that audio send~ and receive~ objects must be spelled out in full, not abbreviated as s~ and r~.


Leave a Reply