Subsystem Search

Pitched instruments and loops

By the end of this chapter, one held note plays across a keyboard, the same note holds for as long as you keep a key down, and a rhythm you tapped plays on the beat, round and round, while its key is held.

The project so far

The project from Shaping a sound on the way out: your own map, watched as it plays, with a compressed kick, a filtered hi-hat and a snare whose brightness is on a knob.

$ 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
    process:
      - compress: true
  - name: My snare
    channel: 10
    notes: drum.snare_1
    select:
      where:
        reference: GM38_AcousticSnare
    process:
      - filter_low: { freq: { cc: 74, min: 200, max: 8000 } }
  - 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 }

One held note

Record one note held steady for a few seconds: hum it, bow it, or run a wet finger round the rim of a glass. Leave a second of quiet before it, hold it as evenly as you can, with no vibrato, and let it stop. Save it in the project folder as note.wav.

A recording for this step is planned. Until then, use one of your own.

Cut it as you cut your hits:

Example not checked: it is not run when this site is built.

$ subsample note.wav

A steady note gives one sample, samples/captures/note_1.wav.

Is it pitched?

Subsample tests every sample for a pitch it holds: one found through most of the sound, found with confidence and barely wandering, in a sound that is more tone than strike. A sample that passes is pitched, and only a pitched sample plays at other pitches. subsample catalog --pitched lists the ones that pass, one to a line:

Example not checked: it is not run when this site is built.

$ subsample catalog --pitched

Your note should be among them. If it is not, subsample catalog with no --pitched writes every sample's measures as a table instead, and seven of its columns are what the test reads, from voiced_fraction, how much of the sound has a pitch at all, to pitch_stability_st, how far it wanders, in semitones. A note held more evenly passes.

A keyboard from one note

Add a keyboard to the map, on MIDI channel 1:

- name: Glass keys
  channel: 1
  notes: C3..C6
  select:
    where:
      name: note_1
  process:
    - repitch: true
  mode: gated

C3..C6 is every note from C3 to C6, 37 keys, and repitch shifts your note to each of them, from the pitch Subsample found in it, without changing its length. Where a map should take whichever of your sounds has a pitch, pitched: true in where keeps only those.

mode says how a sound answers its key. Left out, it plays to its end however soon you let go; gated plays it while the key is down, and stops it with a short fade when you let go. So a key held longer than your recording falls silent when the recording ends.

A note that holds

A sound can loop while its key is down: Subsample finds a stretch of it that repeats without a click, and plays it round and round until you let go. Give your note a key of its own, below the keyboard:

- name: Glass drone
  channel: 1
  notes: C2
  select:
    where:
      name: note_1
  mode: loop

Hold C2, and your note sounds for as long as you hold it, at the pitch you recorded, whichever key it is on. It needs a key of its own because a sound Subsample repitches does not loop: with mode: loop, a repitched sound plays gated instead, and Subsample says so when the map loads. The same is true of a sound it reverses.

subsample loops shows the loop it found:

Example not checked: it is not run when this site is built.

$ subsample loops samples/captures/note_1.wav

It prints where the loop starts and ends, in seconds, the crossfade across the join, and junction_flux, how much the sound jumps at the join: at about 1 or below you will not hear it, and the higher it is, the more you may. With --render auditions it also writes two files to auditions/: the loop as it plays, and the same join with no crossfade, so you can hear what the crossfade does. A point you write in loop wins over the one it found, and a sound with no clean loop plays gated.

A loop on the beat

Now a rhythm to keep in time. Tap on a table with your fingertips: eight taps, one to a beat, at a steady, unhurried speed of about 100 beats a minute. Leave a second of quiet before the first and after the last, and save it in the project folder as taps.wav.

A recording for this step is planned. Until then, use one of your own.

This time bring it in whole, as one sound, rather than cutting it into eight hits:

Example not checked: it is not run when this site is built.

$ subsample import taps.wav

subsample import trims the quiet from either end, measures the sound as it measures a capture, and files it beside your other sounds as taps.

Give the session a tempo, the speed Subsample keeps time at:

tempo:
  bpm: 120

tempo.bpm is in beats a minute. Left at 0, there is no tempo, and nothing is put on the beat. Then add the loop to the map, on a key of its own:

- name: Table loop
  channel: 1
  notes: G2
  select:
    where:
      name: taps
  process:
    - stretch_quantize: { grid: 16 }
  mode: loop

stretch_quantize moves each tap onto a grid laid out at the session's tempo, stretching the sound between taps without changing its pitch. grid: 16 puts every tap on the nearest sixteenth note, so taps played on the beat land on the beat. Subsample hears the tempo you tapped at, and stretches the whole sound from that to the session's, so your taps at 100 come out at 120.

With mode: loop, a sound put on the beat loops over its whole bars, from its first beat to the end of the bar that holds its last tap, counting four beats to a bar: two bars here. Whatever still rings past the end carries on under the next pass, so the join makes no click. Hold G2, and the taps go round, on the beat, for as long as you hold it; let go, and they fade out.

With a keyboard, a held note and a loop beside the kit, the next chapter gathers the kit into a map of its own: shorter, because its pads share a template, and kept with its samples in a folder that can travel.