Recorded audio, to be played as a TuningFork.Voice.
kick = Sample.load!("kick.wav")
part(bpm: 96, synth: Voice.new(sample: kick)) |> steps("x..x..x.")
Summary
Functions
The value at a fractional frame position in the recording, from -1.0 to 1.0.
How long the recording lasts at its own speed, in seconds.
How long the recording lasts when played at freq, in seconds.
How many frames long the recording is.
A sample from PCM already in memory.
Read a recording from disk: a WAV or a FLAC as they are, anything else through
TuningFork.Sample.Decode.
position brought back inside the loop when the recording has one and the position has
passed its end; unchanged otherwise.
How far to move through the recording per output frame to sound at freq through a device
running at rate.
A new sample with the recording reversed, keeping its rate and root.
A new sample cut out of this one: length seconds starting from seconds in.
Types
@type t() :: %TuningFork.Sample{ id: term(), loop: {non_neg_integer(), pos_integer()} | nil, name: String.t(), pcm: binary(), rate: pos_integer(), root: float() | nil }
Functions
The value at a fractional frame position in the recording, from -1.0 to 1.0.
Cubic Hermite interpolation through the two frames either side and their neighbours. A
position before the start or past the end is 0.0 rather than a wrap, unless the recording
has a loop, which looped/2 brings it back inside.
How long the recording lasts at its own speed, in seconds.
How long the recording lasts when played at freq, in seconds.
Longer when pitched down and shorter when pitched up. A sample with no :root, or a freq
of nil, gives duration/1.
@spec frames(t()) :: non_neg_integer()
How many frames long the recording is.
A sample from PCM already in memory.
Stereo input is folded to mono, since a voice is synthesised in mono and panned afterwards.
More than two channels raises ArgumentError.
Options
:rate— samples per second of the PCM given, default 44100:channels— 1 or 2, default 1:root— the pitch the recording already is, as a note name or a frequency in Hz:loop—{from, to}frames a voice goes round between once it reachesto, so a note can outlast the recording; defaultnil:gain— a factor the recording is scaled by as it is loaded, default 1.0:name— what to call it, default"sample"
Read a recording from disk: a WAV or a FLAC as they are, anything else through
TuningFork.Sample.Decode.
Which it is comes from the file's own header, not its name. Raises if the file cannot be read or will not decode.
Options
:root— the pitch the recording already is, as a note name or a frequency in Hz. Leave it out for percussion, which has no pitch to move from:name— what to call it, default the file's basename
:rate and :channels come from the file and are not taken here.
position brought back inside the loop when the recording has one and the position has
passed its end; unchanged otherwise.
@spec ratio(t(), float() | nil, pos_integer()) :: float()
How far to move through the recording per output frame to sound at freq through a device
running at rate.
Two ratios in one: freq against the sample's :root, and the sample's own rate against
rate. A sample with no :root, or a freq of nil, is read at its own pitch and still
corrected for rate.
A new sample with the recording reversed, keeping its rate and root.
A new sample cut out of this one: length seconds starting from seconds in.
A range running past the end is truncated to what is there. The result keeps the rate and
root of the original and gets its own :id, so caches tell it apart from what it came
from.