tonal-pitchset
Advanced tools
Comparing version 0.64.0 to 0.64.1
@@ -5,9 +5,32 @@ 'use strict'; | ||
var tonalNote = require('tonal-note'); | ||
var tonalPitch = require('tonal-pitch'); | ||
var tonalArray = require('tonal-array'); | ||
var tonalTranspose = require('tonal-transpose'); | ||
function toInt (set) { return parseInt(toBinary(set), 2) } | ||
function chroma (p) { p = tonalPitch.asPitch(p); return p ? tonalPitch.chr(p) : null } | ||
/** | ||
* Convert a pitch set into a binary representation | ||
* Get the pitchset binary rotations of a list of notes | ||
*/ | ||
function rotations (set, normalize) { | ||
normalize = normalize !== false | ||
var binary = toBinary(set).split('') | ||
return tonalArray.compact(binary.map(function (_, i) { | ||
var r = tonalArray.rotate(i, binary) | ||
return normalize && r[0] === '0' ? null : r.join('') | ||
})) | ||
} | ||
var REGEX = /^[01]{12}$/ | ||
/** | ||
* Test if the given value is a pitch set in binary representation | ||
*/ | ||
function isBinary (set) { | ||
return REGEX.test(set) | ||
} | ||
/** | ||
* Convert a pitch set into a binary representation. If the argument is | ||
* already a binary representation it returns it. | ||
* | ||
@@ -20,4 +43,5 @@ * @param {Array|String} set - the pitch set | ||
function toBinary (set) { | ||
if (isBinary(set)) return set | ||
var b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | ||
tonalArray.map(tonalNote.chroma, set).forEach(function (i) { | ||
tonalArray.map(chroma, set).forEach(function (i) { | ||
b[i] = 1 | ||
@@ -29,2 +53,35 @@ }) | ||
/** | ||
* Get a pitch set with different tonic | ||
* @param {String|Pitch} tonic - the desired tonic | ||
* @param {Array|String} set - the list of notes or the binary representation | ||
* @param {Array} a list of notes or intervals (depending the root) | ||
* @example | ||
* pitchset.withTonic('c d e f g a b', 'D') | ||
*/ | ||
function withTonic (tonic, set) { | ||
if (arguments.length === 1) return function (s) { return withTonic(tonic, s) } | ||
return fromBinary(toBinary(set), tonic) | ||
} | ||
var IVLS = '1P 2m 2M 3m 3M 4P 5d 5P 6m 6M 7m 7M'.split(' ') | ||
/** | ||
* Given a pitch set in binary notation it returns the intervals or notes | ||
* (depending on the tonic) | ||
* @param {String} binary - the pitch set in binary representation | ||
* @param {String|Pitch} tonic - the pitch set tonic | ||
* @return {Array} a list of notes or intervals | ||
* @example | ||
* pitchset.fromBinary('101010101010', 'C') // => ['C', 'D', 'E', 'Gb', 'Ab', 'Bb'] | ||
*/ | ||
function fromBinary (binary, tonic) { | ||
if (arguments.length === 1) return function (t) { return fromBinary(binary, t) } | ||
if (!isBinary(binary)) return null | ||
tonic = tonic || 'P1' | ||
return tonalArray.compact(binary.split('').map(function (d, i) { | ||
return d === '1' ? tonalTranspose.transpose(IVLS[i], tonic) : null | ||
})) | ||
} | ||
/** | ||
* Test if two pitch sets are identical | ||
@@ -84,3 +141,3 @@ * | ||
set = toBinary(set) | ||
return function (note) { return set[tonalNote.chroma(note)] === '1' } | ||
return function (note) { return set[chroma(note)] === '1' } | ||
} | ||
@@ -103,3 +160,7 @@ | ||
exports.rotations = rotations; | ||
exports.isBinary = isBinary; | ||
exports.toBinary = toBinary; | ||
exports.withTonic = withTonic; | ||
exports.fromBinary = fromBinary; | ||
exports.equal = equal; | ||
@@ -106,0 +167,0 @@ exports.subset = subset; |
63
index.js
@@ -10,9 +10,32 @@ /** | ||
*/ | ||
import { chroma } from 'tonal-note' | ||
import { map, asArr } from 'tonal-array' | ||
import { chr, asPitch } from 'tonal-pitch' | ||
import { map, asArr, rotate, compact } from 'tonal-array' | ||
import { transpose } from 'tonal-transpose' | ||
function toInt (set) { return parseInt(toBinary(set), 2) } | ||
function chroma (p) { p = asPitch(p); return p ? chr(p) : null } | ||
/** | ||
* Convert a pitch set into a binary representation | ||
* Get the pitchset binary rotations of a list of notes | ||
*/ | ||
export function rotations (set, normalize) { | ||
normalize = normalize !== false | ||
var binary = toBinary(set).split('') | ||
return compact(binary.map(function (_, i) { | ||
var r = rotate(i, binary) | ||
return normalize && r[0] === '0' ? null : r.join('') | ||
})) | ||
} | ||
var REGEX = /^[01]{12}$/ | ||
/** | ||
* Test if the given value is a pitch set in binary representation | ||
*/ | ||
export function isBinary (set) { | ||
return REGEX.test(set) | ||
} | ||
/** | ||
* Convert a pitch set into a binary representation. If the argument is | ||
* already a binary representation it returns it. | ||
* | ||
@@ -25,2 +48,3 @@ * @param {Array|String} set - the pitch set | ||
export function toBinary (set) { | ||
if (isBinary(set)) return set | ||
var b = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] | ||
@@ -34,2 +58,35 @@ map(chroma, set).forEach(function (i) { | ||
/** | ||
* Get a pitch set with different tonic | ||
* @param {String|Pitch} tonic - the desired tonic | ||
* @param {Array|String} set - the list of notes or the binary representation | ||
* @param {Array} a list of notes or intervals (depending the root) | ||
* @example | ||
* pitchset.withTonic('c d e f g a b', 'D') | ||
*/ | ||
export function withTonic (tonic, set) { | ||
if (arguments.length === 1) return function (s) { return withTonic(tonic, s) } | ||
return fromBinary(toBinary(set), tonic) | ||
} | ||
var IVLS = '1P 2m 2M 3m 3M 4P 5d 5P 6m 6M 7m 7M'.split(' ') | ||
/** | ||
* Given a pitch set in binary notation it returns the intervals or notes | ||
* (depending on the tonic) | ||
* @param {String} binary - the pitch set in binary representation | ||
* @param {String|Pitch} tonic - the pitch set tonic | ||
* @return {Array} a list of notes or intervals | ||
* @example | ||
* pitchset.fromBinary('101010101010', 'C') // => ['C', 'D', 'E', 'Gb', 'Ab', 'Bb'] | ||
*/ | ||
export function fromBinary (binary, tonic) { | ||
if (arguments.length === 1) return function (t) { return fromBinary(binary, t) } | ||
if (!isBinary(binary)) return null | ||
tonic = tonic || 'P1' | ||
return compact(binary.split('').map(function (d, i) { | ||
return d === '1' ? transpose(IVLS[i], tonic) : null | ||
})) | ||
} | ||
/** | ||
* Test if two pitch sets are identical | ||
@@ -36,0 +93,0 @@ * |
{ | ||
"name": "tonal-pitchset", | ||
"version": "0.64.0", | ||
"version": "0.64.1", | ||
"description": "Pitch set utilities", | ||
@@ -16,5 +16,6 @@ "keywords": [], | ||
"dependencies": { | ||
"tonal-note": "^0.64.0", | ||
"tonal-array": "^0.64.0" | ||
"tonal-pitch": "^0.64.0", | ||
"tonal-transpose": "^0.64.0", | ||
"tonal-array": "^0.64.1" | ||
} | ||
} |
@@ -7,5 +7,37 @@ var test = require('tape') | ||
t.equal(pitchset.toBinary('g g#4 a bb5'), '000000011110') | ||
t.equal(pitchset.toBinary('P1 M2 M3 P4 P5 M6 M7'), | ||
pitchset.toBinary('c d e f g a b')) | ||
t.equal(pitchset.toBinary('101010101010'), '101010101010') | ||
t.end() | ||
}) | ||
test('pitchset: fromBinary', function (t) { | ||
t.deepEqual(pitchset.fromBinary('101010101010', 'C'), | ||
[ 'C', 'D', 'E', 'Gb', 'Ab', 'Bb' ]) | ||
t.deepEqual(pitchset.fromBinary('101010101010', null), | ||
[ '1P', '2M', '3M', '5d', '6m', '7m' ]) | ||
t.end() | ||
}) | ||
test('pitchset: modes', function (t) { | ||
// TODO: fixme, the 4th mode should have F# instead of Gb | ||
t.deepEqual(pitchset.rotations('c d e f g a b').map(pitchset.withTonic('C')), | ||
[ [ 'C', 'D', 'E', 'F', 'G', 'A', 'B' ], | ||
[ 'C', 'D', 'Eb', 'F', 'G', 'A', 'Bb' ], | ||
[ 'C', 'Db', 'Eb', 'F', 'G', 'Ab', 'Bb' ], | ||
[ 'C', 'D', 'E', 'Gb', 'G', 'A', 'B' ], | ||
[ 'C', 'D', 'E', 'F', 'G', 'A', 'Bb' ], | ||
[ 'C', 'D', 'Eb', 'F', 'G', 'Ab', 'Bb' ], | ||
[ 'C', 'Db', 'Eb', 'F', 'Gb', 'Ab', 'Bb' ] ]) | ||
t.end() | ||
}) | ||
test('pitchset: isBinary', function (t) { | ||
t.equal(pitchset.isBinary('101010101010'), true) | ||
t.equal(pitchset.isBinary('1010101'), false) | ||
t.equal(pitchset.isBinary('blah'), false) | ||
t.equal(pitchset.isBinary('c d e'), false) | ||
t.end() | ||
}) | ||
test('pitchset: subset', function (t) { | ||
@@ -42,1 +74,13 @@ t.equal(pitchset.subset('c4 d5 e6', 'c2 d3'), true) | ||
}) | ||
test('pitchset: rotations', function (t) { | ||
t.deepEqual(pitchset.rotations('c d e f g a b'), | ||
[ '101011010101', '101101010110', '110101011010', '101010110101', | ||
'101011010110', '101101011010', '110101101010' ]) | ||
t.deepEqual(pitchset.rotations('c d e f g a b', false), | ||
[ '101011010101', '010110101011', '101101010110', '011010101101', | ||
'110101011010', '101010110101', '010101101011', '101011010110', | ||
'010110101101', '101101011010', '011010110101', '110101101010' ]) | ||
t.deepEqual(pitchset.rotations('blah bleh'), []) | ||
t.end() | ||
}) |
14091
370
3
+ Addedtonal-pitch@^0.64.0
+ Addedtonal-transpose@^0.64.0
- Removedtonal-note@^0.64.0
- Removedtonal-freq@0.61.0(transitive)
- Removedtonal-midi@0.61.0(transitive)
- Removedtonal-note@0.64.0(transitive)
Updatedtonal-array@^0.64.1