A class that converts byte streams into MIDI messages, and stores them in a FIFO. This is useful if you wish to read MIDI messages via polling instead of interrupts. The class supports every type of MIDI message, and System Realtime messages can be interleaved with regular ones.

Committer:
Padman
Date:
Thu Aug 04 12:15:36 2016 +0000
Revision:
2:cbd43ba7f842
Parent:
1:1c3f0c6ea0fb
Further API documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
Padman 0:69cbdcd5d770 1 /**
Padman 0:69cbdcd5d770 2 * @file MIDIparser.cpp
Padman 0:69cbdcd5d770 3 * @brief MIDI parser - converts bytes into queued MIDI messages
Padman 0:69cbdcd5d770 4 * @author Patrick Thomas
Padman 0:69cbdcd5d770 5 * @version 1.0
Padman 0:69cbdcd5d770 6 * @see
Padman 0:69cbdcd5d770 7 *
Padman 0:69cbdcd5d770 8 * Copyright (c) 2016
Padman 0:69cbdcd5d770 9 *
Padman 0:69cbdcd5d770 10 * Licensed under the Apache License, Version 2.0 (the "License");
Padman 0:69cbdcd5d770 11 * you may not use this file except in compliance with the License.
Padman 0:69cbdcd5d770 12 * You may obtain a copy of the License at
Padman 0:69cbdcd5d770 13 *
Padman 0:69cbdcd5d770 14 * http://www.apache.org/licenses/LICENSE-2.0
Padman 0:69cbdcd5d770 15 *
Padman 0:69cbdcd5d770 16 * Unless required by applicable law or agreed to in writing, software
Padman 0:69cbdcd5d770 17 * distributed under the License is distributed on an "AS IS" BASIS,
Padman 0:69cbdcd5d770 18 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Padman 0:69cbdcd5d770 19 * See the License for the specific language governing permissions and
Padman 0:69cbdcd5d770 20 * limitations under the License.
Padman 0:69cbdcd5d770 21 */
Padman 0:69cbdcd5d770 22
Padman 0:69cbdcd5d770 23 #include "MIDIparser.h"
Padman 0:69cbdcd5d770 24
Padman 0:69cbdcd5d770 25 MIDIparser::MIDIparser() {
Padman 0:69cbdcd5d770 26
Padman 0:69cbdcd5d770 27 }
Padman 0:69cbdcd5d770 28
Padman 0:69cbdcd5d770 29 void MIDIparser::parse(uint8_t this_byte) {
Padman 0:69cbdcd5d770 30
Padman 0:69cbdcd5d770 31 // Data byte
Padman 0:69cbdcd5d770 32 if (this_byte < 128) {
Padman 0:69cbdcd5d770 33
Padman 0:69cbdcd5d770 34 // We expect the output buffer to be non-empty here
Padman 0:69cbdcd5d770 35 if (input_vector.available()) {
Padman 0:69cbdcd5d770 36
Padman 0:69cbdcd5d770 37 input_vector.put(this_byte);
Padman 0:69cbdcd5d770 38
Padman 0:69cbdcd5d770 39 // Dual condition - perform one more read after this
Padman 0:69cbdcd5d770 40 if (!sysex && dual) dual = false;
Padman 0:69cbdcd5d770 41
Padman 0:69cbdcd5d770 42 // Single condition - send two bytes now
Padman 0:69cbdcd5d770 43 else if (!sysex && !dual) {
Padman 0:69cbdcd5d770 44
Padman 0:69cbdcd5d770 45 output_queue.push(MIDIMessage(input_vector.head(), input_vector.size()));
Padman 0:69cbdcd5d770 46 input_vector.clear();
Padman 0:69cbdcd5d770 47 }
Padman 0:69cbdcd5d770 48 }
Padman 0:69cbdcd5d770 49 }
Padman 0:69cbdcd5d770 50
Padman 0:69cbdcd5d770 51 // System realtime byte
Padman 0:69cbdcd5d770 52 else if (this_byte > 243) {
Padman 0:69cbdcd5d770 53
Padman 0:69cbdcd5d770 54 switch (this_byte & 0xF) {
Padman 0:69cbdcd5d770 55
Padman 0:69cbdcd5d770 56 // Undefined
Padman 0:69cbdcd5d770 57 case 4:
Padman 0:69cbdcd5d770 58 case 5:
Padman 0:69cbdcd5d770 59 break;
Padman 0:69cbdcd5d770 60
Padman 0:69cbdcd5d770 61 // Sysex end
Padman 0:69cbdcd5d770 62 case 7:
Padman 0:69cbdcd5d770 63 // Only output valid Sysex data
Padman 0:69cbdcd5d770 64 if (sysex && !dual) output_queue.push(MIDIMessage(input_vector.head(), input_vector.size()));
Padman 0:69cbdcd5d770 65 input_vector.clear();
Padman 0:69cbdcd5d770 66 break;
Padman 0:69cbdcd5d770 67
Padman 0:69cbdcd5d770 68 // Realtime
Padman 0:69cbdcd5d770 69 default:
Padman 0:69cbdcd5d770 70 output_queue.push(MIDIMessage(&this_byte, 1));
Padman 0:69cbdcd5d770 71 break;
Padman 0:69cbdcd5d770 72 }
Padman 0:69cbdcd5d770 73 }
Padman 0:69cbdcd5d770 74
Padman 0:69cbdcd5d770 75 // Status byte
Padman 0:69cbdcd5d770 76 else {
Padman 0:69cbdcd5d770 77
Padman 0:69cbdcd5d770 78 // We expect the output buffer to be empty here
Padman 0:69cbdcd5d770 79 if (!input_vector.available()) {
Padman 0:69cbdcd5d770 80
Padman 0:69cbdcd5d770 81 input_vector.put(this_byte);
Padman 0:69cbdcd5d770 82
Padman 0:69cbdcd5d770 83 // Set flags
Padman 0:69cbdcd5d770 84 switch ((this_byte >> 4) & 7) {
Padman 0:69cbdcd5d770 85 case 0:
Padman 0:69cbdcd5d770 86 case 1:
Padman 0:69cbdcd5d770 87 case 2:
Padman 0:69cbdcd5d770 88 case 3:
Padman 0:69cbdcd5d770 89 case 6:
Padman 0:69cbdcd5d770 90 sysex = false;
Padman 0:69cbdcd5d770 91 dual = true;
Padman 0:69cbdcd5d770 92 break;
Padman 0:69cbdcd5d770 93
Padman 0:69cbdcd5d770 94 case 4:
Padman 0:69cbdcd5d770 95 case 5:
Padman 0:69cbdcd5d770 96 sysex = false;
Padman 0:69cbdcd5d770 97 dual = false;
Padman 0:69cbdcd5d770 98 break;
Padman 0:69cbdcd5d770 99
Padman 0:69cbdcd5d770 100 case 7:
Padman 0:69cbdcd5d770 101 switch (this_byte & 7) {
Padman 0:69cbdcd5d770 102 case 0:
Padman 0:69cbdcd5d770 103 sysex = true;
Padman 0:69cbdcd5d770 104 dual = false;
Padman 0:69cbdcd5d770 105 break;
Padman 0:69cbdcd5d770 106
Padman 0:69cbdcd5d770 107 case 1:
Padman 0:69cbdcd5d770 108 case 3:
Padman 0:69cbdcd5d770 109 sysex = false;
Padman 0:69cbdcd5d770 110 dual = false;
Padman 0:69cbdcd5d770 111 break;
Padman 0:69cbdcd5d770 112
Padman 0:69cbdcd5d770 113 case 2:
Padman 0:69cbdcd5d770 114 sysex = false;
Padman 0:69cbdcd5d770 115 dual = true;
Padman 0:69cbdcd5d770 116 break;
Padman 0:69cbdcd5d770 117
Padman 0:69cbdcd5d770 118 default:
Padman 0:69cbdcd5d770 119 break;
Padman 0:69cbdcd5d770 120 }
Padman 0:69cbdcd5d770 121 break;
Padman 0:69cbdcd5d770 122
Padman 0:69cbdcd5d770 123 default:
Padman 0:69cbdcd5d770 124 break;
Padman 0:69cbdcd5d770 125 }
Padman 0:69cbdcd5d770 126 }
Padman 0:69cbdcd5d770 127
Padman 0:69cbdcd5d770 128 // Invalidate the output buffer by setting flags
Padman 0:69cbdcd5d770 129 else {
Padman 0:69cbdcd5d770 130 sysex = true;
Padman 0:69cbdcd5d770 131 dual = true;
Padman 0:69cbdcd5d770 132 }
Padman 0:69cbdcd5d770 133 }
Padman 0:69cbdcd5d770 134 }
Padman 0:69cbdcd5d770 135
Padman 1:1c3f0c6ea0fb 136 uint32_t MIDIparser::available() { return !output_queue.empty(); }
Padman 0:69cbdcd5d770 137
Padman 0:69cbdcd5d770 138 MIDIMessage MIDIparser::grab() {
Padman 0:69cbdcd5d770 139
Padman 0:69cbdcd5d770 140 MIDIMessage output;
Padman 0:69cbdcd5d770 141 output = output_queue.front();
Padman 0:69cbdcd5d770 142 output_queue.pop();
Padman 0:69cbdcd5d770 143 return output;
Padman 0:69cbdcd5d770 144 }