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