music-fns is a JavaScript music utility library that contains small music notation related functions.
npm install music-fns
or
yarn add music-fns
All methods are available as named exports.
example:
import { noteToFrequency } from 'music-fns';
console.log(noteToFrequency('A4'));
// > 440
This is an overview of all methods & constants.
music-fns
uses scientific pitch notation, you can use symbols (â™, ♯) or letters (b, #) as accidentals. The functions preserve your style (flat/sharp, letter/symbol).
Documentation is still WIP, PRs welcome.
An nested array that contains a chromatic C scale with its possible note variations.
import { NOTES } from 'music-fns';
console.log(NOTES);
/* >
[
[ 'C', 'B#' ],
[ 'C#', 'Db' ],
[ 'D' ],
[ 'D#', 'Eb' ],
[ 'E', 'Fb' ],
[ 'F', 'E#' ],
[ 'F#', 'Gb' ],
[ 'G' ],
[ 'G#', 'Ab' ],
[ 'A' ],
[ 'A#', 'Bb' ],
[ 'B', 'Cb' ]
]
*/
Returns the root (only note, no accidental) from a note.
import { getRoot } from 'music-fns';
console.log(getRoot('A#4'));
// > 'A'
Returns the full note (note + accidental) from a note.
import { getNote } from 'music-fns';
console.log(getNote('A#4'));
// > 'A#'
Returns the octave information (or undefined
) from a note.
import { getOctave } from 'music-fns';
console.log(getOctave('A#4'));
// > 4
console.log(getOctave('A#'));
// > undefined
Returns the accidental (or undefined
) from a note.
import { getAccidental } from 'music-fns';
console.log(getAccidental('A#4'));
// > '#'
console.log(getAccidental('A4'));
// > undefined
Returns true
if the note has octave information.
import { hasOctave } from 'music-fns';
console.log(hasOctave('A♯4'));
// > true
console.log(hasOctave('Db'));
// > false
Returns true
if the note has an accidental.
import { hasAccidental } from 'music-fns';
console.log(hasAccidental('A♯4'));
// > true
console.log(hasAccidental('D'));
// > false
Returns true
if the note has an accidental as a letter (b, #).
import { hasAccidentalLetter } from 'music-fns';
console.log(hasAccidentalLetter('A#4'));
// > true
console.log(hasAccidentalLetter('A♯4'));
// > false
Returns true
if the note has an accidental as a symbol (â™, ♯).
import { hasAccidentalSymbol } from 'music-fns';
console.log(hasAccidentalSymbol('A♯4'));
// > true
console.log(hasAccidentalSymbol('A#4'));
// > false
Returns true
if the note is flat (b, â™).
import { isFlat } from 'music-fns';
console.log(isFlat('Gb3'));
// > true
console.log(isFlat('Eâ™'));
// > true
console.log(isFlat('F#3'));
// > false
Returns true
if the note is sharp (#, ♯).
import { isSharp } from 'music-fns';
console.log(isSharp('F#3'));
// > true
console.log(isSharp('A♯'));
// > true
console.log(isSharp('Gb3'));
// > false
Returns true
if the note is natural (no accidental).
import { isNatural } from 'music-fns';
console.log(isNatural('F3'));
// > true
console.log(isNatural('Gb3'));
// > false
Converts a flat to its sharp equivalent, this function preserves the accidental style (letter or symbol). If no flat is found the function returns the unmodified input.
import { flatToSharp } from 'music-fns';
console.log(flatToSharp('Gb3'));
// > 'F#3'
Converts a sharp to its flat equivalent, this function preserves the accidental style (letter or symbol). If no sharp is found the function returns the unmodified input.
import { sharpToFlat } from 'music-fns';
console.log(sharpToFlat('F#3'));
// > 'Gb3'
Returns true
if the provided notes are the same notes.
import { areEqual } from 'music-fns';
// same notes in flat & sharp, symbol and letter
console.log(areEqual(['F#3', 'Gb3', 'Gâ™3', 'F♯3']));
// > true
console.log(areEqual(['A3', 'F3']));
// > false
Returns the (0-indexed) position of the specific root within a chromatic C scale (equals the NOTES
constant).
import { getChromaticCPosition } from 'music-fns';
console.log(getChromaticCPosition('D3'));
// > 2
console.log(getChromaticCPosition('G♯1'));
// > 8
Returns true
if all notes share the same octave information.
import { haveSameOctave } from 'music-fns';
console.log(haveSameOctave(['A3', 'D3', 'G3']));
// > true
console.log(haveSameOctave(['A#1', 'D3', 'G3']));
// > false
Converts a note to a frequency (in Hz). You can use a different base frequency for A4 via standard
.
import { noteToFrequency } from 'music-fns';
console.log(noteToFrequency('A4'));
// > 440
console.log(noteToFrequency('C#3'));
// > 138.59131548843604
console.log(noteToFrequency('A4', { standard: 442 }));
// > 442
Converts a note to its MIDI number. C4 = 60 in our implementation. You can provide a different middle C via standard
.
import { noteToMidi } from 'music-fns';
console.log(noteToMidi('C4'));
// > 60
console.log(noteToMidi('A4'));
// > 81
console.log(noteToMidi('C3', { standard: 'C3' }));
// > 60
Converts a note to an object describing the note.
The object can contain the following keys:
- root: a root note (
C
,D
,E
,F
,G
,A
,B
) - [accidental]:
SHARP
,FLAT
- [accidentalType]:
SYMBOL
,LETTER
- [octave]: number
import { noteToObject } from 'music-fns';
console.log(noteToObject('A4'));
/* > {
root: 'A',
octave: 4
} */
console.log(noteToObject('G♯1'));
/* > {
root: 'G',
accidental: 'SHARP',
accidentalType: 'SYMBOL',
octave: 1
} */
console.log(noteToObject('Ab4'));
/* > {
root: 'A',
accidental: 'FLAT',
accidentalType: 'LETTER',
octave: 4
} */
Converts an object describing the note to a note.
The object can contain following keys:
- root: a root note (
C
,D
,E
,F
,G
,A
,B
) - [accidental]:
SHARP
/FLAT
- [accidentalType]:
SYMBOL
/LETTER
- [octave]: number
import { objectToNote } from 'music-fns';
console.log(
objectToNote({
root: 'A',
octave: 4
})
);
// > 'A4'
console.log(
objectToNote({
root: 'G',
accidental: 'SHARP',
accidentalType: 'SYMBOL',
octave: 1
})
);
// > 'G♯1'
Returns true
if the provided value is a valid note in scientific pitch notation.
import { isNote } from 'music-fns';
console.log(isNote('A#5'));
// > true;
console.log(isNote('Q2'));
// > false;
Converts a note which has an accidental as a symbol (â™, ♯) to a note with the accidental as a letter (b, #).
import { accidentalToLetter } from 'music-fns';
console.log(accidentalToLetter('A♯4'));
// > 'A#4'
Converts a note which has an accidental as a letter (b, #) to a note with the accidental as a symbol (â™, ♯).
import { accidentalToSymbol } from 'music-fns';
console.log(accidentalToSymbol('A#4'));
// > 'A♯4'
Transfer the accidental type (flat or sharp) from a provided reference note
In this example, we've converted F♯3
to Gb3
because the reference note is Bb4
(a flat instead of sharp).
import { transferAccidental } from 'music-fns';
console.log(transferAccidental('F#3', 'Bb4'));
// > 'Gb3';
// = same as 'F#3', different style of notation
Transfer the accidental notation style (letter or symbol) from the provided reference note
In this example, we've converted F♯3
to F♯3
because the reference note is Bâ™4
(a symbol instead of a letter).
import { transferAccidentalStyle } from 'music-fns';
console.log(transferAccidentalStyle('F#3', 'Bâ™4'));
// > 'F♯3';
// = same as 'F#3', different style of notation
Combination of transferAccidental
and transferAccidentalStyle
.
In this example, we've converted F#3
to Gâ™3
because the reference note is Bâ™4
(a flat symbol instead of a sharp letter).
import { transferStyle } from 'music-fns';
console.log(transferStyle('F#3', 'Bâ™4'));
// > 'Gâ™3';
// = same as 'F#3', different style of notation
An object that contains different interval constants. Feel free to open a PR to add more interval constants.
(interval amount between the brackets ())
short:
(0)
ROOT / R(1)
SEMITONE / S(2)
TONE / T(6)
TRITONE / TT(12)
OCTAVE / O
minor / major:
(0)
PERFECT_UNISON / P1(1)
MINOR_SECOND / m2(2)
MAJOR_SECOND / M2(3)
MINOR_THIRD / m3(4)
MAJOR_THIRD / M3(5)
PERFECT_FOURTH / P4(7)
PERFECT_FIFTH / P5(8)
MINOR_SIXTH / m6(9)
MAJOR_SIXTH / M6(10)
MINOR_SEVENTH / m7(11)
MAJOR_SEVENTH / M7(12)
PERFECT_OCTAVE / P8
augmented / diminished:
(0)
DIMINISHED_SECOND / d2(1)
AUGMENTED_UNISON / A1(2)
DIMINISHED_THIRD / d3(3)
AUGMENTED_SECOND / A2(4)
DIMINISHED_FOURTH / d4(5)
AUGMENTED_THIRD / A3(6)
DIMINISHED_FIFTH / d5(6)
AUGMENTED_FOURTH / A4(7)
DIMINISHED_SIXTH / d6(8)
AUGMENTED_FIFTH / A5(9)
DIMINISHED_SEVENTH / d7(10)
AUGMENTED_SIXTH / A6(11)
DIMINISHED_EIGHTH / d8(11)
DIMINISHED_OCTAVE(12)
AUGMENTED_SEVENTH / A7
import { Interval } from 'music-fns';
console.log(Interval.PERFECT_FOURTH);
// > 5
console.log(Interval.A6);
// > 10
console.log(Interval.MAJOR_THIRD);
// > 4
console.log(Interval.S);
// > 1
console.log(Interval.OCTAVE);
// > 12
Transpose a note by a specific interval (use the Interval
constant). An interval can also be negative.
import { transpose, Interval } from 'music-fns';
console.log(transpose('C♯3', Interval.MAJOR_SIXTH));
// > 'A♯3'
console.log(transpose('C♯3', -Interval.O));
// > 'C♯2'
Returns one or more intervals between the provided notes. You can pass fromRoot
to calculate the interval from the first note (= root).
import { getIntervals } from 'music-fns';
console.log(getIntervals(['C♯3', 'A♯3']));
// > [ 9 ]
// interval 'C♯3' -> 'A♯3' and 'A♯3' -> 'B3'
console.log(getIntervals(['C♯3', 'A♯3', 'B3']));
// > [ 9, 1 ]
// interval 'C♯3' -> 'A♯3' and 'C♯3' -> 'B3'
console.log(getIntervals(['C♯3', 'A♯3', 'B3'], { fromRoot: true }));
// > [ 9, 10 ]
Returns true
if the interval is a semitone (1)
.
import { getIntervals, isSemitone } from 'music-fns';
console.log(isSemitone(getIntervals(['C♯3', 'D3'])[0]));
// > true;
Returns true
if the interval is a tone (2)
.
import { getIntervals, isTone } from 'music-fns';
console.log(isTone(getIntervals(['C3', 'D3'])[0]));
// > true;
Returns true
if the interval is a third (diminished, minor, major or augmented) (2, 3, 4, 5)
.
import { getIntervals, isThird } from 'music-fns';
console.log(isThird(getIntervals(['C4', 'E4'])[0]));
// > true;
console.log(isThird(getIntervals(['A4', 'C4'])[0]));
// > true;
console.log(isThird(getIntervals(['C4', 'E#4'])[0]));
// > true;
Returns true
if the interval is a fifth (diminished, perfect or augmented) (6, 7, 8)
.
import { getIntervals, isFifth } from 'music-fns';
console.log(isFifth(getIntervals(['C4', 'G4'])[0]));
// > true;
console.log(isFifth(getIntervals(['C4', 'Gb4'])[0]));
// > true;
console.log(isFifth(getIntervals(['C4', 'G#4'])[0]));
// > true;
Returns true
if the interval is an octave (12)
.
import { getIntervals, isOctave } from 'music-fns';
console.log(isOctave(getIntervals(['C3', 'C4'])[0]));
// > true;
An object containing scale constants (array of intervals). Feel free to open PRs to add more scales.
- ALGERIAN:
[ 2, 1, 2, 1, 1, 1, 3, 1 ]
- ALTERED:
[ 1, 2, 1, 2, 2, 2, 2 ]
- ARABIC:
[ 1, 3, 1, 2, 1, 3, 1 ]
- AUGMENTED:
[ 3, 1, 3, 1, 3, 1 ]
- BALINESE:
[ 1, 2, 4, 1, 4 ]
- BLUES:
[ 3, 2, 1, 1, 3, 2 ]
- BYZANTINE:
[ 1, 3, 1, 2, 1, 3, 1 ]
- CHINESE:
[ 4, 2, 1, 4, 1 ]
- CHROMATIC:
[ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ]
- DOUBLE_HARMONIC:
[ 1, 3, 1, 2, 1, 3, 1 ]
- ENIGMATIC:
[ 1, 3, 2, 2, 2, 1, 1 ]
- GYPSY_MAJOR:
[ 1, 3, 1, 2, 1, 3, 1 ]
- HARMONIC_MINOR:
[ 2, 1, 2, 2, 1, 3, 1 ]
- HIRAJOSHI:
[ 1, 4, 1, 4, 2 ]
- IN_SEN:
[ 1, 4, 2, 3, 2 ]
- JAPANESE:
[ 1, 4, 2, 3, 2 ]
- MAJOR_PENTATONIC:
[ 2, 2, 3, 2, 3 ]
- MAJOR:
[ 2, 2, 1, 2, 2, 2, 1 ]
- MELODIC_MINOR:
[ 2, 1, 2, 2, 2, 2, 1 ]
- MINOR_PENTATONIC:
[ 3, 2, 2, 3, 2 ]
- MONGOLIAN:
[ 2, 2, 3, 2, 3 ]
- NATURAL_MINOR:
[ 2, 1, 2, 2, 1, 2, 2 ]
- PELOG:
[ 1, 2, 4, 1, 4 ]
- PROMETHEUS:
[ 2, 2, 2, 3, 1, 2 ]
- WHOLE_TONE:
[ 2, 2, 2, 2, 2, 2 ]
- YO:
[ 2, 3, 2, 2, 3 ]
import { Scale } from 'music-fns';
console.log(Scale.ALGERIAN);
// > [ 2, 1, 2, 1, 1, 1, 3, 1 ]
console.log(Scale.PELOG);
// > [ 1, 2, 4, 1, 4 ]
console.log(Scale.CHROMATIC);
// > [ 1, 2, 4, 1, 4 ]
An object containing mode constants (array of intervals). White keys on a piano from note -> note an octave up.
- IONIAN: (C - C)
[ 2, 2, 1, 2, 2, 2, 1 ]
- DORIAN: (D - D)
[ 2, 1, 2, 2, 2, 1, 2 ]
- PHRYGIAN: (E - E)
[ 1, 2, 2, 2, 1, 2, 2 ]
- LYDIAN: (F - F)
[ 2, 2, 2, 1, 2, 2, 1 ]
- MIXOLYDIAN: (G - G)
[ 2, 2, 1, 2, 2, 1, 2 ]
- AEOLIAN: (A - A)
[ 2, 1, 2, 2, 1, 2, 2 ]
- LOCRIAN: (B - B)
[ 1, 2, 2, 1, 2, 2, 2 ]
import { Mode } from 'music-fns';
console.log(Mode.IONIAN);
// > [ 2, 2, 1, 2, 2, 2, 1 ]
console.log(Mode.MIXOLYDIAN);
// > [ 2, 2, 1, 2, 2, 1, 2 ]
Creates a scale (or mode) by providing a root note and an intervals (use the Scale
or Mode
constant). You can provide includeRootEnd
to also include the root note transposed an octave up.
import { Scale, Mode, createScale } from 'music-fns';
console.log(createScale('C2', Scale.ARABIC));
// > [ 'C2', 'C#2', 'E2', 'F2', 'G2', 'G#2', 'B2' ]
console.log(createScale('G', Mode.MIXOLYDIAN));
// > [ 'G', 'A', 'B', 'C', 'D', 'E', 'F' ]
console.log(createScale('F2', Scale.BLUES, { includeRootEnd: true }));
// > [ 'F2', 'G#2', 'A#2', 'B2', 'C3', 'D#3', 'F3' ]
Returns true
when the array of notes is a scale.
import { isScale } from 'music-fns';
console.log(isScale(['C2', 'C#2', 'E2', 'F2', 'G2', 'G#2', 'B2']));
// > true
console.log(isScale(['C2', 'C#2', 'E4', 'F2', 'G2', 'G#2', 'C5']));
// > false
Returns true
when the provided array of notes is a mode (Ionian, Dorian, Phrygian, Lydian, Mixolydian, Aeolian or Locrian).
import { isMode } from 'music-fns';
console.log(isMode(['G4', 'A4', 'B4', 'C5', 'D5', 'E5', 'F5']));
// > true
console.log(isMode(['C2', 'C#2', 'E2', 'F2', 'G2', 'G#2', 'B2']));
// > false
Returns true
if the scale is ascending.
import { isAscending } from 'music-fns';
console.log(isAscending(['C1', 'D1', 'E1', 'F1', 'G1', 'A1', 'B1', 'C2']));
// > true
console.log(isAscending(['C2', 'B1', 'A1', 'G1', 'F1', 'E1', 'D1']));
// > false
Returns true
if the scale is descending.
import { isDescending } from 'music-fns';
console.log(isDescending(['C2', 'B1', 'A1', 'G1', 'F1', 'E1', 'D1']));
// > true
console.log(isDescending(['C1', 'D1', 'E1', 'F1', 'G1', 'A1', 'B1', 'C2']));
// > false
Returns true
if a scale has the provided interval amount.
import { hasIntervalAmount } from 'music-fns';
console.log(hasIntervalAmount(['C2', 'C#2', 'E2', 'F2', 'G2', 'G#2', 'B2'], 7));
// > true
console.log(
hasIntervalAmount(['C2', 'C#2', 'E2', 'F2', 'G2', 'G#2', 'B2', 'C3'], 7)
);
// > true
console.log(hasIntervalAmount(['C2', 'C#2', 'E2', 'F2', 'G2', 'G#2'], 7));
// > false
Returns true
if the scale is pentatonic (5 notes per octave).
import { isPentatonic } from 'music-fns';
console.log(isPentatonic(['C', 'D', 'E', 'G', 'A']));
// > true
console.log(isPentatonic(['C', 'D', 'E', 'G', 'A', 'C']));
// > true
console.log(isPentatonic(['C', 'D', 'E', 'G']));
// > false
Returns true
if the scale is hexatonic (6 notes per octave).
import { isHexatonic } from 'music-fns';
console.log(isHexatonic(['C', 'D', 'E', 'F♯', 'G♯', 'A♯']));
// > true
console.log(isHexatonic(['C', 'D', 'E', 'F♯', 'G♯', 'A♯', 'C']));
// > true
console.log(isHexatonic(['C', 'D', 'E', 'F♯', 'G♯']));
// > false
Returns true
if the scale is heptatonic (7 notes per octave).
import { isHeptatonic } from 'music-fns';
console.log(isHeptatonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > true
console.log(isHeptatonic(['C', 'D', 'E', 'F', 'G', 'A', 'B', 'C']));
// > true
console.log(isHeptatonic(['C', 'D', 'E', 'F', 'G', 'A']));
// > false
Returns true
if the scale is octatonic (8 notes per octave).
import { isOctatonic } from 'music-fns';
console.log(isOctatonic(['D', 'E', 'F', 'G', 'Aâ™', 'Bâ™', 'B', 'C♯']));
// > true
console.log(isOctatonic(['D', 'E', 'F', 'G', 'Aâ™', 'Bâ™', 'B', 'C♯', 'D']));
// > true
console.log(isOctatonic(['D', 'E', 'F', 'G', 'Aâ™', 'Bâ™']));
// > false
Returns true
if the scale is diatonic (5 tones & 2 semitones, where the semitones are separated at least 2 steps from each other).
import { isDiatonic } from 'music-fns';
console.log(isDiatonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > true
console.log(isDiatonic(['C', 'D', 'E', 'F#', 'G#', 'A#', 'B']));
// > false
Returns true
if the scale is hemitonic (contains 1 or more semitones).
import { isHemitonic } from 'music-fns';
console.log(isHemitonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > true
console.log(isHemitonic(['C', 'D', 'E', 'F#', 'G#', 'A#']));
// > false
Returns true
if the scale is anhemitonic (does not contain semitones).
import { isAnhemitonic } from 'music-fns';
console.log(isAnhemitonic(['C', 'D', 'E', 'F#', 'G#', 'A#']));
// > true
console.log(isAnhemitonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > false
Returns true
if the scale is cohemitonic (contains 2 or more semitones that appear consecutively in scale order).
import { isCohemitonic } from 'music-fns';
// semitones between F# - G and G - Ab
console.log(isCohemitonic(['C', 'D', 'Eb', 'F#', 'G', 'Ab', 'B', 'C']));
// > true
console.log(isCohemitonic(['C1', 'C#1', 'D#1', 'G1', 'G#1']));
// > false
Returns the note on the provided scale degree.
import { getNoteOnDegree } from 'music-fns';
console.log(getNoteOnDegree(['C1', 'D1', 'E1', 'F1', 'G1', 'A1', 'B1'], 3));
// > E1
console.log(getNoteOnDegree(['C', 'D', 'E', 'F', 'G', 'A', 'B'], 8));
// > C
Returns the note on scale degree 1
in a diatonic scale.
import { getTonic } from 'music-fns';
console.log(getTonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > C
Returns the note on scale degree 2
in a diatonic scale.
import { getSupertonic } from 'music-fns';
console.log(getSupertonic(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > D
Returns the note on scale degree 3
in a diatonic scale.
import { getMediant } from 'music-fns';
console.log(getMediant(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > E
Returns the note on scale degree 4
in a diatonic scale.
import { getSubdominant } from 'music-fns';
console.log(getSubdominant(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > F
Returns the note on scale degree 5
in a diatonic scale.
import { getDominant } from 'music-fns';
console.log(getDominant(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > G
Returns the note on scale degree 6
in a diatonic scale.
import { getLeadingTone } from 'music-fns';
console.log(getLeadingTone(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > A
Returns the note on scale degree 7
in a diatonic scale.
import { getLeadingTone } from 'music-fns';
console.log(getLeadingTone(['C', 'D', 'E', 'F', 'G', 'A', 'B']));
// > B
Normalize a scale by making sure it's ascending & has a root end.
import { normalize } from 'music-fns';
console.log(normalize(['C2', 'G1', 'F1', 'E1', 'D1']));
// > ['C1', 'D1', 'E1', 'F1', 'G1', 'C2']
console.log(normalize(['C1', 'D1', 'E1', 'F1', 'G1']));
// > ['C1', 'D1', 'E1', 'F1', 'G1', 'C2']
An object containing chord constants (array of intervals from root, root included). Feel free to open PRs to add more chords.
- AUGMENTED:
[ 0, 4, 8 ]
- DIMINISHED:
[ 0, 3, 6 ]
- MAJOR_SEVENTH:
[ 0, 4, 7, 11 ]
- MAJOR:
[ 0, 4, 7 ]
- MINOR_MAJOR_SEVENTH:
[ 0, 3, 7, 11 ]
- MINOR_SEVENTH:
[ 0, 3, 7, 10 ]
- MINOR:
[ 0, 3, 7 ]
- SEVENTH:
[ 0, 4, 7, 10 ]
import { Chord } from 'music-fns';
console.log(Chord.MAJOR);
// > [ 0, 4, 7 ]
console.log(Chord.MINOR_MAJOR_SEVENTH);
// > [ 0, 3, 7, 11 ]
Creates a chord by providing a root note and intervals (use the Chord
constant).
import { Chord, createChord } from 'music-fns';
console.log(createChord('C2', Chord.MAJOR));
// > [ 'C2', 'E2', 'G2' ]
console.log(createChord('D#3', Chord.MAJOR_SEVENTH));
// > [ 'D#3', 'G3', 'A#3', 'D4' ]
Returns true
if the chord is a triad (a set of three notes that can be stacked in thirds).
import { isTriad } from 'music-fns';
console.log(isTriad(['F2', 'A2', 'C3']));
// > true
console.log(isTriad(['F2', 'A2', 'C3', 'D4']));
// > false
Creates a melody using a provided array of notes and a pattern.
import { Chord, createMelody } from 'music-fns';
console.log(createMelody(createScale('C2', Scale.MAJOR), [0, 2, 0, 1, 0, 3]));
// > [ 'C2', 'E2', 'C2', 'D2', 'C2', 'F2' ]
Thanks to our employer madewithlove for letting us work on this during our weekly Friyays.