1 /**
2  * \file seq/seq.c
3  * \brief Sequencer Interface
4  * \author Jaroslav Kysela <perex@perex.cz>
5  * \author Abramo Bagnara <abramo@alsa-project.org>
6  * \author Takashi Iwai <tiwai@suse.de>
7  * \date 2000-2001
8  *
9  * See \ref seq page for more details.
10  */
11 
12 /*
13  *  Sequencer Interface - main file
14  *
15  *   This library is free software; you can redistribute it and/or modify
16  *   it under the terms of the GNU Lesser General Public License as
17  *   published by the Free Software Foundation; either version 2.1 of
18  *   the License, or (at your option) any later version.
19  *
20  *   This program is distributed in the hope that it will be useful,
21  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
22  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
23  *   GNU Lesser General Public License for more details.
24  *
25  *   You should have received a copy of the GNU Lesser General Public
26  *   License along with this library; if not, write to the Free Software
27  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
28  *
29  */
30 
31 /*! \page seq Sequencer interface
32 
33 \section seq_general General
34 
35 The ALSA sequencer interface is designed to deliver the MIDI-like
36 events between clients/ports.
37 A typical usage is the MIDI patch-bay.  A MIDI application can be
38 connected arbitrarily from/to the other MIDI clients.
39 The routing between clients can be changed dynamically, so the
40 application can handle incoming or outgoing MIDI events regardless of
41 the devices or the application connections.
42 
43 The sequencer core stuff only takes care of two things:
44 scheduling events and dispatching them to the destination at the
45 right time.  All processing of MIDI events has to be done within the clients.
46 The event can be dispatched immediately without queueing, too.
47 The event scheduling can be done either on a MIDI tempo queue or
48 on a wallclock-time queue.
49 
50 \section seq_client Client and Port
51 
52 A <i>client</i> is created at each time #snd_seq_open() is called.
53 Later on, the attributes of client such as its name string can be changed
54 via #snd_seq_set_client_info().  There are helper functions for ease of use,
55 e.g. #snd_seq_set_client_name() and #snd_seq_set_client_event_filter().
56 A typical code would be like below:
57 \code
58 // create a new client
59 snd_seq_t *open_client()
60 {
61         snd_seq_t *handle;
62         int err;
63         err = snd_seq_open(&handle, "default", SND_SEQ_OPEN_INPUT, 0);
64         if (err < 0)
65                 return NULL;
66         snd_seq_set_client_name(handle, "My Client");
67 	return handle;
68 }
69 \endcode
70 
71 You'll need to know the id number of the client eventually, for example,
72 when accessing to a certain port (see the section \ref seq_subs).
73 The client id can be obtained by #snd_seq_client_id() function.
74 
75 A client can have one or more <i>ports</i> to communicate between other
76 clients.  A port is corresponding to the MIDI port in the case of MIDI device,
77 but in general it is nothing but the access point between other clients.
78 Each port may have capability flags, which specify the read/write
79 accessibility and subscription permissions of the port.
80 For creation of a port, call #snd_seq_create_port()
81 with the appropriate port attribute specified in #snd_seq_port_info_t
82 record.
83 
84 For creating a port for the normal use, there is a helper function
85 #snd_seq_create_simple_port().  An example with this function is like below.
86 \code
87 // create a new port; return the port id
88 // port will be writable and accept the write-subscription.
89 int my_new_port(snd_seq_t *handle)
90 {
91 	return snd_seq_create_simple_port(handle, "my port",
92 			SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
93 			SND_SEQ_PORT_TYPE_MIDI_GENERIC);
94 }
95 \endcode
96 
97 \section seq_memory Memory Pool
98 
99 Each client owns memory pools on kernel space
100 for each input and output events.
101 Here, input and output mean
102 input (read) from other clients and output (write) to others, respectively.
103 Since memory pool of each client is independent from others,
104 it avoids such a situation that a client eats the whole events pool
105 and interfere other clients' response.
106 
107 The all scheduled output events or input events from dispatcher are stored
108 on these pools until delivered to other clients or extracted to user space.
109 The size of input/output pools can be changed independently.
110 The output pool has also a room size, which is used to wake up the
111 thread when it falls into sleep in blocking write mode.
112 
113 Note that ports on the same client share the same memory pool.
114 If a port fills the memory pool, another can't use it any more.
115 For avoiding this, multiple clients can be used.
116 
117 For chancing the pool size and the condition, access to #snd_seq_client_pool_t
118 record.  There are helper functions, #snd_seq_set_client_pool_output(),
119 #snd_seq_set_client_pool_output_room() and #snd_seq_set_client_pool_input(),
120 for setting the total output-pool size, the output-room size and the input-pool
121 size, respectively.
122 
123 \section seq_subs Subscription
124 
125 One of the new features in ALSA sequencer system is <i>subscription</i> of ports.
126 In general, subscription is a connection between two sequencer ports.
127 Even though an event can be delivered to a port without subscription
128 using an explicit destination address,
129 the subscription mechanism provides us more abstraction.
130 
131 Suppose a MIDI input device which sends events from a keyboard.
132 The port associated with this device has READ capability - which means
133 this port is readable from other ports.
134 If a user program wants to capture events from keyboard and store them
135 as MIDI stream, this program must subscribe itself to the MIDI port
136 for read.
137 Then, a connection from MIDI input port to this program is established.
138 From this time, events from keyboard are automatically sent to this program.
139 Timestamps will be updated according to the subscribed queue.
140 \code
141         MIDI input port (keyboard)
142             |
143             V
144         ALSA sequencer - update timestamp
145             |
146             V
147         application port
148 \endcode
149 
150 There is another subscription type for opposite direction:
151 Suppose a MIDI sequencer program which sends events to a MIDI output device.
152 In ALSA system, MIDI device is not opened until the associated MIDI port
153 is accessed.  Thus, in order to activate MIDI device, we have to subscribe
154 to MIDI port for write.
155 After this connection is established, events will be properly sent
156 to MIDI output device.
157 \code
158         application port
159             |
160             V
161         ALSA sequencer - events are scheduled
162             |
163             V
164         MIDI output port (WaveTable etc.)
165 \endcode
166 
167 From the viewpoint of subscription, the examples above are special cases.
168 Basically, subscription means the connection between two arbitrary ports.
169 For example, imagine a filter application which modifies
170 the MIDI events like program, velocity or chorus effects.
171 This application can accept arbitrary MIDI input
172 and send to arbitrary port, just like a Unix pipe application using
173 stdin and stdout files.
174 We can even connect several filter applications which work individually
175 in order to process the MIDI events.
176 Subscription can be used for this purpose.
177 The connection between ports can be done also by the "third" client.
178 Thus, filter applications have to manage
179 only input and output events regardless of receiver/sender addresses.
180 \code
181         sequencer port #1
182             |
183             V
184         ALSA sequencer (scheduled or real-time)
185             |
186             V
187         sequencer port #2
188 \endcode
189 
190 For the detail about subscription, see the section \ref seq_subs_more.
191 
192 \section seq_events Sequencer Events
193 
194 Messaging between clients is performed by sending events from one client to
195 another. These events contain high-level MIDI oriented messages or sequencer
196 specific messages.
197 
198 All the sequencer events are stored in a sequencer event record,
199 #snd_seq_event_t type.
200 Application can send and receive these event records to/from other
201 clients via sequencer.
202 An event has several storage types according to its usage.
203 For example, a SYSEX message is stored on the variable length event,
204 and a large synth sample data is delivered using a user-space data pointer.
205 
206 
207 \subsection seq_ev_struct Structure of an event
208 
209 An event consists of the following items:
210 <ul>
211 <li>The type of the event
212 <li>Event flags.  It describes various conditions:
213   <ul>
214   <li>time stamp; "real time" / "song ticks"
215   <li>time mode; "absolute" / "relative to current time"
216   </ul>
217 <li>Timestamp of the event.
218 <li>Scheduling queue id.
219 <li>Source address of the event, given by the combination
220   of client id and port id numbers.
221 <li>Destination address of the event.
222 <li>The actual event data. (up to 12 bytes)
223 </ul>
224 
225 The actual record is shown in #snd_seq_event_t.
226 The type field contains the type of the event
227 (1 byte).
228 The flags field consists of bit flags which
229 describe several conditions of the event (1 byte).
230 It includes the time-stamp mode, data storage type, and scheduling priority.
231 The tag field is an arbitrary tag.
232 This tag can used for removing a distinct event from the event queue
233 via #snd_seq_remove_events().
234 The queue field is the queue id for scheduling.
235 The source and dest fields are source and destination addresses.
236 The data field is a union of event data.
237 
238 \subsection seq_ev_queue Scheduling queue
239 
240 An event can be delivered either on scheduled or direct dispatch mode.
241 On the scheduling mode, an event is once stored on the priority queue
242 and delivered later (or even immediately) to the destination,
243 whereas on the direct dispatch mode, an event is passed to the destination
244 without any queue.
245 
246 For a scheduled delivery, a queue to process the event must exist.
247 Usually, a client creates its own queue by
248 #snd_seq_alloc_queue() function.
249 Alternatively, a queue may be shared among several clients.
250 For scheduling an event on the specified queue,
251 a client needs to fill queue field
252 with the preferred queue id.
253 
254 Meanwhile, for dispatching an event directly, just
255 use #SND_SEQ_QUEUE_DIRECT as the target queue id.
256 A macro #snd_seq_ev_set_direct() is provided for ease
257 and compatibility.
258 
259 Note that scheduling at the current or earlier time is different
260 from the direct dispatch mode even though the event is delivered immediately.
261 On the former scheme, an event is once stored on priority queue, then
262 delivered actually.  Thus, it acquires a space from memory pool.
263 On the other hand, the latter is passed without using memory pool.
264 Although the direct dispatched event needs less memory, it means also
265 that the event cannot be resent if the destination is unable to receive it
266 momentarily.
267 
268 \subsection seq_ev_time Time stamp
269 
270 The timestamp of the event can either specified in
271 <i>real time</i> or in <i>song ticks</i>.
272 The former means the wallclock time while the latter corresponds to
273 the MIDI ticks.
274 Which format is used is determined by the event flags.
275 
276 The resolution of real-time value is in nano second.
277 Since 64 bit length is required for the actual time calculation,
278 it is represented by
279 a structure of pair of second and nano second
280 defined as #snd_seq_real_time_t type.
281 The song tick is defined simply as a 32 bit integer,
282 defined as #snd_seq_tick_time_t type.
283 The time stored in an event record is a union of these two different
284 time values.
285 
286 Note that the time format used for real time events is very similar to
287 timeval struct used for Unix system time.
288 The absurd resolution of the timestamps allows us to perform very accurate
289 conversions between songposition and real time. Round-off errors can be
290 neglected.
291 
292 If a timestamp with a
293 <i>relative</i> timestamp is delivered to ALSA, the
294 specified timestamp will be used as an offset to the current time of the
295 queue the event is sent into.
296 An <i>absolute</i> timestamp is on the contrary the time
297 counted from the moment when the queue started.
298 
299 An client that relies on these relative timestamps is the MIDI input port.
300 As each sequencer queue has it's own clock the only way to deliver events at
301 the right time is by using the relative timestamp format. When the event
302 arrives at the queue it is normalized to absolute format.
303 
304 The timestamp format is specified in the flag bitfield masked by
305 #SND_SEQ_TIME_STAMP_MASK.
306 To schedule the event in a real-time queue or in a tick queue,
307 macros #snd_seq_ev_schedule_real() and
308 #snd_seq_ev_schedule_tick() are provided, respectively.
309 
310 \subsection seq_ev_addr Source and destination addresses
311 
312 To identify the source and destination of an event, the addressing field
313 contains a combination of client id and port id numbers, defined as
314 #snd_seq_addr_t type.
315 When an event is passed to sequencer from a client, sequencer fills
316 source.client field
317 with the sender's id automatically.
318 It is the responsibility of sender client to
319 fill the port id of source.port and
320 both client and port of dest field.
321 
322 If an existing address is set to the destination,
323 the event is simply delivered to it.
324 When #SND_SEQ_ADDRESS_SUBSCRIBERS is set to the destination client id,
325 the event is delivered to all the clients connected to the source port.
326 
327 
328 A sequencer core has two pre-defined system ports on the system client
329 #SND_SEQ_CLIENT_SYSTEM: #SND_SEQ_PORT_SYSTEM_TIMER and #SND_SEQ_PORT_SYSTEM_ANNOUNCE.
330 The #SND_SEQ_PORT_SYSTEM_TIMER is the system timer port,
331 and #SND_SEQ_PORT_SYSTEM_ANNOUNCE is the system
332 announce port.
333 In order to control a queue from a client, client should send a
334 queue-control event
335 like start, stop and continue queue, change tempo, etc.
336 to the system timer port.
337 Then the sequencer system handles the queue according to the received event.
338 This port supports subscription. The received timer events are
339 broadcasted to all subscribed clients.
340 
341 The latter port does not receive messages but supports subscription.
342 When each client or port is attached, detached or modified,
343 an announcement is sent to subscribers from this port.
344 
345 \subsection seq_ev_data Data storage type
346 
347 Some events like SYSEX message, however, need larger data space
348 than the standard data.
349 For such events, ALSA sequencer provides several different data storage types.
350 The data type is specified in the flag bits masked by #SND_SEQ_EVENT_LENGTH_MASK.
351 The following data types are available:
352 
353 \par Fixed size data
354 Normal events stores their parameters on
355 data field (12 byte).
356 The flag-bit type is  #SND_SEQ_EVENT_LENGTH_FIXED.
357 A macro #snd_seq_ev_set_fixed() is provided to set this type.
358 
359 \par Variable length data
360 SYSEX or a returned error use this type.
361 The actual data is stored on an extra allocated space.
362 On sequencer kernel, the whole extra-data is duplicated, so that the event
363 can be scheduled on queue.
364 The data contains only the length and the
365 pointer of extra-data.
366 The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARIABLE.
367 A macro #snd_seq_ev_set_variable() is provided to set this type.
368 
369 \par User-space data
370 This type refers also an extra data space like variable length data,
371 but the extra-data is not duplicated but
372 but referred as a user-space data on kernel,
373 so that it reduces the time and resource for transferring
374 large bulk of data like synth sample wave.
375 This data type, however, can be used only for direct dispatch mode,
376 and supposed to be used only for a special purpose like a bulk data
377 transfer.
378 The data length and pointer are stored also in
379 data.ext field as well as variable length data.
380 The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARUSR.
381 A macro #snd_seq_ev_set_varusr() is provided to set this type.
382 
383 \subsection seq_ev_sched Scheduling priority
384 
385 There are two priorities for scheduling:
386 \par Normal priority
387 If an event with the same scheduling time is already present on the queue,
388 the new event is appended to the older.
389 \par High priority
390 If an event with the same scheduling time is already present on the queue,
391 the new event is inserted before others.
392 
393 The scheduling priority is set in the flag bitfeld masked by #SND_SEQ_PRIORITY_MASK.
394 A macro #snd_seq_ev_set_priority() is provided to set the mode type.
395 
396 \section seq_queue Event Queues
397 \subsection seq_ev_control Creation of a queue
398 
399 Creating a queue is done usually by calling #snd_seq_alloc_queue.
400 You can create a queue with a certain name by #snd_seq_alloc_named_queue(), too.
401 \code
402 // create a queue and return its id
403 int my_queue(snd_seq_t *handle)
404 {
405 	return snd_seq_alloc_named_queue(handle, "my queue");
406 }
407 \endcode
408 These functions are the wrapper to the function #snd_seq_create_queue().
409 For releasing the allocated queue, call #snd_seq_free_queue() with the
410 obtained queue id.
411 
412 Once when a queue is created, the two queues are associated to that
413 queue record in fact: one is the realtime queue and another is the
414 tick queue.  These two queues are bound together to work
415 synchronously.  Hence, when you schedule an event, you have to choose
416 which queue type is used as described in the section \ref
417 seq_ev_time.
418 
419 \subsection seq_ev_tempo Setting queue tempo
420 
421 The tempo (or the speed) of the scheduling queue is variable.
422 In the case of <i>tick</i> queue, the tempo is controlled
423 in the manner of MIDI.  There are two parameters to define the
424 actual tempo, PPQ (pulse per quarter note) and MIDI tempo.
425 The former defines the base resolution of the ticks, while
426 the latter defines the beat tempo in microseconds.
427 As default, 96 PPQ and 120 BPM are used, respectively.
428 That is, the tempo is set to 500000 (= 60 * 1000000 / 120).
429 Note that PPQ cannot be changed while the queue is running.
430 It must be set before the queue is started.
431 
432 On the other hand, in the case of <i>realtime</i> queue, the
433 time resolution is fixed to nanoseconds.  There is, however,
434 a parameter to change the speed of this queue, called <i>skew</i>.
435 You can make the queue faster or slower by setting the skew value
436 bigger or smaller.  In the API, the skew is defined by two values,
437 the skew base and the skew value.  The actual skew is the fraction
438 of them, <i>value/base</i>.  As default, the skew base is set to 16bit
439 (0x10000) and the skew value is the identical, so that the queue is
440 processed as well as in the real world.
441 
442 When the tempo of realtime queue is changed, the tempo of
443 the associated tick queue is changed together, too.
444 That's the reason why two queues are created always.
445 This feature can be used to synchronize the event queue with
446 the external synchronization source like SMPTE.  In such a case,
447 the realtime queue is skewed to match with the external source,
448 so that both the realtime timestamp and the MIDI timestamp are
449 synchronized.
450 
451 For setting these tempo parameters, use #snd_seq_queue_tempo_t record.
452 For example, to set the tempo of the queue <code>q</code> to
453 48 PPQ, 60 BPM,
454 \code
455 void set_tempo(snd_seq_t *handle, int queue)
456 {
457         snd_seq_queue_tempo_t *tempo;
458         snd_seq_queue_tempo_alloca(&tempo);
459         snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM
460         snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ
461         snd_seq_set_queue_tempo(handle, queue, tempo);
462 }
463 \endcode
464 
465 For changing the (running) queue's tempo on the fly, you can either
466 set the tempo via #snd_seq_set_queue_tempo() or send a MIDI tempo event
467 to the system timer port.  For example,
468 \code
469 int change_tempo(snd_seq_t *handle, int q, unsigned int tempo)
470 {
471 	snd_seq_event_t ev;
472 	snd_seq_ev_clear(&ev);
473 	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
474 	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
475 	ev.source.client = my_client_id;
476 	ev.source.port = my_port_id;
477 	ev.queue = SND_SEQ_QUEUE_DIRECT; // no scheduling
478 	ev.data.queue.queue = q;	// affected queue id
479 	ev.data.queue.value = tempo;	// new tempo in microsec.
480 	return snd_seq_event_output(handle, &ev);
481 }
482 \endcode
483 There is a helper function to do this easily,
484 #snd_seq_change_queue_tempo().
485 Set NULL to the last argument, if you don't need any
486 special settings.
487 
488 In the above example, the tempo is changed immediately after
489 the buffer is flushed by #snd_seq_drain_output() call.
490 You can schedule the event in a certain queue so that the tempo
491 change happens at the scheduled time, too.
492 
493 \subsection seq_ev_start Starting and stopping a queue
494 
495 To start, stop, or continue a queue, you need to send a queue-control
496 event to the system timer port as well.  There are helper functions,
497 #snd_seq_start_queue(), #snd_seq_stop_queue() and
498 #snd_seq_continue_queue().
499 Note that if the last argument of these functions is NULL, the
500 event is sent (i.e. operated) immediately after the buffer flush.
501 If you want to schedule the event at the certain time, set up
502 the event record and provide the pointer of that event record as the
503 argument.
504 
505 Only calling these functions doesn't deliver the event to the
506 sequencer core but only put to the output buffer.  You'll need to
507 call #snd_seq_drain_output() eventually.
508 
509 
510 \section seq_subs_more More inside the subscription
511 
512 \subsection seq_subs_perm Permissions
513 
514 Each ALSA port can have capability flags.
515 The most basic capability flags are
516 #SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE.
517 The former means that the port allows to send events to other ports,
518 whereas the latter capability means
519 that the port allows to receive events from other ports.
520 You may have noticed that meanings of \c READ and \c WRITE
521 are permissions of the port from the viewpoint of other ports.
522 
523 For allowing subscription from/to other clients, another capability
524 flags must be set together with read/write capabilities above.
525 For allowing read and write subscriptions,
526 #SND_SEQ_PORT_CAP_SUBS_READ and
527 #SND_SEQ_PORT_CAP_SUBS_WRITE are used,
528 respectively.
529 For example, the port with MIDI input device always has
530 #SND_SEQ_PORT_CAP_SUBS_READ capability,
531 and the port with MIDI output device always has
532 #SND_SEQ_PORT_CAP_SUBS_WRITE capability together with
533 #SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE capabilities,
534 respectively.
535 Obviously, these flags have no influence
536 if \c READ or \c WRITE> capability is not set.
537 
538 Note that these flags are not necessary if the client subscribes itself
539 to the specified port.
540 For example, when a port makes READ subscription
541 to MIDI input port, this port must have #SND_SEQ_PORT_CAP_WRITE capability,
542 but no #SND_SEQ_PORT_CAP_SUBS_WRITE capability is required.
543 Only MIDI input port must have #SND_SEQ_PORT_CAP_SUBS_READ capability.
544 
545 As default, the connection of ports via the third client is always allowed
546 if proper read and write (subscription) capabilities are set both to the
547 source and destination ports.
548 For prohibiting this behavior, set a capability
549 #SND_SEQ_PORT_CAP_NO_EXPORT to the port.
550 If this flag is set, subscription must be done by sender or receiver
551 client itself.
552 It is useful to avoid unexpected disconnection.
553 The ports which won't accept subscription should have this capability
554 for better security.
555 
556 \subsection seq_subs_handle Subscription handlers
557 
558 In ALSA library, subscription is done via
559 #snd_seq_subscribe_port() function.
560 It takes the argument of #snd_seq_port_subscribe_t record pointer.
561 Suppose that you have a client which will receive data from
562 a MIDI input device.  The source and destination addresses
563 are like the below;
564 \code
565 snd_seq_addr_t sender, dest;
566 sender.client = MIDI_input_client;
567 sender.port = MIDI_input_port;
568 dest.client = my_client;
569 dest.port = my_port;
570 \endcode
571 To set these values as the connection call like this.
572 \code
573 snd_seq_port_subscribe_t *subs;
574 snd_seq_port_subscribe_alloca(&subs);
575 snd_seq_port_subscribe_set_sender(subs, &sender);
576 snd_seq_port_subscribe_set_dest(subs, &dest);
577 snd_seq_subscribe_port(handle, subs);
578 \endcode
579 
580 When the connection should be exclusively done only between
581 a certain pair, set <i>exclusive</i> attribute to the subscription
582 record before calling #snd_seq_subscribe_port.
583 \code
584 snd_seq_port_subscribe_set_exclusive(subs, 1);
585 \endcode
586 The succeeding subscriptions will be refused.
587 
588 The timestamp can be updated independently on each connection.
589 When set up, the timestamp of incoming queue to the destination port
590 is updated automatically to the time of the specified queue.
591 \code
592 snd_seq_port_subscribe_set_time_update(subs, 1);
593 snd_seq_port_subscribe_set_queue(subs, q);
594 \endcode
595 For getting the wallclock time (sec/nsec pair), set <i>real</i> attribute:
596 \code
597 snd_seq_port_subscribe_set_time_real(subs, 1);
598 \endcode
599 Otherwise, the timestamp is stored in tick unit.
600 This feature is useful when receiving events from MIDI input device.
601 The event time is automatically set in the event record.
602 
603 Note that an outsider client may connect other ports.
604 In this case, however, the subscription may be refused
605 if #SND_SEQ_PORT_CAP_NO_EXPORT capability is set in either sender or receiver port.
606 
607 \section seq_subs_ex Examples of subscription
608 
609 \subsection seq_subs_ex_capt Capture from keyboard
610 
611 Assume MIDI input port = 64:0, application port = 128:0, and
612 queue for timestamp = 1 with real-time stamp.
613 The application port must have capability #SND_SEQ_PORT_CAP_WRITE.
614 \code
615 void capture_keyboard(snd_seq_t *seq)
616 {
617         snd_seq_addr_t sender, dest;
618         snd_seq_port_subscribe_t *subs;
619         sender.client = 64;
620         sender.port = 0;
621         dest.client = 128;
622         dest.port = 0;
623         snd_seq_port_subscribe_alloca(&subs);
624         snd_seq_port_subscribe_set_sender(subs, &sender);
625         snd_seq_port_subscribe_set_dest(subs, &dest);
626         snd_seq_port_subscribe_set_queue(subs, 1);
627         snd_seq_port_subscribe_set_time_update(subs, 1);
628         snd_seq_port_subscribe_set_time_real(subs, 1);
629         snd_seq_subscribe_port(seq, subs);
630 }
631 \endcode
632 
633 \subsection seq_subs_ex_out Output to MIDI device
634 
635 Assume MIDI output port = 65:1 and application port = 128:0.
636 The application port must have capability #SND_SEQ_PORT_CAP_READ.
637 \code
638 void subscribe_output(snd_seq_t *seq)
639 {
640         snd_seq_addr_t sender, dest;
641         snd_seq_port_subscribe_t *subs;
642         sender.client = 128;
643         sender.port = 0;
644         dest.client = 65;
645         dest.port = 1;
646         snd_seq_port_subscribe_alloca(&subs);
647         snd_seq_port_subscribe_set_sender(subs, &sender);
648         snd_seq_port_subscribe_set_dest(subs, &dest);
649         snd_seq_subscribe_port(seq, subs);
650 }
651 \endcode
652 This example can be simplified by using #snd_seq_connect_to() function.
653 \code
654 void subscribe_output(snd_seq_t *seq)
655 {
656         snd_seq_connect_to(seq, 0, 65, 1);
657 }
658 \endcode
659 
660 \subsection seq_subs_ex_arbit Arbitrary connection
661 
662 Assume connection from application 128:0 to 129:0,
663 and that subscription is done by the third application (130:0).
664 The sender must have capabilities both
665 #SND_SEQ_PORT_CAP_READ and
666 #SND_SEQ_PORT_CAP_SUBS_READ,
667 and the receiver
668 #SND_SEQ_PORT_CAP_WRITE and
669 #SND_SEQ_PORT_CAP_SUBS_WRITE, respectively.
670 \code
671 // ..in the third application (130:0) ..
672 void coupling(snd_seq_t *seq)
673 {
674         snd_seq_addr_t sender, dest;
675         snd_seq_port_subscribe_t *subs;
676         sender.client = 128;
677         sender.port = 0;
678         dest.client = 129;
679         dest.port = 0;
680         snd_seq_port_subscribe_alloca(&subs);
681         snd_seq_port_subscribe_set_sender(subs, &sender);
682         snd_seq_port_subscribe_set_dest(subs, &dest);
683         snd_seq_subscribe_port(seq, subs);
684 }
685 \endcode
686 
687 \section seq_ex_event Event Processing
688 
689 \subsection seq_ex_address Addressing
690 
691 Now, two ports are connected by subscription.  Then how to send events?
692 
693 The subscribed port doesn't have to know the exact sender address.
694 Instead, there is a special address for subscribers,
695 #SND_SEQ_ADDRESS_SUBSCRIBERS.
696 The sender must set this value as the destination client.
697 Destination port is ignored.
698 
699 The other values in source and destination addresses are identical with
700 the normal event record.
701 If the event is scheduled, proper queue and timestamp values must be set.
702 
703 There is a convenient function to set the address in an event record.
704 In order to set destination as subscribers, use
705 #snd_seq_ev_set_subs().
706 
707 \subsection Scheduled Delivery
708 
709 If we send an event at the scheduled time <code>t</code> (tick)
710 on the queue <code>Q</code>,
711 the sender must set both schedule queue and time in the
712 event record.
713 The program appears like this:
714 \code
715 void schedule_event(snd_seq_t *seq)
716 {
717         snd_seq_event_t ev;
718 
719         snd_seq_ev_clear(&ev);
720         snd_seq_ev_set_source(&ev, my_port);
721         snd_seq_ev_set_subs(&ev);
722         snd_seq_ev_schedule_tick(&ev, Q, 0, t);
723         ... // set event type, data, so on..
724 
725         snd_seq_event_output(seq, &ev);
726         ...
727         snd_seq_drain_output(seq);  // if necessary
728 }
729 \endcode
730 Of course, you can use realtime stamp, too.
731 
732 \subsection seq_ex_direct Direct Delivery
733 
734 If the event is sent immediately without enqueued, the sender doesn't take
735 care of queue and timestamp.
736 As well as the case above, there is a function to set the direct delivery,
737 #snd_seq_ev_set_direct().
738 The program can be more simplified as follows:
739 \code
740 void direct_delivery(snd_seq_t *seq)
741 {
742         snd_seq_event_t ev;
743 
744         snd_seq_ev_clear(&ev);
745         snd_seq_ev_set_source(&ev, port);
746         snd_seq_ev_set_subs(&ev);
747         snd_seq_ev_set_direct(&ev);
748         ... // set event type, data, so on..
749 
750         snd_seq_event_output(seq, &ev);
751         snd_seq_drain_output(seq);
752 }
753 \endcode
754 You should flush event soon after output event.
755 Otherwise, the event is enqueued on output queue of ALSA library
756 (not in the kernel!), and will be never processed until
757 this queue becomes full.
758 
759 \subsection seq_ex_filter Filter Application
760 
761 A typical filter program, which receives an event and sends it immediately
762 after some modification, will appear as following:
763 \code
764 void event_filter(snd_seq_t *seq, snd_seq_event_t *ev)
765 {
766         while (snd_seq_event_input(seq, &ev) >= 0) {
767                 //.. modify input event ..
768 
769                 snd_seq_ev_set_source(ev, my_port);
770                 snd_seq_ev_set_subs(ev);
771                 snd_seq_ev_set_direct(ev);
772                 snd_seq_event_output(seq, ev);
773                 snd_seq_drain_output(seq);
774         }
775 }
776 \endcode
777 
778 */
779 
780 #include <poll.h>
781 #include "seq_local.h"
782 
783 /****************************************************************************
784  *                                                                          *
785  *                                seq.h                                     *
786  *                              Sequencer                                   *
787  *                                                                          *
788  ****************************************************************************/
789 
790 /**
791  * \brief get identifier of sequencer handle
792  * \param seq sequencer handle
793  * \return ASCII identifier of sequencer handle
794  *
795  * Returns the ASCII identifier of the given sequencer handle. It's the same
796  * identifier specified in snd_seq_open().
797  *
798  * \sa snd_seq_open()
799  */
snd_seq_name(snd_seq_t * seq)800 const char *snd_seq_name(snd_seq_t *seq)
801 {
802 	assert(seq);
803 	return seq->name;
804 }
805 
806 /**
807  * \brief get type of sequencer handle
808  * \param seq sequencer handle
809  * \return type of sequencer handle
810  *
811  * Returns the type #snd_seq_type_t of the given sequencer handle.
812  *
813  * \sa snd_seq_open()
814  */
snd_seq_type(snd_seq_t * seq)815 snd_seq_type_t snd_seq_type(snd_seq_t *seq)
816 {
817 	assert(seq);
818 	return seq->type;
819 }
820 
snd_seq_open_conf(snd_seq_t ** seqp,const char * name,snd_config_t * seq_root,snd_config_t * seq_conf,int streams,int mode)821 static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
822 			     snd_config_t *seq_root, snd_config_t *seq_conf,
823 			     int streams, int mode)
824 {
825 	const char *str;
826 	char buf[256], errbuf[256];
827 	int err;
828 	snd_config_t *conf, *type_conf = NULL;
829 	snd_config_iterator_t i, next;
830 	const char *id;
831 	const char *lib = NULL, *open_name = NULL;
832 	int (*open_func)(snd_seq_t **, const char *,
833 			 snd_config_t *, snd_config_t *,
834 			 int, int) = NULL;
835 #ifndef PIC
836 	extern void *snd_seq_open_symbols(void);
837 #endif
838 	void *h = NULL;
839 	if (snd_config_get_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
840 		if (name)
841 			SNDERR("Invalid type for SEQ %s definition", name);
842 		else
843 			SNDERR("Invalid type for SEQ definition");
844 		return -EINVAL;
845 	}
846 	err = snd_config_search(seq_conf, "type", &conf);
847 	if (err < 0) {
848 		SNDERR("type is not defined");
849 		return err;
850 	}
851 	err = snd_config_get_id(conf, &id);
852 	if (err < 0) {
853 		SNDERR("unable to get id");
854 		return err;
855 	}
856 	err = snd_config_get_string(conf, &str);
857 	if (err < 0) {
858 		SNDERR("Invalid type for %s", id);
859 		return err;
860 	}
861 	err = snd_config_search_definition(seq_root, "seq_type", str, &type_conf);
862 	if (err >= 0) {
863 		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
864 			SNDERR("Invalid type for SEQ type %s definition", str);
865 			goto _err;
866 		}
867 		snd_config_for_each(i, next, type_conf) {
868 			snd_config_t *n = snd_config_iterator_entry(i);
869 			const char *id;
870 			if (snd_config_get_id(n, &id) < 0)
871 				continue;
872 			if (strcmp(id, "comment") == 0)
873 				continue;
874 			if (strcmp(id, "lib") == 0) {
875 				err = snd_config_get_string(n, &lib);
876 				if (err < 0) {
877 					SNDERR("Invalid type for %s", id);
878 					goto _err;
879 				}
880 				continue;
881 			}
882 			if (strcmp(id, "open") == 0) {
883 				err = snd_config_get_string(n, &open_name);
884 				if (err < 0) {
885 					SNDERR("Invalid type for %s", id);
886 					goto _err;
887 				}
888 				continue;
889 			}
890 			SNDERR("Unknown field %s", id);
891 			err = -EINVAL;
892 			goto _err;
893 		}
894 	}
895 	if (!open_name) {
896 		open_name = buf;
897 		snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
898 	}
899 #ifndef PIC
900 	snd_seq_open_symbols();
901 #endif
902 	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
903 	if (h)
904 		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_SEQ_DLSYM_VERSION));
905 	err = 0;
906 	if (!h) {
907 		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
908 		err = -ENOENT;
909 	} else if (!open_func) {
910 		SNDERR("symbol %s is not defined inside %s", open_name, lib);
911 		snd_dlclose(h);
912 		err = -ENXIO;
913 	}
914        _err:
915 	if (type_conf)
916 		snd_config_delete(type_conf);
917 	if (! err) {
918 		err = open_func(seqp, name, seq_root, seq_conf, streams, mode);
919 		if (err < 0)
920 			snd_dlclose(h);
921 		else
922 			(*seqp)->dl_handle = h;
923 	}
924 	return err;
925 }
926 
snd_seq_open_noupdate(snd_seq_t ** seqp,snd_config_t * root,const char * name,int streams,int mode,int hop)927 static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
928 				 const char *name, int streams, int mode,
929 				 int hop)
930 {
931 	int err;
932 	snd_config_t *seq_conf;
933 	err = snd_config_search_definition(root, "seq", name, &seq_conf);
934 	if (err < 0) {
935 		SNDERR("Unknown SEQ %s", name);
936 		return err;
937 	}
938 	snd_config_set_hop(seq_conf, hop);
939 	err = snd_seq_open_conf(seqp, name, root, seq_conf, streams, mode);
940 	snd_config_delete(seq_conf);
941 	return err;
942 }
943 
944 
945 /**
946  * \brief Open the ALSA sequencer
947  *
948  * \param seqp Pointer to a snd_seq_t pointer.  This pointer must be
949  * kept and passed to most of the other sequencer functions.
950  * \param name The sequencer's "name".  This is \em not a name you make
951  * up for your own purposes; it has special significance to the ALSA
952  * library.  Usually you need to pass \c "default" here.
953  * \param streams The read/write mode of the sequencer.  Can be one of
954  * three values:
955  * - #SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
956  * - #SND_SEQ_OPEN_INPUT - open the sequencer for input only
957  * - #SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
958  * \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
959  * \c O_RDWR respectively and used as the second argument to the C library
960  * open() call.
961  * \param mode Optional modifier.  Can be either 0, or
962  * #SND_SEQ_NONBLOCK, which will make read/write operations
963  * non-blocking.  This can also be set later using #snd_seq_nonblock().
964  * \return 0 on success otherwise a negative error code
965  *
966  * Creates a new handle and opens a connection to the kernel
967  * sequencer interface.
968  * After a client is created successfully, an event
969  * with #SND_SEQ_EVENT_CLIENT_START is broadcast to announce port.
970  *
971  * \sa snd_seq_open_lconf(), snd_seq_close(), snd_seq_type(), snd_seq_name(),
972  *     snd_seq_nonblock(), snd_seq_client_id()
973  */
snd_seq_open(snd_seq_t ** seqp,const char * name,int streams,int mode)974 int snd_seq_open(snd_seq_t **seqp, const char *name,
975 		 int streams, int mode)
976 {
977 	snd_config_t *top;
978 	int err;
979 
980 	assert(seqp && name);
981 	err = snd_config_update_ref(&top);
982 	if (err < 0)
983 		return err;
984 	err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
985 	snd_config_unref(top);
986 	return err;
987 }
988 
989 /**
990  * \brief Open the ALSA sequencer using local configuration
991  *
992  * \param seqp Pointer to a snd_seq_t pointer.
993  * \param name The name to open
994  * \param streams The read/write mode of the sequencer.
995  * \param mode Optional modifier
996  * \param lconf Local configuration
997  * \return 0 on success otherwise a negative error code
998  *
999  * See the snd_seq_open() function for further details. The extension
1000  * is that the given configuration is used to resolve abstract name.
1001  *
1002  * \sa snd_seq_open()
1003  */
snd_seq_open_lconf(snd_seq_t ** seqp,const char * name,int streams,int mode,snd_config_t * lconf)1004 int snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1005 		       int streams, int mode, snd_config_t *lconf)
1006 {
1007 	assert(seqp && name && lconf);
1008 	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
1009 }
1010 
1011 #ifndef DOC_HIDDEN
_snd_seq_open_lconf(snd_seq_t ** seqp,const char * name,int streams,int mode,snd_config_t * lconf,snd_config_t * parent_conf)1012 int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1013 			int streams, int mode, snd_config_t *lconf,
1014 			snd_config_t *parent_conf)
1015 {
1016 	int hop;
1017 	assert(seqp && name && lconf);
1018 	if ((hop = snd_config_check_hop(parent_conf)) < 0)
1019 		return hop;
1020 	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
1021 }
1022 #endif
1023 
1024 /**
1025  * \brief Close the sequencer
1026  * \param seq Handle returned from #snd_seq_open()
1027  * \return 0 on success otherwise a negative error code
1028  *
1029  * Closes the sequencer client and releases its resources.
1030  * After a client is closed, an event with
1031  * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
1032  * The connection between other clients are disconnected.
1033  * Call this just before exiting your program.
1034  *
1035  * \sa snd_seq_close()
1036  */
snd_seq_close(snd_seq_t * seq)1037 int snd_seq_close(snd_seq_t *seq)
1038 {
1039 	int err;
1040 	assert(seq);
1041 	err = seq->ops->close(seq);
1042 	if (seq->dl_handle)
1043 		snd_dlclose(seq->dl_handle);
1044 	free(seq->obuf);
1045 	free(seq->ibuf);
1046 	free(seq->tmpbuf);
1047 	free(seq->name);
1048 	free(seq);
1049 	return err;
1050 }
1051 
1052 /**
1053  * \brief Returns the number of poll descriptors
1054  * \param seq sequencer handle
1055  * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
1056  * \return the number of poll descriptors.
1057  *
1058  * Get the number of poll descriptors.  The polling events to be checked
1059  * can be specified by the second argument.  When both input and output
1060  * are checked, pass \c POLLIN|POLLOUT
1061  *
1062  * \sa snd_seq_poll_descriptors()
1063  */
snd_seq_poll_descriptors_count(snd_seq_t * seq,short events)1064 int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
1065 {
1066 	int result = 0;
1067 	assert(seq);
1068 	if (events & POLLIN) {
1069 		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1070 		result++;
1071 	}
1072 	if (events & POLLOUT) {
1073 		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1074 		result++;
1075 	}
1076 	return result ? 1 : 0;
1077 }
1078 
1079 /**
1080  * \brief Get poll descriptors
1081  * \param seq sequencer handle
1082  * \param pfds array of poll descriptors
1083  * \param space space in the poll descriptor array
1084  * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
1085  * \return count of filled descriptors
1086  *
1087  * Get poll descriptors assigned to the sequencer handle.
1088  * Since a sequencer handle can duplex streams, you need to set which direction(s)
1089  * is/are polled in \a events argument.  When \c POLLIN bit is specified,
1090  * the incoming events to the ports are checked.
1091  *
1092  * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
1093  * instead of reading the pollfd structs directly.
1094  *
1095  * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
1096  */
snd_seq_poll_descriptors(snd_seq_t * seq,struct pollfd * pfds,unsigned int space,short events)1097 int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
1098 {
1099 	short revents = 0;
1100 
1101 	assert(seq);
1102 	if ((events & POLLIN) && space >= 1) {
1103 		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1104 		revents |= POLLIN|POLLERR|POLLNVAL;
1105 	}
1106 	if ((events & POLLOUT) && space >= 1) {
1107 		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1108 		revents |= POLLOUT|POLLERR|POLLNVAL;
1109 	}
1110 	if (!revents)
1111 		return 0;
1112 	pfds->fd = seq->poll_fd;
1113 	pfds->events = revents;
1114 	return 1;
1115 }
1116 
1117 /**
1118  * \brief get returned events from poll descriptors
1119  * \param seq sequencer handle
1120  * \param pfds array of poll descriptors
1121  * \param nfds count of poll descriptors
1122  * \param revents returned events
1123  * \return zero if success, otherwise a negative error code
1124  *
1125  * \sa snd_seq_poll_descriptors()
1126  */
snd_seq_poll_descriptors_revents(snd_seq_t * seq,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)1127 int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1128 {
1129         assert(seq && pfds && revents);
1130         if (nfds == 1) {
1131                 *revents = pfds->revents;
1132                 return 0;
1133         }
1134         return -EINVAL;
1135 }
1136 
1137 /**
1138  * \brief Set nonblock mode
1139  * \param seq sequencer handle
1140  * \param nonblock 0 = block, 1 = nonblock mode
1141  * \return 0 on success otherwise a negative error code
1142  *
1143  * Change the blocking mode of the given client.
1144  * In block mode, the client falls into sleep when it fills the
1145  * output memory pool with full events.  The client will be woken up
1146  * after a certain amount of free space becomes available.
1147  *
1148  * \sa snd_seq_open()
1149  */
snd_seq_nonblock(snd_seq_t * seq,int nonblock)1150 int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
1151 {
1152 	int err;
1153 	assert(seq);
1154 	err = seq->ops->nonblock(seq, nonblock);
1155 	if (err < 0)
1156 		return err;
1157 	if (nonblock)
1158 		seq->mode |= SND_SEQ_NONBLOCK;
1159 	else
1160 		seq->mode &= ~SND_SEQ_NONBLOCK;
1161 	return 0;
1162 }
1163 
1164 /**
1165  * \brief Get the client id
1166  * \param seq sequencer handle
1167  * \return the client id
1168  *
1169  * Returns the id of the specified client.
1170  * If an error occurs, function returns the negative error code.
1171  * A client id is necessary to inquiry or to set the client information.
1172  * A user client is assigned from 128 to 191.
1173  *
1174  * \sa snd_seq_open()
1175  */
snd_seq_client_id(snd_seq_t * seq)1176 int snd_seq_client_id(snd_seq_t *seq)
1177 {
1178 	assert(seq);
1179 	return seq->client;
1180 }
1181 
1182 /**
1183  * \brief Return the size of output buffer
1184  * \param seq sequencer handle
1185  * \return the size of output buffer in bytes
1186  *
1187  * Obtains the size of output buffer.
1188  * This buffer is used to store decoded byte-stream of output events
1189  * before transferring to sequencer.
1190  *
1191  * \sa snd_seq_set_output_buffer_size()
1192  */
snd_seq_get_output_buffer_size(snd_seq_t * seq)1193 size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
1194 {
1195 	assert(seq);
1196 	if (!seq->obuf)
1197 		return 0;
1198 	return seq->obufsize;
1199 }
1200 
1201 /**
1202  * \brief Return the size of input buffer
1203  * \param seq sequencer handle
1204  * \return the size of input buffer in bytes
1205  *
1206  * Obtains the size of input buffer.
1207  * This buffer is used to read byte-stream of input events from sequencer.
1208  *
1209  * \sa snd_seq_set_input_buffer_size()
1210  */
snd_seq_get_input_buffer_size(snd_seq_t * seq)1211 size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
1212 {
1213 	assert(seq);
1214 	if (!seq->ibuf)
1215 		return 0;
1216 	return seq->ibufsize * sizeof(snd_seq_event_t);
1217 }
1218 
1219 /**
1220  * \brief Change the size of output buffer
1221  * \param seq sequencer handle
1222  * \param size the size of output buffer to be changed in bytes
1223  * \return 0 on success otherwise a negative error code
1224  *
1225  * Changes the size of output buffer.
1226  *
1227  * \sa snd_seq_get_output_buffer_size()
1228  */
snd_seq_set_output_buffer_size(snd_seq_t * seq,size_t size)1229 int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
1230 {
1231 	assert(seq && seq->obuf);
1232 	assert(size >= sizeof(snd_seq_event_t));
1233 	snd_seq_drop_output(seq);
1234 	if (size != seq->obufsize) {
1235 		char *newbuf;
1236 		newbuf = calloc(1, size);
1237 		if (newbuf == NULL)
1238 			return -ENOMEM;
1239 		free(seq->obuf);
1240 		seq->obuf = newbuf;
1241 		seq->obufsize = size;
1242 	}
1243 	return 0;
1244 }
1245 
1246 /**
1247  * \brief Resize the input buffer
1248  * \param seq sequencer handle
1249  * \param size the size of input buffer to be changed in bytes
1250  * \return 0 on success otherwise a negative error code
1251  *
1252  * Changes the size of input buffer.
1253  *
1254  * \sa snd_seq_get_input_buffer_size()
1255  */
snd_seq_set_input_buffer_size(snd_seq_t * seq,size_t size)1256 int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
1257 {
1258 	assert(seq && seq->ibuf);
1259 	assert(size >= sizeof(snd_seq_event_t));
1260 	snd_seq_drop_input(seq);
1261 	size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
1262 	if (size != seq->ibufsize) {
1263 		snd_seq_event_t *newbuf;
1264 		newbuf = calloc(sizeof(snd_seq_event_t), size);
1265 		if (newbuf == NULL)
1266 			return -ENOMEM;
1267 		free(seq->ibuf);
1268 		seq->ibuf = newbuf;
1269 		seq->ibufsize = size;
1270 	}
1271 	return 0;
1272 }
1273 
1274 
1275 /**
1276  * \brief Get size of #snd_seq_system_info_t
1277  * \return size in bytes
1278  */
snd_seq_system_info_sizeof()1279 size_t snd_seq_system_info_sizeof()
1280 {
1281 	return sizeof(snd_seq_system_info_t);
1282 }
1283 
1284 /**
1285  * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
1286  * \param ptr returned pointer
1287  * \return 0 on success otherwise negative error code
1288  */
snd_seq_system_info_malloc(snd_seq_system_info_t ** ptr)1289 int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
1290 {
1291 	assert(ptr);
1292 	*ptr = calloc(1, sizeof(snd_seq_system_info_t));
1293 	if (!*ptr)
1294 		return -ENOMEM;
1295 	return 0;
1296 }
1297 
1298 /**
1299  * \brief Frees a previously allocated #snd_seq_system_info_t
1300  * \param obj pointer to object to free
1301  */
snd_seq_system_info_free(snd_seq_system_info_t * obj)1302 void snd_seq_system_info_free(snd_seq_system_info_t *obj)
1303 {
1304 	free(obj);
1305 }
1306 
1307 /**
1308  * \brief Copy one #snd_seq_system_info_t to another
1309  * \param dst pointer to destination
1310  * \param src pointer to source
1311  */
snd_seq_system_info_copy(snd_seq_system_info_t * dst,const snd_seq_system_info_t * src)1312 void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
1313 {
1314 	assert(dst && src);
1315 	*dst = *src;
1316 }
1317 
1318 
1319 /**
1320  * \brief Get maximum number of queues
1321  * \param info #snd_seq_system_info_t container
1322  * \return maximum number of queues
1323  *
1324  * \sa snd_seq_system_info()
1325  */
snd_seq_system_info_get_queues(const snd_seq_system_info_t * info)1326 int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
1327 {
1328 	assert(info);
1329 	return info->queues;
1330 }
1331 
1332 /**
1333  * \brief Get maximum number of clients
1334  * \param info #snd_seq_system_info_t container
1335  * \return maximum number of clients
1336  *
1337  * \sa snd_seq_system_info()
1338  */
snd_seq_system_info_get_clients(const snd_seq_system_info_t * info)1339 int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
1340 {
1341 	assert(info);
1342 	return info->clients;
1343 }
1344 
1345 /**
1346  * \brief Get maximum number of ports
1347  * \param info #snd_seq_system_info_t container
1348  * \return maximum number of ports
1349  *
1350  * \sa snd_seq_system_info()
1351  */
snd_seq_system_info_get_ports(const snd_seq_system_info_t * info)1352 int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
1353 {
1354 	assert(info);
1355 	return info->ports;
1356 }
1357 
1358 /**
1359  * \brief Get maximum number of channels
1360  * \param info #snd_seq_system_info_t container
1361  * \return maximum number of channels
1362  *
1363  * \sa snd_seq_system_info()
1364  */
snd_seq_system_info_get_channels(const snd_seq_system_info_t * info)1365 int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
1366 {
1367 	assert(info);
1368 	return info->channels;
1369 }
1370 
1371 /**
1372  * \brief Get the current number of clients
1373  * \param info #snd_seq_system_info_t container
1374  * \return current number of clients
1375  *
1376  * \sa snd_seq_system_info()
1377  */
snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t * info)1378 int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
1379 {
1380 	assert(info);
1381 	return info->cur_clients;
1382 }
1383 
1384 /**
1385  * \brief Get the current number of queues
1386  * \param info #snd_seq_system_info_t container
1387  * \return current number of queues
1388  *
1389  * \sa snd_seq_system_info()
1390  */
snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t * info)1391 int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
1392 {
1393 	assert(info);
1394 	return info->cur_queues;
1395 }
1396 
1397 /**
1398  * \brief obtain the sequencer system information
1399  * \param seq sequencer handle
1400  * \param info the pointer to be stored
1401  * \return 0 on success otherwise a negative error code
1402  *
1403  * Stores the global system information of ALSA sequencer system.
1404  * The returned data contains
1405  * the maximum available numbers of queues, clients, ports and channels.
1406  */
snd_seq_system_info(snd_seq_t * seq,snd_seq_system_info_t * info)1407 int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
1408 {
1409 	assert(seq && info);
1410 	return seq->ops->system_info(seq, info);
1411 }
1412 
1413 
1414 /*----------------------------------------------------------------*/
1415 
1416 /**
1417  * \brief get size of #snd_seq_client_info_t
1418  * \return size in bytes
1419  */
snd_seq_client_info_sizeof()1420 size_t snd_seq_client_info_sizeof()
1421 {
1422 	return sizeof(snd_seq_client_info_t);
1423 }
1424 
1425 /**
1426  * \brief allocate an empty #snd_seq_client_info_t using standard malloc
1427  * \param ptr returned pointer
1428  * \return 0 on success otherwise negative error code
1429  */
snd_seq_client_info_malloc(snd_seq_client_info_t ** ptr)1430 int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
1431 {
1432 	assert(ptr);
1433 	*ptr = calloc(1, sizeof(snd_seq_client_info_t));
1434 	if (!*ptr)
1435 		return -ENOMEM;
1436 	return 0;
1437 }
1438 
1439 /**
1440  * \brief frees a previously allocated #snd_seq_client_info_t
1441  * \param obj pointer to object to free
1442  */
snd_seq_client_info_free(snd_seq_client_info_t * obj)1443 void snd_seq_client_info_free(snd_seq_client_info_t *obj)
1444 {
1445 	free(obj);
1446 }
1447 
1448 /**
1449  * \brief copy one #snd_seq_client_info_t to another
1450  * \param dst pointer to destination
1451  * \param src pointer to source
1452  */
snd_seq_client_info_copy(snd_seq_client_info_t * dst,const snd_seq_client_info_t * src)1453 void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
1454 {
1455 	assert(dst && src);
1456 	*dst = *src;
1457 }
1458 
1459 
1460 /**
1461  * \brief Get client id of a client_info container
1462  * \param info client_info container
1463  * \return client id
1464  *
1465  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
1466  */
snd_seq_client_info_get_client(const snd_seq_client_info_t * info)1467 int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
1468 {
1469 	assert(info);
1470 	return info->client;
1471 }
1472 
1473 /**
1474  * \brief Get client type of a client_info container
1475  * \param info client_info container
1476  * \return client type
1477  *
1478  * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
1479  * for kernel or user client respectively.
1480  *
1481  * \sa snd_seq_get_client_info()
1482  */
snd_seq_client_info_get_type(const snd_seq_client_info_t * info)1483 snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
1484 {
1485 	assert(info);
1486 	return info->type;
1487 }
1488 
1489 /**
1490  * \brief Get the name of a client_info container
1491  * \param info client_info container
1492  * \return name string
1493  *
1494  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
1495  */
snd_seq_client_info_get_name(snd_seq_client_info_t * info)1496 const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
1497 {
1498 	assert(info);
1499 	return info->name;
1500 }
1501 
1502 /**
1503  * \brief Get the broadcast filter usage of a client_info container
1504  * \param info client_info container
1505  * \return 1 if broadcast is accepted
1506  *
1507  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
1508  */
snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t * info)1509 int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
1510 {
1511 	assert(info);
1512 	return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
1513 }
1514 
1515 /**
1516  * \brief Get the error-bounce usage of a client_info container
1517  * \param info client_info container
1518  * \return 1 if error-bounce is enabled
1519  *
1520  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
1521  */
snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t * info)1522 int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
1523 {
1524 	assert(info);
1525 	return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
1526 }
1527 
1528 /**
1529  * \brief Get the sound card number.
1530  * \param info client_info container
1531  * \return card number or -1 if value is not available.
1532  *
1533  * Only available for #SND_SEQ_KERNEL_CLIENT clients.
1534  *
1535  * The card number can be used to query state about the hardware
1536  * device providing this client, by concatenating <code>"hw:CARD="</code>
1537  * with the card number and using it as the <code>name</code> parameter
1538  * to #snd_ctl_open().
1539  *
1540  * \note
1541  * The return value of -1 is returned for two different conditions: when the
1542  * running kernel does not support this operation, and when the client
1543  * does not have a hardware card attached. See
1544  * #snd_seq_client_info_get_pid() for a way to determine if the
1545  * currently running kernel has support for this operation.
1546  *
1547  * \sa snd_seq_client_info_get_pid(),
1548  *     snd_card_get_name(),
1549  *     snd_card_get_longname(),
1550  *     snd_ctl_open(),
1551  *     snd_ctl_card_info()
1552  */
snd_seq_client_info_get_card(const snd_seq_client_info_t * info)1553 int snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
1554 {
1555 	assert(info);
1556 	return info->card;
1557 }
1558 
1559 /**
1560  * \brief Get the owning PID.
1561  * \param info client_info container
1562  * \return pid or -1 if value is not available.
1563  *
1564  * Only available for #SND_SEQ_USER_CLIENT clients.
1565  *
1566  * \note
1567  * The functionality for getting a client's PID and getting a
1568  * client's card was added to the kernel at the same time, so you can
1569  * use this function to determine if the running kernel
1570  * supports reporting these values. If your own client has a valid
1571  * PID as reported by this function, then the running kernel supports
1572  * both #snd_seq_client_info_get_card() and #snd_seq_client_info_get_pid().
1573  *
1574  * \note
1575  * Example code for determining kernel support:
1576  * \code
1577  *   int is_get_card_or_pid_supported(snd_seq_t *seq)
1578  *   {
1579  *   	snd_seq_client_info_t *my_client_info;
1580  *   	snd_seq_client_info_alloca(&my_client_info);
1581  *   	snd_seq_get_client_info(seq, my_client_info);
1582  *   	return snd_seq_client_info_get_pid(my_client_info) != -1;
1583  *   }
1584  * \endcode
1585  *
1586  * \sa snd_seq_client_info_get_card()
1587  */
snd_seq_client_info_get_pid(const snd_seq_client_info_t * info)1588 int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
1589 {
1590 	assert(info);
1591 	return info->pid;
1592 }
1593 
1594 /**
1595  * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
1596  * \param info client_info container
1597  * \return NULL if no event filter, or pointer to event filter bitmap
1598  *
1599  * Use #snd_seq_client_info_event_filter_check() instead.
1600  *
1601  * \sa snd_seq_client_info_event_filter_add(),
1602  *     snd_seq_client_info_event_filter_del(),
1603  *     snd_seq_client_info_event_filter_check(),
1604  *     snd_seq_client_info_event_filter_clear(),
1605  *     snd_seq_get_client_info()
1606  */
snd_seq_client_info_get_event_filter(const snd_seq_client_info_t * info)1607 const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
1608 {
1609 	assert(info);
1610 	if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
1611 		return info->event_filter;
1612 	else
1613 		return NULL;
1614 }
1615 
1616 /**
1617  * \brief Disable event filtering of a client_info container
1618  * \param info client_info container
1619  *
1620  * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
1621  * the event filtering flag of this client_info container.
1622  *
1623  * \sa snd_seq_client_info_event_filter_add(),
1624  *     snd_seq_client_info_event_filter_del(),
1625  *     snd_seq_client_info_event_filter_check(),
1626  *     snd_seq_get_client_info(),
1627  *     snd_seq_set_client_info()
1628  */
snd_seq_client_info_event_filter_clear(snd_seq_client_info_t * info)1629 void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
1630 {
1631        assert(info);
1632        info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1633        memset(info->event_filter, 0, sizeof(info->event_filter));
1634 }
1635 
1636 /**
1637  * \brief Add an event type to the event filtering of a client_info container
1638  * \param info client_info container
1639  * \param event_type event type to be added
1640  *
1641  * Set the event filtering flag of this client_info and add the specified event type to the
1642  * filter bitmap of this client_info container.
1643  *
1644  * \sa snd_seq_get_client_info(),
1645  *     snd_seq_set_client_info(),
1646  *     snd_seq_client_info_event_filter_del(),
1647  *     snd_seq_client_info_event_filter_check(),
1648  *     snd_seq_client_info_event_filter_clear()
1649  */
snd_seq_client_info_event_filter_add(snd_seq_client_info_t * info,int event_type)1650 void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
1651 {
1652        assert(info);
1653        info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1654        snd_seq_set_bit(event_type, info->event_filter);
1655 }
1656 
1657 /**
1658  * \brief Remove an event type from the event filtering of a client_info container
1659  * \param info client_info container
1660  * \param event_type event type to be removed
1661  *
1662  * Removes the specified event from the filter bitmap of this client_info container. It will
1663  * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
1664  *
1665  * \sa snd_seq_get_client_info(),
1666  *     snd_seq_set_client_info(),
1667  *     snd_seq_client_info_event_filter_add(),
1668  *     snd_seq_client_info_event_filter_check(),
1669  *     snd_seq_client_info_event_filter_clear()
1670  */
snd_seq_client_info_event_filter_del(snd_seq_client_info_t * info,int event_type)1671 void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
1672 {
1673        assert(info);
1674        snd_seq_unset_bit(event_type, info->event_filter);
1675 }
1676 
1677 /**
1678  * \brief Check if an event type is present in the event filtering of a client_info container
1679  * \param info client_info container
1680  * \param event_type event type to be checked
1681  * \return 1 if the event type is present, 0 otherwise
1682  *
1683  * Test if the event type is in the filter bitmap of this client_info container.
1684  *
1685  * \sa snd_seq_get_client_info(),
1686  *     snd_seq_set_client_info(),
1687  *     snd_seq_client_info_event_filter_add(),
1688  *     snd_seq_client_info_event_filter_del(),
1689  *     snd_seq_client_info_event_filter_clear()
1690  */
snd_seq_client_info_event_filter_check(snd_seq_client_info_t * info,int event_type)1691 int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
1692 {
1693        assert(info);
1694        return snd_seq_get_bit(event_type, info->event_filter);
1695 }
1696 
1697 /**
1698  * \brief Get the number of opened ports of a client_info container
1699  * \param info client_info container
1700  * \return number of opened ports
1701  *
1702  * \sa snd_seq_get_client_info()
1703  */
snd_seq_client_info_get_num_ports(const snd_seq_client_info_t * info)1704 int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
1705 {
1706 	assert(info);
1707 	return info->num_ports;
1708 }
1709 
1710 /**
1711  * \brief Get the number of lost events of a client_info container
1712  * \param info client_info container
1713  * \return number of lost events
1714  *
1715  * \sa snd_seq_get_client_info()
1716  */
snd_seq_client_info_get_event_lost(const snd_seq_client_info_t * info)1717 int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
1718 {
1719 	assert(info);
1720 	return info->event_lost;
1721 }
1722 
1723 /**
1724  * \brief Set the client id of a client_info container
1725  * \param info client_info container
1726  * \param client client id
1727  *
1728  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
1729  */
snd_seq_client_info_set_client(snd_seq_client_info_t * info,int client)1730 void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
1731 {
1732 	assert(info);
1733 	info->client = client;
1734 }
1735 
1736 /**
1737  * \brief Set the name of a client_info container
1738  * \param info client_info container
1739  * \param name name string
1740  *
1741  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
1742  *     snd_seq_set_client_name()
1743  */
snd_seq_client_info_set_name(snd_seq_client_info_t * info,const char * name)1744 void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
1745 {
1746 	assert(info && name);
1747 	snd_strlcpy(info->name, name, sizeof(info->name));
1748 }
1749 
1750 /**
1751  * \brief Set the broadcast filter usage of a client_info container
1752  * \param info client_info container
1753  * \param val non-zero if broadcast is accepted
1754  *
1755  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
1756  */
snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t * info,int val)1757 void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
1758 {
1759 	assert(info);
1760 	if (val)
1761 		info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
1762 	else
1763 		info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
1764 }
1765 
1766 /**
1767  * \brief Set the error-bounce usage of a client_info container
1768  * \param info client_info container
1769  * \param val non-zero if error is bounced
1770  *
1771  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
1772  */
snd_seq_client_info_set_error_bounce(snd_seq_client_info_t * info,int val)1773 void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
1774 {
1775 	assert(info);
1776 	if (val)
1777 		info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
1778 	else
1779 		info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
1780 }
1781 
1782 /**
1783  * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
1784  * \param info client_info container
1785  * \param filter event filter bitmap, pass NULL for no event filtering
1786  *
1787  * Use #snd_seq_client_info_event_filter_add instead.
1788  *
1789  * \sa snd_seq_client_info_event_filter_add(),
1790  *     snd_seq_client_info_event_filter_del(),
1791  *     snd_seq_client_info_event_filter_check(),
1792  *     snd_seq_client_info_event_filter_clear(),
1793  *     snd_seq_set_client_info()
1794  */
snd_seq_client_info_set_event_filter(snd_seq_client_info_t * info,unsigned char * filter)1795 void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
1796 {
1797 	assert(info);
1798 	if (! filter)
1799 		info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1800 	else {
1801 		info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1802 		memcpy(info->event_filter, filter, sizeof(info->event_filter));
1803 	}
1804 }
1805 
1806 
1807 /**
1808  * \brief obtain the information of the given client
1809  * \param seq sequencer handle
1810  * \param client client id
1811  * \param info the pointer to be stored
1812  * \return 0 on success otherwise a negative error code
1813  *
1814  * Obtains the information of the client with a client id specified by
1815  * info argument.
1816  * The obtained information is written on info parameter.
1817  *
1818  * \sa snd_seq_get_client_info()
1819  */
snd_seq_get_any_client_info(snd_seq_t * seq,int client,snd_seq_client_info_t * info)1820 int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
1821 {
1822 	assert(seq && info && client >= 0);
1823 	memset(info, 0, sizeof(snd_seq_client_info_t));
1824 	info->client = client;
1825 	return seq->ops->get_client_info(seq, info);
1826 }
1827 
1828 /**
1829  * \brief obtain the current client information
1830  * \param seq sequencer handle
1831  * \param info the pointer to be stored
1832  * \return 0 on success otherwise a negative error code
1833  *
1834  * Obtains the information of the current client stored on info.
1835  * client and type fields are ignored.
1836  *
1837  * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
1838  *     snd_seq_query_next_client()
1839  */
snd_seq_get_client_info(snd_seq_t * seq,snd_seq_client_info_t * info)1840 int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1841 {
1842 	return snd_seq_get_any_client_info(seq, seq->client, info);
1843 }
1844 
1845 /**
1846  * \brief set the current client information
1847  * \param seq sequencer handle
1848  * \param info the client info data to set
1849  * \return 0 on success otherwise a negative error code
1850  *
1851  * Obtains the information of the current client stored on info.
1852  * client and type fields are ignored.
1853  *
1854  * \sa snd_seq_get_client_info()
1855  */
snd_seq_set_client_info(snd_seq_t * seq,snd_seq_client_info_t * info)1856 int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1857 {
1858 	assert(seq && info);
1859 	info->client = seq->client;
1860 	info->type = USER_CLIENT;
1861 	return seq->ops->set_client_info(seq, info);
1862 }
1863 
1864 /**
1865  * \brief query the next client
1866  * \param seq sequencer handle
1867  * \param info query pattern and result
1868  *
1869  * Queries the next client.
1870  * The search begins at the client with an id one greater than
1871  * client field in info.
1872  * If a client is found, its attributes are stored in info,
1873  * and zero is returned.
1874  * Otherwise returns a negative error code.
1875  *
1876  * \sa snd_seq_get_any_client_info()
1877  */
snd_seq_query_next_client(snd_seq_t * seq,snd_seq_client_info_t * info)1878 int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
1879 {
1880 	assert(seq && info);
1881 	return seq->ops->query_next_client(seq, info);
1882 }
1883 
1884 
1885 /*----------------------------------------------------------------*/
1886 
1887 
1888 /*
1889  * Port
1890  */
1891 
1892 /**
1893  * \brief get size of #snd_seq_port_info_t
1894  * \return size in bytes
1895  */
snd_seq_port_info_sizeof()1896 size_t snd_seq_port_info_sizeof()
1897 {
1898 	return sizeof(snd_seq_port_info_t);
1899 }
1900 
1901 /**
1902  * \brief allocate an empty #snd_seq_port_info_t using standard malloc
1903  * \param ptr returned pointer
1904  * \return 0 on success otherwise negative error code
1905  */
snd_seq_port_info_malloc(snd_seq_port_info_t ** ptr)1906 int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
1907 {
1908 	assert(ptr);
1909 	*ptr = calloc(1, sizeof(snd_seq_port_info_t));
1910 	if (!*ptr)
1911 		return -ENOMEM;
1912 	return 0;
1913 }
1914 
1915 /**
1916  * \brief frees a previously allocated #snd_seq_port_info_t
1917  * \param obj pointer to object to free
1918  */
snd_seq_port_info_free(snd_seq_port_info_t * obj)1919 void snd_seq_port_info_free(snd_seq_port_info_t *obj)
1920 {
1921 	free(obj);
1922 }
1923 
1924 /**
1925  * \brief copy one #snd_seq_port_info_t to another
1926  * \param dst pointer to destination
1927  * \param src pointer to source
1928  */
snd_seq_port_info_copy(snd_seq_port_info_t * dst,const snd_seq_port_info_t * src)1929 void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
1930 {
1931 	assert(dst && src);
1932 	*dst = *src;
1933 }
1934 
1935 
1936 /**
1937  * \brief Get client id of a port_info container
1938  * \param info port_info container
1939  * \return client id
1940  *
1941  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
1942  */
snd_seq_port_info_get_client(const snd_seq_port_info_t * info)1943 int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
1944 {
1945 	assert(info);
1946 	return info->addr.client;
1947 }
1948 
1949 /**
1950  * \brief Get port id of a port_info container
1951  * \param info port_info container
1952  * \return port id
1953  *
1954  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
1955  */
snd_seq_port_info_get_port(const snd_seq_port_info_t * info)1956 int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
1957 {
1958 	assert(info);
1959 	return info->addr.port;
1960 }
1961 
1962 /**
1963  * \brief Get client/port address of a port_info container
1964  * \param info port_info container
1965  * \return client/port address pointer
1966  *
1967  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
1968  */
snd_seq_port_info_get_addr(const snd_seq_port_info_t * info)1969 const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
1970 {
1971 	assert(info);
1972 	return (const snd_seq_addr_t *) &info->addr;
1973 }
1974 
1975 /**
1976  * \brief Get the name of a port_info container
1977  * \param info port_info container
1978  * \return name string
1979  *
1980  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
1981  */
snd_seq_port_info_get_name(const snd_seq_port_info_t * info)1982 const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
1983 {
1984 	assert(info);
1985 	return info->name;
1986 }
1987 
1988 /**
1989  * \brief Get the capability bits of a port_info container
1990  * \param info port_info container
1991  * \return capability bits
1992  *
1993  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
1994  */
snd_seq_port_info_get_capability(const snd_seq_port_info_t * info)1995 unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
1996 {
1997 	assert(info);
1998 	return info->capability;
1999 }
2000 
2001 /**
2002  * \brief Get the type bits of a port_info container
2003  * \param info port_info container
2004  * \return port type bits
2005  *
2006  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
2007  */
snd_seq_port_info_get_type(const snd_seq_port_info_t * info)2008 unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
2009 {
2010 	assert(info);
2011 	return info->type;
2012 }
2013 
2014 /**
2015  * \brief Get the number of read subscriptions of a port_info container
2016  * \param info port_info container
2017  * \return number of read subscriptions
2018  *
2019  * \sa snd_seq_get_port_info()
2020  */
snd_seq_port_info_get_read_use(const snd_seq_port_info_t * info)2021 int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
2022 {
2023 	assert(info);
2024 	return info->read_use;
2025 }
2026 
2027 /**
2028  * \brief Get the number of write subscriptions of a port_info container
2029  * \param info port_info container
2030  * \return number of write subscriptions
2031  *
2032  * \sa snd_seq_get_port_info()
2033  */
snd_seq_port_info_get_write_use(const snd_seq_port_info_t * info)2034 int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
2035 {
2036 	assert(info);
2037 	return info->write_use;
2038 }
2039 
2040 /**
2041  * \brief Get the midi channels of a port_info container
2042  * \param info port_info container
2043  * \return number of midi channels (default 0)
2044  *
2045  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
2046  */
snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t * info)2047 int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
2048 {
2049 	assert(info);
2050 	return info->midi_channels;
2051 }
2052 
2053 /**
2054  * \brief Get the midi voices of a port_info container
2055  * \param info port_info container
2056  * \return number of midi voices (default 0)
2057  *
2058  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
2059  */
snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t * info)2060 int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
2061 {
2062 	assert(info);
2063 	return info->midi_voices;
2064 }
2065 
2066 /**
2067  * \brief Get the synth voices of a port_info container
2068  * \param info port_info container
2069  * \return number of synth voices (default 0)
2070  *
2071  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
2072  */
snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t * info)2073 int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
2074 {
2075 	assert(info);
2076 	return info->synth_voices;
2077 }
2078 
2079 /**
2080  * \brief Get the port-specified mode of a port_info container
2081  * \param info port_info container
2082  * \return 1 if port id is specified at creation
2083  *
2084  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
2085  */
snd_seq_port_info_get_port_specified(const snd_seq_port_info_t * info)2086 int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
2087 {
2088 	assert(info);
2089 	return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
2090 }
2091 
2092 /**
2093  * \brief Get the time-stamping mode of the given port in a port_info container
2094  * \param info port_info container
2095  * \return 1 if the port updates timestamps of incoming events
2096  *
2097  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
2098  */
snd_seq_port_info_get_timestamping(const snd_seq_port_info_t * info)2099 int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
2100 {
2101 	assert(info);
2102 	return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
2103 }
2104 
2105 /**
2106  * \brief Get whether the time-stamping of the given port is real-time mode
2107  * \param info port_info container
2108  * \return 1 if the time-stamping is in the real-time mode
2109  *
2110  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
2111  */
snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t * info)2112 int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
2113 {
2114 	assert(info);
2115 	return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
2116 }
2117 
2118 /**
2119  * \brief Get the queue id to update timestamps
2120  * \param info port_info container
2121  * \return the queue id to get the timestamps
2122  *
2123  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
2124  */
snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t * info)2125 int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
2126 {
2127 	assert(info);
2128 	return info->time_queue;
2129 }
2130 
2131 /**
2132  * \brief Set the client id of a port_info container
2133  * \param info port_info container
2134  * \param client client id
2135  *
2136  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
2137  */
snd_seq_port_info_set_client(snd_seq_port_info_t * info,int client)2138 void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
2139 {
2140 	assert(info);
2141 	info->addr.client = client;
2142 }
2143 
2144 /**
2145  * \brief Set the port id of a port_info container
2146  * \param info port_info container
2147  * \param port port id
2148  *
2149  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
2150  */
snd_seq_port_info_set_port(snd_seq_port_info_t * info,int port)2151 void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
2152 {
2153 	assert(info);
2154 	info->addr.port = port;
2155 }
2156 
2157 /**
2158  * \brief Set the client/port address of a port_info container
2159  * \param info port_info container
2160  * \param addr client/port address
2161  *
2162  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
2163  */
snd_seq_port_info_set_addr(snd_seq_port_info_t * info,const snd_seq_addr_t * addr)2164 void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
2165 {
2166 	assert(info);
2167 	info->addr = *(const struct sndrv_seq_addr *)addr;
2168 }
2169 
2170 /**
2171  * \brief Set the name of a port_info container
2172  * \param info port_info container
2173  * \param name name string
2174  *
2175  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
2176  */
snd_seq_port_info_set_name(snd_seq_port_info_t * info,const char * name)2177 void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
2178 {
2179 	assert(info && name);
2180 	snd_strlcpy(info->name, name, sizeof(info->name));
2181 }
2182 
2183 /**
2184  * \brief set the capability bits of a port_info container
2185  * \param info port_info container
2186  * \param capability capability bits
2187  *
2188  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
2189  */
snd_seq_port_info_set_capability(snd_seq_port_info_t * info,unsigned int capability)2190 void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
2191 {
2192 	assert(info);
2193 	info->capability = capability;
2194 }
2195 
2196 /**
2197  * \brief Get the type bits of a port_info container
2198  * \param info port_info container
2199  * \param type port type bits
2200  *
2201  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
2202  */
snd_seq_port_info_set_type(snd_seq_port_info_t * info,unsigned int type)2203 void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
2204 {
2205 	assert(info);
2206 	info->type = type;
2207 }
2208 
2209 /**
2210  * \brief set the midi channels of a port_info container
2211  * \param info port_info container
2212  * \param channels midi channels (default 0)
2213  *
2214  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
2215  */
snd_seq_port_info_set_midi_channels(snd_seq_port_info_t * info,int channels)2216 void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
2217 {
2218 	assert(info);
2219 	info->midi_channels = channels;
2220 }
2221 
2222 /**
2223  * \brief set the midi voices of a port_info container
2224  * \param info port_info container
2225  * \param voices midi voices (default 0)
2226  *
2227  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
2228  */
snd_seq_port_info_set_midi_voices(snd_seq_port_info_t * info,int voices)2229 void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
2230 {
2231 	assert(info);
2232 	info->midi_voices = voices;
2233 }
2234 
2235 /**
2236  * \brief set the synth voices of a port_info container
2237  * \param info port_info container
2238  * \param voices synth voices (default 0)
2239  *
2240  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
2241  */
snd_seq_port_info_set_synth_voices(snd_seq_port_info_t * info,int voices)2242 void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
2243 {
2244 	assert(info);
2245 	info->synth_voices = voices;
2246 }
2247 
2248 /**
2249  * \brief Set the port-specified mode of a port_info container
2250  * \param info port_info container
2251  * \param val non-zero if specifying the port id at creation
2252  *
2253  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
2254  */
snd_seq_port_info_set_port_specified(snd_seq_port_info_t * info,int val)2255 void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
2256 {
2257 	assert(info);
2258 	if (val)
2259 		info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2260 	else
2261 		info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2262 }
2263 
2264 /**
2265  * \brief Set the time-stamping mode of the given port
2266  * \param info port_info container
2267  * \param enable non-zero if updating the timestamps of incoming events
2268  *
2269  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
2270  */
snd_seq_port_info_set_timestamping(snd_seq_port_info_t * info,int enable)2271 void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
2272 {
2273 	assert(info);
2274 	if (enable)
2275 		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2276 	else
2277 		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2278 }
2279 
2280 /**
2281  * \brief Set whether the timestime is updated in the real-time mode
2282  * \param info port_info container
2283  * \param enable non-zero if updating the timestamps in real-time mode
2284  *
2285  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
2286  */
snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t * info,int enable)2287 void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
2288 {
2289 	assert(info);
2290 	if (enable)
2291 		info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
2292 	else
2293 		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
2294 }
2295 
2296 /**
2297  * \brief Set the queue id for timestamping
2298  * \param info port_info container
2299  * \param queue the queue id to get timestamps
2300  *
2301  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
2302  */
snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t * info,int queue)2303 void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
2304 {
2305 	assert(info);
2306 	info->time_queue = queue;
2307 }
2308 
2309 
2310 /**
2311  * \brief create a sequencer port on the current client
2312  * \param seq sequencer handle
2313  * \param port port information for the new port
2314  * \return 0 on success otherwise a negative error code
2315  *
2316  * Creates a sequencer port on the current client.
2317  * The attributes of created port is specified in \a info argument.
2318  *
2319  * The client field in \a info argument is overwritten with the current client id.
2320  * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
2321  * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
2322  *
2323  * Each port has the capability bit-masks to specify the access capability
2324  * of the port from other clients.
2325  * The capability bit flags are defined as follows:
2326  * - #SND_SEQ_PORT_CAP_READ Readable from this port
2327  * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
2328  * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
2329  * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
2330  * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
2331  * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
2332  * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
2333  * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
2334  *
2335  * Each port has also the type bitmasks defined as follows:
2336  * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
2337  * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
2338  * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
2339  * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
2340  * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
2341  * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
2342  * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
2343  * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
2344  * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
2345  * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
2346  * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
2347  * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
2348  *
2349  * A port may contain specific midi channels, midi voices and synth voices.
2350  * These values could be zero as default.
2351  *
2352  * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
2353  *     snd_seq_create_simple_port()
2354  */
snd_seq_create_port(snd_seq_t * seq,snd_seq_port_info_t * port)2355 int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
2356 {
2357 	assert(seq && port);
2358 	port->addr.client = seq->client;
2359 	return seq->ops->create_port(seq, port);
2360 }
2361 
2362 /**
2363  * \brief delete a sequencer port on the current client
2364  * \param seq sequencer handle
2365  * \param port port to be deleted
2366  * \return 0 on success otherwise a negative error code
2367  *
2368  * Deletes the existing sequencer port on the current client.
2369  *
2370  * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
2371  */
snd_seq_delete_port(snd_seq_t * seq,int port)2372 int snd_seq_delete_port(snd_seq_t *seq, int port)
2373 {
2374 	snd_seq_port_info_t pinfo;
2375 	assert(seq);
2376 	memset(&pinfo, 0, sizeof(pinfo));
2377 	pinfo.addr.client = seq->client;
2378 	pinfo.addr.port = port;
2379 	return seq->ops->delete_port(seq, &pinfo);
2380 }
2381 
2382 /**
2383  * \brief obtain the information of a port on an arbitrary client
2384  * \param seq sequencer handle
2385  * \param client client id to get
2386  * \param port port id to get
2387  * \param info pointer information returns
2388  * \return 0 on success otherwise a negative error code
2389  *
2390  * \sa snd_seq_get_port_info()
2391  */
snd_seq_get_any_port_info(snd_seq_t * seq,int client,int port,snd_seq_port_info_t * info)2392 int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
2393 {
2394 	assert(seq && info && client >= 0 && port >= 0);
2395 	memset(info, 0, sizeof(snd_seq_port_info_t));
2396 	info->addr.client = client;
2397 	info->addr.port = port;
2398 	return seq->ops->get_port_info(seq, info);
2399 }
2400 
2401 /**
2402  * \brief obtain the information of a port on the current client
2403  * \param seq sequencer handle
2404  * \param port port id to get
2405  * \param info pointer information returns
2406  * \return 0 on success otherwise a negative error code
2407  *
2408  * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
2409  *     snd_seq_query_next_port()
2410  */
snd_seq_get_port_info(snd_seq_t * seq,int port,snd_seq_port_info_t * info)2411 int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2412 {
2413 	return snd_seq_get_any_port_info(seq, seq->client, port, info);
2414 }
2415 
2416 /**
2417  * \brief set the information of a port on the current client
2418  * \param seq sequencer handle
2419  * \param port port to be set
2420  * \param info port information to be set
2421  * \return 0 on success otherwise a negative error code
2422  *
2423  * \sa snd_seq_set_port_info()
2424  */
snd_seq_set_port_info(snd_seq_t * seq,int port,snd_seq_port_info_t * info)2425 int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2426 {
2427 	assert(seq && info && port >= 0);
2428 	info->addr.client = seq->client;
2429 	info->addr.port = port;
2430 	return seq->ops->set_port_info(seq, info);
2431 }
2432 
2433 /**
2434  * \brief query the next matching port
2435  * \param seq sequencer handle
2436  * \param info query pattern and result
2437 
2438  * Queries the next matching port on the client specified in
2439  * \a info argument.
2440  * The search begins at the next port specified in
2441  * port field of \a info argument.
2442  * For finding the first port at a certain client, give -1.
2443  *
2444  * If a matching port is found, its attributes are stored on
2445  * \a info and function returns zero.
2446  * Otherwise, a negative error code is returned.
2447  *
2448  * \sa snd_seq_get_port_info()
2449  */
snd_seq_query_next_port(snd_seq_t * seq,snd_seq_port_info_t * info)2450 int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
2451 {
2452 	assert(seq && info);
2453 	return seq->ops->query_next_port(seq, info);
2454 }
2455 
2456 
2457 /*----------------------------------------------------------------*/
2458 
2459 /*
2460  * subscription
2461  */
2462 
2463 
2464 /**
2465  * \brief get size of #snd_seq_port_subscribe_t
2466  * \return size in bytes
2467  */
snd_seq_port_subscribe_sizeof()2468 size_t snd_seq_port_subscribe_sizeof()
2469 {
2470 	return sizeof(snd_seq_port_subscribe_t);
2471 }
2472 
2473 /**
2474  * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
2475  * \param ptr returned pointer
2476  * \return 0 on success otherwise negative error code
2477  */
snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t ** ptr)2478 int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
2479 {
2480 	assert(ptr);
2481 	*ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
2482 	if (!*ptr)
2483 		return -ENOMEM;
2484 	return 0;
2485 }
2486 
2487 /**
2488  * \brief frees a previously allocated #snd_seq_port_subscribe_t
2489  * \param obj pointer to object to free
2490  */
snd_seq_port_subscribe_free(snd_seq_port_subscribe_t * obj)2491 void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
2492 {
2493 	free(obj);
2494 }
2495 
2496 /**
2497  * \brief copy one #snd_seq_port_subscribe_t to another
2498  * \param dst pointer to destination
2499  * \param src pointer to source
2500  */
snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t * dst,const snd_seq_port_subscribe_t * src)2501 void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
2502 {
2503 	assert(dst && src);
2504 	*dst = *src;
2505 }
2506 
2507 
2508 /**
2509  * \brief Get sender address of a port_subscribe container
2510  * \param info port_subscribe container
2511  *
2512  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
2513  */
snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t * info)2514 const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
2515 {
2516 	assert(info);
2517 	return (const snd_seq_addr_t *)&info->sender;
2518 }
2519 
2520 /**
2521  * \brief Get destination address of a port_subscribe container
2522  * \param info port_subscribe container
2523  *
2524  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
2525  */
snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t * info)2526 const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
2527 {
2528 	assert(info);
2529 	return (const snd_seq_addr_t *)&info->dest;
2530 }
2531 
2532 /**
2533  * \brief Get the queue id of a port_subscribe container
2534  * \param info port_subscribe container
2535  * \return queue id
2536  *
2537  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
2538  */
snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t * info)2539 int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
2540 {
2541 	assert(info);
2542 	return info->queue;
2543 }
2544 
2545 /**
2546  * \brief Get the exclusive mode of a port_subscribe container
2547  * \param info port_subscribe container
2548  * \return 1 if exclusive mode
2549  *
2550  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
2551  */
snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t * info)2552 int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
2553 {
2554 	assert(info);
2555 	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2556 }
2557 
2558 /**
2559  * \brief Get the time-update mode of a port_subscribe container
2560  * \param info port_subscribe container
2561  * \return 1 if update timestamp
2562  *
2563  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
2564  */
snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t * info)2565 int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
2566 {
2567 	assert(info);
2568 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2569 }
2570 
2571 /**
2572  * \brief Get the real-time update mode of a port_subscribe container
2573  * \param info port_subscribe container
2574  * \return 1 if real-time update mode
2575  *
2576  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
2577  */
snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t * info)2578 int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
2579 {
2580 	assert(info);
2581 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
2582 }
2583 
2584 /**
2585  * \brief Set sender address of a port_subscribe container
2586  * \param info port_subscribe container
2587  * \param addr sender address
2588  *
2589  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
2590  */
snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t * info,const snd_seq_addr_t * addr)2591 void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2592 {
2593 	assert(info);
2594 	memcpy(&info->sender, addr, sizeof(*addr));
2595 }
2596 
2597 /**
2598  * \brief Set destination address of a port_subscribe container
2599  * \param info port_subscribe container
2600  * \param addr destination address
2601  *
2602  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
2603  */
snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t * info,const snd_seq_addr_t * addr)2604 void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2605 {
2606 	assert(info);
2607 	memcpy(&info->dest, addr, sizeof(*addr));
2608 }
2609 
2610 /**
2611  * \brief Set the queue id of a port_subscribe container
2612  * \param info port_subscribe container
2613  * \param q queue id
2614  *
2615  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
2616  */
snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t * info,int q)2617 void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
2618 {
2619 	assert(info);
2620 	info->queue = q;
2621 }
2622 
2623 /**
2624  * \brief Set the exclusive mode of a port_subscribe container
2625  * \param info port_subscribe container
2626  * \param val non-zero to enable
2627  *
2628  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
2629  */
snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t * info,int val)2630 void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
2631 {
2632 	assert(info);
2633 	if (val)
2634 		info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2635 	else
2636 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2637 }
2638 
2639 /**
2640  * \brief Set the time-update mode of a port_subscribe container
2641  * \param info port_subscribe container
2642  * \param val non-zero to enable
2643  *
2644  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
2645  */
snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t * info,int val)2646 void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
2647 {
2648 	assert(info);
2649 	if (val)
2650 		info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2651 	else
2652 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2653 }
2654 
2655 /**
2656  * \brief Set the real-time mode of a port_subscribe container
2657  * \param info port_subscribe container
2658  * \param val non-zero to enable
2659  *
2660  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
2661  */
snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t * info,int val)2662 void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
2663 {
2664 	assert(info);
2665 	if (val)
2666 		info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2667 	else
2668 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2669 }
2670 
2671 
2672 /**
2673  * \brief obtain subscription information
2674  * \param seq sequencer handle
2675  * \param sub pointer to return the subscription information
2676  * \return 0 on success otherwise a negative error code
2677  *
2678  * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
2679  */
snd_seq_get_port_subscription(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2680 int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2681 {
2682 	assert(seq && sub);
2683 	return seq->ops->get_port_subscription(seq, sub);
2684 }
2685 
2686 /**
2687  * \brief subscribe a port connection
2688  * \param seq sequencer handle
2689  * \param sub subscription information
2690  * \return 0 on success otherwise a negative error code
2691  *
2692  * Subscribes a connection between two ports.
2693  * The subscription information is stored in sub argument.
2694  *
2695  * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
2696  *     snd_seq_connect_from(), snd_seq_connect_to()
2697  */
snd_seq_subscribe_port(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2698 int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2699 {
2700 	assert(seq && sub);
2701 	return seq->ops->subscribe_port(seq, sub);
2702 }
2703 
2704 /**
2705  * \brief unsubscribe a connection between ports
2706  * \param seq sequencer handle
2707  * \param sub subscription information to disconnect
2708  * \return 0 on success otherwise a negative error code
2709  *
2710  * Unsubscribes a connection between two ports,
2711  * described in sender and dest fields in sub argument.
2712  *
2713  * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
2714  */
snd_seq_unsubscribe_port(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2715 int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2716 {
2717 	assert(seq && sub);
2718 	return seq->ops->unsubscribe_port(seq, sub);
2719 }
2720 
2721 
2722 /**
2723  * \brief get size of #snd_seq_query_subscribe_t
2724  * \return size in bytes
2725  */
snd_seq_query_subscribe_sizeof()2726 size_t snd_seq_query_subscribe_sizeof()
2727 {
2728 	return sizeof(snd_seq_query_subscribe_t);
2729 }
2730 
2731 /**
2732  * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
2733  * \param ptr returned pointer
2734  * \return 0 on success otherwise negative error code
2735  */
snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t ** ptr)2736 int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
2737 {
2738 	assert(ptr);
2739 	*ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
2740 	if (!*ptr)
2741 		return -ENOMEM;
2742 	return 0;
2743 }
2744 
2745 /**
2746  * \brief frees a previously allocated #snd_seq_query_subscribe_t
2747  * \param obj pointer to object to free
2748  */
snd_seq_query_subscribe_free(snd_seq_query_subscribe_t * obj)2749 void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
2750 {
2751 	free(obj);
2752 }
2753 
2754 /**
2755  * \brief copy one #snd_seq_query_subscribe_t to another
2756  * \param dst pointer to destination
2757  * \param src pointer to source
2758  */
snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t * dst,const snd_seq_query_subscribe_t * src)2759 void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
2760 {
2761 	assert(dst && src);
2762 	*dst = *src;
2763 }
2764 
2765 
2766 /**
2767  * \brief Get the client id of a query_subscribe container
2768  * \param info query_subscribe container
2769  * \return client id
2770  *
2771  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
2772  */
snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t * info)2773 int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
2774 {
2775 	assert(info);
2776 	return info->root.client;
2777 }
2778 
2779 /**
2780  * \brief Get the port id of a query_subscribe container
2781  * \param info query_subscribe container
2782  * \return port id
2783  *
2784  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
2785  */
snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t * info)2786 int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
2787 {
2788 	assert(info);
2789 	return info->root.port;
2790 }
2791 
2792 /**
2793  * \brief Get the client/port address of a query_subscribe container
2794  * \param info query_subscribe container
2795  * \return client/port address pointer
2796  *
2797  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
2798  */
snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t * info)2799 const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
2800 {
2801 	assert(info);
2802 	return (const snd_seq_addr_t *)&info->root;
2803 }
2804 
2805 /**
2806  * \brief Get the query type of a query_subscribe container
2807  * \param info query_subscribe container
2808  * \return query type
2809  *
2810  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
2811  */
snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t * info)2812 snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
2813 {
2814 	assert(info);
2815 	return info->type;
2816 }
2817 
2818 /**
2819  * \brief Get the index of subscriber of a query_subscribe container
2820  * \param info query_subscribe container
2821  * \return subscriber's index
2822  *
2823  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
2824  */
snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t * info)2825 int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
2826 {
2827 	assert(info);
2828 	return info->index;
2829 }
2830 
2831 /**
2832  * \brief Get the number of subscriptions of a query_subscribe container
2833  * \param info query_subscribe container
2834  * \return number of subscriptions
2835  *
2836  * \sa snd_seq_query_port_subscribers()
2837  */
snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t * info)2838 int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
2839 {
2840 	assert(info);
2841 	return info->num_subs;
2842 }
2843 
2844 /**
2845  * \brief Get the address of subscriber of a query_subscribe container
2846  * \param info query_subscribe container
2847  * \return subscriber's address pointer
2848  *
2849  * \sa snd_seq_query_port_subscribers()
2850  */
snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t * info)2851 const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
2852 {
2853 	assert(info);
2854 	return (const snd_seq_addr_t *)&info->addr;
2855 }
2856 
2857 /**
2858  * \brief Get the queue id of subscriber of a query_subscribe container
2859  * \param info query_subscribe container
2860  * \return subscriber's queue id
2861  *
2862  * \sa snd_seq_query_port_subscribers()
2863  */
snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t * info)2864 int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
2865 {
2866 	assert(info);
2867 	return info->queue;
2868 }
2869 
2870 /**
2871  * \brief Get the exclusive mode of a query_subscribe container
2872  * \param info query_subscribe container
2873  * \return 1 if exclusive mode
2874  *
2875  * \sa snd_seq_query_port_subscribers()
2876  */
snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t * info)2877 int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
2878 {
2879 	assert(info);
2880 	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2881 }
2882 
2883 /**
2884  * \brief Get the time-update mode of a query_subscribe container
2885  * \param info query_subscribe container
2886  * \return 1 if update timestamp
2887  *
2888  * \sa snd_seq_query_port_subscribers()
2889  */
snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t * info)2890 int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
2891 {
2892 	assert(info);
2893 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2894 }
2895 
2896 /**
2897  * \brief Get the real-time update mode of a query_subscribe container
2898  * \param info query_subscribe container
2899  * \return 1 if real-time update mode
2900  *
2901  * \sa snd_seq_query_port_subscribers()
2902  */
snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t * info)2903 int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
2904 {
2905 	assert(info);
2906 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2907 }
2908 
2909 /**
2910  * \brief Set the client id of a query_subscribe container
2911  * \param info query_subscribe container
2912  * \param client client id
2913  *
2914  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
2915  */
snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t * info,int client)2916 void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
2917 {
2918 	assert(info);
2919 	info->root.client = client;
2920 }
2921 
2922 /**
2923  * \brief Set the port id of a query_subscribe container
2924  * \param info query_subscribe container
2925  * \param port port id
2926  *
2927  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
2928  */
snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t * info,int port)2929 void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
2930 {
2931 	assert(info);
2932 	info->root.port = port;
2933 }
2934 
2935 /**
2936  * \brief Set the client/port address of a query_subscribe container
2937  * \param info query_subscribe container
2938  * \param addr client/port address pointer
2939  *
2940  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
2941  */
snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t * info,const snd_seq_addr_t * addr)2942 void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
2943 {
2944 	assert(info);
2945 	info->root = *(const struct snd_seq_addr *)addr;
2946 }
2947 
2948 /**
2949  * \brief Set the query type of a query_subscribe container
2950  * \param info query_subscribe container
2951  * \param type query type
2952  *
2953  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
2954  */
snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t * info,snd_seq_query_subs_type_t type)2955 void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
2956 {
2957 	assert(info);
2958 	info->type = type;
2959 }
2960 
2961 /**
2962  * \brief Set the subscriber's index to be queried
2963  * \param info query_subscribe container
2964  * \param index index to be queried
2965  *
2966  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
2967  */
snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t * info,int index)2968 void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
2969 {
2970 	assert(info);
2971 	info->index = index;
2972 }
2973 
2974 
2975 /**
2976  * \brief query port subscriber list
2977  * \param seq sequencer handle
2978  * \param subs subscription to query
2979  * \return 0 on success otherwise a negative error code
2980  *
2981  * Queries the subscribers accessing to a port.
2982  * The query information is specified in subs argument.
2983  *
2984  * At least, the client id, the port id, the index number and
2985  * the query type must be set to perform a proper query.
2986  * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
2987  * can be specified to check whether the readers or the writers to the port.
2988  * To query the first subscription, set 0 to the index number.  To list up
2989  * all the subscriptions, call this function with the index numbers from 0
2990  * until this returns a negative value.
2991  *
2992  * \sa snd_seq_get_port_subscription()
2993  */
snd_seq_query_port_subscribers(snd_seq_t * seq,snd_seq_query_subscribe_t * subs)2994 int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
2995 {
2996 	assert(seq && subs);
2997 	return seq->ops->query_port_subscribers(seq, subs);
2998 }
2999 
3000 /*----------------------------------------------------------------*/
3001 
3002 /*
3003  * queue handlers
3004  */
3005 
3006 /**
3007  * \brief get size of #snd_seq_queue_info_t
3008  * \return size in bytes
3009  */
snd_seq_queue_info_sizeof()3010 size_t snd_seq_queue_info_sizeof()
3011 {
3012 	return sizeof(snd_seq_queue_info_t);
3013 }
3014 
3015 /**
3016  * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
3017  * \param ptr returned pointer
3018  * \return 0 on success otherwise negative error code
3019  */
snd_seq_queue_info_malloc(snd_seq_queue_info_t ** ptr)3020 int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
3021 {
3022 	assert(ptr);
3023 	*ptr = calloc(1, sizeof(snd_seq_queue_info_t));
3024 	if (!*ptr)
3025 		return -ENOMEM;
3026 	return 0;
3027 }
3028 
3029 /**
3030  * \brief frees a previously allocated #snd_seq_queue_info_t
3031  * \param obj pointer to object to free
3032  */
snd_seq_queue_info_free(snd_seq_queue_info_t * obj)3033 void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
3034 {
3035 	free(obj);
3036 }
3037 
3038 /**
3039  * \brief copy one #snd_seq_queue_info_t to another
3040  * \param dst pointer to destination
3041  * \param src pointer to source
3042  */
snd_seq_queue_info_copy(snd_seq_queue_info_t * dst,const snd_seq_queue_info_t * src)3043 void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
3044 {
3045 	assert(dst && src);
3046 	*dst = *src;
3047 }
3048 
3049 
3050 /**
3051  * \brief Get the queue id of a queue_info container
3052  * \param info queue_info container
3053  * \return queue id
3054  *
3055  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
3056  */
snd_seq_queue_info_get_queue(const snd_seq_queue_info_t * info)3057 int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
3058 {
3059 	assert(info);
3060 	return info->queue;
3061 }
3062 
3063 /**
3064  * \brief Get the name of a queue_info container
3065  * \param info queue_info container
3066  * \return name string
3067  *
3068  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
3069  */
snd_seq_queue_info_get_name(const snd_seq_queue_info_t * info)3070 const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
3071 {
3072 	assert(info);
3073 	return info->name;
3074 }
3075 
3076 /**
3077  * \brief Get the owner client id of a queue_info container
3078  * \param info queue_info container
3079  * \return owner client id
3080  *
3081  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
3082  */
snd_seq_queue_info_get_owner(const snd_seq_queue_info_t * info)3083 int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
3084 {
3085 	assert(info);
3086 	return info->owner;
3087 }
3088 
3089 /**
3090  * \brief Get the lock status of a queue_info container
3091  * \param info queue_info container
3092  * \return lock status --- non-zero = locked
3093  *
3094  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
3095  */
snd_seq_queue_info_get_locked(const snd_seq_queue_info_t * info)3096 int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
3097 {
3098 	assert(info);
3099 	return info->locked;
3100 }
3101 
3102 /**
3103  * \brief Get the conditional bit flags of a queue_info container
3104  * \param info queue_info container
3105  * \return conditional bit flags
3106  *
3107  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
3108  */
snd_seq_queue_info_get_flags(const snd_seq_queue_info_t * info)3109 unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
3110 {
3111 	assert(info);
3112 	return info->flags;
3113 }
3114 
3115 /**
3116  * \brief Set the name of a queue_info container
3117  * \param info queue_info container
3118  * \param name name string
3119  *
3120  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
3121  */
snd_seq_queue_info_set_name(snd_seq_queue_info_t * info,const char * name)3122 void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
3123 {
3124 	assert(info && name);
3125 	snd_strlcpy(info->name, name, sizeof(info->name));
3126 }
3127 
3128 /**
3129  * \brief Set the owner client id of a queue_info container
3130  * \param info queue_info container
3131  * \param owner client id
3132  *
3133  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
3134  */
snd_seq_queue_info_set_owner(snd_seq_queue_info_t * info,int owner)3135 void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
3136 {
3137 	assert(info);
3138 	info->owner = owner;
3139 }
3140 
3141 /**
3142  * \brief Set the lock status of a queue_info container
3143  * \param info queue_info container
3144  * \param locked lock status
3145  *
3146  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
3147  */
snd_seq_queue_info_set_locked(snd_seq_queue_info_t * info,int locked)3148 void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
3149 {
3150 	assert(info);
3151 	info->locked = locked;
3152 }
3153 
3154 /**
3155  * \brief Set the conditional bit flags of a queue_info container
3156  * \param info queue_info container
3157  * \param flags conditional bit flags
3158  *
3159  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
3160  */
snd_seq_queue_info_set_flags(snd_seq_queue_info_t * info,unsigned int flags)3161 void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
3162 {
3163 	assert(info);
3164 	info->flags = flags;
3165 }
3166 
3167 
3168 /**
3169  * \brief create a queue
3170  * \param seq sequencer handle
3171  * \param info queue information to initialize
3172  * \return the queue id (zero or positive) on success otherwise a negative error code
3173  *
3174  * \sa snd_seq_alloc_queue()
3175  */
snd_seq_create_queue(snd_seq_t * seq,snd_seq_queue_info_t * info)3176 int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
3177 {
3178 	int err;
3179 	assert(seq && info);
3180 	info->owner = seq->client;
3181 	err = seq->ops->create_queue(seq, info);
3182 	if (err < 0)
3183 		return err;
3184 	return info->queue;
3185 }
3186 
3187 /**
3188  * \brief allocate a queue with the specified name
3189  * \param seq sequencer handle
3190  * \param name the name of the new queue
3191  * \return the queue id (zero or positive) on success otherwise a negative error code
3192  *
3193  * \sa snd_seq_alloc_queue()
3194  */
snd_seq_alloc_named_queue(snd_seq_t * seq,const char * name)3195 int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
3196 {
3197 	snd_seq_queue_info_t info;
3198 	memset(&info, 0, sizeof(info));
3199 	info.locked = 1;
3200 	if (name)
3201 		snd_strlcpy(info.name, name, sizeof(info.name));
3202 	return snd_seq_create_queue(seq, &info);
3203 }
3204 
3205 /**
3206  * \brief allocate a queue
3207  * \param seq sequencer handle
3208  * \return the queue id (zero or positive) on success otherwise a negative error code
3209  *
3210  * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
3211  *     snd_seq_get_queue_info()
3212  */
snd_seq_alloc_queue(snd_seq_t * seq)3213 int snd_seq_alloc_queue(snd_seq_t *seq)
3214 {
3215 	return snd_seq_alloc_named_queue(seq, NULL);
3216 }
3217 
3218 /**
3219  * \brief delete the specified queue
3220  * \param seq sequencer handle
3221  * \param q queue id to delete
3222  * \return 0 on success otherwise a negative error code
3223  *
3224  * \sa snd_seq_alloc_queue()
3225  */
snd_seq_free_queue(snd_seq_t * seq,int q)3226 int snd_seq_free_queue(snd_seq_t *seq, int q)
3227 {
3228 	snd_seq_queue_info_t info;
3229 	assert(seq);
3230 	memset(&info, 0, sizeof(info));
3231 	info.queue = q;
3232 	return seq->ops->delete_queue(seq, &info);
3233 }
3234 
3235 /**
3236  * \brief obtain queue attributes
3237  * \param seq sequencer handle
3238  * \param q queue id to query
3239  * \param info information returned
3240  * \return 0 on success otherwise a negative error code
3241  *
3242  * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
3243  */
snd_seq_get_queue_info(snd_seq_t * seq,int q,snd_seq_queue_info_t * info)3244 int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3245 {
3246 	assert(seq && info);
3247 	info->queue = q;
3248 	return seq->ops->get_queue_info(seq, info);
3249 }
3250 
3251 /**
3252  * \brief change the queue attributes
3253  * \param seq sequencer handle
3254  * \param q queue id to change
3255  * \param info information changed
3256  * \return 0 on success otherwise a negative error code
3257  *
3258  * \sa snd_seq_get_queue_info()
3259  */
snd_seq_set_queue_info(snd_seq_t * seq,int q,snd_seq_queue_info_t * info)3260 int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3261 {
3262 	assert(seq && info);
3263 	info->queue = q;
3264 	return seq->ops->set_queue_info(seq, info);
3265 }
3266 
3267 /**
3268  * \brief query the matching queue with the specified name
3269  * \param seq sequencer handle
3270  * \param name the name string to query
3271  * \return the queue id if found or negative error code
3272  *
3273  * Searches the matching queue with the specified name string.
3274  *
3275  * \sa snd_seq_get_queue_info()
3276  */
snd_seq_query_named_queue(snd_seq_t * seq,const char * name)3277 int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
3278 {
3279 	int err;
3280 	snd_seq_queue_info_t info;
3281 	assert(seq && name);
3282 	snd_strlcpy(info.name, name, sizeof(info.name));
3283 	err = seq->ops->get_named_queue(seq, &info);
3284 	if (err < 0)
3285 		return err;
3286 	return info.queue;
3287 }
3288 
3289 /**
3290  * \brief Get the queue usage flag to the client
3291  * \param seq sequencer handle
3292  * \param q queue id
3293  * \return 1 = client is allowed to access the queue, 0 = not allowed,
3294  *     otherwise a negative error code
3295  *
3296  * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3297  */
snd_seq_get_queue_usage(snd_seq_t * seq,int q)3298 int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
3299 {
3300 	struct snd_seq_queue_client info;
3301 	int err;
3302 	assert(seq);
3303 	memset(&info, 0, sizeof(info));
3304 	info.queue = q;
3305 	info.client = seq->client;
3306 	if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
3307 		return err;
3308 	return info.used;
3309 }
3310 
3311 /**
3312  * \brief Set the queue usage flag to the client
3313  * \param seq sequencer handle
3314  * \param q queue id
3315  * \param used non-zero if the client is allowed
3316  * \return 0 on success otherwise a negative error code
3317  *
3318  * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3319  */
snd_seq_set_queue_usage(snd_seq_t * seq,int q,int used)3320 int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
3321 {
3322 	struct snd_seq_queue_client info;
3323 	assert(seq);
3324 	memset(&info, 0, sizeof(info));
3325 	info.queue = q;
3326 	info.client = seq->client;
3327 	info.used = used ? 1 : 0;
3328 	return seq->ops->set_queue_client(seq, &info);
3329 }
3330 
3331 
3332 /**
3333  * \brief get size of #snd_seq_queue_status_t
3334  * \return size in bytes
3335  */
snd_seq_queue_status_sizeof()3336 size_t snd_seq_queue_status_sizeof()
3337 {
3338 	return sizeof(snd_seq_queue_status_t);
3339 }
3340 
3341 /**
3342  * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
3343  * \param ptr returned pointer
3344  * \return 0 on success otherwise negative error code
3345  */
snd_seq_queue_status_malloc(snd_seq_queue_status_t ** ptr)3346 int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
3347 {
3348 	assert(ptr);
3349 	*ptr = calloc(1, sizeof(snd_seq_queue_status_t));
3350 	if (!*ptr)
3351 		return -ENOMEM;
3352 	return 0;
3353 }
3354 
3355 /**
3356  * \brief frees a previously allocated #snd_seq_queue_status_t
3357  * \param obj pointer to object to free
3358  */
snd_seq_queue_status_free(snd_seq_queue_status_t * obj)3359 void snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
3360 {
3361 	free(obj);
3362 }
3363 
3364 /**
3365  * \brief copy one #snd_seq_queue_status_t to another
3366  * \param dst pointer to destination
3367  * \param src pointer to source
3368  */
snd_seq_queue_status_copy(snd_seq_queue_status_t * dst,const snd_seq_queue_status_t * src)3369 void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
3370 {
3371 	assert(dst && src);
3372 	*dst = *src;
3373 }
3374 
3375 
3376 /**
3377  * \brief Get the queue id of a queue_status container
3378  * \param info queue_status container
3379  * \return queue id
3380  *
3381  * \sa snd_seq_get_queue_status()
3382  */
snd_seq_queue_status_get_queue(const snd_seq_queue_status_t * info)3383 int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
3384 {
3385 	assert(info);
3386 	return info->queue;
3387 }
3388 
3389 /**
3390  * \brief Get the number of events of a queue_status container
3391  * \param info queue_status container
3392  * \return number of events
3393  *
3394  * \sa snd_seq_get_queue_status()
3395  */
snd_seq_queue_status_get_events(const snd_seq_queue_status_t * info)3396 int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
3397 {
3398 	assert(info);
3399 	return info->events;
3400 }
3401 
3402 /**
3403  * \brief Get the tick time of a queue_status container
3404  * \param info queue_status container
3405  * \return tick time
3406  *
3407  * \sa snd_seq_get_queue_status()
3408  */
snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t * info)3409 snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
3410 {
3411 	assert(info);
3412 	return info->tick;
3413 }
3414 
3415 /**
3416  * \brief Get the real time of a queue_status container
3417  * \param info queue_status container
3418  *
3419  * \sa snd_seq_get_queue_status()
3420  */
snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t * info)3421 const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
3422 {
3423 	assert(info);
3424 	return (const snd_seq_real_time_t *)&info->time;
3425 }
3426 
3427 /**
3428  * \brief Get the running status bits of a queue_status container
3429  * \param info queue_status container
3430  * \return running status bits
3431  *
3432  * \sa snd_seq_get_queue_status()
3433  */
snd_seq_queue_status_get_status(const snd_seq_queue_status_t * info)3434 unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
3435 {
3436 	assert(info);
3437 	return info->running;
3438 }
3439 
3440 
3441 /**
3442  * \brief obtain the running state of the queue
3443  * \param seq sequencer handle
3444  * \param q queue id to query
3445  * \param status pointer to store the current status
3446  * \return 0 on success otherwise a negative error code
3447  *
3448  * Obtains the running state of the specified queue q.
3449  */
snd_seq_get_queue_status(snd_seq_t * seq,int q,snd_seq_queue_status_t * status)3450 int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
3451 {
3452 	assert(seq && status);
3453 	memset(status, 0, sizeof(snd_seq_queue_status_t));
3454 	status->queue = q;
3455 	return seq->ops->get_queue_status(seq, status);
3456 }
3457 
3458 
3459 /**
3460  * \brief get size of #snd_seq_queue_tempo_t
3461  * \return size in bytes
3462  */
snd_seq_queue_tempo_sizeof()3463 size_t snd_seq_queue_tempo_sizeof()
3464 {
3465 	return sizeof(snd_seq_queue_tempo_t);
3466 }
3467 
3468 /**
3469  * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
3470  * \param ptr returned pointer
3471  * \return 0 on success otherwise negative error code
3472  */
snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t ** ptr)3473 int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
3474 {
3475 	assert(ptr);
3476 	*ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
3477 	if (!*ptr)
3478 		return -ENOMEM;
3479 	return 0;
3480 }
3481 
3482 /**
3483  * \brief frees a previously allocated #snd_seq_queue_tempo_t
3484  * \param obj pointer to object to free
3485  */
snd_seq_queue_tempo_free(snd_seq_queue_tempo_t * obj)3486 void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
3487 {
3488 	free(obj);
3489 }
3490 
3491 /**
3492  * \brief copy one #snd_seq_queue_tempo_t to another
3493  * \param dst pointer to destination
3494  * \param src pointer to source
3495  */
snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t * dst,const snd_seq_queue_tempo_t * src)3496 void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
3497 {
3498 	assert(dst && src);
3499 	*dst = *src;
3500 }
3501 
3502 
3503 /**
3504  * \brief Get the queue id of a queue_status container
3505  * \param info queue_status container
3506  * \return queue id
3507  *
3508  * \sa snd_seq_get_queue_tempo()
3509  */
snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t * info)3510 int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
3511 {
3512 	assert(info);
3513 	return info->queue;
3514 }
3515 
3516 /**
3517  * \brief Get the tempo of a queue_status container
3518  * \param info queue_status container
3519  * \return tempo value
3520  *
3521  * \sa snd_seq_get_queue_tempo()
3522  */
snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t * info)3523 unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
3524 {
3525 	assert(info);
3526 	return info->tempo;
3527 }
3528 
3529 /**
3530  * \brief Get the ppq of a queue_status container
3531  * \param info queue_status container
3532  * \return ppq value
3533  *
3534  * \sa snd_seq_get_queue_tempo()
3535  */
snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t * info)3536 int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
3537 {
3538 	assert(info);
3539 	return info->ppq;
3540 }
3541 
3542 /**
3543  * \brief Get the timer skew value of a queue_status container
3544  * \param info queue_status container
3545  * \return timer skew value
3546  *
3547  * \sa snd_seq_get_queue_tempo()
3548  */
snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t * info)3549 unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info)
3550 {
3551 	assert(info);
3552 	return info->skew_value;
3553 }
3554 
3555 /**
3556  * \brief Get the timer skew base value of a queue_status container
3557  * \param info queue_status container
3558  * \return timer skew base value
3559  *
3560  * \sa snd_seq_get_queue_tempo()
3561  */
snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t * info)3562 unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info)
3563 {
3564 	assert(info);
3565 	return info->skew_base;
3566 }
3567 
3568 /**
3569  * \brief Set the tempo of a queue_status container
3570  * \param info queue_status container
3571  * \param tempo tempo value
3572  *
3573  * \sa snd_seq_get_queue_tempo()
3574  */
snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t * info,unsigned int tempo)3575 void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
3576 {
3577 	assert(info);
3578 	info->tempo = tempo;
3579 }
3580 
3581 /**
3582  * \brief Set the ppq of a queue_status container
3583  * \param info queue_status container
3584  * \param ppq ppq value
3585  *
3586  * \sa snd_seq_get_queue_tempo()
3587  */
snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t * info,int ppq)3588 void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
3589 {
3590 	assert(info);
3591 	info->ppq = ppq;
3592 }
3593 
3594 /**
3595  * \brief Set the timer skew value of a queue_status container
3596  * \param info queue_status container
3597  * \param skew timer skew value
3598  *
3599  * The skew of timer is calculated as skew / base.
3600  * For example, to play with double speed, pass base * 2 as the skew value.
3601  *
3602  * \sa snd_seq_get_queue_tempo()
3603  */
snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t * info,unsigned int skew)3604 void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew)
3605 {
3606 	assert(info);
3607 	info->skew_value = skew;
3608 }
3609 
3610 /**
3611  * \brief Set the timer skew base value of a queue_status container
3612  * \param info queue_status container
3613  * \param base timer skew base value
3614  *
3615  * \sa snd_seq_get_queue_tempo()
3616  */
snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t * info,unsigned int base)3617 void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base)
3618 {
3619 	assert(info);
3620 	info->skew_base = base;
3621 }
3622 
3623 /**
3624  * \brief obtain the current tempo of the queue
3625  * \param seq sequencer handle
3626  * \param q queue id to be queried
3627  * \param tempo pointer to store the current tempo
3628  * \return 0 on success otherwise a negative error code
3629  *
3630  * \sa snd_seq_set_queue_tempo()
3631  */
snd_seq_get_queue_tempo(snd_seq_t * seq,int q,snd_seq_queue_tempo_t * tempo)3632 int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3633 {
3634 	assert(seq && tempo);
3635 	memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
3636 	tempo->queue = q;
3637 	return seq->ops->get_queue_tempo(seq, tempo);
3638 }
3639 
3640 /**
3641  * \brief set the tempo of the queue
3642  * \param seq sequencer handle
3643  * \param q queue id to change the tempo
3644  * \param tempo tempo information
3645  * \return 0 on success otherwise a negative error code
3646  *
3647  * \sa snd_seq_get_queue_tempo()
3648  */
snd_seq_set_queue_tempo(snd_seq_t * seq,int q,snd_seq_queue_tempo_t * tempo)3649 int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3650 {
3651 	assert(seq && tempo);
3652 	tempo->queue = q;
3653 	return seq->ops->set_queue_tempo(seq, tempo);
3654 }
3655 
3656 
3657 /*----------------------------------------------------------------*/
3658 
3659 /**
3660  * \brief get size of #snd_seq_queue_timer_t
3661  * \return size in bytes
3662  */
snd_seq_queue_timer_sizeof()3663 size_t snd_seq_queue_timer_sizeof()
3664 {
3665 	return sizeof(snd_seq_queue_timer_t);
3666 }
3667 
3668 /**
3669  * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
3670  * \param ptr returned pointer
3671  * \return 0 on success otherwise negative error code
3672  */
snd_seq_queue_timer_malloc(snd_seq_queue_timer_t ** ptr)3673 int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
3674 {
3675 	assert(ptr);
3676 	*ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
3677 	if (!*ptr)
3678 		return -ENOMEM;
3679 	return 0;
3680 }
3681 
3682 /**
3683  * \brief frees a previously allocated #snd_seq_queue_timer_t
3684  * \param obj pointer to object to free
3685  */
snd_seq_queue_timer_free(snd_seq_queue_timer_t * obj)3686 void snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
3687 {
3688 	free(obj);
3689 }
3690 
3691 /**
3692  * \brief copy one #snd_seq_queue_timer_t to another
3693  * \param dst pointer to destination
3694  * \param src pointer to source
3695  */
snd_seq_queue_timer_copy(snd_seq_queue_timer_t * dst,const snd_seq_queue_timer_t * src)3696 void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
3697 {
3698 	assert(dst && src);
3699 	*dst = *src;
3700 }
3701 
3702 
3703 /**
3704  * \brief Get the queue id of a queue_timer container
3705  * \param info queue_timer container
3706  * \return queue id
3707  *
3708  * \sa snd_seq_get_queue_timer()
3709  */
snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t * info)3710 int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
3711 {
3712 	assert(info);
3713 	return info->queue;
3714 }
3715 
3716 /**
3717  * \brief Get the timer type of a queue_timer container
3718  * \param info queue_timer container
3719  * \return timer type
3720  *
3721  * \sa snd_seq_get_queue_timer()
3722  */
snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t * info)3723 snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
3724 {
3725 	assert(info);
3726 	return (snd_seq_queue_timer_type_t)info->type;
3727 }
3728 
3729 /**
3730  * \brief Get the timer id of a queue_timer container
3731  * \param info queue_timer container
3732  * \return timer id pointer
3733  *
3734  * \sa snd_seq_get_queue_timer()
3735  */
snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t * info)3736 const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
3737 {
3738 	assert(info);
3739 	return &info->u.alsa.id;
3740 }
3741 
3742 /**
3743  * \brief Get the timer resolution of a queue_timer container
3744  * \param info queue_timer container
3745  * \return timer resolution
3746  *
3747  * \sa snd_seq_get_queue_timer()
3748  */
snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t * info)3749 unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
3750 {
3751 	assert(info);
3752 	return info->u.alsa.resolution;
3753 }
3754 
3755 /**
3756  * \brief Set the timer type of a queue_timer container
3757  * \param info queue_timer container
3758  * \param type timer type
3759  *
3760  * \sa snd_seq_get_queue_timer()
3761  */
snd_seq_queue_timer_set_type(snd_seq_queue_timer_t * info,snd_seq_queue_timer_type_t type)3762 void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type)
3763 {
3764 	assert(info);
3765 	info->type = (int)type;
3766 }
3767 
3768 /**
3769  * \brief Set the timer id of a queue_timer container
3770  * \param info queue_timer container
3771  * \param id timer id pointer
3772  *
3773  * \sa snd_seq_get_queue_timer()
3774  */
snd_seq_queue_timer_set_id(snd_seq_queue_timer_t * info,const snd_timer_id_t * id)3775 void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
3776 {
3777 	assert(info && id);
3778 	info->u.alsa.id = *id;
3779 }
3780 
3781 /**
3782  * \brief Set the timer resolution of a queue_timer container
3783  * \param info queue_timer container
3784  * \param resolution timer resolution
3785  *
3786  * \sa snd_seq_get_queue_timer()
3787  */
snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t * info,unsigned int resolution)3788 void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
3789 {
3790 	assert(info);
3791 	info->u.alsa.resolution = resolution;
3792 }
3793 
3794 
3795 /**
3796  * \brief obtain the queue timer information
3797  * \param seq sequencer handle
3798  * \param q queue id to query
3799  * \param timer pointer to store the timer information
3800  * \return 0 on success otherwise a negative error code
3801  *
3802  * \sa snd_seq_set_queue_timer()
3803  */
snd_seq_get_queue_timer(snd_seq_t * seq,int q,snd_seq_queue_timer_t * timer)3804 int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3805 {
3806 	assert(seq && timer);
3807 	memset(timer, 0, sizeof(snd_seq_queue_timer_t));
3808 	timer->queue = q;
3809 	return seq->ops->get_queue_timer(seq, timer);
3810 }
3811 
3812 /**
3813  * \brief set the queue timer information
3814  * \param seq sequencer handle
3815  * \param q queue id to change the timer
3816  * \param timer timer information
3817  * \return 0 on success otherwise a negative error code
3818  *
3819  * \sa snd_seq_get_queue_timer()
3820  */
snd_seq_set_queue_timer(snd_seq_t * seq,int q,snd_seq_queue_timer_t * timer)3821 int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3822 {
3823 	assert(seq && timer);
3824 	timer->queue = q;
3825 	return seq->ops->set_queue_timer(seq, timer);
3826 }
3827 
3828 /*----------------------------------------------------------------*/
3829 
3830 #ifndef DOC_HIDDEN
3831 /**
3832  * \brief (DEPRECATED) create an event cell
3833  * \return the cell pointer allocated
3834  *
3835  * create an event cell via malloc.  the returned pointer must be released
3836  * by the application itself via normal free() call,
3837  * not via snd_seq_free_event().
3838  */
snd_seq_create_event(void)3839 snd_seq_event_t *snd_seq_create_event(void)
3840 {
3841 	return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
3842 }
3843 #endif
3844 
3845 /**
3846  * \brief (DEPRECATED) free an event
3847  *
3848  * In the former version, this function was used to
3849  * release the event pointer which was allocated by snd_seq_event_input().
3850  * In the current version, the event record is not allocated, so
3851  * you don't have to call this function any more.
3852  */
3853 #ifndef DOXYGEN
snd_seq_free_event(snd_seq_event_t * ev ATTRIBUTE_UNUSED)3854 int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
3855 #else
3856 int snd_seq_free_event(snd_seq_event_t *ev)
3857 #endif
3858 {
3859 	return 0;
3860 }
3861 
3862 /**
3863  * \brief calculates the (encoded) byte-stream size of the event
3864  * \param ev the event
3865  * \return the size of decoded bytes
3866  */
snd_seq_event_length(snd_seq_event_t * ev)3867 ssize_t snd_seq_event_length(snd_seq_event_t *ev)
3868 {
3869 	ssize_t len = sizeof(snd_seq_event_t);
3870 	assert(ev);
3871 	if (snd_seq_ev_is_variable(ev))
3872 		len += ev->data.ext.len;
3873 	return len;
3874 }
3875 
3876 /*----------------------------------------------------------------*/
3877 
3878 /*
3879  * output to sequencer
3880  */
3881 
3882 /**
3883  * \brief output an event
3884  * \param seq sequencer handle
3885  * \param ev event to be output
3886  * \return the number of remaining events or a negative error code
3887  *
3888  * An event is once expanded on the output buffer.
3889  * The output buffer will be drained automatically if it becomes full.
3890  *
3891  * If events remain unprocessed on output buffer before drained,
3892  * the size of total byte data on output buffer is returned.
3893  * If the output buffer is empty, this returns zero.
3894  *
3895  * \sa snd_seq_event_output_direct(), snd_seq_event_output_buffer(),
3896  *    snd_seq_event_output_pending(), snd_seq_drain_output(),
3897  *    snd_seq_drop_output(), snd_seq_extract_output(),
3898  *    snd_seq_remove_events()
3899  */
snd_seq_event_output(snd_seq_t * seq,snd_seq_event_t * ev)3900 int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
3901 {
3902 	int result;
3903 
3904 	result = snd_seq_event_output_buffer(seq, ev);
3905 	if (result == -EAGAIN) {
3906 		result = snd_seq_drain_output(seq);
3907 		if (result < 0)
3908 			return result;
3909 		return snd_seq_event_output_buffer(seq, ev);
3910 	}
3911 	return result;
3912 }
3913 
3914 /**
3915  * \brief output an event onto the lib buffer without draining buffer
3916  * \param seq sequencer handle
3917  * \param ev event to be output
3918  * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
3919  *
3920  * This function doesn't drain buffer unlike snd_seq_event_output().
3921  *
3922  * \sa snd_seq_event_output()
3923  */
snd_seq_event_output_buffer(snd_seq_t * seq,snd_seq_event_t * ev)3924 int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
3925 {
3926 	int len;
3927 	assert(seq && ev);
3928 	len = snd_seq_event_length(ev);
3929 	if (len < 0)
3930 		return -EINVAL;
3931 	if ((size_t) len >= seq->obufsize)
3932 		return -EINVAL;
3933 	if ((seq->obufsize - seq->obufused) < (size_t) len)
3934 		return -EAGAIN;
3935 	memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
3936 	seq->obufused += sizeof(snd_seq_event_t);
3937 	if (snd_seq_ev_is_variable(ev)) {
3938 		memcpy(seq->obuf + seq->obufused, ev->data.ext.ptr, ev->data.ext.len);
3939 		seq->obufused += ev->data.ext.len;
3940 	}
3941 	return seq->obufused;
3942 }
3943 
3944 /*
3945  * allocate the temporary buffer
3946  */
alloc_tmpbuf(snd_seq_t * seq,size_t len)3947 static int alloc_tmpbuf(snd_seq_t *seq, size_t len)
3948 {
3949 	size_t size = ((len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t));
3950 	if (seq->tmpbuf == NULL) {
3951 		if (size > DEFAULT_TMPBUF_SIZE)
3952 			seq->tmpbufsize = size;
3953 		else
3954 			seq->tmpbufsize = DEFAULT_TMPBUF_SIZE;
3955 		seq->tmpbuf = malloc(seq->tmpbufsize * sizeof(snd_seq_event_t));
3956 		if (seq->tmpbuf == NULL)
3957 			return -ENOMEM;
3958 	}  else if (len > seq->tmpbufsize) {
3959 		seq->tmpbuf = realloc(seq->tmpbuf, size * sizeof(snd_seq_event_t));
3960 		if (seq->tmpbuf == NULL)
3961 			return -ENOMEM;
3962 		seq->tmpbufsize = size;
3963 	}
3964 	return 0;
3965 }
3966 
3967 /**
3968  * \brief output an event directly to the sequencer NOT through output buffer
3969  * \param seq sequencer handle
3970  * \param ev event to be output
3971  * \return the byte size sent to sequencer or a negative error code
3972  *
3973  * This function sends an event to the sequencer directly not through the
3974  * output buffer.  When the event is a variable length event, a temporary
3975  * buffer is allocated inside alsa-lib and the data is copied there before
3976  * actually sent.
3977  *
3978  * \sa snd_seq_event_output()
3979  */
snd_seq_event_output_direct(snd_seq_t * seq,snd_seq_event_t * ev)3980 int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
3981 {
3982 	ssize_t len;
3983 	void *buf;
3984 
3985 	len = snd_seq_event_length(ev);
3986 	if (len < 0)
3987 		return len;
3988 	else if (len == sizeof(*ev)) {
3989 		buf = ev;
3990 	} else {
3991 		if (alloc_tmpbuf(seq, (size_t)len) < 0)
3992 			return -ENOMEM;
3993 		*seq->tmpbuf = *ev;
3994 		memcpy(seq->tmpbuf + 1, ev->data.ext.ptr, ev->data.ext.len);
3995 		buf = seq->tmpbuf;
3996 	}
3997 	return seq->ops->write(seq, buf, (size_t) len);
3998 }
3999 
4000 /**
4001  * \brief return the size of pending events on output buffer
4002  * \param seq sequencer handle
4003  * \return the byte size of total of pending events
4004  *
4005  * \sa snd_seq_event_output()
4006  */
snd_seq_event_output_pending(snd_seq_t * seq)4007 int snd_seq_event_output_pending(snd_seq_t *seq)
4008 {
4009 	assert(seq);
4010 	return seq->obufused;
4011 }
4012 
4013 /**
4014  * \brief drain output buffer to sequencer
4015  * \param seq sequencer handle
4016  * \return 0 when all events are drained and sent to sequencer.
4017  *         When events still remain on the buffer, the byte size of remaining
4018  *         events are returned.  On error a negative error code is returned.
4019  *
4020  * This function drains all pending events on the output buffer.
4021  * The function returns immediately after the events are sent to the queues
4022  * regardless whether the events are processed or not.
4023  * To get synchronization with the all event processes, use
4024  * #snd_seq_sync_output_queue() after calling this function.
4025  *
4026  * \sa snd_seq_event_output(), snd_seq_sync_output_queue()
4027  */
snd_seq_drain_output(snd_seq_t * seq)4028 int snd_seq_drain_output(snd_seq_t *seq)
4029 {
4030 	ssize_t result, processed = 0;
4031 	assert(seq);
4032 	while (seq->obufused > 0) {
4033 		result = seq->ops->write(seq, seq->obuf, seq->obufused);
4034 		if (result < 0) {
4035 			if (result == -EAGAIN && processed)
4036 				return seq->obufused;
4037 			return result;
4038 		}
4039 		if ((size_t)result < seq->obufused)
4040 			memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
4041 		seq->obufused -= result;
4042 	}
4043 	return 0;
4044 }
4045 
4046 /**
4047  * \brief extract the first event in output buffer
4048  * \param seq sequencer handle
4049  * \param ev_res event pointer to be extracted
4050  * \return 0 on success otherwise a negative error code
4051  *
4052  * Extracts the first event in output buffer.
4053  * If ev_res is NULL, just remove the event.
4054  *
4055  * \sa snd_seq_event_output()
4056  */
snd_seq_extract_output(snd_seq_t * seq,snd_seq_event_t ** ev_res)4057 int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
4058 {
4059 	size_t len, olen;
4060 	snd_seq_event_t ev;
4061 	assert(seq);
4062 	if (ev_res)
4063 		*ev_res = NULL;
4064 	if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
4065 		return -ENOENT;
4066 	memcpy(&ev, seq->obuf, sizeof(snd_seq_event_t));
4067 	len = snd_seq_event_length(&ev);
4068 	if (ev_res) {
4069 		/* extract the event */
4070 		if (alloc_tmpbuf(seq, len) < 0)
4071 			return -ENOMEM;
4072 		memcpy(seq->tmpbuf, seq->obuf, len);
4073 		*ev_res = seq->tmpbuf;
4074 	}
4075 	seq->obufused = olen - len;
4076 	memmove(seq->obuf, seq->obuf + len, seq->obufused);
4077 	return 0;
4078 }
4079 
4080 /*----------------------------------------------------------------*/
4081 
4082 /*
4083  * input from sequencer
4084  */
4085 
4086 /*
4087  * read from sequencer to input buffer
4088  */
snd_seq_event_read_buffer(snd_seq_t * seq)4089 static ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
4090 {
4091 	ssize_t len;
4092 	len = (seq->ops->read)(seq, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
4093 	if (len < 0)
4094 		return len;
4095 	seq->ibuflen = len / sizeof(snd_seq_event_t);
4096 	seq->ibufptr = 0;
4097 	return seq->ibuflen;
4098 }
4099 
snd_seq_event_retrieve_buffer(snd_seq_t * seq,snd_seq_event_t ** retp)4100 static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
4101 {
4102 	size_t ncells;
4103 	snd_seq_event_t *ev;
4104 
4105 	*retp = ev = &seq->ibuf[seq->ibufptr];
4106 	seq->ibufptr++;
4107 	seq->ibuflen--;
4108 	if (! snd_seq_ev_is_variable(ev))
4109 		return 1;
4110 	ncells = (ev->data.ext.len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
4111 	if (seq->ibuflen < ncells) {
4112 		seq->ibuflen = 0; /* clear buffer */
4113 		*retp = NULL;
4114 		return -EINVAL;
4115 	}
4116 	ev->data.ext.ptr = ev + 1;
4117 	seq->ibuflen -= ncells;
4118 	seq->ibufptr += ncells;
4119 	return 1;
4120 }
4121 
4122 /**
4123  * \brief retrieve an event from sequencer
4124  * \param seq sequencer handle
4125  * \param ev event pointer to be stored
4126  * \return
4127  *
4128  * Obtains an input event from sequencer.
4129  * The event is created via snd_seq_create_event(), and its pointer is stored on
4130  * ev argument.
4131  *
4132  * This function firstly receives the event byte-stream data from sequencer
4133  * as much as possible at once.  Then it retrieves the first event record
4134  * and store the pointer on ev.
4135  * By calling this function sequentially, events are extracted from the input buffer.
4136  *
4137  * If there is no input from sequencer, function falls into sleep
4138  * in blocking mode until an event is received,
4139  * or returns \c -EAGAIN error in non-blocking mode.
4140  * Occasionally, this function may return \c -ENOSPC error.
4141  * This means that the input FIFO of sequencer overran, and some events are
4142  * lost.
4143  * Once this error is returned, the input FIFO is cleared automatically.
4144  *
4145  * Function returns the byte size of remaining events on the input buffer
4146  * if an event is successfully received.
4147  * Application can determine from the returned value whether to call
4148  * input once more or not.
4149  *
4150  * \sa snd_seq_event_input_pending(), snd_seq_drop_input()
4151  */
snd_seq_event_input(snd_seq_t * seq,snd_seq_event_t ** ev)4152 int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
4153 {
4154 	int err;
4155 	assert(seq);
4156 	*ev = NULL;
4157 	if (seq->ibuflen <= 0) {
4158 		if ((err = snd_seq_event_read_buffer(seq)) < 0)
4159 			return err;
4160 	}
4161 
4162 	return snd_seq_event_retrieve_buffer(seq, ev);
4163 }
4164 
4165 /*
4166  * read input data from sequencer if available
4167  */
snd_seq_event_input_feed(snd_seq_t * seq,int timeout)4168 static int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
4169 {
4170 	struct pollfd pfd;
4171 	int err;
4172 	pfd.fd = seq->poll_fd;
4173 	pfd.events = POLLIN;
4174 	err = poll(&pfd, 1, timeout);
4175 	if (err < 0) {
4176 		SYSERR("poll");
4177 		return -errno;
4178 	}
4179 	if (pfd.revents & POLLIN)
4180 		return snd_seq_event_read_buffer(seq);
4181 	return seq->ibuflen;
4182 }
4183 
4184 /**
4185  * \brief check events in input buffer
4186  * \return the byte size of remaining input events on input buffer.
4187  *
4188  * If events remain on the input buffer of user-space, function returns
4189  * the total byte size of events on it.
4190  * If fetch_sequencer argument is non-zero,
4191  * this function checks the presence of events on sequencer FIFO
4192  * When events exist, they are transferred to the input buffer,
4193  * and the number of received events are returned.
4194  * If fetch_sequencer argument is zero and
4195  * no events remain on the input buffer, function simply returns zero.
4196  *
4197  * \sa snd_seq_event_input()
4198  */
snd_seq_event_input_pending(snd_seq_t * seq,int fetch_sequencer)4199 int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
4200 {
4201 	if (seq->ibuflen == 0 && fetch_sequencer) {
4202 		return snd_seq_event_input_feed(seq, 0);
4203 	}
4204 	return seq->ibuflen;
4205 }
4206 
4207 /*----------------------------------------------------------------*/
4208 
4209 /*
4210  * clear event buffers
4211  */
4212 
4213 /**
4214  * \brief remove all events on user-space output buffer
4215  * \param seq sequencer handle
4216  *
4217  * Removes all events on user-space output buffer.
4218  * Unlike snd_seq_drain_output(), this function doesn't remove
4219  * events on output memory pool of sequencer.
4220  *
4221  * \sa snd_seq_drop_output()
4222  */
snd_seq_drop_output_buffer(snd_seq_t * seq)4223 int snd_seq_drop_output_buffer(snd_seq_t *seq)
4224 {
4225 	assert(seq);
4226 	seq->obufused = 0;
4227 	return 0;
4228 }
4229 
4230 /**
4231  * \brief remove all events on user-space input FIFO
4232  * \param seq sequencer handle
4233  *
4234  * \sa snd_seq_drop_input()
4235  */
snd_seq_drop_input_buffer(snd_seq_t * seq)4236 int snd_seq_drop_input_buffer(snd_seq_t *seq)
4237 {
4238 	assert(seq);
4239 	seq->ibufptr = 0;
4240 	seq->ibuflen = 0;
4241 	return 0;
4242 }
4243 
4244 /**
4245  * \brief remove all events on output buffer
4246  * \param seq sequencer handle
4247  *
4248  * Removes all events on both user-space output buffer and
4249  * output memory pool on kernel.
4250  *
4251  * \sa snd_seq_drain_output(), snd_seq_drop_output_buffer(), snd_seq_remove_events()
4252  */
snd_seq_drop_output(snd_seq_t * seq)4253 int snd_seq_drop_output(snd_seq_t *seq)
4254 {
4255 	snd_seq_remove_events_t rminfo;
4256 	assert(seq);
4257 
4258 	memset(&rminfo, 0, sizeof(rminfo));
4259 	rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;
4260 
4261 	return snd_seq_remove_events(seq, &rminfo);
4262 }
4263 
4264 /**
4265  * \brief clear input buffer and and remove events in sequencer queue
4266  * \param seq sequencer handle
4267  *
4268  * \sa snd_seq_drop_input_buffer(), snd_seq_remove_events()
4269  */
snd_seq_drop_input(snd_seq_t * seq)4270 int snd_seq_drop_input(snd_seq_t *seq)
4271 {
4272 	snd_seq_remove_events_t rminfo;
4273 	assert(seq);
4274 
4275 	memset(&rminfo, 0, sizeof(rminfo));
4276 	rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;
4277 
4278 	return snd_seq_remove_events(seq, &rminfo);
4279 }
4280 
4281 
4282 /**
4283  * \brief get size of #snd_seq_remove_events_t
4284  * \return size in bytes
4285  */
snd_seq_remove_events_sizeof()4286 size_t snd_seq_remove_events_sizeof()
4287 {
4288 	return sizeof(snd_seq_remove_events_t);
4289 }
4290 
4291 /**
4292  * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
4293  * \param ptr returned pointer
4294  * \return 0 on success otherwise negative error code
4295  */
snd_seq_remove_events_malloc(snd_seq_remove_events_t ** ptr)4296 int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
4297 {
4298 	assert(ptr);
4299 	*ptr = calloc(1, sizeof(snd_seq_remove_events_t));
4300 	if (!*ptr)
4301 		return -ENOMEM;
4302 	return 0;
4303 }
4304 
4305 /**
4306  * \brief frees a previously allocated #snd_seq_remove_events_t
4307  * \param obj pointer to object to free
4308  */
snd_seq_remove_events_free(snd_seq_remove_events_t * obj)4309 void snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
4310 {
4311 	free(obj);
4312 }
4313 
4314 /**
4315  * \brief copy one #snd_seq_remove_events_t to another
4316  * \param dst pointer to destination
4317  * \param src pointer to source
4318  */
snd_seq_remove_events_copy(snd_seq_remove_events_t * dst,const snd_seq_remove_events_t * src)4319 void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
4320 {
4321 	assert(dst && src);
4322 	*dst = *src;
4323 }
4324 
4325 
4326 /**
4327  * \brief Get the removal condition bits
4328  * \param info remove_events container
4329  * \return removal condition bits
4330  *
4331  * \sa snd_seq_remove_events()
4332  */
snd_seq_remove_events_get_condition(const snd_seq_remove_events_t * info)4333 unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
4334 {
4335 	assert(info);
4336 	return info->remove_mode;
4337 }
4338 
4339 /**
4340  * \brief Get the queue as removal condition
4341  * \param info remove_events container
4342  * \return queue id
4343  *
4344  * \sa snd_seq_remove_events()
4345  */
snd_seq_remove_events_get_queue(const snd_seq_remove_events_t * info)4346 int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
4347 {
4348 	assert(info);
4349 	return info->queue;
4350 }
4351 
4352 /**
4353  * \brief Get the event timestamp as removal condition
4354  * \param info remove_events container
4355  * \return time stamp
4356  *
4357  * \sa snd_seq_remove_events()
4358  */
snd_seq_remove_events_get_time(const snd_seq_remove_events_t * info)4359 const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
4360 {
4361 	assert(info);
4362 	return (const snd_seq_timestamp_t *)&info->time;
4363 }
4364 
4365 /**
4366  * \brief Get the event destination address as removal condition
4367  * \param info remove_events container
4368  * \return destination address
4369  *
4370  * \sa snd_seq_remove_events()
4371  */
snd_seq_remove_events_get_dest(const snd_seq_remove_events_t * info)4372 const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
4373 {
4374 	assert(info);
4375 	return (const snd_seq_addr_t *)&info->dest;
4376 }
4377 
4378 /**
4379  * \brief Get the event channel as removal condition
4380  * \param info remove_events container
4381  * \return channel number
4382  *
4383  * \sa snd_seq_remove_events()
4384  */
snd_seq_remove_events_get_channel(const snd_seq_remove_events_t * info)4385 int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
4386 {
4387 	assert(info);
4388 	return info->channel;
4389 }
4390 
4391 /**
4392  * \brief Get the event type as removal condition
4393  * \param info remove_events container
4394  * \return event type
4395  *
4396  * \sa snd_seq_remove_events()
4397  */
snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t * info)4398 int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
4399 {
4400 	assert(info);
4401 	return info->type;
4402 }
4403 
4404 /**
4405  * \brief Get the event tag id as removal condition
4406  * \param info remove_events container
4407  * \return tag id
4408  *
4409  * \sa snd_seq_remove_events()
4410  */
snd_seq_remove_events_get_tag(const snd_seq_remove_events_t * info)4411 int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
4412 {
4413 	assert(info);
4414 	return info->tag;
4415 }
4416 
4417 /**
4418  * \brief Set the removal condition bits
4419  * \param info remove_events container
4420  * \param flags removal condition bits
4421  *
4422  * \sa snd_seq_remove_events()
4423  */
snd_seq_remove_events_set_condition(snd_seq_remove_events_t * info,unsigned int flags)4424 void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
4425 {
4426 	assert(info);
4427 	info->remove_mode = flags;
4428 }
4429 
4430 /**
4431  * \brief Set the queue as removal condition
4432  * \param info remove_events container
4433  * \param queue queue id
4434  *
4435  * \sa snd_seq_remove_events()
4436  */
snd_seq_remove_events_set_queue(snd_seq_remove_events_t * info,int queue)4437 void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
4438 {
4439 	assert(info);
4440 	info->queue = queue;
4441 }
4442 
4443 /**
4444  * \brief Set the timestamp as removal condition
4445  * \param info remove_events container
4446  * \param time timestamp pointer
4447  *
4448  * \sa snd_seq_remove_events()
4449  */
snd_seq_remove_events_set_time(snd_seq_remove_events_t * info,const snd_seq_timestamp_t * time)4450 void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
4451 {
4452 	assert(info);
4453 	info->time = *(const union sndrv_seq_timestamp *)time;
4454 }
4455 
4456 /**
4457  * \brief Set the destination address as removal condition
4458  * \param info remove_events container
4459  * \param addr destination address
4460  *
4461  * \sa snd_seq_remove_events()
4462  */
snd_seq_remove_events_set_dest(snd_seq_remove_events_t * info,const snd_seq_addr_t * addr)4463 void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
4464 {
4465 	assert(info);
4466 	info->dest = *(const struct sndrv_seq_addr *)addr;
4467 }
4468 
4469 /**
4470  * \brief Set the channel as removal condition
4471  * \param info remove_events container
4472  * \param channel channel number
4473  *
4474  * \sa snd_seq_remove_events()
4475  */
snd_seq_remove_events_set_channel(snd_seq_remove_events_t * info,int channel)4476 void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
4477 {
4478 	assert(info);
4479 	info->channel = channel;
4480 }
4481 
4482 /**
4483  * \brief Set the event type as removal condition
4484  * \param info remove_events container
4485  * \param type event type
4486  *
4487  * \sa snd_seq_remove_events()
4488  */
snd_seq_remove_events_set_event_type(snd_seq_remove_events_t * info,int type)4489 void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
4490 {
4491 	assert(info);
4492 	info->type = type;
4493 }
4494 
4495 /**
4496  * \brief Set the event tag as removal condition
4497  * \param info remove_events container
4498  * \param tag tag id
4499  *
4500  * \sa snd_seq_remove_events()
4501  */
snd_seq_remove_events_set_tag(snd_seq_remove_events_t * info,int tag)4502 void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
4503 {
4504 	assert(info);
4505 	info->tag = tag;
4506 }
4507 
4508 
4509 /* compare timestamp between events */
4510 /* return 1 if a >= b; otherwise return 0 */
snd_seq_compare_tick_time(snd_seq_tick_time_t * a,snd_seq_tick_time_t * b)4511 static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
4512 {
4513 	/* compare ticks */
4514 	return (*a >= *b);
4515 }
4516 
snd_seq_compare_real_time(snd_seq_real_time_t * a,snd_seq_real_time_t * b)4517 static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
4518 {
4519 	/* compare real time */
4520 	if (a->tv_sec > b->tv_sec)
4521 		return 1;
4522 	if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
4523 		return 1;
4524 	return 0;
4525 }
4526 
4527 /* Routine to match events to be removed */
remove_match(snd_seq_remove_events_t * info,snd_seq_event_t * ev)4528 static int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
4529 {
4530 	int res;
4531 
4532 	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
4533 		if (ev->dest.client != info->dest.client ||
4534 				ev->dest.port != info->dest.port)
4535 			return 0;
4536 	}
4537 	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
4538 		if (! snd_seq_ev_is_channel_type(ev))
4539 			return 0;
4540 		/* data.note.channel and data.control.channel are identical */
4541 		if (ev->data.note.channel != info->channel)
4542 			return 0;
4543 	}
4544 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
4545 		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4546 			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4547 		else
4548 			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4549 		if (!res)
4550 			return 0;
4551 	}
4552 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
4553 		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4554 			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4555 		else
4556 			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4557 		if (res)
4558 			return 0;
4559 	}
4560 	if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
4561 		if (ev->type != info->type)
4562 			return 0;
4563 	}
4564 	if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
4565 		/* Do not remove off events */
4566 		switch (ev->type) {
4567 		case SND_SEQ_EVENT_NOTEOFF:
4568 		/* case SND_SEQ_EVENT_SAMPLE_STOP: */
4569 			return 0;
4570 		default:
4571 			break;
4572 		}
4573 	}
4574 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
4575 		if (info->tag != ev->tag)
4576 			return 0;
4577 	}
4578 
4579 	return 1;
4580 }
4581 
4582 /**
4583  * \brief remove events on input/output buffers and pools
4584  * \param seq sequencer handle
4585  * \param rmp remove event container
4586  *
4587  * Removes matching events with the given condition from input/output buffers
4588  * and pools.
4589  * The removal condition is specified in \a rmp argument.
4590  *
4591  * \sa snd_seq_event_output(), snd_seq_drop_output(), snd_seq_reset_pool_output()
4592  */
snd_seq_remove_events(snd_seq_t * seq,snd_seq_remove_events_t * rmp)4593 int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
4594 {
4595 	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
4596 		/*
4597 		 * First deal with any events that are still buffered
4598 		 * in the library.
4599 		 */
4600 		snd_seq_drop_input_buffer(seq);
4601 	}
4602 
4603 	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
4604 		/*
4605 		 * First deal with any events that are still buffered
4606 		 * in the library.
4607 		 */
4608 		 if (! (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT))) {
4609 			 /* The simple case - remove all */
4610 			 snd_seq_drop_output_buffer(seq);
4611 		} else {
4612 			char *ep;
4613 			size_t len;
4614 			snd_seq_event_t *ev;
4615 
4616 			ep = seq->obuf;
4617 			while (ep - seq->obuf < (ssize_t)seq->obufused) {
4618 
4619 				ev = (snd_seq_event_t *)ep;
4620 				len = snd_seq_event_length(ev);
4621 
4622 				if (remove_match(rmp, ev)) {
4623 					/* Remove event */
4624 					seq->obufused -= len;
4625 					memmove(ep, ep + len, seq->obufused - (ep - seq->obuf));
4626 				} else {
4627 					ep += len;
4628 				}
4629 			}
4630 		}
4631 	}
4632 
4633 	return seq->ops->remove_events(seq, rmp);
4634 }
4635 
4636 /*----------------------------------------------------------------*/
4637 
4638 /*
4639  * client memory pool
4640  */
4641 
4642 /**
4643  * \brief get size of #snd_seq_client_pool_t
4644  * \return size in bytes
4645  */
snd_seq_client_pool_sizeof()4646 size_t snd_seq_client_pool_sizeof()
4647 {
4648 	return sizeof(snd_seq_client_pool_t);
4649 }
4650 
4651 /**
4652  * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
4653  * \param ptr returned pointer
4654  * \return 0 on success otherwise negative error code
4655  */
snd_seq_client_pool_malloc(snd_seq_client_pool_t ** ptr)4656 int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
4657 {
4658 	assert(ptr);
4659 	*ptr = calloc(1, sizeof(snd_seq_client_pool_t));
4660 	if (!*ptr)
4661 		return -ENOMEM;
4662 	return 0;
4663 }
4664 
4665 /**
4666  * \brief frees a previously allocated #snd_seq_client_pool_t
4667  * \param obj pointer to object to free
4668  */
snd_seq_client_pool_free(snd_seq_client_pool_t * obj)4669 void snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
4670 {
4671 	free(obj);
4672 }
4673 
4674 /**
4675  * \brief copy one #snd_seq_client_pool_t to another
4676  * \param dst pointer to destination
4677  * \param src pointer to source
4678  */
snd_seq_client_pool_copy(snd_seq_client_pool_t * dst,const snd_seq_client_pool_t * src)4679 void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
4680 {
4681 	assert(dst && src);
4682 	*dst = *src;
4683 }
4684 
4685 
4686 /**
4687  * \brief Get the client id of a queue_info container
4688  * \param info client_pool container
4689  * \return client id
4690  */
snd_seq_client_pool_get_client(const snd_seq_client_pool_t * info)4691 int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
4692 {
4693 	assert(info);
4694 	return info->client;
4695 }
4696 
4697 /**
4698  * \brief Get the output pool size of a queue_info container
4699  * \param info client_pool container
4700  * \return output pool size
4701  */
snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t * info)4702 size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
4703 {
4704 	assert(info);
4705 	return info->output_pool;
4706 }
4707 
4708 /**
4709  * \brief Get the input pool size of a queue_info container
4710  * \param info client_pool container
4711  * \return input pool size
4712  */
snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t * info)4713 size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
4714 {
4715 	assert(info);
4716 	return info->input_pool;
4717 }
4718 
4719 /**
4720  * \brief Get the output room size of a queue_info container
4721  * \param info client_pool container
4722  * \return output room size
4723  */
snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t * info)4724 size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
4725 {
4726 	assert(info);
4727 	return info->output_room;
4728 }
4729 
4730 /**
4731  * \brief Get the available size on output pool of a queue_info container
4732  * \param info client_pool container
4733  * \return available output size
4734  */
snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t * info)4735 size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
4736 {
4737 	assert(info);
4738 	return info->output_free;
4739 }
4740 
4741 /**
4742  * \brief Get the available size on input pool of a queue_info container
4743  * \param info client_pool container
4744  * \return available input size
4745  */
snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t * info)4746 size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
4747 {
4748 	assert(info);
4749 	return info->input_free;
4750 }
4751 
4752 /**
4753  * \brief Set the output pool size of a queue_info container
4754  * \param info client_pool container
4755  * \param size output pool size
4756  */
snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t * info,size_t size)4757 void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
4758 {
4759 	assert(info);
4760 	info->output_pool = size;
4761 }
4762 
4763 /**
4764  * \brief Set the input pool size of a queue_info container
4765  * \param info client_pool container
4766  * \param size input pool size
4767  */
snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t * info,size_t size)4768 void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
4769 {
4770 	assert(info);
4771 	info->input_pool = size;
4772 }
4773 
4774 /**
4775  * \brief Set the output room size of a queue_info container
4776  * \param info client_pool container
4777  * \param size output room size
4778  */
snd_seq_client_pool_set_output_room(snd_seq_client_pool_t * info,size_t size)4779 void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
4780 {
4781 	assert(info);
4782 	info->output_room = size;
4783 }
4784 
4785 
4786 /**
4787  * \brief obtain the pool information of the current client
4788  * \param seq sequencer handle
4789  * \param info information to be stored
4790  */
snd_seq_get_client_pool(snd_seq_t * seq,snd_seq_client_pool_t * info)4791 int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4792 {
4793 	assert(seq && info);
4794 	info->client = seq->client;
4795 	return seq->ops->get_client_pool(seq, info);
4796 }
4797 
4798 /**
4799  * \brief set the pool information
4800  * \param seq sequencer handle
4801  * \param info information to update
4802  *
4803  * Sets the pool information of the current client.
4804  * The client field in \a info is replaced automatically with the current id.
4805  */
snd_seq_set_client_pool(snd_seq_t * seq,snd_seq_client_pool_t * info)4806 int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4807 {
4808 	assert(seq && info);
4809 	info->client = seq->client;
4810 	return seq->ops->set_client_pool(seq, info);
4811 }
4812 
4813 /*----------------------------------------------------------------*/
4814 
4815 /*
4816  * misc.
4817  */
4818 
4819 /**
4820  * \brief set a bit flag
4821  */
snd_seq_set_bit(int nr,void * array)4822 void snd_seq_set_bit(int nr, void *array)
4823 {
4824 	((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
4825 }
4826 
4827 /**
4828  * \brief unset a bit flag
4829  */
snd_seq_unset_bit(int nr,void * array)4830 void snd_seq_unset_bit(int nr, void *array)
4831 {
4832        ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
4833 }
4834 
4835 /**
4836  * \brief change a bit flag
4837  */
snd_seq_change_bit(int nr,void * array)4838 int snd_seq_change_bit(int nr, void *array)
4839 {
4840 	int result;
4841 
4842 	result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
4843 	((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
4844 	return result;
4845 }
4846 
4847 /**
4848  * \brief get a bit flag state
4849  */
snd_seq_get_bit(int nr,void * array)4850 int snd_seq_get_bit(int nr, void *array)
4851 {
4852 	return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
4853 }
4854