Blame src/seq/seq.c

Packit 4a16fb
/**
Packit 4a16fb
 * \file seq/seq.c
Packit 4a16fb
 * \brief Sequencer Interface
Packit 4a16fb
 * \author Jaroslav Kysela <perex@perex.cz>
Packit 4a16fb
 * \author Abramo Bagnara <abramo@alsa-project.org>
Packit 4a16fb
 * \author Takashi Iwai <tiwai@suse.de>
Packit 4a16fb
 * \date 2000-2001
Packit 4a16fb
 *
Packit 4a16fb
 * See \ref seq page for more details.
Packit 4a16fb
 */
Packit 4a16fb
Packit 4a16fb
/* 
Packit 4a16fb
 *  Sequencer Interface - main file
Packit 4a16fb
 *
Packit 4a16fb
 *   This library is free software; you can redistribute it and/or modify
Packit 4a16fb
 *   it under the terms of the GNU Lesser General Public License as
Packit 4a16fb
 *   published by the Free Software Foundation; either version 2.1 of
Packit 4a16fb
 *   the License, or (at your option) any later version.
Packit 4a16fb
 *
Packit 4a16fb
 *   This program is distributed in the hope that it will be useful,
Packit 4a16fb
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 4a16fb
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 4a16fb
 *   GNU Lesser General Public License for more details.
Packit 4a16fb
 *
Packit 4a16fb
 *   You should have received a copy of the GNU Lesser General Public
Packit 4a16fb
 *   License along with this library; if not, write to the Free Software
Packit 4a16fb
 *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
Packit 4a16fb
 *
Packit 4a16fb
 */
