Dependencies:   BLE_API mbed nRF51822_BLE_MIDI

Dependents:   BLE_MIDI_one_note_TEST

Fork of BLE_MIDI by Kaoru Shoji

BLEMIDI.h

Committer:
kshoji
Date:
2015-04-03
Revision:
1:cba2eba64f5c
Parent:
0:83889dc90473
Child:
2:dbc6f81b9ba0

File content as of revision 1:cba2eba64f5c:

/* Copyright (c) 2014 mbed.org, MIT License
 *
 * 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.
 */

#ifndef __BLEMIDI_H__
#define __BLEMIDI_H__

#include "BLEDevice.h"

/** 
 * A class to communicate a BLE MIDI device
 */
class BLEMIDI {
public:
    /**
     * Constructor
     */
    BLEMIDI(BLEDevice *device);

    /**
     * Check if a BLE MIDI device is connected
     *
     * @returns true if a midi device is connected
     */
    bool connected();

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onTuneRequest();
     */
    inline void attachTuneRequest(void (*fn)()) {
        onTuneRequest = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onTimingClock();
     */
    inline void attachTimingClock(void (*fn)()) {
        onTimingClock = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onStart();
     */
    inline void attachStart(void (*fn)()) {
        onStart = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onContinue();
     */
    inline void attachContinue(void (*fn)()) {
        onContinue = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onStop();
     */
    inline void attachStop(void (*fn)()) {
        onStop = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onActiveSensing();
     */
    inline void attachActiveSensing(void (*fn)()) {
        onActiveSensing = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onReset();
     */
    inline void attachReset(void (*fn)()) {
        onReset = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onProgramChange(uint8_t, uint8_t);
     */
    inline void attachnProgramChange(void (*fn)(uint8_t, uint8_t)) {
        onProgramChange = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onChannelAftertouch(uint8_t, uint8_t);
     */
    inline void attachChannelAftertouch(void (*fn)(uint8_t, uint8_t)) {
        onChannelAftertouch = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onTimeCodeQuarterFrame(uint8_t);
     */
    inline void attachTimeCodeQuarterFrame(void (*fn)(uint8_t)) {
        onTimeCodeQuarterFrame = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onSongSelect(uint8_t);
     */
    inline void attachSongSelect(void (*fn)(uint8_t)) {
        onSongSelect = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onNoteOff(uint8_t, uint8_t, uint8_t);
     */
    inline void attachNoteOff(void (*fn)(uint8_t, uint8_t, uint8_t)) {
        onNoteOff = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onNoteOn(uint8_t, uint8_t, uint8_t);
     */
    inline void attachNoteOn(void (*fn)(uint8_t, uint8_t, uint8_t)) {
        onNoteOn = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onPolyphonicAftertouch(uint8_t, uint8_t, uint8_t);
     */
    inline void attachPolyphonicAftertouch(void (*fn)(uint8_t, uint8_t, uint8_t)) {
        onPolyphonicAftertouch = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onControlChange(uint8_t, uint8_t, uint8_t);
     */
    inline void attachControlChange(void (*fn)(uint8_t, uint8_t, uint8_t)) {
        onControlChange = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onPitchWheel(uint8_t, uint16_t);
     */
    inline void attachPitchWheel(void (*fn)(uint8_t, uint16_t)) {
        onPitchWheel = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onSongPositionPointer(uint16_t);
     */
    inline void attachSongPositionPointer(void (*fn)(uint16_t)) {
        onSongPositionPointer = fn;
    }

    /**
     * Attach a callback called when the MIDI event is received
     *
     * @param ptr function pointer
     *   prototype: void onSystemExclusive(uint8_t *, uint16_t);
     */
    inline void attachSystemExclusive(void (*fn)(uint8_t *, uint16_t)) {
        onSystemExclusive = fn;
    }

    void sendTuneRequest();
    void sendTimingClock();
    void sendStart();
    void sendContinue();
    void sendStop();
    void sendActiveSensing();
    void sendReset();
    void sendProgramChange(uint8_t channel, uint8_t program);
    void sendChannelAftertouch(uint8_t channel, uint8_t pressure);
    void sendTimeCodeQuarterFrame(uint8_t timing);
    void sendSongSelect(uint8_t song);
    void sendNoteOff(uint8_t channel, uint8_t note, uint8_t velocity);
    void sendNoteOn(uint8_t channel, uint8_t note, uint8_t velocity);
    void sendPolyphonicAftertouch(uint8_t channel, uint8_t note, uint8_t pressure);
    void sendControlChange(uint8_t channel, uint8_t function, uint8_t value);
    void sendPitchWheel(uint8_t channel, uint16_t amount);
    void sendSongPositionPointer(uint16_t position);
    void sendSystemExclusive(uint8_t * sysex, uint16_t length);

    void onBleDisconnection(Gap::Handle_t handle, Gap::DisconnectionReason_t reason);
    void onBleConnection(Gap::Handle_t handle, Gap::addr_type_t type, const Gap::address_t addr, const Gap::ConnectionParams_t *params);


private:
    bool isConnected;

    uint16_t sysExBufferPos;
    uint8_t sysExBuffer[256];
    
    uint16_t timestamp;

    uint8_t midiEventKind;
    uint8_t midiEventNote;
    uint8_t midiEventVelocity;

    enum MIDI_STATE {
        MIDI_STATE_TIMESTAMP = 0,
        MIDI_STATE_WAIT,
        MIDI_STATE_SIGNAL_2BYTES_2,
        MIDI_STATE_SIGNAL_3BYTES_2,
        MIDI_STATE_SIGNAL_3BYTES_3,
        MIDI_STATE_SIGNAL_SYSEX
    };

    MIDI_STATE midiState;

    void (*onTuneRequest)();
    void (*onTimingClock)();
    void (*onStart)();
    void (*onContinue)();
    void (*onStop)();
    void (*onActiveSensing)();
    void (*onReset)();
    void (*onProgramChange)(uint8_t, uint8_t);
    void (*onChannelAftertouch)(uint8_t, uint8_t);
    void (*onTimeCodeQuarterFrame)(uint8_t);
    void (*onSongSelect)(uint8_t);
    void (*onNoteOff)(uint8_t, uint8_t, uint8_t);
    void (*onNoteOn)(uint8_t, uint8_t, uint8_t);
    void (*onPolyphonicAftertouch)(uint8_t, uint8_t, uint8_t);
    void (*onControlChange)(uint8_t, uint8_t, uint8_t);
    void (*onPitchWheel)(uint8_t, uint16_t);
    void (*onSongPositionPointer)(uint16_t);
    void (*onSystemExclusive)(uint8_t *, uint16_t);

    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 dataWrittenCallback(const GattCharacteristicWriteCBParams *params);

    uint8_t midi[20];

    BLEDevice *device;
    GattCharacteristic *midiCharacteristic;    
    Timer tick;
};

#endif /* __BLEMIDI_H__ */