Subsystem Search

How Subsample hears a sound

By the end of this chapter, you can read what Subsample heard in any of your samples, see which of them it ranks closest to each drum, and choose a drum's sound by a recording of your own.

The project so far

The project from A drum kit from a recording: the folder subsample --init made, with the player on and the recorder off, and the samples Subsample cut from your recording in samples/captures/.

$ mkdir kitchen-kit
$ cd kitchen-kit
$ subsample --init
…
recorder:
  enabled: false
player:
  midi_map: midi-map-gm-drums.yaml
  enabled: true

What it measures

Subsample measures every sample as it saves it, and keeps what it measured beside it, in the sample's .analysis.json. The measures fall into a few kinds: how loud the sound is, and how that moves; how bright it is and how noisy; how it starts and how it dies away; how its energy divides between the low and the high spectral bands; and its pitch, where it holds a steady one.

subsample analyze prints them for any sound:

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

$ subsample analyze samples/captures/hits_1.wav

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

Each line is one kind of measure. spectral gives most of them as a number from 0 to 1: centroid is how bright a sound is, from 0, bassy, to 1, bright, and flatness how noisy, from 0, a tone, to 1, noise. level gives the peak and the loudness in dBFS, and pitch a pitch in Hz where there is a steady one. Run it on one of your thuds and one of your ticks and compare them: the lines are the same, and the numbers are how Subsample tells the two apart. The command's reference says what every line means.

How alike two sounds are

To choose a sample for a drum, Subsample compares what it measured in each of your samples with the same measures of a reference, a sound that stands for that drum. It carries a reference for every General MIDI drum, measured from a General MIDI sound font, and only the measures ship with it, not the sounds. How alike a sample and a reference are is one number, where 1 would be the same sound.

The comparison is the same for any sound, a held note as much as a drum. Nothing sorts a sound into a kind first, and nothing is trained: a kick scores high on its attack and a bowed string on its sustained timbre, so a reference of a string finds your most string-like sounds as the kick's finds your thuds.

subsample similar lists, for each reference, your samples most like it, best first:

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

$ subsample similar

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

Each reference is named for its note and its drum, GM36_BassDrum1 for the kick on note 36, and under it are your closest samples, each with how alike it is and its file. The kit plays the first sample under each drum's reference. Look under the kick's for one of your thuds, and under the closed hi-hat's, GM42_ClosedHiHat, for one of your ticks. The sound you struck three or four times alike sits together, its strikes one after another. subsample similar shows more than five with --top.

Name one sound, and it lists your samples most like that sound instead, which is how to find more like a snare you are pleased with:

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

$ subsample similar hits_3

The sound can be a sample in the library, by its name, or an audio file anywhere, which Subsample measures on the spot, keeping what it measured beside the file, as it does for a sample.

A reference of your own

The kit's kick is the sample most like its General MIDI kick. To have it be the sample most like a kick you choose, give the kick a reference of your own: a recording of one hit, such as a kick drum you like, saved in the project as references/my-kick.wav.

Then point the kit's kick at it. In midi-map-gm-drums.yaml, find the entry named Kick 1 (Bass Drum 1), which plays note 36, and change its reference to the file's path:

- name: Kick 1 (Bass Drum 1)
  notes: drum.kick_1
  select:
    where:
      reference: references/my-kick.wav
    order: [{ by: similarity, dir: desc }]
  process:
    - filter_high: { freq: 30 }
    - filter_low: { freq: 8000 }
    - compress: { ratio: 6, attack: 15 }

Only the reference line changes, and the rest is the entry as the kit has it. A path is found from the map's own folder, and the first time Subsample starts with it, it measures the file and keeps what it measured beside it, as it does for a sample. The reference entry has the rest.

A folder of references of your own can stand in for the whole built-in set: library.reference_directory names it. Its references then replace the built-in ones, so a name the kit uses, such as GM36_BassDrum1, resolves only if your folder has a reference of that name.

What counts most

When it compares two sounds, Subsample weighs a few groups of measures: the sound's overall character, its timbre as it holds and as it changes, its attack, and how its energy divides between the spectral bands. The configuration's similarity section sets how much each group counts.

In a drum kit, the attack is what tells a kick from a snare from a hi-hat, so count it for more. The section is in config.yaml only as comments, so add it at the end of the file:

similarity:
  weight_timbre_onset: 2

similarity.weight_timbre_onset is the attack's weight, and 0 leaves the attack out of the comparison altogether. Run subsample similar again: every number moves, and where two of your samples were close for a drum, the one whose attack is more like the drum's comes first.

With a kit you can read and steer, the next chapter records live, from a microphone in the room, and sets Subsample to hear that room.