UNPKG

qambi

Version:

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

126 lines (106 loc) 4.07 kB
'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 } */