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