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