!function(e){ if("object"===typeof exports&&"undefined"!==typeof module){ module.exports=e(); }else if("function"===typeof define&&define.amd){ define([],e); }else{ var f;"undefined"!==typeof window?f=window:"undefined"!==typeof global?f=global:"undefined"!==typeof self&&(f=self),f.teoria=e(); } }(function(){ var define,module,exports;return (function e(t,n,r){ function s(o,u){ if(!n[o]){ if(!t[o]){ var a=typeof require==="function"&&require;if(!u&&a){ return a(o,!0); }if(i){ return i(o,!0); }var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f; }var l=n[o]={ exports : {} };t[o][0].call(l.exports,function(e){ var n=t[o][1][e];return s(n?n:e); },l,l.exports,e,t,n,r); }return n[o].exports; }var i=typeof require==="function"&&require;for(var o=0;o 0) ? val : val - 2; }, type : function() { return knowledge.intervals[this.base()][0] <= 1 ? "perfect" : "minor"; }, base : function() { var fifth = vector.sub(this.coord, vector.mul(knowledge.sharp, this.qualityValue()))[1], name; fifth = this.value() > 0 ? fifth + 5 : -(fifth - 5) % 7; fifth = fifth < 0 ? knowledge.intervalFromFifth.length + fifth : fifth; name = knowledge.intervalFromFifth[fifth]; if (name === "unison" && this.number() >= 8) { name = "octave"; } return name; }, direction : function(dir) { if (dir) { var is = this.value() >= 1 ? "up" : "down"; if (is !== dir) { this.coord = vector.mul(this.coord, -1); } return this; } else { return this.value() >= 1 ? "up" : "down"; } }, simple : function(ignore) { // Get the (upwards) base interval (with quality) var simple = knowledge.intervals[this.base()]; simple = vector.add(simple, vector.mul(knowledge.sharp, this.qualityValue())); // Turn it around if necessary if (!ignore) { simple = this.direction() === "down" ? vector.mul(simple, -1) : simple; } return new Interval(simple); }, isCompound : function() { return this.number() > 8; }, octaves : function() { var without, octaves; if (this.direction() === "up") { without = vector.sub(this.coord, vector.mul(knowledge.sharp, this.qualityValue())); octaves = without[0] - knowledge.intervals[this.base()][0]; } else { without = vector.sub(this.coord, vector.mul(knowledge.sharp, -this.qualityValue())); octaves = -(without[0] + knowledge.intervals[this.base()][0]); } return octaves; }, invert : function() { var i = this.base(); var qual = this.qualityValue(); var acc = this.type() === "minor" ? -(qual - 1) : -qual; var coord = knowledge.intervals[knowledge.intervalsIndex[9 - knowledge.stepNumber[i] - 1]]; coord = vector.add(coord, vector.mul(knowledge.sharp, acc)); return new Interval(coord); }, quality : function(lng) { var quality = knowledge.alterations[this.type()][this.qualityValue() + 2]; return lng ? knowledge.qualityLong[quality] : quality; }, qualityValue : function() { if (this.direction() === "down") { return Math.floor((-this.coord[1] - 2) / 7) + 1; } else { return Math.floor((this.coord[1] - 2) / 7) + 1; } }, equal : function(interval) { return this.coord[0] === interval.coord[0] && this.coord[1] === interval.coord[1]; }, greater : function(interval) { var semi = this.semitones(); var isemi = interval.semitones(); // If equal in absolute size, measure which interval is bigger // For example P4 is bigger than A3 return (semi === isemi) ? (this.number() > interval.number()) : (semi > isemi); }, smaller : function(interval) { return !this.equal(interval) && !this.greater(interval); }, add : function(interval) { return new Interval(vector.add(this.coord, interval.coord)); }, toString : function(ignore) { // If given true, return the positive value var number = ignore ? this.number() : this.value(); return this.quality() + number; } }; Interval.toCoord = function(simple) { var coord = toCoord(simple); if (!coord) { throw new Error("Invalid simple format interval"); } return new Interval(coord); }; Interval.from = function(from, to) { return from.interval(to); }; Interval.between = function(from, to) { return new Interval(vector.sub(to.coord, from.coord)); }; Interval.invert = function(sInterval) { return Interval.toCoord(sInterval).invert().toString(); }; module.exports = Interval; },{ "./knowledge" : 4,"./vector" : 8,"interval-coords" : 13 }],4 : [function(require,module,exports){ // Note coordinates [octave, fifth] relative to C module.exports = { notes : { c : [0, 0], d : [-1, 2], e : [-2, 4], f : [1, -1], g : [0, 1], a : [-1, 3], b : [-2, 5], h : [-2, 5] }, intervals : { unison : [0, 0], second : [3, -5], third : [2, -3], fourth : [1, -1], fifth : [0, 1], sixth : [3, -4], seventh : [2, -2], octave : [1, 0] }, intervalFromFifth : ["second", "sixth", "third", "seventh", "fourth", "unison", "fifth"], intervalsIndex : ["unison", "second", "third", "fourth", "fifth", "sixth", "seventh", "octave", "ninth", "tenth", "eleventh", "twelfth", "thirteenth", "fourteenth", "fifteenth"], // linaer index to fifth = (2 * index + 1) % 7 fifths : ["f", "c", "g", "d", "a", "e", "b"], accidentals : ["bb", "b", "", "#", "x"], sharp : [-4, 7], A4 : [3, 3], durations : { "0.25" : "longa", "0.5" : "breve", "1" : "whole", "2" : "half", "4" : "quarter", "8" : "eighth", "16" : "sixteenth", "32" : "thirty-second", "64" : "sixty-fourth", "128" : "hundred-twenty-eighth" }, qualityLong : { P : "perfect", M : "major", m : "minor", A : "augmented", AA : "doubly augmented", d : "diminished", dd : "doubly diminished" }, alterations : { perfect : ["dd", "d", "P", "A", "AA"], minor : ["dd", "d", "m", "M", "A", "AA"] }, symbols : { "min" : ["m3", "P5"], "m" : ["m3", "P5"], "-" : ["m3", "P5"], "M" : ["M3", "P5"], "" : ["M3", "P5"], "+" : ["M3", "A5"], "aug" : ["M3", "A5"], "dim" : ["m3", "d5"], "o" : ["m3", "d5"], "maj" : ["M3", "P5", "M7"], "dom" : ["M3", "P5", "m7"], "ø" : ["m3", "d5", "m7"], "5" : ["P5"] }, chordShort : { "major" : "M", "minor" : "m", "augmented" : "aug", "diminished" : "dim", "half-diminished" : "7b5", "power" : "5", "dominant" : "7" }, stepNumber : { "unison" : 1, "first" : 1, "second" : 2, "third" : 3, "fourth" : 4, "fifth" : 5, "sixth" : 6, "seventh" : 7, "octave" : 8, "ninth" : 9, "eleventh" : 11, "thirteenth" : 13 }, // Adjusted Shearer syllables - Chromatic solfege system // Some intervals are not provided for. These include: // dd2 - Doubly diminished second // dd3 - Doubly diminished third // AA3 - Doubly augmented third // dd6 - Doubly diminished sixth // dd7 - Doubly diminished seventh // AA7 - Doubly augmented seventh intervalSolfege : { "dd1" : "daw", "d1" : "de", "P1" : "do", "A1" : "di", "AA1" : "dai", "d2" : "raw", "m2" : "ra", "M2" : "re", "A2" : "ri", "AA2" : "rai", "d3" : "maw", "m3" : "me", "M3" : "mi", "A3" : "mai", "dd4" : "faw", "d4" : "fe", "P4" : "fa", "A4" : "fi", "AA4" : "fai", "dd5" : "saw", "d5" : "se", "P5" : "so", "A5" : "si", "AA5" : "sai", "d6" : "law", "m6" : "le", "M6" : "la", "A6" : "li", "AA6" : "lai", "d7" : "taw", "m7" : "te", "M7" : "ti", "A7" : "tai", "dd8" : "daw", "d8" : "de", "P8" : "do", "A8" : "di", "AA8" : "dai" } }; },{}],5 : [function(require,module,exports){ var scientific = require("scientific-notation"); var helmholtz = require("helmholtz"); var knowledge = require("./knowledge"); var vector = require("./vector"); var Interval = require("./interval"); function pad(str, ch, len) { for (; len > 0; len--) { str += ch; } return str; } function Note(coord, duration) { if (!(this instanceof Note)) { return new Note(coord, duration); } duration = duration || {}; this.duration = { value : duration.value || 4, dots : duration.dots || 0 }; this.coord = coord; } Note.prototype = { octave : function() { return this.coord[0] + knowledge.A4[0] - knowledge.notes[this.name()][0] + this.accidentalValue() * 4; }, name : function() { return knowledge.fifths[this.coord[1] + knowledge.A4[1] - this.accidentalValue() * 7 + 1]; }, accidentalValue : function() { return Math.round((this.coord[1] + knowledge.A4[1] - 2) / 7); }, accidental : function() { return knowledge.accidentals[this.accidentalValue() + 2]; }, /** * Returns the key number of the note */ key : function(white) { if (white) { return this.coord[0] * 7 + this.coord[1] * 4 + 29; } else { return this.coord[0] * 12 + this.coord[1] * 7 + 49; } }, /** * Returns a number ranging from 0-127 representing a MIDI note value */ midi : function() { return this.key() + 20; }, /** * Calculates and returns the frequency of the note. * Optional concert pitch (def. 440) */ fq : function(concertPitch) { concertPitch = concertPitch || 440; return concertPitch * Math.pow(2, (this.coord[0] * 12 + this.coord[1] * 7) / 12); }, /** * Returns the pitch class index (chroma) of the note */ chroma : function() { var value = (vector.sum(vector.mul(this.coord, [12, 7])) - 3) % 12; return (value < 0) ? value + 12 : value; }, interval : function(interval) { if (typeof interval === "string") { interval = Interval.toCoord(interval); } if (interval instanceof Interval) { return new Note(vector.add(this.coord, interval.coord)); } else if (interval instanceof Note) { return new Interval(vector.sub(interval.coord, this.coord)); } }, transpose : function(interval) { this.coord = vector.add(this.coord, interval.coord); return this; }, /** * Returns the Helmholtz notation form of the note (fx C,, d' F# g#'') */ helmholtz : function() { var octave = this.octave(); var name = this.name(); name = octave < 3 ? name.toUpperCase() : name.toLowerCase(); var padchar = octave < 3 ? "," : "'"; var padcount = octave < 2 ? 2 - octave : octave - 3; return pad(name + this.accidental(), padchar, padcount); }, /** * Returns the scientific notation form of the note (fx E4, Bb3, C#7 etc.) */ scientific : function() { return this.name().toUpperCase() + this.accidental() + this.octave(); }, /** * Returns notes that are enharmonic with this note. */ enharmonics : function(oneaccidental) { var key = this.key(), limit = oneaccidental ? 2 : 3; return ["m3", "m2", "m-2", "m-3"] .map(this.interval.bind(this)) .filter(function(note) { var acc = note.accidentalValue(); var diff = key - (note.key() - acc); if (diff < limit && diff > -limit) { note.coord = vector.add(note.coord, vector.mul(knowledge.sharp, diff - acc)); return true; } }); }, solfege : function(scale, showOctaves) { var interval = scale.tonic.interval(this), solfege, stroke, count; if (interval.direction() === "down") { interval = interval.invert(); } if (showOctaves) { count = (this.key(true) - scale.tonic.key(true)) / 7; count = (count >= 0) ? Math.floor(count) : -(Math.ceil(-count)); stroke = (count >= 0) ? "'" : ","; } solfege = knowledge.intervalSolfege[interval.simple(true).toString()]; return (showOctaves) ? pad(solfege, stroke, Math.abs(count)) : solfege; }, scaleDegree : function(scale) { var inter = scale.tonic.interval(this); // If the direction is down, or we're dealing with an octave - invert it if (inter.direction() === "down" || (inter.coord[1] === 0 && inter.coord[0] !== 0)) { inter = inter.invert(); } inter = inter.simple(true).coord; return scale.scale.reduce(function(index, current, i) { var coord = Interval.toCoord(current).coord; return coord[0] === inter[0] && coord[1] === inter[1] ? i + 1 : index; }, 0); }, /** * Returns the name of the duration value, * such as 'whole', 'quarter', 'sixteenth' etc. */ durationName : function() { return knowledge.durations[this.duration.value]; }, /** * Returns the duration of the note (including dots) * in seconds. The first argument is the tempo in beats * per minute, the second is the beat unit (i.e. the * lower numeral in a time signature). */ durationInSeconds : function(bpm, beatUnit) { var secs = (60 / bpm) / (this.duration.value / 4) / (beatUnit / 4); return secs * 2 - secs / Math.pow(2, this.duration.dots); }, /** * Returns the name of the note, with an optional display of octave number */ toString : function(dont) { return this.name() + this.accidental() + (dont ? "" : this.octave()); } }; Note.fromString = function(name, dur) { var coord = scientific(name); if (!coord) { coord = helmholtz(name); } return new Note(coord, dur); }; Note.fromKey = function(key) { var octave = Math.floor((key - 4) / 12); var distance = key - (octave * 12) - 4; var name = knowledge.fifths[(2 * Math.round(distance / 2) + 1) % 7]; var note = vector.add(vector.sub(knowledge.notes[name], knowledge.A4), [octave + 1, 0]); var diff = (key - 49) - vector.sum(vector.mul(note, [12, 7])); return new Note(diff ? vector.add(note, vector.mul(knowledge.sharp, diff)) : note); }; Note.fromFrequency = function(fq, concertPitch) { var key, cents, originalFq; concertPitch = concertPitch || 440; key = 49 + 12 * ((Math.log(fq) - Math.log(concertPitch)) / Math.log(2)); key = Math.round(key); originalFq = concertPitch * Math.pow(2, (key - 49) / 12); cents = 1200 * (Math.log(fq / originalFq) / Math.log(2)); return { note : Note.fromKey(key), cents : cents }; }; Note.fromMIDI = function(note) { return Note.fromKey(note - 20); }; module.exports = Note; },{ "./interval" : 3,"./knowledge" : 4,"./vector" : 8,"helmholtz" : 10,"scientific-notation" : 14 }],6 : [function(require,module,exports){ var knowledge = require("./knowledge"); var Interval = require("./interval"); var scales = { aeolian : ["P1", "M2", "m3", "P4", "P5", "m6", "m7"], blues : ["P1", "m3", "P4", "A4", "P5", "m7"], chromatic : ["P1", "m2", "M2", "m3", "M3", "P4", "A4", "P5", "m6", "M6", "m7", "M7"], dorian : ["P1", "M2", "m3", "P4", "P5", "M6", "m7"], doubleharmonic : ["P1", "m2", "M3", "P4", "P5", "m6", "M7"], harmonicminor : ["P1", "M2", "m3", "P4", "P5", "m6", "M7"], ionian : ["P1", "M2", "M3", "P4", "P5", "M6", "M7"], locrian : ["P1", "m2", "m3", "P4", "d5", "m6", "m7"], lydian : ["P1", "M2", "M3", "A4", "P5", "M6", "M7"], majorpentatonic : ["P1", "M2", "M3", "P5", "M6"], melodicminor : ["P1", "M2", "m3", "P4", "P5", "M6", "M7"], minorpentatonic : ["P1", "m3", "P4", "P5", "m7"], mixolydian : ["P1", "M2", "M3", "P4", "P5", "M6", "m7"], phrygian : ["P1", "m2", "m3", "P4", "P5", "m6", "m7"] }; // synonyms scales.harmonicchromatic = scales.chromatic; scales.minor = scales.aeolian; scales.major = scales.ionian; scales.flamenco = scales.doubleharmonic; function Scale(tonic, scale) { if (!(this instanceof Scale)) { return new Scale(tonic, scale); } var scaleName, i; if (!("coord" in tonic)) { throw new Error("Invalid Tonic"); } if (typeof scale === "string") { scaleName = scale; scale = scales[scale]; if (!scale) { throw new Error("Invalid Scale"); } } else { for (i in scales) { if (scales.hasOwnProperty(i)) { if (scales[i].toString() === scale.toString()) { scaleName = i; break; } } } } this.name = scaleName; this.tonic = tonic; this.scale = scale; } Scale.prototype = { notes : function() { var notes = []; for (var i = 0, length = this.scale.length; i < length; i++) { notes.push(this.tonic.interval(this.scale[i])); } return notes; }, simple : function() { return this.notes().map(function(n) { return n.toString(true); }); }, type : function() { var length = this.scale.length - 2; if (length < 8) { return ["di", "tri", "tetra", "penta", "hexa", "hepta", "octa"][length] + "tonic"; } }, get : function(i) { i = (typeof i === "string" && i in knowledge.stepNumber) ? knowledge.stepNumber[i] : i; return this.tonic.interval(this.scale[i - 1]); }, solfege : function(index, showOctaves) { if (index) { return this.get(index).solfege(this, showOctaves); } return this.notes().map(function(n) { return n.solfege(this, showOctaves); }); }, interval : function(interval) { interval = (typeof interval === "string") ? Interval.toCoord(interval) : interval; return new Scale(this.tonic.interval(interval), this.scale); }, transpose : function(interval) { var scale = this.interval(interval); this.scale = scale.scale; this.tonic = scale.tonic; return this; } }; module.exports = Scale; },{ "./interval" : 3,"./knowledge" : 4 }],7 : [function(require,module,exports){ var knowledge = require("./knowledge"); module.exports = function(teoria) { var Note = teoria.Note; var Chord = teoria.Chord; var Scale = teoria.Scale; Note.prototype.chord = function(chord) { chord = (chord in knowledge.chordShort) ? knowledge.chordShort[chord] : chord; return new Chord(this, chord); }; Note.prototype.scale = function(scale) { return new Scale(this, scale); }; }; },{ "./knowledge" : 4 }],8 : [function(require,module,exports){ module.exports = { add : function(note, interval) { return [note[0] + interval[0], note[1] + interval[1]]; }, sub : function(note, interval) { return [note[0] - interval[0], note[1] - interval[1]]; }, mul : function(note, interval) { if (typeof interval === "number") { return [note[0] * interval, note[1] * interval]; } else { return [note[0] * interval[0], note[1] * interval[1]]; } }, sum : function(coord) { return coord[0] + coord[1]; } }; },{}],9 : [function(require,module,exports){ var SYMBOLS = { "m" : ["m3", "P5"], "mi" : ["m3", "P5"], "min" : ["m3", "P5"], "-" : ["m3", "P5"], "M" : ["M3", "P5"], "ma" : ["M3", "P5"], "" : ["M3", "P5"], "+" : ["M3", "A5"], "aug" : ["M3", "A5"], "dim" : ["m3", "d5"], "o" : ["m3", "d5"], "maj" : ["M3", "P5", "M7"], "dom" : ["M3", "P5", "m7"], "ø" : ["m3", "d5", "m7"], "5" : ["P5"], "6/9" : ["M3", "P5", "M6", "M9"] }; module.exports = function(symbol) { var c, parsing = "quality", additionals = [], name, chordLength = 2; var notes = ["P1", "M3", "P5", "m7", "M9", "P11", "M13"]; var explicitMajor = false; function setChord(name) { var intervals = SYMBOLS[name]; for (var i = 0, len = intervals.length; i < len; i++) { notes[i + 1] = intervals[i]; } chordLength = intervals.length; } // Remove whitespace, commas and parentheses symbol = symbol.replace(/[,\s\(\)]/g, ""); for (var i = 0, len = symbol.length; i < len; i++) { if (!(c = symbol[i])) { return; } if (parsing === "quality") { var sub3 = (i + 2) < len ? symbol.substr(i, 3).toLowerCase() : null; var sub2 = (i + 1) < len ? symbol.substr(i, 2).toLowerCase() : null; if (sub3 in SYMBOLS) { name = sub3; } else if (sub2 in SYMBOLS) { name = sub2; } else if (c in SYMBOLS) { name = c; } else { name = ""; } if (name) { setChord(name); } if (name === "M" || name === "ma" || name === "maj") { explicitMajor = true; } i += name.length - 1; parsing = "extension"; } else if (parsing === "extension") { c = (c === "1" && symbol[i + 1]) ? +symbol.substr(i, 2) : +c; if (!isNaN(c) && c !== 6) { chordLength = (c - 1) / 2; if (chordLength !== Math.round(chordLength)) { return new Error("Invalid interval extension: " + c.toString(10)); } if (name === "o" || name === "dim") { notes[3] = "d7"; } else if (explicitMajor) { notes[3] = "M7"; } i += c >= 10 ? 1 : 0; } else if (c === 6) { notes[3] = "M6"; chordLength = Math.max(3, chordLength); } else { i -= 1; } parsing = "alterations"; } else if (parsing === "alterations") { var alterations = symbol.substr(i).split(/(#|b|add|maj|sus|M)/i), next, flat = false, sharp = false; if (alterations.length === 1) { return new Error("Invalid alteration"); } else if (alterations[0].length !== 0) { return new Error("Invalid token: '" + alterations[0] + "'"); } var ignore = false; alterations.forEach(function(alt, i, arr) { if (ignore || !alt.length) { return ignore = false; } var next = arr[i + 1], lower = alt.toLowerCase(); if (alt === "M" || lower === "maj") { if (next === "7") { ignore = true; } chordLength = Math.max(3, chordLength); notes[3] = "M7"; } else if (lower === "sus") { var type = "P4"; if (next === "2" || next === "4") { ignore = true; if (next === "2") { type = "M2"; } } notes[1] = type; // Replace third with M2 or P4 } else if (lower === "add") { if (next === "9") { additionals.push("M9"); } else if (next === "11") { additionals.push("P11"); } else if (next === "13") { additionals.push("M13"); } ignore = true; } else if (lower === "b") { flat = true; } else if (lower === "#") { sharp = true; } else { var token = +alt, quality, intPos; if (isNaN(token) || String(token).length !== alt.length) { return new Error("Invalid token: '" + alt + "'"); } if (token === 6) { if (sharp) { notes[3] = "A6"; } else if (flat) { notes[3] = "m6"; } else { notes[3] = "M6"; } chordLength = Math.max(3, chordLength); return; } // Calculate the position in the 'note' array intPos = (token - 1) / 2; if (chordLength < intPos) { chordLength = intPos; } if (token < 5 || token === 7 || intPos !== Math.round(intPos)) { return new Error("Invalid interval alteration: " + token); } quality = notes[intPos][0]; // Alterate the quality of the interval according the accidentals if (sharp) { if (quality === "d") { quality = "m"; } else if (quality === "m") { quality = "M"; } else if (quality === "M" || quality === "P") { quality = "A"; } } else if (flat) { if (quality === "A") { quality = "M"; } else if (quality === "M") { quality = "m"; } else if (quality === "m" || quality === "P") { quality = "d"; } } sharp = flat = false; notes[intPos] = quality + token; } }); parsing = "ended"; } else if (parsing === "ended") { break; } } return notes.slice(0, chordLength + 1).concat(additionals); }; },{}],10 : [function(require,module,exports){ var coords = require("notecoord"); var accval = require("accidental-value"); module.exports = function helmholtz(name) { var name = name.replace(/\u2032/g, "'").replace(/\u0375/g, ","); var parts = name.match(/^(,*)([a-h])(x|#|bb|b?)([,\']*)$/i); if (!parts || name !== parts[0]) { throw new Error("Invalid formatting"); } var note = parts[2]; var octaveFirst = parts[1]; var octaveLast = parts[4]; var lower = note === note.toLowerCase(); var octave; if (octaveFirst) { if (lower) { throw new Error("Invalid formatting - found commas before lowercase note"); } octave = 2 - octaveFirst.length; } else if (octaveLast) { if (octaveLast.match(/^'+$/) && lower) { octave = 3 + octaveLast.length; } else if (octaveLast.match(/^,+$/) && !lower) { octave = 2 - octaveLast.length; } else { throw new Error("Invalid formatting - mismatch between octave " + "indicator and letter case"); } } else { octave = lower ? 3 : 2; } var accidentalValue = accval.interval(parts[3].toLowerCase()); var coord = coords(note.toLowerCase()); coord[0] += octave; coord[0] += accidentalValue[0] - coords.A4[0]; coord[1] += accidentalValue[1] - coords.A4[1]; return coord; }; },{ "accidental-value" : 11,"notecoord" : 12 }],11 : [function(require,module,exports){ var accidentalValues = { "bb" : -2, "b" : -1, "" : 0, "#" : 1, "x" : 2 }; module.exports = function accidentalNumber(acc) { return accidentalValues[acc]; }; module.exports.interval = function accidentalInterval(acc) { var val = accidentalValues[acc]; return [-4 * val, 7 * val]; }; },{}],12 : [function(require,module,exports){ // First coord is octaves, second is fifths. Distances are relative to c var notes = { c : [0, 0], d : [-1, 2], e : [-2, 4], f : [1, -1], g : [0, 1], a : [-1, 3], b : [-2, 5], h : [-2, 5] }; module.exports = function(name) { return name in notes ? [notes[name][0], notes[name][1]] : null; }; module.exports.notes = notes; module.exports.A4 = [3, 3]; // Relative to C0 (scientic notation, ~16.35Hz) module.exports.sharp = [-4, 7]; },{}],13 : [function(require,module,exports){ var pattern = /^(AA|A|P|M|m|d|dd)(-?\d+)$/; // The interval it takes to raise a note a semitone var sharp = [-4, 7]; var pAlts = ["dd", "d", "P", "A", "AA"]; var mAlts = ["dd", "d", "m", "M", "A", "AA"]; var baseIntervals = [ [0, 0], [3, -5], [2, -3], [1, -1], [0, 1], [3, -4], [2, -2], [1, 0] ]; module.exports = function(simple) { var parser = simple.match(pattern); if (!parser) { return null; } var quality = parser[1]; var number = +parser[2]; var sign = number < 0 ? -1 : 1; number = sign < 0 ? -number : number; var lower = number > 8 ? (number % 7 || 7) : number; var octaves = (number - lower) / 7; var base = baseIntervals[lower - 1]; var alts = base[0] <= 1 ? pAlts : mAlts; var alt = alts.indexOf(quality) - 2; // this happens, if the alteration wasn't suitable for this type // of interval, such as P2 or M5 (no "perfect second" or "major fifth") if (alt === -3) { return null; } return [ sign * (base[0] + octaves + sharp[0] * alt), sign * (base[1] + sharp[1] * alt) ]; }; // Copy to avoid overwriting internal base intervals module.exports.coords = baseIntervals.slice(0); },{}],14 : [function(require,module,exports){ var coords = require("notecoord"); var accval = require("accidental-value"); module.exports = function scientific(name) { var format = /^([a-h])(x|#|bb|b?)(-?\d*)/i; parser = name.match(format); if (!(parser && name === parser[0] && parser[3].length)) { return; } var noteName = parser[1]; var octave = +parser[3]; var accidental = parser[2].length ? parser[2].toLowerCase() : ""; var accidentalValue = accval.interval(accidental); var coord = coords(noteName.toLowerCase()); coord[0] += octave; coord[0] += accidentalValue[0] - coords.A4[0]; coord[1] += accidentalValue[1] - coords.A4[1]; return coord; }; },{ "accidental-value" : 15,"notecoord" : 16 }],15 : [function(require,module,exports){ arguments[4][11][0].apply(exports,arguments); },{ "dup" : 11 }],16 : [function(require,module,exports){ arguments[4][12][0].apply(exports,arguments); },{ "dup" : 12 }] },{},[1])(1); });