Mercurial > hg > beaglert
comparison include/Midi.h @ 197:265a527f8be8
Added MidiParser for channel messages
author | Giulio Moro <giuliomoro@yahoo.it> |
---|---|
date | Fri, 05 Feb 2016 06:16:35 +0000 |
parents | b3a306da03e0 |
children | b128e3ea84ff |
comparison
equal
deleted
inserted
replaced
196:0029562391b1 | 197:265a527f8be8 |
---|---|
11 #include <BeagleRT.h> | 11 #include <BeagleRT.h> |
12 #include <vector> | 12 #include <vector> |
13 | 13 |
14 typedef unsigned char midi_byte_t; | 14 typedef unsigned char midi_byte_t; |
15 | 15 |
16 | |
17 typedef enum midiMessageType{ | |
18 kmmNoteOff = 0, | |
19 kmmNoteOn, | |
20 kmmPolyphonicKeyPressure, | |
21 kmmControlChange, | |
22 kmmProgramChange, | |
23 kmmChannelPressure, | |
24 kmmPitchBend, | |
25 kmmNone, | |
26 kmmAny, | |
27 } MidiMessageType; | |
28 #define midiMessageStatusBytesLength 7+2 //2 being kmmNone and kmmAny | |
29 | |
30 extern midi_byte_t midiMessageStatusBytes[midiMessageStatusBytesLength]; | |
31 extern unsigned int midiMessageNumDataBytes[midiMessageStatusBytesLength]; | |
32 | |
33 class MidiChannelMessage{ | |
34 public: | |
35 MidiChannelMessage(); | |
36 MidiChannelMessage(MidiMessageType type); | |
37 virtual ~MidiChannelMessage(); | |
38 MidiMessageType getType(); | |
39 int getChannel(); | |
40 unsigned int getNumDataBytes(){ | |
41 return midiMessageNumDataBytes[(unsigned int)_type]; | |
42 } | |
43 void setDataByte(unsigned int dataByteIndex, midi_byte_t input){ | |
44 _dataBytes[dataByteIndex] = input; | |
45 } | |
46 void setType(MidiMessageType type){ | |
47 _type = type; | |
48 _statusByte = midiMessageStatusBytes[_type]; | |
49 } | |
50 void setChannel(midi_byte_t channel){ | |
51 _channel = channel; | |
52 } | |
53 midi_byte_t getDataByte(unsigned int index){ | |
54 return _dataBytes[index]; | |
55 } | |
56 void clear(){ | |
57 for(int n = 0; n<maxDataBytes; n++){ | |
58 _dataBytes[n] = 0; | |
59 } | |
60 _type = kmmNone; | |
61 _statusByte = 0; | |
62 } | |
63 void prettyPrint(){ | |
64 rt_printf("MessageType: %x, ", this->getType()); | |
65 rt_printf("channel: %u, ", this->getChannel()); | |
66 for(int n = 0; n < this->getNumDataBytes(); n++){ | |
67 rt_printf("data%d: %d, ", n + 1, this->getDataByte(n)); | |
68 } | |
69 rt_printf("\n"); | |
70 } | |
71 | |
72 private: | |
73 const static int maxDataBytes = 2; | |
74 protected: | |
75 midi_byte_t _statusByte; | |
76 midi_byte_t _dataBytes[maxDataBytes]; // where 2 is the maximum number of data bytes for a channel message | |
77 MidiMessageType _type; | |
78 midi_byte_t _channel; | |
79 }; | |
80 /* | |
81 class MidiControlChangeMessage : public MidiChannelMessage{ | |
82 int number; | |
83 int value; | |
84 public: | |
85 int getNumber(); | |
86 int getNumDataBytes(); | |
87 int setDataByte(midi_byte_t input, unsigned int dataByteIndex); | |
88 int getValue(); | |
89 int set(midi_byte_t* input); | |
90 }; | |
91 | |
92 class MidiNoteMessage : public MidiChannelMessage{ | |
93 int note; | |
94 int velocity; | |
95 public: | |
96 int getNote(); | |
97 int getVelocity(); | |
98 int getNumDataBytes(); | |
99 int setDataByte(midi_byte_t input, unsigned int dataByteIndex); | |
100 }; | |
101 | |
102 class MidiProgramChangeMessage : public MidiChannelMessage{ | |
103 midi_byte_t program; | |
104 public: | |
105 int getNumDataBytes(); | |
106 int setDataByte(midi_byte_t input, unsigned int dataByteIndex); | |
107 midi_byte_t getProgram(); | |
108 }; | |
109 */ | |
110 | |
111 class MidiParser{ | |
112 private: | |
113 std::vector<MidiChannelMessage> messages; | |
114 unsigned int writePointer; | |
115 unsigned int readPointer; | |
116 unsigned int elapsedDataBytes; | |
117 bool waitingForStatus; | |
118 public: | |
119 MidiParser(){ | |
120 waitingForStatus = true; | |
121 elapsedDataBytes= 0; | |
122 messages.resize(100); // 100 is the number of messages that can be buffered | |
123 writePointer = 0; | |
124 readPointer = 0; | |
125 } | |
126 | |
127 /** | |
128 * Parses some midi messages. | |
129 * | |
130 * @param input the array to read from | |
131 * @param length the maximum number of values available at the array | |
132 * | |
133 * @return the number of bytes parsed | |
134 */ | |
135 int parse(midi_byte_t* input, unsigned int length); | |
136 int callme(){ | |
137 return readPointer; | |
138 }; | |
139 int numAvailableMessages(){ | |
140 int num = (writePointer - readPointer + messages.size() ) % messages.size(); | |
141 if(num > 0){ | |
142 int a = a +1; | |
143 a = callme(); | |
144 } | |
145 return num; | |
146 } | |
147 /** | |
148 * Get the oldest channel message in the buffer. | |
149 * | |
150 * You should not call this function when numAvailableMessages() returns 0. | |
151 * @param type the type of the message to retrieve | |
152 * @return a copy of the oldest message of the give type in the buffer | |
153 */ | |
154 MidiChannelMessage getNextChannelMessage(/*MidiMessageType type*/){ | |
155 MidiChannelMessage message; | |
156 message = messages[readPointer]; | |
157 if(message.getType() == kmmNone){ | |
158 message.clear(); | |
159 } | |
160 messages[readPointer].setType(kmmNone); // do not use it again | |
161 readPointer++; | |
162 if(readPointer == messages.size()){ | |
163 readPointer = 0; | |
164 } | |
165 return message; | |
166 }; | |
167 | |
168 // MidiChannelMessage getNextChannelMessage(){ | |
169 // getNextChannelMessage(kmmAny); | |
170 // } | |
171 // MidiControlChangeMessage* getNextControlChangeMessage(){ | |
172 // return (MidiControlChangeMessage*)getNextChannelMessage(kmmControlChange); | |
173 // }; | |
174 // MidiProgramChangeMessage* getNextProgramChangeMessage(){ | |
175 // return (MidiProgramChangeMessage*)getNextChannelMessage(kmmProgramChange); | |
176 // }; | |
177 // MidiNoteMessage* getNextNoteOnMessage(){ | |
178 // return (MidiNoteMessage*)getNextChannelMessage(kmmNoteOn); | |
179 // }; | |
180 }; | |
181 | |
182 | |
16 class Midi { | 183 class Midi { |
17 public: | 184 public: |
18 Midi(); | 185 Midi(); |
186 | |
187 /** | |
188 * Enable the input MidiParser. | |
189 * | |
190 * If the parser is enabled, readFrom() will return an error code. | |
191 * Midi messages should instead be retrieved via, e.g.: getMidiParser()->getNextChannelMessage(); | |
192 * | |
193 * @param enable true to enable the input MidiParser, false to disable it. | |
194 */ | |
195 void enableParser(bool enable); | |
196 | |
197 /** | |
198 * Get access to the input parser in use, if any. | |
199 * | |
200 * @return a pointer to the instance of MidiParser, if currently enabled, zero otherwise. | |
201 */ | |
202 MidiParser* getParser(); | |
203 | |
19 /** | 204 /** |
20 * Open the specified input Midi port and start reading from it. | 205 * Open the specified input Midi port and start reading from it. |
21 * @param port Midi port to open | 206 * @param port Midi port to open |
22 * @return 1 on success, -1 on failure | 207 * @return 1 on success, -1 on failure |
23 */ | 208 */ |
48 * @param bytes an array of bytes to be written | 233 * @param bytes an array of bytes to be written |
49 * @param length number of bytes to write | 234 * @param length number of bytes to write |
50 * @return 1 on success, -1 on error | 235 * @return 1 on success, -1 on error |
51 */ | 236 */ |
52 int writeOutput(midi_byte_t* bytes, unsigned int length); | 237 int writeOutput(midi_byte_t* bytes, unsigned int length); |
53 | 238 /** |
239 * Gives access to the midi parser, if it has been activated. | |
240 * | |
241 * @return a pointer to the midi parser if active, zero otherwise | |
242 */ | |
243 MidiParser* getMidiParser(); | |
54 virtual ~Midi(); | 244 virtual ~Midi(); |
55 static void midiInputLoop(); | 245 static void midiInputLoop(); |
56 static void midiOutputLoop(); | 246 static void midiOutputLoop(); |
57 static bool staticConstructed; | 247 static bool staticConstructed; |
58 static void staticConstructor(); | 248 static void staticConstructor(); |
65 unsigned int inputBytesWritePointer; | 255 unsigned int inputBytesWritePointer; |
66 unsigned int inputBytesReadPointer; | 256 unsigned int inputBytesReadPointer; |
67 std::vector<midi_byte_t> outputBytes; | 257 std::vector<midi_byte_t> outputBytes; |
68 unsigned int outputBytesWritePointer; | 258 unsigned int outputBytesWritePointer; |
69 unsigned int outputBytesReadPointer; | 259 unsigned int outputBytesReadPointer; |
260 MidiParser* inputParser; | |
261 bool parserEnabled; | |
70 static std::vector<Midi*> objAddrs[2]; | 262 static std::vector<Midi*> objAddrs[2]; |
71 static AuxiliaryTask midiInputTask; | 263 static AuxiliaryTask midiInputTask; |
72 static AuxiliaryTask midiOutputTask; | 264 static AuxiliaryTask midiOutputTask; |
73 }; | 265 }; |
74 | 266 |