1/*! 2 \file MidiProducer.h 3 \ingroup midi2 4 \brief Defines producer classes for the MIDI Kit. 5*/ 6 7 8/*! 9 \class BMidiProducer MidiProducer.h 10 \ingroup midi2 11 \brief Streams MIDI events to connected consumers. 12 13 A producer is an object that generate a stream of MIDI events. Each 14 producer has a list of BMidiConsumer objects to which it is connected, 15 and may be asked to connect to or disconnect from a BMidiConsumer. A 16 producer can spray its events to multiple consumers at the same time. 17 A BMidiProducer either represents a local producer, i.e. a class extending 18 from BMidiLocalProducer, or is a proxy for a remote object published by 19 another app. 20*/ 21 22 23/*! 24 \fn status_t BMidiProducer::Connect(BMidiConsumer* cons) 25 \brief Connects a consumer to this producer. 26 27 Establishes a connection between this producer and the specified consumer 28 endpoint. From now on, any events that this producer sprays will be sent 29 to that consumer. You may connect multiple consumers to a producer. 30 31 \return B_OK on success, or an error code when the connection could not be 32 established. If the consumer is a proxy for a remote object and that 33 object no longer exists, Connect() returns B_ERROR. It also returns 34 \c B_ERROR if you try to connect the same producer and consumer more 35 than once. 36 37 \sa Disconnect() 38*/ 39 40 41/*! 42 \fn status_t BMidiProducer::Disconnect(BMidiConsumer* cons) 43 \brief Disconnects a consumer from this producer. 44 45 Terminates the connection between this producer and the specified consumer 46 endpoint. From now on, any events that this producer sprays no longer go 47 to that consumer. 48 49 \return B_OK on success, or an error code if there was no connection to break 50 \sa Connect() 51*/ 52 53 54/*! 55 \fn bool BMidiProducer::IsConnected(BMidiConsumer* cons) const 56 \brief Determines whether a consumer is connected to this producer. 57 58 \sa Connect() 59 \sa Disconnect() 60*/ 61 62 63/*! 64 \fn BList* BMidiProducer::Connections() const 65 \brief Returns a list with all connected consumers. 66 67 Returns a BList with pointers to BMidiEndpoint objects for all consumers 68 that are connected to this producer. You can examine the contents of the 69 list as follows: 70\code 71BList* list = prod->Connections(); 72for (int32 t = 0; t < list->CountItems(); ++t) 73{ 74 BMidiEndpoint* endp = (BMidiEndpoint*) list->ItemAt(t); 75 ...do stuff... 76 endp->Release(); // yes, here too! 77} 78delete list; 79\endcode 80 Every time you call this function, a new BList is allocated. The caller 81 (that is you) is responsible for freeing this list. The BMidiEndpoint 82 objects in the list have their reference counts bumped, so you need to 83 Release() them before you delete the list or they will go all leaky on 84 you. 85*/ 86 87 88/*! 89 \class BMidiLocalProducer MidiProducer.h 90 \ingroup midi2 91 \brief A producer endpoint that is created by your own application. 92 93 You create a BMidiLocalProducer if you want your application to send MIDI 94 events. You use the various spray functions to send events to all connected 95 consumers. If no consumers are connected to the producer, any calls to the 96 spray functions are ignored. 97 98 Most spray functions accept a channel argument. Even though MIDI channels are 99 really numbered 1 through 16, the spray functions work with channels 0 through 100 15. You can also specify the performance time for the event using the time 101 argument. Specify 0 (or any time in the past) to perform the event "now", i.e. 102 as soon as possible. You can also schedule events to be performed in the 103 future, by passing a time such as system_time() + 5000000, which means 5 104 seconds from now. 105 106 Unlike BMidiLocalConsumer, which should be subclassed almost always, you hardly 107 ever need to derive a class from BMidiLocalProducer. The only reason for 108 subclassing is when you need to know when the producer gets connected or 109 disconnected. 110 111 Also unlike consumers, local producers have no thread of control directly 112 associated with them. If you want to send out the MIDI events from a different 113 thread, you will have to create one yourself. 114*/ 115 116 117/*! 118 \fn BMidiLocalProducer::BMidiLocalProducer(const char *name = NULL) 119 \brief Creates a new local producer endpoint. 120 121 The new endpoint is not visible to other applications until you Register() it. 122 You can tell the constructor what the name of the new producer will be. If you 123 pass NULL (or use the default argument), then the producer's name will be an 124 empty string. It won't be NULL, since endpoint names cannot be NULL. 125 There is no guarantee that the endpoint will be successfully created. For 126 example, the Midi Server may not be running. Therefore, you should always call 127 IsValid() after creating a new endpoint to make sure that everything went okay. 128 If not, Release() the object to reclaim memory and abort gracefully. 129\code 130BMidiLocalProducer* prod = new BMidiLocalProducer(...); 131if (!prod->IsValid()) 132{ 133 prod->Release(); 134 ...exit gracefully... 135} 136\endcode 137*/ 138 139 140/*! 141 \fn void BMidiLocalProducer::Connected(BMidiConsumer* cons) 142 \brief Invoked when a new consumer is connected to this producer 143 144 Although typical notifications (i.e. from BMidiRoster's "watching" facility) 145 are only sent if it is some other app that is performing the operation, 146 Connected() is also called if you are making the connection yourself. 147 If you override this hook, you don't have to call the default implementation, 148 because that does nothing. 149 150 \param cons The newly connected consumer. The reference count of the 151 consumer object is not increased, so you should not Release() it. 152 However, if you want to keep track of the consumer beyond this 153 function, you should first Acquire() it, and Release() it when you 154 are done. 155 156 \sa Disconnected() 157*/ 158 159 160/*! 161 \fn void BMidiLocalProducer::Disconnected(BMidiConsumer* cons) 162 \brief Invoked when a consumer is disconnected from this producer. 163 164 \sa Connected() 165*/ 166 167 168/*! 169 \fn void BMidiLocalProducer::SprayData(void* data, size_t length, 170 bool atomic = false, bigtime_t time = 0) const 171 \brief Sends raw MIDI data downstream to all connected consumers. 172 173 Typically you won't have to call SprayData(); the other spray functions 174 will do just fine. If you do call it, remember that you retain ownership 175 of the data and that you are responsible for freeing it at some point. 176 (Even though data is not declared const, the function does not change it.) 177 With atomic set to false, you can send a MIDI message in segments (perhaps 178 for a large sysex dump). However, when you do this, you are on your own. 179 The Midi Kit only tags the data as being non-atomic, but offers no] 180 additional support. 181 182 The default implementation of BMidiLocalConsumer completely ignores such 183 events. To handle non-atomic MIDI data, you should override the 184 BMidiLocalConsumer::Data() hook and process the MIDI event yourself. All of 185 BMidiLocalProducer's other spray functions always send atomic data. 186 187 \param data the MIDI event data. 188 \param length byte size of the data buffer. 189 \param atomic whether the data buffer contains a single complete 190 MIDI event. 191 \param time the required performance time of the event. 192 193 \sa BMidiLocalConsumer::Data() 194*/ 195 196 197/*! 198 \fn void BMidiLocalProducer::SprayNoteOff(uchar channel, uchar note, 199 uchar velocity, bigtime_t time = 0) const 200 \brief Sends a Note Off event to all connected consumers. 201 202 \sa BMidiLocalConsumer::NoteOff() 203*/ 204 205 206/*! 207 \fn void BMidiLocalProducer::SprayNoteOn(uchar channel, uchar note, 208 uchar velocity, bigtime_t time = 0) const 209 \brief Sends a Note On event to all connected consumers. 210 211 \sa BMidiLocalConsumer::NoteOn() 212*/ 213 214 215/*! 216 \fn void BMidiLocalProducer::SprayKeyPressure(uchar channel, uchar note, 217 uchar pressure, bigtime_t time = 0) const 218 \brief Sends a Polyphonic Pressure (Aftertouch) event to all connected 219 consumers. 220 221 \sa BMidiLocalConsumer::KeyPressure() 222*/ 223 224 225/*! 226 \fn void BMidiLocalProducer::SprayControlChange(uchar channel, 227 uchar controlNumber, uchar controlValue, bigtime_t time = 0) const 228 \brief Sends a Controller Change event to all connected consumers. 229 230 \sa Midi2Defs.h 231 \sa BMidiLocalConsumer::ControlChange() 232*/ 233 234 235/*! 236 \fn void BMidiLocalProducer::SprayProgramChange(uchar channel, 237 uchar programNumber, bigtime_t time = 0) const 238 \brief Sends a Program Change event to all connected consumers. 239 240 \sa BMidiLocalConsumer::ProgramChange() 241*/ 242 243 244/*! 245 \fn void BMidiLocalProducer::SprayChannelPressure(uchar channel, 246 uchar pressure, bigtime_t time = 0) const 247 \brief Sends a Channel Pressure event to all connected consumers. 248 249 \sa BMidiLocalConsumer::ChannelPressure() 250*/ 251 252 253/*! 254 \fn void BMidiLocalProducer::SprayPitchBend(uchar channel, uchar lsb, 255 uchar msb, bigtime_t time = 0) const 256 \brief Sends a Pitch Bend event to all connected consumers. 257 258 \sa BMidiLocalConsumer::PitchBend() 259*/ 260 261 262/*! 263 \fn void BMidiLocalProducer::SpraySystemExclusive(void* data, 264 size_t length, bigtime_t time = 0) const 265 \brief Sends a System Exclusive event to all connected consumers. 266 267 You retain ownership of the data and are responsible for freeing it. Even 268 though data is not declared const, the function does not change it. Even 269 though the amount of data may be quite large, this function always sends 270 sysex messages as an atomic block of data. 271 272 \sa BMidiLocalConsumer::SystemExclusive() 273*/ 274 275 276/*! 277 \fn void BMidiLocalProducer::SpraySystemCommon(uchar status,\ 278 uchar data1, uchar data2, bigtime_t time = 0) const 279 \brief Sends a System Common event to the connected consumers. 280 281 The status byte must be one of the following: 282 <table border="1"> 283 <tr> 284 <td>0xF1</td> 285 <td>\c B_MIDI_TIME_CODE</td> 286 <td>data1 only</td> 287 </tr> 288 <tr> 289 <td>0xF2</td> 290 <td>\c B_SONG_POSITION</td> 291 <td>data1 and data2</td> 292 </tr> 293 <tr> 294 <td>0xF3</td> 295 <td>\c B_SONG_SELECT</td> 296 <td>data1 only</td> 297 </tr> 298 <tr> 299 <td>0xF5</td> 300 <td>\c B_CABLE_MESSAGE</td> 301 <td>data1 only</td> 302 </tr> 303 <tr> 304 <td>0xF6</td> 305 <td>\c B_TUNE_REQUEST</td> 306 <td>no data</td> 307 </tr> 308 <tr> 309 <td>0xF7</td> 310 <td>\c B_SYS_EX_END</td> 311 <td>no data</td> 312 </tr> 313 </table> 314 315 \sa BMidiLocalConsumer::SystemCommon() 316*/ 317 318 319/*! 320 \fn void BMidiLocalProducer::SpraySystemRealTime(uchar status, 321 bigtime_t time = 0) const 322 \brief Sends a Real Time event to the connected consumers. 323 324 The status byte must be one of the following: 325 <table border="1"> 326 <tr><td>0xf8</td><td>\c B_TIMING_CLOCK</td></tr> 327 <tr><td>0xfa</td><td>\c B_START</td></tr> 328 <tr><td>0xfb</td><td>\c B_CONTINUE</td></tr> 329 <tr><td>0xfc</td><td>\c B_STOP</td></tr> 330 <tr><td>0xfe</td><td>\c B_ACTIVE_SENSING</td></tr> 331 <tr><td>0xff</td><td>\c B_SYSTEM_RESET</td></tr> 332 </table> 333 334 Because of their high priority, the MIDI specification allows real time 335 messages to "interleave" with other MIDI messages. A large sysex dump, for 336 example, may be interrupted by a real time event. The Midi Kit, however, 337 doesn't care. If you (or another producer) have just sent a big system 338 exclusive to a consumer, any following real time message will simply have 339 to wait until the consumer has dealt with the sysex. 340 341 \sa BMidiLocalConsumer::SystemRealTime() 342*/ 343 344 345/*! 346 \fn void BMidiLocalProducer::SprayTempoChange(int32 bpm, 347 bigtime_t time = 0) const 348 \brief Sends a Tempo Change event to the connected consumers. 349 350 This kind of Tempo Change event is not really part of the MIDI spec, 351 rather it is an extension from the SMF (Standard MIDI File) format. 352 353 \sa BMidiLocalConsumer::TempoChange() 354*/ 355