This commit is contained in:
Peli de Halleux 2017-04-22 22:12:24 -07:00
Родитель 5fbae8a3bc
Коммит 9a4e93e108
8 изменённых файлов: 61 добавлений и 343 удалений

Просмотреть файл

@ -342,6 +342,11 @@ public:
*/
void sendSystemExclusive(uint8_t * sysex, uint16_t length);
void sendMidiMessage(uint8_t data0);
void sendMidiMessage(uint8_t data0, uint8_t data1);
void sendMidiMessage(uint8_t data0, uint8_t data1, uint8_t data2);
private:
uint16_t sysExBufferPos;
uint8_t sysExBuffer[128];
@ -388,10 +393,6 @@ private:
void (*onSongPositionPointer)(uint16_t);
void (*onSystemExclusive)(uint8_t *, uint16_t, bool);
void sendMidiMessage(uint8_t data0);
void sendMidiMessage(uint8_t data0, uint8_t data1);
void sendMidiMessage(uint8_t data0, uint8_t data1, uint8_t data2);
void onDataWritten(const GattWriteCallbackParams *params);
};

Просмотреть файл

@ -11,31 +11,25 @@ For another device like a smartphone to use any of the Bluetooth "services" whic
## Usage
This package allows the @boardname@ to act as a MIDI peripherical, like a piano. It requires to connect to a BLE MIDI device to receive the commands and play them. On iPhone/iPad, try [KORG Module Le](https://itunes.apple.com/us/app/korg-module-le/id1048875111) to play the piano with your @boardname@!
This package allows the @boardname@ to act as a MIDI peripherical, like a piano. It requires to connect to a BLE MIDI device to receive the commands and play them.
### Example
This program plays all the notes from ``F#-0`` to ``F#-5``.
Place a ``||bluetooth start midi service||`` block in your program to enable MDI over Bluetooth low energy.
```blocks
bluetooth.startMidiService();
```
midi.startBluetoothService();
input.onButtonPressed(Button.A, () => {
// blink the screen
led.toggle(0, 0);
// play note
midi.noteOn(0x90, 400, 0x45);
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
basic.pause(150);
//Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
midi.noteOn(0x90, 400, 0x00);
basic.pause(150);
})
```
This library uses the [MIDI package](pxt.microbit.org/pkg/microsoft/pxt-midi).
Please refer to that project documentation for further details.
## Apps
* iPhone/iPad: [Apple GarageBand](https://itunes.apple.com/us/app/garageband/id408709785?mt=8)
* iPhone/iPad: [KORG Module Le](https://itunes.apple.com/us/app/korg-module-le/id1048875111)
## Supported targets
* for PXT/microbit
* for PXT/calliope
(The metadata above is needed for package search.)

13
bluetooth.ts Normal file
Просмотреть файл

@ -0,0 +1,13 @@
namespace bluetooth {
/**
* Starts the MIDI service over Bluetooth and registers it as the MIDI transport.
*/
//% blockId=bluetooth_start_midi block="bluetooth start midi service"
export function startMidiService() {
function send(buffer: Buffer) {
bluetooth.midiSendMessage(buffer);
}
midi.setInputTransport(send);
bluetooth.midiSendMessage(pins.createBuffer(0));
}
}

2
enums.d.ts поставляемый
Просмотреть файл

@ -16,7 +16,7 @@
MIDI_STATE_SIGNAL_3BYTES_3 = 4,
MIDI_STATE_SIGNAL_SYSEX = 5,
}
declare namespace midi {
declare namespace bluetooth {
}
// Auto-generated. Do not edit. Really.

190
midi.cpp
Просмотреть файл

@ -4,8 +4,7 @@ using namespace pxt;
/**
* A set of functions to send MIDI commands over Bluetooth
*/
//% color=#0082FB weight=96 icon="\uf294"
namespace midi {
namespace bluetooth {
BluetoothMIDIService* pMidi;
BluetoothMIDIService* getMidi()
@ -16,177 +15,22 @@ namespace midi {
}
/**
* Starts the MIDI service
* Sends a MIDI message
*/
//% block
void startBluetoothService() {
getMidi();
}
/**
* Send a `Note On` event
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127
*/
//% block
//% channel.min=0 channel.max=15 note.min=0 note.max=127 velocity.min=0 velocity.max=127
void noteOn(uint8_t channel, uint8_t note, uint8_t velocity) {
getMidi()->sendNoteOn(channel, note, velocity);
}
/**
* Send a `Note Off` event
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127
*/
//% block
//% channel.min=0 channel.max=15 note.min=0 note.max=127 velocity.min=0 velocity.max=127
void noteOff(uint8_t channel, uint8_t note, uint8_t velocity) {
getMidi()->sendNoteOff(channel, note, velocity);
}
/**
* Send a `Tune Request` event
*/
//% block
void tuneRequest() {
getMidi()->sendTuneRequest();
}
/**
* Send a `Timing Clock` event
*/
//% block
void timingClock() {
getMidi()->sendTimingClock();
}
/**
* Send a `Start` event
*/
//% block
void start() {
getMidi()->sendStart();
}
/**
* Send a `Continue` event
*/
//% block
void cont() {
getMidi()->sendContinue();
}
/**
* Send a `Stop` event
*/
//% block
void sendStop() {
getMidi()->sendReset();
}
/**
* Send a `Active Sensing` event
*/
//% block
void sendActiveSensing() {
getMidi()->sendReset();
}
/**
* Send a `Reset` event
*/
//% block
void sendReset() {
getMidi()->sendReset();
}
/**
* Send a `Program Change` event
*
* @param channel 0-15
* @param program 0-127
*/
//% block channel.min=0 channel.max=15 program.min=0 program.max=127
void programChange(uint8_t channel, uint8_t program) {
getMidi()->sendProgramChange(channel, program);
}
/**
* Send a `Channel Aftertouch` event
*
* @param channel 0-15
* @param pressure 0-127
*/
//% block channel.min=0 channel.max=15 channel.pressure=0 channel.pressure=127
void channelAftertouch(uint8_t channel, uint8_t pressure) {
getMidi()->sendChannelAftertouch(channel, pressure);
}
/**
* Send a `Time Code Quarter Frame` event
*
* @param timing 0-127
*/
//% block timing.min=0 timing.max=127
void timeCodeQuarterFrame(uint8_t timing) {
getMidi()->sendTimeCodeQuarterFrame(timing);
}
/**
* Send a `Song Select` event
*
* @param song 0-127
*/
//% block song.min=0 song.max=127
void songSelect(uint8_t song) {
getMidi()->sendSongSelect(song);
}
/**
* Send a `Polyphonic Aftertouch` event
*
* @param channel 0-15
* @param note 0-127
* @param pressure 0-127
*/
//% block channel.min=0 channel.max=15 note.min=0 note.max=127 pressure.min=0 pressure.max=127
void polyphonicAftertouch(uint8_t channel, uint8_t note, uint8_t pressure) {
getMidi()->sendPolyphonicAftertouch(channel, note, pressure);
}
/**
* Send a `Control Change` event
*
* @param channel 0-15
* @param func 0-127
* @param value 0-127
*/
//% block channel.min=0 channel.max=15 func.min=0 func.max=127 value.min=0 value.max=127
void controlChange(uint8_t channel, uint8_t func, uint8_t value) {
getMidi()->sendControlChange(channel, func, value);
}
/**
* Send a `Pitch Wheel` event
*
* @param channel 0-15
* @param amount 0-8192(center)-16383, eg: 8192
*/
//% block channel.min=0 channel.max=15 amount.min=0 amount.max=16383
void pitchWheel(uint8_t channel, uint16_t amount) {
getMidi()->sendPitchWheel(channel, amount);
}
/**
* Send a `Song Position Pointer` event
*
* @param position 0-16383
*/
//% block position.min=0 position.max=16383
void songPositionPointer(uint16_t position) {
getMidi()->sendSongPositionPointer(position);
//%
void midiSendMessage(Buffer data) {
BluetoothMIDIService* pMidi = getMidi();
ManagedBuffer buf(data);
switch(buf.length()) {
case 1:
pMidi->sendMidiMessage(buf[0]);
break;
case 2:
pMidi->sendMidiMessage(buf[0], buf[1]);
break;
case 3:
pMidi->sendMidiMessage(buf[0], buf[1], buf[2]);
break;
}
}
}

Просмотреть файл

@ -5,13 +5,15 @@
"license": "MIT",
"dependencies": {
"core": "*",
"bluetooth": "*"
"bluetooth": "*",
"midi": "github:Microsoft/pxt-midi#v0.0.4"
},
"files": [
"README.md",
"BluetoothMIDIService.cpp",
"BluetoothMIDIService.h",
"midi.cpp",
"bluetooth.ts",
"shims.d.ts",
"enums.d.ts"
],

143
shims.d.ts поставляемый
Просмотреть файл

@ -4,147 +4,14 @@
/**
* A set of functions to send MIDI commands over Bluetooth
*/
//% color=#0082FB weight=96 icon="\uf294"
declare namespace midi {
declare namespace bluetooth {
/**
* Starts the MIDI service
* Sends a MIDI message
*/
//% block shim=midi::startBluetoothService
function startBluetoothService(): void;
/**
* Send a `Note On` event
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127
*/
//% block
//% channel.min=0 channel.max=15 note.min=0 note.max=127 velocity.min=0 velocity.max=127 shim=midi::noteOn
function noteOn(channel: uint8, note: uint8, velocity: uint8): void;
/**
* Send a `Note Off` event
* @param channel 0-15
* @param note 0-127
* @param velocity 0-127
*/
//% block
//% channel.min=0 channel.max=15 note.min=0 note.max=127 velocity.min=0 velocity.max=127 shim=midi::noteOff
function noteOff(channel: uint8, note: uint8, velocity: uint8): void;
/**
* Send a `Tune Request` event
*/
//% block shim=midi::tuneRequest
function tuneRequest(): void;
/**
* Send a `Timing Clock` event
*/
//% block shim=midi::timingClock
function timingClock(): void;
/**
* Send a `Start` event
*/
//% block shim=midi::start
function start(): void;
/**
* Send a `Continue` event
*/
//% block shim=midi::cont
function cont(): void;
/**
* Send a `Stop` event
*/
//% block shim=midi::sendStop
function sendStop(): void;
/**
* Send a `Active Sensing` event
*/
//% block shim=midi::sendActiveSensing
function sendActiveSensing(): void;
/**
* Send a `Reset` event
*/
//% block shim=midi::sendReset
function sendReset(): void;
/**
* Send a `Program Change` event
*
* @param channel 0-15
* @param program 0-127
*/
//% block channel.min=0 channel.max=15 program.min=0 program.max=127 shim=midi::programChange
function programChange(channel: uint8, program: uint8): void;
/**
* Send a `Channel Aftertouch` event
*
* @param channel 0-15
* @param pressure 0-127
*/
//% block channel.min=0 channel.max=15 channel.pressure=0 channel.pressure=127 shim=midi::channelAftertouch
function channelAftertouch(channel: uint8, pressure: uint8): void;
/**
* Send a `Time Code Quarter Frame` event
*
* @param timing 0-127
*/
//% block timing.min=0 timing.max=127 shim=midi::timeCodeQuarterFrame
function timeCodeQuarterFrame(timing: uint8): void;
/**
* Send a `Song Select` event
*
* @param song 0-127
*/
//% block song.min=0 song.max=127 shim=midi::songSelect
function songSelect(song: uint8): void;
/**
* Send a `Polyphonic Aftertouch` event
*
* @param channel 0-15
* @param note 0-127
* @param pressure 0-127
*/
//% block channel.min=0 channel.max=15 note.min=0 note.max=127 pressure.min=0 pressure.max=127 shim=midi::polyphonicAftertouch
function polyphonicAftertouch(channel: uint8, note: uint8, pressure: uint8): void;
/**
* Send a `Control Change` event
*
* @param channel 0-15
* @param func 0-127
* @param value 0-127
*/
//% block channel.min=0 channel.max=15 func.min=0 func.max=127 value.min=0 value.max=127 shim=midi::controlChange
function controlChange(channel: uint8, func: uint8, value: uint8): void;
/**
* Send a `Pitch Wheel` event
*
* @param channel 0-15
* @param amount 0-8192(center)-16383, eg: 8192
*/
//% block channel.min=0 channel.max=15 amount.min=0 amount.max=16383 shim=midi::pitchWheel
function pitchWheel(channel: uint8, amount: uint16): void;
/**
* Send a `Song Position Pointer` event
*
* @param position 0-16383
*/
//% block position.min=0 position.max=16383 shim=midi::songPositionPointer
function songPositionPointer(position: uint16): void;
//% shim=bluetooth::midiSendMessage
function midiSendMessage(data: Buffer): void;
}
// Auto-generated. Do not edit. Really.

Просмотреть файл

@ -4,19 +4,16 @@ bluetooth.onBluetoothConnected(() => {
bluetooth.onBluetoothDisconnected(() => {
basic.showString("D")
})
midi.startBluetoothService();
bluetooth.startMidiService();
basic.showString("S")
input.onButtonPressed(Button.A, () => {
basic.clearScreen();
// https://www.arduino.cc/en/tutorial/midi
// play notes from F#-0 (0x1E) to F#-5 (0x5A):
for (let note = 0x1E; note < 0x5A; note++) {
let piano = midi.inputChannel(0);
for (let note = 0x0; note < 0x5A; note++) {
led.toggle(0, 0);
//Note on channel 1 (0x90), some note value (note), middle velocity (0x45):
midi.noteOn(0x90, note, 0x45);
piano.noteOn(note);
basic.pause(100);
//Note on channel 1 (0x90), some note value (note), silent velocity (0x00):
midi.noteOff(0x90, note, 0x00);
piano.noteOff(note);
basic.pause(100);
}
})