TuningFork.Kit (TuningFork v0.1.11)

Copy Markdown View Source

Names to voices: voice/2 turns a drum name, a note name, a MIDI number, hertz or a map of controls into a TuningFork.Voice.

iex> %TuningFork.Voice{} = TuningFork.Kit.voice("bd", 0.25)
iex> TuningFork.Kit.voice("nothing here", 0.25)
nil

Summary

Functions

The sound banks voice/2 knows, sorted.

The drum names voice/2 knows, sorted.

The drum names grouped by what they are, short name first.

A voice from a map of controls.

A sound as a TuningFork.Part instrument: a function that gives voice/3 of %{sound: name, note: note} for each note it is asked for, and of %{sound: name} for nil. opts are voice/3's and controls any other controls to play it with.

Whether voice/3 plays name as a sound rather than a pitch: a drum, a waveform, a GM instrument or a loaded bank, with or without an index after a colon.

The MIDI note a value stands for, or nil when it is not a pitch.

Every note name voice/2 takes, low to high.

Start fetching, in the background, every recording and soundfont the values would play. Values are what voice/3 takes; anything else is skipped. Returns at once.

The voice for value, lasting seconds.

Functions

banks()

@spec banks() :: [String.t()]

The sound banks voice/2 knows, sorted.

iex> "RolandTR909" in TuningFork.Kit.banks()
true

These are adjustments to the drums this kit synthesises, so bank("RolandTR808") gives the long booming kick that name is known for while the recording registered as RolandTR808_bd has not arrived, or where there is none. A name not here changes nothing, so a pattern written for a bank that is not loaded still plays.

drums()

@spec drums() :: [String.t()]

The drum names voice/2 knows, sorted.

families()

@spec families() :: keyword([[String.t()]])

The drum names grouped by what they are, short name first.

iex> TuningFork.Kit.families() |> Keyword.keys()
[:kick, :snare, :hat, :tom, :cymbal, :percussion]

Names in the same group make the same sound; "bd" and "kick" are one entry.

from_map(controls, seconds, opts \\ [])

@spec from_map(map(), number(), keyword()) :: TuningFork.Voice.t() | nil

A voice from a map of controls.

:sound or :note says what to play and is passed to voice/2; every other key changes the voice that comes back. A map with neither is nil. A :bank plays the recording registered as bank_sound when TuningFork.Sample.Bank has one, and is otherwise an adjustment to the kit's drum (banks/0). A bank the kit does not have starts TuningFork.Strudel.defaults/1, the sets such names come from: with wait: true (the default) the voice waits for them, with wait: false it is the kit's drum this time.

instrument(name, seconds \\ 0.5, controls \\ %{}, opts \\ [])

@spec instrument(String.t(), number(), map(), keyword()) ::
  TuningFork.Part.instrument()

A sound as a TuningFork.Part instrument: a function that gives voice/3 of %{sound: name, note: note} for each note it is asked for, and of %{sound: name} for nil. opts are voice/3's and controls any other controls to play it with.

part(bpm: 100, synth: TuningFork.Kit.instrument("gm_flute", 0.5))
|> play(:a4, 1)

known?(name)

@spec known?(String.t()) :: boolean()

Whether voice/3 plays name as a sound rather than a pitch: a drum, a waveform, a GM instrument or a loaded bank, with or without an index after a colon.

iex> TuningFork.Kit.known?("gm_epiano1:2")
true
iex> TuningFork.Kit.known?("c4")
false

midi(controls)

@spec midi(term()) :: integer() | nil

The MIDI note a value stands for, or nil when it is not a pitch.

iex> TuningFork.Kit.midi(%{degree: 4, scale: "g:minor"})
62
iex> TuningFork.Kit.midi(%{sound: "bd"})
nil

A note may be a name as a string or atom, a MIDI number, or a map of controls carrying :note or :degree. A drum name has no pitch, so it is nil. :octave moves the root — 3 is where a scale sits without one — and :transpose adds semitones after everything else.

notes()

@spec notes() :: [String.t()]

Every note name voice/2 takes, low to high.

A name is a letter, s for sharp or b for flat, and an octave: c3, fs4, eb2.

prefetch(values)

@spec prefetch([term()]) :: :ok

Start fetching, in the background, every recording and soundfont the values would play. Values are what voice/3 takes; anything else is skipped. Returns at once.

voice(value, seconds, opts \\ [])

@spec voice(term(), number(), keyword()) :: TuningFork.Voice.t() | nil

The voice for value, lasting seconds.

Returns nil for a value naming nothing, so a pattern carrying words this kit does not have plays the ones it does rather than failing.

Options

  • :wait — whether to wait for a recording still being fetched from the web, default true; with false such a value is nil this time and the fetch carries on behind