Sonic Pi's vocabulary: play, sleep, sample, live_loop, with_fx and the rest.
use TuningFork.SonicPi
live_loop :bells do
sample :perc_bell, rate: rrand(0.125, 1.5)
sleep rrand(0, 2)
end
Summary
Functions
Run a block time beats from now, alongside: at 4 do … end, or at [1, 2], [:a, :b], fn arg -> … end
to run it at each time with the matching argument. On a TuningFork.Part, at/2 is the part's.
Numbers as booleans: zero is false.
A block as a buffer: buffer do … end gives the Buffer for render/4 or play_buffer/2.
Run fun as a buffer: what it plays at the top level becomes the score, and every
live_loop it starts is collected. Returns what run/1 returns.
One element of list, or a TuningFork.Part choice when the first argument is a part.
The notes of a chord — chord(:e3, :minor) — or a TuningFork.Part chord when the first argument is a part.
A chord on the degreeth note of a scale: count notes, every other step. invert: as chord/3.
Skip a block: comment do … end.
Change a sounding note or an open effect from this moment on.
Tell every loop that name has happened, as of this round, with data for sync/1 to read.
The degreeth note of scale_name from tonic, counting from 1.
Run a block count times at count times the tempo: density 2 do … end.
A whole number from 1 to sides, default 6.
Whether number divides by factor exactly.
The TuningFork.SonicPi.Effects names, for with_fx/3.
Silence a stage: every loop, pattern and sounding voice stopped. TuningFork.Stage by default.
A MIDI number for hertz.
Run a block alongside: in_thread do … end. It starts now and the thread's own time does not move. Options such as name: are accepted and ignored.
Values repeated: knit(:a, 2, :b, 1) is [:a, :a, :b].
steps numbers from from towards to, excluding to unless inclusive: true.
Start a named loop that is worked out again every time round: live_loop :name do … end.
Read a sample into memory ahead of playing it. A family atom loads the whole family.
load_sample/1 for each of a list, or for one.
What the last tick gave, without stepping: look(), look(:name), look(list).
A loop with no name: loop do … end, the same as live_loop under a name of its own.
Hertz for a MIDI number.
list followed by itself backwards without repeating the last element.
The MIDI number of a note, or nil for nil; octave: moves it to that octave.
root and the same note in the count - 1 octaves above, as MIDI numbers.
True one time in n.
count independent choices from list, or a TuningFork.Part pick when the first argument is a part.
Sound a note, or a TuningFork.Part note when the first argument is a part.
Start a buffer on a stage: its score once, and each of its loops round and round.
Sound every note of notes at once.
Sound notes one after another, a beat apart.
Sound notes one after another, each followed by the matching entry of times in beats.
Accepted and ignored; a loop cannot print.
Accepted and ignored; a loop cannot print.
A float from 0 up to max, default 1; a range gives one between its ends.
A whole number from 0 up to but not including max.
Numbers from from up to but not including to, step apart.
list followed by itself backwards.
Render a buffer to PCM for seconds, its loops going round and its score playing once.
The element of list at index, wrapping in both directions.
list with its first count elements moved to the end.
A float from low up to high, from the thread's generator; res: rounds it to a step.
A whole number from low to high, both included.
Read a buffer of Sonic Pi-shaped source.
Run fun as one round of a loop and give the score it played. See TuningFork.SonicPi.Blocks.run_round/1.
Sound a recording: a name from TuningFork.Sample.Bank, a path, or a TuningFork.Sample.
How long sample/2 would sound name for with opts, in seconds.
Every bank sample name, or those in one family: sample_names(:ambi).
The notes of a scale, one octave up from root and the octave note above.
list in a random order.
Move the thread on by beats. Outside a round, with a stage running, this waits that long.
hits beats spread as evenly as they go over steps, as booleans — a Euclidean rhythm.
End the round here. Nothing after it is played.
Each element of list repeated count times in place.
Wait for name to have been cued, and give what it was cued with.
Sound a note with a named synth without changing the thread's, or set a part's synth.
The TuningFork.SonicPi.Synth names, for use_synth/1.
Step a counter and give what it was, or the element of a list that count picks.
Put the default counter, or the named one, back to zero.
Put every counter back to zero.
Put a counter at count, so look gives count and the next tick gives one more.
Run a block count times: times 4 do … end, or times(4, fn pass -> … end) to be told which pass.
Run a block as it is: uncomment do … end.
Beats a minute for everything after this point in the thread. Default 60.
Accepted and ignored; there is no debug output to switch.
Options every play/2 from here on starts from, merged over the ones there already.
Seed the thread's generator, so what follows draws the same numbers every time.
Set the tempo so that name lasts num_beats: beats, default 1.
Options every sample/2 from here on starts from.
The synth play/2 uses from here on: a name from TuningFork.SonicPi.Synth.names/0, a
TuningFork.Voice, or a sound name TuningFork.Kit.known?/1 accepts, such as "gm_epiano1",
played at each note through the kit.
Options every play/2 from here on starts from. A play option overrides one here.
Semitones added to every note from here on.
Run a block at bpm, then go back to the tempo before: with_bpm 120 do … end.
Run a block with everything it plays going through an effect: with_fx :reverb, mix: 0.3 do … end.
Run a block with the generator seeded from seed, then carry on from where it was.
Run a block with another synth, then go back: with_synth :saw do … end.
Run a block with other synth defaults, then go back.
Run a block transposed by semitones, then go back: with_transpose 12 do … end.
Functions
Run a block time beats from now, alongside: at 4 do … end, or at [1, 2], [:a, :b], fn arg -> … end
to run it at each time with the matching argument. On a TuningFork.Part, at/2 is the part's.
@spec bools( number(), number(), number(), number(), number(), number(), number(), number() ) :: [ boolean() ]
Numbers as booleans: zero is false.
A block as a buffer: buffer do … end gives the Buffer for render/4 or play_buffer/2.
Raises ArgumentError when a loop in it will not run.
@spec capture((-> term())) :: {:ok, TuningFork.SonicPi.Buffer.t()} | {:error, String.t()}
Run fun as a buffer: what it plays at the top level becomes the score, and every
live_loop it starts is collected. Returns what run/1 returns.
One element of list, or a TuningFork.Part choice when the first argument is a part.
@spec chord(term(), atom() | String.t() | [term()], keyword() | number()) :: [term()] | TuningFork.Part.t()
The notes of a chord — chord(:e3, :minor) — or a TuningFork.Part chord when the first argument is a part.
A chord on the degreeth note of a scale: count notes, every other step. invert: as chord/3.
Skip a block: comment do … end.
@spec control(TuningFork.SonicPi.Handle.t(), keyword()) :: :ok
Change a sounding note or an open effect from this moment on.
On a note, :note, :amp and :cutoff move to the new value — at once, or over
:note_slide, :amp_slide or :cutoff_slide seconds. On an effect, the options given
replace the ones it was opened with for everything played afterwards.
Tell every loop that name has happened, as of this round, with data for sync/1 to read.
The degreeth note of scale_name from tonic, counting from 1.
Run a block count times at count times the tempo: density 2 do … end.
@spec dice(pos_integer()) :: integer()
A whole number from 1 to sides, default 6.
Whether number divides by factor exactly.
@spec fx_names() :: [atom()]
The TuningFork.SonicPi.Effects names, for with_fx/3.
@spec hush(GenServer.server()) :: :ok
Silence a stage: every loop, pattern and sounding voice stopped. TuningFork.Stage by default.
A MIDI number for hertz.
Run a block alongside: in_thread do … end. It starts now and the thread's own time does not move. Options such as name: are accepted and ignored.
@spec knit( term(), non_neg_integer(), term(), non_neg_integer(), term(), non_neg_integer(), term(), non_neg_integer() ) :: [term()]
Values repeated: knit(:a, 2, :b, 1) is [:a, :a, :b].
steps numbers from from towards to, excluding to unless inclusive: true.
Start a named loop that is worked out again every time round: live_loop :name do … end.
Takes a do block or a fn, and an optional keyword list with :stage, :delay beats,
:sync another loop's name, :auto_cue. On a stage this returns :ok or
{:error, message}; inside run/1 or buffer/1 the loop is collected.
Read a sample into memory ahead of playing it. A family atom loads the whole family.
load_sample/1 for each of a list, or for one.
@spec look() :: non_neg_integer()
What the last tick gave, without stepping: look(), look(:name), look(list).
A loop with no name: loop do … end, the same as live_loop under a name of its own.
Hertz for a MIDI number.
list followed by itself backwards without repeating the last element.
The MIDI number of a note, or nil for nil; octave: moves it to that octave.
@spec octs(term(), pos_integer()) :: [integer()]
root and the same note in the count - 1 octaves above, as MIDI numbers.
@spec one_in(pos_integer()) :: boolean()
True one time in n.
@spec pick([term()] | TuningFork.Part.t(), non_neg_integer() | [term()]) :: [term()] | {[term()], TuningFork.Part.t()}
count independent choices from list, or a TuningFork.Part pick when the first argument is a part.
@spec play(term(), keyword()) :: TuningFork.SonicPi.Handle.t()
Sound a note, or a TuningFork.Part note when the first argument is a part.
note is a MIDI number, a name, hertz as a float, a list for a chord, or nil for
nothing. opts are TuningFork.SonicPi.Synth's. Returns a Handle for control/2.
@spec play_buffer(String.t() | TuningFork.SonicPi.Buffer.t(), GenServer.server()) :: :ok | {:error, String.t()}
Start a buffer on a stage: its score once, and each of its loops round and round.
Takes source or a Buffer. Returns :ok, or {:error, message} for source that will not
read.
@spec play_chord([term()], keyword()) :: TuningFork.SonicPi.Handle.t()
Sound every note of notes at once.
Sound notes one after another, a beat apart.
Sound notes one after another, each followed by the matching entry of times in beats.
times is a list read round and round, or one number for every note.
@spec print(term()) :: :ok
Accepted and ignored; a loop cannot print.
@spec puts(term()) :: :ok
Accepted and ignored; a loop cannot print.
A float from 0 up to max, default 1; a range gives one between its ends.
@spec rand_i(pos_integer()) :: integer()
A whole number from 0 up to but not including max.
Numbers from from up to but not including to, step apart.
A negative step counts down. step may also be a keyword list: step: 0.5, or
steps: 8 for eight numbers evenly spaced.
list followed by itself backwards.
@spec render( String.t() | TuningFork.SonicPi.Buffer.t(), pos_integer(), number(), keyword() ) :: binary()
Render a buffer to PCM for seconds, its loops going round and its score playing once.
opts take :channels, default 2, and :limit, where peaks are rounded off as
TuningFork.Stage does, default 0.7; nil for none. Raises ArgumentError for source that
will not read.
A list, read round and round by tick/1, look/1 and ring_at/2.
The element of list at index, wrapping in both directions.
list with its first count elements moved to the end.
A float from low up to high, from the thread's generator; res: rounds it to a step.
A whole number from low to high, both included.
@spec run(String.t()) :: {:ok, TuningFork.SonicPi.Buffer.t()} | {:error, String.t()}
Read a buffer of Sonic Pi-shaped source.
Top-level code becomes score, or nil when nothing was played at the top level; every
live_loop becomes {name, first_round, body}, where body gives a fresh round each call
as TuningFork.Stage.start_loop/4 wants. {:error, message} when the source will not
read or a loop will not run, naming the loop.
@spec run_round((-> term())) :: {:ok, TuningFork.Score.t()} | {:error, String.t()}
Run fun as one round of a loop and give the score it played. See TuningFork.SonicPi.Blocks.run_round/1.
@spec sample(atom() | String.t() | TuningFork.Sample.t(), keyword()) :: TuningFork.SonicPi.Handle.t()
Sound a recording: a name from TuningFork.Sample.Bank, a path, or a TuningFork.Sample.
Options
:rate— speed and pitch together, 1 as recorded, negative backwards:rpitch— the same as a number of semitones:beat_stretch— a rate that makes it last this many beats:start,:finish— the part to play, as fractions from 0 to 1:amp,:pan,:attack,:decay,:sustain,:release,:cutoff,:res— asplay/2
Raises ArgumentError for a name the bank does not have.
@spec sample_duration(atom() | String.t() | TuningFork.Sample.t(), keyword()) :: float()
How long sample/2 would sound name for with opts, in seconds.
Every bank sample name, or those in one family: sample_names(:ambi).
The notes of a scale, one octave up from root and the octave note above.
list in a random order.
@spec sleep(number()) :: :ok
Move the thread on by beats. Outside a round, with a stage running, this waits that long.
@spec spread(non_neg_integer(), pos_integer()) :: [boolean()]
hits beats spread as evenly as they go over steps, as booleans — a Euclidean rhythm.
@spec stop() :: no_return()
End the round here. Nothing after it is played.
@spec stretch([term()], pos_integer()) :: [term()]
Each element of list repeated count times in place.
Wait for name to have been cued, and give what it was cued with.
Once it has, this returns at once. Until then the round is given up with
{:error, "waiting for name"}, and the loop tries again next time round.
@spec synth(atom() | TuningFork.Part.t(), keyword() | TuningFork.Voice.t()) :: TuningFork.SonicPi.Handle.t() | TuningFork.Part.t()
Sound a note with a named synth without changing the thread's, or set a part's synth.
@spec synth_names() :: [atom()]
The TuningFork.SonicPi.Synth names, for use_synth/1.
@spec tick() :: non_neg_integer()
Step a counter and give what it was, or the element of a list that count picks.
tick() and tick(:name) are TuningFork.Tick's; tick(list) reads list at the default
counter's count and tick(list, :name) at a named one.
@spec tick_reset(atom() | nil) :: :ok
Put the default counter, or the named one, back to zero.
@spec tick_reset_all() :: :ok
Put every counter back to zero.
@spec tick_set(atom() | nil, non_neg_integer()) :: :ok
Put a counter at count, so look gives count and the next tick gives one more.
Run a block count times: times 4 do … end, or times(4, fn pass -> … end) to be told which pass.
Run a block as it is: uncomment do … end.
@spec use_bpm(number()) :: :ok
Beats a minute for everything after this point in the thread. Default 60.
@spec use_debug(boolean()) :: :ok
Accepted and ignored; there is no debug output to switch.
@spec use_merged_synth_defaults(keyword()) :: :ok
Options every play/2 from here on starts from, merged over the ones there already.
@spec use_random_seed(term()) :: :ok
Seed the thread's generator, so what follows draws the same numbers every time.
@spec use_sample_bpm(atom() | String.t() | TuningFork.Sample.t(), keyword()) :: :ok
Set the tempo so that name lasts num_beats: beats, default 1.
@spec use_sample_defaults(keyword()) :: :ok
Options every sample/2 from here on starts from.
@spec use_synth(atom() | String.t() | TuningFork.Voice.t()) :: :ok
The synth play/2 uses from here on: a name from TuningFork.SonicPi.Synth.names/0, a
TuningFork.Voice, or a sound name TuningFork.Kit.known?/1 accepts, such as "gm_epiano1",
played at each note through the kit.
@spec use_synth_defaults(keyword()) :: :ok
Options every play/2 from here on starts from. A play option overrides one here.
@spec use_transpose(integer()) :: :ok
Semitones added to every note from here on.
Run a block at bpm, then go back to the tempo before: with_bpm 120 do … end.
Run a block with everything it plays going through an effect: with_fx :reverb, mix: 0.3 do … end.
name is one of fx_names/0. A fn taking one argument is given the effect's Handle,
for control/2.
Run a block with the generator seeded from seed, then carry on from where it was.
Run a block with another synth, then go back: with_synth :saw do … end.
Run a block with other synth defaults, then go back.
Run a block transposed by semitones, then go back: with_transpose 12 do … end.