In this tutorial we talk about how to create a MIDI-controllable sampler in MSP. Along the way, we'll look at different features of many samplers, including looping, keymaps, and multi-timbral operation.
Our fun sampler
The umenu object in our tutorial patcher causes the coll object to dump out different data depending on which sample we select. Looking at its contents by double-clicking it reveals the entire database:
1, 24 sample1 0 0 0; (bd+hh.aiff)
2, 33 sample2 0 0 0; (snare.aiff)
3, 50 sample3 0.136054 373.106537 1; (cym.aiff)
4, 67 sample4 60.204079 70.476189 1; (bass.aiff)
5, 84 sample5 0 0 0; (epno.aiff)
6, 108 sample6 0 0 0; (ahkey.aiff)
base_key buffer~_name loop_start loop_end looping
The base key refers to which MIDI note the sample will play at normal speed. The second item in the coll refers to which buffer~ object will play the sample. The next three values determine the start and end points of an internal loop which the groove~ object will play, and whether or not to use it at all (the last value).
The point of a sampler is to play back recordings (audio samples), often from an acoustic instrument. If an acoustic instrumental source is used, it's inefficient to create a unique sample for every possible note on that instrument. Instead, every few notes are sampled, and in-between pitches are achieved by playing these sampled notes slightly fast or slow based on their base key. Similarly, a sampler is capable of playing notes that sustain for far longer than it's practical to record an instrumental sample. Instead, a sample of modest length is used, as an area is found within the sustaining part of the sample that can be safely looped. When you play a note and hold it, the sample starts playback at the beginning; once it moves into the loop zone, it repeats that area over and over again; when you pick up the note, it plays from the loop zone through to the end of the sample.
The base key is converted from MIDI to frequency by the mtof object and used as a divisor for the frequency we want to play. In this way, we get a ratio of the desired frequency and the base frequency which we can use to set the speed of a groove~ object. If we want the sound to come out an octave higher, we want the ratio to be ; an octave lower, it should be . The second value out of the coll file is formatted with a prefix by the prepend object and send to the groove~ to select the appropriate buffer~ to play. The loop values come out as numeric data, setting the loop start and end points and sending a loop value into an int box which is triggered each time a note plays. Note-on values (i.e. values with velocities greater than ) passed from the stripnote object trigger the message, set the value of the sig~ object, and restart the sample by sending a into the groove~ object. Note-off objects set the state to , allowing the groove~ to play out the sample to the end and then stop.
Multi-timbral samplers and keymaps
The funbuff object is loaded with these values to use them as a key map for a multi-timbral sampler. Any MIDI notes whose pitch values are between and will trigger sample (as defined in the coll file); pitches between and will trigger sample ; and so on.
The MIDI velocity of incoming notes is divided byto scale it between and It is then multiplied by itself, creating an exponential scaling wherein higher values on the MIDI velocity continuum yield far greater increases in volume than lower numbers. This simulates the behavior of logarithmic volume circuits (such as mixer faders) in analog audio equipment.
The seq object, a midiflush, and a midiparse. These objects load a MIDI file and output the raw bytes in response to and messages (seq), shut off all sounding notes in a MIDI byte stream in response to a (midiflush), and parse and extract the pitch/velocity pairs from a MIDI stream so that they can be used elsewhere (midiparse). This allows our awesome MIDI sequence to be played by the sampler logic in the main patch.subpatch contains a
MIDI-controllable samplers can be created using MSP buffer~ and groove~ objects. Different parameters of sampler data (loop points, sample name, base key) can be stored in coll files for easy access so that you can easily switch samples depending on MIDI events within the same MSP patcher logic.