qambi
Version:
MIDI sequencer, loads MIDI files, can record and playback MIDI, uses WebMIDI and WebAudio
126 lines (106 loc) • 4.07 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.MIDIEvent = undefined;
var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); // @ flow
var _note = require('./note');
var _settings = require('./settings');
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var instanceIndex = 0;
var MIDIEvent = exports.MIDIEvent = function () {
function MIDIEvent(ticks, type, data1) {
var data2 = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : -1;
var channel = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 0;
_classCallCheck(this, MIDIEvent);
this.id = this.constructor.name + '_' + instanceIndex++ + '_' + new Date().getTime();
this.ticks = ticks;
this.data1 = data1;
this.data2 = data2;
this.pitch = (0, _settings.getSettings)().pitch;
/* test whether type is a status byte or a command: */
// 1. the higher 4 bits of the status byte form the command
this.type = (type >> 4) * 16;
//this.type = this.command = (type >> 4) * 16
// 2. filter channel events
if (this.type >= 0x80 && this.type <= 0xE0) {
// 3. get the channel number
if (channel > 0) {
// a channel is set, this overrules the channel number in the status byte
this.channel = channel;
} else {
// extract the channel from the status byte: the lower 4 bits of the status byte form the channel number
this.channel = type & 0xF;
}
//this.status = this.command + this.channel
} else {
// 4. not a channel event, set the type and command to the value of type as provided in the constructor
this.type = type;
//this.type = this.command = type
this.channel = 0; // any
}
//console.log(type, this.type, this.command, this.status, this.channel, this.id)
// sometimes NOTE_OFF events are sent as NOTE_ON events with a 0 velocity value
if (type === 144 && data2 === 0) {
this.type = 128;
}
this._part = null;
this._track = null;
this._song = null;
if (type === 144 || type === 128) {
var _getNoteData = (0, _note.getNoteData)({ number: data1 });
this.noteName = _getNoteData.name;
this.fullNoteName = _getNoteData.fullName;
this.frequency = _getNoteData.frequency;
this.octave = _getNoteData.octave;
}
//@TODO: add all other properties
}
_createClass(MIDIEvent, [{
key: 'copy',
value: function copy() {
var m = new MIDIEvent(this.ticks, this.type, this.data1, this.data2);
return m;
}
}, {
key: 'transpose',
value: function transpose(amount) {
// may be better if not a public method?
this.data1 += amount;
this.frequency = this.pitch * Math.pow(2, (this.data1 - 69) / 12);
}
}, {
key: 'updatePitch',
value: function updatePitch(newPitch) {
if (newPitch === this.pitch) {
return;
}
this.pitch = newPitch;
this.transpose(0);
}
}, {
key: 'move',
value: function move(ticks) {
this.ticks += ticks;
if (this.midiNote) {
this.midiNote.update();
}
}
}, {
key: 'moveTo',
value: function moveTo(ticks) {
this.ticks = ticks;
if (this.midiNote) {
this.midiNote.update();
}
}
}]);
return MIDIEvent;
}();
/*
export function deleteMIDIEvent(event){
//event.note = null
event.note = null
event = null
}
*/