Shaping a sound on the way out
By the end of this chapter, your kick is compressed, your hi-hat filtered, and a knob on your controller darkens the snare as you play.
The project so far
The project from Your first MIDI map: your own map, watched as it plays, with a kick by name, a snare by likeness and a hi-hat by rule.
mkdir kitchen-kit
cd kitchen-kit
subsample --init
recorder:
enabled: true
player:
midi_map: midi-map.yaml
watch_midi_map: true
enabled: true
similarity:
weight_timbre_onset: 2
detection:
release_threshold_db: 4
retrigger_threshold_db: 15
min_peak_db: -45
assignments:
- name: My kick
channel: 10
notes: 36
select:
where:
name: hits_1
- name: My snare
channel: 10
notes: drum.snare_1
select:
where:
reference: GM38_AcousticSnare
- name: My hi-hat
channel: 10
notes: drum.hi_hat_closed
select:
where:
duration: { lte: 0.5 }
order: [{ by: level, dir: desc }]
pick: velocity
A chain of processors
An assignment can change its sound before it plays: process is a list of processors, and the sound passes through them from the top down. Give the kick one:
- name: My kick
channel: 10
notes: 36
select:
where:
name: hits_1
process:
- compress: true
true gives a processor its own settings. The compressor takes them from the sound it is given, as gate, distort, transient and reshape do, while the rest, such as the filters and saturate, start from fixed settings, each given on the processing page. The compressor reads each sample's level, how fast it starts and how it decays, and sets itself from those, so a kick's strike keeps its punch. Save the map and play the kick, and listen for the quieter part of its sound coming up to meet the strike: evening the two out is what compression does.
A value where you want one
true is the place to start, and a value is for when you know the one you want. A tick recorded on a worktop can carry some low thud with it, and a filter that lets through only what is above 300 Hz, as the General MIDI kit filters its hi-hats, takes it out:
- name: My hi-hat
channel: 10
notes: drum.hi_hat_closed
select:
where:
duration: { lte: 0.5 }
order: [{ by: level, dir: desc }]
pick: velocity
process:
- filter_high: { freq: 300 }
Listen for the hi-hat losing its body and keeping its tick. The processing reference lists each processor, what it does, and every value it takes.
A knob on any setting
Wherever a processor takes a number, a controller can set it instead. Give the snare a filter that darkens it as its cutoff comes down, and put the cutoff on controller 74, which MIDI calls brightness and General MIDI 2 uses for a filter's cutoff. Set a knob on your controller to send it, if none does already:
- name: My snare
channel: 10
notes: drum.snare_1
select:
where:
reference: GM38_AcousticSnare
process:
- filter_low: { freq: { cc: 74, min: 200, max: 8000 } }
The knob's travel runs from 200 Hz at the bottom to 8000 Hz at the top: cc says which controller, and min and max where its ends fall. Play the snare and turn the knob: it goes from muffled to open.
Why a change arrives a moment late
Subsample does not process a sound as each note plays. It prepares each processed version in the background, as soon as it knows it will need it, and keeps it on disk, in samples/variant-cache/, so a note plays it with nothing left to compute. Until a version is ready, a note plays the one it played last, or the sound unprocessed. So the first notes after Subsample starts, or after you change a setting or turn the knob, can come out without the change, and the notes after it have it.
With the kit shaped, the next chapter turns from drums to a keyboard played by one held sound, and a loop that stays on the beat.