Named scales, and the MIDI notes their degrees stand for.
iex> TuningFork.Scale.midi("g:minor", 4)
62
Summary
Functions
How many semitones above the root degree sits, wrapping into octaves.
The MIDI note degree stands for in scale.
Every scale name, sorted.
Split "g2:minor" into its root note and scale.
The semitones a scale's degrees sit on, from its root.
Types
@type name() :: atom()
Functions
@spec interval([non_neg_integer()], integer()) :: integer()
How many semitones above the root degree sits, wrapping into octaves.
iex> TuningFork.Scale.interval([0, 2, 3, 5, 7, 8, 10], 9)
15
The MIDI note degree stands for in scale.
scale is a "root:name" string as parse/1 reads it, or a {root_midi, name} pair.
Degree 0 is the root; degrees past the scale's length carry into the octave above and
negative degrees into the octave below. Returns nil for a scale it cannot read.
iex> TuningFork.Scale.midi("g:minor", 7)
67
iex> TuningFork.Scale.midi("g:minor", -1)
53
@spec names() :: [name()]
Every scale name, sorted.
Split "g2:minor" into its root note and scale.
The root is a letter with s for sharp or b for flat and an optional octave. Returns
{:ok, root_midi, scale} or {:error, reason}. Without an octave the root is in octave
3; without a scale it is :major.
iex> TuningFork.Scale.parse("eb2:dorian")
{:ok, 39, :dorian}
@spec steps(name() | String.t()) :: [non_neg_integer()] | nil
The semitones a scale's degrees sit on, from its root.
iex> TuningFork.Scale.steps(:minor)
[0, 2, 3, 5, 7, 8, 10]Returns nil for a name there is no scale for.