New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

tonal-key

Package Overview
Dependencies
Maintainers
1
Versions
42
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

tonal-key - npm Package Compare versions

Comparing version 0.68.0 to 0.68.1

241

build/index.js

@@ -12,31 +12,108 @@ 'use strict';

var isArr = Array.isArray
/**
* _Key_ refers to the tonal system based on the major and minor scales. This is
* is the most common tonal system, but tonality can be present in music
* based in other scales or concepts.
*
* This is a collection of functions related to keys.
*
* @example
* var key = require('tonal-key')
* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
* key.relative('minor', 'C major') // => 'A minor'
*
* @module key
*/
// Order matters: use an array
var MODES = ['ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian',
'aeolian', 'locrian', 'major', 'minor']
'aeolian', 'locrian', 'major', 'minor'];
// { C: 0, D: 2, E: 4, F: -1, G: 1, A: 3, B: 5 }
var FIFTHS = [0, 2, 4, -1, 1, 3, 5, 0, 3]
var FIFTHS = [0, 2, 4, -1, 1, 3, 5, 0, 3];
var SCALES = [0, 1, 2, 3, 4, 5, 6, 0, 5].map(function (n) {
return tonalHarmonizer.harmonics(tonalArray.rotate(n, ['C', 'D', 'E', 'F', 'G', 'A', 'B']))
})
});
// PRIVATE
// Given a tonic, mode pair, return the key string
function toKey (t, m) { return !t ? m : t + ' ' + m }
// Given the alterations, return the major key
function majorKey (n) { return toKey(tonalTranspose.trFifths('C', n), 'major') }
// given the mode name, return the alterations
function modeNum (mode) { return FIFTHS[MODES.indexOf(mode)] }
// given a string, return the valid mode it represents or null
function validMode (m) {
m = m.trim().toLowerCase();
return MODES.indexOf(m) === -1 ? null : m
}
/**
* Get scale of a key (with optionally a mode)
* Return the key properties, an object with { tonic, mode }
*
* @param {String|Object} key
* @return {Array} the key scale
* @param {String} name - the key name
* @return {Key} the key properties object or null if not a valid key
* @example
* var key = require('tonal-key')
* key.scale('A major') // => [ 'A', 'B', 'C#', 'D', 'E', 'F#', 'G#' ]
* key.scale('Bb minor') // => [ 'Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab' ]
* key.scale('C dorian') // => [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ]
* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
* key.props('C3 dorian') // => { tonic: 'C', mode: 'dorian' }
* key.props('dorian') // => { tonic: false, mode: 'dorian' }
* key.props('Ab bebop') // => null
* key.props('blah') // => null
*/
function scale (key) {
var k = asKey(key)
if (!k || !hasTonic(k)) return null
return tonalHarmonizer.harmonize(SCALES[MODES.indexOf(k[0])], k[1])
function props (str) {
if (typeof str !== 'string') return null
var ndx = str.indexOf(' ');
var key;
if (ndx === -1) {
var p = tonalNote.pc(str);
key = p ? { tonic: p, mode: 'major' }
: { tonic: false, mode: validMode(str) };
} else {
key = { tonic: tonalNote.pc(str.slice(0, ndx)), mode: validMode(str.slice(ndx + 1)) };
}
return key.mode ? key : null
}
/**
* Test if a given name is a valid key name
*
* @param {String} name
* @param {Boolean}
* @example
* key.isKeyName('C major') // => true
* key.isKeyName('major') // => true
* key.isKeyName('Bb bebop') // => false
*/
function isKeyName (name) {
return props(name) !== null
}
/**
* Get the tonic of a key
*
* @param {String} key - the key
* @return {String} the tonic or false is no tonic, or null if its not a valid key
* @example
* key.tonic('c3 major') // => 'C'
* key.tonic('minor') // => false
* key.tonic('bebop') // null
*/
function tonic (key) {
return (props(key) || key || {}).tonic || null
}
/**
* Get the mode of a key. It can be used to test if its a valid key mode.
*
* @param {String}
* @return {Boolean}
* @example
* key.mode('A dorian') // => 'dorian'
* key.mode('DORIAN') // => 'dorian'
* key.mode('mixophrygian') // => null
*/
function mode (key) {
return (props(key) || key || {}).mode || null
}
/**
* Get relative of a key. Two keys are relative when the have the same

@@ -50,15 +127,16 @@ * key signature (for example C major and A minor)

* @example
* key.relative('dorian', 'C major') // => ['dorian', 'D']
* // partially application
* key.relative('dorian', 'B major') // => 'C# dorian'
* // partial application
* var minor = key.relative('minor')
* minor('C major') // => ['minor', 'A']
* minor('C major') // => 'A minor'
* minor('E major') // => 'C# minor'
*/
function relative (rel, key) {
if (arguments.length === 1) return function (k) { return relative(rel, k) }
var r = asKey(rel)
if (!r || hasTonic(r)) return null
var k = asKey(key)
if (!k || !hasTonic(k)) return null
var tonic = tonalTranspose.trFifths(k[1], modeNum(r) - modeNum(k))
return build(tonic, rel)
rel = props(rel);
if (!rel || rel.tonic) return null
key = props(key);
if (!key || !key.tonic) return null
var tonic = tonalTranspose.trFifths(key.tonic, modeNum(rel.mode) - modeNum(key.mode));
return toKey(tonic, rel.mode)
}

@@ -76,3 +154,3 @@

function alteredNotes (key) {
var alt = alteration(key)
var alt = alteration(key);
return alt === null ? null

@@ -89,4 +167,9 @@ : alt < 0 ? tonalRange.numeric([-1, alt]).map(tonalTranspose.trFifths('F'))

* @return {Array} an array of strings
* @example
* key.modes() // => [ 'ionian', 'dorian', 'phrygian', 'lydian',
* // 'mixolydian', 'aeolian', 'locrian' ]
* key.modes(true) // => [ 'ionian', 'dorian', 'phrygian', 'lydian',
* // 'mixolydian', 'aeolian', 'locrian', 'major', 'minor' ]
*/
function names (alias) {
function modes (alias) {
return alias ? MODES.slice() : MODES.slice(0, -2)

@@ -96,37 +179,2 @@ }

/**
* Check if the given string is a valid mode name
* @param {String}
* @return {Boolean}
*/
function isKeyMode (m) { return MODES.indexOf(m) !== -1 }
/**
* Build a key object from tonic a mode.
*
* A key object is an array with the mode name and the tonic (or false if
* no tonic specified)
*
* @param {String} tonic - the key tonic (or null or false to no tonic)
* @param {String} mode - the keymode
* @return {Key} a key data object
* @example
* var key = require('tonal-key')
* key.build('g3', 'minor') // => ['minor', 'G']
* key.build(false, 'locrian') // => ['locrian', false]
*/
function build (tonic, mode) {
if (typeof mode !== 'string') return null
var m = mode.trim().toLowerCase()
if (!isKeyMode(m)) return null
if (tonic === false || tonic === null) return [m, false]
var t = tonalNote.pc(tonic)
return t ? [m, t] : null
}
function isKey (o) { return isArr(o) && isKeyMode(o[0]) }
function hasTonic (o) { return isKey(o) && o[1] }
function majorKey (n) { return build(tonalTranspose.trFifths('C', n), 'major') }
/**
* Create a major key from alterations

@@ -138,3 +186,3 @@ * @function

* var key = require('tonal-key')
* key.fromAlter(2) // => ['major', 'D']
* key.fromAlter(2) // => 'D major'
*/

@@ -146,3 +194,4 @@ function fromAlter (n) {

/**
* Create a major key from accidentals
* Get key name from accidentals
*
* @param {String} acc - the accidentals string

@@ -152,3 +201,4 @@ * @return {Key} the key object

* var key = require('tonal-key')
* key.fromAlter('bb') // => ['major', 'Bb']
* key.fromAcc('b') // => 'F major'
* key.fromAcc('##') // => 'D major'
*/

@@ -162,34 +212,19 @@ function fromAcc (s) {

/**
* Create a key from key name
* @param {String} name - the key name
* @return {Key} the key object or null if not valid key
* Get scale of a key
*
* @param {String|Object} key
* @return {Array} the key scale
* @example
* var key = require('tonal-key')
* key.fromName('C3 dorian') // => ['dorian', 'C']
* key.fromName('blah') // => null
* key.scale('A major') // => [ 'A', 'B', 'C#', 'D', 'E', 'F#', 'G#' ]
* key.scale('Bb minor') // => [ 'Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab' ]
* key.scale('C dorian') // => [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ]
* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
*/
function fromName (str) {
if (typeof str !== 'string') return null
var p = str.split(/\s+/)
switch (p.length) {
case 1: return tonalNote.pc(p[0]) ? build(p[0], 'major') : build(false, p[0])
case 2: return build(p[0], p[1])
default: return null
}
function scale (key) {
var p = props(key);
if (!p || !p.tonic) return null
return tonalHarmonizer.harmonize(SCALES[MODES.indexOf(p.mode)], p.tonic)
}
/**
* Try to interpret the given object as a key. Given an object it will try to
* parse as if it were a name, accidentals or alterations.
* @function
* @param {Object} obj
* @return {Key} the key object or null
*/
function asKey (obj) {
return isKey(obj) ? obj : fromName(obj) || fromAcc(obj) || fromAlter(obj)
}
function modeNum (k) { return FIFTHS[MODES.indexOf(k[0])] }
/**
* Get key alteration. The alteration is a number indicating the number of

@@ -204,6 +239,6 @@ * sharpen notes (positive) or flaten notes (negative)

function alteration (key) {
var k = asKey(key)
if (!k || !hasTonic(k)) return null
var toMajor = modeNum(k)
var toC = tonalNote.pcFifths(k[1])
var k = props(key);
if (!k || !k.tonic) return null
var toMajor = modeNum(k.mode);
var toC = tonalNote.pcFifths(k.tonic);
return toC - toMajor

@@ -226,16 +261,16 @@ }

*/
var accidentals = signature
var accidentals = signature;
exports.scale = scale;
exports.props = props;
exports.isKeyName = isKeyName;
exports.tonic = tonic;
exports.mode = mode;
exports.relative = relative;
exports.alteredNotes = alteredNotes;
exports.names = names;
exports.isKeyMode = isKeyMode;
exports.build = build;
exports.modes = modes;
exports.fromAlter = fromAlter;
exports.fromAcc = fromAcc;
exports.fromName = fromName;
exports.asKey = asKey;
exports.scale = scale;
exports.alteration = alteration;
exports.signature = signature;
exports.accidentals = accidentals;
exports.accidentals = accidentals;

@@ -11,3 +11,3 @@ /**

* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
* key.relative('minor', 'C major') // => ['minor', 'A']
* key.relative('minor', 'C major') // => 'A minor'
*

@@ -24,3 +24,2 @@ * @module key

var isArr = Array.isArray
// Order matters: use an array

@@ -35,21 +34,84 @@ var MODES = ['ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian',

// PRIVATE
// Given a tonic, mode pair, return the key string
function toKey (t, m) { return !t ? m : t + ' ' + m }
// Given the alterations, return the major key
function majorKey (n) { return toKey(trFifths('C', n), 'major') }
// given the mode name, return the alterations
function modeNum (mode) { return FIFTHS[MODES.indexOf(mode)] }
// given a string, return the valid mode it represents or null
function validMode (m) {
m = m.trim().toLowerCase()
return MODES.indexOf(m) === -1 ? null : m
}
/**
* Get scale of a key (with optionally a mode)
* Return the key properties, an object with { tonic, mode }
*
* @param {String|Object} key
* @return {Array} the key scale
* @param {String} name - the key name
* @return {Key} the key properties object or null if not a valid key
* @example
* var key = require('tonal-key')
* key.scale('A major') // => [ 'A', 'B', 'C#', 'D', 'E', 'F#', 'G#' ]
* key.scale('Bb minor') // => [ 'Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab' ]
* key.scale('C dorian') // => [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ]
* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
* key.props('C3 dorian') // => { tonic: 'C', mode: 'dorian' }
* key.props('dorian') // => { tonic: false, mode: 'dorian' }
* key.props('Ab bebop') // => null
* key.props('blah') // => null
*/
export function scale (key) {
var k = asKey(key)
if (!k || !hasTonic(k)) return null
return harmonize(SCALES[MODES.indexOf(k[0])], k[1])
export function props (str) {
if (typeof str !== 'string') return null
var ndx = str.indexOf(' ')
var key
if (ndx === -1) {
var p = pc(str)
key = p ? { tonic: p, mode: 'major' }
: { tonic: false, mode: validMode(str) }
} else {
key = { tonic: pc(str.slice(0, ndx)), mode: validMode(str.slice(ndx + 1)) }
}
return key.mode ? key : null
}
/**
* Test if a given name is a valid key name
*
* @param {String} name
* @param {Boolean}
* @example
* key.isKeyName('C major') // => true
* key.isKeyName('major') // => true
* key.isKeyName('Bb bebop') // => false
*/
export function isKeyName (name) {
return props(name) !== null
}
/**
* Get the tonic of a key
*
* @param {String} key - the key
* @return {String} the tonic or false is no tonic, or null if its not a valid key
* @example
* key.tonic('c3 major') // => 'C'
* key.tonic('minor') // => false
* key.tonic('bebop') // null
*/
export function tonic (key) {
return (props(key) || key || {}).tonic || null
}
/**
* Get the mode of a key. It can be used to test if its a valid key mode.
*
* @param {String}
* @return {Boolean}
* @example
* key.mode('A dorian') // => 'dorian'
* key.mode('DORIAN') // => 'dorian'
* key.mode('mixophrygian') // => null
*/
export function mode (key) {
return (props(key) || key || {}).mode || null
}
/**
* Get relative of a key. Two keys are relative when the have the same

@@ -63,15 +125,16 @@ * key signature (for example C major and A minor)

* @example
* key.relative('dorian', 'C major') // => ['dorian', 'D']
* // partially application
* key.relative('dorian', 'B major') // => 'C# dorian'
* // partial application
* var minor = key.relative('minor')
* minor('C major') // => ['minor', 'A']
* minor('C major') // => 'A minor'
* minor('E major') // => 'C# minor'
*/
export function relative (rel, key) {
if (arguments.length === 1) return function (k) { return relative(rel, k) }
var r = asKey(rel)
if (!r || hasTonic(r)) return null
var k = asKey(key)
if (!k || !hasTonic(k)) return null
var tonic = trFifths(k[1], modeNum(r) - modeNum(k))
return build(tonic, rel)
rel = props(rel)
if (!rel || rel.tonic) return null
key = props(key)
if (!key || !key.tonic) return null
var tonic = trFifths(key.tonic, modeNum(rel.mode) - modeNum(key.mode))
return toKey(tonic, rel.mode)
}

@@ -101,4 +164,9 @@

* @return {Array} an array of strings
* @example
* key.modes() // => [ 'ionian', 'dorian', 'phrygian', 'lydian',
* // 'mixolydian', 'aeolian', 'locrian' ]
* key.modes(true) // => [ 'ionian', 'dorian', 'phrygian', 'lydian',
* // 'mixolydian', 'aeolian', 'locrian', 'major', 'minor' ]
*/
export function names (alias) {
export function modes (alias) {
return alias ? MODES.slice() : MODES.slice(0, -2)

@@ -108,37 +176,2 @@ }

/**
* Check if the given string is a valid mode name
* @param {String}
* @return {Boolean}
*/
export function isKeyMode (m) { return MODES.indexOf(m) !== -1 }
/**
* Build a key object from tonic a mode.
*
* A key object is an array with the mode name and the tonic (or false if
* no tonic specified)
*
* @param {String} tonic - the key tonic (or null or false to no tonic)
* @param {String} mode - the keymode
* @return {Key} a key data object
* @example
* var key = require('tonal-key')
* key.build('g3', 'minor') // => ['minor', 'G']
* key.build(false, 'locrian') // => ['locrian', false]
*/
export function build (tonic, mode) {
if (typeof mode !== 'string') return null
var m = mode.trim().toLowerCase()
if (!isKeyMode(m)) return null
if (tonic === false || tonic === null) return [m, false]
var t = pc(tonic)
return t ? [m, t] : null
}
function isKey (o) { return isArr(o) && isKeyMode(o[0]) }
function hasTonic (o) { return isKey(o) && o[1] }
function majorKey (n) { return build(trFifths('C', n), 'major') }
/**
* Create a major key from alterations

@@ -150,3 +183,3 @@ * @function

* var key = require('tonal-key')
* key.fromAlter(2) // => ['major', 'D']
* key.fromAlter(2) // => 'D major'
*/

@@ -158,3 +191,4 @@ export function fromAlter (n) {

/**
* Create a major key from accidentals
* Get key name from accidentals
*
* @param {String} acc - the accidentals string

@@ -164,3 +198,4 @@ * @return {Key} the key object

* var key = require('tonal-key')
* key.fromAlter('bb') // => ['major', 'Bb']
* key.fromAcc('b') // => 'F major'
* key.fromAcc('##') // => 'D major'
*/

@@ -174,34 +209,19 @@ export function fromAcc (s) {

/**
* Create a key from key name
* @param {String} name - the key name
* @return {Key} the key object or null if not valid key
* Get scale of a key
*
* @param {String|Object} key
* @return {Array} the key scale
* @example
* var key = require('tonal-key')
* key.fromName('C3 dorian') // => ['dorian', 'C']
* key.fromName('blah') // => null
* key.scale('A major') // => [ 'A', 'B', 'C#', 'D', 'E', 'F#', 'G#' ]
* key.scale('Bb minor') // => [ 'Bb', 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab' ]
* key.scale('C dorian') // => [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ]
* key.scale('E mixolydian') // => [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ]
*/
export function fromName (str) {
if (typeof str !== 'string') return null
var p = str.split(/\s+/)
switch (p.length) {
case 1: return pc(p[0]) ? build(p[0], 'major') : build(false, p[0])
case 2: return build(p[0], p[1])
default: return null
}
export function scale (key) {
var p = props(key)
if (!p || !p.tonic) return null
return harmonize(SCALES[MODES.indexOf(p.mode)], p.tonic)
}
/**
* Try to interpret the given object as a key. Given an object it will try to
* parse as if it were a name, accidentals or alterations.
* @function
* @param {Object} obj
* @return {Key} the key object or null
*/
export function asKey (obj) {
return isKey(obj) ? obj : fromName(obj) || fromAcc(obj) || fromAlter(obj)
}
function modeNum (k) { return FIFTHS[MODES.indexOf(k[0])] }
/**
* Get key alteration. The alteration is a number indicating the number of

@@ -216,6 +236,6 @@ * sharpen notes (positive) or flaten notes (negative)

export function alteration (key) {
var k = asKey(key)
if (!k || !hasTonic(k)) return null
var toMajor = modeNum(k)
var toC = pcFifths(k[1])
var k = props(key)
if (!k || !k.tonic) return null
var toMajor = modeNum(k.mode)
var toC = pcFifths(k.tonic)
return toC - toMajor

@@ -222,0 +242,0 @@ }

{
"name": "tonal-key",
"version": "0.68.0",
"version": "0.68.1",
"description": "Conversion between key numbers and note names",

@@ -23,7 +23,7 @@ "repository": "https://github.com/danigb/tonal/packages/key",

"tonal-transpose": "^0.66.0",
"tonal-note": "^0.68.0",
"tonal-note": "^0.68.1",
"tonal-array": "^0.68.0",
"tonal-harmonizer": "^0.68.0",
"tonal-range": "^0.68.0"
"tonal-harmonizer": "^0.68.1",
"tonal-range": "^0.68.1"
}
}

@@ -5,83 +5,73 @@

test('scale', function (t) {
t.deepEqual(key.scale('C major'), [ 'C', 'D', 'E', 'F', 'G', 'A', 'B' ])
t.deepEqual(key.scale('C dorian'), [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ])
t.deepEqual(key.scale('E mixolydian'), [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ])
t.end()
})
test('isKeyMode', function (t) {
key.names(true).forEach(function (m) {
t.ok(key.isKeyMode(m), m)
test('key: mode', function (t) {
t.equal(key.mode('mixophrygian'), null)
t.equal(key.mode('blah'), null)
t.equal(key.mode(null), null)
key.modes(true).forEach(function (m) {
t.equal(key.mode(m), m)
})
t.equal(key.isKeyMode('blah'), false)
t.equal(key.isKeyMode(null), false)
t.end()
})
test('names', function (t) {
t.deepEqual(key.names(false),
[ 'ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian' ])
t.deepEqual(key.names(true),
[ 'ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian',
'major', 'minor' ])
test('key: tonic', function (t) {
t.equal(key.tonic('c4 mixolydian'), 'C')
t.equal(key.tonic('mixolydian'), null)
t.end()
})
test('build', function (t) {
t.deepEqual(key.build('C3', 'mixolydian'),
['mixolydian', 'C'])
t.deepEqual(key.build(null, 'phrygian'),
['phrygian', false])
t.deepEqual(key.build('blah', 'major'), null)
t.deepEqual(key.build('C', 'blah'), null)
test('key: props', function (t) {
t.deepEqual(key.props('Eb mixolydian'), { mode: 'mixolydian', tonic: 'Eb' })
t.deepEqual(key.props('lydian'), { mode: 'lydian', tonic: false })
t.deepEqual(key.props('F#'), { mode: 'major', tonic: 'F#' })
t.deepEqual(key.props('blah'), null)
t.deepEqual(key.props('Eb blah'), null)
t.end()
})
test('from alter', function (t) {
t.deepEqual([0, 1, 2, 3, 4, 5, 6, 7].map(key.fromAlter),
[ [ 'major', 'C' ], [ 'major', 'G' ], [ 'major', 'D' ], [ 'major', 'A' ],
[ 'major', 'E' ], [ 'major', 'B' ], [ 'major', 'F#' ], [ 'major', 'C#' ] ])
t.deepEqual([-0, -1, -2, -3, -4, -5, -6, -7, -8].map(key.fromAlter),
[ [ 'major', 'C' ], [ 'major', 'F' ], [ 'major', 'Bb' ], [ 'major', 'Eb' ],
[ 'major', 'Ab' ], [ 'major', 'Db' ], [ 'major', 'Gb' ], [ 'major', 'Cb' ],
[ 'major', 'Fb' ] ])
test('key: scale', function (t) {
t.deepEqual(key.scale('C major'), [ 'C', 'D', 'E', 'F', 'G', 'A', 'B' ])
t.deepEqual(key.scale('C dorian'), [ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ])
t.deepEqual(key.scale('E mixolydian'), [ 'E', 'F#', 'G#', 'A', 'B', 'C#', 'D' ])
t.end()
})
test('from accidentals', function (t) {
t.deepEqual(key.fromAcc('###'), [ 'major', 'A' ])
t.deepEqual(key.fromAcc('bbb'), [ 'major', 'Eb' ])
test('key: modes', function (t) {
t.deepEqual(key.modes(false),
[ 'ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian' ])
t.deepEqual(key.modes(true),
[ 'ionian', 'dorian', 'phrygian', 'lydian', 'mixolydian', 'aeolian', 'locrian',
'major', 'minor' ])
t.end()
})
test('from name', function (t) {
t.deepEqual(key.fromName('Eb mixolydian'), [ 'mixolydian', 'Eb' ])
t.deepEqual(key.fromName('lydian'), [ 'lydian', false ])
t.deepEqual(key.fromName('F#'), [ 'major', 'F#' ])
t.equal(key.fromName('blah'), null)
t.equal(key.fromName('Eb blah'), null)
test('from alter', function (t) {
t.deepEqual([0, 1, 2, 3, 4, 5, 6, 7].map(key.fromAlter),
[ 'C major', 'G major', 'D major', 'A major', 'E major',
'B major', 'F# major', 'C# major' ])
t.deepEqual([-0, -1, -2, -3, -4, -5, -6, -7, -8].map(key.fromAlter),
[ 'C major', 'F major', 'Bb major', 'Eb major', 'Ab major',
'Db major', 'Gb major', 'Cb major', 'Fb major' ])
t.end()
})
test('asKey', function (t) {
t.deepEqual(key.asKey('C minor'), ['minor', 'C'])
t.equal(key.asKey('blah'), null)
test('key: from accidentals', function (t) {
t.equal(key.fromAcc('###'), 'A major')
t.equal(key.fromAcc('bbb'), 'Eb major')
t.end()
})
test('relative', function (t) {
t.deepEqual(key.relative('minor', 'Eb major'), ['minor', 'C'])
t.deepEqual(key.relative('dorian', 'Bb mixolydian'), ['dorian', 'F'])
test('key: relative', function (t) {
t.equal(key.relative('minor', 'Eb major'), 'C minor')
t.equal(key.relative('dorian', 'Bb mixolydian'), 'F dorian')
t.equal(key.relative('blah', 'C major'), null)
var minor = key.relative('minor')
t.deepEqual(minor('C'), [ 'minor', 'A' ])
t.equal(minor('C'), 'A minor')
t.end()
})
test('alteration', function (t) {
test('key: alteration', function (t) {
t.equal(key.alteration('A major'), 3)
var Amaj = 'A B C# D E F# G#'.split(' ')
var modes = key.names(false)
var modes = key.modes(false)
Amaj.forEach(function (tonic, i) {

@@ -88,0 +78,0 @@ t.equal(key.alteration(tonic + ' ' + modes[i]), 3)

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc