xref: /haiku/docs/user/midi2/MidiProducer.dox (revision f5821a1aee77d3b9a979b42c68a79e50b5ebaefe)
1/*!
2	\file MidiProducer.h
3	\ingroup midi2
4	\ingroup libbe
5	\brief Defines producer classes for the MIDI Kit.
6*/
7
8
9/*!
10	\class BMidiProducer MidiProducer.h
11	\ingroup midi2
12	\ingroup libmidi2
13	\ingroup libbe
14	\brief Streams MIDI events to connected consumers.
15
16	A producer is an object that generate a stream of MIDI events. Each
17	producer has a list of BMidiConsumer objects to which it is connected,
18	and may be asked to connect to or disconnect from a BMidiConsumer. A
19	producer can spray its  events to multiple consumers at the same time.
20	A BMidiProducer either represents a local producer, i.e. a class extending
21	from BMidiLocalProducer, or is a proxy for a remote object published by
22	another app.
23*/
24
25
26/*!
27	\fn status_t BMidiProducer::Connect(BMidiConsumer* cons)
28	\brief Connects a consumer to this producer.
29
30	Establishes a connection between this producer and the specified consumer
31	endpoint. From now on, any events that this producer sprays will be sent
32	to that consumer. You may connect multiple consumers to a producer.
33
34	\return B_OK on success, or an error code when the connection could not be
35		established. If the consumer is a proxy for a remote object and that
36		object no longer exists, Connect() returns B_ERROR. It also returns
37		\c B_ERROR if you try to connect the same producer and consumer more
38		than once.
39
40	\sa Disconnect()
41*/
42
43
44/*!
45	\fn status_t BMidiProducer::Disconnect(BMidiConsumer* cons)
46	\brief Disconnects a consumer from this producer.
47
48	Terminates the connection between this producer and the specified consumer
49	endpoint. From now on, any events that this producer sprays no longer go
50	to that consumer.
51
52	\return B_OK on success, or an error code if there was no connection to break
53	\sa Connect()
54*/
55
56
57/*!
58	\fn bool BMidiProducer::IsConnected(BMidiConsumer* cons) const
59	\brief Determines whether a consumer is connected to this producer.
60
61	\sa Connect()
62	\sa Disconnect()
63*/
64
65
66/*!
67	\fn BList* BMidiProducer::Connections() const
68	\brief Returns a list with all connected consumers.
69
70	Returns a BList with pointers to BMidiEndpoint objects for all consumers
71	that are connected to this producer. You can examine the contents of the
72	list as follows:
73\code
74BList* list = prod->Connections();
75for (int32 t = 0; t < list->CountItems(); ++t)
76{
77    BMidiEndpoint* endp = (BMidiEndpoint*) list->ItemAt(t);
78    ...do stuff...
79    endp->Release();  // yes, here too!
80}
81delete list;
82\endcode
83	Every time you call this function, a new BList is allocated. The caller
84	(that is you) is responsible for freeing this list. The BMidiEndpoint
85	objects in the list have their reference counts bumped, so you need to
86	Release() them before you delete the list or they will go all leaky on
87	you.
88*/
89
90
91/*!
92	\class BMidiLocalProducer MidiProducer.h
93	\ingroup midi2
94	\ingroup libmidi2
95	\ingroup libbe
96	\brief A producer endpoint that is created by your own application.
97
98	You create a BMidiLocalProducer if you want your application to send MIDI
99	events. You use the various spray functions to send events to all connected
100	consumers. If no consumers are connected to the producer, any calls to the
101	spray functions are ignored.
102
103	Most spray functions accept a channel argument. Even though MIDI channels are
104	really numbered 1 through 16, the spray functions work with channels 0 through
105	15. You can also specify the performance time for the event using the time
106	argument. Specify 0 (or any time in the past) to perform the event "now", i.e.
107	as soon as possible. You can also schedule events to be performed in the
108	future, by passing a time such as system_time() + 5000000, which means 5
109	seconds from now.
110
111	Unlike BMidiLocalConsumer, which should be subclassed almost always, you hardly
112	ever need to derive a class from BMidiLocalProducer. The only reason for
113	subclassing is when you need to know when the producer gets connected or
114	disconnected.
115
116	Also unlike consumers, local producers have no thread of control directly
117	associated with them. If you want to send out the MIDI events from a different
118	thread, you will have to create one yourself.
119*/
120
121
122/*!
123	\fn BMidiLocalProducer::BMidiLocalProducer(const char *name = NULL)
124	\brief Creates a new local producer endpoint.
125
126	The new endpoint is not visible to other applications until you Register() it.
127	You can tell the constructor what the name of the new producer will be. If you
128	pass NULL (or use the default argument), then the producer's name will be an
129	empty string. It won't be NULL, since endpoint names cannot be NULL.
130	There is no guarantee that the endpoint will be successfully created. For
131	example, the Midi Server may not be running. Therefore, you should always call
132	IsValid() after creating a new endpoint to make sure that everything went okay.
133	If not, Release() the object to reclaim memory and abort gracefully.
134\code
135BMidiLocalProducer* prod = new BMidiLocalProducer(...);
136if (!prod->IsValid())
137{
138    prod->Release();
139    ...exit gracefully...
140}
141\endcode
142*/
143
144
145/*!
146	\fn void BMidiLocalProducer::Connected(BMidiConsumer* cons)
147	\brief Invoked when a new consumer is connected to this producer
148
149	Although typical notifications (i.e. from BMidiRoster's "watching" facility)
150	are only sent if it is some other app that is performing the operation,
151	Connected() is also called if you are making the connection yourself.
152	If you override this hook, you don't have to call the default implementation,
153	because that does nothing.
154
155	\param cons The newly connected consumer. The reference count of the
156		consumer object is not increased, so you should not Release() it.
157		However, if you want to keep track of the consumer beyond this
158		function, you should first Acquire() it, and Release() it when you
159		are done.
160
161	\sa Disconnected()
162*/
163
164
165/*!
166	\fn void BMidiLocalProducer::Disconnected(BMidiConsumer* cons)
167	\brief Invoked when a consumer is disconnected from this producer.
168
169	\sa Connected()
170*/
171
172
173/*!
174	\fn void BMidiLocalProducer::SprayData(void* data, size_t length,
175		bool atomic = false, bigtime_t time = 0) const
176	\brief Sends raw MIDI data downstream to all connected consumers.
177
178	Typically you won't have to call SprayData(); the other spray functions
179	will do just fine. If you do call it, remember that you retain ownership
180	of the data and that you are responsible for freeing it at some point.
181	(Even though data is not declared const, the function does not change it.)
182	With atomic set to false, you can send a MIDI message in segments (perhaps
183	for a large sysex dump). However, when you do this, you are on your own.
184	The Midi Kit only tags the data as being non-atomic, but offers no]
185	additional support.
186
187	The default implementation of BMidiLocalConsumer completely ignores such
188	events. To handle non-atomic MIDI data, you should override the
189	BMidiLocalConsumer::Data() hook and process the MIDI event yourself. All of
190	BMidiLocalProducer's other spray functions always send atomic data.
191
192	\param data the MIDI event data.
193	\param length byte size of the data buffer.
194	\param atomic whether the data buffer contains a single complete
195		   MIDI event.
196	\param time the required performance time of the event.
197
198	\sa BMidiLocalConsumer::Data()
199*/
200
201
202/*!
203	\fn void BMidiLocalProducer::SprayNoteOff(uchar channel, uchar note,
204		uchar velocity, bigtime_t time = 0) const
205	\brief Sends a Note Off event to all connected consumers.
206
207	\sa BMidiLocalConsumer::NoteOff()
208*/
209
210
211/*!
212	\fn void BMidiLocalProducer::SprayNoteOn(uchar channel, uchar note,
213		uchar velocity, bigtime_t time = 0) const
214	\brief Sends a Note On event to all connected consumers.
215
216	\sa BMidiLocalConsumer::NoteOn()
217*/
218
219
220/*!
221	\fn void BMidiLocalProducer::SprayKeyPressure(uchar channel, uchar note,
222		uchar pressure, bigtime_t time = 0) const
223	\brief Sends a Polyphonic Pressure (Aftertouch) event to all connected
224		   consumers.
225
226	\sa BMidiLocalConsumer::KeyPressure()
227*/
228
229
230/*!
231	\fn void BMidiLocalProducer::SprayControlChange(uchar channel,
232		uchar controlNumber, uchar controlValue, bigtime_t time = 0) const
233	\brief Sends a Controller Change event to all connected consumers.
234
235	\sa Midi2Defs.h
236	\sa BMidiLocalConsumer::ControlChange()
237*/
238
239
240/*!
241	\fn void BMidiLocalProducer::SprayProgramChange(uchar channel,
242		uchar programNumber, bigtime_t time = 0) const
243	\brief Sends a Program Change event to all connected consumers.
244
245	\sa BMidiLocalConsumer::ProgramChange()
246*/
247
248
249/*!
250	\fn void BMidiLocalProducer::SprayChannelPressure(uchar channel,
251		uchar pressure, bigtime_t time = 0) const
252	\brief Sends a Channel Pressure event to all connected consumers.
253
254	\sa BMidiLocalConsumer::ChannelPressure()
255*/
256
257
258/*!
259	\fn void BMidiLocalProducer::SprayPitchBend(uchar channel, uchar lsb,
260		uchar msb, bigtime_t time = 0) const
261	\brief Sends a Pitch Bend event to all connected consumers.
262
263	\sa BMidiLocalConsumer::PitchBend()
264*/
265
266
267/*!
268	\fn void BMidiLocalProducer::SpraySystemExclusive(void* data,
269		size_t length, bigtime_t time = 0) const
270	\brief Sends a System Exclusive event to all connected consumers.
271
272	You retain ownership of the data and are responsible for freeing it. Even
273	though data is not declared const, the function does not change it. Even
274	though the amount of data may be quite large, this function always sends
275	sysex messages as an atomic block of data.
276
277	\sa BMidiLocalConsumer::SystemExclusive()
278*/
279
280
281/*!
282	\fn void BMidiLocalProducer::SpraySystemCommon(uchar status,\
283		uchar data1, uchar data2, bigtime_t time = 0) const
284	\brief Sends a System Common event to the connected consumers.
285
286	The status byte must be one of the following:
287	<table border="1">
288		<tr>
289			<td>0xF1</td>
290			<td>\c B_MIDI_TIME_CODE</td>
291			<td>data1 only</td>
292		</tr>
293		<tr>
294			<td>0xF2</td>
295			<td>\c B_SONG_POSITION</td>
296			<td>data1 and data2</td>
297		</tr>
298		<tr>
299			<td>0xF3</td>
300			<td>\c B_SONG_SELECT</td>
301			<td>data1 only</td>
302		</tr>
303		<tr>
304			<td>0xF5</td>
305			<td>\c B_CABLE_MESSAGE</td>
306			<td>data1 only</td>
307		</tr>
308		<tr>
309			<td>0xF6</td>
310			<td>\c B_TUNE_REQUEST</td>
311			<td>no data</td>
312		</tr>
313		<tr>
314			<td>0xF7</td>
315			<td>\c B_SYS_EX_END</td>
316			<td>no data</td>
317		</tr>
318	</table>
319
320	\sa BMidiLocalConsumer::SystemCommon()
321*/
322
323
324/*!
325	\fn void BMidiLocalProducer::SpraySystemRealTime(uchar status,
326		bigtime_t time = 0) const
327	\brief Sends a Real Time event to the connected consumers.
328
329	The status byte must be one of the following:
330	<table border="1">
331		<tr><td>0xf8</td><td>\c B_TIMING_CLOCK</td></tr>
332		<tr><td>0xfa</td><td>\c B_START</td></tr>
333		<tr><td>0xfb</td><td>\c B_CONTINUE</td></tr>
334		<tr><td>0xfc</td><td>\c B_STOP</td></tr>
335		<tr><td>0xfe</td><td>\c B_ACTIVE_SENSING</td></tr>
336		<tr><td>0xff</td><td>\c B_SYSTEM_RESET</td></tr>
337	</table>
338
339	Because of their high priority, the MIDI specification allows real time
340	messages to "interleave" with other MIDI messages. A large sysex dump, for
341	example, may be interrupted by a real time event. The Midi Kit, however,
342	doesn't care. If you (or another producer) have just sent a big system
343	exclusive to a consumer, any following real time message will simply have
344	to wait until the consumer has dealt with the sysex.
345
346	\sa BMidiLocalConsumer::SystemRealTime()
347*/
348
349
350/*!
351	\fn void BMidiLocalProducer::SprayTempoChange(int32 bpm,
352		bigtime_t time = 0) const
353	\brief Sends a Tempo Change event to the connected consumers.
354
355	This kind of Tempo Change event is not really part of the MIDI spec,
356	rather it is an extension from the SMF (Standard MIDI File) format.
357
358	\sa BMidiLocalConsumer::TempoChange()
359*/
360