'use strict'
var memoize = require('../memoize')
var R = require('./regex')
var BASES = { C: [0, 0], D: [2, -1], E: [4, -2], F: [-1, 1], G: [1, 0], A: [3, -1], B: [5, -2] }
/**
* Get a pitch in [array notation]()
* from a string in [scientific pitch notation](https://en.wikipedia.org/wiki/Scientific_pitch_notation)
*
* The string to parse must be in the form of: `letter[accidentals][octave]`
* The accidentals can be up to four # (sharp) or b (flat) or two x (double sharps)
*
* This function is cached for better performance.
*
* @name note.parse
* @function
* @param {String} str - the string to parse
* @return {Array} the note in array notation or null if not valid note
*
* @example
* var parse = require('music-notation/note/parse')
* parse('C') // => [ 0 ]
* parse('c#') // => [ 8 ]
* parse('c##') // => [ 16 ]
* parse('Cx') // => [ 16 ] (double sharp)
* parse('Cb') // => [ -6 ]
* parse('db') // => [ -4 ]
* parse('G4') // => [ 2, 3, null ]
* parse('c#3') // => [ 8, -1, null ]
*/
module.exports = memoize(function (str) {
var m = R.exec(str)
if (!m || m[5]) return null
var base = BASES[m[1].toUpperCase()]
var alt = m[2].replace(/x/g, '##').length
if (m[2][0] === 'b') alt *= -1
var fifths = base[0] + 7 * alt
if (!m[3]) return [fifths]
var oct = +m[3] + base[1] - 4 * alt
var dur = m[4] ? +(m[4].substring(1)) : null
return [fifths, oct, dur]
})
|