1/*! 2 \file MidiRoster.h 3 \ingroup midi2 4 \ingroup libbe 5 \brief Defines the heart of the MIDI Kit: the MIDI Roster. 6*/ 7 8 9/*! 10 \enum BMidiOp 11 \ingroup midi2 12 \brief Defines the status codes for MIDI Server notification messages. 13 14 These codes are used when you request notification as in 15 BMidiRoster::StartWatching(). Check against these codes to determine what 16 is happening. See the StartWatching() method for a more complete 17 description of the codes and their meaning. 18*/ 19 20 21/*! 22 \var B_MIDI_EVENT 23 \brief BMessage identifier of MIDI messages. 24*/ 25 26 27/*! 28 \class BMidiRoster MidiRoster.h 29 \ingroup midi2 30 \ingroup libmidi2 31 \ingroup libbe 32 \brief Interface to the system-wide Midi Roster. 33 34 BMidiRoster allows you to find available MIDI consumer and producer 35 objects. You can locate these objects using the iterative NextEndpoint(), 36 NextProducer(), and NextConsumer() methods or by requesting notification 37 messages to be sent with StartWatching(). Notification messages may 38 contain object IDs which can be resolved using the FindEndpoint(), 39 FindProducer(), and FindConsumer() methods. 40 41 The constructor and destructor of BMidiRoster are private, which means 42 that you cannot create or delete your own BMidiRoster objects. Every 43 application can have only one instance of BMidiRoster, which is 44 automatically created the very first time you use a Midi Kit function. 45 You can call BMidiRoster's functions like this: 46\code 47producer = BMidiRoster::FindProducer(someID); 48\endcode 49Or using the slightly more annoying: 50\code 51BMidiRoster* roster = BMidiRoster::MidiRoster(); 52if (roster != NULL) 53{ 54 producer = roster->FindProducer(someID); 55} 56\endcode 57*/ 58 59 60/*! 61 \fn BMidiEndpoint* BMidiRoster::NextEndpoint(int32* id) 62 \brief Returns the next endpoint from the roster 63 64 The "next endpoint" means: the endpoint with the ID that follows \a id. 65 So if you set id to 3, the first possible endpoint it returns is 66 endpoint 4. No endpoint can have ID 0, so passing 0 gives you the first 67 endpoint. If you pass \c NULL instead of an ID, NextEndpoint() always 68 returns \c NULL. When the function returns, it sets \a id to the ID of the 69 endpoint that was found. If no more endpoints exist, NextEndpoint() 70 returns \c NULL and id is not changed. NextEndpoint() does <b>not</b> 71 return locally created endpoints, even if they are Register()'ed. 72 73 Usage example: 74\code 75int32 id = 0; 76BMidiEndpoint* endp; 77while ((endp = BMidiRoster::NextEndpoint(&id)) != NULL) 78{ 79 ... do something with endpoint ... 80 endp->Release(); // don't forget! 81} 82\endcode 83 Remember that NextEndpoint() bumps the endpoint's reference count, so you 84 should always \link BMidiEndpoint::Release() Release() \endlink it when 85 you are done. 86*/ 87 88 89/*! 90 \fn BMidiProducer* BMidiRoster::NextProducer(int32* id) 91 \brief Returns the next producer from the roster. 92 93 Like NextEndpoint(), but only returns producer endpoints. 94 95 \sa NextConsumer 96 \sa NextEndpoint 97*/ 98 99 100/*! 101 \fn BMidiConsumer* BMidiRoster::NextConsumer(int32* id) 102 \brief Returns the next consumer from the roster. 103 104 Like NextEndpoint(), but only returns consumer endpoints. 105 106 \sa NextProducer 107 \sa NextEndpoint 108*/ 109 110 111/*! 112 \fn BMidiEndpoint* BMidiRoster::FindEndpoint(int32 id, 113 bool localOnly = false) 114 \brief Returns the endpoint with the specified \a id. 115 116 FindEndpoint() will always find <b>any</b> local endpoints created by this 117 application; they do not have to be published with Register() first. If 118 localOnly is false, FindEndpoint() also looks at remote endpoints, 119 otherwise only local endpoints will be resolved. Returns NULL if no such 120 endpoint could be found. 121 122 You should use a dynamic_cast to convert the BMidiEndpoint into a producer 123 or consumer: 124\code 125BMidiEndpoint* endp = ...; 126BMidiProducer* prod = NULL; 127BMidiConsumer* cons = NULL; 128if (endp->IsProducer()) 129{ 130 prod = dynamic_cast<BMidiProducer*>(endp); 131} 132else if (endp->IsConsumer()) 133{ 134 cons = dynamic_cast<BMidiConsumer*>(endp); 135} 136\endcode 137 138 Remember that FindEndpoint() increments the endpoint's reference count, 139 so you should always \link BMidiEndpoint::Release() Release() \endlink 140 an endpoint when you are done with it: 141\code 142BMidiEndpoint* endp = BMidiRoster::FindEndpoint(someID); 143if (endp != NULL) 144{ 145 ...do stuff with the endpoint... 146 endp->Release(); 147} 148\endcode 149*/ 150 151 152/*! 153 \fn BMidiProducer* BMidiRoster::FindProducer(int32 id, 154 bool localOnly = false) 155 \brief Finds the producer with the specified \a id. 156 157 Like FindEndpoint(), but only looks for producer endpoints. Returns 158 \c NULL if no endpoint with that ID exists, or if that endpoint is not 159 a producer. 160 161 \sa FindConsumer 162 \sa FindEndpoint 163*/ 164 165 166/*! 167 \fn BMidiConsumer* BMidiRoster::FindConsumer(int32 id, 168 bool localOnly = false) 169 \brief Finds the consumer with the specified \a id. 170 171 Like FindEndpoint(), but only looks for consumer endpoints. Returns 172 \c NULL if no endpoint with that ID exists, or if that endpoint is not 173 a consumer. 174 175 \sa FindProducer 176 \sa FindEndpoint 177*/ 178 179 180/*! 181 \fn void BMidiRoster::StartWatching(const BMessenger* msngr) 182 \brief Start receiving notifications from the Midi Roster 183 184 When you start watching, BMidiRoster sends you notifications for all 185 currently \b published \c remote endpoints, and all the current 186 connections between them. (At this point, BMidiRoster does not let you 187 know about connections between unpublished endpoints, nor does it tell 188 you anything about your local endpoints, even though they may be 189 published.) 190 191 Thereafter, you'll receive notifications any time something important 192 happens to an object. The application that performs these operations is 193 itself not notified. The assumption here is that you already know about 194 these changes, because you are the one that is performing them. 195 196 The notifications are BMessages with code B_MIDI_EVENT. You specify the 197 BMessenger that will be used to send these messages. Each message contains 198 a field called be:op that describes the type of notification. 199 200 The "registered" and "unregistered" notifications are sent when a remote 201 endpoint Register()'s or Unregister()'s, respectively. You don't receive 202 these notifications when you register or unregister your local endpoints, 203 but the other apps will. 204 205 <table border="1"> 206 <tr> 207 <td>be:op</td> 208 <td>int32</td> 209 <td>\c B_MIDI_REGISTERED</td> 210 </tr> 211 <tr> 212 <td>be:id</td> 213 <td>int32</td> 214 <td>id of the endpoint</td> 215 </tr> 216 <tr> 217 <td>be:type</td> 218 <td>string</td> 219 <td>"producer" or "consumer"</td> 220 </tr> 221 </table> 222 <table border="1"> 223 <tr> 224 <td>be:op</td> 225 <td>int32</td> 226 <td>\c B_MIDI_UNREGISTERED</td> 227 </tr> 228 <tr> 229 <td>be:id</td> 230 <td>int32</td> 231 <td>id of the endpoint</td> 232 </tr> 233 <tr> 234 <td>be:type</td> 235 <td>string</td> 236 <td>"producer" or "consumer"</td> 237 </tr> 238 </table> 239 240 The "connected" and "disconnected" notifications are sent when a consumer 241 \link BMidiProducer::Connect() Connect()\endlink's to a producer, or when 242 they \link BMidiProducer::Disconnect() Disconnect() \endlink. You will 243 receive these notifications when \b any two endpoints connect or 244 disconnect, even if they are not published. (The purpose of which is 245 debatable.) You won't receive the notifications if you are the one making 246 the connection, even if both endpoints are remote. You \b will be notified 247 when another app connects one of your published endpoints. 248 <table border="1"> 249 <tr> 250 <td>be:op</td> 251 <td>\c int32</td> 252 <td>\c B_MIDI_CONNECTED</td> 253 </tr> 254 <tr> 255 <td>be:producer</td> 256 <td>\c int32</td> 257 <td>id of the connector</td> 258 </tr> 259 <tr> 260 <td>be:consumer</td> 261 <td>\c int32</td> 262 <td>id of the connectee</td> 263 </tr> 264 </table> 265 266 <table border="1"> 267 <tr> 268 <td>be:op</td> 269 <td>\c int32</td> 270 <td>\c B_MIDI_DISCONNECTED</td> 271 </tr> 272 <tr> 273 <td>be:producer</td> 274 <td>\c int32</td> 275 <td>id of the connector</td> 276 </tr> 277 <tr> 278 <td>be:consumer</td> 279 <td>int32</td> 280 <td>id of the connectee</td> 281 </tr> 282 </table> 283 284 the following notifications are sent when an endpoint's attributes are 285 changed. you receive these notifications only if another application is 286 changing one of its published endpoints. 287 288 <table border="1"> 289 <tr> 290 <td>be:op</td> 291 <td>\c int32</td> 292 <td>\c B_MIDI_CHANGED_NAME</td> 293 </tr> 294 <tr> 295 <td>be:id</td> 296 <td>\c int32</td> 297 <td>id of the endpoint</td> 298 </tr> 299 <tr> 300 <td>be:type</td> 301 <td>string</td> 302 <td>"producer" or "consumer"</td> 303 </tr> 304 <tr> 305 <td>be:name</td> 306 <td>string</td> 307 <td>the endpoint's new name</td> 308 </tr> 309 </table> 310 311 <table border="1"> 312 <tr> 313 <td>be:op</td> 314 <td>\c int32</td> 315 <td>\c B_MIDI_CHANGED_LATENCY</td> 316 </tr> 317 <tr> 318 <td>be:id</td> 319 <td>\c int32</td> 320 <td>id of the endpoint</td> 321 </tr> 322 <tr> 323 <td>be:type</td> 324 <td>string</td> 325 <td>"producer" or "consumer"</td> 326 </tr> 327 <tr> 328 <td>be:latency</td> 329 <td>int64</td> 330 <td>the new latency (microseconds)</td> 331 </tr> 332 </table> 333 334 <table border="1"> 335 <tr> 336 <td>be:op</td> 337 <td>int32</td> 338 <td>\c B_MIDI_CHANGED_PROPERTIES</td> 339 </tr> 340 <tr> 341 <td>be:id</td> 342 <td>\c int32</td> 343 <td>id of the endpoint</td> 344 </tr> 345 <tr> 346 <td>be:type</td> 347 <td>string</td> 348 <td>"producer" or "consumer"</td> 349 </tr> 350 <tr> 351 <td>be:properties</td> 352 <td>bmessage</td> 353 <td>the new properties</td> 354 </tr> 355 </table> 356 357 Typical usage example: 358 359\code 360void MyView::AttachedToWindow() 361{ 362 BMessenger msgr(this); 363 BMidiRoster::StartWatching(&msgr); 364} 365void MyView::MessageReceived(BMessage* msg) 366{ 367 switch (msg->what) 368 { 369 case B_MIDI_EVENT: 370 HandleMidiEvent(msg); 371 break; 372 default: 373 super::MessageReceived(msg); 374 break; 375 } 376} 377\endcode 378 379 For the possible midi options, see #BMidiOp 380*/ 381 382 383/*! 384 \fn void BMidiRoster::StopWatching() 385 \brief Stop receiving notifications from the Midi Roster. 386 387 \sa StartWatching() 388*/ 389 390 391/*! 392 \fn status_t BMidiRoster::Register(BMidiEndpoint* object) 393 \brief Publishes an endpoint to other applications. 394 395 Calls BMidiEndpoint's \link BMidiEndpoint::Register() Register() \endlink 396 method to publish an endpoint, which makes it visible to other 397 applications. 398*/ 399 400 401/*! 402 \fn status_t BMidiRoster::Unregister(BMidiEndpoint* object) 403 \brief Hides an endpoint from other applications. 404 405 Calls BMidiEndpoint's 406 \link BMidiEndpoint::Unregister() Unregister() \endlink method to hide 407 a previously published endpoint from other applications. 408*/ 409 410 411/*! 412 \fn BMidiRoster* BMidiRoster::MidiRoster() 413 \brief Returns a pointer to the only instance of BMidiRoster. 414 415 There is no real reason use this function, since all BMidiRoster's public 416 function are static. 417*/ 418