0.5.10 ā€¢ Published 2 months ago

noon-io v0.5.10

Weekly downloads
-
License
apache-2.0
Repository
github
Last release
2 months ago

šŸŽ¹ noon-io

tests release doc

Easy io for the Web MIDI API

šŸšØ Disclaimer

Development has just started and until v1.0.0 has been released, noon-io should be considered unstable.

šŸ—’ļø API Documentation

A more detailed documentation of noon-io can be found here.

šŸš€ Getting started

šŸ“¦ Install

npm i noon-io

šŸ“¤ Send MIDI messages

Send a A4 NOTE ON message on all available MIDI outputs

import * as MIDI from 'noon-io';

// Gain access to the Web MIDI API
const midiAccess = await navigator.requestMIDIAccess();

// Send a Note On message over all available outputs on channel 2
for (const output of midiAccess.outputs.values()) {
    const noteOnMessage = {
        status: MIDI.Status.NOTE_ON,
        channel: 2,
        data: {
            value: 69, // A4
            velocity: 127
        }
    };
    output.send(MIDI.write(noteOnMessage));
}

šŸ”Ø Using channel message factory functions

For one dedicated channel, noon-io offers a more concise way of writing messages using factory functions.

// send a CC of 80 for control 71
output.send(MIDI.channel(2).controlChange(71, 80));
// send a A4 note on message with a velocity of 120
output.send(MIDI.channel(2).noteOn(69, 120));
// send the subsequent note off message for our A4 note
output.send(MIDI.channel(2).noteOff(69));

For more information about noon-io factories, you can checkout this documentation

šŸ“„ Read MIDI messages

import * as MIDI from 'noon-io';

// Gain access to the Web MIDI API
const midiAccess = await navigator.requestMIDIAccess();

// Bind MIDI reader to all midi inputs
for (const input of midiAccess.inputs.values()) {
    input.onmidimessage = MIDI.read;
}

šŸŽØ Decorating MIDI messages

The read function can be instantiated through the reader factory which takes an optional configuration object. This object allow to define one decorator function per MIDI status, in order to populate the meta property of the message with application specific data, in order to implement custom logic when subscribing to the message.

// example: read current UI state to check if MIDI learning is enabled
input.onmidimessage = MIDI.reader({
    decorators: {
        [MIDI.Status.CONTROL_CHANGE](message) {
            return {
                isMidiLearning: isMidiLearning() 
            };
        }
    },
});

ā³ Subscribing to the messages stream

Once read, messages are exposed through the Rx Subject.

import * as MIDI from 'noon-io';

MIDI.Rx.subscribe(message => {
    console.log(message.meta); // log the meta object populated by the custom decorator function
});

ā³ Filtering messages

In addition to the message stream, noon-io provides a convenient observe function, which will return a observable of MIDI messages matching the given MIDI status and an optional MIDI chanel.

import * as MIDI from 'noon-io';

MIDI.observe(MIDI.Status.CONTROL_CHANGE, 1)
    .subscribe(message => {
        // handle control change message for channel 1
    });

āš—ļø Bank Select / Program Change

Sending a bank select followed by a program change can be achieved by sending two consecutive control change messages before sending the actual program change.

(The following has been tested on a Dave Smith Instruments Mopho device)

import * as MIDI from 'noon-io';
/*
 * Start Bank Select message
 * Selects banks 2 (bank 1 is 0) for channel 2
 */
output.send(
    MIDI.writeMidiMessage({
        status: MIDI.Status.CONTROL_CHANGE,
        channel: 2,
        data: {
            control: 0, // bank select MSB (always 0)
            value: 1, // MSB multiplier
        }
    })
);

output.send(
    MIDI.writeMidiMessage({
        status: MIDI.Status.CONTROL_CHANGE,
        channel: 2,
        data: {
            control: 0, // bank select LSB (always 32)
            value: 1, // LSB multiplier
        }
    })
); // Ends bank select message

/*
 * Now that we have selected bank 2,
 * let's select a random program
 */
output.send(
    MIDI.writeMidiMessage({
        status: MIDI.Status.PROGRAM_CHANGE,
        channel: 2,
        data: {
            value: Math.ceil(Math.random() * 127),
        }
    })
);

Or using the bankSelectMSB and bankSelectLSB factories provided by noon-io

// Select bank 1
output.send(MIDI.channel(2).bankSelectMSB(0));
output.send(MIDI.channel(2).bankSelectLSB(0));
// Select program 109 from bank 1
output.send(MIDI.channel(2).programChange(Math.ceil(Math.random() * 127)));

šŸš§ Supported Messages

āš ļø Some of the following MIDI messages may not have been tested on a MIDI port (see the status section of the following tables)

šŸŽ¶ Channel Messages

TypeReaderWriterStatus
NOTE ONāœ…āœ…Read and write have been tested on a MIDI port
NOTE OFFāœ…āœ…Read and write have been tested on a MIDI port
PITCH BENDāœ…āœ…Read and write have been tested on a MIDI port
CONTROL CHANGEāœ…āœ…Read and write have been tested on a MIDI port
PROGRAM CHANGEāœ…āœ…Read and write have been tested on a MIDI port
POLYPHONIC AFTER TOUCHāœ…āœ…Both read and write have not been tested
CHANNEL AFTER TOUCHāœ…āœ…Both read and write have not been tested

šŸŽ›ļø System Messages

TypeReaderWriterStatus
TIMING CLOCKāœ…āœ…Only Read has been tester on a MIDI port
STARTāœ…āœ…Both read and write have not been tested
STOPāœ…āœ…Both read and write have not been tested
CONTINUEāœ…āœ…Both read and write have not been tested
SYSTEM RESETāœ…āœ…Both read and write have not been tested
ACTIVE SENSINGāœ…āœ…Both read and write have not been tested
SYSTEM EXCLUSIVEāœ…āŒReader has not been tested, writer is not implemented
MIDI TIME CODEāŒāŒNot Implemented
SONG POSITIONāŒāŒNot Implemented
SONG SELECTāŒāŒNot Implemented
TUNE REQUESTāŒāŒNot Implemented
0.5.10

2 months ago

0.5.9

12 months ago

0.5.8

1 year ago

0.5.7

1 year ago

0.3.0

1 year ago

0.1.2

1 year ago

0.2.0

1 year ago

0.5.4

1 year ago

0.5.3

1 year ago

0.5.6

1 year ago

0.5.5

1 year ago

0.5.0

1 year ago

0.4.0

1 year ago

0.1.3

1 year ago

0.5.2

1 year ago

0.5.1

1 year ago

1.0.0

1 year ago

0.0.30

1 year ago

0.0.31

1 year ago

0.0.32

1 year ago

0.0.33

1 year ago

0.1.0

1 year ago

0.1.1

1 year ago

0.0.29

2 years ago

0.0.21

2 years ago

0.0.22

2 years ago

0.0.23

2 years ago

0.0.24

2 years ago

0.0.25

2 years ago

0.0.27

2 years ago

0.0.28

2 years ago

0.0.20

2 years ago

0.0.19

2 years ago

0.0.18

2 years ago

0.0.17

2 years ago

0.0.16

2 years ago

0.0.15

2 years ago

0.0.14

2 years ago

0.0.13

2 years ago

0.0.10

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.3

2 years ago

0.0.2

2 years ago

0.0.1

2 years ago