Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

rewrite on node-api #228

Draft
wants to merge 19 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
github: [julusian]
148 changes: 148 additions & 0 deletions .github/workflows/node.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
name: Prebuild

on:
push:
# tags:
# - v*

env:
NAPI_VERSION: 7
BINDING_NAME: midi

jobs:
build-and-test:
name: Build ${{ matrix.arch }} on ${{ matrix.os }} ${{ matrix.libc }}
runs-on: ${{ matrix.os }}

strategy:
fail-fast: false
matrix:
include:
# windows
- os: windows-2019
arch: x64
is-native: true
- os: windows-2019
arch: ia32
is-native: false
# macos
- os: macos-11
arch: arm64
is-native: false
- os: macos-10.15
arch: x64
is-native: true
# linux
- os: ubuntu-18.04
arch: x64
is-native: true
# linux-libc
- os: ubuntu-latest
arch: arm64
is-native: false
docker-arch: linux/arm64
docker-image: node:14-buster
- os: ubuntu-latest
arch: arm
is-native: false
docker-arch: linux/arm/v7
docker-image: node:14-buster
# linux-musl
- os: ubuntu-latest
arch: x64
is-native: false
docker-arch: linux/amd64
docker-image: node:14-alpine
libc: musl

steps:
- uses: actions/checkout@v2
- name: Checkout submodules
shell: bash
run: |
auth_header="$(git config --local --get http.https://github.com/.extraheader)"
git submodule sync --recursive
git -c "http.extraheader=$auth_header" -c protocol.version=2 submodule update --init --force --recursive --depth=1

- name: Install Linux dependencies
if: runner.os == 'Linux'
run: |
sudo apt-get update
sudo apt-get install -y libasound2-dev

- name: Use Node.js 14.x
uses: actions/setup-node@v1
with:
node-version: 14.x

- name: rebuild
if: ${{ !matrix.docker-arch }}
shell: bash
run: |
yarn

# if [ -n "${{ matrix.is-native }}" ]; then
# yarn test
# fi

yarn rebuild --arch=${{ matrix.arch }}
yarn pkg-prebuilds-copy --source build/Release/$BINDING_NAME.node --name=$BINDING_NAME --strip --napi_version=$NAPI_VERSION --arch=${{ matrix.arch }}
env:
CI: true
npm_config_build_from_source: true

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
if: matrix.docker-arch
- name: rebuild (in docker)
uses: addnab/docker-run-action@v3
if: matrix.docker-arch
with:
image: ${{ matrix.docker-image }}
# shell: bash
options: --platform=${{ matrix.docker-arch }} -v ${{ github.workspace }}:/work -e CI=1 -e npm_config_build_from_source=1 -e NAPI_VERSION -e BINDING_NAME
run: |
if command -v apt-get &> /dev/null
then
apt-get update
apt-get install -y libasound2-dev
elif command -v apk &> /dev/null
then
apk update
apk add python3 make g++ gcc alsa-lib-dev
fi

cd /work

yarn
# yarn test

yarn pkg-prebuilds-copy --source build/Release/$BINDING_NAME.node --name=$BINDING_NAME --strip --napi_version=$NAPI_VERSION --arch=${{ matrix.arch }} --libc=${{ matrix.libc }}

- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: ${{ runner.os }}-${{ matrix.arch }}-${{ matrix.libc }}-prebuilds
path: prebuilds
retention-days: 1

bundle:
name: Bundle prebuilds
needs: build-and-test
runs-on: ubuntu-latest
steps:
- uses: actions/download-artifact@v3
with:
path: tmp

