UNPKG

qambi

Version:

MIDI sequencer, loads MIDI files, can record and playback MIDI, uses WebMIDI and WebAudio

214 lines (178 loc) 5.67 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.getNoteData = getNoteData; var _settings = require('./settings'); var pow = Math.pow; var floor = Math.floor; //const checkNoteName = /^[A-G]{1}(b{0,2}}|#{0,2})[\-]{0,1}[0-9]{1}$/ var regexCheckNoteName = /^[A-G]{1}(b|bb|#|##){0,1}$/; var regexCheckFullNoteName = /^[A-G]{1}(b|bb|#|##){0,1}(\-1|[0-9]{1})$/; var regexSplitFullName = /^([A-G]{1}(b|bb|#|##){0,1})(\-1|[0-9]{1})$/; var regexGetOctave = /(\-1|[0-9]{1})$/; var noteNames = { sharp: ['C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B'], flat: ['C', 'Db', 'D', 'Eb', 'E', 'F', 'Gb', 'G', 'Ab', 'A', 'Bb', 'B'], 'enharmonic-sharp': ['B#', 'C#', 'C##', 'D#', 'D##', 'E#', 'F#', 'F##', 'G#', 'G##', 'A#', 'A##'], 'enharmonic-flat': ['Dbb', 'Db', 'Ebb', 'Eb', 'Fb', 'Gbb', 'Gb', 'Abb', 'Ab', 'Bbb', 'Bb', 'Cb'] }; var noteNameMode = void 0; var pitch = void 0; /* settings = { name: 'C', octave: 4, fullName: 'C4', number: 60, frequency: 234.16 // not yet implemented } */ function getNoteData(settings) { var fullName = settings.fullName, name = settings.name, octave = settings.octave, mode = settings.mode, number = settings.number, frequency = settings.frequency; var _getSettings = (0, _settings.getSettings)(); noteNameMode = _getSettings.noteNameMode; pitch = _getSettings.pitch; if (typeof name !== 'string' && typeof fullName !== 'string' && typeof number !== 'number' && typeof frequency !== 'number') { return null; } if (number < 0 || number > 127) { console.log('please provide a note between 0 (C-1) and 127 (G9)'); return null; } mode = _checkNoteNameMode(mode); //console.log(mode) if (typeof number === 'number') { var _getNoteName2 = _getNoteName(number, mode); fullName = _getNoteName2.fullName; name = _getNoteName2.name; octave = _getNoteName2.octave; } else if (typeof name === 'string') { if (regexCheckNoteName.test(name)) { fullName = '' + name + octave; number = _getNoteNumber(name, octave); } else { console.log('invalid name ' + name); return null; } } else if (typeof fullName === 'string') { if (regexCheckFullNoteName.test(fullName)) { var _splitFullName2 = _splitFullName(fullName); octave = _splitFullName2.octave; name = _splitFullName2.name; number = _getNoteNumber(name, octave); } else { console.log('invalid fullname ' + fullName); return null; } } var data = { name: name, octave: octave, fullName: fullName, number: number, frequency: _getFrequency(number), blackKey: _isBlackKey(number) //console.log(data) };return data; } function _getNoteName(number) { var mode = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : noteNameMode; //let octave = Math.floor((number / 12) - 2), // → in Cubase central C = C3 instead of C4 var octave = floor(number / 12 - 1); var name = noteNames[mode][number % 12]; return { fullName: '' + name + octave, name: name, octave: octave }; } function _getOctave(fullName) { return parseInt(fullName.match(regexGetOctave)[0], 10); } function _splitFullName(fullName) { var octave = _getOctave(fullName); return { octave: octave, name: fullName.replace(octave, '') }; } function _getNoteNumber(name, octave) { var keys = Object.keys(noteNames); var index = void 0; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = keys[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var key = _step.value; var mode = noteNames[key]; index = mode.findIndex(function (x) { return x === name; }); if (index !== -1) { break; } } //number = (index + 12) + (octave * 12) + 12 // → in Cubase central C = C3 instead of C4 } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } var number = index + 12 + octave * 12; // → midi standard + scientific naming, see: http://en.wikipedia.org/wiki/Middle_C and http://en.wikipedia.org/wiki/Scientific_pitch_notation if (number < 0 || number > 127) { console.log('please provide a note between 0 (C-1) and 127 (G9)'); return -1; } return number; } function _getFrequency(number) { return pitch * pow(2, (number - 69) / 12); // midi standard, see: http://en.wikipedia.org/wiki/MIDI_Tuning_Standard } //@TODO: calculate note from frequency function _getPitch(hertz) { //fm = 2(m−69)/12(440 Hz). } function _checkNoteNameMode(mode) { var keys = Object.keys(noteNames); var result = keys.includes(mode); //console.log(result) if (result === false) { if (typeof mode !== 'undefined') { console.log(mode + ' is not a valid note name mode, using "' + noteNameMode + '" instead'); } mode = noteNameMode; } return mode; } function _isBlackKey(noteNumber) { var black = void 0; switch (true) { case noteNumber % 12 === 1: //C# case noteNumber % 12 === 3: //D# case noteNumber % 12 === 6: //F# case noteNumber % 12 === 8: //G# case noteNumber % 12 === 10: //A# black = true; break; default: black = false; } return black; }