npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

nativescript-midi

v0.0.6

Published

A NativeScript plugin for communicating with MIDI devices (e.g. musical instruments or apps).

Downloads

4

Readme

nativescript-midi

A NativeScript plugin for communicating with MIDI devices (e.g. musical instruments or apps).

A basic understanding of the MIDI (Musical Instrument Digital Interface) message protocol is required to use this plugin.

Project status: No Longer Developed / Maintained

This plugin has been designed to allow a uniform interface to be used for MIDI communication on both iOS and Android, however only the iOS platform implementation has been finished. I started to develop the Android implementation, but I ultimately shifted my focus to a different project, and I currently have no plans to finish development or to maintain it for compatibility with new NativeScript versions (> v2).

Installation

Assuming you've already installed the NativeScript CLI:

tns plugin add nativescript-midi

Programming interfaces

An application interacts with the plugin through interfaces which resemble those in Android's MIDI API:

  • MidiDeviceManager: Fetches available MIDI devices and notifies the application of device changes.
  • MidiDevice: A named device with input ports and output ports through which communication occurs.
  • MidiInputPort: Provides a method by which an application can send MIDI messages to the device.
  • MidiOutputPort: Notifies the application of messages received from the device.

For more information on these interfaces, check out the API docs.

Example

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));

Logging

The plugin's classes log information internally. To capture or display this log info, construct the MidiDeviceManager with a logger object that implements a Winston-style logger.

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 });

Contributing

Contributions are welcome, especially on the Android work that's needed for the 1.0 release.

Building

This module is implemented in ES 6 and transpiled to ES 5 for export. To build the source:

npm run build

There's also a git pre-commit hook that automatically builds upon commit, since the dist directory is committed.

Linting

npm run lint

Project Dependencies

A MIDI packet (i.e. MIDIPacketList on iOS) can contain multiple MIDI messages, and a single MIDI System Exclusive (SysEx) message can span multiple packets. This detail is hidden from the plugin consumer so that the application just receives an array of messages that have already been parsed and validated.

This message parsing logic is implemented in the midi-message-parser C library, which I am also using within a separate a MIDI hardware product with which this plugin can communicate. The cocoa-midi-message-parser wrapper is used to expose this C library to the NativeScript runtime and to avoid some of the runtime's limitations surrounding C interop (e.g. lack of support for C structs which contain arrays).

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

Attribution

Thank you to Pete Goodliffe, author of the open source PGMidi library that is used internally by nativescript-midi.