/music-scale

Music scales made easy

Primary LanguageJavaScript

music-scale

Build Status Code Climate js-standard-style npm version license pitch-array

Music scales made easy:

var scale = require('music-scale')
var major = scale('1 2 3 4 5 6 7')
major('A') // => ['A', 'B', 'C#', 'D', 'E', 'F#', 'G#']

It includes a dictionary with more than 100 scales:

var lydianAug = scale.fromName('lydian augmented')
lydianAug('C') // => ['C', 'D', 'E', 'F#', 'G#', 'A', 'B']

Install

Node

Install via npm: npm i --save music-scale and require it.

Browsers

Currently there's no distribution for browsers, but is planned. You can use browserify, webpack or a similar tool to create one.

For webpack users: If you use the .json files (or any function that consumes the json file like fromName and names) you will need add a plugin to webpack.config file.

Usage

Build scales from intervals

The simplest use case is build scales from intervals:

scale('1M 2M 3m 7m', 'F') // => ['F', 'G', 'Ab', 'Eb']
scale('1 2 3 4 5', 'A3') // => ['A3', 'B3', 'C#4', 'D4', 'E4']

To know the interval string format see interval-parser. Notice that if the tonic contains octave, the scale will have octaves in it.

Also, you can partially apply the scale function:

var pentatonic = scale('1 2 3 5 6')
pentatonic('E') // => ['E', 'F#', 'G#', 'B', 'C#']

Build scales from notes

You can also use notes as the source of your scale:

var lydian = scale('C D E F# G A B')
lydian('A') // => ['A', 'B', 'C#', 'D#', 'E', 'F#', 'G#']

scale function assumes that the first note is the tonic.

Get scale intervals

You can get the scale intervals passing null as tonic:

var dorian = scale('D E F G A B C')
dorian(null) // => ['1P', '2M', '3m', '4P', '5P', '6M', '7m']

Create a dictionary of scales

You can create a dictionary of scales with a hash that maps names to intervals (or notes). Optionally, you can pass a dictionary of aliases:

var scales = scale.fromName(
  {'major': 'C D E F G A B', 'minor': 'A B C D E F G'},
  {'ionian': 'major', 'eolian': 'minor'})
scales('major', 'F') // => ['F', 'G', 'A', 'Bb', 'C', 'D', 'E']
scales('ionian', 'A') // same as scales('major', 'A')
scales('eolian', 'G') // same as scales('minor', 'G')
scale('dorian', 'C') // => null

Use the built-in scale dictionary

music-scale has a couple of .json data hash with about 100 scales (see dict directory):

scale.fromName('bebop locrian', 'C') // => [ 'C', 'Db', 'Eb', 'F', 'Gb', 'G', 'Ab', 'Bb']

You can get all scales names with names function:

scale.names() // => ['major', 'minor', ...]

Get degrees of a scale

You can get specific degrees of a scale:

scale.degrees('1 3 5', 'C D E F G A B') // => [ 'C', 'E', 'G' ]
scale.degrees('1 5 2 6', 'C D E F G A B') // => [ 'C', 'G', 'D', 'A' ]

Notice that scale notes are the same that the order of the degrees (Jerry Bergonzi would be very happy with this...)

Scale detection

Not implemented yet: get the name of scale from a collection of notes

This library is too big

You can require the individual functions:

var scale = require('music-scale/scale')
var fromName = require('music-scale/fromName')

This library is too small

Sugestions welcomed. Pull request are perfect.

API

degrees(degrees, notes) → {Array}

Get the degrees of a scale

The resulting array will contain the notes in the same order as degrees. If a given degree is not present in the scale, the result will contain a null in that position.

Parameters:
Name Type Description
degrees Array | String

the degrees numbers

notes Array | String

the scale notes

Source:
Returns:

the notes of the given degrees (or null if not present)

Type
Array
Example
scale.degrees('1 3 5', 'C D E F G A B') // => [ 'C', 'E', 'G' ]
scale.degrees('1 5 2 6', 'C D E F G A B') // => [ 'C', 'G', 'D', 'A' ]
scale.degrees('1 2 6', 'C D E F G') // => [ 'C', 'D', null ]

dictionary(data, aliases) → {function}

Create a scale builder function from a hash of data

A scale builder is a function that given a names and a tonic, returns a scale (array). It can be partially applied.

Parameters:
Name Type Description
data Hash

the data (maps names to intervals or notes)

aliases Hash

(Optional) maps names to names in the data hash

Source:
Returns:

a function to create scales

Type
function
Example
var scales = dictionary({ major: '1 2 3 4 5 6 7', minor: '1 2 3b 4 5 6b 7b' }, {eolian: 'minor'})
scales('major', 'C') // => ['C', 'D', 'E', 'F', 'G', 'A', 'B']
scales('aeolian', 'A') // => ['A', 'B', 'C', 'D', 'E', 'F', 'G']
var minor = scales('minor')
minor('D') // => ['D', 'E', 'F', 'G', 'A', 'Bb', 'C']

fromName(name, tonic)

Build a scale using a name and a tonic

It uses a dictionary of scales (see dict directory)

Can be partially applied (see example)

Parameters:
Name Type Description
name String

the name of the scale

tonic String | Array

the tonic of the scale

Source:
Example
scale.fromName('bebop locrian', 'C') // => [ 'C', 'Db', 'Eb', 'F', 'Gb', 'G', 'Ab', 'Bb' ]
var kumoi = scale.fromName('kumoi')
kumoi('G') // => ['G', 'A', 'Bb', 'D', 'E']

names(withAliases) → {Array.<String>}

Get all scale names available

Parameters:
Name Type Description
withAliases Boolean

set to true to get aliases names

Source:
Returns:

the list of all scale names

Type
Array.<String>
Example
scale.names() // => ['major', 'minor', ...]

scale(source, tonic) → {Array}

Build a scale from a source and a tonic. A scale is an array of notes (or intervals if tonic is null) ordered by frequency

A source can be a list of intervals or notes. The tonic must be a pitch (with or without octave) or null to get the scale intervals

This function is currified, so you can partially apply the function passing one parameter instead of two (see example)

Parameters:
Name Type Description
source Array

the list of intervals or notes

tonic String

the tonic of the scale

Source:
Returns:

the list of notes

Type
Array
Example
scale('1 2 3 5 6', 'G') // => ['G', 'A', 'B', 'D', 'E']
var dorian = scale('D E F G A B C')
dorian('C4')

generated with docme

License

MIT License