xref: /haiku/docs/user/midi2/MidiRoster.dox (revision b617a7b410c05275effb95f4b2f5608359d9b7b9)
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