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