fix thinko when dealing with non-MIDI tracks
[ardour.git] / libs / ardour / raw_midi_parser.cc
1 /*
2  * Copyright (C) 2017 Robin Gareus <robin@gareus.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License along
15  * with this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  */
18
19 #include "ardour/raw_midi_parser.h"
20
21 using namespace ARDOUR;
22
23 RawMidiParser::RawMidiParser ()
24 {
25         reset ();
26 }
27
28 /* based on AlsaRawMidiIn, some code-dup */
29 bool
30 RawMidiParser::process_byte (const uint8_t byte)
31 {
32         if (byte >= 0xf8) {
33                 // Realtime
34                 if (byte == 0xfd) {
35                         return false;
36                 }
37                 prepare_byte_event (byte);
38                 return true;
39         }
40         if (byte == 0xf7) {
41                 // Sysex end
42                 if (_status_byte == 0xf0) {
43                         record_byte (byte);
44                         return prepare_buffered_event ();
45                 }
46                 _total_bytes = 0;
47                 _unbuffered_bytes = 0;
48                 _expected_bytes = 0;
49                 _status_byte = 0;
50                 return false;
51         }
52         if (byte >= 0x80) {
53                 // Non-realtime status byte
54                 if (_total_bytes) {
55                         _total_bytes = 0;
56                         _unbuffered_bytes = 0;
57                 }
58                 _status_byte = byte;
59                 switch (byte & 0xf0) {
60                         case 0x80:
61                         case 0x90:
62                         case 0xa0:
63                         case 0xb0:
64                         case 0xe0:
65                                 // Note On, Note Off, Aftertouch, Control Change, Pitch Wheel
66                                 _expected_bytes = 3;
67                                 break;
68                         case 0xc0:
69                         case 0xd0:
70                                 // Program Change, Channel Pressure
71                                 _expected_bytes = 2;
72                                 break;
73                         case 0xf0:
74                                 switch (byte) {
75                                         case 0xf0:
76                                                 // Sysex
77                                                 _expected_bytes = 0;
78                                                 break;
79                                         case 0xf1:
80                                         case 0xf3:
81                                                 // MTC Quarter Frame, Song Select
82                                                 _expected_bytes = 2;
83                                                 break;
84                                         case 0xf2:
85                                                 // Song Position
86                                                 _expected_bytes = 3;
87                                                 break;
88                                         case 0xf4:
89                                         case 0xf5:
90                                                 // Undefined
91                                                 _expected_bytes = 0;
92                                                 _status_byte = 0;
93                                                 return false;
94                                         case 0xf6:
95                                                 // Tune Request
96                                                 prepare_byte_event (byte);
97                                                 _expected_bytes = 0;
98                                                 _status_byte = 0;
99                                                 return true;
100                                 }
101                 }
102                 record_byte (byte);
103                 return false;
104         }
105         // Data byte
106         if (!_status_byte) {
107                 // Data bytes without a status will be discarded.
108                 _total_bytes++;
109                 _unbuffered_bytes++;
110                 return false;
111         }
112         if (!_total_bytes) {
113                 record_byte (_status_byte);
114         }
115         record_byte (byte);
116         return (_total_bytes == _expected_bytes) ? prepare_buffered_event () : false;
117 }