• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 	if (_snd_is_ucm_device(name)) {
982 		name = uc_mgr_alibcfg_by_device(&top, name);
983 		if (name == NULL)
984 			return -ENODEV;
985 	} else {
986 		err = snd_config_update_ref(&top);
987 		if (err < 0)
988 			return err;
989 	}
990 	err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
991 	snd_config_unref(top);
992 	return err;
993 }
994 
995 /**
996  * \brief Open the ALSA sequencer using local configuration
997  *
998  * \param seqp Pointer to a snd_seq_t pointer.
999  * \param name The name to open
1000  * \param streams The read/write mode of the sequencer.
1001  * \param mode Optional modifier
1002  * \param lconf Local configuration
1003  * \return 0 on success otherwise a negative error code
1004  *
1005  * See the snd_seq_open() function for further details. The extension
1006  * is that the given configuration is used to resolve abstract name.
1007  *
1008  * \sa snd_seq_open()
1009  */
snd_seq_open_lconf(snd_seq_t ** seqp,const char * name,int streams,int mode,snd_config_t * lconf)1010 int snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1011 		       int streams, int mode, snd_config_t *lconf)
1012 {
1013 	assert(seqp && name && lconf);
1014 	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
1015 }
1016 
1017 #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)1018 int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1019 			int streams, int mode, snd_config_t *lconf,
1020 			snd_config_t *parent_conf)
1021 {
1022 	int hop;
1023 	assert(seqp && name && lconf);
1024 	if ((hop = snd_config_check_hop(parent_conf)) < 0)
1025 		return hop;
1026 	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
1027 }
1028 #endif
1029 
1030 /**
1031  * \brief Close the sequencer
1032  * \param seq Handle returned from #snd_seq_open()
1033  * \return 0 on success otherwise a negative error code
1034  *
1035  * Closes the sequencer client and releases its resources.
1036  * After a client is closed, an event with
1037  * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
1038  * The connection between other clients are disconnected.
1039  * Call this just before exiting your program.
1040  *
1041  * \sa snd_seq_close()
1042  */
snd_seq_close(snd_seq_t * seq)1043 int snd_seq_close(snd_seq_t *seq)
1044 {
1045 	int err;
1046 	assert(seq);
1047 	err = seq->ops->close(seq);
1048 	if (seq->dl_handle)
1049 		snd_dlclose(seq->dl_handle);
1050 	free(seq->obuf);
1051 	free(seq->ibuf);
1052 	free(seq->tmpbuf);
1053 	free(seq->name);
1054 	free(seq);
1055 	return err;
1056 }
1057 
1058 /**
1059  * \brief Returns the number of poll descriptors
1060  * \param seq sequencer handle
1061  * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
1062  * \return the number of poll descriptors.
1063  *
1064  * Get the number of poll descriptors.  The polling events to be checked
1065  * can be specified by the second argument.  When both input and output
1066  * are checked, pass \c POLLIN|POLLOUT
1067  *
1068  * \sa snd_seq_poll_descriptors()
1069  */
snd_seq_poll_descriptors_count(snd_seq_t * seq,short events)1070 int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
1071 {
1072 	int result = 0;
1073 	assert(seq);
1074 	if (events & POLLIN) {
1075 		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1076 		result++;
1077 	}
1078 	if (events & POLLOUT) {
1079 		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1080 		result++;
1081 	}
1082 	return result ? 1 : 0;
1083 }
1084 
1085 /**
1086  * \brief Get poll descriptors
1087  * \param seq sequencer handle
1088  * \param pfds array of poll descriptors
1089  * \param space space in the poll descriptor array
1090  * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
1091  * \return count of filled descriptors
1092  *
1093  * Get poll descriptors assigned to the sequencer handle.
1094  * Since a sequencer handle can duplex streams, you need to set which direction(s)
1095  * is/are polled in \a events argument.  When \c POLLIN bit is specified,
1096  * the incoming events to the ports are checked.
1097  *
1098  * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
1099  * instead of reading the pollfd structs directly.
1100  *
1101  * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
1102  */
snd_seq_poll_descriptors(snd_seq_t * seq,struct pollfd * pfds,unsigned int space,short events)1103 int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
1104 {
1105 	short revents = 0;
1106 
1107 	assert(seq);
1108 	if ((events & POLLIN) && space >= 1) {
1109 		assert(seq->streams & SND_SEQ_OPEN_INPUT);
1110 		revents |= POLLIN|POLLERR|POLLNVAL;
1111 	}
1112 	if ((events & POLLOUT) && space >= 1) {
1113 		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1114 		revents |= POLLOUT|POLLERR|POLLNVAL;
1115 	}
1116 	if (!revents)
1117 		return 0;
1118 	pfds->fd = seq->poll_fd;
1119 	pfds->events = revents;
1120 	return 1;
1121 }
1122 
1123 /**
1124  * \brief get returned events from poll descriptors
1125  * \param seq sequencer handle
1126  * \param pfds array of poll descriptors
1127  * \param nfds count of poll descriptors
1128  * \param revents returned events
1129  * \return zero if success, otherwise a negative error code
1130  *
1131  * \sa snd_seq_poll_descriptors()
1132  */
snd_seq_poll_descriptors_revents(snd_seq_t * seq,struct pollfd * pfds,unsigned int nfds,unsigned short * revents)1133 int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1134 {
1135         assert(seq && pfds && revents);
1136         if (nfds == 1) {
1137                 *revents = pfds->revents;
1138                 return 0;
1139         }
1140         return -EINVAL;
1141 }
1142 
1143 /**
1144  * \brief Set nonblock mode
1145  * \param seq sequencer handle
1146  * \param nonblock 0 = block, 1 = nonblock mode
1147  * \return 0 on success otherwise a negative error code
1148  *
1149  * Change the blocking mode of the given client.
1150  * In block mode, the client falls into sleep when it fills the
1151  * output memory pool with full events.  The client will be woken up
1152  * after a certain amount of free space becomes available.
1153  *
1154  * \sa snd_seq_open()
1155  */
snd_seq_nonblock(snd_seq_t * seq,int nonblock)1156 int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
1157 {
1158 	int err;
1159 	assert(seq);
1160 	err = seq->ops->nonblock(seq, nonblock);
1161 	if (err < 0)
1162 		return err;
1163 	if (nonblock)
1164 		seq->mode |= SND_SEQ_NONBLOCK;
1165 	else
1166 		seq->mode &= ~SND_SEQ_NONBLOCK;
1167 	return 0;
1168 }
1169 
1170 /**
1171  * \brief Get the client id
1172  * \param seq sequencer handle
1173  * \return the client id
1174  *
1175  * Returns the id of the specified client.
1176  * If an error occurs, function returns the negative error code.
1177  * A client id is necessary to inquiry or to set the client information.
1178  * A user client is assigned from 128 to 191.
1179  *
1180  * \sa snd_seq_open()
1181  */
snd_seq_client_id(snd_seq_t * seq)1182 int snd_seq_client_id(snd_seq_t *seq)
1183 {
1184 	assert(seq);
1185 	return seq->client;
1186 }
1187 
1188 /**
1189  * \brief Return the size of output buffer
1190  * \param seq sequencer handle
1191  * \return the size of output buffer in bytes
1192  *
1193  * Obtains the size of output buffer.
1194  * This buffer is used to store decoded byte-stream of output events
1195  * before transferring to sequencer.
1196  *
1197  * \sa snd_seq_set_output_buffer_size()
1198  */
snd_seq_get_output_buffer_size(snd_seq_t * seq)1199 size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
1200 {
1201 	assert(seq);
1202 	if (!seq->obuf)
1203 		return 0;
1204 	return seq->obufsize;
1205 }
1206 
1207 /**
1208  * \brief Return the size of input buffer
1209  * \param seq sequencer handle
1210  * \return the size of input buffer in bytes
1211  *
1212  * Obtains the size of input buffer.
1213  * This buffer is used to read byte-stream of input events from sequencer.
1214  *
1215  * \sa snd_seq_set_input_buffer_size()
1216  */
snd_seq_get_input_buffer_size(snd_seq_t * seq)1217 size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
1218 {
1219 	assert(seq);
1220 	if (!seq->ibuf)
1221 		return 0;
1222 	return seq->ibufsize * sizeof(snd_seq_event_t);
1223 }
1224 
1225 /**
1226  * \brief Change the size of output buffer
1227  * \param seq sequencer handle
1228  * \param size the size of output buffer to be changed in bytes
1229  * \return 0 on success otherwise a negative error code
1230  *
1231  * Changes the size of output buffer.
1232  *
1233  * \sa snd_seq_get_output_buffer_size()
1234  */
snd_seq_set_output_buffer_size(snd_seq_t * seq,size_t size)1235 int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
1236 {
1237 	assert(seq && seq->obuf);
1238 	assert(size >= sizeof(snd_seq_event_t));
1239 	snd_seq_drop_output(seq);
1240 	if (size != seq->obufsize) {
1241 		char *newbuf;
1242 		newbuf = calloc(1, size);
1243 		if (newbuf == NULL)
1244 			return -ENOMEM;
1245 		free(seq->obuf);
1246 		seq->obuf = newbuf;
1247 		seq->obufsize = size;
1248 	}
1249 	return 0;
1250 }
1251 
1252 /**
1253  * \brief Resize the input buffer
1254  * \param seq sequencer handle
1255  * \param size the size of input buffer to be changed in bytes
1256  * \return 0 on success otherwise a negative error code
1257  *
1258  * Changes the size of input buffer.
1259  *
1260  * \sa snd_seq_get_input_buffer_size()
1261  */
snd_seq_set_input_buffer_size(snd_seq_t * seq,size_t size)1262 int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
1263 {
1264 	assert(seq && seq->ibuf);
1265 	assert(size >= sizeof(snd_seq_event_t));
1266 	snd_seq_drop_input(seq);
1267 	size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
1268 	if (size != seq->ibufsize) {
1269 		snd_seq_event_t *newbuf;
1270 		newbuf = calloc(sizeof(snd_seq_event_t), size);
1271 		if (newbuf == NULL)
1272 			return -ENOMEM;
1273 		free(seq->ibuf);
1274 		seq->ibuf = newbuf;
1275 		seq->ibufsize = size;
1276 	}
1277 	return 0;
1278 }
1279 
1280 
1281 /**
1282  * \brief Get size of #snd_seq_system_info_t
1283  * \return size in bytes
1284  */
snd_seq_system_info_sizeof()1285 size_t snd_seq_system_info_sizeof()
1286 {
1287 	return sizeof(snd_seq_system_info_t);
1288 }
1289 
1290 /**
1291  * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
1292  * \param ptr returned pointer
1293  * \return 0 on success otherwise negative error code
1294  */
snd_seq_system_info_malloc(snd_seq_system_info_t ** ptr)1295 int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
1296 {
1297 	assert(ptr);
1298 	*ptr = calloc(1, sizeof(snd_seq_system_info_t));
1299 	if (!*ptr)
1300 		return -ENOMEM;
1301 	return 0;
1302 }
1303 
1304 /**
1305  * \brief Frees a previously allocated #snd_seq_system_info_t
1306  * \param obj pointer to object to free
1307  */
snd_seq_system_info_free(snd_seq_system_info_t * obj)1308 void snd_seq_system_info_free(snd_seq_system_info_t *obj)
1309 {
1310 	free(obj);
1311 }
1312 
1313 /**
1314  * \brief Copy one #snd_seq_system_info_t to another
1315  * \param dst pointer to destination
1316  * \param src pointer to source
1317  */
snd_seq_system_info_copy(snd_seq_system_info_t * dst,const snd_seq_system_info_t * src)1318 void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
1319 {
1320 	assert(dst && src);
1321 	*dst = *src;
1322 }
1323 
1324 
1325 /**
1326  * \brief Get maximum number of queues
1327  * \param info #snd_seq_system_info_t container
1328  * \return maximum number of queues
1329  *
1330  * \sa snd_seq_system_info()
1331  */
snd_seq_system_info_get_queues(const snd_seq_system_info_t * info)1332 int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
1333 {
1334 	assert(info);
1335 	return info->queues;
1336 }
1337 
1338 /**
1339  * \brief Get maximum number of clients
1340  * \param info #snd_seq_system_info_t container
1341  * \return maximum number of clients
1342  *
1343  * \sa snd_seq_system_info()
1344  */
snd_seq_system_info_get_clients(const snd_seq_system_info_t * info)1345 int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
1346 {
1347 	assert(info);
1348 	return info->clients;
1349 }
1350 
1351 /**
1352  * \brief Get maximum number of ports
1353  * \param info #snd_seq_system_info_t container
1354  * \return maximum number of ports
1355  *
1356  * \sa snd_seq_system_info()
1357  */
snd_seq_system_info_get_ports(const snd_seq_system_info_t * info)1358 int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
1359 {
1360 	assert(info);
1361 	return info->ports;
1362 }
1363 
1364 /**
1365  * \brief Get maximum number of channels
1366  * \param info #snd_seq_system_info_t container
1367  * \return maximum number of channels
1368  *
1369  * \sa snd_seq_system_info()
1370  */
snd_seq_system_info_get_channels(const snd_seq_system_info_t * info)1371 int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
1372 {
1373 	assert(info);
1374 	return info->channels;
1375 }
1376 
1377 /**
1378  * \brief Get the current number of clients
1379  * \param info #snd_seq_system_info_t container
1380  * \return current number of clients
1381  *
1382  * \sa snd_seq_system_info()
1383  */
snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t * info)1384 int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
1385 {
1386 	assert(info);
1387 	return info->cur_clients;
1388 }
1389 
1390 /**
1391  * \brief Get the current number of queues
1392  * \param info #snd_seq_system_info_t container
1393  * \return current number of queues
1394  *
1395  * \sa snd_seq_system_info()
1396  */
snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t * info)1397 int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
1398 {
1399 	assert(info);
1400 	return info->cur_queues;
1401 }
1402 
1403 /**
1404  * \brief obtain the sequencer system information
1405  * \param seq sequencer handle
1406  * \param info the pointer to be stored
1407  * \return 0 on success otherwise a negative error code
1408  *
1409  * Stores the global system information of ALSA sequencer system.
1410  * The returned data contains
1411  * the maximum available numbers of queues, clients, ports and channels.
1412  */
snd_seq_system_info(snd_seq_t * seq,snd_seq_system_info_t * info)1413 int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
1414 {
1415 	assert(seq && info);
1416 	return seq->ops->system_info(seq, info);
1417 }
1418 
1419 
1420 /*----------------------------------------------------------------*/
1421 
1422 /**
1423  * \brief get size of #snd_seq_client_info_t
1424  * \return size in bytes
1425  */
snd_seq_client_info_sizeof()1426 size_t snd_seq_client_info_sizeof()
1427 {
1428 	return sizeof(snd_seq_client_info_t);
1429 }
1430 
1431 /**
1432  * \brief allocate an empty #snd_seq_client_info_t using standard malloc
1433  * \param ptr returned pointer
1434  * \return 0 on success otherwise negative error code
1435  */
snd_seq_client_info_malloc(snd_seq_client_info_t ** ptr)1436 int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
1437 {
1438 	assert(ptr);
1439 	*ptr = calloc(1, sizeof(snd_seq_client_info_t));
1440 	if (!*ptr)
1441 		return -ENOMEM;
1442 	return 0;
1443 }
1444 
1445 /**
1446  * \brief frees a previously allocated #snd_seq_client_info_t
1447  * \param obj pointer to object to free
1448  */
snd_seq_client_info_free(snd_seq_client_info_t * obj)1449 void snd_seq_client_info_free(snd_seq_client_info_t *obj)
1450 {
1451 	free(obj);
1452 }
1453 
1454 /**
1455  * \brief copy one #snd_seq_client_info_t to another
1456  * \param dst pointer to destination
1457  * \param src pointer to source
1458  */
snd_seq_client_info_copy(snd_seq_client_info_t * dst,const snd_seq_client_info_t * src)1459 void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
1460 {
1461 	assert(dst && src);
1462 	*dst = *src;
1463 }
1464 
1465 
1466 /**
1467  * \brief Get client id of a client_info container
1468  * \param info client_info container
1469  * \return client id
1470  *
1471  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
1472  */
snd_seq_client_info_get_client(const snd_seq_client_info_t * info)1473 int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
1474 {
1475 	assert(info);
1476 	return info->client;
1477 }
1478 
1479 /**
1480  * \brief Get client type of a client_info container
1481  * \param info client_info container
1482  * \return client type
1483  *
1484  * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
1485  * for kernel or user client respectively.
1486  *
1487  * \sa snd_seq_get_client_info()
1488  */
snd_seq_client_info_get_type(const snd_seq_client_info_t * info)1489 snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
1490 {
1491 	assert(info);
1492 	return info->type;
1493 }
1494 
1495 /**
1496  * \brief Get the name of a client_info container
1497  * \param info client_info container
1498  * \return name string
1499  *
1500  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
1501  */
snd_seq_client_info_get_name(snd_seq_client_info_t * info)1502 const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
1503 {
1504 	assert(info);
1505 	return info->name;
1506 }
1507 
1508 /**
1509  * \brief Get the broadcast filter usage of a client_info container
1510  * \param info client_info container
1511  * \return 1 if broadcast is accepted
1512  *
1513  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
1514  */
snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t * info)1515 int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
1516 {
1517 	assert(info);
1518 	return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
1519 }
1520 
1521 /**
1522  * \brief Get the error-bounce usage of a client_info container
1523  * \param info client_info container
1524  * \return 1 if error-bounce is enabled
1525  *
1526  * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
1527  */
snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t * info)1528 int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
1529 {
1530 	assert(info);
1531 	return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
1532 }
1533 
1534 /**
1535  * \brief Get the sound card number.
1536  * \param info client_info container
1537  * \return card number or -1 if value is not available.
1538  *
1539  * Only available for #SND_SEQ_KERNEL_CLIENT clients.
1540  *
1541  * The card number can be used to query state about the hardware
1542  * device providing this client, by concatenating <code>"hw:CARD="</code>
1543  * with the card number and using it as the <code>name</code> parameter
1544  * to #snd_ctl_open().
1545  *
1546  * \note
1547  * The return value of -1 is returned for two different conditions: when the
1548  * running kernel does not support this operation, and when the client
1549  * does not have a hardware card attached. See
1550  * #snd_seq_client_info_get_pid() for a way to determine if the
1551  * currently running kernel has support for this operation.
1552  *
1553  * \sa snd_seq_client_info_get_pid(),
1554  *     snd_card_get_name(),
1555  *     snd_card_get_longname(),
1556  *     snd_ctl_open(),
1557  *     snd_ctl_card_info()
1558  */
snd_seq_client_info_get_card(const snd_seq_client_info_t * info)1559 int snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
1560 {
1561 	assert(info);
1562 	return info->card;
1563 }
1564 
1565 /**
1566  * \brief Get the owning PID.
1567  * \param info client_info container
1568  * \return pid or -1 if value is not available.
1569  *
1570  * Only available for #SND_SEQ_USER_CLIENT clients.
1571  *
1572  * \note
1573  * The functionality for getting a client's PID and getting a
1574  * client's card was added to the kernel at the same time, so you can
1575  * use this function to determine if the running kernel
1576  * supports reporting these values. If your own client has a valid
1577  * PID as reported by this function, then the running kernel supports
1578  * both #snd_seq_client_info_get_card() and #snd_seq_client_info_get_pid().
1579  *
1580  * \note
1581  * Example code for determining kernel support:
1582  * \code
1583  *   int is_get_card_or_pid_supported(snd_seq_t *seq)
1584  *   {
1585  *   	snd_seq_client_info_t *my_client_info;
1586  *   	snd_seq_client_info_alloca(&my_client_info);
1587  *   	snd_seq_get_client_info(seq, my_client_info);
1588  *   	return snd_seq_client_info_get_pid(my_client_info) != -1;
1589  *   }
1590  * \endcode
1591  *
1592  * \sa snd_seq_client_info_get_card()
1593  */
snd_seq_client_info_get_pid(const snd_seq_client_info_t * info)1594 int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
1595 {
1596 	assert(info);
1597 	return info->pid;
1598 }
1599 
1600 /**
1601  * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
1602  * \param info client_info container
1603  * \return NULL if no event filter, or pointer to event filter bitmap
1604  *
1605  * Use #snd_seq_client_info_event_filter_check() instead.
1606  *
1607  * \sa snd_seq_client_info_event_filter_add(),
1608  *     snd_seq_client_info_event_filter_del(),
1609  *     snd_seq_client_info_event_filter_check(),
1610  *     snd_seq_client_info_event_filter_clear(),
1611  *     snd_seq_get_client_info()
1612  */
snd_seq_client_info_get_event_filter(const snd_seq_client_info_t * info)1613 const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
1614 {
1615 	assert(info);
1616 	if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
1617 		return info->event_filter;
1618 	else
1619 		return NULL;
1620 }
1621 
1622 /**
1623  * \brief Disable event filtering of a client_info container
1624  * \param info client_info container
1625  *
1626  * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
1627  * the event filtering flag of this client_info container.
1628  *
1629  * \sa snd_seq_client_info_event_filter_add(),
1630  *     snd_seq_client_info_event_filter_del(),
1631  *     snd_seq_client_info_event_filter_check(),
1632  *     snd_seq_get_client_info(),
1633  *     snd_seq_set_client_info()
1634  */
snd_seq_client_info_event_filter_clear(snd_seq_client_info_t * info)1635 void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
1636 {
1637        assert(info);
1638        info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1639        memset(info->event_filter, 0, sizeof(info->event_filter));
1640 }
1641 
1642 /**
1643  * \brief Add an event type to the event filtering of a client_info container
1644  * \param info client_info container
1645  * \param event_type event type to be added
1646  *
1647  * Set the event filtering flag of this client_info and add the specified event type to the
1648  * filter bitmap of this client_info container.
1649  *
1650  * \sa snd_seq_get_client_info(),
1651  *     snd_seq_set_client_info(),
1652  *     snd_seq_client_info_event_filter_del(),
1653  *     snd_seq_client_info_event_filter_check(),
1654  *     snd_seq_client_info_event_filter_clear()
1655  */
snd_seq_client_info_event_filter_add(snd_seq_client_info_t * info,int event_type)1656 void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
1657 {
1658        assert(info);
1659        info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1660        snd_seq_set_bit(event_type, info->event_filter);
1661 }
1662 
1663 /**
1664  * \brief Remove an event type from the event filtering of a client_info container
1665  * \param info client_info container
1666  * \param event_type event type to be removed
1667  *
1668  * Removes the specified event from the filter bitmap of this client_info container. It will
1669  * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
1670  *
1671  * \sa snd_seq_get_client_info(),
1672  *     snd_seq_set_client_info(),
1673  *     snd_seq_client_info_event_filter_add(),
1674  *     snd_seq_client_info_event_filter_check(),
1675  *     snd_seq_client_info_event_filter_clear()
1676  */
snd_seq_client_info_event_filter_del(snd_seq_client_info_t * info,int event_type)1677 void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
1678 {
1679        assert(info);
1680        snd_seq_unset_bit(event_type, info->event_filter);
1681 }
1682 
1683 /**
1684  * \brief Check if an event type is present in the event filtering of a client_info container
1685  * \param info client_info container
1686  * \param event_type event type to be checked
1687  * \return 1 if the event type is present, 0 otherwise
1688  *
1689  * Test if the event type is in the filter bitmap of this client_info container.
1690  *
1691  * \sa snd_seq_get_client_info(),
1692  *     snd_seq_set_client_info(),
1693  *     snd_seq_client_info_event_filter_add(),
1694  *     snd_seq_client_info_event_filter_del(),
1695  *     snd_seq_client_info_event_filter_clear()
1696  */
snd_seq_client_info_event_filter_check(snd_seq_client_info_t * info,int event_type)1697 int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
1698 {
1699        assert(info);
1700        return snd_seq_get_bit(event_type, info->event_filter);
1701 }
1702 
1703 /**
1704  * \brief Get the number of opened ports of a client_info container
1705  * \param info client_info container
1706  * \return number of opened ports
1707  *
1708  * \sa snd_seq_get_client_info()
1709  */
snd_seq_client_info_get_num_ports(const snd_seq_client_info_t * info)1710 int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
1711 {
1712 	assert(info);
1713 	return info->num_ports;
1714 }
1715 
1716 /**
1717  * \brief Get the number of lost events of a client_info container
1718  * \param info client_info container
1719  * \return number of lost events
1720  *
1721  * \sa snd_seq_get_client_info()
1722  */
snd_seq_client_info_get_event_lost(const snd_seq_client_info_t * info)1723 int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
1724 {
1725 	assert(info);
1726 	return info->event_lost;
1727 }
1728 
1729 /**
1730  * \brief Set the client id of a client_info container
1731  * \param info client_info container
1732  * \param client client id
1733  *
1734  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
1735  */
snd_seq_client_info_set_client(snd_seq_client_info_t * info,int client)1736 void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
1737 {
1738 	assert(info);
1739 	info->client = client;
1740 }
1741 
1742 /**
1743  * \brief Set the name of a client_info container
1744  * \param info client_info container
1745  * \param name name string
1746  *
1747  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
1748  *     snd_seq_set_client_name()
1749  */
snd_seq_client_info_set_name(snd_seq_client_info_t * info,const char * name)1750 void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
1751 {
1752 	assert(info && name);
1753 	snd_strlcpy(info->name, name, sizeof(info->name));
1754 }
1755 
1756 /**
1757  * \brief Set the broadcast filter usage of a client_info container
1758  * \param info client_info container
1759  * \param val non-zero if broadcast is accepted
1760  *
1761  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
1762  */
snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t * info,int val)1763 void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
1764 {
1765 	assert(info);
1766 	if (val)
1767 		info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
1768 	else
1769 		info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
1770 }
1771 
1772 /**
1773  * \brief Set the error-bounce usage of a client_info container
1774  * \param info client_info container
1775  * \param val non-zero if error is bounced
1776  *
1777  * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
1778  */
snd_seq_client_info_set_error_bounce(snd_seq_client_info_t * info,int val)1779 void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
1780 {
1781 	assert(info);
1782 	if (val)
1783 		info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
1784 	else
1785 		info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
1786 }
1787 
1788 /**
1789  * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
1790  * \param info client_info container
1791  * \param filter event filter bitmap, pass NULL for no event filtering
1792  *
1793  * Use #snd_seq_client_info_event_filter_add instead.
1794  *
1795  * \sa snd_seq_client_info_event_filter_add(),
1796  *     snd_seq_client_info_event_filter_del(),
1797  *     snd_seq_client_info_event_filter_check(),
1798  *     snd_seq_client_info_event_filter_clear(),
1799  *     snd_seq_set_client_info()
1800  */
snd_seq_client_info_set_event_filter(snd_seq_client_info_t * info,unsigned char * filter)1801 void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
1802 {
1803 	assert(info);
1804 	if (! filter)
1805 		info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1806 	else {
1807 		info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1808 		memcpy(info->event_filter, filter, sizeof(info->event_filter));
1809 	}
1810 }
1811 
1812 
1813 /**
1814  * \brief obtain the information of the given client
1815  * \param seq sequencer handle
1816  * \param client client id
1817  * \param info the pointer to be stored
1818  * \return 0 on success otherwise a negative error code
1819  *
1820  * Obtains the information of the client with a client id specified by
1821  * info argument.
1822  * The obtained information is written on info parameter.
1823  *
1824  * \sa snd_seq_get_client_info()
1825  */
snd_seq_get_any_client_info(snd_seq_t * seq,int client,snd_seq_client_info_t * info)1826 int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
1827 {
1828 	assert(seq && info && client >= 0);
1829 	memset(info, 0, sizeof(snd_seq_client_info_t));
1830 	info->client = client;
1831 	return seq->ops->get_client_info(seq, info);
1832 }
1833 
1834 /**
1835  * \brief obtain the current client information
1836  * \param seq sequencer handle
1837  * \param info the pointer to be stored
1838  * \return 0 on success otherwise a negative error code
1839  *
1840  * Obtains the information of the current client stored on info.
1841  * client and type fields are ignored.
1842  *
1843  * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
1844  *     snd_seq_query_next_client()
1845  */
snd_seq_get_client_info(snd_seq_t * seq,snd_seq_client_info_t * info)1846 int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1847 {
1848 	return snd_seq_get_any_client_info(seq, seq->client, info);
1849 }
1850 
1851 /**
1852  * \brief set the current client information
1853  * \param seq sequencer handle
1854  * \param info the client info data to set
1855  * \return 0 on success otherwise a negative error code
1856  *
1857  * Obtains the information of the current client stored on info.
1858  * client and type fields are ignored.
1859  *
1860  * \sa snd_seq_get_client_info()
1861  */
snd_seq_set_client_info(snd_seq_t * seq,snd_seq_client_info_t * info)1862 int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1863 {
1864 	assert(seq && info);
1865 	info->client = seq->client;
1866 	info->type = USER_CLIENT;
1867 	return seq->ops->set_client_info(seq, info);
1868 }
1869 
1870 /**
1871  * \brief query the next client
1872  * \param seq sequencer handle
1873  * \param info query pattern and result
1874  *
1875  * Queries the next client.
1876  * The search begins at the client with an id one greater than
1877  * client field in info.
1878  * If a client is found, its attributes are stored in info,
1879  * and zero is returned.
1880  * Otherwise returns a negative error code.
1881  *
1882  * \sa snd_seq_get_any_client_info()
1883  */
snd_seq_query_next_client(snd_seq_t * seq,snd_seq_client_info_t * info)1884 int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
1885 {
1886 	assert(seq && info);
1887 	return seq->ops->query_next_client(seq, info);
1888 }
1889 
1890 
1891 /*----------------------------------------------------------------*/
1892 
1893 
1894 /*
1895  * Port
1896  */
1897 
1898 /**
1899  * \brief get size of #snd_seq_port_info_t
1900  * \return size in bytes
1901  */
snd_seq_port_info_sizeof()1902 size_t snd_seq_port_info_sizeof()
1903 {
1904 	return sizeof(snd_seq_port_info_t);
1905 }
1906 
1907 /**
1908  * \brief allocate an empty #snd_seq_port_info_t using standard malloc
1909  * \param ptr returned pointer
1910  * \return 0 on success otherwise negative error code
1911  */
snd_seq_port_info_malloc(snd_seq_port_info_t ** ptr)1912 int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
1913 {
1914 	assert(ptr);
1915 	*ptr = calloc(1, sizeof(snd_seq_port_info_t));
1916 	if (!*ptr)
1917 		return -ENOMEM;
1918 	return 0;
1919 }
1920 
1921 /**
1922  * \brief frees a previously allocated #snd_seq_port_info_t
1923  * \param obj pointer to object to free
1924  */
snd_seq_port_info_free(snd_seq_port_info_t * obj)1925 void snd_seq_port_info_free(snd_seq_port_info_t *obj)
1926 {
1927 	free(obj);
1928 }
1929 
1930 /**
1931  * \brief copy one #snd_seq_port_info_t to another
1932  * \param dst pointer to destination
1933  * \param src pointer to source
1934  */
snd_seq_port_info_copy(snd_seq_port_info_t * dst,const snd_seq_port_info_t * src)1935 void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
1936 {
1937 	assert(dst && src);
1938 	*dst = *src;
1939 }
1940 
1941 
1942 /**
1943  * \brief Get client id of a port_info container
1944  * \param info port_info container
1945  * \return client id
1946  *
1947  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
1948  */
snd_seq_port_info_get_client(const snd_seq_port_info_t * info)1949 int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
1950 {
1951 	assert(info);
1952 	return info->addr.client;
1953 }
1954 
1955 /**
1956  * \brief Get port id of a port_info container
1957  * \param info port_info container
1958  * \return port id
1959  *
1960  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
1961  */
snd_seq_port_info_get_port(const snd_seq_port_info_t * info)1962 int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
1963 {
1964 	assert(info);
1965 	return info->addr.port;
1966 }
1967 
1968 /**
1969  * \brief Get client/port address of a port_info container
1970  * \param info port_info container
1971  * \return client/port address pointer
1972  *
1973  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
1974  */
snd_seq_port_info_get_addr(const snd_seq_port_info_t * info)1975 const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
1976 {
1977 	assert(info);
1978 	return (const snd_seq_addr_t *) &info->addr;
1979 }
1980 
1981 /**
1982  * \brief Get the name of a port_info container
1983  * \param info port_info container
1984  * \return name string
1985  *
1986  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
1987  */
snd_seq_port_info_get_name(const snd_seq_port_info_t * info)1988 const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
1989 {
1990 	assert(info);
1991 	return info->name;
1992 }
1993 
1994 /**
1995  * \brief Get the capability bits of a port_info container
1996  * \param info port_info container
1997  * \return capability bits
1998  *
1999  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
2000  */
snd_seq_port_info_get_capability(const snd_seq_port_info_t * info)2001 unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
2002 {
2003 	assert(info);
2004 	return info->capability;
2005 }
2006 
2007 /**
2008  * \brief Get the type bits of a port_info container
2009  * \param info port_info container
2010  * \return port type bits
2011  *
2012  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
2013  */
snd_seq_port_info_get_type(const snd_seq_port_info_t * info)2014 unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
2015 {
2016 	assert(info);
2017 	return info->type;
2018 }
2019 
2020 /**
2021  * \brief Get the number of read subscriptions of a port_info container
2022  * \param info port_info container
2023  * \return number of read subscriptions
2024  *
2025  * \sa snd_seq_get_port_info()
2026  */
snd_seq_port_info_get_read_use(const snd_seq_port_info_t * info)2027 int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
2028 {
2029 	assert(info);
2030 	return info->read_use;
2031 }
2032 
2033 /**
2034  * \brief Get the number of write subscriptions of a port_info container
2035  * \param info port_info container
2036  * \return number of write subscriptions
2037  *
2038  * \sa snd_seq_get_port_info()
2039  */
snd_seq_port_info_get_write_use(const snd_seq_port_info_t * info)2040 int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
2041 {
2042 	assert(info);
2043 	return info->write_use;
2044 }
2045 
2046 /**
2047  * \brief Get the midi channels of a port_info container
2048  * \param info port_info container
2049  * \return number of midi channels (default 0)
2050  *
2051  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
2052  */
snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t * info)2053 int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
2054 {
2055 	assert(info);
2056 	return info->midi_channels;
2057 }
2058 
2059 /**
2060  * \brief Get the midi voices of a port_info container
2061  * \param info port_info container
2062  * \return number of midi voices (default 0)
2063  *
2064  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
2065  */
snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t * info)2066 int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
2067 {
2068 	assert(info);
2069 	return info->midi_voices;
2070 }
2071 
2072 /**
2073  * \brief Get the synth voices of a port_info container
2074  * \param info port_info container
2075  * \return number of synth voices (default 0)
2076  *
2077  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
2078  */
snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t * info)2079 int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
2080 {
2081 	assert(info);
2082 	return info->synth_voices;
2083 }
2084 
2085 /**
2086  * \brief Get the port-specified mode of a port_info container
2087  * \param info port_info container
2088  * \return 1 if port id is specified at creation
2089  *
2090  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
2091  */
snd_seq_port_info_get_port_specified(const snd_seq_port_info_t * info)2092 int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
2093 {
2094 	assert(info);
2095 	return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
2096 }
2097 
2098 /**
2099  * \brief Get the time-stamping mode of the given port in a port_info container
2100  * \param info port_info container
2101  * \return 1 if the port updates timestamps of incoming events
2102  *
2103  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
2104  */
snd_seq_port_info_get_timestamping(const snd_seq_port_info_t * info)2105 int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
2106 {
2107 	assert(info);
2108 	return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
2109 }
2110 
2111 /**
2112  * \brief Get whether the time-stamping of the given port is real-time mode
2113  * \param info port_info container
2114  * \return 1 if the time-stamping is in the real-time mode
2115  *
2116  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
2117  */
snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t * info)2118 int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
2119 {
2120 	assert(info);
2121 	return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
2122 }
2123 
2124 /**
2125  * \brief Get the queue id to update timestamps
2126  * \param info port_info container
2127  * \return the queue id to get the timestamps
2128  *
2129  * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
2130  */
snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t * info)2131 int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
2132 {
2133 	assert(info);
2134 	return info->time_queue;
2135 }
2136 
2137 /**
2138  * \brief Set the client id of a port_info container
2139  * \param info port_info container
2140  * \param client client id
2141  *
2142  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
2143  */
snd_seq_port_info_set_client(snd_seq_port_info_t * info,int client)2144 void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
2145 {
2146 	assert(info);
2147 	info->addr.client = client;
2148 }
2149 
2150 /**
2151  * \brief Set the port id of a port_info container
2152  * \param info port_info container
2153  * \param port port id
2154  *
2155  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
2156  */
snd_seq_port_info_set_port(snd_seq_port_info_t * info,int port)2157 void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
2158 {
2159 	assert(info);
2160 	info->addr.port = port;
2161 }
2162 
2163 /**
2164  * \brief Set the client/port address of a port_info container
2165  * \param info port_info container
2166  * \param addr client/port address
2167  *
2168  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
2169  */
snd_seq_port_info_set_addr(snd_seq_port_info_t * info,const snd_seq_addr_t * addr)2170 void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
2171 {
2172 	assert(info);
2173 	info->addr = *(const struct sndrv_seq_addr *)addr;
2174 }
2175 
2176 /**
2177  * \brief Set the name of a port_info container
2178  * \param info port_info container
2179  * \param name name string
2180  *
2181  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
2182  */
snd_seq_port_info_set_name(snd_seq_port_info_t * info,const char * name)2183 void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
2184 {
2185 	assert(info && name);
2186 	snd_strlcpy(info->name, name, sizeof(info->name));
2187 }
2188 
2189 /**
2190  * \brief set the capability bits of a port_info container
2191  * \param info port_info container
2192  * \param capability capability bits
2193  *
2194  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
2195  */
snd_seq_port_info_set_capability(snd_seq_port_info_t * info,unsigned int capability)2196 void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
2197 {
2198 	assert(info);
2199 	info->capability = capability;
2200 }
2201 
2202 /**
2203  * \brief Get the type bits of a port_info container
2204  * \param info port_info container
2205  * \param type port type bits
2206  *
2207  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
2208  */
snd_seq_port_info_set_type(snd_seq_port_info_t * info,unsigned int type)2209 void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
2210 {
2211 	assert(info);
2212 	info->type = type;
2213 }
2214 
2215 /**
2216  * \brief set the midi channels of a port_info container
2217  * \param info port_info container
2218  * \param channels midi channels (default 0)
2219  *
2220  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
2221  */
snd_seq_port_info_set_midi_channels(snd_seq_port_info_t * info,int channels)2222 void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
2223 {
2224 	assert(info);
2225 	info->midi_channels = channels;
2226 }
2227 
2228 /**
2229  * \brief set the midi voices of a port_info container
2230  * \param info port_info container
2231  * \param voices midi voices (default 0)
2232  *
2233  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
2234  */
snd_seq_port_info_set_midi_voices(snd_seq_port_info_t * info,int voices)2235 void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
2236 {
2237 	assert(info);
2238 	info->midi_voices = voices;
2239 }
2240 
2241 /**
2242  * \brief set the synth voices of a port_info container
2243  * \param info port_info container
2244  * \param voices synth voices (default 0)
2245  *
2246  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
2247  */
snd_seq_port_info_set_synth_voices(snd_seq_port_info_t * info,int voices)2248 void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
2249 {
2250 	assert(info);
2251 	info->synth_voices = voices;
2252 }
2253 
2254 /**
2255  * \brief Set the port-specified mode of a port_info container
2256  * \param info port_info container
2257  * \param val non-zero if specifying the port id at creation
2258  *
2259  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
2260  */
snd_seq_port_info_set_port_specified(snd_seq_port_info_t * info,int val)2261 void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
2262 {
2263 	assert(info);
2264 	if (val)
2265 		info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2266 	else
2267 		info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2268 }
2269 
2270 /**
2271  * \brief Set the time-stamping mode of the given port
2272  * \param info port_info container
2273  * \param enable non-zero if updating the timestamps of incoming events
2274  *
2275  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
2276  */
snd_seq_port_info_set_timestamping(snd_seq_port_info_t * info,int enable)2277 void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
2278 {
2279 	assert(info);
2280 	if (enable)
2281 		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2282 	else
2283 		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2284 }
2285 
2286 /**
2287  * \brief Set whether the timestime is updated in the real-time mode
2288  * \param info port_info container
2289  * \param enable non-zero if updating the timestamps in real-time mode
2290  *
2291  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
2292  */
snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t * info,int enable)2293 void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
2294 {
2295 	assert(info);
2296 	if (enable)
2297 		info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
2298 	else
2299 		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
2300 }
2301 
2302 /**
2303  * \brief Set the queue id for timestamping
2304  * \param info port_info container
2305  * \param queue the queue id to get timestamps
2306  *
2307  * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
2308  */
snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t * info,int queue)2309 void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
2310 {
2311 	assert(info);
2312 	info->time_queue = queue;
2313 }
2314 
2315 
2316 /**
2317  * \brief create a sequencer port on the current client
2318  * \param seq sequencer handle
2319  * \param port port information for the new port
2320  * \return 0 on success otherwise a negative error code
2321  *
2322  * Creates a sequencer port on the current client.
2323  * The attributes of created port is specified in \a info argument.
2324  *
2325  * The client field in \a info argument is overwritten with the current client id.
2326  * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
2327  * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
2328  *
2329  * Each port has the capability bit-masks to specify the access capability
2330  * of the port from other clients.
2331  * The capability bit flags are defined as follows:
2332  * - #SND_SEQ_PORT_CAP_READ Readable from this port
2333  * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
2334  * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
2335  * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
2336  * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
2337  * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
2338  * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
2339  * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
2340  *
2341  * Each port has also the type bitmasks defined as follows:
2342  * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
2343  * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
2344  * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
2345  * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
2346  * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
2347  * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
2348  * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
2349  * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
2350  * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
2351  * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
2352  * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
2353  * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
2354  *
2355  * A port may contain specific midi channels, midi voices and synth voices.
2356  * These values could be zero as default.
2357  *
2358  * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
2359  *     snd_seq_create_simple_port()
2360  */
snd_seq_create_port(snd_seq_t * seq,snd_seq_port_info_t * port)2361 int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
2362 {
2363 	assert(seq && port);
2364 	port->addr.client = seq->client;
2365 	return seq->ops->create_port(seq, port);
2366 }
2367 
2368 /**
2369  * \brief delete a sequencer port on the current client
2370  * \param seq sequencer handle
2371  * \param port port to be deleted
2372  * \return 0 on success otherwise a negative error code
2373  *
2374  * Deletes the existing sequencer port on the current client.
2375  *
2376  * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
2377  */
snd_seq_delete_port(snd_seq_t * seq,int port)2378 int snd_seq_delete_port(snd_seq_t *seq, int port)
2379 {
2380 	snd_seq_port_info_t pinfo;
2381 	assert(seq);
2382 	memset(&pinfo, 0, sizeof(pinfo));
2383 	pinfo.addr.client = seq->client;
2384 	pinfo.addr.port = port;
2385 	return seq->ops->delete_port(seq, &pinfo);
2386 }
2387 
2388 /**
2389  * \brief obtain the information of a port on an arbitrary client
2390  * \param seq sequencer handle
2391  * \param client client id to get
2392  * \param port port id to get
2393  * \param info pointer information returns
2394  * \return 0 on success otherwise a negative error code
2395  *
2396  * \sa snd_seq_get_port_info()
2397  */
snd_seq_get_any_port_info(snd_seq_t * seq,int client,int port,snd_seq_port_info_t * info)2398 int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
2399 {
2400 	assert(seq && info && client >= 0 && port >= 0);
2401 	memset(info, 0, sizeof(snd_seq_port_info_t));
2402 	info->addr.client = client;
2403 	info->addr.port = port;
2404 	return seq->ops->get_port_info(seq, info);
2405 }
2406 
2407 /**
2408  * \brief obtain the information of a port on the current client
2409  * \param seq sequencer handle
2410  * \param port port id to get
2411  * \param info pointer information returns
2412  * \return 0 on success otherwise a negative error code
2413  *
2414  * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
2415  *     snd_seq_query_next_port()
2416  */
snd_seq_get_port_info(snd_seq_t * seq,int port,snd_seq_port_info_t * info)2417 int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2418 {
2419 	return snd_seq_get_any_port_info(seq, seq->client, port, info);
2420 }
2421 
2422 /**
2423  * \brief set the information of a port on the current client
2424  * \param seq sequencer handle
2425  * \param port port to be set
2426  * \param info port information to be set
2427  * \return 0 on success otherwise a negative error code
2428  *
2429  * \sa snd_seq_set_port_info()
2430  */
snd_seq_set_port_info(snd_seq_t * seq,int port,snd_seq_port_info_t * info)2431 int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2432 {
2433 	assert(seq && info && port >= 0);
2434 	info->addr.client = seq->client;
2435 	info->addr.port = port;
2436 	return seq->ops->set_port_info(seq, info);
2437 }
2438 
2439 /**
2440  * \brief query the next matching port
2441  * \param seq sequencer handle
2442  * \param info query pattern and result
2443 
2444  * Queries the next matching port on the client specified in
2445  * \a info argument.
2446  * The search begins at the next port specified in
2447  * port field of \a info argument.
2448  * For finding the first port at a certain client, give -1.
2449  *
2450  * If a matching port is found, its attributes are stored on
2451  * \a info and function returns zero.
2452  * Otherwise, a negative error code is returned.
2453  *
2454  * \sa snd_seq_get_port_info()
2455  */
snd_seq_query_next_port(snd_seq_t * seq,snd_seq_port_info_t * info)2456 int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
2457 {
2458 	assert(seq && info);
2459 	return seq->ops->query_next_port(seq, info);
2460 }
2461 
2462 
2463 /*----------------------------------------------------------------*/
2464 
2465 /*
2466  * subscription
2467  */
2468 
2469 
2470 /**
2471  * \brief get size of #snd_seq_port_subscribe_t
2472  * \return size in bytes
2473  */
snd_seq_port_subscribe_sizeof()2474 size_t snd_seq_port_subscribe_sizeof()
2475 {
2476 	return sizeof(snd_seq_port_subscribe_t);
2477 }
2478 
2479 /**
2480  * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
2481  * \param ptr returned pointer
2482  * \return 0 on success otherwise negative error code
2483  */
snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t ** ptr)2484 int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
2485 {
2486 	assert(ptr);
2487 	*ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
2488 	if (!*ptr)
2489 		return -ENOMEM;
2490 	return 0;
2491 }
2492 
2493 /**
2494  * \brief frees a previously allocated #snd_seq_port_subscribe_t
2495  * \param obj pointer to object to free
2496  */
snd_seq_port_subscribe_free(snd_seq_port_subscribe_t * obj)2497 void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
2498 {
2499 	free(obj);
2500 }
2501 
2502 /**
2503  * \brief copy one #snd_seq_port_subscribe_t to another
2504  * \param dst pointer to destination
2505  * \param src pointer to source
2506  */
snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t * dst,const snd_seq_port_subscribe_t * src)2507 void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
2508 {
2509 	assert(dst && src);
2510 	*dst = *src;
2511 }
2512 
2513 
2514 /**
2515  * \brief Get sender address of a port_subscribe container
2516  * \param info port_subscribe container
2517  *
2518  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
2519  */
snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t * info)2520 const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
2521 {
2522 	assert(info);
2523 	return (const snd_seq_addr_t *)&info->sender;
2524 }
2525 
2526 /**
2527  * \brief Get destination address of a port_subscribe container
2528  * \param info port_subscribe container
2529  *
2530  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
2531  */
snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t * info)2532 const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
2533 {
2534 	assert(info);
2535 	return (const snd_seq_addr_t *)&info->dest;
2536 }
2537 
2538 /**
2539  * \brief Get the queue id of a port_subscribe container
2540  * \param info port_subscribe container
2541  * \return queue id
2542  *
2543  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
2544  */
snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t * info)2545 int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
2546 {
2547 	assert(info);
2548 	return info->queue;
2549 }
2550 
2551 /**
2552  * \brief Get the exclusive mode of a port_subscribe container
2553  * \param info port_subscribe container
2554  * \return 1 if exclusive mode
2555  *
2556  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
2557  */
snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t * info)2558 int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
2559 {
2560 	assert(info);
2561 	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2562 }
2563 
2564 /**
2565  * \brief Get the time-update mode of a port_subscribe container
2566  * \param info port_subscribe container
2567  * \return 1 if update timestamp
2568  *
2569  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
2570  */
snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t * info)2571 int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
2572 {
2573 	assert(info);
2574 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2575 }
2576 
2577 /**
2578  * \brief Get the real-time update mode of a port_subscribe container
2579  * \param info port_subscribe container
2580  * \return 1 if real-time update mode
2581  *
2582  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
2583  */
snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t * info)2584 int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
2585 {
2586 	assert(info);
2587 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
2588 }
2589 
2590 /**
2591  * \brief Set sender address of a port_subscribe container
2592  * \param info port_subscribe container
2593  * \param addr sender address
2594  *
2595  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
2596  */
snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t * info,const snd_seq_addr_t * addr)2597 void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2598 {
2599 	assert(info);
2600 	memcpy(&info->sender, addr, sizeof(*addr));
2601 }
2602 
2603 /**
2604  * \brief Set destination address of a port_subscribe container
2605  * \param info port_subscribe container
2606  * \param addr destination address
2607  *
2608  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
2609  */
snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t * info,const snd_seq_addr_t * addr)2610 void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2611 {
2612 	assert(info);
2613 	memcpy(&info->dest, addr, sizeof(*addr));
2614 }
2615 
2616 /**
2617  * \brief Set the queue id of a port_subscribe container
2618  * \param info port_subscribe container
2619  * \param q queue id
2620  *
2621  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
2622  */
snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t * info,int q)2623 void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
2624 {
2625 	assert(info);
2626 	info->queue = q;
2627 }
2628 
2629 /**
2630  * \brief Set the exclusive mode of a port_subscribe container
2631  * \param info port_subscribe container
2632  * \param val non-zero to enable
2633  *
2634  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
2635  */
snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t * info,int val)2636 void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
2637 {
2638 	assert(info);
2639 	if (val)
2640 		info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2641 	else
2642 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2643 }
2644 
2645 /**
2646  * \brief Set the time-update mode of a port_subscribe container
2647  * \param info port_subscribe container
2648  * \param val non-zero to enable
2649  *
2650  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
2651  */
snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t * info,int val)2652 void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
2653 {
2654 	assert(info);
2655 	if (val)
2656 		info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2657 	else
2658 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2659 }
2660 
2661 /**
2662  * \brief Set the real-time mode of a port_subscribe container
2663  * \param info port_subscribe container
2664  * \param val non-zero to enable
2665  *
2666  * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
2667  */
snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t * info,int val)2668 void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
2669 {
2670 	assert(info);
2671 	if (val)
2672 		info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2673 	else
2674 		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2675 }
2676 
2677 
2678 /**
2679  * \brief obtain subscription information
2680  * \param seq sequencer handle
2681  * \param sub pointer to return the subscription information
2682  * \return 0 on success otherwise a negative error code
2683  *
2684  * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
2685  */
snd_seq_get_port_subscription(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2686 int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2687 {
2688 	assert(seq && sub);
2689 	return seq->ops->get_port_subscription(seq, sub);
2690 }
2691 
2692 /**
2693  * \brief subscribe a port connection
2694  * \param seq sequencer handle
2695  * \param sub subscription information
2696  * \return 0 on success otherwise a negative error code
2697  *
2698  * Subscribes a connection between two ports.
2699  * The subscription information is stored in sub argument.
2700  *
2701  * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
2702  *     snd_seq_connect_from(), snd_seq_connect_to()
2703  */
snd_seq_subscribe_port(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2704 int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2705 {
2706 	assert(seq && sub);
2707 	return seq->ops->subscribe_port(seq, sub);
2708 }
2709 
2710 /**
2711  * \brief unsubscribe a connection between ports
2712  * \param seq sequencer handle
2713  * \param sub subscription information to disconnect
2714  * \return 0 on success otherwise a negative error code
2715  *
2716  * Unsubscribes a connection between two ports,
2717  * described in sender and dest fields in sub argument.
2718  *
2719  * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
2720  */
snd_seq_unsubscribe_port(snd_seq_t * seq,snd_seq_port_subscribe_t * sub)2721 int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2722 {
2723 	assert(seq && sub);
2724 	return seq->ops->unsubscribe_port(seq, sub);
2725 }
2726 
2727 
2728 /**
2729  * \brief get size of #snd_seq_query_subscribe_t
2730  * \return size in bytes
2731  */
snd_seq_query_subscribe_sizeof()2732 size_t snd_seq_query_subscribe_sizeof()
2733 {
2734 	return sizeof(snd_seq_query_subscribe_t);
2735 }
2736 
2737 /**
2738  * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
2739  * \param ptr returned pointer
2740  * \return 0 on success otherwise negative error code
2741  */
snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t ** ptr)2742 int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
2743 {
2744 	assert(ptr);
2745 	*ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
2746 	if (!*ptr)
2747 		return -ENOMEM;
2748 	return 0;
2749 }
2750 
2751 /**
2752  * \brief frees a previously allocated #snd_seq_query_subscribe_t
2753  * \param obj pointer to object to free
2754  */
snd_seq_query_subscribe_free(snd_seq_query_subscribe_t * obj)2755 void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
2756 {
2757 	free(obj);
2758 }
2759 
2760 /**
2761  * \brief copy one #snd_seq_query_subscribe_t to another
2762  * \param dst pointer to destination
2763  * \param src pointer to source
2764  */
snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t * dst,const snd_seq_query_subscribe_t * src)2765 void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
2766 {
2767 	assert(dst && src);
2768 	*dst = *src;
2769 }
2770 
2771 
2772 /**
2773  * \brief Get the client id of a query_subscribe container
2774  * \param info query_subscribe container
2775  * \return client id
2776  *
2777  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
2778  */
snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t * info)2779 int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
2780 {
2781 	assert(info);
2782 	return info->root.client;
2783 }
2784 
2785 /**
2786  * \brief Get the port id of a query_subscribe container
2787  * \param info query_subscribe container
2788  * \return port id
2789  *
2790  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
2791  */
snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t * info)2792 int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
2793 {
2794 	assert(info);
2795 	return info->root.port;
2796 }
2797 
2798 /**
2799  * \brief Get the client/port address of a query_subscribe container
2800  * \param info query_subscribe container
2801  * \return client/port address pointer
2802  *
2803  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
2804  */
snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t * info)2805 const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
2806 {
2807 	assert(info);
2808 	return (const snd_seq_addr_t *)&info->root;
2809 }
2810 
2811 /**
2812  * \brief Get the query type of a query_subscribe container
2813  * \param info query_subscribe container
2814  * \return query type
2815  *
2816  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
2817  */
snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t * info)2818 snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
2819 {
2820 	assert(info);
2821 	return info->type;
2822 }
2823 
2824 /**
2825  * \brief Get the index of subscriber of a query_subscribe container
2826  * \param info query_subscribe container
2827  * \return subscriber's index
2828  *
2829  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
2830  */
snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t * info)2831 int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
2832 {
2833 	assert(info);
2834 	return info->index;
2835 }
2836 
2837 /**
2838  * \brief Get the number of subscriptions of a query_subscribe container
2839  * \param info query_subscribe container
2840  * \return number of subscriptions
2841  *
2842  * \sa snd_seq_query_port_subscribers()
2843  */
snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t * info)2844 int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
2845 {
2846 	assert(info);
2847 	return info->num_subs;
2848 }
2849 
2850 /**
2851  * \brief Get the address of subscriber of a query_subscribe container
2852  * \param info query_subscribe container
2853  * \return subscriber's address pointer
2854  *
2855  * \sa snd_seq_query_port_subscribers()
2856  */
snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t * info)2857 const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
2858 {
2859 	assert(info);
2860 	return (const snd_seq_addr_t *)&info->addr;
2861 }
2862 
2863 /**
2864  * \brief Get the queue id of subscriber of a query_subscribe container
2865  * \param info query_subscribe container
2866  * \return subscriber's queue id
2867  *
2868  * \sa snd_seq_query_port_subscribers()
2869  */
snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t * info)2870 int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
2871 {
2872 	assert(info);
2873 	return info->queue;
2874 }
2875 
2876 /**
2877  * \brief Get the exclusive mode of a query_subscribe container
2878  * \param info query_subscribe container
2879  * \return 1 if exclusive mode
2880  *
2881  * \sa snd_seq_query_port_subscribers()
2882  */
snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t * info)2883 int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
2884 {
2885 	assert(info);
2886 	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2887 }
2888 
2889 /**
2890  * \brief Get the time-update mode of a query_subscribe container
2891  * \param info query_subscribe container
2892  * \return 1 if update timestamp
2893  *
2894  * \sa snd_seq_query_port_subscribers()
2895  */
snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t * info)2896 int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
2897 {
2898 	assert(info);
2899 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2900 }
2901 
2902 /**
2903  * \brief Get the real-time update mode of a query_subscribe container
2904  * \param info query_subscribe container
2905  * \return 1 if real-time update mode
2906  *
2907  * \sa snd_seq_query_port_subscribers()
2908  */
snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t * info)2909 int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
2910 {
2911 	assert(info);
2912 	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2913 }
2914 
2915 /**
2916  * \brief Set the client id of a query_subscribe container
2917  * \param info query_subscribe container
2918  * \param client client id
2919  *
2920  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
2921  */
snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t * info,int client)2922 void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
2923 {
2924 	assert(info);
2925 	info->root.client = client;
2926 }
2927 
2928 /**
2929  * \brief Set the port id of a query_subscribe container
2930  * \param info query_subscribe container
2931  * \param port port id
2932  *
2933  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
2934  */
snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t * info,int port)2935 void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
2936 {
2937 	assert(info);
2938 	info->root.port = port;
2939 }
2940 
2941 /**
2942  * \brief Set the client/port address of a query_subscribe container
2943  * \param info query_subscribe container
2944  * \param addr client/port address pointer
2945  *
2946  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
2947  */
snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t * info,const snd_seq_addr_t * addr)2948 void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
2949 {
2950 	assert(info);
2951 	info->root = *(const struct snd_seq_addr *)addr;
2952 }
2953 
2954 /**
2955  * \brief Set the query type of a query_subscribe container
2956  * \param info query_subscribe container
2957  * \param type query type
2958  *
2959  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
2960  */
snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t * info,snd_seq_query_subs_type_t type)2961 void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
2962 {
2963 	assert(info);
2964 	info->type = type;
2965 }
2966 
2967 /**
2968  * \brief Set the subscriber's index to be queried
2969  * \param info query_subscribe container
2970  * \param index index to be queried
2971  *
2972  * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
2973  */
snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t * info,int index)2974 void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
2975 {
2976 	assert(info);
2977 	info->index = index;
2978 }
2979 
2980 
2981 /**
2982  * \brief query port subscriber list
2983  * \param seq sequencer handle
2984  * \param subs subscription to query
2985  * \return 0 on success otherwise a negative error code
2986  *
2987  * Queries the subscribers accessing to a port.
2988  * The query information is specified in subs argument.
2989  *
2990  * At least, the client id, the port id, the index number and
2991  * the query type must be set to perform a proper query.
2992  * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
2993  * can be specified to check whether the readers or the writers to the port.
2994  * To query the first subscription, set 0 to the index number.  To list up
2995  * all the subscriptions, call this function with the index numbers from 0
2996  * until this returns a negative value.
2997  *
2998  * \sa snd_seq_get_port_subscription()
2999  */
snd_seq_query_port_subscribers(snd_seq_t * seq,snd_seq_query_subscribe_t * subs)3000 int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
3001 {
3002 	assert(seq && subs);
3003 	return seq->ops->query_port_subscribers(seq, subs);
3004 }
3005 
3006 /*----------------------------------------------------------------*/
3007 
3008 /*
3009  * queue handlers
3010  */
3011 
3012 /**
3013  * \brief get size of #snd_seq_queue_info_t
3014  * \return size in bytes
3015  */
snd_seq_queue_info_sizeof()3016 size_t snd_seq_queue_info_sizeof()
3017 {
3018 	return sizeof(snd_seq_queue_info_t);
3019 }
3020 
3021 /**
3022  * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
3023  * \param ptr returned pointer
3024  * \return 0 on success otherwise negative error code
3025  */
snd_seq_queue_info_malloc(snd_seq_queue_info_t ** ptr)3026 int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
3027 {
3028 	assert(ptr);
3029 	*ptr = calloc(1, sizeof(snd_seq_queue_info_t));
3030 	if (!*ptr)
3031 		return -ENOMEM;
3032 	return 0;
3033 }
3034 
3035 /**
3036  * \brief frees a previously allocated #snd_seq_queue_info_t
3037  * \param obj pointer to object to free
3038  */
snd_seq_queue_info_free(snd_seq_queue_info_t * obj)3039 void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
3040 {
3041 	free(obj);
3042 }
3043 
3044 /**
3045  * \brief copy one #snd_seq_queue_info_t to another
3046  * \param dst pointer to destination
3047  * \param src pointer to source
3048  */
snd_seq_queue_info_copy(snd_seq_queue_info_t * dst,const snd_seq_queue_info_t * src)3049 void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
3050 {
3051 	assert(dst && src);
3052 	*dst = *src;
3053 }
3054 
3055 
3056 /**
3057  * \brief Get the queue id of a queue_info container
3058  * \param info queue_info container
3059  * \return queue id
3060  *
3061  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
3062  */
snd_seq_queue_info_get_queue(const snd_seq_queue_info_t * info)3063 int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
3064 {
3065 	assert(info);
3066 	return info->queue;
3067 }
3068 
3069 /**
3070  * \brief Get the name of a queue_info container
3071  * \param info queue_info container
3072  * \return name string
3073  *
3074  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
3075  */
snd_seq_queue_info_get_name(const snd_seq_queue_info_t * info)3076 const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
3077 {
3078 	assert(info);
3079 	return info->name;
3080 }
3081 
3082 /**
3083  * \brief Get the owner client id of a queue_info container
3084  * \param info queue_info container
3085  * \return owner client id
3086  *
3087  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
3088  */
snd_seq_queue_info_get_owner(const snd_seq_queue_info_t * info)3089 int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
3090 {
3091 	assert(info);
3092 	return info->owner;
3093 }
3094 
3095 /**
3096  * \brief Get the lock status of a queue_info container
3097  * \param info queue_info container
3098  * \return lock status --- non-zero = locked
3099  *
3100  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
3101  */
snd_seq_queue_info_get_locked(const snd_seq_queue_info_t * info)3102 int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
3103 {
3104 	assert(info);
3105 	return info->locked;
3106 }
3107 
3108 /**
3109  * \brief Get the conditional bit flags of a queue_info container
3110  * \param info queue_info container
3111  * \return conditional bit flags
3112  *
3113  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
3114  */
snd_seq_queue_info_get_flags(const snd_seq_queue_info_t * info)3115 unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
3116 {
3117 	assert(info);
3118 	return info->flags;
3119 }
3120 
3121 /**
3122  * \brief Set the name of a queue_info container
3123  * \param info queue_info container
3124  * \param name name string
3125  *
3126  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
3127  */
snd_seq_queue_info_set_name(snd_seq_queue_info_t * info,const char * name)3128 void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
3129 {
3130 	assert(info && name);
3131 	snd_strlcpy(info->name, name, sizeof(info->name));
3132 }
3133 
3134 /**
3135  * \brief Set the owner client id of a queue_info container
3136  * \param info queue_info container
3137  * \param owner client id
3138  *
3139  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
3140  */
snd_seq_queue_info_set_owner(snd_seq_queue_info_t * info,int owner)3141 void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
3142 {
3143 	assert(info);
3144 	info->owner = owner;
3145 }
3146 
3147 /**
3148  * \brief Set the lock status of a queue_info container
3149  * \param info queue_info container
3150  * \param locked lock status
3151  *
3152  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
3153  */
snd_seq_queue_info_set_locked(snd_seq_queue_info_t * info,int locked)3154 void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
3155 {
3156 	assert(info);
3157 	info->locked = locked;
3158 }
3159 
3160 /**
3161  * \brief Set the conditional bit flags of a queue_info container
3162  * \param info queue_info container
3163  * \param flags conditional bit flags
3164  *
3165  * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
3166  */
snd_seq_queue_info_set_flags(snd_seq_queue_info_t * info,unsigned int flags)3167 void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
3168 {
3169 	assert(info);
3170 	info->flags = flags;
3171 }
3172 
3173 
3174 /**
3175  * \brief create a queue
3176  * \param seq sequencer handle
3177  * \param info queue information to initialize
3178  * \return the queue id (zero or positive) on success otherwise a negative error code
3179  *
3180  * \sa snd_seq_alloc_queue()
3181  */
snd_seq_create_queue(snd_seq_t * seq,snd_seq_queue_info_t * info)3182 int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
3183 {
3184 	int err;
3185 	assert(seq && info);
3186 	info->owner = seq->client;
3187 	err = seq->ops->create_queue(seq, info);
3188 	if (err < 0)
3189 		return err;
3190 	return info->queue;
3191 }
3192 
3193 /**
3194  * \brief allocate a queue with the specified name
3195  * \param seq sequencer handle
3196  * \param name the name of the new queue
3197  * \return the queue id (zero or positive) on success otherwise a negative error code
3198  *
3199  * \sa snd_seq_alloc_queue()
3200  */
snd_seq_alloc_named_queue(snd_seq_t * seq,const char * name)3201 int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
3202 {
3203 	snd_seq_queue_info_t info;
3204 	memset(&info, 0, sizeof(info));
3205 	info.locked = 1;
3206 	if (name)
3207 		snd_strlcpy(info.name, name, sizeof(info.name));
3208 	return snd_seq_create_queue(seq, &info);
3209 }
3210 
3211 /**
3212  * \brief allocate a queue
3213  * \param seq sequencer handle
3214  * \return the queue id (zero or positive) on success otherwise a negative error code
3215  *
3216  * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
3217  *     snd_seq_get_queue_info()
3218  */
snd_seq_alloc_queue(snd_seq_t * seq)3219 int snd_seq_alloc_queue(snd_seq_t *seq)
3220 {
3221 	return snd_seq_alloc_named_queue(seq, NULL);
3222 }
3223 
3224 /**
3225  * \brief delete the specified queue
3226  * \param seq sequencer handle
3227  * \param q queue id to delete
3228  * \return 0 on success otherwise a negative error code
3229  *
3230  * \sa snd_seq_alloc_queue()
3231  */
snd_seq_free_queue(snd_seq_t * seq,int q)3232 int snd_seq_free_queue(snd_seq_t *seq, int q)
3233 {
3234 	snd_seq_queue_info_t info;
3235 	assert(seq);
3236 	memset(&info, 0, sizeof(info));
3237 	info.queue = q;
3238 	return seq->ops->delete_queue(seq, &info);
3239 }
3240 
3241 /**
3242  * \brief obtain queue attributes
3243  * \param seq sequencer handle
3244  * \param q queue id to query
3245  * \param info information returned
3246  * \return 0 on success otherwise a negative error code
3247  *
3248  * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
3249  */
snd_seq_get_queue_info(snd_seq_t * seq,int q,snd_seq_queue_info_t * info)3250 int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3251 {
3252 	assert(seq && info);
3253 	info->queue = q;
3254 	return seq->ops->get_queue_info(seq, info);
3255 }
3256 
3257 /**
3258  * \brief change the queue attributes
3259  * \param seq sequencer handle
3260  * \param q queue id to change
3261  * \param info information changed
3262  * \return 0 on success otherwise a negative error code
3263  *
3264  * \sa snd_seq_get_queue_info()
3265  */
snd_seq_set_queue_info(snd_seq_t * seq,int q,snd_seq_queue_info_t * info)3266 int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3267 {
3268 	assert(seq && info);
3269 	info->queue = q;
3270 	return seq->ops->set_queue_info(seq, info);
3271 }
3272 
3273 /**
3274  * \brief query the matching queue with the specified name
3275  * \param seq sequencer handle
3276  * \param name the name string to query
3277  * \return the queue id if found or negative error code
3278  *
3279  * Searches the matching queue with the specified name string.
3280  *
3281  * \sa snd_seq_get_queue_info()
3282  */
snd_seq_query_named_queue(snd_seq_t * seq,const char * name)3283 int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
3284 {
3285 	int err;
3286 	snd_seq_queue_info_t info;
3287 	assert(seq && name);
3288 	snd_strlcpy(info.name, name, sizeof(info.name));
3289 	err = seq->ops->get_named_queue(seq, &info);
3290 	if (err < 0)
3291 		return err;
3292 	return info.queue;
3293 }
3294 
3295 /**
3296  * \brief Get the queue usage flag to the client
3297  * \param seq sequencer handle
3298  * \param q queue id
3299  * \return 1 = client is allowed to access the queue, 0 = not allowed,
3300  *     otherwise a negative error code
3301  *
3302  * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3303  */
snd_seq_get_queue_usage(snd_seq_t * seq,int q)3304 int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
3305 {
3306 	struct snd_seq_queue_client info;
3307 	int err;
3308 	assert(seq);
3309 	memset(&info, 0, sizeof(info));
3310 	info.queue = q;
3311 	info.client = seq->client;
3312 	if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
3313 		return err;
3314 	return info.used;
3315 }
3316 
3317 /**
3318  * \brief Set the queue usage flag to the client
3319  * \param seq sequencer handle
3320  * \param q queue id
3321  * \param used non-zero if the client is allowed
3322  * \return 0 on success otherwise a negative error code
3323  *
3324  * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3325  */
snd_seq_set_queue_usage(snd_seq_t * seq,int q,int used)3326 int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
3327 {
3328 	struct snd_seq_queue_client info;
3329 	assert(seq);
3330 	memset(&info, 0, sizeof(info));
3331 	info.queue = q;
3332 	info.client = seq->client;
3333 	info.used = used ? 1 : 0;
3334 	return seq->ops->set_queue_client(seq, &info);
3335 }
3336 
3337 
3338 /**
3339  * \brief get size of #snd_seq_queue_status_t
3340  * \return size in bytes
3341  */
snd_seq_queue_status_sizeof()3342 size_t snd_seq_queue_status_sizeof()
3343 {
3344 	return sizeof(snd_seq_queue_status_t);
3345 }
3346 
3347 /**
3348  * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
3349  * \param ptr returned pointer
3350  * \return 0 on success otherwise negative error code
3351  */
snd_seq_queue_status_malloc(snd_seq_queue_status_t ** ptr)3352 int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
3353 {
3354 	assert(ptr);
3355 	*ptr = calloc(1, sizeof(snd_seq_queue_status_t));
3356 	if (!*ptr)
3357 		return -ENOMEM;
3358 	return 0;
3359 }
3360 
3361 /**
3362  * \brief frees a previously allocated #snd_seq_queue_status_t
3363  * \param obj pointer to object to free
3364  */
snd_seq_queue_status_free(snd_seq_queue_status_t * obj)3365 void snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
3366 {
3367 	free(obj);
3368 }
3369 
3370 /**
3371  * \brief copy one #snd_seq_queue_status_t to another
3372  * \param dst pointer to destination
3373  * \param src pointer to source
3374  */
snd_seq_queue_status_copy(snd_seq_queue_status_t * dst,const snd_seq_queue_status_t * src)3375 void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
3376 {
3377 	assert(dst && src);
3378 	*dst = *src;
3379 }
3380 
3381 
3382 /**
3383  * \brief Get the queue id of a queue_status container
3384  * \param info queue_status container
3385  * \return queue id
3386  *
3387  * \sa snd_seq_get_queue_status()
3388  */
snd_seq_queue_status_get_queue(const snd_seq_queue_status_t * info)3389 int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
3390 {
3391 	assert(info);
3392 	return info->queue;
3393 }
3394 
3395 /**
3396  * \brief Get the number of events of a queue_status container
3397  * \param info queue_status container
3398  * \return number of events
3399  *
3400  * \sa snd_seq_get_queue_status()
3401  */
snd_seq_queue_status_get_events(const snd_seq_queue_status_t * info)3402 int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
3403 {
3404 	assert(info);
3405 	return info->events;
3406 }
3407 
3408 /**
3409  * \brief Get the tick time of a queue_status container
3410  * \param info queue_status container
3411  * \return tick time
3412  *
3413  * \sa snd_seq_get_queue_status()
3414  */
snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t * info)3415 snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
3416 {
3417 	assert(info);
3418 	return info->tick;
3419 }
3420 
3421 /**
3422  * \brief Get the real time of a queue_status container
3423  * \param info queue_status container
3424  *
3425  * \sa snd_seq_get_queue_status()
3426  */
snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t * info)3427 const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
3428 {
3429 	assert(info);
3430 	return (const snd_seq_real_time_t *)&info->time;
3431 }
3432 
3433 /**
3434  * \brief Get the running status bits of a queue_status container
3435  * \param info queue_status container
3436  * \return running status bits
3437  *
3438  * \sa snd_seq_get_queue_status()
3439  */
snd_seq_queue_status_get_status(const snd_seq_queue_status_t * info)3440 unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
3441 {
3442 	assert(info);
3443 	return info->running;
3444 }
3445 
3446 
3447 /**
3448  * \brief obtain the running state of the queue
3449  * \param seq sequencer handle
3450  * \param q queue id to query
3451  * \param status pointer to store the current status
3452  * \return 0 on success otherwise a negative error code
3453  *
3454  * Obtains the running state of the specified queue q.
3455  */
snd_seq_get_queue_status(snd_seq_t * seq,int q,snd_seq_queue_status_t * status)3456 int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
3457 {
3458 	assert(seq && status);
3459 	memset(status, 0, sizeof(snd_seq_queue_status_t));
3460 	status->queue = q;
3461 	return seq->ops->get_queue_status(seq, status);
3462 }
3463 
3464 
3465 /**
3466  * \brief get size of #snd_seq_queue_tempo_t
3467  * \return size in bytes
3468  */
snd_seq_queue_tempo_sizeof()3469 size_t snd_seq_queue_tempo_sizeof()
3470 {
3471 	return sizeof(snd_seq_queue_tempo_t);
3472 }
3473 
3474 /**
3475  * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
3476  * \param ptr returned pointer
3477  * \return 0 on success otherwise negative error code
3478  */
snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t ** ptr)3479 int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
3480 {
3481 	assert(ptr);
3482 	*ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
3483 	if (!*ptr)
3484 		return -ENOMEM;
3485 	return 0;
3486 }
3487 
3488 /**
3489  * \brief frees a previously allocated #snd_seq_queue_tempo_t
3490  * \param obj pointer to object to free
3491  */
snd_seq_queue_tempo_free(snd_seq_queue_tempo_t * obj)3492 void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
3493 {
3494 	free(obj);
3495 }
3496 
3497 /**
3498  * \brief copy one #snd_seq_queue_tempo_t to another
3499  * \param dst pointer to destination
3500  * \param src pointer to source
3501  */
snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t * dst,const snd_seq_queue_tempo_t * src)3502 void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
3503 {
3504 	assert(dst && src);
3505 	*dst = *src;
3506 }
3507 
3508 
3509 /**
3510  * \brief Get the queue id of a queue_status container
3511  * \param info queue_status container
3512  * \return queue id
3513  *
3514  * \sa snd_seq_get_queue_tempo()
3515  */
snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t * info)3516 int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
3517 {
3518 	assert(info);
3519 	return info->queue;
3520 }
3521 
3522 /**
3523  * \brief Get the tempo of a queue_status container
3524  * \param info queue_status container
3525  * \return tempo value
3526  *
3527  * \sa snd_seq_get_queue_tempo()
3528  */
snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t * info)3529 unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
3530 {
3531 	assert(info);
3532 	return info->tempo;
3533 }
3534 
3535 /**
3536  * \brief Get the ppq of a queue_status container
3537  * \param info queue_status container
3538  * \return ppq value
3539  *
3540  * \sa snd_seq_get_queue_tempo()
3541  */
snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t * info)3542 int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
3543 {
3544 	assert(info);
3545 	return info->ppq;
3546 }
3547 
3548 /**
3549  * \brief Get the timer skew value of a queue_status container
3550  * \param info queue_status container
3551  * \return timer skew value
3552  *
3553  * \sa snd_seq_get_queue_tempo()
3554  */
snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t * info)3555 unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info)
3556 {
3557 	assert(info);
3558 	return info->skew_value;
3559 }
3560 
3561 /**
3562  * \brief Get the timer skew base value of a queue_status container
3563  * \param info queue_status container
3564  * \return timer skew base value
3565  *
3566  * \sa snd_seq_get_queue_tempo()
3567  */
snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t * info)3568 unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info)
3569 {
3570 	assert(info);
3571 	return info->skew_base;
3572 }
3573 
3574 /**
3575  * \brief Set the tempo of a queue_status container
3576  * \param info queue_status container
3577  * \param tempo tempo value
3578  *
3579  * \sa snd_seq_get_queue_tempo()
3580  */
snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t * info,unsigned int tempo)3581 void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
3582 {
3583 	assert(info);
3584 	info->tempo = tempo;
3585 }
3586 
3587 /**
3588  * \brief Set the ppq of a queue_status container
3589  * \param info queue_status container
3590  * \param ppq ppq value
3591  *
3592  * \sa snd_seq_get_queue_tempo()
3593  */
snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t * info,int ppq)3594 void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
3595 {
3596 	assert(info);
3597 	info->ppq = ppq;
3598 }
3599 
3600 /**
3601  * \brief Set the timer skew value of a queue_status container
3602  * \param info queue_status container
3603  * \param skew timer skew value
3604  *
3605  * The skew of timer is calculated as skew / base.
3606  * For example, to play with double speed, pass base * 2 as the skew value.
3607  *
3608  * \sa snd_seq_get_queue_tempo()
3609  */
snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t * info,unsigned int skew)3610 void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew)
3611 {
3612 	assert(info);
3613 	info->skew_value = skew;
3614 }
3615 
3616 /**
3617  * \brief Set the timer skew base value of a queue_status container
3618  * \param info queue_status container
3619  * \param base timer skew base value
3620  *
3621  * \sa snd_seq_get_queue_tempo()
3622  */
snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t * info,unsigned int base)3623 void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base)
3624 {
3625 	assert(info);
3626 	info->skew_base = base;
3627 }
3628 
3629 /**
3630  * \brief obtain the current tempo of the queue
3631  * \param seq sequencer handle
3632  * \param q queue id to be queried
3633  * \param tempo pointer to store the current tempo
3634  * \return 0 on success otherwise a negative error code
3635  *
3636  * \sa snd_seq_set_queue_tempo()
3637  */
snd_seq_get_queue_tempo(snd_seq_t * seq,int q,snd_seq_queue_tempo_t * tempo)3638 int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3639 {
3640 	assert(seq && tempo);
3641 	memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
3642 	tempo->queue = q;
3643 	return seq->ops->get_queue_tempo(seq, tempo);
3644 }
3645 
3646 /**
3647  * \brief set the tempo of the queue
3648  * \param seq sequencer handle
3649  * \param q queue id to change the tempo
3650  * \param tempo tempo information
3651  * \return 0 on success otherwise a negative error code
3652  *
3653  * \sa snd_seq_get_queue_tempo()
3654  */
snd_seq_set_queue_tempo(snd_seq_t * seq,int q,snd_seq_queue_tempo_t * tempo)3655 int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3656 {
3657 	assert(seq && tempo);
3658 	tempo->queue = q;
3659 	return seq->ops->set_queue_tempo(seq, tempo);
3660 }
3661 
3662 
3663 /*----------------------------------------------------------------*/
3664 
3665 /**
3666  * \brief get size of #snd_seq_queue_timer_t
3667  * \return size in bytes
3668  */
snd_seq_queue_timer_sizeof()3669 size_t snd_seq_queue_timer_sizeof()
3670 {
3671 	return sizeof(snd_seq_queue_timer_t);
3672 }
3673 
3674 /**
3675  * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
3676  * \param ptr returned pointer
3677  * \return 0 on success otherwise negative error code
3678  */
snd_seq_queue_timer_malloc(snd_seq_queue_timer_t ** ptr)3679 int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
3680 {
3681 	assert(ptr);
3682 	*ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
3683 	if (!*ptr)
3684 		return -ENOMEM;
3685 	return 0;
3686 }
3687 
3688 /**
3689  * \brief frees a previously allocated #snd_seq_queue_timer_t
3690  * \param obj pointer to object to free
3691  */
snd_seq_queue_timer_free(snd_seq_queue_timer_t * obj)3692 void snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
3693 {
3694 	free(obj);
3695 }
3696 
3697 /**
3698  * \brief copy one #snd_seq_queue_timer_t to another
3699  * \param dst pointer to destination
3700  * \param src pointer to source
3701  */
snd_seq_queue_timer_copy(snd_seq_queue_timer_t * dst,const snd_seq_queue_timer_t * src)3702 void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
3703 {
3704 	assert(dst && src);
3705 	*dst = *src;
3706 }
3707 
3708 
3709 /**
3710  * \brief Get the queue id of a queue_timer container
3711  * \param info queue_timer container
3712  * \return queue id
3713  *
3714  * \sa snd_seq_get_queue_timer()
3715  */
snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t * info)3716 int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
3717 {
3718 	assert(info);
3719 	return info->queue;
3720 }
3721 
3722 /**
3723  * \brief Get the timer type of a queue_timer container
3724  * \param info queue_timer container
3725  * \return timer type
3726  *
3727  * \sa snd_seq_get_queue_timer()
3728  */
snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t * info)3729 snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
3730 {
3731 	assert(info);
3732 	return (snd_seq_queue_timer_type_t)info->type;
3733 }
3734 
3735 /**
3736  * \brief Get the timer id of a queue_timer container
3737  * \param info queue_timer container
3738  * \return timer id pointer
3739  *
3740  * \sa snd_seq_get_queue_timer()
3741  */
snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t * info)3742 const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
3743 {
3744 	assert(info);
3745 	return &info->u.alsa.id;
3746 }
3747 
3748 /**
3749  * \brief Get the timer resolution of a queue_timer container
3750  * \param info queue_timer container
3751  * \return timer resolution
3752  *
3753  * \sa snd_seq_get_queue_timer()
3754  */
snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t * info)3755 unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
3756 {
3757 	assert(info);
3758 	return info->u.alsa.resolution;
3759 }
3760 
3761 /**
3762  * \brief Set the timer type of a queue_timer container
3763  * \param info queue_timer container
3764  * \param type timer type
3765  *
3766  * \sa snd_seq_get_queue_timer()
3767  */
snd_seq_queue_timer_set_type(snd_seq_queue_timer_t * info,snd_seq_queue_timer_type_t type)3768 void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type)
3769 {
3770 	assert(info);
3771 	info->type = (int)type;
3772 }
3773 
3774 /**
3775  * \brief Set the timer id of a queue_timer container
3776  * \param info queue_timer container
3777  * \param id timer id pointer
3778  *
3779  * \sa snd_seq_get_queue_timer()
3780  */
snd_seq_queue_timer_set_id(snd_seq_queue_timer_t * info,const snd_timer_id_t * id)3781 void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
3782 {
3783 	assert(info && id);
3784 	info->u.alsa.id = *id;
3785 }
3786 
3787 /**
3788  * \brief Set the timer resolution of a queue_timer container
3789  * \param info queue_timer container
3790  * \param resolution timer resolution
3791  *
3792  * \sa snd_seq_get_queue_timer()
3793  */
snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t * info,unsigned int resolution)3794 void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
3795 {
3796 	assert(info);
3797 	info->u.alsa.resolution = resolution;
3798 }
3799 
3800 
3801 /**
3802  * \brief obtain the queue timer information
3803  * \param seq sequencer handle
3804  * \param q queue id to query
3805  * \param timer pointer to store the timer information
3806  * \return 0 on success otherwise a negative error code
3807  *
3808  * \sa snd_seq_set_queue_timer()
3809  */
snd_seq_get_queue_timer(snd_seq_t * seq,int q,snd_seq_queue_timer_t * timer)3810 int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3811 {
3812 	assert(seq && timer);
3813 	memset(timer, 0, sizeof(snd_seq_queue_timer_t));
3814 	timer->queue = q;
3815 	return seq->ops->get_queue_timer(seq, timer);
3816 }
3817 
3818 /**
3819  * \brief set the queue timer information
3820  * \param seq sequencer handle
3821  * \param q queue id to change the timer
3822  * \param timer timer information
3823  * \return 0 on success otherwise a negative error code
3824  *
3825  * \sa snd_seq_get_queue_timer()
3826  */
snd_seq_set_queue_timer(snd_seq_t * seq,int q,snd_seq_queue_timer_t * timer)3827 int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3828 {
3829 	assert(seq && timer);
3830 	timer->queue = q;
3831 	return seq->ops->set_queue_timer(seq, timer);
3832 }
3833 
3834 /*----------------------------------------------------------------*/
3835 
3836 #ifndef DOC_HIDDEN
3837 /**
3838  * \brief (DEPRECATED) create an event cell
3839  * \return the cell pointer allocated
3840  *
3841  * create an event cell via malloc.  the returned pointer must be released
3842  * by the application itself via normal free() call,
3843  * not via snd_seq_free_event().
3844  */
snd_seq_create_event(void)3845 snd_seq_event_t *snd_seq_create_event(void)
3846 {
3847 	return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
3848 }
3849 #endif
3850 
3851 /**
3852  * \brief (DEPRECATED) free an event
3853  *
3854  * In the former version, this function was used to
3855  * release the event pointer which was allocated by snd_seq_event_input().
3856  * In the current version, the event record is not allocated, so
3857  * you don't have to call this function any more.
3858  */
3859 #ifndef DOXYGEN
snd_seq_free_event(snd_seq_event_t * ev ATTRIBUTE_UNUSED)3860 int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
3861 #else
3862 int snd_seq_free_event(snd_seq_event_t *ev)
3863 #endif
3864 {
3865 	return 0;
3866 }
3867 
3868 /**
3869  * \brief calculates the (encoded) byte-stream size of the event
3870  * \param ev the event
3871  * \return the size of decoded bytes
3872  */
snd_seq_event_length(snd_seq_event_t * ev)3873 ssize_t snd_seq_event_length(snd_seq_event_t *ev)
3874 {
3875 	ssize_t len = sizeof(snd_seq_event_t);
3876 	assert(ev);
3877 	if (snd_seq_ev_is_variable(ev))
3878 		len += ev->data.ext.len;
3879 	return len;
3880 }
3881 
3882 /*----------------------------------------------------------------*/
3883 
3884 /*
3885  * output to sequencer
3886  */
3887 
3888 /**
3889  * \brief output an event
3890  * \param seq sequencer handle
3891  * \param ev event to be output
3892  * \return the number of remaining events or a negative error code
3893  *
3894  * An event is once expanded on the output buffer.
3895  * The output buffer will be drained automatically if it becomes full.
3896  *
3897  * If events remain unprocessed on output buffer before drained,
3898  * the size of total byte data on output buffer is returned.
3899  * If the output buffer is empty, this returns zero.
3900  *
3901  * \sa snd_seq_event_output_direct(), snd_seq_event_output_buffer(),
3902  *    snd_seq_event_output_pending(), snd_seq_drain_output(),
3903  *    snd_seq_drop_output(), snd_seq_extract_output(),
3904  *    snd_seq_remove_events()
3905  */
snd_seq_event_output(snd_seq_t * seq,snd_seq_event_t * ev)3906 int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
3907 {
3908 	int result;
3909 
3910 	result = snd_seq_event_output_buffer(seq, ev);
3911 	if (result == -EAGAIN) {
3912 		result = snd_seq_drain_output(seq);
3913 		if (result < 0)
3914 			return result;
3915 		return snd_seq_event_output_buffer(seq, ev);
3916 	}
3917 	return result;
3918 }
3919 
3920 /**
3921  * \brief output an event onto the lib buffer without draining buffer
3922  * \param seq sequencer handle
3923  * \param ev event to be output
3924  * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
3925  *
3926  * This function doesn't drain buffer unlike snd_seq_event_output().
3927  *
3928  * \sa snd_seq_event_output()
3929  */
snd_seq_event_output_buffer(snd_seq_t * seq,snd_seq_event_t * ev)3930 int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
3931 {
3932 	int len;
3933 	assert(seq && ev);
3934 	len = snd_seq_event_length(ev);
3935 	if (len < 0)
3936 		return -EINVAL;
3937 	if ((size_t) len >= seq->obufsize)
3938 		return -EINVAL;
3939 	if ((seq->obufsize - seq->obufused) < (size_t) len)
3940 		return -EAGAIN;
3941 	memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
3942 	seq->obufused += sizeof(snd_seq_event_t);
3943 	if (snd_seq_ev_is_variable(ev)) {
3944 		memcpy(seq->obuf + seq->obufused, ev->data.ext.ptr, ev->data.ext.len);
3945 		seq->obufused += ev->data.ext.len;
3946 	}
3947 	return seq->obufused;
3948 }
3949 
3950 /*
3951  * allocate the temporary buffer
3952  */
alloc_tmpbuf(snd_seq_t * seq,size_t len)3953 static int alloc_tmpbuf(snd_seq_t *seq, size_t len)
3954 {
3955 	size_t size = ((len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t));
3956 	if (seq->tmpbuf == NULL) {
3957 		if (size > DEFAULT_TMPBUF_SIZE)
3958 			seq->tmpbufsize = size;
3959 		else
3960 			seq->tmpbufsize = DEFAULT_TMPBUF_SIZE;
3961 		seq->tmpbuf = malloc(seq->tmpbufsize * sizeof(snd_seq_event_t));
3962 		if (seq->tmpbuf == NULL)
3963 			return -ENOMEM;
3964 	}  else if (len > seq->tmpbufsize) {
3965 		seq->tmpbuf = realloc(seq->tmpbuf, size * sizeof(snd_seq_event_t));
3966 		if (seq->tmpbuf == NULL)
3967 			return -ENOMEM;
3968 		seq->tmpbufsize = size;
3969 	}
3970 	return 0;
3971 }
3972 
3973 /**
3974  * \brief output an event directly to the sequencer NOT through output buffer
3975  * \param seq sequencer handle
3976  * \param ev event to be output
3977  * \return the byte size sent to sequencer or a negative error code
3978  *
3979  * This function sends an event to the sequencer directly not through the
3980  * output buffer.  When the event is a variable length event, a temporary
3981  * buffer is allocated inside alsa-lib and the data is copied there before
3982  * actually sent.
3983  *
3984  * \sa snd_seq_event_output()
3985  */
snd_seq_event_output_direct(snd_seq_t * seq,snd_seq_event_t * ev)3986 int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
3987 {
3988 	ssize_t len;
3989 	void *buf;
3990 
3991 	len = snd_seq_event_length(ev);
3992 	if (len < 0)
3993 		return len;
3994 	else if (len == sizeof(*ev)) {
3995 		buf = ev;
3996 	} else {
3997 		if (alloc_tmpbuf(seq, (size_t)len) < 0)
3998 			return -ENOMEM;
3999 		*seq->tmpbuf = *ev;
4000 		memcpy(seq->tmpbuf + 1, ev->data.ext.ptr, ev->data.ext.len);
4001 		buf = seq->tmpbuf;
4002 	}
4003 	return seq->ops->write(seq, buf, (size_t) len);
4004 }
4005 
4006 /**
4007  * \brief return the size of pending events on output buffer
4008  * \param seq sequencer handle
4009  * \return the byte size of total of pending events
4010  *
4011  * \sa snd_seq_event_output()
4012  */
snd_seq_event_output_pending(snd_seq_t * seq)4013 int snd_seq_event_output_pending(snd_seq_t *seq)
4014 {
4015 	assert(seq);
4016 	return seq->obufused;
4017 }
4018 
4019 /**
4020  * \brief drain output buffer to sequencer
4021  * \param seq sequencer handle
4022  * \return 0 when all events are drained and sent to sequencer.
4023  *         When events still remain on the buffer, the byte size of remaining
4024  *         events are returned.  On error a negative error code is returned.
4025  *
4026  * This function drains all pending events on the output buffer.
4027  * The function returns immediately after the events are sent to the queues
4028  * regardless whether the events are processed or not.
4029  * To get synchronization with the all event processes, use
4030  * #snd_seq_sync_output_queue() after calling this function.
4031  *
4032  * \sa snd_seq_event_output(), snd_seq_sync_output_queue()
4033  */
snd_seq_drain_output(snd_seq_t * seq)4034 int snd_seq_drain_output(snd_seq_t *seq)
4035 {
4036 	ssize_t result, processed = 0;
4037 	assert(seq);
4038 	while (seq->obufused > 0) {
4039 		result = seq->ops->write(seq, seq->obuf, seq->obufused);
4040 		if (result < 0) {
4041 			if (result == -EAGAIN && processed)
4042 				return seq->obufused;
4043 			return result;
4044 		}
4045 		if ((size_t)result < seq->obufused)
4046 			memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
4047 		seq->obufused -= result;
4048 	}
4049 	return 0;
4050 }
4051 
4052 /**
4053  * \brief extract the first event in output buffer
4054  * \param seq sequencer handle
4055  * \param ev_res event pointer to be extracted
4056  * \return 0 on success otherwise a negative error code
4057  *
4058  * Extracts the first event in output buffer.
4059  * If ev_res is NULL, just remove the event.
4060  *
4061  * \sa snd_seq_event_output()
4062  */
snd_seq_extract_output(snd_seq_t * seq,snd_seq_event_t ** ev_res)4063 int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
4064 {
4065 	size_t len, olen;
4066 	snd_seq_event_t ev;
4067 	assert(seq);
4068 	if (ev_res)
4069 		*ev_res = NULL;
4070 	if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
4071 		return -ENOENT;
4072 	memcpy(&ev, seq->obuf, sizeof(snd_seq_event_t));
4073 	len = snd_seq_event_length(&ev);
4074 	if (ev_res) {
4075 		/* extract the event */
4076 		if (alloc_tmpbuf(seq, len) < 0)
4077 			return -ENOMEM;
4078 		memcpy(seq->tmpbuf, seq->obuf, len);
4079 		*ev_res = seq->tmpbuf;
4080 	}
4081 	seq->obufused = olen - len;
4082 	memmove(seq->obuf, seq->obuf + len, seq->obufused);
4083 	return 0;
4084 }
4085 
4086 /*----------------------------------------------------------------*/
4087 
4088 /*
4089  * input from sequencer
4090  */
4091 
4092 /*
4093  * read from sequencer to input buffer
4094  */
snd_seq_event_read_buffer(snd_seq_t * seq)4095 static ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
4096 {
4097 	ssize_t len;
4098 	len = (seq->ops->read)(seq, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
4099 	if (len < 0)
4100 		return len;
4101 	seq->ibuflen = len / sizeof(snd_seq_event_t);
4102 	seq->ibufptr = 0;
4103 	return seq->ibuflen;
4104 }
4105 
snd_seq_event_retrieve_buffer(snd_seq_t * seq,snd_seq_event_t ** retp)4106 static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
4107 {
4108 	size_t ncells;
4109 	snd_seq_event_t *ev;
4110 
4111 	*retp = ev = &seq->ibuf[seq->ibufptr];
4112 	seq->ibufptr++;
4113 	seq->ibuflen--;
4114 	if (! snd_seq_ev_is_variable(ev))
4115 		return 1;
4116 	ncells = (ev->data.ext.len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
4117 	if (seq->ibuflen < ncells) {
4118 		seq->ibuflen = 0; /* clear buffer */
4119 		*retp = NULL;
4120 		return -EINVAL;
4121 	}
4122 	ev->data.ext.ptr = ev + 1;
4123 	seq->ibuflen -= ncells;
4124 	seq->ibufptr += ncells;
4125 	return 1;
4126 }
4127 
4128 /**
4129  * \brief retrieve an event from sequencer
4130  * \param seq sequencer handle
4131  * \param ev event pointer to be stored
4132  * \return
4133  *
4134  * Obtains an input event from sequencer.
4135  * The event is created via snd_seq_create_event(), and its pointer is stored on
4136  * ev argument.
4137  *
4138  * This function firstly receives the event byte-stream data from sequencer
4139  * as much as possible at once.  Then it retrieves the first event record
4140  * and store the pointer on ev.
4141  * By calling this function sequentially, events are extracted from the input buffer.
4142  *
4143  * If there is no input from sequencer, function falls into sleep
4144  * in blocking mode until an event is received,
4145  * or returns \c -EAGAIN error in non-blocking mode.
4146  * Occasionally, this function may return \c -ENOSPC error.
4147  * This means that the input FIFO of sequencer overran, and some events are
4148  * lost.
4149  * Once this error is returned, the input FIFO is cleared automatically.
4150  *
4151  * Function returns the byte size of remaining events on the input buffer
4152  * if an event is successfully received.
4153  * Application can determine from the returned value whether to call
4154  * input once more or not.
4155  *
4156  * \sa snd_seq_event_input_pending(), snd_seq_drop_input()
4157  */
snd_seq_event_input(snd_seq_t * seq,snd_seq_event_t ** ev)4158 int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
4159 {
4160 	int err;
4161 	assert(seq);
4162 	*ev = NULL;
4163 	if (seq->ibuflen <= 0) {
4164 		if ((err = snd_seq_event_read_buffer(seq)) < 0)
4165 			return err;
4166 	}
4167 
4168 	return snd_seq_event_retrieve_buffer(seq, ev);
4169 }
4170 
4171 /*
4172  * read input data from sequencer if available
4173  */
snd_seq_event_input_feed(snd_seq_t * seq,int timeout)4174 static int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
4175 {
4176 	struct pollfd pfd;
4177 	int err;
4178 	pfd.fd = seq->poll_fd;
4179 	pfd.events = POLLIN;
4180 	err = poll(&pfd, 1, timeout);
4181 	if (err < 0) {
4182 		SYSERR("poll");
4183 		return -errno;
4184 	}
4185 	if (pfd.revents & POLLIN)
4186 		return snd_seq_event_read_buffer(seq);
4187 	return seq->ibuflen;
4188 }
4189 
4190 /**
4191  * \brief check events in input buffer
4192  * \return the byte size of remaining input events on input buffer.
4193  *
4194  * If events remain on the input buffer of user-space, function returns
4195  * the total byte size of events on it.
4196  * If fetch_sequencer argument is non-zero,
4197  * this function checks the presence of events on sequencer FIFO
4198  * When events exist, they are transferred to the input buffer,
4199  * and the number of received events are returned.
4200  * If fetch_sequencer argument is zero and
4201  * no events remain on the input buffer, function simply returns zero.
4202  *
4203  * \sa snd_seq_event_input()
4204  */
snd_seq_event_input_pending(snd_seq_t * seq,int fetch_sequencer)4205 int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
4206 {
4207 	if (seq->ibuflen == 0 && fetch_sequencer) {
4208 		return snd_seq_event_input_feed(seq, 0);
4209 	}
4210 	return seq->ibuflen;
4211 }
4212 
4213 /*----------------------------------------------------------------*/
4214 
4215 /*
4216  * clear event buffers
4217  */
4218 
4219 /**
4220  * \brief remove all events on user-space output buffer
4221  * \param seq sequencer handle
4222  *
4223  * Removes all events on user-space output buffer.
4224  * Unlike snd_seq_drain_output(), this function doesn't remove
4225  * events on output memory pool of sequencer.
4226  *
4227  * \sa snd_seq_drop_output()
4228  */
snd_seq_drop_output_buffer(snd_seq_t * seq)4229 int snd_seq_drop_output_buffer(snd_seq_t *seq)
4230 {
4231 	assert(seq);
4232 	seq->obufused = 0;
4233 	return 0;
4234 }
4235 
4236 /**
4237  * \brief remove all events on user-space input FIFO
4238  * \param seq sequencer handle
4239  *
4240  * \sa snd_seq_drop_input()
4241  */
snd_seq_drop_input_buffer(snd_seq_t * seq)4242 int snd_seq_drop_input_buffer(snd_seq_t *seq)
4243 {
4244 	assert(seq);
4245 	seq->ibufptr = 0;
4246 	seq->ibuflen = 0;
4247 	return 0;
4248 }
4249 
4250 /**
4251  * \brief remove all events on output buffer
4252  * \param seq sequencer handle
4253  *
4254  * Removes all events on both user-space output buffer and
4255  * output memory pool on kernel.
4256  *
4257  * \sa snd_seq_drain_output(), snd_seq_drop_output_buffer(), snd_seq_remove_events()
4258  */
snd_seq_drop_output(snd_seq_t * seq)4259 int snd_seq_drop_output(snd_seq_t *seq)
4260 {
4261 	snd_seq_remove_events_t rminfo;
4262 	assert(seq);
4263 
4264 	memset(&rminfo, 0, sizeof(rminfo));
4265 	rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;
4266 
4267 	return snd_seq_remove_events(seq, &rminfo);
4268 }
4269 
4270 /**
4271  * \brief clear input buffer and and remove events in sequencer queue
4272  * \param seq sequencer handle
4273  *
4274  * \sa snd_seq_drop_input_buffer(), snd_seq_remove_events()
4275  */
snd_seq_drop_input(snd_seq_t * seq)4276 int snd_seq_drop_input(snd_seq_t *seq)
4277 {
4278 	snd_seq_remove_events_t rminfo;
4279 	assert(seq);
4280 
4281 	memset(&rminfo, 0, sizeof(rminfo));
4282 	rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;
4283 
4284 	return snd_seq_remove_events(seq, &rminfo);
4285 }
4286 
4287 
4288 /**
4289  * \brief get size of #snd_seq_remove_events_t
4290  * \return size in bytes
4291  */
snd_seq_remove_events_sizeof()4292 size_t snd_seq_remove_events_sizeof()
4293 {
4294 	return sizeof(snd_seq_remove_events_t);
4295 }
4296 
4297 /**
4298  * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
4299  * \param ptr returned pointer
4300  * \return 0 on success otherwise negative error code
4301  */
snd_seq_remove_events_malloc(snd_seq_remove_events_t ** ptr)4302 int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
4303 {
4304 	assert(ptr);
4305 	*ptr = calloc(1, sizeof(snd_seq_remove_events_t));
4306 	if (!*ptr)
4307 		return -ENOMEM;
4308 	return 0;
4309 }
4310 
4311 /**
4312  * \brief frees a previously allocated #snd_seq_remove_events_t
4313  * \param obj pointer to object to free
4314  */
snd_seq_remove_events_free(snd_seq_remove_events_t * obj)4315 void snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
4316 {
4317 	free(obj);
4318 }
4319 
4320 /**
4321  * \brief copy one #snd_seq_remove_events_t to another
4322  * \param dst pointer to destination
4323  * \param src pointer to source
4324  */
snd_seq_remove_events_copy(snd_seq_remove_events_t * dst,const snd_seq_remove_events_t * src)4325 void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
4326 {
4327 	assert(dst && src);
4328 	*dst = *src;
4329 }
4330 
4331 
4332 /**
4333  * \brief Get the removal condition bits
4334  * \param info remove_events container
4335  * \return removal condition bits
4336  *
4337  * \sa snd_seq_remove_events()
4338  */
snd_seq_remove_events_get_condition(const snd_seq_remove_events_t * info)4339 unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
4340 {
4341 	assert(info);
4342 	return info->remove_mode;
4343 }
4344 
4345 /**
4346  * \brief Get the queue as removal condition
4347  * \param info remove_events container
4348  * \return queue id
4349  *
4350  * \sa snd_seq_remove_events()
4351  */
snd_seq_remove_events_get_queue(const snd_seq_remove_events_t * info)4352 int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
4353 {
4354 	assert(info);
4355 	return info->queue;
4356 }
4357 
4358 /**
4359  * \brief Get the event timestamp as removal condition
4360  * \param info remove_events container
4361  * \return time stamp
4362  *
4363  * \sa snd_seq_remove_events()
4364  */
snd_seq_remove_events_get_time(const snd_seq_remove_events_t * info)4365 const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
4366 {
4367 	assert(info);
4368 	return (const snd_seq_timestamp_t *)&info->time;
4369 }
4370 
4371 /**
4372  * \brief Get the event destination address as removal condition
4373  * \param info remove_events container
4374  * \return destination address
4375  *
4376  * \sa snd_seq_remove_events()
4377  */
snd_seq_remove_events_get_dest(const snd_seq_remove_events_t * info)4378 const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
4379 {
4380 	assert(info);
4381 	return (const snd_seq_addr_t *)&info->dest;
4382 }
4383 
4384 /**
4385  * \brief Get the event channel as removal condition
4386  * \param info remove_events container
4387  * \return channel number
4388  *
4389  * \sa snd_seq_remove_events()
4390  */
snd_seq_remove_events_get_channel(const snd_seq_remove_events_t * info)4391 int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
4392 {
4393 	assert(info);
4394 	return info->channel;
4395 }
4396 
4397 /**
4398  * \brief Get the event type as removal condition
4399  * \param info remove_events container
4400  * \return event type
4401  *
4402  * \sa snd_seq_remove_events()
4403  */
snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t * info)4404 int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
4405 {
4406 	assert(info);
4407 	return info->type;
4408 }
4409 
4410 /**
4411  * \brief Get the event tag id as removal condition
4412  * \param info remove_events container
4413  * \return tag id
4414  *
4415  * \sa snd_seq_remove_events()
4416  */
snd_seq_remove_events_get_tag(const snd_seq_remove_events_t * info)4417 int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
4418 {
4419 	assert(info);
4420 	return info->tag;
4421 }
4422 
4423 /**
4424  * \brief Set the removal condition bits
4425  * \param info remove_events container
4426  * \param flags removal condition bits
4427  *
4428  * \sa snd_seq_remove_events()
4429  */
snd_seq_remove_events_set_condition(snd_seq_remove_events_t * info,unsigned int flags)4430 void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
4431 {
4432 	assert(info);
4433 	info->remove_mode = flags;
4434 }
4435 
4436 /**
4437  * \brief Set the queue as removal condition
4438  * \param info remove_events container
4439  * \param queue queue id
4440  *
4441  * \sa snd_seq_remove_events()
4442  */
snd_seq_remove_events_set_queue(snd_seq_remove_events_t * info,int queue)4443 void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
4444 {
4445 	assert(info);
4446 	info->queue = queue;
4447 }
4448 
4449 /**
4450  * \brief Set the timestamp as removal condition
4451  * \param info remove_events container
4452  * \param time timestamp pointer
4453  *
4454  * \sa snd_seq_remove_events()
4455  */
snd_seq_remove_events_set_time(snd_seq_remove_events_t * info,const snd_seq_timestamp_t * time)4456 void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
4457 {
4458 	assert(info);
4459 	info->time = *(const union sndrv_seq_timestamp *)time;
4460 }
4461 
4462 /**
4463  * \brief Set the destination address as removal condition
4464  * \param info remove_events container
4465  * \param addr destination address
4466  *
4467  * \sa snd_seq_remove_events()
4468  */
snd_seq_remove_events_set_dest(snd_seq_remove_events_t * info,const snd_seq_addr_t * addr)4469 void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
4470 {
4471 	assert(info);
4472 	info->dest = *(const struct sndrv_seq_addr *)addr;
4473 }
4474 
4475 /**
4476  * \brief Set the channel as removal condition
4477  * \param info remove_events container
4478  * \param channel channel number
4479  *
4480  * \sa snd_seq_remove_events()
4481  */
snd_seq_remove_events_set_channel(snd_seq_remove_events_t * info,int channel)4482 void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
4483 {
4484 	assert(info);
4485 	info->channel = channel;
4486 }
4487 
4488 /**
4489  * \brief Set the event type as removal condition
4490  * \param info remove_events container
4491  * \param type event type
4492  *
4493  * \sa snd_seq_remove_events()
4494  */
snd_seq_remove_events_set_event_type(snd_seq_remove_events_t * info,int type)4495 void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
4496 {
4497 	assert(info);
4498 	info->type = type;
4499 }
4500 
4501 /**
4502  * \brief Set the event tag as removal condition
4503  * \param info remove_events container
4504  * \param tag tag id
4505  *
4506  * \sa snd_seq_remove_events()
4507  */
snd_seq_remove_events_set_tag(snd_seq_remove_events_t * info,int tag)4508 void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
4509 {
4510 	assert(info);
4511 	info->tag = tag;
4512 }
4513 
4514 
4515 /* compare timestamp between events */
4516 /* 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)4517 static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
4518 {
4519 	/* compare ticks */
4520 	return (*a >= *b);
4521 }
4522 
snd_seq_compare_real_time(snd_seq_real_time_t * a,snd_seq_real_time_t * b)4523 static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
4524 {
4525 	/* compare real time */
4526 	if (a->tv_sec > b->tv_sec)
4527 		return 1;
4528 	if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
4529 		return 1;
4530 	return 0;
4531 }
4532 
4533 /* Routine to match events to be removed */
remove_match(snd_seq_remove_events_t * info,snd_seq_event_t * ev)4534 static int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
4535 {
4536 	int res;
4537 
4538 	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
4539 		if (ev->dest.client != info->dest.client ||
4540 				ev->dest.port != info->dest.port)
4541 			return 0;
4542 	}
4543 	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
4544 		if (! snd_seq_ev_is_channel_type(ev))
4545 			return 0;
4546 		/* data.note.channel and data.control.channel are identical */
4547 		if (ev->data.note.channel != info->channel)
4548 			return 0;
4549 	}
4550 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
4551 		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4552 			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4553 		else
4554 			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4555 		if (!res)
4556 			return 0;
4557 	}
4558 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
4559 		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4560 			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4561 		else
4562 			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
4563 		if (res)
4564 			return 0;
4565 	}
4566 	if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
4567 		if (ev->type != info->type)
4568 			return 0;
4569 	}
4570 	if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
4571 		/* Do not remove off events */
4572 		switch (ev->type) {
4573 		case SND_SEQ_EVENT_NOTEOFF:
4574 		/* case SND_SEQ_EVENT_SAMPLE_STOP: */
4575 			return 0;
4576 		default:
4577 			break;
4578 		}
4579 	}
4580 	if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
4581 		if (info->tag != ev->tag)
4582 			return 0;
4583 	}
4584 
4585 	return 1;
4586 }
4587 
4588 /**
4589  * \brief remove events on input/output buffers and pools
4590  * \param seq sequencer handle
4591  * \param rmp remove event container
4592  *
4593  * Removes matching events with the given condition from input/output buffers
4594  * and pools.
4595  * The removal condition is specified in \a rmp argument.
4596  *
4597  * \sa snd_seq_event_output(), snd_seq_drop_output(), snd_seq_reset_pool_output()
4598  */
snd_seq_remove_events(snd_seq_t * seq,snd_seq_remove_events_t * rmp)4599 int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
4600 {
4601 	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
4602 		/*
4603 		 * First deal with any events that are still buffered
4604 		 * in the library.
4605 		 */
4606 		snd_seq_drop_input_buffer(seq);
4607 	}
4608 
4609 	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
4610 		/*
4611 		 * First deal with any events that are still buffered
4612 		 * in the library.
4613 		 */
4614 		 if (! (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT))) {
4615 			 /* The simple case - remove all */
4616 			 snd_seq_drop_output_buffer(seq);
4617 		} else {
4618 			char *ep;
4619 			size_t len;
4620 			snd_seq_event_t *ev;
4621 
4622 			ep = seq->obuf;
4623 			while (ep - seq->obuf < (ssize_t)seq->obufused) {
4624 
4625 				ev = (snd_seq_event_t *)ep;
4626 				len = snd_seq_event_length(ev);
4627 
4628 				if (remove_match(rmp, ev)) {
4629 					/* Remove event */
4630 					seq->obufused -= len;
4631 					memmove(ep, ep + len, seq->obufused - (ep - seq->obuf));
4632 				} else {
4633 					ep += len;
4634 				}
4635 			}
4636 		}
4637 	}
4638 
4639 	return seq->ops->remove_events(seq, rmp);
4640 }
4641 
4642 /*----------------------------------------------------------------*/
4643 
4644 /*
4645  * client memory pool
4646  */
4647 
4648 /**
4649  * \brief get size of #snd_seq_client_pool_t
4650  * \return size in bytes
4651  */
snd_seq_client_pool_sizeof()4652 size_t snd_seq_client_pool_sizeof()
4653 {
4654 	return sizeof(snd_seq_client_pool_t);
4655 }
4656 
4657 /**
4658  * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
4659  * \param ptr returned pointer
4660  * \return 0 on success otherwise negative error code
4661  */
snd_seq_client_pool_malloc(snd_seq_client_pool_t ** ptr)4662 int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
4663 {
4664 	assert(ptr);
4665 	*ptr = calloc(1, sizeof(snd_seq_client_pool_t));
4666 	if (!*ptr)
4667 		return -ENOMEM;
4668 	return 0;
4669 }
4670 
4671 /**
4672  * \brief frees a previously allocated #snd_seq_client_pool_t
4673  * \param obj pointer to object to free
4674  */
snd_seq_client_pool_free(snd_seq_client_pool_t * obj)4675 void snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
4676 {
4677 	free(obj);
4678 }
4679 
4680 /**
4681  * \brief copy one #snd_seq_client_pool_t to another
4682  * \param dst pointer to destination
4683  * \param src pointer to source
4684  */
snd_seq_client_pool_copy(snd_seq_client_pool_t * dst,const snd_seq_client_pool_t * src)4685 void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
4686 {
4687 	assert(dst && src);
4688 	*dst = *src;
4689 }
4690 
4691 
4692 /**
4693  * \brief Get the client id of a queue_info container
4694  * \param info client_pool container
4695  * \return client id
4696  */
snd_seq_client_pool_get_client(const snd_seq_client_pool_t * info)4697 int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
4698 {
4699 	assert(info);
4700 	return info->client;
4701 }
4702 
4703 /**
4704  * \brief Get the output pool size of a queue_info container
4705  * \param info client_pool container
4706  * \return output pool size
4707  */
snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t * info)4708 size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
4709 {
4710 	assert(info);
4711 	return info->output_pool;
4712 }
4713 
4714 /**
4715  * \brief Get the input pool size of a queue_info container
4716  * \param info client_pool container
4717  * \return input pool size
4718  */
snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t * info)4719 size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
4720 {
4721 	assert(info);
4722 	return info->input_pool;
4723 }
4724 
4725 /**
4726  * \brief Get the output room size of a queue_info container
4727  * \param info client_pool container
4728  * \return output room size
4729  */
snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t * info)4730 size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
4731 {
4732 	assert(info);
4733 	return info->output_room;
4734 }
4735 
4736 /**
4737  * \brief Get the available size on output pool of a queue_info container
4738  * \param info client_pool container
4739  * \return available output size
4740  */
snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t * info)4741 size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
4742 {
4743 	assert(info);
4744 	return info->output_free;
4745 }
4746 
4747 /**
4748  * \brief Get the available size on input pool of a queue_info container
4749  * \param info client_pool container
4750  * \return available input size
4751  */
snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t * info)4752 size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
4753 {
4754 	assert(info);
4755 	return info->input_free;
4756 }
4757 
4758 /**
4759  * \brief Set the output pool size of a queue_info container
4760  * \param info client_pool container
4761  * \param size output pool size
4762  */
snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t * info,size_t size)4763 void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
4764 {
4765 	assert(info);
4766 	info->output_pool = size;
4767 }
4768 
4769 /**
4770  * \brief Set the input pool size of a queue_info container
4771  * \param info client_pool container
4772  * \param size input pool size
4773  */
snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t * info,size_t size)4774 void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
4775 {
4776 	assert(info);
4777 	info->input_pool = size;
4778 }
4779 
4780 /**
4781  * \brief Set the output room size of a queue_info container
4782  * \param info client_pool container
4783  * \param size output room size
4784  */
snd_seq_client_pool_set_output_room(snd_seq_client_pool_t * info,size_t size)4785 void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
4786 {
4787 	assert(info);
4788 	info->output_room = size;
4789 }
4790 
4791 
4792 /**
4793  * \brief obtain the pool information of the current client
4794  * \param seq sequencer handle
4795  * \param info information to be stored
4796  */
snd_seq_get_client_pool(snd_seq_t * seq,snd_seq_client_pool_t * info)4797 int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4798 {
4799 	assert(seq && info);
4800 	info->client = seq->client;
4801 	return seq->ops->get_client_pool(seq, info);
4802 }
4803 
4804 /**
4805  * \brief set the pool information
4806  * \param seq sequencer handle
4807  * \param info information to update
4808  *
4809  * Sets the pool information of the current client.
4810  * The client field in \a info is replaced automatically with the current id.
4811  */
snd_seq_set_client_pool(snd_seq_t * seq,snd_seq_client_pool_t * info)4812 int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4813 {
4814 	assert(seq && info);
4815 	info->client = seq->client;
4816 	return seq->ops->set_client_pool(seq, info);
4817 }
4818 
4819 /*----------------------------------------------------------------*/
4820 
4821 /*
4822  * misc.
4823  */
4824 
4825 /**
4826  * \brief set a bit flag
4827  */
snd_seq_set_bit(int nr,void * array)4828 void snd_seq_set_bit(int nr, void *array)
4829 {
4830 	((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
4831 }
4832 
4833 /**
4834  * \brief unset a bit flag
4835  */
snd_seq_unset_bit(int nr,void * array)4836 void snd_seq_unset_bit(int nr, void *array)
4837 {
4838        ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
4839 }
4840 
4841 /**
4842  * \brief change a bit flag
4843  */
snd_seq_change_bit(int nr,void * array)4844 int snd_seq_change_bit(int nr, void *array)
4845 {
4846 	int result;
4847 
4848 	result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
4849 	((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
4850 	return result;
4851 }
4852 
4853 /**
4854  * \brief get a bit flag state
4855  */
snd_seq_get_bit(int nr,void * array)4856 int snd_seq_get_bit(int nr, void *array)
4857 {
4858 	return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
4859 }
4860