nativeScript-midi
一个用于与 MIDI 设备(例如乐器或应用)通信的 NativeScript 插件。
npm i --save nativescript-midi

nativeScript-midi

一个用于与 MIDI 设备(例如乐器或应用)通信的 NativeScript 插件。

要使用此插件,需要具备对 MIDI (音乐仪器数字接口) 通信协议的基本理解。

项目状态:不再开发 / 维护

此插件旨在允许使用统一的接口在 iOS 和 Android 上进行 MIDI 通信,但目前只完成了 iOS 平台的实施。我已经开始开发 Android 实现 ,但最终我将注意力转移到了另一个项目,并且目前没有计划完成开发或为新版本的 NativeScript 兼容性进行维护 (> v2)。

安装

假设您已经安装了 NativeScript CLI

tns plugin add nativescript-midi

编程接口

应用程序通过类似于 Android MIDI API 的接口与插件交互

  • MidiDeviceManager:检索可用的 MIDI 设备并通知应用程序设备更改。
  • MidiDevice:一个具有输入端口和输出端口的命名设备,通过这些端口进行通信。
  • MidiInputPort:提供一种方法,使应用程序可以向设备发送 MIDI 消息。
  • MidiOutputPort:通知应用程序从设备接收到的消息。

有关这些接口的更多信息,请参阅 API 文档

示例

import { MidiDeviceManager } from 'nativescript-midi';


let midiDeviceManager = new MidiDeviceManager(),
midiDevices;

midiDeviceManager.getDevices()
.then(devices => {

midiDevices = devices; // Save a reference to the devices for later use in the app.

// Listen for device added / removed / updated events.
midiDeviceManager.addDeviceAddedListener(deviceAdded => { /* handle added device */ });
midiDeviceManager.addDeviceRemovedListener(deviceRemoved => { /* handle removed device */ });
midiDeviceManager.addDeviceUpdatedListener(deviceUpdated => { /* handle updated device (e.g. ports changed) */ });

// Let's assume for this example that we know there's a device with at least one input port and one output port.
let device = midiDevices.find(device => device.inputPorts.length && device.outputPorts.length);

// Here we listen for any messages from the device (i.e. from all outputPorts), but alternatively, you can listen for messages on just a single port with `device.outputPorts[i].addMessageListener()`
device.addMessageListener((messages, outputPort) => {

let portIndex = device.outputPorts.indexOf(outputPort);

// The packets received from a system's MIDI device (i.e. MIDIPacketList on iOS) are automatically parsed into discrete messages for you 👍.
for (let message of messages) {

console.log(`Received a MIDI message from outputPort ${portIndex} of device ${device.name}:`);
console.log(message instanceof Uint8Array); // `true`
message.forEach((byte, byteIndex) => console.log(`byte ${byteIndex}: ${byte}`));
}
});

console.log(`Sending a message to inputPort 0 of device ${device.name} to play middle-C...`);

let bytes = new Uint8Array([
0x90, // "Note On" status byte
0x3C, // Pitch value for middle-C
0xFF // Full volume
]);

// Here we send a message to a single input port on the device. Alternatively, you can send the message to *all* of the device's input ports with `device.send()`.
return device.inputPort[0].send({ bytes });
})
.then(() => console.log(`Successfully finished sending the MIDI message 🎵`))
.catch(error => console.log(`Yikes - something went wrong. ` + error.stack));

日志记录

插件类内部记录信息。要捕获或显示此日志信息,请使用实现一个 Winston 风格的记录器的 logger 对象来构建 MidiDeviceManager

let logger = {

info(message, metadata) {
console.log(`INFO: ${message} ${JSON.stringify(metadata)}`);
},

warn(message, metadata) {
console.log(`WARN: ${message} ${JSON.stringify(metadata)}`);
},

error(message, metadata) {
console.log(`ERROR: ${message} ${JSON.stringify(metadata)}`);
}
};

let midiDeviceManager = new MidiDeviceManager({ logger });

贡献

欢迎贡献,特别是在 1.0 版本发布所需的 Android 工作方面。

构建

此模块用 ES 6 实现,并转换为 ES 5 以导出。要构建源代码

npm run build

还有一个 git 预提交钩子,在提交时自动构建,因为 dist 目录已提交。

代码检查

npm run lint

项目依赖项

MIDI 数据包(即 iOS 上的 MIDIPacketList)可以包含多个 MIDI 消息,单个 MIDI 系统专用(SysEx)消息可以跨越多个数据包。此详细信息被隐藏在插件消费者中,因此应用程序仅接收已解析和验证的消息数组。

此消息解析逻辑在 midi-message-parser C 库 中实现,我还将其用于一个单独的 MIDI 硬件产品中,该产品可以与此插件通信。使用 cocoa-midi-message-parser 包装器将此 C 库公开给 NativeScript 运行时,并避免一些运行时关于 C 互操作的限制(例如,不支持包含数组的 C 结构)。

nativescript-midi
|
|-- cocoa-midi-message-parser
|
|-- midi-message-parser

署名

感谢 Pete Goodliffe,他是开源 PGMidi 库的作者,该库在 nativescript-midi 中内部使用。