• Home
  • History
  • Annotate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/ap/gpl/iserver/alsa-lib-1.0.26/src/seq/

Lines Matching defs:*

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
9 * See \ref seq page for more details.
13 * Sequencer Interface - main file
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
31 /*! \page seq Sequencer interface
33 \section seq_general General
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.
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.
50 \section seq_client Client and Port
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()
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;
69 \endcode
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.
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.
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)
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);
95 \endcode
97 \section seq_memory Memory Pool
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.
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.
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.
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.
123 \section seq_subs Subscription
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.
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)
143 V
144 ALSA sequencer - update timestamp
146 V
147 application port
148 \endcode
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
160 V
161 ALSA sequencer - events are scheduled
163 V
164 MIDI output port (WaveTable etc.)
165 \endcode
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
183 V
184 ALSA sequencer (scheduled or real-time)
186 V
187 sequencer port #2
188 \endcode
190 For the detail about subscription, see the section \ref seq_subs_more.
192 \section seq_events Sequencer Events
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.
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.
207 \subsection seq_ev_struct Structure of an event
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>
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.
238 \subsection seq_ev_queue Scheduling queue
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.
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.
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.
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.
268 \subsection seq_ev_time Time stamp
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.
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.
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.
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.
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.
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.
310 \subsection seq_ev_addr Source and destination addresses
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.
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.
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.
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.
345 \subsection seq_ev_data Data storage type
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:
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.
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.
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.
383 \subsection seq_ev_sched Scheduling priority
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.
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.
396 \section seq_queue Event Queues
397 \subsection seq_ev_control Creation of a queue
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)
405 return snd_seq_alloc_named_queue(handle, "my queue");
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.
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.
419 \subsection seq_ev_tempo Setting queue tempo
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.
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.
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.
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)
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, tempo);
463 \endcode
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)
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);
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.
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.
493 \subsection seq_ev_start Starting and stopping a queue
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.
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.
510 \section seq_subs_more More inside the subscription
512 \subsection seq_subs_perm Permissions
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.
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.
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.
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.
556 \subsection seq_subs_handle Subscription handlers
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
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.
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.
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.
607 \section seq_subs_ex Examples of subscription
609 \subsection seq_subs_ex_capt Capture from keyboard
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)
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);
631 \endcode
633 \subsection seq_subs_ex_out Output to MIDI device
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)
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);
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)
656 snd_seq_connect_to(seq, 0, 65, 1);
658 \endcode
660 \subsection seq_subs_ex_arbit Arbitrary connection
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)
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);
685 \endcode
687 \section seq_ex_event Event Processing
689 \subsection seq_ex_address Addressing
691 Now, two ports are connected by subscription. Then how to send events?
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.
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.
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().
707 \subsection Scheduled Delivery
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)
717 snd_seq_event_t ev;
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..
725 snd_seq_event_output(seq, &ev);
726 ...
727 snd_seq_drain_output(seq); // if necessary
729 \endcode
730 Of course, you can use realtime stamp, too.
732 \subsection seq_ex_direct Direct Delivery
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)
742 snd_seq_event_t ev;
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..
750 snd_seq_event_output(seq, &ev);
751 snd_seq_drain_output(seq);
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.
759 \subsection seq_ex_filter Filter Application
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)
766 while (snd_seq_event_input(seq, &ev) >= 0) {
767 //.. modify input event ..
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);
776 \endcode
780 #include <sys/poll.h>
781 #include "seq_local.h"
785 * seq.h *
786 * Sequencer *
791 * \brief get identifier of sequencer handle
792 * \param seq sequencer handle
793 * \return ASCII identifier of sequencer handle
795 * Returns the ASCII identifier of the given sequencer handle. It's the same
796 * identifier specified in snd_seq_open().
798 * \sa snd_seq_open()
800 const char *snd_seq_name(snd_seq_t *seq)
802 assert(seq);
803 return seq->name;
807 * \brief get type of sequencer handle
808 * \param seq sequencer handle
809 * \return type of sequencer handle
811 * Returns the type #snd_seq_type_t of the given sequencer handle.
813 * \sa snd_seq_open()
815 snd_seq_type_t snd_seq_type(snd_seq_t *seq)
817 assert(seq);
818 return seq->type;
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)
825 const char *str;
826 char buf[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;
846 err = snd_config_search(seq_conf, "type", &conf);
847 if (err < 0) {
848 SNDERR("type is not defined");
849 return err;
851 err = snd_config_get_id(conf, &id);
852 if (err < 0) {
853 SNDERR("unable to get id");
854 return err;
856 err = snd_config_get_string(conf, &str);
857 if (err < 0) {
858 SNDERR("Invalid type for %s", id);
859 return err;
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;
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;
880 continue;
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;
888 continue;
890 SNDERR("Unknown field %s", id);
891 err = -EINVAL;
892 goto _err;
895 if (!open_name) {
896 open_name = buf;
897 snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
899 #ifndef PIC
900 snd_seq_open_symbols();
901 #endif
902 h = snd_dlopen(lib, RTLD_NOW);
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", lib);
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;
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;
924 return err;
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)
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;
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;
946 * \brief Open the ALSA sequencer
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
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.
971 * \sa snd_seq_open_lconf(), snd_seq_close(), snd_seq_type(), snd_seq_name(),
972 * snd_seq_nonblock(), snd_seq_client_id()
974 int snd_seq_open(snd_seq_t **seqp, const char *name,
975 int streams, int mode)
977 int err;
978 assert(seqp && name);
979 err = snd_config_update();
980 if (err < 0)
981 return err;
982 return snd_seq_open_noupdate(seqp, snd_config, name, streams, mode, 0);
986 * \brief Open the ALSA sequencer using local configuration
988 * \param seqp Pointer to a snd_seq_t pointer.
989 * \param name The name to open
990 * \param streams The read/write mode of the sequencer.
991 * \param mode Optional modifier
992 * \param lconf Local configuration
993 * \return 0 on success otherwise a negative error code
995 * See the snd_seq_open() function for further details. The extension
996 * is that the given configuration is used to resolve abstract name.
998 * \sa snd_seq_open()
1000 int snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1001 int streams, int mode, snd_config_t *lconf)
1003 assert(seqp && name && lconf);
1004 return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
1007 #ifndef DOC_HIDDEN
1008 int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name,
1009 int streams, int mode, snd_config_t *lconf,
1010 snd_config_t *parent_conf)
1012 int hop;
1013 assert(seqp && name && lconf);
1014 if ((hop = snd_config_check_hop(parent_conf)) < 0)
1015 return hop;
1016 return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
1018 #endif
1021 * \brief Close the sequencer
1022 * \param seq Handle returned from #snd_seq_open()
1023 * \return 0 on success otherwise a negative error code
1025 * Closes the sequencer client and releases its resources.
1026 * After a client is closed, an event with
1027 * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
1028 * The connection between other clients are disconnected.
1029 * Call this just before exiting your program.
1031 * \sa snd_seq_close()
1033 int snd_seq_close(snd_seq_t *seq)
1035 int err;
1036 assert(seq);
1037 err = seq->ops->close(seq);
1038 if (seq->dl_handle)
1039 snd_dlclose(seq->dl_handle);
1040 free(seq->obuf);
1041 free(seq->ibuf);
1042 free(seq->tmpbuf);
1043 free(seq->name);
1044 free(seq);
1045 return err;
1049 * \brief Returns the number of poll descriptors
1050 * \param seq sequencer handle
1051 * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
1052 * \return the number of poll descriptors.
1054 * Get the number of poll descriptors. The polling events to be checked
1055 * can be specified by the second argument. When both input and output
1056 * are checked, pass \c POLLIN|POLLOUT
1058 * \sa snd_seq_poll_descriptors()
1060 int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
1062 int result = 0;
1063 assert(seq);
1064 if (events & POLLIN) {
1065 assert(seq->streams & SND_SEQ_OPEN_INPUT);
1066 result++;
1068 if (events & POLLOUT) {
1069 assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1070 result++;
1072 return result ? 1 : 0;
1076 * \brief Get poll descriptors
1077 * \param seq sequencer handle
1078 * \param pfds array of poll descriptors
1079 * \param space space in the poll descriptor array
1080 * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
1081 * \return count of filled descriptors
1083 * Get poll descriptors assigned to the sequencer handle.
1084 * Since a sequencer handle can duplex streams, you need to set which direction(s)
1085 * is/are polled in \a events argument. When \c POLLIN bit is specified,
1086 * the incoming events to the ports are checked.
1088 * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
1089 * instead of reading the pollfd structs directly.
1091 * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
1093 int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
1095 short revents = 0;
1097 assert(seq);
1098 if ((events & POLLIN) && space >= 1) {
1099 assert(seq->streams & SND_SEQ_OPEN_INPUT);
1100 revents |= POLLIN|POLLERR|POLLNVAL;
1102 if ((events & POLLOUT) && space >= 1) {
1103 assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
1104 revents |= POLLOUT|POLLERR|POLLNVAL;
1106 if (!revents)
1107 return 0;
1108 pfds->fd = seq->poll_fd;
1109 pfds->events = revents;
1110 return 1;
1114 * \brief get returned events from poll descriptors
1115 * \param seq sequencer handle
1116 * \param pfds array of poll descriptors
1117 * \param nfds count of poll descriptors
1118 * \param revents returned events
1119 * \return zero if success, otherwise a negative error code
1121 * \sa snd_seq_poll_descriptors()
1123 int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
1125 assert(seq && pfds && revents);
1126 if (nfds == 1) {
1127 *revents = pfds->revents;
1128 return 0;
1130 return -EINVAL;
1134 * \brief Set nonblock mode
1135 * \param seq sequencer handle
1136 * \param nonblock 0 = block, 1 = nonblock mode
1137 * \return 0 on success otherwise a negative error code
1139 * Change the blocking mode of the given client.
1140 * In block mode, the client falls into sleep when it fills the
1141 * output memory pool with full events. The client will be woken up
1142 * after a certain amount of free space becomes available.
1144 * \sa snd_seq_open()
1146 int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
1148 int err;
1149 assert(seq);
1150 err = seq->ops->nonblock(seq, nonblock);
1151 if (err < 0)
1152 return err;
1153 if (nonblock)
1154 seq->mode |= SND_SEQ_NONBLOCK;
1155 else
1156 seq->mode &= ~SND_SEQ_NONBLOCK;
1157 return 0;
1161 * \brief Get the client id
1162 * \param seq sequencer handle
1163 * \return the client id
1165 * Returns the id of the specified client.
1166 * If an error occurs, function returns the negative error code.
1167 * A client id is necessary to inquiry or to set the client information.
1168 * A user client is assigned from 128 to 191.
1170 * \sa snd_seq_open()
1172 int snd_seq_client_id(snd_seq_t *seq)
1174 assert(seq);
1175 return seq->client;
1179 * \brief Return the size of output buffer
1180 * \param seq sequencer handle
1181 * \return the size of output buffer in bytes
1183 * Obtains the size of output buffer.
1184 * This buffer is used to store decoded byte-stream of output events
1185 * before transferring to sequencer.
1187 * \sa snd_seq_set_output_buffer_size()
1189 size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
1191 assert(seq);
1192 if (!seq->obuf)
1193 return 0;
1194 return seq->obufsize;
1198 * \brief Return the size of input buffer
1199 * \param seq sequencer handle
1200 * \return the size of input buffer in bytes
1202 * Obtains the size of input buffer.
1203 * This buffer is used to read byte-stream of input events from sequencer.
1205 * \sa snd_seq_set_input_buffer_size()
1207 size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
1209 assert(seq);
1210 if (!seq->ibuf)
1211 return 0;
1212 return seq->ibufsize * sizeof(snd_seq_event_t);
1216 * \brief Change the size of output buffer
1217 * \param seq sequencer handle
1218 * \param size the size of output buffer to be changed in bytes
1219 * \return 0 on success otherwise a negative error code
1221 * Changes the size of output buffer.
1223 * \sa snd_seq_get_output_buffer_size()
1225 int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
1227 assert(seq && seq->obuf);
1228 assert(size >= sizeof(snd_seq_event_t));
1229 snd_seq_drop_output(seq);
1230 if (size != seq->obufsize) {
1231 char *newbuf;
1232 newbuf = calloc(1, size);
1233 if (newbuf == NULL)
1234 return -ENOMEM;
1235 free(seq->obuf);
1236 seq->obuf = newbuf;
1237 seq->obufsize = size;
1239 return 0;
1243 * \brief Resize the input buffer
1244 * \param seq sequencer handle
1245 * \param size the size of input buffer to be changed in bytes
1246 * \return 0 on success otherwise a negative error code
1248 * Changes the size of input buffer.
1250 * \sa snd_seq_get_input_buffer_size()
1252 int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
1254 assert(seq && seq->ibuf);
1255 assert(size >= sizeof(snd_seq_event_t));
1256 snd_seq_drop_input(seq);
1257 size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
1258 if (size != seq->ibufsize) {
1259 snd_seq_event_t *newbuf;
1260 newbuf = calloc(sizeof(snd_seq_event_t), size);
1261 if (newbuf == NULL)
1262 return -ENOMEM;
1263 free(seq->ibuf);
1264 seq->ibuf = newbuf;
1265 seq->ibufsize = size;
1267 return 0;
1272 * \brief Get size of #snd_seq_system_info_t
1273 * \return size in bytes
1275 size_t snd_seq_system_info_sizeof()
1277 return sizeof(snd_seq_system_info_t);
1281 * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
1282 * \param ptr returned pointer
1283 * \return 0 on success otherwise negative error code
1285 int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
1287 assert(ptr);
1288 *ptr = calloc(1, sizeof(snd_seq_system_info_t));
1289 if (!*ptr)
1290 return -ENOMEM;
1291 return 0;
1295 * \brief Frees a previously allocated #snd_seq_system_info_t
1296 * \param obj pointer to object to free
1298 void snd_seq_system_info_free(snd_seq_system_info_t *obj)
1300 free(obj);
1304 * \brief Copy one #snd_seq_system_info_t to another
1305 * \param dst pointer to destination
1306 * \param src pointer to source
1308 void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
1310 assert(dst && src);
1311 *dst = *src;
1316 * \brief Get maximum number of queues
1317 * \param info #snd_seq_system_info_t container
1318 * \return maximum number of queues
1320 * \sa snd_seq_system_info()
1322 int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
1324 assert(info);
1325 return info->queues;
1329 * \brief Get maximum number of clients
1330 * \param info #snd_seq_system_info_t container
1331 * \return maximum number of clients
1333 * \sa snd_seq_system_info()
1335 int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
1337 assert(info);
1338 return info->clients;
1342 * \brief Get maximum number of ports
1343 * \param info #snd_seq_system_info_t container
1344 * \return maximum number of ports
1346 * \sa snd_seq_system_info()
1348 int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
1350 assert(info);
1351 return info->ports;
1355 * \brief Get maximum number of channels
1356 * \param info #snd_seq_system_info_t container
1357 * \return maximum number of channels
1359 * \sa snd_seq_system_info()
1361 int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
1363 assert(info);
1364 return info->channels;
1368 * \brief Get the current number of clients
1369 * \param info #snd_seq_system_info_t container
1370 * \return current number of clients
1372 * \sa snd_seq_system_info()
1374 int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
1376 assert(info);
1377 return info->cur_clients;
1381 * \brief Get the current number of queues
1382 * \param info #snd_seq_system_info_t container
1383 * \return current number of queues
1385 * \sa snd_seq_system_info()
1387 int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
1389 assert(info);
1390 return info->cur_queues;
1394 * \brief obtain the sequencer system information
1395 * \param seq sequencer handle
1396 * \param info the pointer to be stored
1397 * \return 0 on success otherwise a negative error code
1399 * Stores the global system information of ALSA sequencer system.
1400 * The returned data contains
1401 * the maximum available numbers of queues, clients, ports and channels.
1403 int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
1405 assert(seq && info);
1406 return seq->ops->system_info(seq, info);
1410 /*----------------------------------------------------------------*/
1413 * \brief get size of #snd_seq_client_info_t
1414 * \return size in bytes
1416 size_t snd_seq_client_info_sizeof()
1418 return sizeof(snd_seq_client_info_t);
1422 * \brief allocate an empty #snd_seq_client_info_t using standard malloc
1423 * \param ptr returned pointer
1424 * \return 0 on success otherwise negative error code
1426 int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
1428 assert(ptr);
1429 *ptr = calloc(1, sizeof(snd_seq_client_info_t));
1430 if (!*ptr)
1431 return -ENOMEM;
1432 return 0;
1436 * \brief frees a previously allocated #snd_seq_client_info_t
1437 * \param obj pointer to object to free
1439 void snd_seq_client_info_free(snd_seq_client_info_t *obj)
1441 free(obj);
1445 * \brief copy one #snd_seq_client_info_t to another
1446 * \param dst pointer to destination
1447 * \param src pointer to source
1449 void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
1451 assert(dst && src);
1452 *dst = *src;
1457 * \brief Get client id of a client_info container
1458 * \param info client_info container
1459 * \return client id
1461 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
1463 int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
1465 assert(info);
1466 return info->client;
1470 * \brief Get client type of a client_info container
1471 * \param info client_info container
1472 * \return client type
1474 * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
1475 * for kernel or user client respectively.
1477 * \sa snd_seq_get_client_info()
1479 snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
1481 assert(info);
1482 return info->type;
1486 * \brief Get the name of a client_info container
1487 * \param info client_info container
1488 * \return name string
1490 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
1492 const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
1494 assert(info);
1495 return info->name;
1499 * \brief Get the broadcast filter usage of a client_info container
1500 * \param info client_info container
1501 * \return 1 if broadcast is accepted
1503 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
1505 int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
1507 assert(info);
1508 return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
1512 * \brief Get the error-bounce usage of a client_info container
1513 * \param info client_info container
1514 * \return 1 if error-bounce is enabled
1516 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
1518 int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
1520 assert(info);
1521 return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
1525 * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
1526 * \param info client_info container
1527 * \return NULL if no event filter, or pointer to event filter bitmap
1529 * Use #snd_seq_client_info_event_filter_check() instead.
1531 * \sa snd_seq_client_info_event_filter_add(),
1532 * snd_seq_client_info_event_filter_del(),
1533 * snd_seq_client_info_event_filter_check(),
1534 * snd_seq_client_info_event_filter_clear(),
1535 * snd_seq_get_client_info()
1537 const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
1539 assert(info);
1540 if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
1541 return info->event_filter;
1542 else
1543 return NULL;
1547 * \brief Disable event filtering of a client_info container
1548 * \param info client_info container
1550 * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
1551 * the event filtering flag of this client_info container.
1553 * \sa snd_seq_client_info_event_filter_add(),
1554 * snd_seq_client_info_event_filter_del(),
1555 * snd_seq_client_info_event_filter_check(),
1556 * snd_seq_get_client_info(),
1557 * snd_seq_set_client_info()
1559 void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
1561 assert(info);
1562 info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1563 memset(info->event_filter, 0, sizeof(info->event_filter));
1567 * \brief Add an event type to the event filtering of a client_info container
1568 * \param info client_info container
1569 * \param event_type event type to be added
1571 * Set the event filtering flag of this client_info and add the specified event type to the
1572 * filter bitmap of this client_info container.
1574 * \sa snd_seq_get_client_info(),
1575 * snd_seq_set_client_info(),
1576 * snd_seq_client_info_event_filter_del(),
1577 * snd_seq_client_info_event_filter_check(),
1578 * snd_seq_client_info_event_filter_clear()
1580 void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
1582 assert(info);
1583 info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1584 snd_seq_set_bit(event_type, info->event_filter);
1588 * \brief Remove an event type from the event filtering of a client_info container
1589 * \param info client_info container
1590 * \param event_type event type to be removed
1592 * Removes the specified event from the filter bitmap of this client_info container. It will
1593 * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
1595 * \sa snd_seq_get_client_info(),
1596 * snd_seq_set_client_info(),
1597 * snd_seq_client_info_event_filter_add(),
1598 * snd_seq_client_info_event_filter_check(),
1599 * snd_seq_client_info_event_filter_clear()
1601 void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
1603 assert(info);
1604 snd_seq_unset_bit(event_type, info->event_filter);
1608 * \brief Check if an event type is present in the event filtering of a client_info container
1609 * \param info client_info container
1610 * \param event_type event type to be checked
1611 * \return 1 if the event type is present, 0 otherwise
1613 * Test if the event type is in the filter bitmap of this client_info container.
1615 * \sa snd_seq_get_client_info(),
1616 * snd_seq_set_client_info(),
1617 * snd_seq_client_info_event_filter_add(),
1618 * snd_seq_client_info_event_filter_del(),
1619 * snd_seq_client_info_event_filter_clear()
1621 int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
1623 assert(info);
1624 return snd_seq_get_bit(event_type, info->event_filter);
1628 * \brief Get the number of opened ports of a client_info container
1629 * \param info client_info container
1630 * \return number of opened ports
1632 * \sa snd_seq_get_client_info()
1634 int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
1636 assert(info);
1637 return info->num_ports;
1641 * \brief Get the number of lost events of a client_info container
1642 * \param info client_info container
1643 * \return number of lost events
1645 * \sa snd_seq_get_client_info()
1647 int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
1649 assert(info);
1650 return info->event_lost;
1654 * \brief Set the client id of a client_info container
1655 * \param info client_info container
1656 * \param client client id
1658 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
1660 void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
1662 assert(info);
1663 info->client = client;
1667 * \brief Set the name of a client_info container
1668 * \param info client_info container
1669 * \param name name string
1671 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
1672 * snd_seq_set_client_name()
1674 void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
1676 assert(info && name);
1677 strncpy(info->name, name, sizeof(info->name));
1681 * \brief Set the broadcast filter usage of a client_info container
1682 * \param info client_info container
1683 * \param val non-zero if broadcast is accepted
1685 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
1687 void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
1689 assert(info);
1690 if (val)
1691 info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
1692 else
1693 info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
1697 * \brief Set the error-bounce usage of a client_info container
1698 * \param info client_info container
1699 * \param val non-zero if error is bounced
1701 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
1703 void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
1705 assert(info);
1706 if (val)
1707 info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
1708 else
1709 info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
1713 * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
1714 * \param info client_info container
1715 * \param filter event filter bitmap, pass NULL for no event filtering
1717 * Use #snd_seq_client_info_event_filter_add instead.
1719 * \sa snd_seq_client_info_event_filter_add(),
1720 * snd_seq_client_info_event_filter_del(),
1721 * snd_seq_client_info_event_filter_check(),
1722 * snd_seq_client_info_event_filter_clear(),
1723 * snd_seq_set_client_info()
1725 void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
1727 assert(info);
1728 if (! filter)
1729 info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
1730 else {
1731 info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
1732 memcpy(info->event_filter, filter, sizeof(info->event_filter));
1738 * \brief obtain the information of the given client
1739 * \param seq sequencer handle
1740 * \param client client id
1741 * \param info the pointer to be stored
1742 * \return 0 on success otherwise a negative error code
1744 * Obtains the information of the client with a client id specified by
1745 * info argument.
1746 * The obtained information is written on info parameter.
1748 * \sa snd_seq_get_client_info()
1750 int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
1752 assert(seq && info && client >= 0);
1753 memset(info, 0, sizeof(snd_seq_client_info_t));
1754 info->client = client;
1755 return seq->ops->get_client_info(seq, info);
1759 * \brief obtain the current client information
1760 * \param seq sequencer handle
1761 * \param info the pointer to be stored
1762 * \return 0 on success otherwise a negative error code
1764 * Obtains the information of the current client stored on info.
1765 * client and type fields are ignored.
1767 * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
1768 * snd_seq_query_next_client()
1770 int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1772 return snd_seq_get_any_client_info(seq, seq->client, info);
1776 * \brief set the current client information
1777 * \param seq sequencer handle
1778 * \param info the client info data to set
1779 * \return 0 on success otherwise a negative error code
1781 * Obtains the information of the current client stored on info.
1782 * client and type fields are ignored.
1784 * \sa snd_seq_get_client_info()
1786 int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
1788 assert(seq && info);
1789 info->client = seq->client;
1790 info->type = USER_CLIENT;
1791 return seq->ops->set_client_info(seq, info);
1795 * \brief query the next client
1796 * \param seq sequencer handle
1797 * \param info query pattern and result
1799 * Queries the next client.
1800 * The search begins at the client with an id one greater than
1801 * client field in info.
1802 * If a client is found, its attributes are stored in info,
1803 * and zero is returned.
1804 * Otherwise returns a negative error code.
1806 * \sa snd_seq_get_any_client_info()
1808 int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
1810 assert(seq && info);
1811 return seq->ops->query_next_client(seq, info);
1815 /*----------------------------------------------------------------*/
1819 * Port
1823 * \brief get size of #snd_seq_port_info_t
1824 * \return size in bytes
1826 size_t snd_seq_port_info_sizeof()
1828 return sizeof(snd_seq_port_info_t);
1832 * \brief allocate an empty #snd_seq_port_info_t using standard malloc
1833 * \param ptr returned pointer
1834 * \return 0 on success otherwise negative error code
1836 int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
1838 assert(ptr);
1839 *ptr = calloc(1, sizeof(snd_seq_port_info_t));
1840 if (!*ptr)
1841 return -ENOMEM;
1842 return 0;
1846 * \brief frees a previously allocated #snd_seq_port_info_t
1847 * \param obj pointer to object to free
1849 void snd_seq_port_info_free(snd_seq_port_info_t *obj)
1851 free(obj);
1855 * \brief copy one #snd_seq_port_info_t to another
1856 * \param dst pointer to destination
1857 * \param src pointer to source
1859 void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
1861 assert(dst && src);
1862 *dst = *src;
1867 * \brief Get client id of a port_info container
1868 * \param info port_info container
1869 * \return client id
1871 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
1873 int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
1875 assert(info);
1876 return info->addr.client;
1880 * \brief Get port id of a port_info container
1881 * \param info port_info container
1882 * \return port id
1884 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
1886 int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
1888 assert(info);
1889 return info->addr.port;
1893 * \brief Get client/port address of a port_info container
1894 * \param info port_info container
1895 * \return client/port address pointer
1897 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
1899 const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
1901 assert(info);
1902 return &info->addr;
1906 * \brief Get the name of a port_info container
1907 * \param info port_info container
1908 * \return name string
1910 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
1912 const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
1914 assert(info);
1915 return info->name;
1919 * \brief Get the capability bits of a port_info container
1920 * \param info port_info container
1921 * \return capability bits
1923 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
1925 unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
1927 assert(info);
1928 return info->capability;
1932 * \brief Get the type bits of a port_info container
1933 * \param info port_info container
1934 * \return port type bits
1936 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
1938 unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
1940 assert(info);
1941 return info->type;
1945 * \brief Get the number of read subscriptions of a port_info container
1946 * \param info port_info container
1947 * \return number of read subscriptions
1949 * \sa snd_seq_get_port_info()
1951 int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
1953 assert(info);
1954 return info->read_use;
1958 * \brief Get the number of write subscriptions of a port_info container
1959 * \param info port_info container
1960 * \return number of write subscriptions
1962 * \sa snd_seq_get_port_info()
1964 int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
1966 assert(info);
1967 return info->write_use;
1971 * \brief Get the midi channels of a port_info container
1972 * \param info port_info container
1973 * \return number of midi channels (default 0)
1975 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
1977 int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
1979 assert(info);
1980 return info->midi_channels;
1984 * \brief Get the midi voices of a port_info container
1985 * \param info port_info container
1986 * \return number of midi voices (default 0)
1988 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
1990 int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
1992 assert(info);
1993 return info->midi_voices;
1997 * \brief Get the synth voices of a port_info container
1998 * \param info port_info container
1999 * \return number of synth voices (default 0)
2001 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
2003 int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
2005 assert(info);
2006 return info->synth_voices;
2010 * \brief Get the port-specified mode of a port_info container
2011 * \param info port_info container
2012 * \return 1 if port id is specified at creation
2014 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
2016 int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
2018 assert(info);
2019 return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
2023 * \brief Get the time-stamping mode of the given port in a port_info container
2024 * \param info port_info container
2025 * \return 1 if the port updates timestamps of incoming events
2027 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
2029 int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
2031 assert(info);
2032 return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
2036 * \brief Get whether the time-stamping of the given port is real-time mode
2037 * \param info port_info container
2038 * \return 1 if the time-stamping is in the real-time mode
2040 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
2042 int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
2044 assert(info);
2045 return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
2049 * \brief Get the queue id to update timestamps
2050 * \param info port_info container
2051 * \return the queue id to get the timestamps
2053 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
2055 int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
2057 assert(info);
2058 return info->time_queue;
2062 * \brief Set the client id of a port_info container
2063 * \param info port_info container
2064 * \param client client id
2066 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
2068 void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
2070 assert(info);
2071 info->addr.client = client;
2075 * \brief Set the port id of a port_info container
2076 * \param info port_info container
2077 * \param port port id
2079 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
2081 void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
2083 assert(info);
2084 info->addr.port = port;
2088 * \brief Set the client/port address of a port_info container
2089 * \param info port_info container
2090 * \param addr client/port address
2092 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
2094 void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
2096 assert(info);
2097 info->addr = *addr;
2101 * \brief Set the name of a port_info container
2102 * \param info port_info container
2103 * \param name name string
2105 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
2107 void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
2109 assert(info && name);
2110 strncpy(info->name, name, sizeof(info->name));
2114 * \brief set the capability bits of a port_info container
2115 * \param info port_info container
2116 * \param capability capability bits
2118 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
2120 void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
2122 assert(info);
2123 info->capability = capability;
2127 * \brief Get the type bits of a port_info container
2128 * \param info port_info container
2129 * \param type port type bits
2131 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
2133 void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
2135 assert(info);
2136 info->type = type;
2140 * \brief set the midi channels of a port_info container
2141 * \param info port_info container
2142 * \param channels midi channels (default 0)
2144 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
2146 void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
2148 assert(info);
2149 info->midi_channels = channels;
2153 * \brief set the midi voices of a port_info container
2154 * \param info port_info container
2155 * \param voices midi voices (default 0)
2157 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
2159 void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
2161 assert(info);
2162 info->midi_voices = voices;
2166 * \brief set the synth voices of a port_info container
2167 * \param info port_info container
2168 * \param voices synth voices (default 0)
2170 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
2172 void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
2174 assert(info);
2175 info->synth_voices = voices;
2179 * \brief Set the port-specified mode of a port_info container
2180 * \param info port_info container
2181 * \param val non-zero if specifying the port id at creation
2183 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
2185 void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
2187 assert(info);
2188 if (val)
2189 info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2190 else
2191 info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
2195 * \brief Set the time-stamping mode of the given port
2196 * \param info port_info container
2197 * \param enable non-zero if updating the timestamps of incoming events
2199 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
2201 void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
2203 assert(info);
2204 if (enable)
2205 info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2206 else
2207 info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
2211 * \brief Set whether the timestime is updated in the real-time mode
2212 * \param info port_info container
2213 * \param enable non-zero if updating the timestamps in real-time mode
2215 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
2217 void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
2219 assert(info);
2220 if (enable)
2221 info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
2222 else
2223 info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
2227 * \brief Set the queue id for timestamping
2228 * \param info port_info container
2229 * \param queue the queue id to get timestamps
2231 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
2233 void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
2235 assert(info);
2236 info->time_queue = queue;
2241 * \brief create a sequencer port on the current client
2242 * \param seq sequencer handle
2243 * \param port port information for the new port
2244 * \return 0 on success otherwise a negative error code
2246 * Creates a sequencer port on the current client.
2247 * The attributes of created port is specified in \a info argument.
2249 * The client field in \a info argument is overwritten with the current client id.
2250 * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
2251 * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
2253 * Each port has the capability bit-masks to specify the access capability
2254 * of the port from other clients.
2255 * The capability bit flags are defined as follows:
2256 * - #SND_SEQ_PORT_CAP_READ Readable from this port
2257 * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
2258 * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
2259 * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
2260 * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
2261 * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
2262 * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
2263 * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
2265 * Each port has also the type bitmasks defined as follows:
2266 * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
2267 * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
2268 * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
2269 * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
2270 * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
2271 * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
2272 * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
2273 * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
2274 * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
2275 * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
2276 * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
2277 * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
2279 * A port may contain specific midi channels, midi voices and synth voices.
2280 * These values could be zero as default.
2282 * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
2283 * snd_seq_create_simple_port()
2285 int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
2287 assert(seq && port);
2288 port->addr.client = seq->client;
2289 return seq->ops->create_port(seq, port);
2293 * \brief delete a sequencer port on the current client
2294 * \param seq sequencer handle
2295 * \param port port to be deleted
2296 * \return 0 on success otherwise a negative error code
2298 * Deletes the existing sequencer port on the current client.
2300 * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
2302 int snd_seq_delete_port(snd_seq_t *seq, int port)
2304 snd_seq_port_info_t pinfo;
2305 assert(seq);
2306 memset(&pinfo, 0, sizeof(pinfo));
2307 pinfo.addr.client = seq->client;
2308 pinfo.addr.port = port;
2309 return seq->ops->delete_port(seq, &pinfo);
2313 * \brief obtain the information of a port on an arbitrary client
2314 * \param seq sequencer handle
2315 * \param client client id to get
2316 * \param port port id to get
2317 * \param info pointer information returns
2318 * \return 0 on success otherwise a negative error code
2320 * \sa snd_seq_get_port_info()
2322 int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
2324 assert(seq && info && client >= 0 && port >= 0);
2325 memset(info, 0, sizeof(snd_seq_port_info_t));
2326 info->addr.client = client;
2327 info->addr.port = port;
2328 return seq->ops->get_port_info(seq, info);
2332 * \brief obtain the information of a port on the current client
2333 * \param seq sequencer handle
2334 * \param port port id to get
2335 * \param info pointer information returns
2336 * \return 0 on success otherwise a negative error code
2338 * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
2339 * snd_seq_query_next_port()
2341 int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2343 return snd_seq_get_any_port_info(seq, seq->client, port, info);
2347 * \brief set the information of a port on the current client
2348 * \param seq sequencer handle
2349 * \param port port to be set
2350 * \param info port information to be set
2351 * \return 0 on success otherwise a negative error code
2353 * \sa snd_seq_set_port_info()
2355 int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
2357 assert(seq && info && port >= 0);
2358 info->addr.client = seq->client;
2359 info->addr.port = port;
2360 return seq->ops->set_port_info(seq, info);
2364 * \brief query the next matching port
2365 * \param seq sequencer handle
2366 * \param info query pattern and result
2368 * Queries the next matching port on the client specified in
2369 * \a info argument.
2370 * The search begins at the next port specified in
2371 * port field of \a info argument.
2372 * For finding the first port at a certain client, give -1.
2374 * If a matching port is found, its attributes are stored on
2375 * \a info and function returns zero.
2376 * Otherwise, a negative error code is returned.
2378 * \sa snd_seq_get_port_info()
2380 int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
2382 assert(seq && info);
2383 return seq->ops->query_next_port(seq, info);
2387 /*----------------------------------------------------------------*/
2390 * subscription
2395 * \brief get size of #snd_seq_port_subscribe_t
2396 * \return size in bytes
2398 size_t snd_seq_port_subscribe_sizeof()
2400 return sizeof(snd_seq_port_subscribe_t);
2404 * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
2405 * \param ptr returned pointer
2406 * \return 0 on success otherwise negative error code
2408 int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
2410 assert(ptr);
2411 *ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
2412 if (!*ptr)
2413 return -ENOMEM;
2414 return 0;
2418 * \brief frees a previously allocated #snd_seq_port_subscribe_t
2419 * \param obj pointer to object to free
2421 void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
2423 free(obj);
2427 * \brief copy one #snd_seq_port_subscribe_t to another
2428 * \param dst pointer to destination
2429 * \param src pointer to source
2431 void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
2433 assert(dst && src);
2434 *dst = *src;
2439 * \brief Get sender address of a port_subscribe container
2440 * \param info port_subscribe container
2442 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
2444 const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
2446 assert(info);
2447 return &info->sender;
2451 * \brief Get destination address of a port_subscribe container
2452 * \param info port_subscribe container
2454 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
2456 const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
2458 assert(info);
2459 return &info->dest;
2463 * \brief Get the queue id of a port_subscribe container
2464 * \param info port_subscribe container
2465 * \return queue id
2467 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
2469 int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
2471 assert(info);
2472 return info->queue;
2476 * \brief Get the exclusive mode of a port_subscribe container
2477 * \param info port_subscribe container
2478 * \return 1 if exclusive mode
2480 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
2482 int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
2484 assert(info);
2485 return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2489 * \brief Get the time-update mode of a port_subscribe container
2490 * \param info port_subscribe container
2491 * \return 1 if update timestamp
2493 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
2495 int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
2497 assert(info);
2498 return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2502 * \brief Get the real-time update mode of a port_subscribe container
2503 * \param info port_subscribe container
2504 * \return 1 if real-time update mode
2506 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
2508 int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
2510 assert(info);
2511 return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
2515 * \brief Set sender address of a port_subscribe container
2516 * \param info port_subscribe container
2517 * \param addr sender address
2519 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
2521 void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2523 assert(info);
2524 memcpy(&info->sender, addr, sizeof(*addr));
2528 * \brief Set destination address of a port_subscribe container
2529 * \param info port_subscribe container
2530 * \param addr destination address
2532 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
2534 void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
2536 assert(info);
2537 memcpy(&info->dest, addr, sizeof(*addr));
2541 * \brief Set the queue id of a port_subscribe container
2542 * \param info port_subscribe container
2543 * \param q queue id
2545 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
2547 void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
2549 assert(info);
2550 info->queue = q;
2554 * \brief Set the exclusive mode of a port_subscribe container
2555 * \param info port_subscribe container
2556 * \param val non-zero to enable
2558 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
2560 void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
2562 assert(info);
2563 if (val)
2564 info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2565 else
2566 info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
2570 * \brief Set the time-update mode of a port_subscribe container
2571 * \param info port_subscribe container
2572 * \param val non-zero to enable
2574 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
2576 void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
2578 assert(info);
2579 if (val)
2580 info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2581 else
2582 info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
2586 * \brief Set the real-time mode of a port_subscribe container
2587 * \param info port_subscribe container
2588 * \param val non-zero to enable
2590 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
2592 void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
2594 assert(info);
2595 if (val)
2596 info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2597 else
2598 info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
2603 * \brief obtain subscription information
2604 * \param seq sequencer handle
2605 * \param sub pointer to return the subscription information
2606 * \return 0 on success otherwise a negative error code
2608 * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
2610 int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2612 assert(seq && sub);
2613 return seq->ops->get_port_subscription(seq, sub);
2617 * \brief subscribe a port connection
2618 * \param seq sequencer handle
2619 * \param sub subscription information
2620 * \return 0 on success otherwise a negative error code
2622 * Subscribes a connection between two ports.
2623 * The subscription information is stored in sub argument.
2625 * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
2626 * snd_seq_connect_from(), snd_seq_connect_to()
2628 int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2630 assert(seq && sub);
2631 return seq->ops->subscribe_port(seq, sub);
2635 * \brief unsubscribe a connection between ports
2636 * \param seq sequencer handle
2637 * \param sub subscription information to disconnect
2638 * \return 0 on success otherwise a negative error code
2640 * Unsubscribes a connection between two ports,
2641 * described in sender and dest fields in sub argument.
2643 * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
2645 int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
2647 assert(seq && sub);
2648 return seq->ops->unsubscribe_port(seq, sub);
2653 * \brief get size of #snd_seq_query_subscribe_t
2654 * \return size in bytes
2656 size_t snd_seq_query_subscribe_sizeof()
2658 return sizeof(snd_seq_query_subscribe_t);
2662 * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
2663 * \param ptr returned pointer
2664 * \return 0 on success otherwise negative error code
2666 int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
2668 assert(ptr);
2669 *ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
2670 if (!*ptr)
2671 return -ENOMEM;
2672 return 0;
2676 * \brief frees a previously allocated #snd_seq_query_subscribe_t
2677 * \param obj pointer to object to free
2679 void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
2681 free(obj);
2685 * \brief copy one #snd_seq_query_subscribe_t to another
2686 * \param dst pointer to destination
2687 * \param src pointer to source
2689 void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
2691 assert(dst && src);
2692 *dst = *src;
2697 * \brief Get the client id of a query_subscribe container
2698 * \param info query_subscribe container
2699 * \return client id
2701 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
2703 int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
2705 assert(info);
2706 return info->root.client;
2710 * \brief Get the port id of a query_subscribe container
2711 * \param info query_subscribe container
2712 * \return port id
2714 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
2716 int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
2718 assert(info);
2719 return info->root.port;
2723 * \brief Get the client/port address of a query_subscribe container
2724 * \param info query_subscribe container
2725 * \return client/port address pointer
2727 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
2729 const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
2731 assert(info);
2732 return &info->root;
2736 * \brief Get the query type of a query_subscribe container
2737 * \param info query_subscribe container
2738 * \return query type
2740 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
2742 snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
2744 assert(info);
2745 return info->type;
2749 * \brief Get the index of subscriber of a query_subscribe container
2750 * \param info query_subscribe container
2751 * \return subscriber's index
2753 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
2755 int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
2757 assert(info);
2758 return info->index;
2762 * \brief Get the number of subscriptions of a query_subscribe container
2763 * \param info query_subscribe container
2764 * \return number of subscriptions
2766 * \sa snd_seq_query_port_subscribers()
2768 int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
2770 assert(info);
2771 return info->num_subs;
2775 * \brief Get the address of subscriber of a query_subscribe container
2776 * \param info query_subscribe container
2777 * \return subscriber's address pointer
2779 * \sa snd_seq_query_port_subscribers()
2781 const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
2783 assert(info);
2784 return &info->addr;
2788 * \brief Get the queue id of subscriber of a query_subscribe container
2789 * \param info query_subscribe container
2790 * \return subscriber's queue id
2792 * \sa snd_seq_query_port_subscribers()
2794 int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
2796 assert(info);
2797 return info->queue;
2801 * \brief Get the exclusive mode of a query_subscribe container
2802 * \param info query_subscribe container
2803 * \return 1 if exclusive mode
2805 * \sa snd_seq_query_port_subscribers()
2807 int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
2809 assert(info);
2810 return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
2814 * \brief Get the time-update mode of a query_subscribe container
2815 * \param info query_subscribe container
2816 * \return 1 if update timestamp
2818 * \sa snd_seq_query_port_subscribers()
2820 int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
2822 assert(info);
2823 return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2827 * \brief Get the real-time update mode of a query_subscribe container
2828 * \param info query_subscribe container
2829 * \return 1 if real-time update mode
2831 * \sa snd_seq_query_port_subscribers()
2833 int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
2835 assert(info);
2836 return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
2840 * \brief Set the client id of a query_subscribe container
2841 * \param info query_subscribe container
2842 * \param client client id
2844 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
2846 void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
2848 assert(info);
2849 info->root.client = client;
2853 * \brief Set the port id of a query_subscribe container
2854 * \param info query_subscribe container
2855 * \param port port id
2857 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
2859 void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
2861 assert(info);
2862 info->root.port = port;
2866 * \brief Set the client/port address of a query_subscribe container
2867 * \param info query_subscribe container
2868 * \param addr client/port address pointer
2870 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
2872 void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
2874 assert(info);
2875 info->root = *addr;
2879 * \brief Set the query type of a query_subscribe container
2880 * \param info query_subscribe container
2881 * \param type query type
2883 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
2885 void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
2887 assert(info);
2888 info->type = type;
2892 * \brief Set the subscriber's index to be queried
2893 * \param info query_subscribe container
2894 * \param index index to be queried
2896 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
2898 void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
2900 assert(info);
2901 info->index = index;
2906 * \brief query port subscriber list
2907 * \param seq sequencer handle
2908 * \param subs subscription to query
2909 * \return 0 on success otherwise a negative error code
2911 * Queries the subscribers accessing to a port.
2912 * The query information is specified in subs argument.
2914 * At least, the client id, the port id, the index number and
2915 * the query type must be set to perform a proper query.
2916 * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
2917 * can be specified to check whether the readers or the writers to the port.
2918 * To query the first subscription, set 0 to the index number. To list up
2919 * all the subscriptions, call this function with the index numbers from 0
2920 * until this returns a negative value.
2922 * \sa snd_seq_get_port_subscription()
2924 int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
2926 assert(seq && subs);
2927 return seq->ops->query_port_subscribers(seq, subs);
2930 /*----------------------------------------------------------------*/
2933 * queue handlers
2937 * \brief get size of #snd_seq_queue_info_t
2938 * \return size in bytes
2940 size_t snd_seq_queue_info_sizeof()
2942 return sizeof(snd_seq_queue_info_t);
2946 * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
2947 * \param ptr returned pointer
2948 * \return 0 on success otherwise negative error code
2950 int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
2952 assert(ptr);
2953 *ptr = calloc(1, sizeof(snd_seq_queue_info_t));
2954 if (!*ptr)
2955 return -ENOMEM;
2956 return 0;
2960 * \brief frees a previously allocated #snd_seq_queue_info_t
2961 * \param obj pointer to object to free
2963 void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
2965 free(obj);
2969 * \brief copy one #snd_seq_queue_info_t to another
2970 * \param dst pointer to destination
2971 * \param src pointer to source
2973 void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
2975 assert(dst && src);
2976 *dst = *src;
2981 * \brief Get the queue id of a queue_info container
2982 * \param info queue_info container
2983 * \return queue id
2985 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
2987 int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
2989 assert(info);
2990 return info->queue;
2994 * \brief Get the name of a queue_info container
2995 * \param info queue_info container
2996 * \return name string
2998 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
3000 const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
3002 assert(info);
3003 return info->name;
3007 * \brief Get the owner client id of a queue_info container
3008 * \param info queue_info container
3009 * \return owner client id
3011 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
3013 int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
3015 assert(info);
3016 return info->owner;
3020 * \brief Get the lock status of a queue_info container
3021 * \param info queue_info container
3022 * \return lock status --- non-zero = locked
3024 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
3026 int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
3028 assert(info);
3029 return info->locked;
3033 * \brief Get the conditional bit flags of a queue_info container
3034 * \param info queue_info container
3035 * \return conditional bit flags
3037 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
3039 unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
3041 assert(info);
3042 return info->flags;
3046 * \brief Set the name of a queue_info container
3047 * \param info queue_info container
3048 * \param name name string
3050 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
3052 void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
3054 assert(info && name);
3055 strncpy(info->name, name, sizeof(info->name));
3059 * \brief Set the owner client id of a queue_info container
3060 * \param info queue_info container
3061 * \param owner client id
3063 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
3065 void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
3067 assert(info);
3068 info->owner = owner;
3072 * \brief Set the lock status of a queue_info container
3073 * \param info queue_info container
3074 * \param locked lock status
3076 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
3078 void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
3080 assert(info);
3081 info->locked = locked;
3085 * \brief Set the conditional bit flags of a queue_info container
3086 * \param info queue_info container
3087 * \param flags conditional bit flags
3089 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
3091 void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
3093 assert(info);
3094 info->flags = flags;
3099 * \brief create a queue
3100 * \param seq sequencer handle
3101 * \param info queue information to initialize
3102 * \return the queue id (zero or positive) on success otherwise a negative error code
3104 * \sa snd_seq_alloc_queue()
3106 int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
3108 int err;
3109 assert(seq && info);
3110 info->owner = seq->client;
3111 err = seq->ops->create_queue(seq, info);
3112 if (err < 0)
3113 return err;
3114 return info->queue;
3118 * \brief allocate a queue with the specified name
3119 * \param seq sequencer handle
3120 * \param name the name of the new queue
3121 * \return the queue id (zero or positive) on success otherwise a negative error code
3123 * \sa snd_seq_alloc_queue()
3125 int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
3127 snd_seq_queue_info_t info;
3128 memset(&info, 0, sizeof(info));
3129 info.locked = 1;
3130 if (name)
3131 strncpy(info.name, name, sizeof(info.name) - 1);
3132 return snd_seq_create_queue(seq, &info);
3136 * \brief allocate a queue
3137 * \param seq sequencer handle
3138 * \return the queue id (zero or positive) on success otherwise a negative error code
3140 * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
3141 * snd_seq_get_queue_info()
3143 int snd_seq_alloc_queue(snd_seq_t *seq)
3145 return snd_seq_alloc_named_queue(seq, NULL);
3149 * \brief delete the specified queue
3150 * \param seq sequencer handle
3151 * \param q queue id to delete
3152 * \return 0 on success otherwise a negative error code
3154 * \sa snd_seq_alloc_queue()
3156 int snd_seq_free_queue(snd_seq_t *seq, int q)
3158 snd_seq_queue_info_t info;
3159 assert(seq);
3160 memset(&info, 0, sizeof(info));
3161 info.queue = q;
3162 return seq->ops->delete_queue(seq, &info);
3166 * \brief obtain queue attributes
3167 * \param seq sequencer handle
3168 * \param q queue id to query
3169 * \param info information returned
3170 * \return 0 on success otherwise a negative error code
3172 * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
3174 int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3176 assert(seq && info);
3177 info->queue = q;
3178 return seq->ops->get_queue_info(seq, info);
3182 * \brief change the queue attributes
3183 * \param seq sequencer handle
3184 * \param q queue id to change
3185 * \param info information changed
3186 * \return 0 on success otherwise a negative error code
3188 * \sa snd_seq_get_queue_info()
3190 int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
3192 assert(seq && info);
3193 info->queue = q;
3194 return seq->ops->set_queue_info(seq, info);
3198 * \brief query the matching queue with the specified name
3199 * \param seq sequencer handle
3200 * \param name the name string to query
3201 * \return the queue id if found or negative error code
3203 * Searches the matching queue with the specified name string.
3205 * \sa snd_seq_get_queue_info()
3207 int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
3209 int err;
3210 snd_seq_queue_info_t info;
3211 assert(seq && name);
3212 strncpy(info.name, name, sizeof(info.name));
3213 err = seq->ops->get_named_queue(seq, &info);
3214 if (err < 0)
3215 return err;
3216 return info.queue;
3220 * \brief Get the queue usage flag to the client
3221 * \param seq sequencer handle
3222 * \param q queue id
3223 * \return 1 = client is allowed to access the queue, 0 = not allowed,
3224 * otherwise a negative error code
3226 * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3228 int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
3230 struct sndrv_seq_queue_client info;
3231 int err;
3232 assert(seq);
3233 memset(&info, 0, sizeof(info));
3234 info.queue = q;
3235 info.client = seq->client;
3236 if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
3237 return err;
3238 return info.used;
3242 * \brief Set the queue usage flag to the client
3243 * \param seq sequencer handle
3244 * \param q queue id
3245 * \param used non-zero if the client is allowed
3246 * \return 0 on success otherwise a negative error code
3248 * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
3250 int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
3252 struct sndrv_seq_queue_client info;
3253 assert(seq);
3254 memset(&info, 0, sizeof(info));
3255 info.queue = q;
3256 info.client = seq->client;
3257 info.used = used ? 1 : 0;
3258 return seq->ops->set_queue_client(seq, &info);
3263 * \brief get size of #snd_seq_queue_status_t
3264 * \return size in bytes
3266 size_t snd_seq_queue_status_sizeof()
3268 return sizeof(snd_seq_queue_status_t);
3272 * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
3273 * \param ptr returned pointer
3274 * \return 0 on success otherwise negative error code
3276 int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
3278 assert(ptr);
3279 *ptr = calloc(1, sizeof(snd_seq_queue_status_t));
3280 if (!*ptr)
3281 return -ENOMEM;
3282 return 0;
3286 * \brief frees a previously allocated #snd_seq_queue_status_t
3287 * \param obj pointer to object to free
3289 void snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
3291 free(obj);
3295 * \brief copy one #snd_seq_queue_status_t to another
3296 * \param dst pointer to destination
3297 * \param src pointer to source
3299 void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
3301 assert(dst && src);
3302 *dst = *src;
3307 * \brief Get the queue id of a queue_status container
3308 * \param info queue_status container
3309 * \return queue id
3311 * \sa snd_seq_get_queue_status()
3313 int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
3315 assert(info);
3316 return info->queue;
3320 * \brief Get the number of events of a queue_status container
3321 * \param info queue_status container
3322 * \return number of events
3324 * \sa snd_seq_get_queue_status()
3326 int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
3328 assert(info);
3329 return info->events;
3333 * \brief Get the tick time of a queue_status container
3334 * \param info queue_status container
3335 * \return tick time
3337 * \sa snd_seq_get_queue_status()
3339 snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
3341 assert(info);
3342 return info->tick;
3346 * \brief Get the real time of a queue_status container
3347 * \param info queue_status container
3349 * \sa snd_seq_get_queue_status()
3351 const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
3353 assert(info);
3354 return &info->time;
3358 * \brief Get the running status bits of a queue_status container
3359 * \param info queue_status container
3360 * \return running status bits
3362 * \sa snd_seq_get_queue_status()
3364 unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
3366 assert(info);
3367 return info->running;
3372 * \brief obtain the running state of the queue
3373 * \param seq sequencer handle
3374 * \param q queue id to query
3375 * \param status pointer to store the current status
3376 * \return 0 on success otherwise a negative error code
3378 * Obtains the running state of the specified queue q.
3380 int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
3382 assert(seq && status);
3383 memset(status, 0, sizeof(snd_seq_queue_status_t));
3384 status->queue = q;
3385 return seq->ops->get_queue_status(seq, status);
3390 * \brief get size of #snd_seq_queue_tempo_t
3391 * \return size in bytes
3393 size_t snd_seq_queue_tempo_sizeof()
3395 return sizeof(snd_seq_queue_tempo_t);
3399 * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
3400 * \param ptr returned pointer
3401 * \return 0 on success otherwise negative error code
3403 int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
3405 assert(ptr);
3406 *ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
3407 if (!*ptr)
3408 return -ENOMEM;
3409 return 0;
3413 * \brief frees a previously allocated #snd_seq_queue_tempo_t
3414 * \param obj pointer to object to free
3416 void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
3418 free(obj);
3422 * \brief copy one #snd_seq_queue_tempo_t to another
3423 * \param dst pointer to destination
3424 * \param src pointer to source
3426 void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
3428 assert(dst && src);
3429 *dst = *src;
3434 * \brief Get the queue id of a queue_status container
3435 * \param info queue_status container
3436 * \return queue id
3438 * \sa snd_seq_get_queue_tempo()
3440 int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
3442 assert(info);
3443 return info->queue;
3447 * \brief Get the tempo of a queue_status container
3448 * \param info queue_status container
3449 * \return tempo value
3451 * \sa snd_seq_get_queue_tempo()
3453 unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
3455 assert(info);
3456 return info->tempo;
3460 * \brief Get the ppq of a queue_status container
3461 * \param info queue_status container
3462 * \return ppq value
3464 * \sa snd_seq_get_queue_tempo()
3466 int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
3468 assert(info);
3469 return info->ppq;
3473 * \brief Get the timer skew value of a queue_status container
3474 * \param info queue_status container
3475 * \return timer skew value
3477 * \sa snd_seq_get_queue_tempo()
3479 unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info)
3481 assert(info);
3482 return info->skew_value;
3486 * \brief Get the timer skew base value of a queue_status container
3487 * \param info queue_status container
3488 * \return timer skew base value
3490 * \sa snd_seq_get_queue_tempo()
3492 unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info)
3494 assert(info);
3495 return info->skew_base;
3499 * \brief Set the tempo of a queue_status container
3500 * \param info queue_status container
3501 * \param tempo tempo value
3503 * \sa snd_seq_get_queue_tempo()
3505 void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
3507 assert(info);
3508 info->tempo = tempo;
3512 * \brief Set the ppq of a queue_status container
3513 * \param info queue_status container
3514 * \param ppq ppq value
3516 * \sa snd_seq_get_queue_tempo()
3518 void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
3520 assert(info);
3521 info->ppq = ppq;
3525 * \brief Set the timer skew value of a queue_status container
3526 * \param info queue_status container
3527 * \param skew timer skew value
3529 * The skew of timer is calculated as skew / base.
3530 * For example, to play with double speed, pass base * 2 as the skew value.
3532 * \sa snd_seq_get_queue_tempo()
3534 void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew)
3536 assert(info);
3537 info->skew_value = skew;
3541 * \brief Set the timer skew base value of a queue_status container
3542 * \param info queue_status container
3543 * \param base timer skew base value
3545 * \sa snd_seq_get_queue_tempo()
3547 void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base)
3549 assert(info);
3550 info->skew_base = base;
3554 * \brief obtain the current tempo of the queue
3555 * \param seq sequencer handle
3556 * \param q queue id to be queried
3557 * \param tempo pointer to store the current tempo
3558 * \return 0 on success otherwise a negative error code
3560 * \sa snd_seq_set_queue_tempo()
3562 int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3564 assert(seq && tempo);
3565 memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
3566 tempo->queue = q;
3567 return seq->ops->get_queue_tempo(seq, tempo);
3571 * \brief set the tempo of the queue
3572 * \param seq sequencer handle
3573 * \param q queue id to change the tempo
3574 * \param tempo tempo information
3575 * \return 0 on success otherwise a negative error code
3577 * \sa snd_seq_get_queue_tempo()
3579 int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
3581 assert(seq && tempo);
3582 tempo->queue = q;
3583 return seq->ops->set_queue_tempo(seq, tempo);
3587 /*----------------------------------------------------------------*/
3590 * \brief get size of #snd_seq_queue_timer_t
3591 * \return size in bytes
3593 size_t snd_seq_queue_timer_sizeof()
3595 return sizeof(snd_seq_queue_timer_t);
3599 * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
3600 * \param ptr returned pointer
3601 * \return 0 on success otherwise negative error code
3603 int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
3605 assert(ptr);
3606 *ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
3607 if (!*ptr)
3608 return -ENOMEM;
3609 return 0;
3613 * \brief frees a previously allocated #snd_seq_queue_timer_t
3614 * \param obj pointer to object to free
3616 void snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
3618 free(obj);
3622 * \brief copy one #snd_seq_queue_timer_t to another
3623 * \param dst pointer to destination
3624 * \param src pointer to source
3626 void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
3628 assert(dst && src);
3629 *dst = *src;
3634 * \brief Get the queue id of a queue_timer container
3635 * \param info queue_timer container
3636 * \return queue id
3638 * \sa snd_seq_get_queue_timer()
3640 int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
3642 assert(info);
3643 return info->queue;
3647 * \brief Get the timer type of a queue_timer container
3648 * \param info queue_timer container
3649 * \return timer type
3651 * \sa snd_seq_get_queue_timer()
3653 snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
3655 assert(info);
3656 return (snd_seq_queue_timer_type_t)info->type;
3660 * \brief Get the timer id of a queue_timer container
3661 * \param info queue_timer container
3662 * \return timer id pointer
3664 * \sa snd_seq_get_queue_timer()
3666 const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
3668 assert(info);
3669 return &info->u.alsa.id;
3673 * \brief Get the timer resolution of a queue_timer container
3674 * \param info queue_timer container
3675 * \return timer resolution
3677 * \sa snd_seq_get_queue_timer()
3679 unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
3681 assert(info);
3682 return info->u.alsa.resolution;
3686 * \brief Set the timer type of a queue_timer container
3687 * \param info queue_timer container
3688 * \param type timer type
3690 * \sa snd_seq_get_queue_timer()
3692 void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type)
3694 assert(info);
3695 info->type = (int)type;
3699 * \brief Set the timer id of a queue_timer container
3700 * \param info queue_timer container
3701 * \param id timer id pointer
3703 * \sa snd_seq_get_queue_timer()
3705 void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
3707 assert(info && id);
3708 info->u.alsa.id = *id;
3712 * \brief Set the timer resolution of a queue_timer container
3713 * \param info queue_timer container
3714 * \param resolution timer resolution
3716 * \sa snd_seq_get_queue_timer()
3718 void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
3720 assert(info);
3721 info->u.alsa.resolution = resolution;
3726 * \brief obtain the queue timer information
3727 * \param seq sequencer handle
3728 * \param q queue id to query
3729 * \param timer pointer to store the timer information
3730 * \return 0 on success otherwise a negative error code
3732 * \sa snd_seq_set_queue_timer()
3734 int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3736 assert(seq && timer);
3737 memset(timer, 0, sizeof(snd_seq_queue_timer_t));
3738 timer->queue = q;
3739 return seq->ops->get_queue_timer(seq, timer);
3743 * \brief set the queue timer information
3744 * \param seq sequencer handle
3745 * \param q queue id to change the timer
3746 * \param timer timer information
3747 * \return 0 on success otherwise a negative error code
3749 * \sa snd_seq_get_queue_timer()
3751 int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
3753 assert(seq && timer);
3754 timer->queue = q;
3755 return seq->ops->set_queue_timer(seq, timer);
3758 /*----------------------------------------------------------------*/
3760 #ifndef DOC_HIDDEN
3762 * \brief (DEPRECATED) create an event cell
3763 * \return the cell pointer allocated
3765 * create an event cell via malloc. the returned pointer must be released
3766 * by the application itself via normal free() call,
3767 * not via snd_seq_free_event().
3769 snd_seq_event_t *snd_seq_create_event(void)
3771 return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
3773 #endif
3776 * \brief (DEPRECATED) free an event
3778 * In the former version, this function was used to
3779 * release the event pointer which was allocated by snd_seq_event_input().
3780 * In the current version, the event record is not allocated, so
3781 * you don't have to call this function any more.
3783 #ifndef DOXYGEN
3784 int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
3785 #else
3786 int snd_seq_free_event(snd_seq_event_t *ev)
3787 #endif
3789 return 0;
3793 * \brief calculates the (encoded) byte-stream size of the event
3794 * \param ev the event
3795 * \return the size of decoded bytes
3797 ssize_t snd_seq_event_length(snd_seq_event_t *ev)
3799 ssize_t len = sizeof(snd_seq_event_t);
3800 assert(ev);
3801 if (snd_seq_ev_is_variable(ev))
3802 len += ev->data.ext.len;
3803 return len;
3806 /*----------------------------------------------------------------*/
3809 * output to sequencer
3813 * \brief output an event
3814 * \param seq sequencer handle
3815 * \param ev event to be output
3816 * \return the number of remaining events or a negative error code
3818 * An event is once expanded on the output buffer.
3819 * The output buffer will be drained automatically if it becomes full.
3821 * If events remain unprocessed on output buffer before drained,
3822 * the size of total byte data on output buffer is returned.
3823 * If the output buffer is empty, this returns zero.
3825 * \sa snd_seq_event_output_direct(), snd_seq_event_output_buffer(),
3826 * snd_seq_event_output_pending(), snd_seq_drain_output(),
3827 * snd_seq_drop_output(), snd_seq_extract_output(),
3828 * snd_seq_remove_events()
3830 int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
3832 int result;
3834 result = snd_seq_event_output_buffer(seq, ev);
3835 if (result == -EAGAIN) {
3836 result = snd_seq_drain_output(seq);
3837 if (result < 0)
3838 return result;
3839 return snd_seq_event_output_buffer(seq, ev);
3841 return result;
3845 * \brief output an event onto the lib buffer without draining buffer
3846 * \param seq sequencer handle
3847 * \param ev event to be output
3848 * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
3850 * This function doesn't drain buffer unlike snd_seq_event_output().
3852 * \sa snd_seq_event_output()
3854 int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
3856 int len;
3857 assert(seq && ev);
3858 len = snd_seq_event_length(ev);
3859 if (len < 0)
3860 return -EINVAL;
3861 if ((size_t) len >= seq->obufsize)
3862 return -EINVAL;
3863 if ((seq->obufsize - seq->obufused) < (size_t) len)
3864 return -EAGAIN;
3865 memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
3866 seq->obufused += sizeof(snd_seq_event_t);
3867 if (snd_seq_ev_is_variable(ev)) {
3868 memcpy(seq->obuf + seq->obufused, ev->data.ext.ptr, ev->data.ext.len);
3869 seq->obufused += ev->data.ext.len;
3871 return seq->obufused;
3875 * allocate the temporary buffer
3877 static int alloc_tmpbuf(snd_seq_t *seq, size_t len)
3879 size_t size = ((len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t));
3880 if (seq->tmpbuf == NULL) {
3881 if (size > DEFAULT_TMPBUF_SIZE)
3882 seq->tmpbufsize = size;
3883 else
3884 seq->tmpbufsize = DEFAULT_TMPBUF_SIZE;
3885 seq->tmpbuf = malloc(seq->tmpbufsize * sizeof(snd_seq_event_t));
3886 if (seq->tmpbuf == NULL)
3887 return -ENOMEM;
3888 } else if (len > seq->tmpbufsize) {
3889 seq->tmpbuf = realloc(seq->tmpbuf, size * sizeof(snd_seq_event_t));
3890 if (seq->tmpbuf == NULL)
3891 return -ENOMEM;
3892 seq->tmpbufsize = size;
3894 return 0;
3898 * \brief output an event directly to the sequencer NOT through output buffer
3899 * \param seq sequencer handle
3900 * \param ev event to be output
3901 * \return the byte size sent to sequencer or a negative error code
3903 * This function sends an event to the sequencer directly not through the
3904 * output buffer. When the event is a variable length event, a temporary
3905 * buffer is allocated inside alsa-lib and the data is copied there before
3906 * actually sent.
3908 * \sa snd_seq_event_output()
3910 int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
3912 ssize_t len;
3913 void *buf;
3915 len = snd_seq_event_length(ev);
3916 if (len < 0)
3917 return len;
3918 else if (len == sizeof(*ev)) {
3919 buf = ev;
3920 } else {
3921 if (alloc_tmpbuf(seq, (size_t)len) < 0)
3922 return -ENOMEM;
3923 *seq->tmpbuf = *ev;
3924 memcpy(seq->tmpbuf + 1, ev->data.ext.ptr, ev->data.ext.len);
3925 buf = seq->tmpbuf;
3927 return seq->ops->write(seq, buf, (size_t) len);
3931 * \brief return the size of pending events on output buffer
3932 * \param seq sequencer handle
3933 * \return the byte size of total of pending events
3935 * \sa snd_seq_event_output()
3937 int snd_seq_event_output_pending(snd_seq_t *seq)
3939 assert(seq);
3940 return seq->obufused;
3944 * \brief drain output buffer to sequencer
3945 * \param seq sequencer handle
3946 * \return 0 when all events are drained and sent to sequencer.
3947 * When events still remain on the buffer, the byte size of remaining
3948 * events are returned. On error a negative error code is returned.
3950 * This function drains all pending events on the output buffer.
3951 * The function returns immediately after the events are sent to the queues
3952 * regardless whether the events are processed or not.
3953 * To get synchronization with the all event processes, use
3954 * #snd_seq_sync_output_queue() after calling this function.
3956 * \sa snd_seq_event_output(), snd_seq_sync_output_queue()
3958 int snd_seq_drain_output(snd_seq_t *seq)
3960 ssize_t result, processed = 0;
3961 assert(seq);
3962 while (seq->obufused > 0) {
3963 result = seq->ops->write(seq, seq->obuf, seq->obufused);
3964 if (result < 0) {
3965 if (result == -EAGAIN && processed)
3966 return seq->obufused;
3967 return result;
3969 if ((size_t)result < seq->obufused)
3970 memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
3971 seq->obufused -= result;
3973 return 0;
3977 * \brief extract the first event in output buffer
3978 * \param seq sequencer handle
3979 * \param ev_res event pointer to be extracted
3980 * \return 0 on success otherwise a negative error code
3982 * Extracts the first event in output buffer.
3983 * If ev_res is NULL, just remove the event.
3985 * \sa snd_seq_event_output()
3987 int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
3989 size_t len, olen;
3990 snd_seq_event_t ev;
3991 assert(seq);
3992 if (ev_res)
3993 *ev_res = NULL;
3994 if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
3995 return -ENOENT;
3996 memcpy(&ev, seq->obuf, sizeof(snd_seq_event_t));
3997 len = snd_seq_event_length(&ev);
3998 if (ev_res) {
3999 /* extract the event */
4000 if (alloc_tmpbuf(seq, len) < 0)
4001 return -ENOMEM;
4002 memcpy(seq->tmpbuf, seq->obuf, len);
4003 *ev_res = seq->tmpbuf;
4005 seq->obufused = olen - len;
4006 memmove(seq->obuf, seq->obuf + len, seq->obufused);
4007 return 0;
4010 /*----------------------------------------------------------------*/
4013 * input from sequencer
4017 * read from sequencer to input buffer
4019 static ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
4021 ssize_t len;
4022 len = (seq->ops->read)(seq, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
4023 if (len < 0)
4024 return len;
4025 seq->ibuflen = len / sizeof(snd_seq_event_t);
4026 seq->ibufptr = 0;
4027 return seq->ibuflen;
4030 static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
4032 size_t ncells;
4033 snd_seq_event_t *ev;
4035 *retp = ev = &seq->ibuf[seq->ibufptr];
4036 seq->ibufptr++;
4037 seq->ibuflen--;
4038 if (! snd_seq_ev_is_variable(ev))
4039 return 1;
4040 ncells = (ev->data.ext.len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
4041 if (seq->ibuflen < ncells) {
4042 seq->ibuflen = 0; /* clear buffer */
4043 *retp = NULL;
4044 return -EINVAL;
4046 ev->data.ext.ptr = ev + 1;
4047 seq->ibuflen -= ncells;
4048 seq->ibufptr += ncells;
4049 return 1;
4053 * \brief retrieve an event from sequencer
4054 * \param seq sequencer handle
4055 * \param ev event pointer to be stored
4056 * \return
4058 * Obtains an input event from sequencer.
4059 * The event is created via snd_seq_create_event(), and its pointer is stored on
4060 * ev argument.
4062 * This function firstly receives the event byte-stream data from sequencer
4063 * as much as possible at once. Then it retrieves the first event record
4064 * and store the pointer on ev.
4065 * By calling this function sequentially, events are extracted from the input buffer.
4067 * If there is no input from sequencer, function falls into sleep
4068 * in blocking mode until an event is received,
4069 * or returns \c -EAGAIN error in non-blocking mode.
4070 * Occasionally, this function may return \c -ENOSPC error.
4071 * This means that the input FIFO of sequencer overran, and some events are
4072 * lost.
4073 * Once this error is returned, the input FIFO is cleared automatically.
4075 * Function returns the byte size of remaining events on the input buffer
4076 * if an event is successfully received.
4077 * Application can determine from the returned value whether to call
4078 * input once more or not.
4080 * \sa snd_seq_event_input_pending(), snd_seq_drop_input()
4082 int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
4084 int err;
4085 assert(seq);
4086 *ev = NULL;
4087 if (seq->ibuflen <= 0) {
4088 if ((err = snd_seq_event_read_buffer(seq)) < 0)
4089 return err;
4092 return snd_seq_event_retrieve_buffer(seq, ev);
4096 * read input data from sequencer if available
4098 static int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
4100 struct pollfd pfd;
4101 int err;
4102 pfd.fd = seq->poll_fd;
4103 pfd.events = POLLIN;
4104 err = poll(&pfd, 1, timeout);
4105 if (err < 0) {
4106 SYSERR("poll");
4107 return -errno;
4109 if (pfd.revents & POLLIN)
4110 return snd_seq_event_read_buffer(seq);
4111 return seq->ibuflen;
4115 * \brief check events in input buffer
4116 * \return the byte size of remaining input events on input buffer.
4118 * If events remain on the input buffer of user-space, function returns
4119 * the total byte size of events on it.
4120 * If fetch_sequencer argument is non-zero,
4121 * this function checks the presence of events on sequencer FIFO
4122 * When events exist, they are transferred to the input buffer,
4123 * and the number of received events are returned.
4124 * If fetch_sequencer argument is zero and
4125 * no events remain on the input buffer, function simply returns zero.
4127 * \sa snd_seq_event_input()
4129 int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
4131 if (seq->ibuflen == 0 && fetch_sequencer) {
4132 return snd_seq_event_input_feed(seq, 0);
4134 return seq->ibuflen;
4137 /*----------------------------------------------------------------*/
4140 * clear event buffers
4144 * \brief remove all events on user-space output buffer
4145 * \param seq sequencer handle
4147 * Removes all events on user-space output buffer.
4148 * Unlike snd_seq_drain_output(), this function doesn't remove
4149 * events on output memory pool of sequencer.
4151 * \sa snd_seq_drop_output()
4153 int snd_seq_drop_output_buffer(snd_seq_t *seq)
4155 assert(seq);
4156 seq->obufused = 0;
4157 return 0;
4161 * \brief remove all events on user-space input FIFO
4162 * \param seq sequencer handle
4164 * \sa snd_seq_drop_input()
4166 int snd_seq_drop_input_buffer(snd_seq_t *seq)
4168 assert(seq);
4169 seq->ibufptr = 0;
4170 seq->ibuflen = 0;
4171 return 0;
4175 * \brief remove all events on output buffer
4176 * \param seq sequencer handle
4178 * Removes all events on both user-space output buffer and
4179 * output memory pool on kernel.
4181 * \sa snd_seq_drain_output(), snd_seq_drop_output_buffer(), snd_seq_remove_events()
4183 int snd_seq_drop_output(snd_seq_t *seq)
4185 snd_seq_remove_events_t rminfo;
4186 assert(seq);
4188 memset(&rminfo, 0, sizeof(rminfo));
4189 rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;
4191 return snd_seq_remove_events(seq, &rminfo);
4195 * \brief clear input buffer and and remove events in sequencer queue
4196 * \param seq sequencer handle
4198 * \sa snd_seq_drop_input_buffer(), snd_seq_remove_events()
4200 int snd_seq_drop_input(snd_seq_t *seq)
4202 snd_seq_remove_events_t rminfo;
4203 assert(seq);
4205 memset(&rminfo, 0, sizeof(rminfo));
4206 rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;
4208 return snd_seq_remove_events(seq, &rminfo);
4213 * \brief get size of #snd_seq_remove_events_t
4214 * \return size in bytes
4216 size_t snd_seq_remove_events_sizeof()
4218 return sizeof(snd_seq_remove_events_t);
4222 * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
4223 * \param ptr returned pointer
4224 * \return 0 on success otherwise negative error code
4226 int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
4228 assert(ptr);
4229 *ptr = calloc(1, sizeof(snd_seq_remove_events_t));
4230 if (!*ptr)
4231 return -ENOMEM;
4232 return 0;
4236 * \brief frees a previously allocated #snd_seq_remove_events_t
4237 * \param obj pointer to object to free
4239 void snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
4241 free(obj);
4245 * \brief copy one #snd_seq_remove_events_t to another
4246 * \param dst pointer to destination
4247 * \param src pointer to source
4249 void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
4251 assert(dst && src);
4252 *dst = *src;
4257 * \brief Get the removal condition bits
4258 * \param info remove_events container
4259 * \return removal condition bits
4261 * \sa snd_seq_remove_events()
4263 unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
4265 assert(info);
4266 return info->remove_mode;
4270 * \brief Get the queue as removal condition
4271 * \param info remove_events container
4272 * \return queue id
4274 * \sa snd_seq_remove_events()
4276 int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
4278 assert(info);
4279 return info->queue;
4283 * \brief Get the event timestamp as removal condition
4284 * \param info remove_events container
4285 * \return time stamp
4287 * \sa snd_seq_remove_events()
4289 const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
4291 assert(info);
4292 return &info->time;
4296 * \brief Get the event destination address as removal condition
4297 * \param info remove_events container
4298 * \return destination address
4300 * \sa snd_seq_remove_events()
4302 const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
4304 assert(info);
4305 return &info->dest;
4309 * \brief Get the event channel as removal condition
4310 * \param info remove_events container
4311 * \return channel number
4313 * \sa snd_seq_remove_events()
4315 int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
4317 assert(info);
4318 return info->channel;
4322 * \brief Get the event type as removal condition
4323 * \param info remove_events container
4324 * \return event type
4326 * \sa snd_seq_remove_events()
4328 int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
4330 assert(info);
4331 return info->type;
4335 * \brief Get the event tag id as removal condition
4336 * \param info remove_events container
4337 * \return tag id
4339 * \sa snd_seq_remove_events()
4341 int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
4343 assert(info);
4344 return info->tag;
4348 * \brief Set the removal condition bits
4349 * \param info remove_events container
4350 * \param flags removal condition bits
4352 * \sa snd_seq_remove_events()
4354 void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
4356 assert(info);
4357 info->remove_mode = flags;
4361 * \brief Set the queue as removal condition
4362 * \param info remove_events container
4363 * \param queue queue id
4365 * \sa snd_seq_remove_events()
4367 void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
4369 assert(info);
4370 info->queue = queue;
4374 * \brief Set the timestamp as removal condition
4375 * \param info remove_events container
4376 * \param time timestamp pointer
4378 * \sa snd_seq_remove_events()
4380 void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
4382 assert(info);
4383 info->time = *time;
4387 * \brief Set the destination address as removal condition
4388 * \param info remove_events container
4389 * \param addr destination address
4391 * \sa snd_seq_remove_events()
4393 void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
4395 assert(info);
4396 info->dest = *addr;
4400 * \brief Set the channel as removal condition
4401 * \param info remove_events container
4402 * \param channel channel number
4404 * \sa snd_seq_remove_events()
4406 void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
4408 assert(info);
4409 info->channel = channel;
4413 * \brief Set the event type as removal condition
4414 * \param info remove_events container
4415 * \param type event type
4417 * \sa snd_seq_remove_events()
4419 void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
4421 assert(info);
4422 info->type = type;
4426 * \brief Set the event tag as removal condition
4427 * \param info remove_events container
4428 * \param tag tag id
4430 * \sa snd_seq_remove_events()
4432 void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
4434 assert(info);
4435 info->tag = tag;
4439 /* compare timestamp between events */
4440 /* return 1 if a >= b; otherwise return 0 */
4441 static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
4443 /* compare ticks */
4444 return (*a >= *b);
4447 static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
4449 /* compare real time */
4450 if (a->tv_sec > b->tv_sec)
4451 return 1;
4452 if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
4453 return 1;
4454 return 0;
4457 /* Routine to match events to be removed */
4458 static int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
4460 int res;
4462 if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
4463 if (ev->dest.client != info->dest.client ||
4464 ev->dest.port != info->dest.port)
4465 return 0;
4467 if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
4468 if (! snd_seq_ev_is_channel_type(ev))
4469 return 0;
4470 /* data.note.channel and data.control.channel are identical */
4471 if (ev->data.note.channel != info->channel)
4472 return 0;
4474 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
4475 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4476 res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4477 else
4478 res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
4479 if (!res)
4480 return 0;
4482 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
4483 if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
4484 res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
4485 else
4486 res = snd_seq_compare_real_time(&ev->time.time, &info->time.time);
4487 if (res)
4488 return 0;
4490 if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
4491 if (ev->type != info->type)
4492 return 0;
4494 if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
4495 /* Do not remove off events */
4496 switch (ev->type) {
4497 case SND_SEQ_EVENT_NOTEOFF:
4498 /* case SND_SEQ_EVENT_SAMPLE_STOP: */
4499 return 0;
4500 default:
4501 break;
4504 if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
4505 if (info->tag != ev->tag)
4506 return 0;
4509 return 1;
4513 * \brief remove events on input/output buffers and pools
4514 * \param seq sequencer handle
4515 * \param rmp remove event container
4517 * Removes matching events with the given condition from input/output buffers
4518 * and pools.
4519 * The removal condition is specified in \a rmp argument.
4521 * \sa snd_seq_event_output(), snd_seq_drop_output(), snd_seq_reset_pool_output()
4523 int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
4525 if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
4527 * First deal with any events that are still buffered
4528 * in the library.
4530 snd_seq_drop_input_buffer(seq);
4533 if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
4535 * First deal with any events that are still buffered
4536 * in the library.
4538 if (! (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT))) {
4539 /* The simple case - remove all */
4540 snd_seq_drop_output_buffer(seq);
4541 } else {
4542 char *ep;
4543 size_t len;
4544 snd_seq_event_t *ev;
4546 ep = seq->obuf;
4547 while (ep - seq->obuf < (ssize_t)seq->obufused) {
4549 ev = (snd_seq_event_t *)ep;
4550 len = snd_seq_event_length(ev);
4552 if (remove_match(rmp, ev)) {
4553 /* Remove event */
4554 seq->obufused -= len;
4555 memmove(ep, ep + len, seq->obufused - (ep - seq->obuf));
4556 } else {
4557 ep += len;
4563 return seq->ops->remove_events(seq, rmp);
4566 /*----------------------------------------------------------------*/
4569 * client memory pool
4573 * \brief get size of #snd_seq_client_pool_t
4574 * \return size in bytes
4576 size_t snd_seq_client_pool_sizeof()
4578 return sizeof(snd_seq_client_pool_t);
4582 * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
4583 * \param ptr returned pointer
4584 * \return 0 on success otherwise negative error code
4586 int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
4588 assert(ptr);
4589 *ptr = calloc(1, sizeof(snd_seq_client_pool_t));
4590 if (!*ptr)
4591 return -ENOMEM;
4592 return 0;
4596 * \brief frees a previously allocated #snd_seq_client_pool_t
4597 * \param obj pointer to object to free
4599 void snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
4601 free(obj);
4605 * \brief copy one #snd_seq_client_pool_t to another
4606 * \param dst pointer to destination
4607 * \param src pointer to source
4609 void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
4611 assert(dst && src);
4612 *dst = *src;
4617 * \brief Get the client id of a queue_info container
4618 * \param info client_pool container
4619 * \return client id
4621 int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
4623 assert(info);
4624 return info->client;
4628 * \brief Get the output pool size of a queue_info container
4629 * \param info client_pool container
4630 * \return output pool size
4632 size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
4634 assert(info);
4635 return info->output_pool;
4639 * \brief Get the input pool size of a queue_info container
4640 * \param info client_pool container
4641 * \return input pool size
4643 size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
4645 assert(info);
4646 return info->input_pool;
4650 * \brief Get the output room size of a queue_info container
4651 * \param info client_pool container
4652 * \return output room size
4654 size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
4656 assert(info);
4657 return info->output_room;
4661 * \brief Get the available size on output pool of a queue_info container
4662 * \param info client_pool container
4663 * \return available output size
4665 size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
4667 assert(info);
4668 return info->output_free;
4672 * \brief Get the available size on input pool of a queue_info container
4673 * \param info client_pool container
4674 * \return available input size
4676 size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
4678 assert(info);
4679 return info->input_free;
4683 * \brief Set the output pool size of a queue_info container
4684 * \param info client_pool container
4685 * \param size output pool size
4687 void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
4689 assert(info);
4690 info->output_pool = size;
4694 * \brief Set the input pool size of a queue_info container
4695 * \param info client_pool container
4696 * \param size input pool size
4698 void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
4700 assert(info);
4701 info->input_pool = size;
4705 * \brief Set the output room size of a queue_info container
4706 * \param info client_pool container
4707 * \param size output room size
4709 void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
4711 assert(info);
4712 info->output_room = size;
4717 * \brief obtain the pool information of the current client
4718 * \param seq sequencer handle
4719 * \param info information to be stored
4721 int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4723 assert(seq && info);
4724 info->client = seq->client;
4725 return seq->ops->get_client_pool(seq, info);
4729 * \brief set the pool information
4730 * \param seq sequencer handle
4731 * \param info information to update
4733 * Sets the pool information of the current client.
4734 * The client field in \a info is replaced automatically with the current id.
4736 int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
4738 assert(seq && info);
4739 info->client = seq->client;
4740 return seq->ops->set_client_pool(seq, info);
4743 /*----------------------------------------------------------------*/
4746 * misc.
4750 * \brief set a bit flag
4752 void snd_seq_set_bit(int nr, void *array)
4754 ((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
4758 * \brief unset a bit flag
4760 void snd_seq_unset_bit(int nr, void *array)
4762 ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
4766 * \brief change a bit flag
4768 int snd_seq_change_bit(int nr, void *array)
4770 int result;
4772 result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
4773 ((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
4774 return result;
4778 * \brief get a bit flag state
4780 int snd_seq_get_bit(int nr, void *array)
4782 return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;