In this chapter we demonstrate a design for playing pre-recorded samples from a MIDI keyboard. This design implements some of the main features of a basic sampler keyboard: assigning samples to regions of the keyboard, specifying a base (untransposed) key location for each sample, playing samples back with the proper transposition depending on which key is played, and making polyphonic voice assignments. For the sake of simplicity, this patch does not implement control from the pitchbend wheel or mod wheel, but the method for doing so would not be much different from that demonstrated in the previous two chapters.
In this patch we use the
groove~ object to play samples back at various speeds, in some cases using looped samples. As was noted in
Tutorial 19, if we want a polyphonic instrument we need as many sound-generating objects as we want separate simultaneous notes. In this tutorial patch, we use four copies of a subpatch called
samplervoice~ to supply four-voice polyphony. As in
Tutorial 19— we use a
poly object to assign a voice number to each MIDI note, and we use
route to send the note information to the correct
samplervoice~ subpatch.
poly assigns a voice number to each MIDI note, to send information to the correct subpatch
Before we examine the workings of the samplervoice~ subpatch, it will help to review what information is needed to play a sample correctly.
• 1. The sound samples must be read into memory (in
buffer~ objects), and a list of the memory locations (
buffer~ names) must be kept.
• 2. Each sample must be assigned to a region of the keyboard, and a list of the key assignments must be kept.
• 3. A list of the base key for each region -- the key at which the sample should play back untransposed -- must be kept.
• 4. A list of the loop points for each sample (and whether looping should be on or off) must be kept.
• 5. When a MIDI note message is received, and is routed to a
samplervoice~ subpatch, the
groove~ object in that subpatch must first be told which
buffer~ to read (based on the key region being played), how fast to play the sample (based on the ratio between the frequency being played and the base key frequency for that region), what loop points to use for that sample, whether looping is on or off, and what amplitude scaling factor to use based on the note- on velocity.
In this patch, the samples are all read into memory when the patch is first loaded.
• Double-click on the
p samplebuffers subpatch to open its Patcher window.
You can see that six samples have been loaded into
buffer~ objects named
sample1,
sample2, etc. If, in a performance situation, you need to have access to more samples than you can store at once in RAM, you can use
read messages with filename arguments to load new samples into
buffer~ objects as needed.
• Close the subpatch window. Click on the
message box marked ‘keyboard sample assignments’.
This stores a set of numbered key regions in the
funbuff object. (This information could have been embedded in the
funbuff and saved with the patch, but we left it in the
message box here so that you can see the contents of the
funbuff.) MIDI key numbers 0 to 40 are key region 1, keys 41 to 47 are key region 2, etc. When a note-on message is received, the key number goes into
funbuff, and
funbuff reports the key region number for that key. The key region number is used to look up other vital information in the
coll.
Note-on key number finds region number in funbuff, which looks up sample info in coll
• Double-click on the
coll object to see its contents.
1, 24 sample1 0 0 0;
2, 33 sample2 0 0 0;
3, 50 sample3 0.136054 373.106537 1;
4, 67 sample4 60.204079 70.476189 1;
5, 84 sample5 0 0 0;
6, 108 sample6 0 0 0;
coll contains sample information for each key region
The key region number is used to index the information in
coll. For example, whenever a key from 48 to 52 is pressed,
funbuff sends out the number
3, and the information for key region 3 is recalled and sent to the appropriate
samplervoice~ subpatch. The data for each key region is: base key,
buffer~ name, loop start time, loop end time, and loop on/off flag.
The voice number from
poly opens the correct outlet of
gate so that the information from
coll goes to the right subpatch.
• Close the
coll window, and double-click on one of the
samplervoice~ subpatch objects to open its Patcher window.
The samplervoice~ subpatch
You can see that the information from
coll is unpacked in the subpatch and is sent to the proper places to prepare the
groove~ object for the note that is about to be played. This tells
groove~ what
buffer~ to read, what loop times to use, and whether looping should be on or off. Then, when the note information comes in the left inlet, the velocity is used to send an amplitude value to the
*~ object, and the note-on key number is used (along with the base key number received from the right inlet) to calculate the proper playback speed for
groove~ and to trigger
groove~ to begin playback from time
0.
• Close the subpatch window.
You're almost ready to begin playing samples, but there is one more detail to attend to first. To save storage space, the samples used in this patch are mono AIFF files with a sample rate of 22,050 Hz. To hear them play properly you should set the sample rate of MSP to that rate.
• Double-click on the
dac~ object to open the DSP Status window. Set the Sampling Rate to
22.050 kHz, then close the DSP Status window.
• Note: Resetting the sampling rate may not be possible, depending on your hardware.
The difference between the sample rate of an audio file and the sample rate being used in MSP is a potential problem when playing samples. This method of resolving the difference suffices in this situation because the audio files are all at the same sample rate and because these samples are the only sounds we will be playing in MSP. In other situations, however, you're likely to want to play samples (perhaps with different sampling rates) combined with other sounds in MSP, and you'll want to use the optimum sampling rate.
For such situations, you would be best advised to use the ratio between the audio file sample rate and the MSP sample rate as an additional factor in determining the correct playback speed for
groove~. For example, if the sample rate of the audio file is half the sample rate being used by MSP, then
groove~ should play the sample half as fast.
You can use the objects
info~ and
dspstate~ to find out the sampling rate of the sample and of MSP respectively, as demonstrated in the following example.
Calculate playback speed based on the sampling rates of the audio file and of MSP
The note-on key number is used first to recall the information for the sample to be played. The name of a
buffer~ is sent to
groove~ and
info~. Next, a
bang is sent to
dspstate~ and
info~. Upon receiving a
bang,
dspstate~ reports the sampling rate of MSP and
info~ reports the sampling rate of the AIFF file stored in the
buffer~. In the lower left part of the example, you can see how this sampling rate information is used as a factor in determining the correct playback speed for
groove~.
• Turn audio on and set the ‘Output Level’
number box to a comfortable listening level. Play a slow chromatic scale on the MIDI keyboard to hear the different samples and their arrangement on the keyboard.
To arrange a unified single instrument sound across the whole keyboard, each key region should contain a sample of a note from the same source. In this case, though, the samples are arranged on the keyboard in such a way as to make available a full ‘band’ consisting of drums, bass, and keyboard. This sort of multi-timbral keyboard layout is useful for simple keyboard splits (such as bass in the left hand and piano in the right hand) or, as in this case, for accessing several different sounds on a single MIDI channel with a sequencer.
• For an example of how a multi-timbral sample layout can be used by a sequencer, click on the
toggle marked ‘Play Sequence’. Click on it again when you want to stop the sequence. Turn audio off. Double-click on the
p sequence object to open the Patcher window of the subpatch.
The p sequence subpatch
The
seq sampleseq.midi object contains a pre-recorded MIDI file. The
midiparse object sends the MIDI key number and velocity to
poly in the main patch. Each time the sequence finishes playing, a
bang is sent out the right outlet of
seq; the
bang is used to restart the
seq immediately, to play the sequence as a continuous loop. When the sequence is stopped by the user, a
bang is sent to
midiflush to turn off any notes currently being played.
• When you have finished with this patch, don't forget to open the DSP Status window and restore the Sampling Rate to its original setting.
To play samples from the MIDI keyboard, load each sample into a
buffer~ and play the samples with
groove~. For polyphonic sample playback, you will need one
groove~ object per voice of polyphony. You can route MIDI notes to different
groove~ objects using voice assignments from the
poly object.
To assign each sample to a region of the MIDI keyboard, you will need to keep a list of key regions, and for each key region you will need to keep information about which
buffer~ to use, what transposition to use, what loop points to use, etc. A
funbuff object is good for storing keyboard region assignments. The various items of information about each sample can be best stored together as lists in a
coll, indexed by the key region number. When a note is played, the key region is looked up in the
funbuff, and that number is used to look up the sample information in
coll.
The proper transposition for each note can be calculated by dividing the played frequency (obtained with the
mtof object) by the base frequency of the sample. The result is used as the playback speed for
groove~. If the sampling rate of the recorded samples differs from the sampling rate being used in MSP, that fact must be accounted for when playing the samples with
groove~. Dividing the audio file sampling rate by the MSP sampling rate provides the correct factor by which to multiply the playback speed of
groove~. The sampling rate of MSP can be obtained with the
dspstate~ object. The sampling rate of the AIFF file in a
buffer~ can be obtained with
info~ (Remember -- resetting the sampling rate may not be possible on your hardware).
Note-on velocity can be used to control the amplitude of the samples. An exponential mapping of velocity to amplitude is usually best. Multi-timbral sample layouts on the keyboard can be useful for playing many different sounds, especially from a sequencer. The end-of-file
bang from the right outlet of
seq can be used to restart the
seq to play it in a continuous loop. If the MIDI data goes through a
midiflush object, any notes that are on when the
seq is stopped can be turned off by sending a
bang to
midiflush.
See Also
Name |
Description |
buffer~ |
Store audio samples
|
dspstate~ |
Report current DSP settings
|
groove~ |
Variable-rate looping sample playback
|
poly~ |
Polyphony/DSP manager for patchers
|