Subsystem Search

A kit of your own

By the end of this chapter, your kit is a map of its own, short because its pads share their settings, kept in a folder with its sounds, which you can copy anywhere and play.

The project so far

The project from Pitched instruments and loops: your own map, watched as it plays, with a kick, a snare and a hi-hat shaped on the way out, a keyboard and a held note from one recorded note, and a loop you tapped, kept on the beat.

$ 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
tempo:
  bpm: 120
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 }
  - name: Glass keys
    channel: 1
    notes: C3..C6
    select:
      where:
        name: note_1
    process:
      - repitch: true
    mode: gated
  - name: Glass drone
    channel: 1
    notes: C2
    select:
      where:
        name: note_1
    mode: loop
  - name: Table loop
    channel: 1
    notes: G2
    select:
      where:
        name: taps
    process:
      - stretch_quantize: { grid: 16 }
    mode: loop

A folder for the kit

Until now, your map has chosen from every sound in samples/captures/. A kit of your own keeps its sounds in a folder with it: make a folder kits/kitchen/ in the project, and inside it a folder for each pad, kick, snare, layer, hat and open-hat.

Then move each sound into the folder of the pad it should play: your thuds into kick, your cracks into snare, your ticks into hat, the ring you recorded in Recording well into open-hat, and a second crack or a clap into layer, to play under the snare. Each sound in samples/captures/ has two files beside it that share its name, what Subsample measured and a picture of it, and they move with it:

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

$ mkdir -p kits/kitchen/kick kits/kitchen/snare kits/kitchen/layer kits/kitchen/hat kits/kitchen/open-hat
$ mv samples/captures/hits_1.wav* kits/kitchen/kick/

A map for the kit

The kit's map lives in its folder too. Point the player at it:

player:
  midi_map: kits/kitchen/midi-map.yaml

The keyboard, the held note and the loop stay in midi-map.yaml, which the player no longer plays. Write the kit's map, as kits/kitchen/midi-map.yaml:

channel: 10
templates:
  pad:
    process:
      - compress: true
assignments:
  - name: Kick
    template: pad
    notes: drum.kick_1
    select: { where: { directory: kick }, pick: any }
  - name: Snare
    template: pad
    notes: drum.snare_1
    select: { where: { directory: snare }, pick: any }
  - name: Closed hi-hat
    template: pad
    notes: drum.hi_hat_closed
    select: { where: { directory: hat }, pick: any }

Start Subsample again, since it loads a folder's sounds when it starts.

How a template merges

A pad starts from its template's settings, and its own win. A setting the pad writes replaces the template's whole, with nothing merged inside it: a pad with a process of its own loses the template's compressor rather than adding to it. A template cannot name a template of its own, and a pad that names a template the map does not have is refused, with the list of those it does.

A pad can name several templates, and each later one overrides the one before it. Add a second template, for a sound played quieter:

templates:
  pad:
    process:
      - compress: true
  quiet:
    gain: -6

Two sounds on one pad

A pad can play two sounds at once. Give the snare a layer, from the layer folder, 6 dB quieter:

- name: Snare
  template: pad
  notes: drum.snare_1
  select: { where: { directory: snare }, pick: any }
  stack: true
- name: Snare layer
  template: [pad, quiet]
  notes: drum.snare_1
  select: { where: { directory: layer }, pick: any }
  stack: true

stack lets a pad sound together with another on the same note, and every pad on that note must set it, or the map is refused. template: [pad, quiet] takes the compressor from pad and the lower gain from quiet.

A closed hat that cuts an open one

On a drum kit, closing the hi-hat stops its open ring. Add the open hi-hat, and have the closed one cut it short:

- name: Open hi-hat
  template: pad
  notes: drum.hi_hat_open
  select: { where: { directory: open-hat }, pick: any }
  silenced_by: drum.hi_hat_closed

Play the open hat and let it ring, then the closed one: the ring stops. silenced_by names the notes on the same MIDI channel that cut a sound short, with a quick damp, and self has a new strike of a sound cut the last.

A kit that travels

Nothing marks kits/kitchen/ as a kit that can travel. It is one because every path its map writes is found from the map's own folder, and a reference, where a pad uses one, names one of the fingerprints Subsample carries. So the folder holds all it needs: copy it to another project, or another machine, and it plays as it does here. Nor need it be copied: one copy on a shared or network drive can be played in place by several projects, each naming its map by its full path. Subsample calls such a folder a sample set. Its channel lets a project play it on whatever MIDI channel suits, without editing it.

A set can hold several maps over the same sounds, a full kit and one of just kick and snare, say, and a project plays whichever it names.

Names of your own

A map can call a note, a controller or a MIDI channel by a name of your own, kept in a definitions file. A sequencer that reads the same file plays your kit by the same names, and a pad moved to another note moves in one place. Subsequence, Subsample's sister project, an algorithmic MIDI sequencer for Python, reads it. Save this beside the map, as kits/kitchen/names.yaml:

notes:
  kick: 36
  snare: 38
  hat: 42
  open_hat: 46
cc:
  brightness: 74
channels:
  kit: 10

Then mount it in the map, under a prefix of your choosing, and use its names:

definitions: { my: names.yaml }
channel: my.kit
- name: Kick
  template: pad
  notes: my.kick
  select: { where: { directory: kick }, pick: any }

definitions mounts each file under a prefix, here my, found from the map's own folder, and my.kick then works anywhere the map takes a note, as drum.kick_1 does; drum is kept for the General MIDI names. my.brightness works wherever the map takes a controller, such as the knob in Shaping a sound on the way out. The definitions file can name programs too.

With the kit in a folder of its own, the next chapter looks after the library it came from: new sounds loading while Subsample runs, a folder of sounds imported, and near-duplicates found and thinned.