1/*! 2 \file MidiConsumer.h 3 \ingroup midi2 4 \ingroup libbe 5 \brief Defines consumer classes for the MIDI Kit. 6*/ 7 8 9/*! 10 \class BMidiConsumer MidiConsumer.h 11 \ingroup midi2 12 \ingroup libmidi2 13 \ingroup libbe 14 \brief Receives MIDI events from a producer 15 16 A consumer is an object that knows how to deal with incoming MIDI events. A 17 consumer can be connected to multiple producers at the same time. There is no 18 way to find out which producers are connected to this consumer just by looking 19 at the BMidiConsumer object; you will have to consult BMidiRoster for that. 20 21 A BMidiConsumer either represents a local consumer, i.e. a class extending from 22 BMidiLocalConsumer, or is a proxy for a remote object published by another app. 23*/ 24 25 26/*! 27 \fn bigtime_t BMidiConsumer::Latency() const 28 \brief Returns the latency of this consumer 29 30 The latency is measured in microseconds. Producers should attempt to get MIDI 31 events to this consumer by <I>(when - latency)</I>. You do this by subtracting 32 the latency from the performance time when you spray the events (provided that 33 you spray these events ahead of time, of course). 34 35 You cannot <I>set</I> the latency on a BMidiConsumer, only on a 36 BMidiLocalConsumer. 37 38 The latency issue gets slightly more complicated when multiple endpoints are 39 chained together, as in the following picture: 40 41\verbatim 42+-------+ +-------------+ +-------+ 43| | | | | | 44| prodA |---->| consB prodB |---->| consC | 45| | | | | | 46+-------+ +-------------+ +-------+ 47 appA appB (filter) appC 48\endverbatim 49 50 Suppose consC has 200ms latency, and consB has 100ms latency. If consB simply 51 reports 100ms, then prodA will schedule its events for (t - 100), which is 52 really 200ms too late. (Of course, producers send out their events as soon as 53 possible, so depending on the load of the system, everything may work out just 54 fine.) 55 56 ConsB should report the latency of the consumer that is hooked up to its 57 output, consC, in addition to its own latency. In other words, the full 58 downstream latency. So, the reported latency in this case would be 300ms. This 59 also means that appB should change the latency of consB when prodB makes or 60 breaks a connection, and when consC reports a latency change. (If multiple 61 consumers are connected to prodB, you should take the slowest one.) 62 Unfortunately, the Midi Kit provides no easy mechanism for doing any of this, 63 so you are on your own here. 64*/ 65 66/*! 67 \class BMidiLocalConsumer MidiConsumer.h 68 \ingroup midi2 69 \ingroup libmidi2 70 \ingroup libbe 71 \brief A consumer endpoint that is created by your own application. 72 73 If you want to create a consumer that reacts to MIDI events, you should 74 subclass BMidiLocalConsumer. 75 76 Each local consumer has its own thread that receives and dispatches the MIDI 77 events. Whenever MIDI data arrives, the Data() hook passes the MIDI event on to 78 a more specific hook function: NoteOn(), NoteOff(), SystemExclusive(), and so 79 on. Calls to these hook functions are serialized -- they will never have to be 80 re-entrant. They also should not be called from outside the thread that is 81 invoking them. 82 83 Your subclass can override any of the MIDI event hooks. BMidiLocalConsumer 84 doesn't provide default implementations for them, so you don't have to call a 85 hook's default implementation if you override it. For complete control, you can 86 also override Data(). 87 88 Most hook functions take a channel argument. Even though MIDI channels are 89 really numbered 1 through 16, the hook functions work with channels 0 through 90 15. The performance time for the event is specified in microseconds relative to 91 the system time base. A performance time that is 0 (or really any time in the 92 past) means "play as soon as possible". See the \ref midi2time "introduction" 93 for more information about timing and consumers. 94 95 The thread driving the consumer's events is a very high priority real time 96 thread. Events should be handled as quickly as possible (not counting 97 snoozing). If non-time-critical computation is needed it may be wise to queue 98 events up for a lower priority thread to handle them external to the main event 99 thread. 100*/ 101 102 103/*! 104 \fn BMidiLocalConsumer::BMidiLocalConsumer(const char *name = NULL) 105 \brief Creates a new local consumer endpoint 106 107 The new endpoint is not visible to other applications until you Register() it. 108 109 You can tell the constructor what the name of the new consumer will be. If you 110 pass NULL (or use the default argument), then the consumer's name will be an 111 empty string. It won't be NULL, since endpoint names cannot be NULL. 112 113 There is no guarantee that the endpoint will be successfully created. For 114 example, the Midi Server may not be running. Therefore, you should always call 115 IsValid() after creating a new endpoint to make sure that everything went okay. 116 If not, Release() the object to reclaim memory and abort gracefully. 117 118\code 119MyConsumer* cons = new MyConsumer(...); 120if (!cons->IsValid()) 121{ 122 cons->Release(); 123 ...exit gracefully... 124} 125\endcode 126 127*/ 128 129 130/*! 131 \fn void BMidiLocalConsumer::SetLatency(bigtime_t latency) 132 \brief Changes the published latency of the consumer. 133 134 \sa Latency() 135*/ 136 137 138/*! 139 \fn int32 BMidiLocalConsumer::GetProducerID() 140 \brief Returns the ID of the producer that most recently sent a MIDI event to 141 this consumer. 142 143 You can call this from one of the hooks to determine which producer the event 144 came from. 145*/ 146 147 148/*! 149 \fn void BMidiLocalConsumer::SetTimeout(bigtime_t when, void* data) 150 \brief Requests that the Timeout() hook will be called at some point. 151 152 This method asks the consumer thread to call the Timeout() hook as soon as 153 possible after the timeout expires. For every call to SetTimeout(), the 154 Timeout() hook is only called once. Note: the term "timeout" may be a little 155 misleading; the hook will <I>always</I> be called, even if events are received 156 in the mean time. Apparently, this facility is handy for dealing with early 157 events. 158 159 Note that the event thread blocks on the consumer's port as long as no events 160 arrive. By default no timeout is set, and as a result the thread blocks 161 forever. Your call to SetTimeout() doesn't change this. The new timeout value 162 will go into effect the next time the thread tries to read from the port, i.e. 163 after the first event has been received. If no event ever comes in, the 164 Timeout() hook will never be called. This also means that you cannot cancel a 165 timeout once you have set it. To repeat, calling SetTimeout() only takes effect 166 after at least one new event has been received. 167 168 \param when An absolute time that's measured against the system clock. 169 170 \param data A pointer to a "cookie" that you can pass along to Timeout(). The 171 data is not copied, so you must ensure that the pointer remains valid until 172 Timeout() is called. You typically delete the data inside Timeout(). 173*/ 174 175 176/*! 177 \fn void BMidiLocalConsumer::Timeout(void* data) 178 \brief Hook function that is called per your own request. 179 180 \sa SetTimeout() 181*/ 182 183/*! 184 \fn void BMidiLocalConsumer::Data(uchar* data, size_t length, bool atomic, 185 bigtime_t time) 186 \brief Invoked when raw MIDI is received. 187 188 What the default implementation of Data() does depends on the value of atomic. 189 If atomic is true, the data received comprises a single MIDI event; i.e. one 190 status byte followed by the appropriate number of data bytes and nothing else. 191 In this case, Data() calls the event-specific hook function that corresponds to 192 that status byte. This optimization is used by the Midi Kit to allow faster 193 dispatch of events generated by the specific Spray functions from 194 BMidiLocalProducer. 195 196 If atomic is false, Data() ignores the MIDI event. If you want a consumer to 197 handle non-atomic events, you have to override Data() and program this 198 yourself. In that case, you probably also want to call the default 199 implementation to handle the "normal" MIDI events. 200 201 Data() is rarely overridden, but you can override it if you want to. If you do, 202 remember that the data buffer is owned by the Midi Kit. Do not attempt to 203 modify or free it, lest you wish to be laughed at by other developers. 204 205 \param data the MIDI event data 206 \param length byte size of the data buffer 207 \param atomic whether the data buffer contains a single complete MIDI event 208 \param time the requested performance time of the event 209 210 \sa BMidiLocalProducer::SprayData() 211*/ 212 213 214/*! 215 \fn void BMidiLocalConsumer::NoteOff(uchar channel, uchar note, 216 uchar velocity, bigtime_t time) 217 \brief Invoked when a Note Off event is received. 218 219 \sa BMidiLocalProducer::SprayNoteOff() 220*/ 221 222 223/*! 224 \fn void BMidiLocalConsumer::NoteOn(uchar channel, uchar note, 225 uchar velocity, bigtime_t time) 226 \brief Invoked when a Note On event is received. 227 228 \sa BMidiLocalProducer::SprayNoteOn() 229*/ 230 231 232/*! 233 \fn void BMidiLocalConsumer::KeyPressure(uchar channel, uchar note, 234 uchar pressure, bigtime_t time) 235 \brief Invoked when a Polyphonic Pressure (Aftertouch) event is received. 236 237 \sa BMidiLocalProducer::SprayKeyPressure() 238*/ 239 240 241/*! 242 \fn void BMidiLocalConsumer::ControlChange(uchar channel, 243 uchar controlNumber, uchar controlValue, bigtime_t time) 244 \brief Invoked when a Controller Change event is received. 245 246 \sa BMidiLocalProducer::SprayControlChange() 247*/ 248 249 250/*! 251 \fn void BMidiLocalConsumer::ProgramChange(uchar channel, 252 uchar programNumber, bigtime_t time) 253 \brief Invoked when a Program Change event is received. 254 255 \sa BMidiLocalProducer::SprayProgramChange() 256*/ 257 258 259/*! 260 \fn void BMidiLocalConsumer::ChannelPressure(uchar channel, 261 uchar pressure, bigtime_t time) 262 \brief Invoked when a Channel Pressure event is received. 263 264 \sa BMidiLocalProducer::SprayChannelPressure() 265*/ 266 267 268/*! 269 \fn void BMidiLocalConsumer::PitchBend(uchar channel, uchar lsb, 270 uchar msb, bigtime_t time) 271 \brief Invoked when a Pitch Bend event is received. 272 273 \sa BMidiLocalProducer::SprayPitchBend() 274*/ 275 276 277/*! 278 \fn void BMidiLocalConsumer::SystemExclusive(void* data, size_t length, 279 bigtime_t time) 280 \brief Invoked when a System Exclusive event is received. 281 282 The data does not include the sysex start and end control bytes 283 (0xF0 and 0xF7), only the payload of the sysex message. 284 285 The data belongs to the Midi Kit and is only valid for the duration of 286 this event. You may not modify or free it. 287 288 \sa BMidiLocalProducer::SpraySystemExclusive() 289*/ 290 291 292/*! 293 \fn void BMidiLocalConsumer::SystemCommon(uchar status, uchar data1, 294 uchar data2, bigtime_t time) 295 \brief Invoked when a System Common event is received. 296 297 Not all data bytes are used for all common events. Unused bytes are 298 set to 0. 299 300 \sa BMidiLocalProducer::SpraySystemCommon() 301*/ 302 303 304/*! 305 \fn void BMidiLocalConsumer::SystemRealTime(uchar status, bigtime_t time) 306 \brief Invoked when a Real Time event is received. 307 308 \sa BMidiLocalProducer::SpraySystemRealTime() 309*/ 310 311 312/*! 313 \fn void BMidiLocalConsumer::TempoChange(int32 beatsPerMinute, bigtime_t time) 314 315 \brief Invoked when a Tempo Change event is received 316 \sa BMidiLocalProducer::SprayTempoChange() 317*/ 318 319 320/*! 321 \fn void BMidiLocalConsumer::AllNotesOff(bool justChannel, bigtime_t time) 322 \brief Not used. 323*/ 324