Jamoma API  0.6.0.a19
MIDIParserFrom.cpp
Go to the documentation of this file.
1 /** @file
2  *
3  * @ingroup modularMIDI
4  *
5  * @brief edit /channel.N/command.M #TTAddress and a #TTValue from incoming bytes
6  *
7  * @details it handles sysex @n
8  *
9  * @author Theo Delahogue
10  *
11  * @copyright © 2014, GMEA (http://www.gmea.net) @n
12  * This code is licensed under the terms of the "New BSD License" @n
13  * http://creativecommons.org/licenses/BSD/
14  */
15 
16 #include "MIDIParserFrom.h"
17 
18 MIDIParserFrom::MIDIParserFrom() :
19 sysex(NO)
20 {
21  ;
22 }
23 
24 MIDIParserFrom::~MIDIParserFrom()
25 {
26  ;
27 }
28 
29 TTBoolean MIDIParserFrom::parse(TTUInt8 statusByte, TTUInt8 dataByte1, TTUInt8 dataByte2)
30 {
31  // clear the parser (except in sysex case)
32  if (!sysex) {
33  address = kTTAdrsEmpty;
34  value.clear();
35  }
36 
37  // parse command and channel
38  TTUInt8 command = statusByte & 0xF0;
39  TTUInt8 channel = (statusByte & 0x0F) + 1;
40 
41  // SYSTEM EXCLUSIVE starts : dataByte1 = id code then any number of byte
42  if (!sysex && command == 240 && channel == 1) {
43 
44  sysex = YES;
45  address = TTAddress("/sysex");
46  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
47  return NO;
48  }
49 
50  if (sysex) {
51 
52  // SYSTEM EXCLUSIVE ends
53  if (command == 247 && channel == 1) {
54  sysex = NO;
55  return YES;
56  }
57 
58  value.append(TTUInt32(statusByte));
59 
60  // SYSTEM EXCLUSIVE ends
61  if (TTUInt8(dataByte1) == 247) {
62  sysex = NO;
63  return YES;
64  }
65 
66  value.append(TTUInt32(dataByte1));
67 
68  // SYSTEM EXCLUSIVE ends
69  if (TTUInt8(dataByte2) == 247) {
70  sysex = NO;
71  return YES;
72  }
73 
74  value.append(TTUInt32(dataByte2));
75 
76  return NO;
77  }
78  else {
79 
80  // edit channel address part
81  TTAddress channelPart;
82  editAddress("/channel.%ld", channel, channelPart);
83 
84  // edit command address part and value
85  TTAddress commandPart;
86 
87  switch (command) {
88 
89  case 128 : // NOTE OFF : dataByte1 = pitch, dataByte2 = velocity (always 0)
90  {
91  editAddress("note.%ld", dataByte1, commandPart);
92  value = TTUInt32(dataByte2);
93  break;
94  }
95  case 144 : // NOTE ON : dataByte1 = pitch, dataByte2 = velocity (always > 0)
96  {
97  editAddress("note.%ld", dataByte1, commandPart);
98  value = TTUInt32(dataByte2);
99  break;
100  }
101  case 160 : // POLY PRESSURE : dataByte1 = pitch, dataByte2 = pressure
102  {
103  editAddress("pressure.%ld", dataByte1, commandPart);
104  value = TTUInt32(dataByte2);
105  break;
106  }
107  case 176 : // CONTROL CHANGE : dataByte1 = control type, dataByte2 = control value
108  {
109  editAddress("control.%ld", dataByte1, commandPart);
110  value = TTUInt32(dataByte2);
111  break;
112  }
113  case 192 : // PROGRAM CHANGE : dataByte1 = program number, dataByte2 not used
114  {
115  editAddress("program.%ld", dataByte1, commandPart);
116  value.clear();
117  break;
118  }
119  case 208 : // CHANNEL PRESSURE : dataByte1 = pressure, dataByte2 not used
120  {
121  commandPart = TTAddress("pressure");
122  value = TTUInt32(dataByte1);
123  break;
124  }
125  case 224 : // PITCH WHEEL : dataByte1 = LSB, dataByte2 = MSB
126  {
127  commandPart = TTAddress("wheel");
128 
129  TTUInt16 LSB = dataByte1;
130  TTUInt16 MSB = TTUInt16(dataByte2) << 8;
131  value = TTUInt32(MSB + LSB);
132  break;
133  }
134  case 241 : // UNDEFINED : dataByte1 not used, dataByte2 not used
135  {
136  channelPart = kTTAdrsRoot;
137  editAddress("undefined.%ld", command, commandPart);
138  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
139  break;
140  }
141  case 242 : // SONG POSITION : dataByte1 = LSB, dataByte2 = MSB
142  {
143  channelPart = kTTAdrsRoot;
144  commandPart = TTAddress("song/position");
145 
146  TTUInt16 LSB = dataByte1;
147  TTUInt16 MSB = TTUInt16(dataByte2) << 8;
148  value = TTUInt32(MSB + LSB);
149  break;
150  }
151  case 243 : // SONG SELECT : dataByte1 = song, dataByte2 not used
152  {
153  channelPart = kTTAdrsRoot;
154  commandPart = TTAddress("song/select");
155  value = TTUInt32(dataByte1);
156  break;
157  }
158  case 244 : // UNDEFINED : dataByte1 not used, dataByte2 not used
159  {
160  channelPart = kTTAdrsRoot;
161  editAddress("undefined.%ld", command, commandPart);
162  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
163  break;
164  }
165  case 245 : // UNDEFINED : dataByte1 not used, dataByte2 not used
166  {
167  channelPart = kTTAdrsRoot;
168  editAddress("undefined.%ld", command, commandPart);
169  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
170  break;
171  }
172  case 246 : // TUNE REQUEST : dataByte1 not used, dataByte2 not used
173  {
174  commandPart = TTAddress("tune_request");
175  value.clear();
176  break;
177  }
178  case 248 : // TIMING CLOCK : dataByte1 not used, dataByte2 not used
179  {
180  commandPart = TTAddress("clock");
181  value.clear();
182  break;
183  }
184  case 249 : // UNDEFINED : dataByte1 not used, dataByte2 not used
185  {
186  channelPart = kTTAdrsRoot;
187  editAddress("undefined.%ld", command, commandPart);
188  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
189  break;
190  }
191  case 250 : // START : dataByte1 not used, dataByte2 not used
192  {
193  commandPart = TTAddress("start");
194  value.clear();
195  break;
196  }
197  case 251 : // CONTINUE : dataByte1 not used, dataByte2 not used
198  {
199  commandPart = TTAddress("continue");
200  value.clear();
201  break;
202  }
203  case 252 : // STOP : dataByte1 not used, dataByte2 not used
204  {
205  commandPart = TTAddress("stop");
206  value.clear();
207  break;
208  }
209  case 253 : // UNDEFINED : dataByte1 not used, dataByte2 not used
210  {
211  channelPart = kTTAdrsRoot;
212  editAddress("undefined.%ld", command, commandPart);
213  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
214  break;
215  }
216  case 254 : // ACTIVE SENSING : dataByte1 not used, dataByte2 not used
217  {
218  commandPart = TTAddress("active_sensing");
219  value.clear();
220  break;
221  }
222  case 255 : // SYSTEM RESET : dataByte1 not used, dataByte2 not used
223  {
224  commandPart = TTAddress("reset");
225  value.clear();
226  break;
227  }
228  default : // UNDEFINED : dataByte1 not used, dataByte2 not used
229  {
230  channelPart = kTTAdrsRoot;
231  editAddress("undefined.%ld", command, commandPart);
232  value = TTValue(TTUInt32(dataByte1), TTUInt32(dataByte2));
233  break;
234  }
235  }
236 
237  // edit /channelPart/commandPart address
238  address = channelPart.appendAddress(commandPart);
239 
240  // TODO ? edit /raw statusByte dataByte1 dataByte2
241  // TODO ? return buffer[i].timestamp
242 
243  return YES;
244  }
245 }
246 
247 void MIDIParserFrom::editAddress(TTString format, TTUInt8 i, TTAddress& returnedAddress)
248 {
249  char *s_num;
250  TTUInt8 len;
251 
252  if (i > 0) {
253  len = format.size() + (TTInt32)log10((TTFloat32)i); // note : %d (lenght = 2) is replaced by 1 character (0::9), 2 charecters (10 :: 99), 3 char...
254  s_num = (char *)malloc(sizeof(char)*len);
255  snprintf(s_num, len, format.c_str(), i);
256  returnedAddress = TTAddress(s_num);
257  free(s_num);
258  }
259 }
TTAddress appendAddress(const TTAddress &toAppend)
Return a new TTAddress with the appended part.
Definition: TTAddress.h:167
bool TTBoolean
Boolean flag, same as Boolean on the Mac.
Definition: TTBase.h:167
std::uint16_t TTUInt16
16 bit unsigned integer
Definition: TTBase.h:176
edit /channel.N/command.M TTAddress and a TTValue from incoming bytes
const char * c_str() const
Return a pointer to the internal C-string.
Definition: TTString.h:83
The TTAddress class is used to represent a string and efficiently pass and compare that string...
Definition: TTAddress.h:29
float TTFloat32
32 bit floating point number
Definition: TTBase.h:187
std::int32_t TTInt32
32 bit signed integer
Definition: TTBase.h:177
std::uint32_t TTUInt32
32 bit unsigned integer
Definition: TTBase.h:178
size_t size() const
Find out the length of a string.
Definition: TTString.h:144
The TTString class is used to represent a string.
Definition: TTString.h:34
[doxygenAppendixC_copyExample]
Definition: TTValue.h:34
unsigned char TTUInt8
8 bit unsigned integer (char)
Definition: TTBase.h:174