!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) });