qambi
Version:
MIDI sequencer, loads MIDI files, can record and playback MIDI, uses WebMIDI and WebAudio
214 lines (178 loc) • 5.67 kB
JavaScript
;
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;
}