Packit 4a16fb
Packit 4a16fb
/*! \page seq Sequencer interface
Packit 4a16fb
Packit 4a16fb
\section seq_general General
Packit 4a16fb
Packit 4a16fb
The ALSA sequencer interface is designed to deliver the MIDI-like
Packit 4a16fb
events between clients/ports.
Packit 4a16fb
A typical usage is the MIDI patch-bay.  A MIDI application can be
Packit 4a16fb
connected arbitrarily from/to the other MIDI clients.
Packit 4a16fb
The routing between clients can be changed dynamically, so the
Packit 4a16fb
application can handle incoming or outgoing MIDI events regardless of
Packit 4a16fb
the devices or the application connections.
Packit 4a16fb
Packit 4a16fb
The sequencer core stuff only takes care of two things:
Packit 4a16fb
scheduling events and dispatching them to the destination at the
Packit 4a16fb
right time.  All processing of MIDI events has to be done within the clients.
Packit 4a16fb
The event can be dispatched immediately without queueing, too.
Packit 4a16fb
The event scheduling can be done either on a MIDI tempo queue or
Packit 4a16fb
on a wallclock-time queue.
Packit 4a16fb
Packit 4a16fb
\section seq_client Client and Port
Packit 4a16fb
Packit 4a16fb
A client is created at each time #snd_seq_open() is called.
Packit 4a16fb
Later on, the attributes of client such as its name string can be changed
Packit 4a16fb
via #snd_seq_set_client_info().  There are helper functions for ease of use,
Packit 4a16fb
e.g. #snd_seq_set_client_name() and #snd_seq_set_client_event_filter().
Packit 4a16fb
A typical code would be like below:
Packit 4a16fb
\code
Packit 4a16fb
// create a new client
Packit 4a16fb
snd_seq_t *open_client()
Packit 4a16fb
{
Packit 4a16fb
        snd_seq_t *handle;
Packit 4a16fb
        int err;
Packit 4a16fb
        err = snd_seq_open(&handle, "default", SND_SEQ_OPEN_INPUT, 0);
Packit 4a16fb
        if (err < 0)
Packit 4a16fb
                return NULL;
Packit 4a16fb
        snd_seq_set_client_name(handle, "My Client");
Packit 4a16fb
	return handle;
Packit 4a16fb
}
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
You'll need to know the id number of the client eventually, for example,
Packit 4a16fb
when accessing to a certain port (see the section \ref seq_subs).
Packit 4a16fb
The client id can be obtained by #snd_seq_client_id() function.
Packit 4a16fb
Packit 4a16fb
A client can have one or more ports to communicate between other
Packit 4a16fb
clients.  A port is corresponding to the MIDI port in the case of MIDI device,
Packit 4a16fb
but in general it is nothing but the access point between other clients.
Packit 4a16fb
Each port may have capability flags, which specify the read/write
Packit 4a16fb
accessibility and subscription permissions of the port.
Packit 4a16fb
For creation of a port, call #snd_seq_create_port()
Packit 4a16fb
with the appropriate port attribute specified in #snd_seq_port_info_t
Packit 4a16fb
record.
Packit 4a16fb
Packit 4a16fb
For creating a port for the normal use, there is a helper function
Packit 4a16fb
#snd_seq_create_simple_port().  An example with this function is like below.
Packit 4a16fb
\code
Packit 4a16fb
// create a new port; return the port id
Packit 4a16fb
// port will be writable and accept the write-subscription.
Packit 4a16fb
int my_new_port(snd_seq_t *handle)
Packit 4a16fb
{
Packit 4a16fb
	return snd_seq_create_simple_port(handle, "my port",
Packit 4a16fb
			SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
Packit 4a16fb
			SND_SEQ_PORT_TYPE_MIDI_GENERIC);
Packit 4a16fb
}
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
\section seq_memory Memory Pool
Packit 4a16fb
Packit 4a16fb
Each client owns memory pools on kernel space
Packit 4a16fb
for each input and output events.
Packit 4a16fb
Here, input and output mean
Packit 4a16fb
input (read) from other clients and output (write) to others, respectively.
Packit 4a16fb
Since memory pool of each client is independent from others,
Packit 4a16fb
it avoids such a situation that a client eats the whole events pool
Packit 4a16fb
and interfere other clients' response.
Packit 4a16fb
Packit 4a16fb
The all scheduled output events or input events from dispatcher are stored
Packit 4a16fb
on these pools until delivered to other clients or extracted to user space.
Packit 4a16fb
The size of input/output pools can be changed independently.
Packit 4a16fb
The output pool has also a room size, which is used to wake up the
Packit 4a16fb
thread when it falls into sleep in blocking write mode.
Packit 4a16fb
Packit 4a16fb
Note that ports on the same client share the same memory pool.
Packit 4a16fb
If a port fills the memory pool, another can't use it any more.
Packit 4a16fb
For avoiding this, multiple clients can be used.
Packit 4a16fb
Packit 4a16fb
For chancing the pool size and the condition, access to #snd_seq_client_pool_t
Packit 4a16fb
record.  There are helper functions, #snd_seq_set_client_pool_output(),
Packit 4a16fb
#snd_seq_set_client_pool_output_room() and #snd_seq_set_client_pool_input(),
Packit 4a16fb
for setting the total output-pool size, the output-room size and the input-pool
Packit 4a16fb
size, respectively.
Packit 4a16fb
Packit 4a16fb
\section seq_subs Subscription
Packit 4a16fb
Packit 4a16fb
One of the new features in ALSA sequencer system is subscription of ports.
Packit 4a16fb
In general, subscription is a connection between two sequencer ports.
Packit 4a16fb
Even though an event can be delivered to a port without subscription
Packit 4a16fb
using an explicit destination address,
Packit 4a16fb
the subscription mechanism provides us more abstraction.
Packit 4a16fb
Packit 4a16fb
Suppose a MIDI input device which sends events from a keyboard.
Packit 4a16fb
The port associated with this device has READ capability - which means
Packit 4a16fb
this port is readable from other ports.
Packit 4a16fb
If a user program wants to capture events from keyboard and store them
Packit 4a16fb
as MIDI stream, this program must subscribe itself to the MIDI port
Packit 4a16fb
for read.
Packit 4a16fb
Then, a connection from MIDI input port to this program is established.
Packit 4a16fb
From this time, events from keyboard are automatically sent to this program.
Packit 4a16fb
Timestamps will be updated according to the subscribed queue.
Packit 4a16fb
\code
Packit 4a16fb
        MIDI input port (keyboard)
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        ALSA sequencer - update timestamp
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        application port
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
There is another subscription type for opposite direction:
Packit 4a16fb
Suppose a MIDI sequencer program which sends events to a MIDI output device.
Packit 4a16fb
In ALSA system, MIDI device is not opened until the associated MIDI port
Packit 4a16fb
is accessed.  Thus, in order to activate MIDI device, we have to subscribe
Packit 4a16fb
to MIDI port for write.
Packit 4a16fb
After this connection is established, events will be properly sent
Packit 4a16fb
to MIDI output device.
Packit 4a16fb
\code
Packit 4a16fb
        application port
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        ALSA sequencer - events are scheduled
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        MIDI output port (WaveTable etc.)
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
From the viewpoint of subscription, the examples above are special cases.
Packit 4a16fb
Basically, subscription means the connection between two arbitrary ports.
Packit 4a16fb
For example, imagine a filter application which modifies
Packit 4a16fb
the MIDI events like program, velocity or chorus effects.
Packit 4a16fb
This application can accept arbitrary MIDI input
Packit 4a16fb
and send to arbitrary port, just like a Unix pipe application using
Packit 4a16fb
stdin and stdout files.
Packit 4a16fb
We can even connect several filter applications which work individually
Packit 4a16fb
in order to process the MIDI events.
Packit 4a16fb
Subscription can be used for this purpose.
Packit 4a16fb
The connection between ports can be done also by the "third" client.
Packit 4a16fb
Thus, filter applications have to manage
Packit 4a16fb
only input and output events regardless of receiver/sender addresses.
Packit 4a16fb
\code
Packit 4a16fb
        sequencer port #1
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        ALSA sequencer (scheduled or real-time)
Packit 4a16fb
            |
Packit 4a16fb
            V
Packit 4a16fb
        sequencer port #2
Packit 4a16fb
\endcode
Packit 4a16fb
Packit 4a16fb
For the detail about subscription, see the section \ref seq_subs_more.
Packit 4a16fb
Packit 4a16fb
\section seq_events Sequencer Events
Packit 4a16fb
Packit 4a16fb
Messaging between clients is performed by sending events from one client to
Packit 4a16fb
another. These events contain high-level MIDI oriented messages or sequencer
Packit 4a16fb
specific messages.
Packit 4a16fb
Packit 4a16fb
All the sequencer events are stored in a sequencer event record,
Packit 4a16fb
#snd_seq_event_t type.
Packit 4a16fb
Application can send and receive these event records to/from other
Packit 4a16fb
clients via sequencer.
Packit 4a16fb
An event has several storage types according to its usage.
Packit 4a16fb
For example, a SYSEX message is stored on the variable length event,
Packit 4a16fb
and a large synth sample data is delivered using a user-space data pointer.
Packit 4a16fb
Packit 4a16fb
Packit 4a16fb
\subsection seq_ev_struct Structure of an event
Packit 4a16fb
Packit 4a16fb
An event consists of the following items:
Packit 4a16fb
    Packit 4a16fb
  • The type of the event
  • Packit 4a16fb
  • Event flags. It describes various conditions:
  • Packit 4a16fb
      
      Packit 4a16fb
        
    • time stamp; "real time" / "song ticks"
    • Packit 4a16fb
        
    • time mode; "absolute" / "relative to current time"
    • Packit 4a16fb
        
      Packit 4a16fb
    • Timestamp of the event.
    • Packit 4a16fb
    • Scheduling queue id.
    • Packit 4a16fb
    • Source address of the event, given by the combination
    • Packit 4a16fb
        of client id and port id numbers.
      Packit 4a16fb
    • Destination address of the event.
    • Packit 4a16fb
    • The actual event data. (up to 12 bytes)
    • Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      The actual record is shown in #snd_seq_event_t.
      Packit 4a16fb
      The type field contains the type of the event
      Packit 4a16fb
      (1 byte).
      Packit 4a16fb
      The flags field consists of bit flags which
      Packit 4a16fb
      describe several conditions of the event (1 byte).
      Packit 4a16fb
      It includes the time-stamp mode, data storage type, and scheduling priority.
      Packit 4a16fb
      The tag field is an arbitrary tag.
      Packit 4a16fb
      This tag can used for removing a distinct event from the event queue
      Packit 4a16fb
      via #snd_seq_remove_events().
      Packit 4a16fb
      The queue field is the queue id for scheduling.
      Packit 4a16fb
      The source and dest fields are source and destination addresses.
      Packit 4a16fb
      The data field is a union of event data.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_queue Scheduling queue
      Packit 4a16fb
      Packit 4a16fb
      An event can be delivered either on scheduled or direct dispatch mode.
      Packit 4a16fb
      On the scheduling mode, an event is once stored on the priority queue
      Packit 4a16fb
      and delivered later (or even immediately) to the destination,
      Packit 4a16fb
      whereas on the direct dispatch mode, an event is passed to the destination
      Packit 4a16fb
      without any queue.
      Packit 4a16fb
      Packit 4a16fb
      For a scheduled delivery, a queue to process the event must exist.
      Packit 4a16fb
      Usually, a client creates its own queue by
      Packit 4a16fb
      #snd_seq_alloc_queue() function.
      Packit 4a16fb
      Alternatively, a queue may be shared among several clients.
      Packit 4a16fb
      For scheduling an event on the specified queue,
      Packit 4a16fb
      a client needs to fill queue field
      Packit 4a16fb
      with the preferred queue id.
      Packit 4a16fb
      Packit 4a16fb
      Meanwhile, for dispatching an event directly, just
      Packit 4a16fb
      use #SND_SEQ_QUEUE_DIRECT as the target queue id.
      Packit 4a16fb
      A macro #snd_seq_ev_set_direct() is provided for ease
      Packit 4a16fb
      and compatibility.
      Packit 4a16fb
      Packit 4a16fb
      Note that scheduling at the current or earlier time is different
      Packit 4a16fb
      from the direct dispatch mode even though the event is delivered immediately.
      Packit 4a16fb
      On the former scheme, an event is once stored on priority queue, then
      Packit 4a16fb
      delivered actually.  Thus, it acquires a space from memory pool.
      Packit 4a16fb
      On the other hand, the latter is passed without using memory pool.
      Packit 4a16fb
      Although the direct dispatched event needs less memory, it means also
      Packit 4a16fb
      that the event cannot be resent if the destination is unable to receive it
      Packit 4a16fb
      momentarily.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_time Time stamp
      Packit 4a16fb
      Packit 4a16fb
      The timestamp of the event can either specified in
      Packit 4a16fb
      real time or in song ticks.
      Packit 4a16fb
      The former means the wallclock time while the latter corresponds to
      Packit 4a16fb
      the MIDI ticks.
      Packit 4a16fb
      Which format is used is determined by the event flags.
      Packit 4a16fb
      Packit 4a16fb
      The resolution of real-time value is in nano second.
      Packit 4a16fb
      Since 64 bit length is required for the actual time calculation,
      Packit 4a16fb
      it is represented by
      Packit 4a16fb
      a structure of pair of second and nano second
      Packit 4a16fb
      defined as #snd_seq_real_time_t type.
      Packit 4a16fb
      The song tick is defined simply as a 32 bit integer,
      Packit 4a16fb
      defined as #snd_seq_tick_time_t type.
      Packit 4a16fb
      The time stored in an event record is a union of these two different
      Packit 4a16fb
      time values.
      Packit 4a16fb
      Packit 4a16fb
      Note that the time format used for real time events is very similar to
      Packit 4a16fb
      timeval struct used for Unix system time.
      Packit 4a16fb
      The absurd resolution of the timestamps allows us to perform very accurate
      Packit 4a16fb
      conversions between songposition and real time. Round-off errors can be
      Packit 4a16fb
      neglected.
      Packit 4a16fb
      Packit 4a16fb
      If a timestamp with a
      Packit 4a16fb
      relative timestamp is delivered to ALSA, the
      Packit 4a16fb
      specified timestamp will be used as an offset to the current time of the
      Packit 4a16fb
      queue the event is sent into.
      Packit 4a16fb
      An absolute timestamp is on the contrary the time
      Packit 4a16fb
      counted from the moment when the queue started.
      Packit 4a16fb
      Packit 4a16fb
      An client that relies on these relative timestamps is the MIDI input port.
      Packit 4a16fb
      As each sequencer queue has it's own clock the only way to deliver events at
      Packit 4a16fb
      the right time is by using the relative timestamp format. When the event
      Packit 4a16fb
      arrives at the queue it is normalized to absolute format.
      Packit 4a16fb
      Packit 4a16fb
      The timestamp format is specified in the flag bitfield masked by
      Packit 4a16fb
      #SND_SEQ_TIME_STAMP_MASK.
      Packit 4a16fb
      To schedule the event in a real-time queue or in a tick queue,
      Packit 4a16fb
      macros #snd_seq_ev_schedule_real() and
      Packit 4a16fb
      #snd_seq_ev_schedule_tick() are provided, respectively.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_addr Source and destination addresses
      Packit 4a16fb
      Packit 4a16fb
      To identify the source and destination of an event, the addressing field
      Packit 4a16fb
      contains a combination of client id and port id numbers, defined as
      Packit 4a16fb
      #snd_seq_addr_t type.
      Packit 4a16fb
      When an event is passed to sequencer from a client, sequencer fills
      Packit 4a16fb
      source.client field
      Packit 4a16fb
      with the sender's id automatically.
      Packit 4a16fb
      It is the responsibility of sender client to 
      Packit 4a16fb
      fill the port id of source.port and
      Packit 4a16fb
      both client and port of dest field.
      Packit 4a16fb
      Packit 4a16fb
      If an existing address is set to the destination,
      Packit 4a16fb
      the event is simply delivered to it.
      Packit 4a16fb
      When #SND_SEQ_ADDRESS_SUBSCRIBERS is set to the destination client id,
      Packit 4a16fb
      the event is delivered to all the clients connected to the source port.
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      A sequencer core has two pre-defined system ports on the system client
      Packit 4a16fb
      #SND_SEQ_CLIENT_SYSTEM: #SND_SEQ_PORT_SYSTEM_TIMER and #SND_SEQ_PORT_SYSTEM_ANNOUNCE.
      Packit 4a16fb
      The #SND_SEQ_PORT_SYSTEM_TIMER is the system timer port,
      Packit 4a16fb
      and #SND_SEQ_PORT_SYSTEM_ANNOUNCE is the system
      Packit 4a16fb
      announce port.
      Packit 4a16fb
      In order to control a queue from a client, client should send a
      Packit 4a16fb
      queue-control event
      Packit 4a16fb
      like start, stop and continue queue, change tempo, etc.
      Packit 4a16fb
      to the system timer port.
      Packit 4a16fb
      Then the sequencer system handles the queue according to the received event.
      Packit 4a16fb
      This port supports subscription. The received timer events are 
      Packit 4a16fb
      broadcasted to all subscribed clients.
      Packit 4a16fb
      Packit 4a16fb
      The latter port does not receive messages but supports subscription.
      Packit 4a16fb
      When each client or port is attached, detached or modified,
      Packit 4a16fb
      an announcement is sent to subscribers from this port.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_data Data storage type
      Packit 4a16fb
      Packit 4a16fb
      Some events like SYSEX message, however, need larger data space
      Packit 4a16fb
      than the standard data.
      Packit 4a16fb
      For such events, ALSA sequencer provides several different data storage types.
      Packit 4a16fb
      The data type is specified in the flag bits masked by #SND_SEQ_EVENT_LENGTH_MASK.
      Packit 4a16fb
      The following data types are available:
      Packit 4a16fb
      Packit 4a16fb
      \par Fixed size data
      Packit 4a16fb
      Normal events stores their parameters on
      Packit 4a16fb
      data field (12 byte).
      Packit 4a16fb
      The flag-bit type is  #SND_SEQ_EVENT_LENGTH_FIXED.
      Packit 4a16fb
      A macro #snd_seq_ev_set_fixed() is provided to set this type.
      Packit 4a16fb
      Packit 4a16fb
      \par Variable length data
      Packit 4a16fb
      SYSEX or a returned error use this type.
      Packit 4a16fb
      The actual data is stored on an extra allocated space.
      Packit 4a16fb
      On sequencer kernel, the whole extra-data is duplicated, so that the event
      Packit 4a16fb
      can be scheduled on queue.
      Packit 4a16fb
      The data contains only the length and the
      Packit 4a16fb
      pointer of extra-data.
      Packit 4a16fb
      The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARIABLE.
      Packit 4a16fb
      A macro #snd_seq_ev_set_variable() is provided to set this type.
      Packit 4a16fb
      Packit 4a16fb
      \par User-space data
      Packit 4a16fb
      This type refers also an extra data space like variable length data,
      Packit 4a16fb
      but the extra-data is not duplicated but
      Packit 4a16fb
      but referred as a user-space data on kernel,
      Packit 4a16fb
      so that it reduces the time and resource for transferring
      Packit 4a16fb
      large bulk of data like synth sample wave.
      Packit 4a16fb
      This data type, however, can be used only for direct dispatch mode,
      Packit 4a16fb
      and supposed to be used only for a special purpose like a bulk data
      Packit 4a16fb
      transfer.
      Packit 4a16fb
      The data length and pointer are stored also in
      Packit 4a16fb
      data.ext field as well as variable length data.
      Packit 4a16fb
      The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARUSR.
      Packit 4a16fb
      A macro #snd_seq_ev_set_varusr() is provided to set this type.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_sched Scheduling priority
      Packit 4a16fb
      Packit 4a16fb
      There are two priorities for scheduling:
      Packit 4a16fb
      \par Normal priority
      Packit 4a16fb
      If an event with the same scheduling time is already present on the queue,
      Packit 4a16fb
      the new event is appended to the older.
      Packit 4a16fb
      \par High priority
      Packit 4a16fb
      If an event with the same scheduling time is already present on the queue,
      Packit 4a16fb
      the new event is inserted before others.
      Packit 4a16fb
      Packit 4a16fb
      The scheduling priority is set in the flag bitfeld masked by #SND_SEQ_PRIORITY_MASK.
      Packit 4a16fb
      A macro #snd_seq_ev_set_priority() is provided to set the mode type.
      Packit 4a16fb
      Packit 4a16fb
      \section seq_queue Event Queues
      Packit 4a16fb
      \subsection seq_ev_control Creation of a queue
      Packit 4a16fb
      Packit 4a16fb
      Creating a queue is done usually by calling #snd_seq_alloc_queue.
      Packit 4a16fb
      You can create a queue with a certain name by #snd_seq_alloc_named_queue(), too.
      Packit 4a16fb
      \code
      Packit 4a16fb
      // create a queue and return its id
      Packit 4a16fb
      int my_queue(snd_seq_t *handle)
      Packit 4a16fb
      {
      Packit 4a16fb
      	return snd_seq_alloc_named_queue(handle, "my queue");
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      These functions are the wrapper to the function #snd_seq_create_queue().
      Packit 4a16fb
      For releasing the allocated queue, call #snd_seq_free_queue() with the
      Packit 4a16fb
      obtained queue id.
      Packit 4a16fb
      Packit 4a16fb
      Once when a queue is created, the two queues are associated to that
      Packit 4a16fb
      queue record in fact: one is the realtime queue and another is the
      Packit 4a16fb
      tick queue.  These two queues are bound together to work
      Packit 4a16fb
      synchronously.  Hence, when you schedule an event, you have to choose
      Packit 4a16fb
      which queue type is used as described in the section \ref
      Packit 4a16fb
      seq_ev_time.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_tempo Setting queue tempo
      Packit 4a16fb
      Packit 4a16fb
      The tempo (or the speed) of the scheduling queue is variable.
      Packit 4a16fb
      In the case of tick queue, the tempo is controlled
      Packit 4a16fb
      in the manner of MIDI.  There are two parameters to define the
      Packit 4a16fb
      actual tempo, PPQ (pulse per quarter note) and MIDI tempo.
      Packit 4a16fb
      The former defines the base resolution of the ticks, while
      Packit 4a16fb
      the latter defines the beat tempo in microseconds.
      Packit 4a16fb
      As default, 96 PPQ and 120 BPM are used, respectively.
      Packit 4a16fb
      That is, the tempo is set to 500000 (= 60 * 1000000 / 120).
      Packit 4a16fb
      Note that PPQ cannot be changed while the queue is running.
      Packit 4a16fb
      It must be set before the queue is started.
      Packit 4a16fb
      Packit 4a16fb
      On the other hand, in the case of realtime queue, the
      Packit 4a16fb
      time resolution is fixed to nanoseconds.  There is, however,
      Packit 4a16fb
      a parameter to change the speed of this queue, called skew.
      Packit 4a16fb
      You can make the queue faster or slower by setting the skew value
      Packit 4a16fb
      bigger or smaller.  In the API, the skew is defined by two values,
      Packit 4a16fb
      the skew base and the skew value.  The actual skew is the fraction
      Packit 4a16fb
      of them, value/base.  As default, the skew base is set to 16bit
      Packit 4a16fb
      (0x10000) and the skew value is the identical, so that the queue is
      Packit 4a16fb
      processed as well as in the real world.
      Packit 4a16fb
      Packit 4a16fb
      When the tempo of realtime queue is changed, the tempo of
      Packit 4a16fb
      the associated tick queue is changed together, too.
      Packit 4a16fb
      That's the reason why two queues are created always.
      Packit 4a16fb
      This feature can be used to synchronize the event queue with
      Packit 4a16fb
      the external synchronization source like SMPTE.  In such a case,
      Packit 4a16fb
      the realtime queue is skewed to match with the external source,
      Packit 4a16fb
      so that both the realtime timestamp and the MIDI timestamp are
      Packit 4a16fb
      synchronized.
      Packit 4a16fb
      Packit 4a16fb
      For setting these tempo parameters, use #snd_seq_queue_tempo_t record.
      Packit 4a16fb
      For example, to set the tempo of the queue q to
      Packit 4a16fb
      48 PPQ, 60 BPM,
      Packit 4a16fb
      \code
      Packit 4a16fb
      void set_tempo(snd_seq_t *handle, int queue)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_queue_tempo_t *tempo;
      Packit 4a16fb
              snd_seq_queue_tempo_alloca(&tempo);
      Packit 4a16fb
              snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM
      Packit 4a16fb
              snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ
      Packit 4a16fb
              snd_seq_set_queue_tempo(handle, queue, tempo);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      For changing the (running) queue's tempo on the fly, you can either
      Packit 4a16fb
      set the tempo via #snd_seq_set_queue_tempo() or send a MIDI tempo event
      Packit 4a16fb
      to the system timer port.  For example,
      Packit 4a16fb
      \code
      Packit 4a16fb
      int change_tempo(snd_seq_t *handle, int q, unsigned int tempo)
      Packit 4a16fb
      {
      Packit 4a16fb
      	snd_seq_event_t ev;
      Packit 4a16fb
      	snd_seq_ev_clear(&ev;;
      Packit 4a16fb
      	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
      Packit 4a16fb
      	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
      Packit 4a16fb
      	ev.source.client = my_client_id;
      Packit 4a16fb
      	ev.source.port = my_port_id;
      Packit 4a16fb
      	ev.queue = SND_SEQ_QUEUE_DIRECT; // no scheduling
      Packit 4a16fb
      	ev.data.queue.queue = q;	// affected queue id
      Packit 4a16fb
      	ev.data.queue.value = tempo;	// new tempo in microsec.
      Packit 4a16fb
      	return snd_seq_event_output(handle, &ev;;
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      There is a helper function to do this easily,
      Packit 4a16fb
      #snd_seq_change_queue_tempo().
      Packit 4a16fb
      Set NULL to the last argument, if you don't need any
      Packit 4a16fb
      special settings.
      Packit 4a16fb
      Packit 4a16fb
      In the above example, the tempo is changed immediately after
      Packit 4a16fb
      the buffer is flushed by #snd_seq_drain_output() call.
      Packit 4a16fb
      You can schedule the event in a certain queue so that the tempo
      Packit 4a16fb
      change happens at the scheduled time, too.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ev_start Starting and stopping a queue
      Packit 4a16fb
      Packit 4a16fb
      To start, stop, or continue a queue, you need to send a queue-control
      Packit 4a16fb
      event to the system timer port as well.  There are helper functions,
      Packit 4a16fb
      #snd_seq_start_queue(), #snd_seq_stop_queue() and
      Packit 4a16fb
      #snd_seq_continue_queue().
      Packit 4a16fb
      Note that if the last argument of these functions is NULL, the
      Packit 4a16fb
      event is sent (i.e. operated) immediately after the buffer flush.
      Packit 4a16fb
      If you want to schedule the event at the certain time, set up
      Packit 4a16fb
      the event record and provide the pointer of that event record as the
      Packit 4a16fb
      argument.
      Packit 4a16fb
      Packit 4a16fb
      Only calling these functions doesn't deliver the event to the
      Packit 4a16fb
      sequencer core but only put to the output buffer.  You'll need to
      Packit 4a16fb
      call #snd_seq_drain_output() eventually.
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      \section seq_subs_more More inside the subscription
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_subs_perm Permissions
      Packit 4a16fb
      Packit 4a16fb
      Each ALSA port can have capability flags.
      Packit 4a16fb
      The most basic capability flags are
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE.
      Packit 4a16fb
      The former means that the port allows to send events to other ports,
      Packit 4a16fb
      whereas the latter capability means
      Packit 4a16fb
      that the port allows to receive events from other ports.
      Packit 4a16fb
      You may have noticed that meanings of \c READ and \c WRITE
      Packit 4a16fb
      are permissions of the port from the viewpoint of other ports.
      Packit 4a16fb
      Packit 4a16fb
      For allowing subscription from/to other clients, another capability
      Packit 4a16fb
      flags must be set together with read/write capabilities above.
      Packit 4a16fb
      For allowing read and write subscriptions,
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_READ and
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_WRITE are used,
      Packit 4a16fb
      respectively.
      Packit 4a16fb
      For example, the port with MIDI input device always has
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_READ capability,
      Packit 4a16fb
      and the port with MIDI output device always has
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_WRITE capability together with
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE capabilities,
      Packit 4a16fb
      respectively.
      Packit 4a16fb
      Obviously, these flags have no influence
      Packit 4a16fb
      if \c READ or \c WRITE> capability is not set.
      Packit 4a16fb
      Packit 4a16fb
      Note that these flags are not necessary if the client subscribes itself
      Packit 4a16fb
      to the specified port.
      Packit 4a16fb
      For example, when a port makes READ subscription
      Packit 4a16fb
      to MIDI input port, this port must have #SND_SEQ_PORT_CAP_WRITE capability,
      Packit 4a16fb
      but no #SND_SEQ_PORT_CAP_SUBS_WRITE capability is required.
      Packit 4a16fb
      Only MIDI input port must have #SND_SEQ_PORT_CAP_SUBS_READ capability.
      Packit 4a16fb
      Packit 4a16fb
      As default, the connection of ports via the third client is always allowed
      Packit 4a16fb
      if proper read and write (subscription) capabilities are set both to the
      Packit 4a16fb
      source and destination ports.
      Packit 4a16fb
      For prohibiting this behavior, set a capability
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_NO_EXPORT to the port.
      Packit 4a16fb
      If this flag is set, subscription must be done by sender or receiver
      Packit 4a16fb
      client itself.
      Packit 4a16fb
      It is useful to avoid unexpected disconnection.
      Packit 4a16fb
      The ports which won't accept subscription should have this capability
      Packit 4a16fb
      for better security.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_subs_handle Subscription handlers
      Packit 4a16fb
      Packit 4a16fb
      In ALSA library, subscription is done via
      Packit 4a16fb
      #snd_seq_subscribe_port() function.
      Packit 4a16fb
      It takes the argument of #snd_seq_port_subscribe_t record pointer.
      Packit 4a16fb
      Suppose that you have a client which will receive data from
      Packit 4a16fb
      a MIDI input device.  The source and destination addresses
      Packit 4a16fb
      are like the below;
      Packit 4a16fb
      \code
      Packit 4a16fb
      snd_seq_addr_t sender, dest;
      Packit 4a16fb
      sender.client = MIDI_input_client;
      Packit 4a16fb
      sender.port = MIDI_input_port;
      Packit 4a16fb
      dest.client = my_client;
      Packit 4a16fb
      dest.port = my_port;
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      To set these values as the connection call like this.
      Packit 4a16fb
      \code
      Packit 4a16fb
      snd_seq_port_subscribe_t *subs;
      Packit 4a16fb
      snd_seq_port_subscribe_alloca(&subs);
      Packit 4a16fb
      snd_seq_port_subscribe_set_sender(subs, &sender);
      Packit 4a16fb
      snd_seq_port_subscribe_set_dest(subs, &dest);
      Packit 4a16fb
      snd_seq_subscribe_port(handle, subs);
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      When the connection should be exclusively done only between
      Packit 4a16fb
      a certain pair, set exclusive attribute to the subscription
      Packit 4a16fb
      record before calling #snd_seq_subscribe_port.
      Packit 4a16fb
      \code
      Packit 4a16fb
      snd_seq_port_subscribe_set_exclusive(subs, 1);
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      The succeeding subscriptions will be refused.
      Packit 4a16fb
      Packit 4a16fb
      The timestamp can be updated independently on each connection.
      Packit 4a16fb
      When set up, the timestamp of incoming queue to the destination port
      Packit 4a16fb
      is updated automatically to the time of the specified queue.
      Packit 4a16fb
      \code
      Packit 4a16fb
      snd_seq_port_subscribe_set_time_update(subs, 1);
      Packit 4a16fb
      snd_seq_port_subscribe_set_queue(subs, q);
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      For getting the wallclock time (sec/nsec pair), set real attribute:
      Packit 4a16fb
      \code
      Packit 4a16fb
      snd_seq_port_subscribe_set_time_real(subs, 1);
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Otherwise, the timestamp is stored in tick unit.
      Packit 4a16fb
      This feature is useful when receiving events from MIDI input device.
      Packit 4a16fb
      The event time is automatically set in the event record.
      Packit 4a16fb
      Packit 4a16fb
      Note that an outsider client may connect other ports.
      Packit 4a16fb
      In this case, however, the subscription may be refused
      Packit 4a16fb
      if #SND_SEQ_PORT_CAP_NO_EXPORT capability is set in either sender or receiver port.
      Packit 4a16fb
      Packit 4a16fb
      \section seq_subs_ex Examples of subscription
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_subs_ex_capt Capture from keyboard
      Packit 4a16fb
      Packit 4a16fb
      Assume MIDI input port = 64:0, application port = 128:0, and
      Packit 4a16fb
      queue for timestamp = 1 with real-time stamp.
      Packit 4a16fb
      The application port must have capability #SND_SEQ_PORT_CAP_WRITE.
      Packit 4a16fb
      \code
      Packit 4a16fb
      void capture_keyboard(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_addr_t sender, dest;
      Packit 4a16fb
              snd_seq_port_subscribe_t *subs;
      Packit 4a16fb
              sender.client = 64;
      Packit 4a16fb
              sender.port = 0;
      Packit 4a16fb
              dest.client = 128;
      Packit 4a16fb
              dest.port = 0;
      Packit 4a16fb
              snd_seq_port_subscribe_alloca(&subs);
      Packit 4a16fb
              snd_seq_port_subscribe_set_sender(subs, &sender);
      Packit 4a16fb
              snd_seq_port_subscribe_set_dest(subs, &dest);
      Packit 4a16fb
              snd_seq_port_subscribe_set_queue(subs, 1);
      Packit 4a16fb
              snd_seq_port_subscribe_set_time_update(subs, 1);
      Packit 4a16fb
              snd_seq_port_subscribe_set_time_real(subs, 1);
      Packit 4a16fb
              snd_seq_subscribe_port(seq, subs);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_subs_ex_out Output to MIDI device
      Packit 4a16fb
      Packit 4a16fb
      Assume MIDI output port = 65:1 and application port = 128:0.
      Packit 4a16fb
      The application port must have capability #SND_SEQ_PORT_CAP_READ.
      Packit 4a16fb
      \code
      Packit 4a16fb
      void subscribe_output(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_addr_t sender, dest;
      Packit 4a16fb
              snd_seq_port_subscribe_t *subs;
      Packit 4a16fb
              sender.client = 128;
      Packit 4a16fb
              sender.port = 0;
      Packit 4a16fb
              dest.client = 65;
      Packit 4a16fb
              dest.port = 1;
      Packit 4a16fb
              snd_seq_port_subscribe_alloca(&subs);
      Packit 4a16fb
              snd_seq_port_subscribe_set_sender(subs, &sender);
      Packit 4a16fb
              snd_seq_port_subscribe_set_dest(subs, &dest);
      Packit 4a16fb
              snd_seq_subscribe_port(seq, subs);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      This example can be simplified by using #snd_seq_connect_to() function.
      Packit 4a16fb
      \code
      Packit 4a16fb
      void subscribe_output(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_connect_to(seq, 0, 65, 1);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_subs_ex_arbit Arbitrary connection
      Packit 4a16fb
      Packit 4a16fb
      Assume connection from application 128:0 to 129:0,
      Packit 4a16fb
      and that subscription is done by the third application (130:0).
      Packit 4a16fb
      The sender must have capabilities both
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_READ and
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_READ,
      Packit 4a16fb
      and the receiver
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_WRITE and
      Packit 4a16fb
      #SND_SEQ_PORT_CAP_SUBS_WRITE, respectively.
      Packit 4a16fb
      \code
      Packit 4a16fb
      // ..in the third application (130:0) ..
      Packit 4a16fb
      void coupling(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_addr_t sender, dest;
      Packit 4a16fb
              snd_seq_port_subscribe_t *subs;
      Packit 4a16fb
              sender.client = 128;
      Packit 4a16fb
              sender.port = 0;
      Packit 4a16fb
              dest.client = 129;
      Packit 4a16fb
              dest.port = 0;
      Packit 4a16fb
              snd_seq_port_subscribe_alloca(&subs);
      Packit 4a16fb
              snd_seq_port_subscribe_set_sender(subs, &sender);
      Packit 4a16fb
              snd_seq_port_subscribe_set_dest(subs, &dest);
      Packit 4a16fb
              snd_seq_subscribe_port(seq, subs);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      \section seq_ex_event Event Processing
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ex_address Addressing
      Packit 4a16fb
      Packit 4a16fb
      Now, two ports are connected by subscription.  Then how to send events?
      Packit 4a16fb
      Packit 4a16fb
      The subscribed port doesn't have to know the exact sender address.
      Packit 4a16fb
      Instead, there is a special address for subscribers,
      Packit 4a16fb
      #SND_SEQ_ADDRESS_SUBSCRIBERS.
      Packit 4a16fb
      The sender must set this value as the destination client.
      Packit 4a16fb
      Destination port is ignored.
      Packit 4a16fb
      Packit 4a16fb
      The other values in source and destination addresses are identical with
      Packit 4a16fb
      the normal event record.
      Packit 4a16fb
      If the event is scheduled, proper queue and timestamp values must be set.
      Packit 4a16fb
      Packit 4a16fb
      There is a convenient function to set the address in an event record.
      Packit 4a16fb
      In order to set destination as subscribers, use
      Packit 4a16fb
      #snd_seq_ev_set_subs().
      Packit 4a16fb
      Packit 4a16fb
      \subsection Scheduled Delivery
      Packit 4a16fb
      Packit 4a16fb
      If we send an event at the scheduled time t (tick)
      Packit 4a16fb
      on the queue Q,
      Packit 4a16fb
      the sender must set both schedule queue and time in the
      Packit 4a16fb
      event record.
      Packit 4a16fb
      The program appears like this:
      Packit 4a16fb
      \code
      Packit 4a16fb
      void schedule_event(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_event_t ev;
      Packit 4a16fb
      Packit 4a16fb
              snd_seq_ev_clear(&ev;;
      Packit 4a16fb
              snd_seq_ev_set_source(&ev, my_port);
      Packit 4a16fb
              snd_seq_ev_set_subs(&ev;;
      Packit 4a16fb
              snd_seq_ev_schedule_tick(&ev, Q, 0, t);
      Packit 4a16fb
              ... // set event type, data, so on..
      Packit 4a16fb
      Packit 4a16fb
              snd_seq_event_output(seq, &ev;;
      Packit 4a16fb
              ...
      Packit 4a16fb
              snd_seq_drain_output(seq);  // if necessary
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Of course, you can use realtime stamp, too.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ex_direct Direct Delivery
      Packit 4a16fb
      Packit 4a16fb
      If the event is sent immediately without enqueued, the sender doesn't take
      Packit 4a16fb
      care of queue and timestamp.
      Packit 4a16fb
      As well as the case above, there is a function to set the direct delivery,
      Packit 4a16fb
      #snd_seq_ev_set_direct().
      Packit 4a16fb
      The program can be more simplified as follows:
      Packit 4a16fb
      \code
      Packit 4a16fb
      void direct_delivery(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
              snd_seq_event_t ev;
      Packit 4a16fb
      Packit 4a16fb
              snd_seq_ev_clear(&ev;;
      Packit 4a16fb
              snd_seq_ev_set_source(&ev, port);
      Packit 4a16fb
              snd_seq_ev_set_subs(&ev;;
      Packit 4a16fb
              snd_seq_ev_set_direct(&ev;;
      Packit 4a16fb
              ... // set event type, data, so on..
      Packit 4a16fb
      Packit 4a16fb
              snd_seq_event_output(seq, &ev;;
      Packit 4a16fb
              snd_seq_drain_output(seq);
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      You should flush event soon after output event.
      Packit 4a16fb
      Otherwise, the event is enqueued on output queue of ALSA library
      Packit 4a16fb
      (not in the kernel!), and will be never processed until
      Packit 4a16fb
      this queue becomes full.
      Packit 4a16fb
      Packit 4a16fb
      \subsection seq_ex_filter Filter Application
      Packit 4a16fb
      Packit 4a16fb
      A typical filter program, which receives an event and sends it immediately
      Packit 4a16fb
      after some modification, will appear as following:
      Packit 4a16fb
      \code
      Packit 4a16fb
      void event_filter(snd_seq_t *seq, snd_seq_event_t *ev)
      Packit 4a16fb
      {
      Packit 4a16fb
              while (snd_seq_event_input(seq, &ev) >= 0) {
      Packit 4a16fb
                      //.. modify input event ..
      Packit 4a16fb
      Packit 4a16fb
                      snd_seq_ev_set_source(ev, my_port);
      Packit 4a16fb
                      snd_seq_ev_set_subs(ev);
      Packit 4a16fb
                      snd_seq_ev_set_direct(ev);
      Packit 4a16fb
                      snd_seq_event_output(seq, ev);
      Packit 4a16fb
                      snd_seq_drain_output(seq);
      Packit 4a16fb
              }
      Packit 4a16fb
      }
      Packit 4a16fb
      \endcode
      Packit 4a16fb
      Packit 4a16fb
      */
      Packit 4a16fb
      Packit 4a16fb
      #include <poll.h>
      Packit 4a16fb
      #include "seq_local.h"
      Packit 4a16fb
      Packit 4a16fb
      /****************************************************************************
      Packit 4a16fb
       *                                                                          *
      Packit 4a16fb
       *                                seq.h                                     *
      Packit 4a16fb
       *                              Sequencer                                   *
      Packit 4a16fb
       *                                                                          *
      Packit 4a16fb
       ****************************************************************************/
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get identifier of sequencer handle
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return ASCII identifier of sequencer handle
      Packit 4a16fb
       *
      Packit 4a16fb
       * Returns the ASCII identifier of the given sequencer handle. It's the same
      Packit 4a16fb
       * identifier specified in snd_seq_open().
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open()
      Packit 4a16fb
       */
      Packit 4a16fb
      const char *snd_seq_name(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	return seq->name;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get type of sequencer handle
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return type of sequencer handle
      Packit 4a16fb
       *
      Packit 4a16fb
       * Returns the type #snd_seq_type_t of the given sequencer handle.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open()
      Packit 4a16fb
       */
      Packit 4a16fb
      snd_seq_type_t snd_seq_type(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	return seq->type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
      Packit 4a16fb
      			     snd_config_t *seq_root, snd_config_t *seq_conf,
      Packit 4a16fb
      			     int streams, int mode)
      Packit 4a16fb
      {
      Packit 4a16fb
      	const char *str;
      Packit 4a16fb
      	char buf[256], errbuf[256];
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	snd_config_t *conf, *type_conf = NULL;
      Packit 4a16fb
      	snd_config_iterator_t i, next;
      Packit 4a16fb
      	const char *id;
      Packit 4a16fb
      	const char *lib = NULL, *open_name = NULL;
      Packit 4a16fb
      	int (*open_func)(snd_seq_t **, const char *,
      Packit 4a16fb
      			 snd_config_t *, snd_config_t *, 
      Packit 4a16fb
      			 int, int) = NULL;
      Packit 4a16fb
      #ifndef PIC
      Packit 4a16fb
      	extern void *snd_seq_open_symbols(void);
      Packit 4a16fb
      #endif
      Packit 4a16fb
      	void *h = NULL;
      Packit 4a16fb
      	if (snd_config_get_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
      Packit 4a16fb
      		if (name)
      Packit 4a16fb
      			SNDERR("Invalid type for SEQ %s definition", name);
      Packit 4a16fb
      		else
      Packit 4a16fb
      			SNDERR("Invalid type for SEQ definition");
      Packit 4a16fb
      		return -EINVAL;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	err = snd_config_search(seq_conf, "type", &conf;;
      Packit 4a16fb
      	if (err < 0) {
      Packit 4a16fb
      		SNDERR("type is not defined");
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	err = snd_config_get_id(conf, &id;;
      Packit 4a16fb
      	if (err < 0) {
      Packit 4a16fb
      		SNDERR("unable to get id");
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	err = snd_config_get_string(conf, &str);
      Packit 4a16fb
      	if (err < 0) {
      Packit 4a16fb
      		SNDERR("Invalid type for %s", id);
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	err = snd_config_search_definition(seq_root, "seq_type", str, &type_conf);
      Packit 4a16fb
      	if (err >= 0) {
      Packit 4a16fb
      		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
      Packit 4a16fb
      			SNDERR("Invalid type for SEQ type %s definition", str);
      Packit 4a16fb
      			goto _err;
      Packit 4a16fb
      		}
      Packit 4a16fb
      		snd_config_for_each(i, next, type_conf) {
      Packit 4a16fb
      			snd_config_t *n = snd_config_iterator_entry(i);
      Packit 4a16fb
      			const char *id;
      Packit 4a16fb
      			if (snd_config_get_id(n, &id) < 0)
      Packit 4a16fb
      				continue;
      Packit 4a16fb
      			if (strcmp(id, "comment") == 0)
      Packit 4a16fb
      				continue;
      Packit 4a16fb
      			if (strcmp(id, "lib") == 0) {
      Packit 4a16fb
      				err = snd_config_get_string(n, &lib);
      Packit 4a16fb
      				if (err < 0) {
      Packit 4a16fb
      					SNDERR("Invalid type for %s", id);
      Packit 4a16fb
      					goto _err;
      Packit 4a16fb
      				}
      Packit 4a16fb
      				continue;
      Packit 4a16fb
      			}
      Packit 4a16fb
      			if (strcmp(id, "open") == 0) {
      Packit 4a16fb
      				err = snd_config_get_string(n, &open_name);
      Packit 4a16fb
      				if (err < 0) {
      Packit 4a16fb
      					SNDERR("Invalid type for %s", id);
      Packit 4a16fb
      					goto _err;
      Packit 4a16fb
      				}
      Packit 4a16fb
      				continue;
      Packit 4a16fb
      			}
      Packit 4a16fb
      			SNDERR("Unknown field %s", id);
      Packit 4a16fb
      			err = -EINVAL;
      Packit 4a16fb
      			goto _err;
      Packit 4a16fb
      		}
      Packit 4a16fb
      	}
      Packit 4a16fb
      	if (!open_name) {
      Packit 4a16fb
      		open_name = buf;
      Packit 4a16fb
      		snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
      Packit 4a16fb
      	}
      Packit 4a16fb
      #ifndef PIC
      Packit 4a16fb
      	snd_seq_open_symbols();
      Packit 4a16fb
      #endif
      Packit 4a16fb
      	h = INTERNAL(snd_dlopen)(lib, RTLD_NOW, errbuf, sizeof(errbuf));
      Packit 4a16fb
      	if (h)
      Packit 4a16fb
      		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_SEQ_DLSYM_VERSION));
      Packit 4a16fb
      	err = 0;
      Packit 4a16fb
      	if (!h) {
      Packit 4a16fb
      		SNDERR("Cannot open shared library %s (%s)", lib, errbuf);
      Packit 4a16fb
      		err = -ENOENT;
      Packit 4a16fb
      	} else if (!open_func) {
      Packit 4a16fb
      		SNDERR("symbol %s is not defined inside %s", open_name, lib);
      Packit 4a16fb
      		snd_dlclose(h);
      Packit 4a16fb
      		err = -ENXIO;
      Packit 4a16fb
      	}
      Packit 4a16fb
             _err:
      Packit 4a16fb
      	if (type_conf)
      Packit 4a16fb
      		snd_config_delete(type_conf);
      Packit 4a16fb
      	if (! err) {
      Packit 4a16fb
      		err = open_func(seqp, name, seq_root, seq_conf, streams, mode);
      Packit 4a16fb
      		if (err < 0)
      Packit 4a16fb
      			snd_dlclose(h);
      Packit 4a16fb
      		else
      Packit 4a16fb
      			(*seqp)->dl_handle = h;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	return err;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
      Packit 4a16fb
      				 const char *name, int streams, int mode,
      Packit 4a16fb
      				 int hop)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	snd_config_t *seq_conf;
      Packit 4a16fb
      	err = snd_config_search_definition(root, "seq", name, &seq_conf);
      Packit 4a16fb
      	if (err < 0) {
      Packit 4a16fb
      		SNDERR("Unknown SEQ %s", name);
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	snd_config_set_hop(seq_conf, hop);
      Packit 4a16fb
      	err = snd_seq_open_conf(seqp, name, root, seq_conf, streams, mode);
      Packit 4a16fb
      	snd_config_delete(seq_conf);
      Packit 4a16fb
      	return err;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Open the ALSA sequencer
      Packit 4a16fb
       *
      Packit 4a16fb
       * \param seqp Pointer to a snd_seq_t pointer.  This pointer must be
      Packit 4a16fb
       * kept and passed to most of the other sequencer functions.
      Packit 4a16fb
       * \param name The sequencer's "name".  This is \em not a name you make
      Packit 4a16fb
       * up for your own purposes; it has special significance to the ALSA
      Packit 4a16fb
       * library.  Usually you need to pass \c "default" here.
      Packit 4a16fb
       * \param streams The read/write mode of the sequencer.  Can be one of
      Packit 4a16fb
       * three values:
      Packit 4a16fb
       * - #SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
      Packit 4a16fb
       * - #SND_SEQ_OPEN_INPUT - open the sequencer for input only
      Packit 4a16fb
       * - #SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
      Packit 4a16fb
       * \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
      Packit 4a16fb
       * \c O_RDWR respectively and used as the second argument to the C library
      Packit 4a16fb
       * open() call.
      Packit 4a16fb
       * \param mode Optional modifier.  Can be either 0, or
      Packit 4a16fb
       * #SND_SEQ_NONBLOCK, which will make read/write operations
      Packit 4a16fb
       * non-blocking.  This can also be set later using #snd_seq_nonblock().
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Creates a new handle and opens a connection to the kernel
      Packit 4a16fb
       * sequencer interface.
      Packit 4a16fb
       * After a client is created successfully, an event
      Packit 4a16fb
       * with #SND_SEQ_EVENT_CLIENT_START is broadcast to announce port.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open_lconf(), snd_seq_close(), snd_seq_type(), snd_seq_name(),
      Packit 4a16fb
       *     snd_seq_nonblock(), snd_seq_client_id()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_open(snd_seq_t **seqp, const char *name, 
      Packit 4a16fb
      		 int streams, int mode)
      Packit 4a16fb
      {
      Packit 4a16fb
      	snd_config_t *top;
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      Packit 4a16fb
      	assert(seqp && name);
      Packit 4a16fb
      	err = snd_config_update_ref(&top);
      Packit 4a16fb
      	if (err < 0)
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
      Packit 4a16fb
      	snd_config_unref(top);
      Packit 4a16fb
      	return err;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Open the ALSA sequencer using local configuration
      Packit 4a16fb
       *
      Packit 4a16fb
       * \param seqp Pointer to a snd_seq_t pointer.
      Packit 4a16fb
       * \param name The name to open
      Packit 4a16fb
       * \param streams The read/write mode of the sequencer.
      Packit 4a16fb
       * \param mode Optional modifier
      Packit 4a16fb
       * \param lconf Local configuration
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * See the snd_seq_open() function for further details. The extension
      Packit 4a16fb
       * is that the given configuration is used to resolve abstract name.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_open_lconf(snd_seq_t **seqp, const char *name, 
      Packit 4a16fb
      		       int streams, int mode, snd_config_t *lconf)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seqp && name && lconf);
      Packit 4a16fb
      	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      #ifndef DOC_HIDDEN
      Packit 4a16fb
      int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name, 
      Packit 4a16fb
      			int streams, int mode, snd_config_t *lconf,
      Packit 4a16fb
      			snd_config_t *parent_conf)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int hop;
      Packit 4a16fb
      	assert(seqp && name && lconf);
      Packit 4a16fb
      	if ((hop = snd_config_check_hop(parent_conf)) < 0)
      Packit 4a16fb
      		return hop;
      Packit 4a16fb
      	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
      Packit 4a16fb
      }
      Packit 4a16fb
      #endif
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Close the sequencer
      Packit 4a16fb
       * \param seq Handle returned from #snd_seq_open()
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Closes the sequencer client and releases its resources.
      Packit 4a16fb
       * After a client is closed, an event with
      Packit 4a16fb
       * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
      Packit 4a16fb
       * The connection between other clients are disconnected.
      Packit 4a16fb
       * Call this just before exiting your program.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_close()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_close(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	err = seq->ops->close(seq);
      Packit 4a16fb
      	if (seq->dl_handle)
      Packit 4a16fb
      		snd_dlclose(seq->dl_handle);
      Packit 4a16fb
      	free(seq->obuf);
      Packit 4a16fb
      	free(seq->ibuf);
      Packit 4a16fb
      	free(seq->tmpbuf);
      Packit 4a16fb
      	free(seq->name);
      Packit 4a16fb
      	free(seq);
      Packit 4a16fb
      	return err;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Returns the number of poll descriptors
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
      Packit 4a16fb
       * \return the number of poll descriptors.
      Packit 4a16fb
       *
      Packit 4a16fb
       * Get the number of poll descriptors.  The polling events to be checked
      Packit 4a16fb
       * can be specified by the second argument.  When both input and output
      Packit 4a16fb
       * are checked, pass \c POLLIN|POLLOUT
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_poll_descriptors()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int result = 0;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	if (events & POLLIN) {
      Packit 4a16fb
      		assert(seq->streams & SND_SEQ_OPEN_INPUT);
      Packit 4a16fb
      		result++;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	if (events & POLLOUT) {
      Packit 4a16fb
      		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
      Packit 4a16fb
      		result++;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	return result ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get poll descriptors
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param pfds array of poll descriptors
      Packit 4a16fb
       * \param space space in the poll descriptor array
      Packit 4a16fb
       * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
      Packit 4a16fb
       * \return count of filled descriptors
      Packit 4a16fb
       *
      Packit 4a16fb
       * Get poll descriptors assigned to the sequencer handle.
      Packit 4a16fb
       * Since a sequencer handle can duplex streams, you need to set which direction(s)
      Packit 4a16fb
       * is/are polled in \a events argument.  When \c POLLIN bit is specified,
      Packit 4a16fb
       * the incoming events to the ports are checked.
      Packit 4a16fb
       *
      Packit 4a16fb
       * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
      Packit 4a16fb
       * instead of reading the pollfd structs directly.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
      Packit 4a16fb
      {
      Packit 4a16fb
      	short revents = 0;
      Packit 4a16fb
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	if ((events & POLLIN) && space >= 1) {
      Packit 4a16fb
      		assert(seq->streams & SND_SEQ_OPEN_INPUT);
      Packit 4a16fb
      		revents |= POLLIN|POLLERR|POLLNVAL;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	if ((events & POLLOUT) && space >= 1) {
      Packit 4a16fb
      		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
      Packit 4a16fb
      		revents |= POLLOUT|POLLERR|POLLNVAL;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	if (!revents)
      Packit 4a16fb
      		return 0;
      Packit 4a16fb
      	pfds->fd = seq->poll_fd;
      Packit 4a16fb
      	pfds->events = revents;
      Packit 4a16fb
      	return 1;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get returned events from poll descriptors
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param pfds array of poll descriptors
      Packit 4a16fb
       * \param nfds count of poll descriptors
      Packit 4a16fb
       * \param revents returned events
      Packit 4a16fb
       * \return zero if success, otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_poll_descriptors()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
      Packit 4a16fb
      {
      Packit 4a16fb
              assert(seq && pfds && revents);
      Packit 4a16fb
              if (nfds == 1) {
      Packit 4a16fb
                      *revents = pfds->revents;
      Packit 4a16fb
                      return 0;
      Packit 4a16fb
              }
      Packit 4a16fb
              return -EINVAL;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set nonblock mode
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param nonblock 0 = block, 1 = nonblock mode
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Change the blocking mode of the given client.
      Packit 4a16fb
       * In block mode, the client falls into sleep when it fills the
      Packit 4a16fb
       * output memory pool with full events.  The client will be woken up
      Packit 4a16fb
       * after a certain amount of free space becomes available.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	err = seq->ops->nonblock(seq, nonblock);
      Packit 4a16fb
      	if (err < 0)
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	if (nonblock)
      Packit 4a16fb
      		seq->mode |= SND_SEQ_NONBLOCK;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		seq->mode &= ~SND_SEQ_NONBLOCK;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the client id
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return the client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * Returns the id of the specified client.
      Packit 4a16fb
       * If an error occurs, function returns the negative error code.
      Packit 4a16fb
       * A client id is necessary to inquiry or to set the client information.
      Packit 4a16fb
       * A user client is assigned from 128 to 191.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_open()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_id(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	return seq->client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Return the size of output buffer
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return the size of output buffer in bytes
      Packit 4a16fb
       *
      Packit 4a16fb
       * Obtains the size of output buffer.
      Packit 4a16fb
       * This buffer is used to store decoded byte-stream of output events
      Packit 4a16fb
       * before transferring to sequencer.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_set_output_buffer_size()
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	if (!seq->obuf)
      Packit 4a16fb
      		return 0;
      Packit 4a16fb
      	return seq->obufsize;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Return the size of input buffer
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return the size of input buffer in bytes
      Packit 4a16fb
       *
      Packit 4a16fb
       * Obtains the size of input buffer.
      Packit 4a16fb
       * This buffer is used to read byte-stream of input events from sequencer.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_set_input_buffer_size()
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	if (!seq->ibuf)
      Packit 4a16fb
      		return 0;
      Packit 4a16fb
      	return seq->ibufsize * sizeof(snd_seq_event_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Change the size of output buffer
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param size the size of output buffer to be changed in bytes
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Changes the size of output buffer.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_output_buffer_size()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && seq->obuf);
      Packit 4a16fb
      	assert(size >= sizeof(snd_seq_event_t));
      Packit 4a16fb
      	snd_seq_drop_output(seq);
      Packit 4a16fb
      	if (size != seq->obufsize) {
      Packit 4a16fb
      		char *newbuf;
      Packit 4a16fb
      		newbuf = calloc(1, size);
      Packit 4a16fb
      		if (newbuf == NULL)
      Packit 4a16fb
      			return -ENOMEM;
      Packit 4a16fb
      		free(seq->obuf);
      Packit 4a16fb
      		seq->obuf = newbuf;
      Packit 4a16fb
      		seq->obufsize = size;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Resize the input buffer
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param size the size of input buffer to be changed in bytes
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Changes the size of input buffer.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_input_buffer_size()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && seq->ibuf);
      Packit 4a16fb
      	assert(size >= sizeof(snd_seq_event_t));
      Packit 4a16fb
      	snd_seq_drop_input(seq);
      Packit 4a16fb
      	size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
      Packit 4a16fb
      	if (size != seq->ibufsize) {
      Packit 4a16fb
      		snd_seq_event_t *newbuf;
      Packit 4a16fb
      		newbuf = calloc(sizeof(snd_seq_event_t), size);
      Packit 4a16fb
      		if (newbuf == NULL)
      Packit 4a16fb
      			return -ENOMEM;
      Packit 4a16fb
      		free(seq->ibuf);
      Packit 4a16fb
      		seq->ibuf = newbuf;
      Packit 4a16fb
      		seq->ibufsize = size;
      Packit 4a16fb
      	}
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get size of #snd_seq_system_info_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_system_info_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_system_info_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_system_info_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Frees a previously allocated #snd_seq_system_info_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_system_info_free(snd_seq_system_info_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Copy one #snd_seq_system_info_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get maximum number of queues
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return maximum number of queues
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->queues;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get maximum number of clients
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return maximum number of clients
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->clients;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get maximum number of ports
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return maximum number of ports
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->ports;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get maximum number of channels
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return maximum number of channels
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->channels;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the current number of clients
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return current number of clients
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->cur_clients;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the current number of queues
      Packit 4a16fb
       * \param info #snd_seq_system_info_t container
      Packit 4a16fb
       * \return current number of queues
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_system_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->cur_queues;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain the sequencer system information
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info the pointer to be stored
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Stores the global system information of ALSA sequencer system.
      Packit 4a16fb
       * The returned data contains
      Packit 4a16fb
       * the maximum available numbers of queues, clients, ports and channels.
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	return seq->ops->system_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /*----------------------------------------------------------------*/
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_client_info_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_client_info_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_client_info_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate an empty #snd_seq_client_info_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_client_info_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief frees a previously allocated #snd_seq_client_info_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_free(snd_seq_client_info_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief copy one #snd_seq_client_info_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get client id of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get client type of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return client type
      Packit 4a16fb
       *
      Packit 4a16fb
       * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
      Packit 4a16fb
       * for kernel or user client respectively.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the name of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->name;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the broadcast filter usage of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return 1 if broadcast is accepted
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the error-bounce usage of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return 1 if error-bounce is enabled
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the sound card number.
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return card number or -1 if value is not available.
      Packit 4a16fb
       *
      Packit 4a16fb
       * Only available for #SND_SEQ_KERNEL_CLIENT clients.
      Packit 4a16fb
       *
      Packit 4a16fb
       * The card number can be used to query state about the hardware
      Packit 4a16fb
       * device providing this client, by concatenating "hw:CARD="
      Packit 4a16fb
       * with the card number and using it as the name parameter
      Packit 4a16fb
       * to #snd_ctl_open().
      Packit 4a16fb
       *
      Packit 4a16fb
       * \note
      Packit 4a16fb
       * The return value of -1 is returned for two different conditions: when the
      Packit 4a16fb
       * running kernel does not support this operation, and when the client
      Packit 4a16fb
       * does not have a hardware card attached. See
      Packit 4a16fb
       * #snd_seq_client_info_get_pid() for a way to determine if the
      Packit 4a16fb
       * currently running kernel has support for this operation.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_client_info_get_pid(),
      Packit 4a16fb
       *     snd_card_get_name(),
      Packit 4a16fb
       *     snd_card_get_longname(),
      Packit 4a16fb
       *     snd_ctl_open(),
      Packit 4a16fb
       *     snd_ctl_card_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->card;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the owning PID.
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return pid or -1 if value is not available.
      Packit 4a16fb
       *
      Packit 4a16fb
       * Only available for #SND_SEQ_USER_CLIENT clients.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \note
      Packit 4a16fb
       * The functionality for getting a client's PID and getting a
      Packit 4a16fb
       * client's card was added to the kernel at the same time, so you can
      Packit 4a16fb
       * use this function to determine if the running kernel
      Packit 4a16fb
       * supports reporting these values. If your own client has a valid
      Packit 4a16fb
       * PID as reported by this function, then the running kernel supports
      Packit 4a16fb
       * both #snd_seq_client_info_get_card() and #snd_seq_client_info_get_pid().
      Packit 4a16fb
       *
      Packit 4a16fb
       * \note
      Packit 4a16fb
       * Example code for determining kernel support:
      Packit 4a16fb
       * \code
      Packit 4a16fb
       *   int is_get_card_or_pid_supported(snd_seq_t *seq)
      Packit 4a16fb
       *   {
      Packit 4a16fb
       *   	snd_seq_client_info_t *my_client_info;
      Packit 4a16fb
       *   	snd_seq_client_info_alloca(&my_client_info);
      Packit 4a16fb
       *   	snd_seq_get_client_info(seq, my_client_info);
      Packit 4a16fb
       *   	return snd_seq_client_info_get_pid(my_client_info) != -1;
      Packit 4a16fb
       *   }
      Packit 4a16fb
       * \endcode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_client_info_get_card()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->pid;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return NULL if no event filter, or pointer to event filter bitmap
      Packit 4a16fb
       *
      Packit 4a16fb
       * Use #snd_seq_client_info_event_filter_check() instead.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_client_info_event_filter_add(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_del(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_check(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_clear(),
      Packit 4a16fb
       *     snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
      Packit 4a16fb
      		return info->event_filter;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		return NULL;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Disable event filtering of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       *
      Packit 4a16fb
       * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
      Packit 4a16fb
       * the event filtering flag of this client_info container.
      Packit 4a16fb
       * 
      Packit 4a16fb
       * \sa snd_seq_client_info_event_filter_add(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_del(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_check(),
      Packit 4a16fb
       *     snd_seq_get_client_info(),
      Packit 4a16fb
       *     snd_seq_set_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
             assert(info);
      Packit 4a16fb
             info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
      Packit 4a16fb
             memset(info->event_filter, 0, sizeof(info->event_filter));
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Add an event type to the event filtering of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param event_type event type to be added
      Packit 4a16fb
       * 
      Packit 4a16fb
       * Set the event filtering flag of this client_info and add the specified event type to the 
      Packit 4a16fb
       * filter bitmap of this client_info container.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(),
      Packit 4a16fb
       *     snd_seq_set_client_info(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_del(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_check(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_clear()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
      Packit 4a16fb
      {
      Packit 4a16fb
             assert(info);
      Packit 4a16fb
             info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
      Packit 4a16fb
             snd_seq_set_bit(event_type, info->event_filter);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Remove an event type from the event filtering of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param event_type event type to be removed
      Packit 4a16fb
       *
      Packit 4a16fb
       * Removes the specified event from the filter bitmap of this client_info container. It will
      Packit 4a16fb
       * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(),
      Packit 4a16fb
       *     snd_seq_set_client_info(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_add(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_check(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_clear()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
      Packit 4a16fb
      {
      Packit 4a16fb
             assert(info);
      Packit 4a16fb
             snd_seq_unset_bit(event_type, info->event_filter);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Check if an event type is present in the event filtering of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param event_type event type to be checked
      Packit 4a16fb
       * \return 1 if the event type is present, 0 otherwise
      Packit 4a16fb
       *
      Packit 4a16fb
       * Test if the event type is in the filter bitmap of this client_info container.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(),
      Packit 4a16fb
       *     snd_seq_set_client_info(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_add(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_del(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_clear()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
      Packit 4a16fb
      {
      Packit 4a16fb
             assert(info);
      Packit 4a16fb
             return snd_seq_get_bit(event_type, info->event_filter);
      Packit 4a16fb
      } 
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the number of opened ports of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return number of opened ports
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->num_ports;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the number of lost events of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \return number of lost events
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->event_lost;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the client id of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param client client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->client = client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the name of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param name name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
      Packit 4a16fb
       *     snd_seq_set_client_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info && name);
      Packit 4a16fb
      	snd_strlcpy(info->name, name, sizeof(info->name));
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the broadcast filter usage of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param val non-zero if broadcast is accepted
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the error-bounce usage of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param val non-zero if error is bounced
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
      Packit 4a16fb
       * \param info client_info container
      Packit 4a16fb
       * \param filter event filter bitmap, pass NULL for no event filtering
      Packit 4a16fb
       *
      Packit 4a16fb
       * Use #snd_seq_client_info_event_filter_add instead.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_client_info_event_filter_add(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_del(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_check(),
      Packit 4a16fb
       *     snd_seq_client_info_event_filter_clear(),
      Packit 4a16fb
       *     snd_seq_set_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (! filter)
      Packit 4a16fb
      		info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
      Packit 4a16fb
      	else {
      Packit 4a16fb
      		info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
      Packit 4a16fb
      		memcpy(info->event_filter, filter, sizeof(info->event_filter));
      Packit 4a16fb
      	}
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain the information of the given client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param client client id
      Packit 4a16fb
       * \param info the pointer to be stored
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       * 
      Packit 4a16fb
       * Obtains the information of the client with a client id specified by
      Packit 4a16fb
       * info argument.
      Packit 4a16fb
       * The obtained information is written on info parameter.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info && client >= 0);
      Packit 4a16fb
      	memset(info, 0, sizeof(snd_seq_client_info_t));
      Packit 4a16fb
      	info->client = client;
      Packit 4a16fb
      	return seq->ops->get_client_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain the current client information
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info the pointer to be stored
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Obtains the information of the current client stored on info.
      Packit 4a16fb
       * client and type fields are ignored.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
      Packit 4a16fb
       *     snd_seq_query_next_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	return snd_seq_get_any_client_info(seq, seq->client, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the current client information
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info the client info data to set
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Obtains the information of the current client stored on info.
      Packit 4a16fb
       * client and type fields are ignored.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	info->client = seq->client;
      Packit 4a16fb
      	info->type = USER_CLIENT;
      Packit 4a16fb
      	return seq->ops->set_client_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief query the next client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info query pattern and result
      Packit 4a16fb
       *
      Packit 4a16fb
       * Queries the next client.
      Packit 4a16fb
       * The search begins at the client with an id one greater than
      Packit 4a16fb
       * client field in info.
      Packit 4a16fb
       * If a client is found, its attributes are stored in info,
      Packit 4a16fb
       * and zero is returned.
      Packit 4a16fb
       * Otherwise returns a negative error code.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_any_client_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	return seq->ops->query_next_client(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /*----------------------------------------------------------------*/
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /*
      Packit 4a16fb
       * Port
      Packit 4a16fb
       */
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_port_info_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_port_info_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_port_info_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate an empty #snd_seq_port_info_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_port_info_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief frees a previously allocated #snd_seq_port_info_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_free(snd_seq_port_info_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief copy one #snd_seq_port_info_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get client id of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->addr.client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get port id of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return port id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->addr.port;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get client/port address of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return client/port address pointer
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
      Packit 4a16fb
       */
      Packit 4a16fb
      const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (const snd_seq_addr_t *) &info->addr;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the name of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->name;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the capability bits of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return capability bits
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
      Packit 4a16fb
       */
      Packit 4a16fb
      unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->capability;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the type bits of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return port type bits
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
      Packit 4a16fb
       */
      Packit 4a16fb
      unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the number of read subscriptions of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return number of read subscriptions
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->read_use;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the number of write subscriptions of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return number of write subscriptions
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->write_use;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the midi channels of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return number of midi channels (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->midi_channels;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the midi voices of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return number of midi voices (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->midi_voices;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the synth voices of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return number of synth voices (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->synth_voices;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the port-specified mode of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return 1 if port id is specified at creation
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the time-stamping mode of the given port in a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return 1 if the port updates timestamps of incoming events
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get whether the time-stamping of the given port is real-time mode
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return 1 if the time-stamping is in the real-time mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the queue id to update timestamps
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \return the queue id to get the timestamps
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->time_queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the client id of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param client client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->addr.client = client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the port id of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param port port id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->addr.port = port;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the client/port address of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param addr client/port address
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->addr = *(const struct sndrv_seq_addr *)addr;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the name of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param name name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info && name);
      Packit 4a16fb
      	snd_strlcpy(info->name, name, sizeof(info->name));
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the capability bits of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param capability capability bits
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->capability = capability;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the type bits of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param type port type bits
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->type = type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the midi channels of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param channels midi channels (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->midi_channels = channels;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the midi voices of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param voices midi voices (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->midi_voices = voices;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the synth voices of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param voices synth voices (default 0)
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->synth_voices = voices;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the port-specified mode of a port_info container
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param val non-zero if specifying the port id at creation
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the time-stamping mode of the given port
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param enable non-zero if updating the timestamps of incoming events
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (enable)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set whether the timestime is updated in the real-time mode
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param enable non-zero if updating the timestamps in real-time mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (enable)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the queue id for timestamping
      Packit 4a16fb
       * \param info port_info container
      Packit 4a16fb
       * \param queue the queue id to get timestamps
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->time_queue = queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief create a sequencer port on the current client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param port port information for the new port
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Creates a sequencer port on the current client.
      Packit 4a16fb
       * The attributes of created port is specified in \a info argument.
      Packit 4a16fb
       *
      Packit 4a16fb
       * The client field in \a info argument is overwritten with the current client id.
      Packit 4a16fb
       * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
      Packit 4a16fb
       * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
      Packit 4a16fb
       *
      Packit 4a16fb
       * Each port has the capability bit-masks to specify the access capability
      Packit 4a16fb
       * of the port from other clients.
      Packit 4a16fb
       * The capability bit flags are defined as follows:
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_READ Readable from this port
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
      Packit 4a16fb
       * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
      Packit 4a16fb
       *
      Packit 4a16fb
       * Each port has also the type bitmasks defined as follows:
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
      Packit 4a16fb
       * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
      Packit 4a16fb
       *
      Packit 4a16fb
       * A port may contain specific midi channels, midi voices and synth voices.
      Packit 4a16fb
       * These values could be zero as default.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
      Packit 4a16fb
       *     snd_seq_create_simple_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && port);
      Packit 4a16fb
      	port->addr.client = seq->client;
      Packit 4a16fb
      	return seq->ops->create_port(seq, port);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief delete a sequencer port on the current client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param port port to be deleted
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Deletes the existing sequencer port on the current client.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_delete_port(snd_seq_t *seq, int port)
      Packit 4a16fb
      {
      Packit 4a16fb
      	snd_seq_port_info_t pinfo;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	memset(&pinfo, 0, sizeof(pinfo));
      Packit 4a16fb
      	pinfo.addr.client = seq->client;
      Packit 4a16fb
      	pinfo.addr.port = port;
      Packit 4a16fb
      	return seq->ops->delete_port(seq, &pinfo);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain the information of a port on an arbitrary client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param client client id to get
      Packit 4a16fb
       * \param port port id to get
      Packit 4a16fb
       * \param info pointer information returns
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info && client >= 0 && port >= 0);
      Packit 4a16fb
      	memset(info, 0, sizeof(snd_seq_port_info_t));
      Packit 4a16fb
      	info->addr.client = client;
      Packit 4a16fb
      	info->addr.port = port;
      Packit 4a16fb
      	return seq->ops->get_port_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain the information of a port on the current client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param port port id to get
      Packit 4a16fb
       * \param info pointer information returns
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
      Packit 4a16fb
       *     snd_seq_query_next_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	return snd_seq_get_any_port_info(seq, seq->client, port, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief set the information of a port on the current client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param port port to be set
      Packit 4a16fb
       * \param info port information to be set
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_set_port_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info && port >= 0);
      Packit 4a16fb
      	info->addr.client = seq->client;
      Packit 4a16fb
      	info->addr.port = port;
      Packit 4a16fb
      	return seq->ops->set_port_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief query the next matching port
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info query pattern and result
      Packit 4a16fb
      Packit 4a16fb
       * Queries the next matching port on the client specified in
      Packit 4a16fb
       * \a info argument.
      Packit 4a16fb
       * The search begins at the next port specified in
      Packit 4a16fb
       * port field of \a info argument.
      Packit 4a16fb
       * For finding the first port at a certain client, give -1.
      Packit 4a16fb
       *
      Packit 4a16fb
       * If a matching port is found, its attributes are stored on
      Packit 4a16fb
       * \a info and function returns zero.
      Packit 4a16fb
       * Otherwise, a negative error code is returned.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	return seq->ops->query_next_port(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /*----------------------------------------------------------------*/
      Packit 4a16fb
      Packit 4a16fb
      /*
      Packit 4a16fb
       * subscription
      Packit 4a16fb
       */
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_port_subscribe_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_port_subscribe_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_port_subscribe_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief frees a previously allocated #snd_seq_port_subscribe_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief copy one #snd_seq_port_subscribe_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get sender address of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
      Packit 4a16fb
       */
      Packit 4a16fb
      const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (const snd_seq_addr_t *)&info->sender;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get destination address of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
      Packit 4a16fb
       */
      Packit 4a16fb
      const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (const snd_seq_addr_t *)&info->dest;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the queue id of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \return queue id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the exclusive mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \return 1 if exclusive mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the time-update mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \return 1 if update timestamp
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the real-time update mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \return 1 if real-time update mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set sender address of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param addr sender address
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	memcpy(&info->sender, addr, sizeof(*addr));
      Packit 4a16fb
      }
      Packit 4a16fb
            
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set destination address of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param addr destination address
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	memcpy(&info->dest, addr, sizeof(*addr));
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the queue id of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param q queue id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->queue = q;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the exclusive mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param val non-zero to enable
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the time-update mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param val non-zero to enable
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the real-time mode of a port_subscribe container
      Packit 4a16fb
       * \param info port_subscribe container
      Packit 4a16fb
       * \param val non-zero to enable
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	if (val)
      Packit 4a16fb
      		info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
      Packit 4a16fb
      	else
      Packit 4a16fb
      		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain subscription information
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param sub pointer to return the subscription information
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && sub);
      Packit 4a16fb
      	return seq->ops->get_port_subscription(seq, sub);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief subscribe a port connection
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param sub subscription information
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Subscribes a connection between two ports.
      Packit 4a16fb
       * The subscription information is stored in sub argument.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
      Packit 4a16fb
       *     snd_seq_connect_from(), snd_seq_connect_to()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && sub);
      Packit 4a16fb
      	return seq->ops->subscribe_port(seq, sub);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief unsubscribe a connection between ports
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param sub subscription information to disconnect
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Unsubscribes a connection between two ports,
      Packit 4a16fb
       * described in sender and dest fields in sub argument.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && sub);
      Packit 4a16fb
      	return seq->ops->unsubscribe_port(seq, sub);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_query_subscribe_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_query_subscribe_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_query_subscribe_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief frees a previously allocated #snd_seq_query_subscribe_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief copy one #snd_seq_query_subscribe_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the client id of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->root.client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the port id of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return port id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->root.port;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the client/port address of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return client/port address pointer
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
      Packit 4a16fb
       */
      Packit 4a16fb
      const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (const snd_seq_addr_t *)&info->root;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the query type of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return query type
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
      Packit 4a16fb
       */
      Packit 4a16fb
      snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the index of subscriber of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return subscriber's index
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->index;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the number of subscriptions of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return number of subscriptions
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->num_subs;
      Packit 4a16fb
      }	
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the address of subscriber of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return subscriber's address pointer
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (const snd_seq_addr_t *)&info->addr;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the queue id of subscriber of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return subscriber's queue id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the exclusive mode of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return 1 if exclusive mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the time-update mode of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return 1 if update timestamp
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the real-time update mode of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \return 1 if real-time update mode
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the client id of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \param client client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->root.client = client;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the port id of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \param port port id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->root.port = port;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the client/port address of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \param addr client/port address pointer
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->root = *(const struct snd_seq_addr *)addr;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the query type of a query_subscribe container
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \param type query type
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->type = type;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the subscriber's index to be queried
      Packit 4a16fb
       * \param info query_subscribe container
      Packit 4a16fb
       * \param index index to be queried
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->index = index;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief query port subscriber list
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param subs subscription to query
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Queries the subscribers accessing to a port.
      Packit 4a16fb
       * The query information is specified in subs argument.
      Packit 4a16fb
       *
      Packit 4a16fb
       * At least, the client id, the port id, the index number and
      Packit 4a16fb
       * the query type must be set to perform a proper query.
      Packit 4a16fb
       * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
      Packit 4a16fb
       * can be specified to check whether the readers or the writers to the port.
      Packit 4a16fb
       * To query the first subscription, set 0 to the index number.  To list up
      Packit 4a16fb
       * all the subscriptions, call this function with the index numbers from 0
      Packit 4a16fb
       * until this returns a negative value.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_port_subscription()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && subs);
      Packit 4a16fb
      	return seq->ops->query_port_subscribers(seq, subs);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /*----------------------------------------------------------------*/
      Packit 4a16fb
      Packit 4a16fb
      /*
      Packit 4a16fb
       * queue handlers
      Packit 4a16fb
       */
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_queue_info_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_queue_info_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_queue_info_t);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
      Packit 4a16fb
       * \param ptr returned pointer
      Packit 4a16fb
       * \return 0 on success otherwise negative error code
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(ptr);
      Packit 4a16fb
      	*ptr = calloc(1, sizeof(snd_seq_queue_info_t));
      Packit 4a16fb
      	if (!*ptr)
      Packit 4a16fb
      		return -ENOMEM;
      Packit 4a16fb
      	return 0;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief frees a previously allocated #snd_seq_queue_info_t
      Packit 4a16fb
       * \param obj pointer to object to free
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
      Packit 4a16fb
      {
      Packit 4a16fb
      	free(obj);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief copy one #snd_seq_queue_info_t to another
      Packit 4a16fb
       * \param dst pointer to destination
      Packit 4a16fb
       * \param src pointer to source
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(dst && src);
      Packit 4a16fb
      	*dst = *src;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the queue id of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \return queue id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the name of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \return name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->name;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the owner client id of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \return owner client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->owner;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the lock status of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \return lock status --- non-zero = locked
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->locked;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the conditional bit flags of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \return conditional bit flags
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
      Packit 4a16fb
       */
      Packit 4a16fb
      unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	return info->flags;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the name of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \param name name string
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info && name);
      Packit 4a16fb
      	snd_strlcpy(info->name, name, sizeof(info->name));
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the owner client id of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \param owner client id
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->owner = owner;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the lock status of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \param locked lock status
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->locked = locked;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the conditional bit flags of a queue_info container
      Packit 4a16fb
       * \param info queue_info container
      Packit 4a16fb
       * \param flags conditional bit flags
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
      Packit 4a16fb
       */
      Packit 4a16fb
      void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(info);
      Packit 4a16fb
      	info->flags = flags;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief create a queue
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param info queue information to initialize
      Packit 4a16fb
       * \return the queue id (zero or positive) on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_alloc_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	info->owner = seq->client;
      Packit 4a16fb
      	err = seq->ops->create_queue(seq, info);
      Packit 4a16fb
      	if (err < 0)
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	return info->queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate a queue with the specified name
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param name the name of the new queue
      Packit 4a16fb
       * \return the queue id (zero or positive) on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_alloc_queue()
      Packit 4a16fb
       */ 
      Packit 4a16fb
      int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
      Packit 4a16fb
      {
      Packit 4a16fb
      	snd_seq_queue_info_t info;
      Packit 4a16fb
      	memset(&info, 0, sizeof(info));
      Packit 4a16fb
      	info.locked = 1;
      Packit 4a16fb
      	if (name)
      Packit 4a16fb
      		snd_strlcpy(info.name, name, sizeof(info.name));
      Packit 4a16fb
      	return snd_seq_create_queue(seq, &info;;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief allocate a queue
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \return the queue id (zero or positive) on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
      Packit 4a16fb
       *     snd_seq_get_queue_info()
      Packit 4a16fb
       */ 
      Packit 4a16fb
      int snd_seq_alloc_queue(snd_seq_t *seq)
      Packit 4a16fb
      {
      Packit 4a16fb
      	return snd_seq_alloc_named_queue(seq, NULL);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief delete the specified queue
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param q queue id to delete
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_alloc_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_free_queue(snd_seq_t *seq, int q)
      Packit 4a16fb
      {
      Packit 4a16fb
      	snd_seq_queue_info_t info;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	memset(&info, 0, sizeof(info));
      Packit 4a16fb
      	info.queue = q;
      Packit 4a16fb
      	return seq->ops->delete_queue(seq, &info;;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief obtain queue attributes
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param q queue id to query
      Packit 4a16fb
       * \param info information returned
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	info->queue = q;
      Packit 4a16fb
      	return seq->ops->get_queue_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief change the queue attributes
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param q queue id to change
      Packit 4a16fb
       * \param info information changed
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
      Packit 4a16fb
      {
      Packit 4a16fb
      	assert(seq && info);
      Packit 4a16fb
      	info->queue = q;
      Packit 4a16fb
      	return seq->ops->set_queue_info(seq, info);
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief query the matching queue with the specified name
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param name the name string to query
      Packit 4a16fb
       * \return the queue id if found or negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * Searches the matching queue with the specified name string.
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
      Packit 4a16fb
      {
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	snd_seq_queue_info_t info;
      Packit 4a16fb
      	assert(seq && name);
      Packit 4a16fb
      	snd_strlcpy(info.name, name, sizeof(info.name));
      Packit 4a16fb
      	err = seq->ops->get_named_queue(seq, &info;;
      Packit 4a16fb
      	if (err < 0)
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	return info.queue;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Get the queue usage flag to the client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param q queue id
      Packit 4a16fb
       * \return 1 = client is allowed to access the queue, 0 = not allowed, 
      Packit 4a16fb
       *     otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
      Packit 4a16fb
      {
      Packit 4a16fb
      	struct snd_seq_queue_client info;
      Packit 4a16fb
      	int err;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	memset(&info, 0, sizeof(info));
      Packit 4a16fb
      	info.queue = q;
      Packit 4a16fb
      	info.client = seq->client;
      Packit 4a16fb
      	if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
      Packit 4a16fb
      		return err;
      Packit 4a16fb
      	return info.used;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief Set the queue usage flag to the client
      Packit 4a16fb
       * \param seq sequencer handle
      Packit 4a16fb
       * \param q queue id
      Packit 4a16fb
       * \param used non-zero if the client is allowed
      Packit 4a16fb
       * \return 0 on success otherwise a negative error code
      Packit 4a16fb
       *
      Packit 4a16fb
       * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
      Packit 4a16fb
       */
      Packit 4a16fb
      int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
      Packit 4a16fb
      {
      Packit 4a16fb
      	struct snd_seq_queue_client info;
      Packit 4a16fb
      	assert(seq);
      Packit 4a16fb
      	memset(&info, 0, sizeof(info));
      Packit 4a16fb
      	info.queue = q;
      Packit 4a16fb
      	info.client = seq->client;
      Packit 4a16fb
      	info.used = used ? 1 : 0;
      Packit 4a16fb
      	return seq->ops->set_queue_client(seq, &info;;
      Packit 4a16fb
      }
      Packit 4a16fb
      Packit 4a16fb
      Packit 4a16fb
      /**
      Packit 4a16fb
       * \brief get size of #snd_seq_queue_status_t
      Packit 4a16fb
       * \return size in bytes
      Packit 4a16fb
       */
      Packit 4a16fb
      size_t snd_seq_queue_status_sizeof()
      Packit 4a16fb
      {
      Packit 4a16fb
      	return sizeof(snd_seq_queue_status_t);