0.5.0 • Published 6 months ago

twelve-tones v0.5.0

Weekly downloads
-
License
MIT
Repository
github
Last release
6 months ago

Twelve Tones

JavaScript (TypeScript) utilities for working with musical pitches and durations in the 12 tone system.

Pitches

Creating a Pitch object

import { pitch } from "twelve-tones";

const bFlat = pitch("B", "♭", 4);

Learning more about a Pitch

import { pitch, pitchName } from "twelve-tones";

const bFlat = pitch("B", "♭", 4);
pitchName(bFlat); // => 'B♭4'

// or:
`I like ${bFlat}.`; // => 'I like B♭4.'
import { pitch, midiNoteNumber } from "twelve-tones";

const bFlat = pitch("B", "♭", 4);
midiNoteNumber(bFlat); // => 70
import {
  pitch,
  isSamePitch,
  isEnharmonicEquivalent,
  numberOfAccidentals,
} from "twelve-tones";

const bFlat = pitch("B", "♭", 4);
const aSharp = pitch("A", "♯", 4);

isSamePitch(bFlat, aSharp); // => false

isEnharmonicEquivalent(bFlat, aSharp); // => true

numberOfAccidentals(bFlat); // => -1
numberOfAccidentals(aSharp); // => 1

Transform a Pitch

import { natural, transpose, interval } from "twelve-tones";

const bNatural = natural(bFlat);
numberOfAccidentals(bNatural); // => 0

`I like ${bNatural}.`; // => 'I like B4.'

const eFlat = transpose(bFlat, interval("perfect", "fourth")); // see 'Intervals'

Shorthand notation

Allows for compact, inline creation of pitches and intervals.

import { numberOfAccidentals, natural, transpose } from "twelve-tones";

numberOfAccidentals(["F", "♯♯", 5]); // => 2

natural(["A", "♭♭", 3]); // => Pitch (A3)

const eFlat = transpose(["C", "♮", 4], ["minor", "third"]); // see 'Intervals'
eFlat.toString(); // => E♭4

Intervals

Creating an Interval object

import { interval } from "twelve-tones";

// full notation
const majorThird = interval("major", "third");
const perfectFifth = interval("perfect", "fifth");
const diminishedSeventh = interval("diminished", "seventh");

// compact notation
const minorSecond = interval("m", "2");
const majorSixth = interval("M", "6");
const perfectFourth = interval("P", "4");
const augmentedThird = interval("A", "3");

Learning more about an Interval

import { intervalName } from "twelve-tones";

intervalName(interval("minor", "second")); // => 'minor second'
intervalName(["m", "2"]); // => 'minor second'

const P8 = interval("perfect", "octave");
`A ${P8} is a big jump.`; // => 'A perfect octave is a big jump.'
import { interval, isSameInterval } from "twelve-tones";

const perfectFourth = interval("perfect", "fourth");
const diminishedFifth = interval("diminished", "fifth");

isSameInterval(perfectFourth, diminishedFifth); // => false
isSameInterval(perfectFourth, interval("P", 4)); // => true
import { interval, quality } from "twelve-tones";

quality(interval("P", "8")); // => 'perfect'
quality(interval("M", "3")); // => 'major'
quality(interval("m", "6")); // => 'minor'

quality(interval("diminished", "fourth")); // => -1
quality(interval("A", 2)); // => 1

Transposing pitches

import { pitch, interval } from "twelve-tones";

const fNatural = pitch("F", "♮", 4);
const perfectFifth = interval("perfect", "fifth");
transpose(fNatural, perfectFifth); // => C♮5 (Pitch object)
transpose(fNatural, perfectFifth, "down"); // => B♭4 (Pitch object)

// shorthand notation
transpose(["C", "♮", 3], ["M", "3"], "down"); // => A♭2

By default, transpositions are applied in the up direction. To transpose down, provide 'down' or -1 as a third parameter to transpose.

