Dependencies:   BLE_API mbed nRF51822_BLE_MIDI

Dependents:   BLE_MIDI_one_note_TEST

Fork of BLE_MIDI by Kaoru Shoji

Committer:
kshoji
Date:
Thu Apr 02 05:17:14 2015 +0000
Revision:
0:83889dc90473
Child:
1:cba2eba64f5c
Tested MIDI receiving

Who changed what in which revision?

UserRevisionLine numberNew contents of line
kshoji 0:83889dc90473 1 /* Copyright (c) 2014 mbed.org, MIT License
kshoji 0:83889dc90473 2 *
kshoji 0:83889dc90473 3 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
kshoji 0:83889dc90473 4 * and associated documentation files (the "Software"), to deal in the Software without
kshoji 0:83889dc90473 5 * restriction, including without limitation the rights to use, copy, modify, merge, publish,
kshoji 0:83889dc90473 6 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the
kshoji 0:83889dc90473 7 * Software is furnished to do so, subject to the following conditions:
kshoji 0:83889dc90473 8 *
kshoji 0:83889dc90473 9 * The above copyright notice and this permission notice shall be included in all copies or
kshoji 0:83889dc90473 10 * substantial portions of the Software.
kshoji 0:83889dc90473 11 *
kshoji 0:83889dc90473 12 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
kshoji 0:83889dc90473 13 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
kshoji 0:83889dc90473 14 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
kshoji 0:83889dc90473 15 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
kshoji 0:83889dc90473 16 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
kshoji 0:83889dc90473 17 */
kshoji 0:83889dc90473 18
kshoji 0:83889dc90473 19 #ifndef __BLEMIDI_H__
kshoji 0:83889dc90473 20 #define __BLEMIDI_H__
kshoji 0:83889dc90473 21
kshoji 0:83889dc90473 22 #include "BLEDevice.h"
kshoji 0:83889dc90473 23
kshoji 0:83889dc90473 24 /**
kshoji 0:83889dc90473 25 * A class to communicate a BLE MIDI device
kshoji 0:83889dc90473 26 */
kshoji 0:83889dc90473 27 class BLEMIDI {
kshoji 0:83889dc90473 28 public:
kshoji 0:83889dc90473 29 /**
kshoji 0:83889dc90473 30 * Constructor
kshoji 0:83889dc90473 31 */
kshoji 0:83889dc90473 32 BLEMIDI(BLEDevice *device);
kshoji 0:83889dc90473 33
kshoji 0:83889dc90473 34 /**
kshoji 0:83889dc90473 35 * Check if a BLE MIDI device is connected
kshoji 0:83889dc90473 36 *
kshoji 0:83889dc90473 37 * @returns true if a midi device is connected
kshoji 0:83889dc90473 38 */
kshoji 0:83889dc90473 39 bool connected();
kshoji 0:83889dc90473 40
kshoji 0:83889dc90473 41 /**
kshoji 0:83889dc90473 42 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 43 *
kshoji 0:83889dc90473 44 * @param ptr function pointer
kshoji 0:83889dc90473 45 * prototype: void onTuneRequest();
kshoji 0:83889dc90473 46 */
kshoji 0:83889dc90473 47 inline void attachTuneRequest(void (*fn)()) {
kshoji 0:83889dc90473 48 onTuneRequest = fn;
kshoji 0:83889dc90473 49 }
kshoji 0:83889dc90473 50
kshoji 0:83889dc90473 51 /**
kshoji 0:83889dc90473 52 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 53 *
kshoji 0:83889dc90473 54 * @param ptr function pointer
kshoji 0:83889dc90473 55 * prototype: void onTimingClock();
kshoji 0:83889dc90473 56 */
kshoji 0:83889dc90473 57 inline void attachTimingClock(void (*fn)()) {
kshoji 0:83889dc90473 58 onTimingClock = fn;
kshoji 0:83889dc90473 59 }
kshoji 0:83889dc90473 60
kshoji 0:83889dc90473 61 /**
kshoji 0:83889dc90473 62 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 63 *
kshoji 0:83889dc90473 64 * @param ptr function pointer
kshoji 0:83889dc90473 65 * prototype: void onStart();
kshoji 0:83889dc90473 66 */
kshoji 0:83889dc90473 67 inline void attachStart(void (*fn)()) {
kshoji 0:83889dc90473 68 onStart = fn;
kshoji 0:83889dc90473 69 }
kshoji 0:83889dc90473 70
kshoji 0:83889dc90473 71 /**
kshoji 0:83889dc90473 72 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 73 *
kshoji 0:83889dc90473 74 * @param ptr function pointer
kshoji 0:83889dc90473 75 * prototype: void onContinue();
kshoji 0:83889dc90473 76 */
kshoji 0:83889dc90473 77 inline void attachContinue(void (*fn)()) {
kshoji 0:83889dc90473 78 onContinue = fn;
kshoji 0:83889dc90473 79 }
kshoji 0:83889dc90473 80
kshoji 0:83889dc90473 81 /**
kshoji 0:83889dc90473 82 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 83 *
kshoji 0:83889dc90473 84 * @param ptr function pointer
kshoji 0:83889dc90473 85 * prototype: void onStop();
kshoji 0:83889dc90473 86 */
kshoji 0:83889dc90473 87 inline void attachStop(void (*fn)()) {
kshoji 0:83889dc90473 88 onStop = fn;
kshoji 0:83889dc90473 89 }
kshoji 0:83889dc90473 90
kshoji 0:83889dc90473 91 /**
kshoji 0:83889dc90473 92 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 93 *
kshoji 0:83889dc90473 94 * @param ptr function pointer
kshoji 0:83889dc90473 95 * prototype: void onActiveSensing();
kshoji 0:83889dc90473 96 */
kshoji 0:83889dc90473 97 inline void attachActiveSensing(void (*fn)()) {
kshoji 0:83889dc90473 98 onActiveSensing = fn;
kshoji 0:83889dc90473 99 }
kshoji 0:83889dc90473 100
kshoji 0:83889dc90473 101 /**
kshoji 0:83889dc90473 102 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 103 *
kshoji 0:83889dc90473 104 * @param ptr function pointer
kshoji 0:83889dc90473 105 * prototype: void onReset();
kshoji 0:83889dc90473 106 */
kshoji 0:83889dc90473 107 inline void attachReset(void (*fn)()) {
kshoji 0:83889dc90473 108 onReset = fn;
kshoji 0:83889dc90473 109 }
kshoji 0:83889dc90473 110
kshoji 0:83889dc90473 111 /**
kshoji 0:83889dc90473 112 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 113 *
kshoji 0:83889dc90473 114 * @param ptr function pointer
kshoji 0:83889dc90473 115 * prototype: void onProgramChange(uint8_t, uint8_t);
kshoji 0:83889dc90473 116 */
kshoji 0:83889dc90473 117 inline void attachnProgramChange(void (*fn)(uint8_t, uint8_t)) {
kshoji 0:83889dc90473 118 onProgramChange = fn;
kshoji 0:83889dc90473 119 }
kshoji 0:83889dc90473 120
kshoji 0:83889dc90473 121 /**
kshoji 0:83889dc90473 122 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 123 *
kshoji 0:83889dc90473 124 * @param ptr function pointer
kshoji 0:83889dc90473 125 * prototype: void onChannelAftertouch(uint8_t, uint8_t);
kshoji 0:83889dc90473 126 */
kshoji 0:83889dc90473 127 inline void attachChannelAftertouch(void (*fn)(uint8_t, uint8_t)) {
kshoji 0:83889dc90473 128 onChannelAftertouch = fn;
kshoji 0:83889dc90473 129 }
kshoji 0:83889dc90473 130
kshoji 0:83889dc90473 131 /**
kshoji 0:83889dc90473 132 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 133 *
kshoji 0:83889dc90473 134 * @param ptr function pointer
kshoji 0:83889dc90473 135 * prototype: void onTimeCodeQuarterFrame(uint8_t);
kshoji 0:83889dc90473 136 */
kshoji 0:83889dc90473 137 inline void attachTimeCodeQuarterFrame(void (*fn)(uint8_t)) {
kshoji 0:83889dc90473 138 onTimeCodeQuarterFrame = fn;
kshoji 0:83889dc90473 139 }
kshoji 0:83889dc90473 140
kshoji 0:83889dc90473 141 /**
kshoji 0:83889dc90473 142 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 143 *
kshoji 0:83889dc90473 144 * @param ptr function pointer
kshoji 0:83889dc90473 145 * prototype: void onSongSelect(uint8_t);
kshoji 0:83889dc90473 146 */
kshoji 0:83889dc90473 147 inline void attachSongSelect(void (*fn)(uint8_t)) {
kshoji 0:83889dc90473 148 onSongSelect = fn;
kshoji 0:83889dc90473 149 }
kshoji 0:83889dc90473 150
kshoji 0:83889dc90473 151 /**
kshoji 0:83889dc90473 152 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 153 *
kshoji 0:83889dc90473 154 * @param ptr function pointer
kshoji 0:83889dc90473 155 * prototype: void onNoteOff(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 156 */
kshoji 0:83889dc90473 157 inline void attachNoteOff(void (*fn)(uint8_t, uint8_t, uint8_t)) {
kshoji 0:83889dc90473 158 onNoteOff = fn;
kshoji 0:83889dc90473 159 }
kshoji 0:83889dc90473 160
kshoji 0:83889dc90473 161 /**
kshoji 0:83889dc90473 162 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 163 *
kshoji 0:83889dc90473 164 * @param ptr function pointer
kshoji 0:83889dc90473 165 * prototype: void onNoteOn(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 166 */
kshoji 0:83889dc90473 167 inline void attachNoteOn(void (*fn)(uint8_t, uint8_t, uint8_t)) {
kshoji 0:83889dc90473 168 onNoteOn = fn;
kshoji 0:83889dc90473 169 }
kshoji 0:83889dc90473 170
kshoji 0:83889dc90473 171 /**
kshoji 0:83889dc90473 172 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 173 *
kshoji 0:83889dc90473 174 * @param ptr function pointer
kshoji 0:83889dc90473 175 * prototype: void onPolyphonicAftertouch(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 176 */
kshoji 0:83889dc90473 177 inline void attachPolyphonicAftertouch(void (*fn)(uint8_t, uint8_t, uint8_t)) {
kshoji 0:83889dc90473 178 onPolyphonicAftertouch = fn;
kshoji 0:83889dc90473 179 }
kshoji 0:83889dc90473 180
kshoji 0:83889dc90473 181 /**
kshoji 0:83889dc90473 182 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 183 *
kshoji 0:83889dc90473 184 * @param ptr function pointer
kshoji 0:83889dc90473 185 * prototype: void onControlChange(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 186 */
kshoji 0:83889dc90473 187 inline void attachControlChange(void (*fn)(uint8_t, uint8_t, uint8_t)) {
kshoji 0:83889dc90473 188 onControlChange = fn;
kshoji 0:83889dc90473 189 }
kshoji 0:83889dc90473 190
kshoji 0:83889dc90473 191 /**
kshoji 0:83889dc90473 192 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 193 *
kshoji 0:83889dc90473 194 * @param ptr function pointer
kshoji 0:83889dc90473 195 * prototype: void onPitchWheel(uint8_t, uint16_t);
kshoji 0:83889dc90473 196 */
kshoji 0:83889dc90473 197 inline void attachPitchWheel(void (*fn)(uint8_t, uint16_t)) {
kshoji 0:83889dc90473 198 onPitchWheel = fn;
kshoji 0:83889dc90473 199 }
kshoji 0:83889dc90473 200
kshoji 0:83889dc90473 201 /**
kshoji 0:83889dc90473 202 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 203 *
kshoji 0:83889dc90473 204 * @param ptr function pointer
kshoji 0:83889dc90473 205 * prototype: void onSongPositionPointer(uint16_t);
kshoji 0:83889dc90473 206 */
kshoji 0:83889dc90473 207 inline void attachSongPositionPointer(void (*fn)(uint16_t)) {
kshoji 0:83889dc90473 208 onSongPositionPointer = fn;
kshoji 0:83889dc90473 209 }
kshoji 0:83889dc90473 210
kshoji 0:83889dc90473 211 /**
kshoji 0:83889dc90473 212 * Attach a callback called when the MIDI event is received
kshoji 0:83889dc90473 213 *
kshoji 0:83889dc90473 214 * @param ptr function pointer
kshoji 0:83889dc90473 215 * prototype: void onSystemExclusive(uint8_t *, uint16_t);
kshoji 0:83889dc90473 216 */
kshoji 0:83889dc90473 217 inline void attachSystemExclusive(void (*fn)(uint8_t *, uint16_t)) {
kshoji 0:83889dc90473 218 onSystemExclusive = fn;
kshoji 0:83889dc90473 219 }
kshoji 0:83889dc90473 220
kshoji 0:83889dc90473 221 void sendTuneRequest();
kshoji 0:83889dc90473 222 void sendTimingClock();
kshoji 0:83889dc90473 223 void sendStart();
kshoji 0:83889dc90473 224 void sendContinue();
kshoji 0:83889dc90473 225 void sendStop();
kshoji 0:83889dc90473 226 void sendActiveSensing();
kshoji 0:83889dc90473 227 void sendReset();
kshoji 0:83889dc90473 228 void sendProgramChange(uint8_t channel, uint8_t program);
kshoji 0:83889dc90473 229 void sendChannelAftertouch(uint8_t channel, uint8_t pressure);
kshoji 0:83889dc90473 230 void sendTimeCodeQuarterFrame(uint8_t timing);
kshoji 0:83889dc90473 231 void sendSongSelect(uint8_t song);
kshoji 0:83889dc90473 232 void sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
kshoji 0:83889dc90473 233 void sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
kshoji 0:83889dc90473 234 void sendPolyphonicAftertouch(uint8_t channel, uint8_t note, uint8_t pressure);
kshoji 0:83889dc90473 235 void sendControlChange(uint8_t channel, uint8_t function, uint8_t value);
kshoji 0:83889dc90473 236 void sendPitchWheel(uint8_t channel, uint16_t amount);
kshoji 0:83889dc90473 237 void sendSongPositionPointer(uint16_t position);
kshoji 0:83889dc90473 238 void sendSystemExclusive(uint8_t * sysex, uint16_t length);
kshoji 0:83889dc90473 239
kshoji 0:83889dc90473 240 void onBleDisconnection(Gap::Handle_t handle, Gap::DisconnectionReason_t reason);
kshoji 0:83889dc90473 241 void onBleConnection(Gap::Handle_t handle, Gap::addr_type_t type, const Gap::address_t addr, const Gap::ConnectionParams_t *params);
kshoji 0:83889dc90473 242
kshoji 0:83889dc90473 243
kshoji 0:83889dc90473 244 private:
kshoji 0:83889dc90473 245 bool isConnected;
kshoji 0:83889dc90473 246
kshoji 0:83889dc90473 247 uint16_t sysExBufferPos;
kshoji 0:83889dc90473 248 uint8_t sysExBuffer[256];
kshoji 0:83889dc90473 249
kshoji 0:83889dc90473 250 uint16_t timestamp;
kshoji 0:83889dc90473 251
kshoji 0:83889dc90473 252 uint8_t midiEventKind;
kshoji 0:83889dc90473 253 uint8_t midiEventNote;
kshoji 0:83889dc90473 254 uint8_t midiEventVelocity;
kshoji 0:83889dc90473 255
kshoji 0:83889dc90473 256 enum MIDI_STATE {
kshoji 0:83889dc90473 257 MIDI_STATE_TIMESTAMP = 0,
kshoji 0:83889dc90473 258 MIDI_STATE_WAIT,
kshoji 0:83889dc90473 259 MIDI_STATE_SIGNAL_2BYTES_2,
kshoji 0:83889dc90473 260 MIDI_STATE_SIGNAL_3BYTES_2,
kshoji 0:83889dc90473 261 MIDI_STATE_SIGNAL_3BYTES_3,
kshoji 0:83889dc90473 262 MIDI_STATE_SIGNAL_SYSEX
kshoji 0:83889dc90473 263 };
kshoji 0:83889dc90473 264
kshoji 0:83889dc90473 265 MIDI_STATE midiState;
kshoji 0:83889dc90473 266
kshoji 0:83889dc90473 267 void (*onTuneRequest)();
kshoji 0:83889dc90473 268 void (*onTimingClock)();
kshoji 0:83889dc90473 269 void (*onStart)();
kshoji 0:83889dc90473 270 void (*onContinue)();
kshoji 0:83889dc90473 271 void (*onStop)();
kshoji 0:83889dc90473 272 void (*onActiveSensing)();
kshoji 0:83889dc90473 273 void (*onReset)();
kshoji 0:83889dc90473 274 void (*onProgramChange)(uint8_t, uint8_t);
kshoji 0:83889dc90473 275 void (*onChannelAftertouch)(uint8_t, uint8_t);
kshoji 0:83889dc90473 276 void (*onTimeCodeQuarterFrame)(uint8_t);
kshoji 0:83889dc90473 277 void (*onSongSelect)(uint8_t);
kshoji 0:83889dc90473 278 void (*onNoteOff)(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 279 void (*onNoteOn)(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 280 void (*onPolyphonicAftertouch)(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 281 void (*onControlChange)(uint8_t, uint8_t, uint8_t);
kshoji 0:83889dc90473 282 void (*onPitchWheel)(uint8_t, uint16_t);
kshoji 0:83889dc90473 283 void (*onSongPositionPointer)(uint16_t);
kshoji 0:83889dc90473 284 void (*onSystemExclusive)(uint8_t *, uint16_t);
kshoji 0:83889dc90473 285
kshoji 0:83889dc90473 286 void sendMidiMessage(uint8_t data0);
kshoji 0:83889dc90473 287 void sendMidiMessage(uint8_t data0, uint8_t data1);
kshoji 0:83889dc90473 288 void sendMidiMessage(uint8_t data0, uint8_t data1, uint8_t data2);
kshoji 0:83889dc90473 289
kshoji 0:83889dc90473 290 void dataWrittenCallback(const GattCharacteristicWriteCBParams *params);
kshoji 0:83889dc90473 291
kshoji 0:83889dc90473 292 BLEDevice *device;
kshoji 0:83889dc90473 293 GattCharacteristic *midiCharacteristic;
kshoji 0:83889dc90473 294 Timer tick;
kshoji 0:83889dc90473 295 };
kshoji 0:83889dc90473 296
kshoji 0:83889dc90473 297 #endif /* __BLEMIDI_H__ */