UNPKG

@showbridge/lib

Version:

Main library for showbridge protocol router

174 lines (173 loc) 6.86 kB
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); }; var _MIDIProtocol_instances, _MIDIProtocol_getPortName, _MIDIProtocol_findMidiOutput; import { MIDIMessage } from '../messages/index.js'; import { disabled, logger } from '../utils/index.js'; import { Input, Output } from '@julusian/midi'; import Protocol from './protocol.js'; class MIDIProtocol extends Protocol { constructor(protocolObj, router) { super(protocolObj, router); _MIDIProtocol_instances.add(this); this.inputs = []; this.outputs = []; } reload(params) { // if (midi === undefined) { // logger.error('midi: midi library not loaded skipping reload'); // this.emit('started'); // return; // } if (this.virtualInput) { this.virtualInput.destroy(); delete this.virtualInput; } if (this.virtualOutput) { this.virtualOutput.destroy(); delete this.virtualInput; } this.virtualInput = new Input(); this.virtualOutput = new Output(); this.virtualInputName = `showbridge Input`; this.virtualOutputName = `showbridge Output`; if (params?.virtualInputName) { this.virtualInputName = params.virtualInputName; } this.virtualInput.openVirtualPort(this.virtualInputName); this.virtualInput.ignoreTypes(false, false, false); if (params?.virtualOutputName) { this.virtualOutputName = params.virtualOutputName; } this.virtualOutput.openVirtualPort(this.virtualOutputName); this.virtualInput.on('message', (deltaTime, msg) => { try { const midiMessage = new MIDIMessage(msg, 'virtual'); this.emit('messageIn', midiMessage); } catch (error) { logger.error(`midi: problem processing MIDI message - ${error}`); } }); // TODO(jwetzell): look into better way to reload inputs // TODO(jwetzell): consider letting the user configure the inputs that are loaded this.inputs.forEach((input) => { if (input.isPortOpen()) { input.destroy(); } }); this.inputs = []; for (let index = 0; index < this.virtualInput.getPortCount(); index += 1) { const input = new Input(); this.inputs.push(input); input.openPort(index); input.ignoreTypes(false, false, false); input.on('message', (deltaTime, msg) => { try { const midiMessage = new MIDIMessage(msg, __classPrivateFieldGet(this, _MIDIProtocol_instances, "m", _MIDIProtocol_getPortName).call(this, input, index)); this.emit('messageIn', midiMessage); } catch (error) { logger.error(`midi: problem processing MIDI message - ${error}`); } }); } this.outputs.forEach((output) => { if (output.output.isPortOpen()) { output.output.destroy(); } }); this.outputs = []; for (let index = 0; index < this.virtualOutput.getPortCount(); index += 1) { const output = new Output(); const outputName = __classPrivateFieldGet(this, _MIDIProtocol_instances, "m", _MIDIProtocol_getPortName).call(this, output, index); this.outputs.push({ name: outputName, index, output, }); } this.emit('started'); // TODO(jwetzell): find a way to detect midi device changes } send(bytes, port) { const output = port === undefined ? this.virtualOutput : __classPrivateFieldGet(this, _MIDIProtocol_instances, "m", _MIDIProtocol_findMidiOutput).call(this, port); if (output === undefined) { logger.error(`midi: no midi device found with name ${port}`); return; } try { output.sendMessage(bytes); } catch (error) { logger.error('midi: problem sending midi'); logger.error(error); } } stop() { this.stopped = true; this.inputs.forEach((input) => { input.destroy(); }); this.outputs.forEach((output) => { output.output.destroy(); }); if (this.virtualInput) { this.virtualInput.destroy(); } if (this.virtualOutput) { this.virtualOutput.destroy(); } this.emit('stopped'); } get status() { const devices = []; try { this.inputs.forEach((port, index) => { if (!this.stopped && port.isPortOpen()) { devices.push({ type: 'input', name: __classPrivateFieldGet(this, _MIDIProtocol_instances, "m", _MIDIProtocol_getPortName).call(this, port, index), }); } }); this.outputs.forEach((output) => { devices.push({ type: 'output', name: output.name, }); }); } catch (error) { logger.error('midi: problem assembling midi status'); logger.error(error); } return { enabled: !disabled.protocols.has('midi'), // && midi !== undefined, devices, }; } } _MIDIProtocol_instances = new WeakSet(), _MIDIProtocol_getPortName = function _MIDIProtocol_getPortName(port, index) { if (process.platform === 'linux') { const rawPortName = port.getPortName(index); const parts = rawPortName.match(/^(.*):(.*)\s+(\d+:\d+)$/); if (parts) { return parts[2]; } return rawPortName; } return port.getPortName(index); }, _MIDIProtocol_findMidiOutput = function _MIDIProtocol_findMidiOutput(port) { const foundOutput = this.outputs.find((output) => output.name === port); if (foundOutput !== undefined && foundOutput.output !== undefined) { if (!foundOutput.output.isPortOpen()) { foundOutput.output.openPort(foundOutput.index); } return foundOutput.output; } return undefined; }; export default MIDIProtocol;