Advanced quality factors

The quality factor of a diminished or augmented chord can be provided as a number to generate higher orders such as doubly-augmented or triply-diminished:

import { interval, quality } from "twelve-tones";

const triplyDiminishedFifth = interval([-3, "fifth"]);
const octuplyAugmentedThird = interval([+8, "third"]);

quality(triplyDiminishedFifth); // => -3
quality(octuplyAugmentedThird); // => 8

Combining multiple intervals together

Intervals from unison to octave can be built using the above mentioned syntax. When an interval needs to span more than an octave (such as a ninth, or thirteens), use combine to construct greater intervals:

import { combine } from "twelve-tones";

const ninth = combine(['P', '8'], ['M', '2']);

This allows for any interval to be created:

import { interval, combine, transpose } from "twelve-tones";

const P8 = interval('perfect', 'octave');
const A6 = interval('augmented', 'sixth');
const M2 = interval('major', 'second');

const bigInterval = combine(P8, A6, M2);

transpose(['E', '♭', 4], bigInterval, 'up'); // => Pitch (D♯6)

Chords

Commonly used chords can be created using triad or seventhChord:

import { triad, seventhChord } from "twelve-tones";

triad('major'); // Chord object representing a major triad
triad('minor'); // Chord object representing a minor triad

seventhChord('dominant'); // Chord object representing a dominant seventh chord
seventhChord('half-diminished'); // Chord object representing a dominant seventh chord

A Chord object is root-agnostic, until pitch values are extracted with a provided rootnote:

import { triad, pitches } from "twelve-tones";

const aFlatMajor = pitches(triad('major'), ['A', '♭', 4]); // => Pitch[]: A♭4, C♮5, E♭5
const fSharpMinor = pitches(triad('minor'), ['F', '♯', 4]); // => Pitch[]: F♯4, A♯4, C♯5

const cMajorFirstInversion = pitches(triad('major'), ['C', '♮', 4], 1); // => Pitch[]: E♮4, G♮4, C♮5

Behind the scenes

The properties on the Pitch and Interval objects may be confusing.

The easiest way to use twelve-tones is to ignore these properties, and use the utiliy functions as described above, such as pitchName, interval, isSamePitch, etc.

But in case you are interested, here's what the properties represent.

Pitch object structure

A Pitch object is a reference to a specific position on the Circle of Fifths, along with an absolute octave number.

The circlePosition property of a Pitch refers to:

-3-2-1012345678
A flatE flatB flatC naturalG naturalD naturalA naturalE naturalB naturalF sharpC sharpG sharp

expanding infinitely in both directions.

import { pitch } from "twelve-tones";

pitch('A', '♮', 4).circlePosition; // => 3
pitch('A', '♮', 4).octave; // => 4

pitch('A', '♭', 7).circlePosition; // => -3
pitch('A', '♭', 7).octave; // => 7

Interval object structure

An Interval object describes how to jump around on the Circle of Fifths in order to transpose a note by a certain amount.

For example:

  • a major second can be described as: move 2 steps to the right
  • a perfect fourth can be described as: move 1 step to the left
import { interval } from "twelve-tones";

interval('major', 'second').circleShift; // => 2
interval('perfect', 'fourth').circleShift; // => -1

Additionally, an Interval can span multiple octaves, hence the octaveShift property.

  • a perfect fifth requires 1 steps along the circle, but no octave jumps
  • a perfect octave requires no steps along the circle, but 1 octave jump
import { interval } from "twelve-tones";

interval('perfect', 'fifth'); // => { circleShift: 1, octaveShift: 0 }
interval('perfect', 'octave'); // => { circleShift: 0, octaveShift: 1 }
0.5.0

6 months ago

0.4.0

6 months ago

0.3.1

6 months ago

0.3.0

6 months ago

0.2.0

6 months ago

0.1.2

6 months ago

0.1.1

6 months ago

0.1.0

6 months ago