Notes on a beat grid with a tempo map, rendered to one buffer that loops without a break.
Score.from_parts([bass, arpeggio, drums], beats: 64)
|> Score.render(44_100)
Summary
Functions
Place a voice on a beat.
Place the same voice on each of beats.
Where beat falls, in seconds, read through the tempo map.
How long the score runs, in seconds: where :beats falls on the tempo map.
Build a score by mixing parts together.
An empty score.
The frequency of a named note, such as :a3, :fs4 or :eb5.
The frequency interval semitones from name.
Render to signed 16-bit little-endian PCM that loops without a break.
Place a voice every every beats, from from up to but not including :beats.
Which beat seconds falls on, read through the tempo map. The inverse of beat_to_seconds/2.
Change tempo at beat, for everything from there until the next change.
Every tempo this score runs at, as [{beat, bpm}], starting from beat zero.
Types
@type layer() :: %{fx: keyword(), notes: [{float(), TuningFork.Voice.t()}]}
Functions
@spec add(t(), number(), TuningFork.Voice.t()) :: t()
Place a voice on a beat.
@spec add_all(t(), [number()], TuningFork.Voice.t()) :: t()
Place the same voice on each of beats.
Where beat falls, in seconds, read through the tempo map.
How long the score runs, in seconds: where :beats falls on the tempo map.
@spec from_parts([TuningFork.Part.t()], keyword()) :: t()
Build a score by mixing parts together.
Each part is read from its own beat zero. Every part must have the same :bpm; parts that
disagree raise ArgumentError.
Options
:bpm— the tempo, default the parts'. All parts play at it:beats— how long the score is, default the longest part'sTuningFork.Part.beats/1:changes— tempo changes, asnew/1takes them
An empty score.
Options
:bpm— the tempo it starts at, default 120:beats— how long it runs, default 16:changes— tempo changes after the start, as[{beat, bpm}]. Sorted by beat, and where two name the same beat the later one in the list wins
The frequency of a named note, such as :a3, :fs4 or :eb5.
The frequency interval semitones from name.
@spec render(t(), pos_integer(), keyword()) :: binary()
Render to signed 16-bit little-endian PCM that loops without a break.
rate is samples per second. The result is duration/1 seconds long, and at least one
frame; anything running past the end is folded back over the start. Each voice lands where
its :pan says.
Options
:channels— 2 for stereo, the default, or 1 for mono
@spec repeat(t(), number(), number(), TuningFork.Voice.t()) :: t()
Place a voice every every beats, from from up to but not including :beats.
Raises ArgumentError unless every is greater than zero.
Which beat seconds falls on, read through the tempo map. The inverse of beat_to_seconds/2.
Change tempo at beat, for everything from there until the next change.
A change at a beat that already has one replaces it. A score runs at one tempo at a time.
Every tempo this score runs at, as [{beat, bpm}], starting from beat zero.
A change stated at beat zero is the starting tempo and replaces :bpm.