From 37a5ee2e737a17c4b3831b5c79c09719618da126 Mon Sep 17 00:00:00 2001 From: Oren Levy Date: Mon, 20 Jun 2016 14:59:09 -0700 Subject: [PATCH 1/3] added MIDI Added MIDI examples --- .../CurieBLE/examples/MIDIBLE/MIDIBLE.ino | 126 ++++++++++++++++++ .../examples/HardwiredMIDI/HardwiredMIDI.ino | 55 ++++++++ 2 files changed, 181 insertions(+) create mode 100644 libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino create mode 100644 libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino diff --git a/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino b/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino new file mode 100644 index 00000000..f6ed72d6 --- /dev/null +++ b/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino @@ -0,0 +1,126 @@ +/* Written by Oren Levy (auxren.com) based off some lackluster + documentation released by Intel. + MIDI over BLE info from: https://developer.apple.com/bluetooth/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf + The MIT License (MIT) + + Copyright (c) 2016 auxren + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in all + copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + SOFTWARE. + +*/ +#include + +#define TXRX_BUF_LEN 20 //max number of bytes +#define RX_BUF_LEN 20 //max number of bytes +uint8_t rx_buf[RX_BUF_LEN]; +int rx_buf_num, rx_state = 0; +uint8_t rx_temp_buf[20]; +uint8_t outBufMidi[128]; + +//Buffer to hold 5 bytes of MIDI data. Note the timestamp is forced +uint8_t midiData[] = {0x80, 0x80, 0x00, 0x00, 0x00}; + +//Loads up buffer with values for note On +void noteOn(char chan, char note, char vel) //channel 1 +{ + midiData[2] = 0x90 + chan; + midiData[3] = note; + midiData[4] = vel; +} + +//Loads up buffer with values for note Off +void noteOff(char chan, char note) //channel 1 +{ + midiData[2] = 0x80 + chan; + midiData[3] = note; + midiData[4] = 0; +} + +BLEPeripheral midiDevice; // create peripheral instance + +BLEService midiSvc("03B80E5A-EDE8-4B33-A751-6CE34EC4C700"); // create service + +// create switch characteristic and allow remote device to read and write +BLECharacteristic midiChar("7772E5DB-3868-4112-A1A9-F2669D106BF3", BLEWrite | BLEWriteWithoutResponse | BLENotify | BLERead, 5); + +void setup() { + Serial.begin(9600); + + BLESetup(); + Serial.println(("Bluetooth device active, waiting for connections...")); +} + +void BLESetup() +{ + // set the local name peripheral advertises + midiDevice.setLocalName("Auxren"); + midiDevice.setDeviceName("Auxren"); + + // set the UUID for the service this peripheral advertises + midiDevice.setAdvertisedServiceUuid(midiSvc.uuid()); + + // add service and characteristic + midiDevice.addAttribute(midiSvc); + midiDevice.addAttribute(midiChar); + + // assign event handlers for connected, disconnected to peripheral + midiDevice.setEventHandler(BLEConnected, midiDeviceConnectHandler); + midiDevice.setEventHandler(BLEDisconnected, midiDeviceDisconnectHandler); + + // assign event handlers for characteristic + midiChar.setEventHandler(BLEWritten, midiCharacteristicWritten); + // set an initial value for the characteristic + midiChar.setValue(midiData, 5); + + // advertise the service + midiDevice.begin(); +} + +void loop() { + + /*Simple randome note player to test MIDI output + Plays random note every 400ms + */ + int note = random(0, 127); + //readMIDI(); + noteOn(0, note, 127); //loads up midiData buffer + midiChar.setValue(midiData, 5);//midiData); //posts 5 bytes + delay(200); + noteOff(0, note); + midiChar.setValue(midiData, 5);//midiData); //posts 5 bytes + delay(200); +} + + +void midiDeviceConnectHandler(BLECentral& central) { + // central connected event handler + Serial.print("Connected event, central: "); + Serial.println(central.address()); +} + +void midiDeviceDisconnectHandler(BLECentral& central) { + // central disconnected event handler + Serial.print("Disconnected event, central: "); + Serial.println(central.address()); +} + +void midiCharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic) { + // central wrote new value to characteristic, update LED + Serial.print("Characteristic event, written: "); +} diff --git a/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino b/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino new file mode 100644 index 00000000..fff2974b --- /dev/null +++ b/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino @@ -0,0 +1,55 @@ +/* + MIDI note player + + This sketch shows how to use the serial transmit pin (pin 1) to send MIDI note data. + If this circuit is connected to a MIDI synth, it will play + the notes F#-0 (0x1E) to F#-5 (0x5A) in sequence. + + + The circuit: + digital in 1 connected to MIDI jack pin 5 + MIDI jack pin 2 connected to ground + MIDI jack pin 4 connected to +5V through 220-ohm resistor + Attach a MIDI cable to the jack, then to a MIDI synth, and play music. + + created 13 Jun 2006 + modified 13 Aug 2012 + by Tom Igoe + + Modified 11 Jun 2016 to work with Arduino 101 + by Oren Levy + + This example code is in the public domain. + + http://www.arduino.cc/en/Tutorial/Midi + +*/ + +#include +SoftwareSerial midiSerial(0, 1); // RX, TX + +void setup() { + // Set MIDI baud rate: + midiSerial.begin(31250); +} + +void loop() { + // play notes from F#-0 (0x1E) to F#-5 (0x5A): + for (int note = 0x1E; note < 0x5A; note ++) { + //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): + noteOn(0x90, note, 0x45); + delay(100); + //Note on channel 1 (0x90), some note value (note), silent velocity (0x00): + noteOn(0x90, note, 0x00); + delay(100); + } +} + +// plays a MIDI note. Doesn't check to see that +// cmd is greater than 127, or that data values are less than 127: +void noteOn(int cmd, int pitch, int velocity) { + midiSerial.write(cmd); + midiSerial.write(pitch); + midiSerial.write(velocity); +} + From 0e8edb7780ae6483218a82a9e50ab4c46304c446 Mon Sep 17 00:00:00 2001 From: Oren Levy Date: Tue, 21 Jun 2016 15:26:04 -0700 Subject: [PATCH 2/3] Removed HardwiredMIDI Example Removed HardwiredMIDI example from wire --- .../examples/HardwiredMIDI/HardwiredMIDI.ino | 55 ------------------- 1 file changed, 55 deletions(-) delete mode 100644 libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino diff --git a/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino b/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino deleted file mode 100644 index fff2974b..00000000 --- a/libraries/Wire/examples/HardwiredMIDI/HardwiredMIDI.ino +++ /dev/null @@ -1,55 +0,0 @@ -/* - MIDI note player - - This sketch shows how to use the serial transmit pin (pin 1) to send MIDI note data. - If this circuit is connected to a MIDI synth, it will play - the notes F#-0 (0x1E) to F#-5 (0x5A) in sequence. - - - The circuit: - digital in 1 connected to MIDI jack pin 5 - MIDI jack pin 2 connected to ground - MIDI jack pin 4 connected to +5V through 220-ohm resistor - Attach a MIDI cable to the jack, then to a MIDI synth, and play music. - - created 13 Jun 2006 - modified 13 Aug 2012 - by Tom Igoe - - Modified 11 Jun 2016 to work with Arduino 101 - by Oren Levy - - This example code is in the public domain. - - http://www.arduino.cc/en/Tutorial/Midi - -*/ - -#include -SoftwareSerial midiSerial(0, 1); // RX, TX - -void setup() { - // Set MIDI baud rate: - midiSerial.begin(31250); -} - -void loop() { - // play notes from F#-0 (0x1E) to F#-5 (0x5A): - for (int note = 0x1E; note < 0x5A; note ++) { - //Note on channel 1 (0x90), some note value (note), middle velocity (0x45): - noteOn(0x90, note, 0x45); - delay(100); - //Note on channel 1 (0x90), some note value (note), silent velocity (0x00): - noteOn(0x90, note, 0x00); - delay(100); - } -} - -// plays a MIDI note. Doesn't check to see that -// cmd is greater than 127, or that data values are less than 127: -void noteOn(int cmd, int pitch, int velocity) { - midiSerial.write(cmd); - midiSerial.write(pitch); - midiSerial.write(velocity); -} - From 2ff6362520ef14d29fb890aa877dca55c4646f31 Mon Sep 17 00:00:00 2001 From: Oren Levy Date: Thu, 23 Jun 2016 17:07:35 -0700 Subject: [PATCH 3/3] Comments and Instructins Added more comments and instructions on how to use the sketch. --- .../CurieBLE/examples/MIDIBLE/MIDIBLE.ino | 40 +++++++++++++++++-- 1 file changed, 36 insertions(+), 4 deletions(-) diff --git a/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino b/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino index f6ed72d6..2dbe9833 100644 --- a/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino +++ b/libraries/CurieBLE/examples/MIDIBLE/MIDIBLE.ino @@ -1,9 +1,41 @@ -/* Written by Oren Levy (auxren.com) based off some lackluster - documentation released by Intel. +/* Written by Oren Levy (auxren.com; @auxren) while competing on + America's Greatest Makers with help from Intel. MIDI over BLE info from: https://developer.apple.com/bluetooth/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf - The MIT License (MIT) - Copyright (c) 2016 auxren + This sketch plays a random MIDI note (between 0 and 127) every 400ms. + For a 'smarter' sketch, check out my Airpeggiator example. + The Airpeggiator uses the Curie's IMU to allow you to play + an imaginary harp in the air. I included a quantizer so you can + select a key and scale so you can jam along with friends. + https://github.com/auxren/MIDIBLE101/tree/master/Airpeggiator + + I have only tested MIDI over BLE using Apple devices. Android doesn't + support native MIDI over BLE yet and I haven't had much of a chance + to test with Windows machines. + + To connect on a Mac, search for Audio MIDI Setup. + Click 'Window' on the top menu and choose 'Show MIDI Studio'. + Double click 'Bluetooth' and the bluetooth configuration window + will pop up. After loading the MIDIBLE sketch on your Arduino 101 + you should see it advertising as Auxren. Click connect and the device + will be available as MIDI device in all your audio software like Garageband. + + There are a few ways to connect using an iOS device. One way to to open + up Garageband. Click on the wrench icon in the upper right and choose 'Advanced' + Towards the bottom of advanced, you will see 'Bluetooth MIDI devices'. + You should see your Arduino 101 advertising in the list. Connect to + your device and it should be available to all other iOS MIDI apps you have. + + To send data, you use the following line: char.setValue(d, n); where char is + the BLE characteristic (in our case, midiCha), d is the data, and n is the + number of bytes of data. + The first 2 bytes of data are the header byte and timestamp byte. If you want, + you can figure out the timestamping scheme, but I just left it with a generic value + since I haven't worked on anything timeing sensitive yet (like a sequencer). + The third, fourth, and fifth bytes are standard MIDI bytes. You can send more bytes + if you would like as long as it is complies to the standard MIDI spec. + + The MIT License (MIT) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal