twelvetet-spn
Version:
Scientific pitch notation parser/formatter for Node.js and the browser
91 lines (73 loc) • 3.35 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
var data = [[null, 0], ['B#', 0], ['C', 0], [null, 0], ['Dbb', 0], ['Bx', 1], ['C#', 1], [null, 1], ['Db', 1], [null, 1], ['Cx', 2], [null, 2], ['D', 2], [null, 2], ['Ebb', 2], [null, 3], ['D#', 3], [null, 3], ['Eb', 3], ['Fbb', 3], ['Dx', 4], [null, 4], ['E', 4], ['Fb', 4], [null, 4], [null, 5], ['E#', 5], ['F', 5], [null, 5], ['Gbb', 5], ['Ex', 6], ['F#', 6], [null, 6], ['Gb', 6], [null, 6], ['Fx', 7], [null, 7], ['G', 7], [null, 7], ['Abb', 7], [null, 8], ['G#', 8], [null, 8], ['Ab', 8], [null, 8], ['Gx', 9], [null, 9], ['A', 9], [null, 9], ['Bbb', 9], [null, 10], ['A#', 10], [null, 10], ['Bb', 10], ['Cbb', 10], ['Ax', 11], [null, 11], ['B', 11], ['Cb', 11], [null, 11]];
var isArray = (function (value) {
return (/^\[object Array\]$/.test(Object.prototype.toString.call(value))
);
});
var isInteger = (function (value) {
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value;
});
/**
* Formats a musical pitch to scientific pitch notation.
*
* @function format
* @memberof module:twelvetet-spn
* @param {Array.<Number>} value An array representing the musical pitch's class and octave.
* @param {Number} value.0 The pitch class of the musical pitch.
* @param {Number} value.1 The octave of the musical pitch.
* @returns {Array} An array of scientific pitch notation enharmonic equivalents of the musical pitch.
* The array always has 5 elements. The order is always `[<double sharp>, <sharp>, <natural>, <flat>, <double flat>]`.
* An element of the array is `null` if there is no corresponding enharmonic equivalent
* @throws {TypeError} Will throw an error if the `value` argument is not an array
*/
var format = (function (value) {
if (!isArray(value)) {
throw new Error('Missing or invalid value. Array expected.');
}
var pitchClass = value[0];
var octave = value[1];
if (!isInteger(pitchClass)) {
throw new Error('Missing or invalid pitch class. Integer expected.');
}
if (!isInteger(octave)) {
throw new Error('Missing or invalid octave. Integer expected.');
}
return data.filter(function (datum) {
return datum[1] === pitchClass;
}).map(function (datum) {
return datum[0] != null ? datum[0] + octave : null;
});
});
/**
* Parses scientific pitch notation of a musical pitch.
*
* @function parse
* @memberof module:twelvetet-spn
* @param {String} value Scientific pitch notation of a musical pitch.
* @returns {Array.<Number>} An array representing the musical pitch's class and octave.
* @throws {TypeError} Will throw an error if the `value` argument is not a string
*/
var parse = (function (value) {
if (typeof value !== 'string') {
throw new TypeError('Missing or invalid value. String expected.');
}
var re = /^(.*?)(-?\d+)$/i;
var found = value.match(re);
if (found == null) {
return null;
}
var name = found[1].toLowerCase().replace(/^./, function (l) {
return l.toUpperCase();
});
var datum = data.find(function (datum) {
return datum[0] === name;
});
if (datum == null) {
return null;
}
return [datum[1], +found[2]];
});
/** @module twelvetet-spn */
exports.format = format;
exports.parse = parse;