Skip to content

Commit 4d96428

Browse files
auxrencalvinatintel
authored andcommitted
Added MIDI examples
1 parent 2cd33f4 commit 4d96428

File tree

1 file changed

+158
-0
lines changed

1 file changed

+158
-0
lines changed
Lines changed: 158 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
/* Written by Oren Levy (auxren.com; @auxren) while competing on
2+
America's Greatest Makers with help from Intel.
3+
MIDI over BLE info from: https://developer.apple.com/bluetooth/Apple-Bluetooth-Low-Energy-MIDI-Specification.pdf
4+
5+
This sketch plays a random MIDI note (between 0 and 127) every 400ms.
6+
For a 'smarter' sketch, check out my Airpeggiator example.
7+
The Airpeggiator uses the Curie's IMU to allow you to play
8+
an imaginary harp in the air. I included a quantizer so you can
9+
select a key and scale so you can jam along with friends.
10+
https://github.com/auxren/MIDIBLE101/tree/master/Airpeggiator
11+
12+
I have only tested MIDI over BLE using Apple devices. Android doesn't
13+
support native MIDI over BLE yet and I haven't had much of a chance
14+
to test with Windows machines.
15+
16+
To connect on a Mac, search for Audio MIDI Setup.
17+
Click 'Window' on the top menu and choose 'Show MIDI Studio'.
18+
Double click 'Bluetooth' and the bluetooth configuration window
19+
will pop up. After loading the MIDIBLE sketch on your Arduino 101
20+
you should see it advertising as Auxren. Click connect and the device
21+
will be available as MIDI device in all your audio software like Garageband.
22+
23+
There are a few ways to connect using an iOS device. One way to to open
24+
up Garageband. Click on the wrench icon in the upper right and choose 'Advanced'
25+
Towards the bottom of advanced, you will see 'Bluetooth MIDI devices'.
26+
You should see your Arduino 101 advertising in the list. Connect to
27+
your device and it should be available to all other iOS MIDI apps you have.
28+
29+
To send data, you use the following line: char.setValue(d, n); where char is
30+
the BLE characteristic (in our case, midiCha), d is the data, and n is the
31+
number of bytes of data.
32+
The first 2 bytes of data are the header byte and timestamp byte. If you want,
33+
you can figure out the timestamping scheme, but I just left it with a generic value
34+
since I haven't worked on anything timeing sensitive yet (like a sequencer).
35+
The third, fourth, and fifth bytes are standard MIDI bytes. You can send more bytes
36+
if you would like as long as it is complies to the standard MIDI spec.
37+
38+
The MIT License (MIT)
39+
40+
Permission is hereby granted, free of charge, to any person obtaining a copy
41+
of this software and associated documentation files (the "Software"), to deal
42+
in the Software without restriction, including without limitation the rights
43+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
44+
copies of the Software, and to permit persons to whom the Software is
45+
furnished to do so, subject to the following conditions:
46+
47+
The above copyright notice and this permission notice shall be included in all
48+
copies or substantial portions of the Software.
49+
50+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
51+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
52+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
53+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
54+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
55+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
56+
SOFTWARE.
57+
58+
*/
59+
#include <CurieBLE.h>
60+
61+
#define TXRX_BUF_LEN 20 //max number of bytes
62+
#define RX_BUF_LEN 20 //max number of bytes
63+
uint8_t rx_buf[RX_BUF_LEN];
64+
int rx_buf_num, rx_state = 0;
65+
uint8_t rx_temp_buf[20];
66+
uint8_t outBufMidi[128];
67+
68+
//Buffer to hold 5 bytes of MIDI data. Note the timestamp is forced
69+
uint8_t midiData[] = {0x80, 0x80, 0x00, 0x00, 0x00};
70+
71+
//Loads up buffer with values for note On
72+
void noteOn(char chan, char note, char vel) //channel 1
73+
{
74+
midiData[2] = 0x90 + chan;
75+
midiData[3] = note;
76+
midiData[4] = vel;
77+
}
78+
79+
//Loads up buffer with values for note Off
80+
void noteOff(char chan, char note) //channel 1
81+
{
82+
midiData[2] = 0x80 + chan;
83+
midiData[3] = note;
84+
midiData[4] = 0;
85+
}
86+
87+
BLEPeripheral midiDevice; // create peripheral instance
88+
89+
BLEService midiSvc("03B80E5A-EDE8-4B33-A751-6CE34EC4C700"); // create service
90+
91+
// create switch characteristic and allow remote device to read and write
92+
BLECharacteristic midiChar("7772E5DB-3868-4112-A1A9-F2669D106BF3", BLEWrite | BLEWriteWithoutResponse | BLENotify | BLERead, 5);
93+
94+
void setup() {
95+
Serial.begin(9600);
96+
97+
BLESetup();
98+
Serial.println(("Bluetooth device active, waiting for connections..."));
99+
}
100+
101+
void BLESetup()
102+
{
103+
// set the local name peripheral advertises
104+
midiDevice.setLocalName("Auxren");
105+
midiDevice.setDeviceName("Auxren");
106+
107+
// set the UUID for the service this peripheral advertises
108+
midiDevice.setAdvertisedServiceUuid(midiSvc.uuid());
109+
110+
// add service and characteristic
111+
midiDevice.addAttribute(midiSvc);
112+
midiDevice.addAttribute(midiChar);
113+
114+
// assign event handlers for connected, disconnected to peripheral
115+
midiDevice.setEventHandler(BLEConnected, midiDeviceConnectHandler);
116+
midiDevice.setEventHandler(BLEDisconnected, midiDeviceDisconnectHandler);
117+
118+
// assign event handlers for characteristic
119+
midiChar.setEventHandler(BLEWritten, midiCharacteristicWritten);
120+
// set an initial value for the characteristic
121+
midiChar.setValue(midiData, 5);
122+
123+
// advertise the service
124+
midiDevice.begin();
125+
}
126+
127+
void loop() {
128+
129+
/*Simple randome note player to test MIDI output
130+
Plays random note every 400ms
131+
*/
132+
int note = random(0, 127);
133+
//readMIDI();
134+
noteOn(0, note, 127); //loads up midiData buffer
135+
midiChar.setValue(midiData, 5);//midiData); //posts 5 bytes
136+
delay(200);
137+
noteOff(0, note);
138+
midiChar.setValue(midiData, 5);//midiData); //posts 5 bytes
139+
delay(200);
140+
}
141+
142+
143+
void midiDeviceConnectHandler(BLECentral& central) {
144+
// central connected event handler
145+
Serial.print("Connected event, central: ");
146+
Serial.println(central.address());
147+
}
148+
149+
void midiDeviceDisconnectHandler(BLECentral& central) {
150+
// central disconnected event handler
151+
Serial.print("Disconnected event, central: ");
152+
Serial.println(central.address());
153+
}
154+
155+
void midiCharacteristicWritten(BLECentral& central, BLECharacteristic& characteristic) {
156+
// central wrote new value to characteristic, update LED
157+
Serial.print("Characteristic event, written: ");
158+
}

0 commit comments

Comments
 (0)