Line data Source code
1 : #pragma once 2 : 3 : #include <stddef.h> 4 : #include <stdint.h> 5 : #include <stdlib.h> 6 : 7 : #include <Def/Def.hpp> 8 : #include <Settings/SettingsWrapper.hpp> 9 : 10 : #ifndef ARDUINO 11 : #include <vector> 12 : #endif 13 : 14 : BEGIN_CS_NAMESPACE 15 : 16 : const uint8_t NOTE_OFF = 0x80; 17 : const uint8_t NOTE_ON = 0x90; 18 : const uint8_t KEY_PRESSURE = 0xA0; 19 : const uint8_t CC = 0xB0, CONTROL_CHANGE = CC; 20 : const uint8_t PROGRAM_CHANGE = 0xC0; 21 : const uint8_t CHANNEL_PRESSURE = 0xD0; 22 : const uint8_t PITCH_BEND = 0xE0; 23 : 24 : const uint8_t SysExStart = 0xF0; 25 : const uint8_t SysExEnd = 0xF7; 26 : 27 : const uint8_t TuneRequest = 0xF6; 28 : 29 : enum MIDI_read_t : uint8_t { 30 : NO_MESSAGE = 0, 31 : CHANNEL_MESSAGE = 1, 32 : SYSEX_MESSAGE = 2, 33 : 34 : /* System Real-Time messages */ 35 : TIMING_CLOCK_MESSAGE = 0xF8, 36 : UNDEFINED_REALTIME_MESSAGE_1 = 0xF9, 37 : START_MESSAGE = 0xFA, 38 : CONTINUE_MESSAGE = 0xFB, 39 : STOP_MESSAGE = 0xFC, 40 : UNDEFINED_REALTIME_MESSAGE_2 = 0xFD, 41 : ACTIVE_SENSING_MESSAGE = 0xFE, 42 : RESET_MESSAGE = 0xFF 43 : }; 44 : 45 : // -------------------------------------------------------------------------- // 46 : 47 : struct ChannelMessage { 48 : uint8_t header; 49 : uint8_t data1; 50 : uint8_t data2; 51 : 52 : uint8_t CN = 0; 53 : 54 17 : bool operator==(const ChannelMessage &other) const { 55 34 : return this->header == other.header && this->data1 == other.data1 && 56 17 : this->data2 == other.data2 && this->CN == other.CN; 57 : } 58 : 59 : bool operator!=(const ChannelMessage &other) const { 60 : return !(*this == other); 61 : } 62 : }; 63 : 64 : struct SysExMessage { 65 3 : SysExMessage() : data(nullptr), length(0), CN(0) {} 66 93 : SysExMessage(const uint8_t *data, size_t length, uint8_t CN = 0) 67 93 : : data(data), length(length), CN(CN) {} 68 : #ifndef ARDUINO 69 12 : SysExMessage(const std::vector<uint8_t> &vec, uint8_t CN = 0) 70 12 : : data(vec.data()), length(vec.size()), CN(CN) {} 71 : #endif 72 : const uint8_t *data; 73 : uint8_t length; 74 : uint8_t CN; 75 : }; 76 : 77 : struct RealTimeMessage { 78 : uint8_t message; 79 : uint8_t CN; 80 : }; 81 : 82 : // -------------------------------------------------------------------------- // 83 : 84 85 : class MIDI_Parser { 85 : public: 86 : /** Get the latest MIDI channel message */ 87 : ChannelMessage getChannelMessage(); 88 : #if !IGNORE_SYSEX 89 : /** Get the latest SysEx message. */ 90 : virtual SysExMessage getSysEx() const = 0; 91 : #else 92 : SysExMessage getSysEx() const { return {nullptr, 0, 0}; } 93 : #endif 94 : /** Get the pointer to the SysEx data. */ 95 48 : const uint8_t *getSysExBuffer() const { return getSysEx().data; } 96 : /** Get the length of the SysEx message. */ 97 24 : size_t getSysExLength() const { return getSysEx().length; } 98 : /** Get the cable number of the latests MIDI message */ 99 2 : virtual uint8_t getCN() const { return 0; }; 100 : 101 : protected: 102 85 : ChannelMessage midimsg = {}; 103 : 104 : public: 105 : /** Check if the given byte is a MIDI header byte. */ 106 : static bool isStatus(uint8_t data); 107 : /** Check if the given byte is a MIDI data byte. */ 108 : static bool isData(uint8_t data); 109 : }; 110 : 111 : END_CS_NAMESPACE