Juno 6 and Juno 60, first with MIDI • 6-note polyphony • 1 DCO ft. pulse, saw, square sub, and noise, LFO, ADSR envelope, and 24 dB/oct resonant LPF per voice • HPF and chorus effect
synths are limited only by CPU power • Voice stealing can be musical • Track an array of active voices • Remove a note if the same pitch is triggered • Remove the oldest note when MAX_POLYPHONY is reached • Manage oscillator lifespan with OscillatorNode.onended
the oscillators are stopped. The DCO's noteOff() method takes an optional releaseLength param, so it can kill a note immediately (for stealing), or after a delay (for an envelope release).
whenever a message is received • Now you just need to understand the anatomy of a MIDI message to deal with it appropriately • MIDI manufacturer's assoc. summary: midi.org/techspecs/midimessages.php • Another good resource: indiana.edu/~emusic/etext/MIDI/chapter3_MIDI4.shtml
the MIDIMessageEvent.data array and consist of 3 bytes • Status byte, data byte 1, data byte 2 • Status byte tells us which channel and what kind of message • MIDI channels are a way of namespacing MIDI events – 106.js ignores MIDI channel, a.k.a. “Omni mode” • MIDI message types include Note On, Note Off, Control Change (CC), Pitch Bend, Aftertouch, Program Change, Sysex
MIDI message data as binary, sometimes as decimal • A “Note on” message with velocity 0 should be interpreted as a “Note Off” message • 106.js ignores velocity because the Juno 106 wasn't velocity-sensitive
• Some MIDI CCs are defined in the spec, but with modern devices they're essentially arbitrary • A single MIDI message uses 7-bits to represent 0 – 127, but 2 messages can be combined for increased resolution (14-bit MIDI) • Many modern controllers transmit 14-bit MIDI from their knobs or faders • 14-bit MIDI consists of an MSB and an LSB, offset by 32 • To handle 14-bit CCs, we fill a buffer with 2 consecutive messages to determine if it's 7- or 14-bit