Patterns of control maps, built as a chain of setters that TuningFork.Kit turns into voices.
import TuningFork.Pattern.Control
n("<0 4 0 9 7>*16") |> scale("g:minor") |> transpose(-12) |> octave(3) |> shape(:saw)
Summary
Functions
Set cutoff, resonance, lpenv, lpsustain and lpdecay together from one knob,
amount from 0.0 to 1.0. Any of them set later in the chain wins.
Attack, decay, sustain and release in one go. Any of them may be nil to leave that part of
the envelope as it was.
The note a voicing is placed against, as TuningFork.Pattern.Voicing.render/2's :anchor.
How long the note takes to reach full level, in seconds.
Which bank the sounds come from: s("bd") |> bank("crate") plays the recording registered
as crate_bd once TuningFork.Sample.Bank has it, as Strudel does, and until then the
kit's own drum, adjusted for a name in TuningFork.Kit.banks/0.
How narrow the bandpass is. See bpf/2.
A pattern of chord symbols, each as %{chord: symbol}, for voicing/1.
Hold every sample for every samples. 1 changes nothing.
How hard the bus is compressed, 0.0 for not at all and 1.0 for flat.
Round every sample to bits bits: 16 is untouched, 1 is a square.
Where the filter turns over, in hertz. Lower is darker.
How long it takes to fall from full level to sustain/2, in seconds.
How much of the note comes back as an echo, 0.0 to 1.0. delaytime/2 is how far behind, in
cycles, and delayfeedback/2 how much of each repeat survives into the next. The echoes are
the note played again, quieter; echoes/1 makes them.
How much of each echo survives into the next, 0.0 to 1.0. See delay/2.
How far behind the echoes fall, in cycles. Default an eighth. See delay/2.
Which voicing dictionary voicing/1 reads: one of TuningFork.Pattern.Voicing.dictionaries/0.
How hard to drive into a soft clipper, 0.0 for clean.
What a pattern has asked to be drawn as, or nil for nothing.
Move pattern earlier by amount cycles; a pattern of amounts applies each over its own span.
Turn every event carrying a :delay above zero into itself plus four echoes: the same event
:delaytime cycles later each time (default 0.125, capped at 0.5), with :gain scaled by
:delay and then by :delayfeedback per repeat (default 0.5, capped at 0.95), and :delay
removed. Any other event is passed straight through.
The four echoes an event carrying a :delay above zero makes, as echoes/1 places them,
and [] for any other event.
Frequency modulation depth, 0.0 upwards. fmh/2 sets the modulator's ratio to the note.
How much of the note the FM modulation takes to arrive, 0.0 to 1.0 of its length. Left out, the modulation is there from the first sample.
How high the modulator sits against the note, 1.0 being in unison. See fm/2.
Which kind of filter cutoff/2 makes: :lowpass (the default), :highpass or :bandpass,
as an atom or string.
How loud, 0.0 to 1.0.
Highpass filter amount, 0.0 to 1.0. Higher is thinner.
The same as highpass/2.
How much the highpass peaks at its corner. Applies to ftype(:highpass) with cutoff/2,
not to highpass/2.
Stack the pattern panned hard left with fun of it panned hard right.
jux/2 with the pattern panned to -amount and fun of it to amount: 1.0 is hard left
and right, 0.0 leaves both in the middle.
Move pattern later by amount cycles; a pattern of amounts applies each over its own span.
How long the filter sweep takes to open, in seconds. Default 0.002.
How long the filter sweep takes to fall back, in seconds. Default 0.2.
The same as cutoff/2.
The same as resonance/2.
How long the filter sweep takes to release. See lpenv/2.
Where the filter sweep settles, 0.0 to 1.0 of the way up. Default 0.0.
Keep only the events of pattern that fall where source is true.
A pattern from mini-notation: mini("bd*2 [~ sn]").
How a voicing sits against its anchor: :below, :above, :root or :duck, or a string
such as "root:g2" naming the anchor too.
Set the degree on an existing pattern's events, as set/3 does.
A pattern of notes, by name or by MIDI number. source is as for s/1; each value becomes
%{note: value}.
Set the note on an existing pattern's events, as set/3 does.
Which octave the scale sits in. Without one it is 3.
How many voicings along the dictionary's list voicing/1 moves.
Which bus this goes to, counting from zero. room/2, postgain/2, xfade/2 and
compressor/2 apply per bus.
Where in the stereo field, -1.0 left to 1.0 right.
Phaser rate: how many times a second the notches sweep. phaserdepth/2 says how far.
How far the phaser's notches travel, 0.0 to 1.0. Default 0.5. See phaser/2.
Mark this row to be drawn as a pianoroll. A row not marked is not drawn.
How loud the bus is after everything else, 0.0 upwards.
How long the note takes to fall silent after it ends, in seconds.
How much the filter peaks at its cutoff: 0.707 is flat, 8 is a howl.
How much reverb the bus is heard through, 0.0 to 1.0. The reverb is shared by every event on
the bus, and the loudest room asked for is the one applied. roomsize/2 says how big it is.
How long the room rings, in seconds to silence; 2 unless set. See room/2.
A pattern of sounds. source is mini-notation, a pattern, or a bare value; each value
becomes %{sound: value} unless it is already a map.
Set the sound on an existing pattern's events, as set/3 does: n("0 1") |> s("hh").
Which scale n/1's degrees are in, as "root:name"; TuningFork.Scale lists the roots and
names. Like every setter here, scale may be a plain value or a pattern; see set/3.
Mark this row to be drawn as an oscilloscope of the whole mix.
Merge the controls of other onto every event of pattern, keeping pattern's wholes: an
event is cut into parts where other changes inside it, each part carrying other's map
merged over the event's. Where other has nothing, the event is left alone.
Set control key on every event of a pattern.
The waveform: :sine, :saw, :square, :triangle or :noise. A number is Strudel's
shape, a waveshaper from 0.0 to below 1.0, and goes on :waveshape instead.
roomsize/2 under Strudel's shorter name.
How fast a sample or oscillator runs, 1.0 being as written: 2.0 is an octave up and half as long. A negative value is taken as its absolute value.
Keep the values of pattern but the structure of source: an event for every true step of
source, carrying the value pattern holds at that moment. x, t, 1 are true; ~,
f, 0 are not.
The level the note holds at after its decay, 0.0 to 1.0.
Move every note by semitones, up or down.
How hard the note is struck, 0.0 to 1.0. Multiplies gain/2.
Vibrato rate, in hertz. vibmod/2 says how far.
Vibrato depth, in semitones. Default half a semitone. See vib/2.
Turn a pattern of chord symbols into their notes, one event per note with the symbol's
timing and its other controls, as TuningFork.Pattern.Voicing.render/2 voices them under
the event's :dict, :anchor, :mode, :offset and :degree. A string is chord/1
first. A symbol the dictionary does not know is silent.
Filter the sound into a vowel: "a", "e", "i", "o" or "u", as a string or atom.
Fade between this bus and the rest: 0.0 none of it, 0.5 equal, 1.0 all of it.
Functions
@spec acid(TuningFork.Pattern.t(), number()) :: TuningFork.Pattern.t()
Set cutoff, resonance, lpenv, lpsustain and lpdecay together from one knob,
amount from 0.0 to 1.0. Any of them set later in the chain wins.
n("<0 4 0 9 7>*16") |> scale("g:minor") |> transpose(-12) |> shape(:saw) |> acid(0.55)
@spec adsr( TuningFork.Pattern.t(), number() | nil, number() | nil, number() | nil, number() | nil ) :: TuningFork.Pattern.t()
Attack, decay, sustain and release in one go. Any of them may be nil to leave that part of
the envelope as it was.
n("0 4") |> adsr(0.01, 0.1, 0.4, 0.2)
@spec anchor(TuningFork.Pattern.t(), String.t() | integer() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
The note a voicing is placed against, as TuningFork.Pattern.Voicing.render/2's :anchor.
@spec attack(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the note takes to reach full level, in seconds.
@spec bank(TuningFork.Pattern.t(), String.t() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which bank the sounds come from: s("bd") |> bank("crate") plays the recording registered
as crate_bd once TuningFork.Sample.Bank has it, as Strudel does, and until then the
kit's own drum, adjusted for a name in TuningFork.Kit.banks/0.
@spec bpf(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
A bandpass at this frequency, in hertz. cutoff/2 and ftype/2 in one.
@spec bpq(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How narrow the bandpass is. See bpf/2.
@spec chord(TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
A pattern of chord symbols, each as %{chord: symbol}, for voicing/1.
chord("<Bbm9 Fm9>/4") |> voicing()
@spec coarse(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Hold every sample for every samples. 1 changes nothing.
@spec compressor(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How hard the bus is compressed, 0.0 for not at all and 1.0 for flat.
@spec crush(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Round every sample to bits bits: 16 is untouched, 1 is a square.
@spec cutoff(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Where the filter turns over, in hertz. Lower is darker.
@spec decay(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long it takes to fall from full level to sustain/2, in seconds.
@spec delay(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much of the note comes back as an echo, 0.0 to 1.0. delaytime/2 is how far behind, in
cycles, and delayfeedback/2 how much of each repeat survives into the next. The echoes are
the note played again, quieter; echoes/1 makes them.
s("bd rim") |> delay(0.5) |> delaytime(0.125) |> delayfeedback(0.6)
@spec delayfeedback(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much of each echo survives into the next, 0.0 to 1.0. See delay/2.
@spec delaytime(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How far behind the echoes fall, in cycles. Default an eighth. See delay/2.
@spec dict(TuningFork.Pattern.t(), atom() | String.t() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which voicing dictionary voicing/1 reads: one of TuningFork.Pattern.Voicing.dictionaries/0.
@spec distort(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How hard to drive into a soft clipper, 0.0 for clean.
@spec drawing(TuningFork.Pattern.t()) :: :pianoroll | :scope | nil
What a pattern has asked to be drawn as, or nil for nothing.
iex> TuningFork.Pattern.Control.drawing(TuningFork.Pattern.Control.s("bd"))
nil
iex> TuningFork.Pattern.Control.drawing(TuningFork.Pattern.Control.scope(TuningFork.Pattern.Control.s("bd")))
:scope
@spec early( TuningFork.Pattern.t() | String.t(), number() | TuningFork.Pattern.t() | String.t() ) :: TuningFork.Pattern.t()
Move pattern earlier by amount cycles; a pattern of amounts applies each over its own span.
@spec echoes(TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Turn every event carrying a :delay above zero into itself plus four echoes: the same event
:delaytime cycles later each time (default 0.125, capped at 0.5), with :gain scaled by
:delay and then by :delayfeedback per repeat (default 0.5, capped at 0.95), and :delay
removed. Any other event is passed straight through.
@spec echoes_of(TuningFork.Pattern.event()) :: [TuningFork.Pattern.event()]
The four echoes an event carrying a :delay above zero makes, as echoes/1 places them,
and [] for any other event.
@spec fm(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Frequency modulation depth, 0.0 upwards. fmh/2 sets the modulator's ratio to the note.
note("c3") |> fm(3) |> fmh(2)
@spec fmattack(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much of the note the FM modulation takes to arrive, 0.0 to 1.0 of its length. Left out, the modulation is there from the first sample.
@spec fmh(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How high the modulator sits against the note, 1.0 being in unison. See fm/2.
@spec ftype(TuningFork.Pattern.t(), atom() | String.t() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which kind of filter cutoff/2 makes: :lowpass (the default), :highpass or :bandpass,
as an atom or string.
@spec gain(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How loud, 0.0 to 1.0.
@spec highpass(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Highpass filter amount, 0.0 to 1.0. Higher is thinner.
@spec hpf(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
The same as highpass/2.
@spec hpq(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much the highpass peaks at its corner. Applies to ftype(:highpass) with cutoff/2,
not to highpass/2.
@spec jux(TuningFork.Pattern.t(), (TuningFork.Pattern.t() -> TuningFork.Pattern.t())) :: TuningFork.Pattern.t()
Stack the pattern panned hard left with fun of it panned hard right.
s("bd*4") |> jux(&rev/1)
@spec jux_by(TuningFork.Pattern.t(), number(), (TuningFork.Pattern.t() -> TuningFork.Pattern.t())) :: TuningFork.Pattern.t()
jux/2 with the pattern panned to -amount and fun of it to amount: 1.0 is hard left
and right, 0.0 leaves both in the middle.
@spec late( TuningFork.Pattern.t() | String.t(), number() | TuningFork.Pattern.t() | String.t() ) :: TuningFork.Pattern.t()
Move pattern later by amount cycles; a pattern of amounts applies each over its own span.
@spec lpattack(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the filter sweep takes to open, in seconds. Default 0.002.
@spec lpdecay(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the filter sweep takes to fall back, in seconds. Default 0.2.
@spec lpenv(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Octaves the filter sweeps above cutoff/2 over the note, falling away over lpdecay/2.
@spec lpf(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
The same as cutoff/2.
@spec lpq(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
The same as resonance/2.
@spec lprelease(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the filter sweep takes to release. See lpenv/2.
@spec lpsustain(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Where the filter sweep settles, 0.0 to 1.0 of the way up. Default 0.0.
@spec mask(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t()) :: TuningFork.Pattern.t()
Keep only the events of pattern that fall where source is true.
s("bd*8") |> mask("1 0 1 1")
@spec mini(String.t()) :: TuningFork.Pattern.t()
A pattern from mini-notation: mini("bd*2 [~ sn]").
@spec mode(TuningFork.Pattern.t(), atom() | String.t() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How a voicing sits against its anchor: :below, :above, :root or :duck, or a string
such as "root:g2" naming the anchor too.
@spec n(TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
A pattern of scale degrees, 0 being the root of the scale/2 ("c:major" without one).
source is as for s/1; each value becomes %{degree: value}.
iex> TuningFork.Pattern.first_cycle(TuningFork.Pattern.Control.n("0 4"))
[{0.0, 0.5, %{degree: 0}}, {0.5, 1.0, %{degree: 4}}]
@spec n(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
Set the degree on an existing pattern's events, as set/3 does.
@spec note(TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
A pattern of notes, by name or by MIDI number. source is as for s/1; each value becomes
%{note: value}.
iex> TuningFork.Pattern.first_cycle(TuningFork.Pattern.Control.note("c3 g3"))
[{0.0, 0.5, %{note: "c3"}}, {0.5, 1.0, %{note: "g3"}}]
@spec note(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
Set the note on an existing pattern's events, as set/3 does.
@spec octave(TuningFork.Pattern.t(), integer() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which octave the scale sits in. Without one it is 3.
@spec offset(TuningFork.Pattern.t(), integer() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How many voicings along the dictionary's list voicing/1 moves.
@spec orbit(TuningFork.Pattern.t(), non_neg_integer() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which bus this goes to, counting from zero. room/2, postgain/2, xfade/2 and
compressor/2 apply per bus.
@spec pan(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Where in the stereo field, -1.0 left to 1.0 right.
@spec phaser(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Phaser rate: how many times a second the notches sweep. phaserdepth/2 says how far.
@spec phaserdepth(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How far the phaser's notches travel, 0.0 to 1.0. Default 0.5. See phaser/2.
@spec pianoroll(TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Mark this row to be drawn as a pianoroll. A row not marked is not drawn.
n("<0 4 0 9 7>*16") |> scale("g:minor") |> acid(0.55) |> pianoroll()
@spec postgain(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How loud the bus is after everything else, 0.0 upwards.
@spec release(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the note takes to fall silent after it ends, in seconds.
@spec resonance(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much the filter peaks at its cutoff: 0.707 is flat, 8 is a howl.
@spec room(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How much reverb the bus is heard through, 0.0 to 1.0. The reverb is shared by every event on
the bus, and the loudest room asked for is the one applied. roomsize/2 says how big it is.
@spec roomsize(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How long the room rings, in seconds to silence; 2 unless set. See room/2.
@spec s(TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
A pattern of sounds. source is mini-notation, a pattern, or a bare value; each value
becomes %{sound: value} unless it is already a map.
iex> TuningFork.Pattern.first_cycle(TuningFork.Pattern.Control.s("bd sn"))
[{0.0, 0.5, %{sound: "bd"}}, {0.5, 1.0, %{sound: "sn"}}]
@spec s(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t() | term()) :: TuningFork.Pattern.t()
Set the sound on an existing pattern's events, as set/3 does: n("0 1") |> s("hh").
@spec scale(TuningFork.Pattern.t(), String.t() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Which scale n/1's degrees are in, as "root:name"; TuningFork.Scale lists the roots and
names. Like every setter here, scale may be a plain value or a pattern; see set/3.
@spec scope(TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Mark this row to be drawn as an oscilloscope of the whole mix.
s("bd!4") |> scope()
@spec set(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t()) :: TuningFork.Pattern.t()
Merge the controls of other onto every event of pattern, keeping pattern's wholes: an
event is cut into parts where other changes inside it, each part carrying other's map
merged over the event's. Where other has nothing, the event is left alone.
n("0 4") |> set(chord("Bbm9")) |> voicing()
@spec set(TuningFork.Pattern.t(), atom(), term()) :: TuningFork.Pattern.t()
Set control key on every event of a pattern.
value is a plain term, a pattern, or a mini-notation string. A pattern keeps the event's
whole and cuts it into parts where the pattern changes inside it, as Pattern.app_left/3;
where it has nothing the event is left out. An event whose value is not yet a map becomes
%{key => value, sound: old_value}.
@spec shape( TuningFork.Pattern.t(), atom() | number() | String.t() | TuningFork.Pattern.t() ) :: TuningFork.Pattern.t()
The waveform: :sine, :saw, :square, :triangle or :noise. A number is Strudel's
shape, a waveshaper from 0.0 to below 1.0, and goes on :waveshape instead.
@spec size(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
roomsize/2 under Strudel's shorter name.
@spec speed(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How fast a sample or oscillator runs, 1.0 being as written: 2.0 is an octave up and half as long. A negative value is taken as its absolute value.
@spec struct(TuningFork.Pattern.t(), TuningFork.Pattern.t() | String.t()) :: TuningFork.Pattern.t()
Keep the values of pattern but the structure of source: an event for every true step of
source, carrying the value pattern holds at that moment. x, t, 1 are true; ~,
f, 0 are not.
s("bd") |> struct("x ~ x ~")
@spec sustain(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
The level the note holds at after its decay, 0.0 to 1.0.
@spec transpose(TuningFork.Pattern.t(), integer() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Move every note by semitones, up or down.
@spec velocity(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
How hard the note is struck, 0.0 to 1.0. Multiplies gain/2.
@spec vib(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Vibrato rate, in hertz. vibmod/2 says how far.
@spec vibmod(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Vibrato depth, in semitones. Default half a semitone. See vib/2.
@spec voicing(TuningFork.Pattern.t() | String.t()) :: TuningFork.Pattern.t()
Turn a pattern of chord symbols into their notes, one event per note with the symbol's
timing and its other controls, as TuningFork.Pattern.Voicing.render/2 voices them under
the event's :dict, :anchor, :mode, :offset and :degree. A string is chord/1
first. A symbol the dictionary does not know is silent.
chord("<C^7 Dm7 G7>") |> voicing() |> shape(:saw)
@spec vowel(TuningFork.Pattern.t(), String.t() | atom() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Filter the sound into a vowel: "a", "e", "i", "o" or "u", as a string or atom.
@spec xfade(TuningFork.Pattern.t(), number() | TuningFork.Pattern.t()) :: TuningFork.Pattern.t()
Fade between this bus and the rest: 0.0 none of it, 0.5 equal, 1.0 all of it.