- name: Display structure of downloaded files
run: |
mkdir prebuilds
mv tmp/*/* prebuilds/

- name: Upload artifacts
uses: actions/upload-artifact@v3
with:
name: all-prebuilds
path: prebuilds
retention-days: 7
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ build/
node_modules/
.vscode/
.vs/
prebuilds/
2 changes: 1 addition & 1 deletion .gitmodules
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
[submodule "vendor/rtmidi"]
path = vendor/rtmidi
url = https://github.com/justinlatimer/rtmidi.git
url = https://github.com/thestk/rtmidi.git
19 changes: 0 additions & 19 deletions .travis.yml

This file was deleted.

1 change: 1 addition & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Copyright (C) 2011-2021 by Justin Latimer.
Copyright (C) 2022 by Julian Waller.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
43 changes: 13 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,44 +1,25 @@
♪ ♫ ♩ ♬

# node-midi
# @julusian/midi

A node.js wrapper for the RtMidi C++ library that provides realtime MIDI I/O.
RtMidi supports Linux (ALSA & Jack), Macintosh OS X (CoreMidi), and Windows
(Multimedia).

[![Build Status](https://travis-ci.com/justinlatimer/node-midi.svg?branch=master)](https://travis-ci.com/github/justinlatimer/node-midi)

## Prerequisites

### OSX

* Some version of Xcode (or Command Line Tools)
* Python (for node-gyp)

### Windows

* Microsoft Visual C++ (the Express edition works fine)
* Python (for node-gyp)

### Linux

* A C++ compiler
* You must have installed and configured ALSA. Without it this module will **NOT** build.
* Install the libasound2-dev package.
* Python (for node-gyp)
This is an api compatible alternative to [midi](https://www.npmjs.com/package/midi), updated to work with modern nodejs.

## Installation

Installation uses node-gyp and requires Python 2.7.2 or higher.
Prebuilds are available for all common platforms. If you are using an uncommon platform you may need a C++ compiler and Python 3.

From npm:
```bash
$ npm install midi
$ npm install @julusian/midi
```

From source:
```bash
$ git clone https://github.com/justinlatimer/node-midi.git
$ git clone https://github.com/julusian/node-midi.git
$ cd node-midi/
$ npm install
```
Expand All @@ -54,7 +35,7 @@ For list of midi status codes, see http://www.midi.org/techspecs/midimessages.ph
### Input

```js
const midi = require('midi');
const midi = require('@julusian/midi');

// Set up a new input.
const input = new midi.Input();
Expand Down Expand Up @@ -97,7 +78,7 @@ setTimeout(function() {
### Output

```js
const midi = require('midi');
const midi = require('@julusian/midi');

// Set up a new output.
const output = new midi.Output();
Expand Down Expand Up @@ -126,7 +107,7 @@ connect to. This can be done simply by calling openVirtualPort(portName) instead
of openPort(portNumber).

```js
const midi = require('midi');
const midi = require('@julusian/midi');

// Set up a new input.
const input = new midi.Input();
Expand Down Expand Up @@ -191,19 +172,21 @@ require('fs').createReadStream('something.bin').pipe(stream2);

## Maintainers

* Justin Latimer - [@justinlatimer](https://github.com/justinlatimer)
* Elijah Insua - [@tmpvar](https://github.com/tmpvar)
* Andrew Morton - [@drewish](https://github.com/drewish)
* Julian Waller - [@julusian](https://github.com/julusian)

## Contributors

* Justin Latimer - [@justinlatimer](https://github.com/justinlatimer)
* Elijah Insua - [@tmpvar](https://github.com/tmpvar)
* Andrew Morton - [@drewish](https://github.com/drewish)
* Luc Deschenaux - [@luxigo](https://github.com/luxigo)
* Michael Alyn Miller - [@malyn](https://github.com/malyn)
* Hugo Hromic - [@hhromic](https://github.com/hhromic)

## License

Copyright (C) 2011-2021 by Justin Latimer.
Copyright (C) 2022 by Julian Waller.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
4 changes: 4 additions & 0 deletions binding-options.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
module.exports = {
name: 'midi',
napi_versions: [7],
}
12 changes: 10 additions & 2 deletions binding.gyp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,17 @@
'targets': [
{
'target_name': 'midi',
'cflags!': [ '-fno-exceptions' ],
'cflags_cc!': [ '-fno-exceptions' ],
'xcode_settings': { 'GCC_ENABLE_CPP_EXCEPTIONS': 'YES',
'CLANG_CXX_LIBRARY': 'libc++',
'MACOSX_DEPLOYMENT_TARGET': '10.7',
},
'msvs_settings': {
'VCCLCompilerTool': { 'ExceptionHandling': 1 },
},
'include_dirs': [
"<!(node -e \"require('nan')\")",
'<!(node -p "require(\'node-addon-api\').include_dir")',
'src',
'vendor/rtmidi'
],
Expand Down Expand Up @@ -60,7 +69,6 @@
},
'defines': [
'__WINDOWS_MM__',
'RT_SYSEX_BUFFER_SIZE=2048',
'RTMIDI_DO_NOT_ENSURE_UNIQUE_PORTNAMES'
],
'link_settings': {
Expand Down
72 changes: 72 additions & 0 deletions midi.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/// <reference types="node" />

import * as Stream from 'stream';
import * as EventEmitter from 'events';

/**
* An array of numbers corresponding to the MIDI bytes: [status, data1, data2].
* See https://www.cs.cf.ac.uk/Dave/Multimedia/node158.html for more info.
*/
export type MidiMessage = [number, number, number];
export type MidiCallback = (deltaTime: number, message: MidiMessage) => void;

export class Input extends EventEmitter {
/** Close the midi port */
closePort(): void;
/** Count the available input ports */
getPortCount(): number;
/** Get the name of a specified input port */
getPortName(port: number): string;
isPortOpen(): boolean
/**
* Sysex, timing, and active sensing messages are ignored by default. To
* enable these message types, pass false for the appropriate type in the
* function below. Order: (Sysex, Timing, Active Sensing) For example if
* you want to receive only MIDI Clock beats you should use
* input.ignoreTypes(true, false, true)
*/
ignoreTypes(sysex: boolean, timing: boolean, activeSensing: boolean): void;
/** Open the specified input port */
openPort(port: number): void;
/**
* Instead of opening a connection to an existing MIDI device, on Mac OS X
* and Linux with ALSA you can create a virtual device that other software
* may connect to. This can be done simply by calling
* openVirtualPort(portName) instead of openPort(portNumber).
*/
openVirtualPort(port: string): void;

on(event: 'message', callback: MidiCallback): this;
}

export class Output {
/** Close the midi port */
closePort(): void;
/** Count the available output ports */
getPortCount(): number;
/** Get the name of a specified output port */
getPortName(port: number): string;
isPortOpen(): boolean
/** Open the specified output port */
openPort(port: number): void;
/**
* Instead of opening a connection to an existing MIDI device, on Mac OS X
* and Linux with ALSA you can create a virtual device that other software
* may connect to. This can be done simply by calling
* openVirtualPort(portName) instead of openPort(portNumber).
*/
openVirtualPort(port: string): void;
/** Send a MIDI message */
send(message: MidiMessage): void;
/** Send a MIDI message */
sendMessage(message: MidiMessage): void;
}

/** @deprecated */
export const input: typeof Input;
/** @deprecated */
export const output: typeof Output;

export function createReadStream(input?: Input): Stream;

export function createWriteStream(output?: Output): Stream;
Loading