Utility class for MIDI over Bluetooth LE
Dependencies: BLE_API mbed nRF51822
BLEMIDI.h
00001 /* Copyright (c) 2014 mbed.org, MIT License 00002 * 00003 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 00004 * and associated documentation files (the "Software"), to deal in the Software without 00005 * restriction, including without limitation the rights to use, copy, modify, merge, publish, 00006 * distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 00007 * Software is furnished to do so, subject to the following conditions: 00008 * 00009 * The above copyright notice and this permission notice shall be included in all copies or 00010 * substantial portions of the Software. 00011 * 00012 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 00013 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 00014 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 00015 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00016 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 00017 */ 00018 00019 #ifndef __BLEMIDI_H__ 00020 #define __BLEMIDI_H__ 00021 00022 #include "BLEDevice.h" 00023 00024 /** 00025 * A class to communicate a BLE MIDI device 00026 */ 00027 class BLEMIDI { 00028 public: 00029 /** 00030 * Constructor 00031 */ 00032 BLEMIDI(BLEDevice *device); 00033 00034 /** 00035 * Constructor with device name 00036 */ 00037 BLEMIDI(BLEDevice *dev, char *deviceName); 00038 00039 /** 00040 * Check if a BLE MIDI device is connected 00041 * 00042 * @returns true if a midi device is connected 00043 */ 00044 bool connected(); 00045 00046 /** 00047 * Attach a callback called when the `Tune Request` event is received 00048 * 00049 * @param ptr function pointer 00050 * prototype: void onTuneRequest(); 00051 */ 00052 inline void attachTuneRequest(void (*fn)()) { 00053 onTuneRequest = fn; 00054 } 00055 00056 /** 00057 * Attach a callback called when the `Timing Clock` event is received 00058 * 00059 * @param ptr function pointer 00060 * prototype: void onTimingClock(); 00061 */ 00062 inline void attachTimingClock(void (*fn)()) { 00063 onTimingClock = fn; 00064 } 00065 00066 /** 00067 * Attach a callback called when the `Start` event is received 00068 * 00069 * @param ptr function pointer 00070 * prototype: void onStart(); 00071 */ 00072 inline void attachStart(void (*fn)()) { 00073 onStart = fn; 00074 } 00075 00076 /** 00077 * Attach a callback called when the `Continue` event is received 00078 * 00079 * @param ptr function pointer 00080 * prototype: void onContinue(); 00081 */ 00082 inline void attachContinue(void (*fn)()) { 00083 onContinue = fn; 00084 } 00085 00086 /** 00087 * Attach a callback called when the `Stop` event is received 00088 * 00089 * @param ptr function pointer 00090 * prototype: void onStop(); 00091 */ 00092 inline void attachStop(void (*fn)()) { 00093 onStop = fn; 00094 } 00095 00096 /** 00097 * Attach a callback called when the `Active Sensing` event is received 00098 * 00099 * @param ptr function pointer 00100 * prototype: void onActiveSensing(); 00101 */ 00102 inline void attachActiveSensing(void (*fn)()) { 00103 onActiveSensing = fn; 00104 } 00105 00106 /** 00107 * Attach a callback called when the `Reset` event is received 00108 * 00109 * @param ptr function pointer 00110 * prototype: void onReset(); 00111 */ 00112 inline void attachReset(void (*fn)()) { 00113 onReset = fn; 00114 } 00115 00116 /** 00117 * Attach a callback called when the `Program Change` event is received 00118 * 00119 * @param ptr function pointer 00120 * prototype: void onProgramChange(uint8_t channel, uint8_t program); 00121 */ 00122 inline void attachnProgramChange(void (*fn)(uint8_t, uint8_t)) { 00123 onProgramChange = fn; 00124 } 00125 00126 /** 00127 * Attach a callback called when the `Channel Aftertouch` event is received 00128 * 00129 * @param ptr function pointer 00130 * prototype: void onChannelAftertouch(uint8_t channel, uint8_t pressure); 00131 */ 00132 inline void attachChannelAftertouch(void (*fn)(uint8_t, uint8_t)) { 00133 onChannelAftertouch = fn; 00134 } 00135 00136 /** 00137 * Attach a callback called when the `Time Code Quarter Frame` event is received 00138 * 00139 * @param ptr function pointer 00140 * prototype: void onTimeCodeQuarterFrame(uint8_t timing); 00141 */ 00142 inline void attachTimeCodeQuarterFrame(void (*fn)(uint8_t)) { 00143 onTimeCodeQuarterFrame = fn; 00144 } 00145 00146 /** 00147 * Attach a callback called when the `Song Select` event is received 00148 * 00149 * @param ptr function pointer 00150 * prototype: void onSongSelect(uint8_t song); 00151 */ 00152 inline void attachSongSelect(void (*fn)(uint8_t)) { 00153 onSongSelect = fn; 00154 } 00155 00156 /** 00157 * Attach a callback called when the `Note Off` event is received 00158 * 00159 * @param ptr function pointer 00160 * prototype: void onNoteOff(uint8_t channel, uint8_t note, uint8_t velocity); 00161 */ 00162 inline void attachNoteOff(void (*fn)(uint8_t, uint8_t, uint8_t)) { 00163 onNoteOff = fn; 00164 } 00165 00166 /** 00167 * Attach a callback called when the `Note On` event is received 00168 * 00169 * @param ptr function pointer 00170 * prototype: void onNoteOn(uint8_t channel, uint8_t note, uint8_t velocity); 00171 */ 00172 inline void attachNoteOn(void (*fn)(uint8_t, uint8_t, uint8_t)) { 00173 onNoteOn = fn; 00174 } 00175 00176 /** 00177 * Attach a callback called when the `Polyphonic Aftertouch` event is received 00178 * 00179 * @param ptr function pointer 00180 * prototype: void onPolyphonicAftertouch(uint8_t channel, uint8_t note, uint8_t pressure); 00181 */ 00182 inline void attachPolyphonicAftertouch(void (*fn)(uint8_t, uint8_t, uint8_t)) { 00183 onPolyphonicAftertouch = fn; 00184 } 00185 00186 /** 00187 * Attach a callback called when the `Control Change` event is received 00188 * 00189 * @param ptr function pointer 00190 * prototype: void onControlChange(uint8_t channel, uint8_t function, uint8_t value); 00191 */ 00192 inline void attachControlChange(void (*fn)(uint8_t, uint8_t, uint8_t)) { 00193 onControlChange = fn; 00194 } 00195 00196 /** 00197 * Attach a callback called when the `Pitch Wheel` event is received 00198 * 00199 * @param ptr function pointer 00200 * prototype: void onPitchWheel(uint8_t channel, uint16_t amount); 00201 */ 00202 inline void attachPitchWheel(void (*fn)(uint8_t, uint16_t)) { 00203 onPitchWheel = fn; 00204 } 00205 00206 /** 00207 * Attach a callback called when the `Song Position Pointer` event is received 00208 * 00209 * @param ptr function pointer 00210 * prototype: void onSongPositionPointer(uint16_t position); 00211 */ 00212 inline void attachSongPositionPointer(void (*fn)(uint16_t)) { 00213 onSongPositionPointer = fn; 00214 } 00215 00216 /** 00217 * Attach a callback called when the `System Exclusive` event is received 00218 * 00219 * @param ptr function pointer 00220 * prototype: void onSystemExclusive(uint8_t *sysex, uint16_t length, bool hasNextData); 00221 */ 00222 inline void attachSystemExclusive(void (*fn)(uint8_t *, uint16_t, bool)) { 00223 onSystemExclusive = fn; 00224 } 00225 00226 /** 00227 * Send a `Tune Request` event 00228 */ 00229 void sendTuneRequest(); 00230 00231 /** 00232 * Send a `Timing Clock` event 00233 */ 00234 void sendTimingClock(); 00235 00236 /** 00237 * Send a `Start` event 00238 */ 00239 void sendStart(); 00240 00241 /** 00242 * Send a `Continue` event 00243 */ 00244 void sendContinue(); 00245 00246 /** 00247 * Send a `Stop` event 00248 */ 00249 void sendStop(); 00250 00251 /** 00252 * Send a `Active Sensing` event 00253 */ 00254 void sendActiveSensing(); 00255 00256 /** 00257 * Send a `Reset` event 00258 */ 00259 void sendReset(); 00260 00261 /** 00262 * Send a `Program Change` event 00263 * 00264 * @param channel 0-15 00265 * @param program 0-127 00266 */ 00267 void sendProgramChange(uint8_t channel, uint8_t program); 00268 00269 /** 00270 * Send a `Channel Aftertouch` event 00271 * 00272 * @param channel 0-15 00273 * @param pressure 0-127 00274 */ 00275 void sendChannelAftertouch(uint8_t channel, uint8_t pressure); 00276 00277 /** 00278 * Send a `Time Code Quarter Frame` event 00279 * 00280 * @param timing 0-127 00281 */ 00282 void sendTimeCodeQuarterFrame(uint8_t timing); 00283 00284 /** 00285 * Send a `Song Select` event 00286 * 00287 * @param song 0-127 00288 */ 00289 void sendSongSelect(uint8_t song); 00290 00291 /** 00292 * Send a `Note Off` event 00293 * 00294 * @param channel 0-15 00295 * @param note 0-127 00296 * @param velocity 0-127 00297 */ 00298 void sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity); 00299 00300 /** 00301 * Send a `Note On` event 00302 * 00303 * @param channel 0-15 00304 * @param note 0-127 00305 * @param velocity 0-127 00306 */ 00307 void sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity); 00308 00309 /** 00310 * Send a `Polyphonic Aftertouch` event 00311 * 00312 * @param channel 0-15 00313 * @param note 0-127 00314 * @param pressure 0-127 00315 */ 00316 void sendPolyphonicAftertouch(uint8_t channel, uint8_t note, uint8_t pressure); 00317 00318 /** 00319 * Send a `Control Change` event 00320 * 00321 * @param channel 0-15 00322 * @param function 0-127 00323 * @param value 0-127 00324 */ 00325 void sendControlChange(uint8_t channel, uint8_t function, uint8_t value); 00326 00327 /** 00328 * Send a `Pitch Wheel` event 00329 * 00330 * @param channel 0-15 00331 * @param amount 0-8192(center)-16383 00332 */ 00333 void sendPitchWheel(uint8_t channel, uint16_t amount); 00334 00335 /** 00336 * Send a `Song Position Pointer` event 00337 * 00338 * @param position 0-16383 00339 */ 00340 void sendSongPositionPointer(uint16_t position); 00341 00342 /** 00343 * Send a `System Exclusive` event 00344 * 00345 * @param sysex the data starts with `0xf0` and ends with `0xf7` 00346 * @param length 00347 */ 00348 void sendSystemExclusive(uint8_t * sysex, uint16_t length); 00349 00350 /** 00351 * Notifies BLE disconnection to this BLE MIDI instance 00352 */ 00353 void onBleDisconnection(Gap::Handle_t handle, Gap::DisconnectionReason_t reason); 00354 00355 /** 00356 * Notifies BLE connection to this BLE MIDI instance 00357 */ 00358 void onBleConnection(Gap::Handle_t handle, Gap::addr_type_t type, const Gap::address_t addr, const Gap::ConnectionParams_t *params); 00359 00360 private: 00361 bool isConnected; 00362 00363 uint16_t sysExBufferPos; 00364 uint8_t sysExBuffer[128]; 00365 00366 uint16_t timestamp; 00367 00368 uint8_t midiEventKind; 00369 uint8_t midiEventNote; 00370 uint8_t midiEventVelocity; 00371 00372 enum MIDI_STATE { 00373 MIDI_STATE_TIMESTAMP = 0, 00374 MIDI_STATE_WAIT, 00375 MIDI_STATE_SIGNAL_2BYTES_2, 00376 MIDI_STATE_SIGNAL_3BYTES_2, 00377 MIDI_STATE_SIGNAL_3BYTES_3, 00378 MIDI_STATE_SIGNAL_SYSEX 00379 }; 00380 00381 MIDI_STATE midiState; 00382 00383 void (*onTuneRequest)(); 00384 void (*onTimingClock)(); 00385 void (*onStart)(); 00386 void (*onContinue)(); 00387 void (*onStop)(); 00388 void (*onActiveSensing)(); 00389 void (*onReset)(); 00390 void (*onProgramChange)(uint8_t, uint8_t); 00391 void (*onChannelAftertouch)(uint8_t, uint8_t); 00392 void (*onTimeCodeQuarterFrame)(uint8_t); 00393 void (*onSongSelect)(uint8_t); 00394 void (*onNoteOff)(uint8_t, uint8_t, uint8_t); 00395 void (*onNoteOn)(uint8_t, uint8_t, uint8_t); 00396 void (*onPolyphonicAftertouch)(uint8_t, uint8_t, uint8_t); 00397 void (*onControlChange)(uint8_t, uint8_t, uint8_t); 00398 void (*onPitchWheel)(uint8_t, uint16_t); 00399 void (*onSongPositionPointer)(uint16_t); 00400 void (*onSystemExclusive)(uint8_t *, uint16_t, bool); 00401 00402 void sendMidiMessage(uint8_t data0); 00403 void sendMidiMessage(uint8_t data0, uint8_t data1); 00404 void sendMidiMessage(uint8_t data0, uint8_t data1, uint8_t data2); 00405 00406 void dataWrittenCallback(const GattCharacteristicWriteCBParams *params); 00407 00408 uint8_t midi[20]; 00409 00410 BLEDevice *device; 00411 GattCharacteristic *midiCharacteristic; 00412 Timer tick; 00413 }; 00414 00415 #endif /* __BLEMIDI_H__ */
Generated on Tue Jul 12 2022 14:18:15 by 1.7.2