/**
 * \file seq/seq.c
 * \brief Sequencer Interface
 * \author Jaroslav Kysela <perex@perex.cz>
 * \author Abramo Bagnara <abramo@alsa-project.org>
 * \author Takashi Iwai <tiwai@suse.de>
 * \date 2000-2001
 *
 * See \ref seq page for more details.
 */

/* 
 *  Sequencer Interface - main file
 *
 *   This library is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU Lesser General Public License as
 *   published by the Free Software Foundation; either version 2.1 of
 *   the License, or (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU Lesser General Public License for more details.
 *
 *   You should have received a copy of the GNU Lesser General Public
 *   License along with this library; if not, write to the Free Software
 *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 *
 */

/*! \page seq Sequencer interface

\section seq_general General

The ALSA sequencer interface is designed to deliver the MIDI-like
events between clients/ports.
A typical usage is the MIDI patch-bay.  A MIDI application can be
connected arbitrarily from/to the other MIDI clients.
The routing between clients can be changed dynamically, so the
application can handle incoming or outgoing MIDI events regardless of
the devices or the application connections.

The sequencer core stuff only takes care of two things:
scheduling events and dispatching them to the destination at the
right time.  All processing of MIDI events has to be done within the clients.
The event can be dispatched immediately without queueing, too.
The event scheduling can be done either on a MIDI tempo queue or
on a wallclock-time queue.

\section seq_client Client and Port

A <i>client</i> is created at each time #snd_seq_open() is called.
Later on, the attributes of client such as its name string can be changed
via #snd_seq_set_client_info().  There are helper functions for ease of use,
e.g. #snd_seq_set_client_name() and #snd_seq_set_client_event_filter().
A typical code would be like below:
\code
// create a new client
snd_seq_t *open_client()
{
        snd_seq_t *handle;
        int err;
        err = snd_seq_open(&handle, "default", SND_SEQ_OPEN_INPUT, 0);
        if (err < 0)
                return NULL;
        snd_seq_set_client_name(handle, "My Client");
	return handle;
}
\endcode

You'll need to know the id number of the client eventually, for example,
when accessing to a certain port (see the section \ref seq_subs).
The client id can be obtained by #snd_seq_client_id() function.

A client can have one or more <i>ports</i> to communicate between other
clients.  A port is corresponding to the MIDI port in the case of MIDI device,
but in general it is nothing but the access point between other clients.
Each port may have capability flags, which specify the read/write
accessibility and subscription permissions of the port.
For creation of a port, call #snd_seq_create_port()
with the appropriate port attribute specified in #snd_seq_port_info_t
record.

For creating a port for the normal use, there is a helper function
#snd_seq_create_simple_port().  An example with this function is like below.
\code
// create a new port; return the port id
// port will be writable and accept the write-subscription.
int my_new_port(snd_seq_t *handle)
{
	return snd_seq_create_simple_port(handle, "my port",
			SND_SEQ_PORT_CAP_WRITE|SND_SEQ_PORT_CAP_SUBS_WRITE,
			SND_SEQ_PORT_TYPE_MIDI_GENERIC);
}
\endcode

\section seq_memory Memory Pool

Each client owns memory pools on kernel space
for each input and output events.
Here, input and output mean
input (read) from other clients and output (write) to others, respectively.
Since memory pool of each client is independent from others,
it avoids such a situation that a client eats the whole events pool
and interfere other clients' response.

The all scheduled output events or input events from dispatcher are stored
on these pools until delivered to other clients or extracted to user space.
The size of input/output pools can be changed independently.
The output pool has also a room size, which is used to wake up the
thread when it falls into sleep in blocking write mode.

Note that ports on the same client share the same memory pool.
If a port fills the memory pool, another can't use it any more.
For avoiding this, multiple clients can be used.

For chancing the pool size and the condition, access to #snd_seq_client_pool_t
record.  There are helper functions, #snd_seq_set_client_pool_output(),
#snd_seq_set_client_pool_output_room() and #snd_seq_set_client_pool_input(),
for setting the total output-pool size, the output-room size and the input-pool
size, respectively.

\section seq_subs Subscription

One of the new features in ALSA sequencer system is <i>subscription</i> of ports.
In general, subscription is a connection between two sequencer ports.
Even though an event can be delivered to a port without subscription
using an explicit destination address,
the subscription mechanism provides us more abstraction.

Suppose a MIDI input device which sends events from a keyboard.
The port associated with this device has READ capability - which means
this port is readable from other ports.
If a user program wants to capture events from keyboard and store them
as MIDI stream, this program must subscribe itself to the MIDI port
for read.
Then, a connection from MIDI input port to this program is established.
From this time, events from keyboard are automatically sent to this program.
Timestamps will be updated according to the subscribed queue.
\code
        MIDI input port (keyboard)
            |
            V
        ALSA sequencer - update timestamp
            |
            V
        application port
\endcode

There is another subscription type for opposite direction:
Suppose a MIDI sequencer program which sends events to a MIDI output device.
In ALSA system, MIDI device is not opened until the associated MIDI port
is accessed.  Thus, in order to activate MIDI device, we have to subscribe
to MIDI port for write.
After this connection is established, events will be properly sent
to MIDI output device.
\code
        application port
            |
            V
        ALSA sequencer - events are scheduled
            |
            V
        MIDI output port (WaveTable etc.)
\endcode

From the viewpoint of subscription, the examples above are special cases.
Basically, subscription means the connection between two arbitrary ports.
For example, imagine a filter application which modifies
the MIDI events like program, velocity or chorus effects.
This application can accept arbitrary MIDI input
and send to arbitrary port, just like a Unix pipe application using
stdin and stdout files.
We can even connect several filter applications which work individually
in order to process the MIDI events.
Subscription can be used for this purpose.
The connection between ports can be done also by the "third" client.
Thus, filter applications have to manage
only input and output events regardless of receiver/sender addresses.
\code
        sequencer port #1
            |
            V
        ALSA sequencer (scheduled or real-time)
            |
            V
        sequencer port #2
\endcode

For the detail about subscription, see the section \ref seq_subs_more.

\section seq_events Sequencer Events

Messaging between clients is performed by sending events from one client to
another. These events contain high-level MIDI oriented messages or sequencer
specific messages.

All the sequencer events are stored in a sequencer event record,
#snd_seq_event_t type.
Application can send and receive these event records to/from other
clients via sequencer.
An event has several storage types according to its usage.
For example, a SYSEX message is stored on the variable length event,
and a large synth sample data is delivered using a user-space data pointer.


\subsection seq_ev_struct Structure of an event

An event consists of the following items:
<ul>
<li>The type of the event
<li>Event flags.  It describes various conditions:
  <ul>
  <li>time stamp; "real time" / "song ticks"
  <li>time mode; "absolute" / "relative to current time"
  </ul>
<li>Timestamp of the event.
<li>Scheduling queue id.
<li>Source address of the event, given by the combination
  of client id and port id numbers.
<li>Destination address of the event.
<li>The actual event data. (up to 12 bytes)
</ul>

The actual record is shown in #snd_seq_event_t.
The type field contains the type of the event
(1 byte).
The flags field consists of bit flags which
describe several conditions of the event (1 byte).
It includes the time-stamp mode, data storage type, and scheduling priority.
The tag field is an arbitrary tag.
This tag can used for removing a distinct event from the event queue
via #snd_seq_remove_events().
The queue field is the queue id for scheduling.
The source and dest fields are source and destination addresses.
The data field is a union of event data.

\subsection seq_ev_queue Scheduling queue

An event can be delivered either on scheduled or direct dispatch mode.
On the scheduling mode, an event is once stored on the priority queue
and delivered later (or even immediately) to the destination,
whereas on the direct dispatch mode, an event is passed to the destination
without any queue.

For a scheduled delivery, a queue to process the event must exist.
Usually, a client creates its own queue by
#snd_seq_alloc_queue() function.
Alternatively, a queue may be shared among several clients.
For scheduling an event on the specified queue,
a client needs to fill queue field
with the preferred queue id.

Meanwhile, for dispatching an event directly, just
use #SND_SEQ_QUEUE_DIRECT as the target queue id.
A macro #snd_seq_ev_set_direct() is provided for ease
and compatibility.

Note that scheduling at the current or earlier time is different
from the direct dispatch mode even though the event is delivered immediately.
On the former scheme, an event is once stored on priority queue, then
delivered actually.  Thus, it acquires a space from memory pool.
On the other hand, the latter is passed without using memory pool.
Although the direct dispatched event needs less memory, it means also
that the event cannot be resent if the destination is unable to receive it
momentarily.

\subsection seq_ev_time Time stamp

The timestamp of the event can either specified in
<i>real time</i> or in <i>song ticks</i>.
The former means the wallclock time while the latter corresponds to
the MIDI ticks.
Which format is used is determined by the event flags.

The resolution of real-time value is in nano second.
Since 64 bit length is required for the actual time calculation,
it is represented by
a structure of pair of second and nano second
defined as #snd_seq_real_time_t type.
The song tick is defined simply as a 32 bit integer,
defined as #snd_seq_tick_time_t type.
The time stored in an event record is a union of these two different
time values.

Note that the time format used for real time events is very similar to
timeval struct used for Unix system time.
The absurd resolution of the timestamps allows us to perform very accurate
conversions between songposition and real time. Round-off errors can be
neglected.

If a timestamp with a
<i>relative</i> timestamp is delivered to ALSA, the
specified timestamp will be used as an offset to the current time of the
queue the event is sent into.
An <i>absolute</i> timestamp is on the contrary the time
counted from the moment when the queue started.

An client that relies on these relative timestamps is the MIDI input port.
As each sequencer queue has it's own clock the only way to deliver events at
the right time is by using the relative timestamp format. When the event
arrives at the queue it is normalized to absolute format.

The timestamp format is specified in the flag bitfield masked by
#SND_SEQ_TIME_STAMP_MASK.
To schedule the event in a real-time queue or in a tick queue,
macros #snd_seq_ev_schedule_real() and
#snd_seq_ev_schedule_tick() are provided, respectively.

\subsection seq_ev_addr Source and destination addresses

To identify the source and destination of an event, the addressing field
contains a combination of client id and port id numbers, defined as
#snd_seq_addr_t type.
When an event is passed to sequencer from a client, sequencer fills
source.client field
with the sender's id automatically.
It is the responsibility of sender client to 
fill the port id of source.port and
both client and port of dest field.

If an existing address is set to the destination,
the event is simply delivered to it.
When #SND_SEQ_ADDRESS_SUBSCRIBERS is set to the destination client id,
the event is delivered to all the clients connected to the source port.


A sequencer core has two pre-defined system ports on the system client
#SND_SEQ_CLIENT_SYSTEM: #SND_SEQ_PORT_SYSTEM_TIMER and #SND_SEQ_PORT_SYSTEM_ANNOUNCE.
The #SND_SEQ_PORT_SYSTEM_TIMER is the system timer port,
and #SND_SEQ_PORT_SYSTEM_ANNOUNCE is the system
announce port.
In order to control a queue from a client, client should send a
queue-control event
like start, stop and continue queue, change tempo, etc.
to the system timer port.
Then the sequencer system handles the queue according to the received event.
This port supports subscription. The received timer events are 
broadcasted to all subscribed clients.

The latter port does not receive messages but supports subscription.
When each client or port is attached, detached or modified,
an announcement is sent to subscribers from this port.

\subsection seq_ev_data Data storage type

Some events like SYSEX message, however, need larger data space
than the standard data.
For such events, ALSA sequencer provides several different data storage types.
The data type is specified in the flag bits masked by #SND_SEQ_EVENT_LENGTH_MASK.
The following data types are available:

\par Fixed size data
Normal events stores their parameters on
data field (12 byte).
The flag-bit type is  #SND_SEQ_EVENT_LENGTH_FIXED.
A macro #snd_seq_ev_set_fixed() is provided to set this type.

\par Variable length data
SYSEX or a returned error use this type.
The actual data is stored on an extra allocated space.
On sequencer kernel, the whole extra-data is duplicated, so that the event
can be scheduled on queue.
The data contains only the length and the
pointer of extra-data.
The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARIABLE.
A macro #snd_seq_ev_set_variable() is provided to set this type.

\par User-space data
This type refers also an extra data space like variable length data,
but the extra-data is not duplicated but
but referred as a user-space data on kernel,
so that it reduces the time and resource for transferring
large bulk of data like synth sample wave.
This data type, however, can be used only for direct dispatch mode,
and supposed to be used only for a special purpose like a bulk data
transfer.
The data length and pointer are stored also in
data.ext field as well as variable length data.
The flag-bit type is  #SND_SEQ_EVENT_LENGTH_VARUSR.
A macro #snd_seq_ev_set_varusr() is provided to set this type.

\subsection seq_ev_sched Scheduling priority

There are two priorities for scheduling:
\par Normal priority
If an event with the same scheduling time is already present on the queue,
the new event is appended to the older.
\par High priority
If an event with the same scheduling time is already present on the queue,
the new event is inserted before others.

The scheduling priority is set in the flag bitfeld masked by #SND_SEQ_PRIORITY_MASK.
A macro #snd_seq_ev_set_priority() is provided to set the mode type.

\section seq_queue Event Queues
\subsection seq_ev_control Creation of a queue

Creating a queue is done usually by calling #snd_seq_alloc_queue.
You can create a queue with a certain name by #snd_seq_alloc_named_queue(), too.
\code
// create a queue and return its id
int my_queue(snd_seq_t *handle)
{
	return snd_seq_alloc_named_queue(handle, "my queue");
}
\endcode
These functions are the wrapper to the function #snd_seq_create_queue().
For releasing the allocated queue, call #snd_seq_free_queue() with the
obtained queue id.

Once when a queue is created, the two queues are associated to that
queue record in fact: one is the realtime queue and another is the
tick queue.  These two queues are bound together to work
synchronously.  Hence, when you schedule an event, you have to choose
which queue type is used as described in the section \ref
seq_ev_time.

\subsection seq_ev_tempo Setting queue tempo

The tempo (or the speed) of the scheduling queue is variable.
In the case of <i>tick</i> queue, the tempo is controlled
in the manner of MIDI.  There are two parameters to define the
actual tempo, PPQ (pulse per quarter note) and MIDI tempo.
The former defines the base resolution of the ticks, while
the latter defines the beat tempo in microseconds.
As default, 96 PPQ and 120 BPM are used, respectively.
That is, the tempo is set to 500000 (= 60 * 1000000 / 120).
Note that PPQ cannot be changed while the queue is running.
It must be set before the queue is started.

On the other hand, in the case of <i>realtime</i> queue, the
time resolution is fixed to nanoseconds.  There is, however,
a parameter to change the speed of this queue, called <i>skew</i>.
You can make the queue faster or slower by setting the skew value
bigger or smaller.  In the API, the skew is defined by two values,
the skew base and the skew value.  The actual skew is the fraction
of them, <i>value/base</i>.  As default, the skew base is set to 16bit
(0x10000) and the skew value is the identical, so that the queue is
processed as well as in the real world.

When the tempo of realtime queue is changed, the tempo of
the associated tick queue is changed together, too.
That's the reason why two queues are created always.
This feature can be used to synchronize the event queue with
the external synchronization source like SMPTE.  In such a case,
the realtime queue is skewed to match with the external source,
so that both the realtime timestamp and the MIDI timestamp are
synchronized.

For setting these tempo parameters, use #snd_seq_queue_tempo_t record.
For example, to set the tempo of the queue <code>q</code> to
48 PPQ, 60 BPM,
\code
void set_tempo(snd_seq_t *handle)
{
        snd_seq_queue_tempo_t *tempo;
        snd_seq_queue_tempo_alloca(&tempo);
        snd_seq_queue_tempo_set_tempo(tempo, 1000000); // 60 BPM
        snd_seq_queue_tempo_set_ppq(tempo, 48); // 48 PPQ
        snd_seq_set_queue_tempo(handle, tempo);
}
\endcode

For changing the (running) queue's tempo on the fly, you can either
set the tempo via #snd_seq_set_queue_tempo() or send a MIDI tempo event
to the system timer port.  For example,
\code
int change_tempo(snd_seq_t *handle, int q, unsigned int tempo)
{
	snd_seq_event_t ev;
	snd_seq_ev_clear(&ev);
	ev.dest.client = SND_SEQ_CLIENT_SYSTEM;
	ev.dest.port = SND_SEQ_PORT_SYSTEM_TIMER;
	ev.source.client = my_client_id;
	ev.source.port = my_port_id;
	ev.queue = SND_SEQ_QUEUE_DIRECT; // no scheduling
	ev.data.queue.queue = q;	// affected queue id
	ev.data.queue.value = tempo;	// new tempo in microsec.
	return snd_seq_event_output(handle, &ev);
}
\endcode
There is a helper function to do this easily,
#snd_seq_change_queue_tempo().
Set NULL to the last argument, if you don't need any
special settings.

In the above example, the tempo is changed immediately after
the buffer is flushed by #snd_seq_drain_output() call.
You can schedule the event in a certain queue so that the tempo
change happens at the scheduled time, too.

\subsection seq_ev_start Starting and stopping a queue

To start, stop, or continue a queue, you need to send a queue-control
event to the system timer port as well.  There are helper functions,
#snd_seq_start_queue(), #snd_seq_stop_queue() and
#snd_seq_continue_queue().
Note that if the last argument of these functions is NULL, the
event is sent (i.e. operated) immediately after the buffer flush.
If you want to schedule the event at the certain time, set up
the event record and provide the pointer of that event record as the
argument.

Only calling these functions doesn't deliver the event to the
sequencer core but only put to the output buffer.  You'll need to
call #snd_seq_drain_output() eventually.


\section seq_subs_more More inside the subscription

\subsection seq_subs_perm Permissions

Each ALSA port can have capability flags.
The most basic capability flags are
#SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE.
The former means that the port allows to send events to other ports,
whereas the latter capability means
that the port allows to receive events from other ports.
You may have noticed that meanings of \c READ and \c WRITE
are permissions of the port from the viewpoint of other ports.

For allowing subscription from/to other clients, another capability
flags must be set together with read/write capabilities above.
For allowing read and write subscriptions,
#SND_SEQ_PORT_CAP_SUBS_READ and
#SND_SEQ_PORT_CAP_SUBS_WRITE are used,
respectively.
For example, the port with MIDI input device always has
#SND_SEQ_PORT_CAP_SUBS_READ capability,
and the port with MIDI output device always has
#SND_SEQ_PORT_CAP_SUBS_WRITE capability together with
#SND_SEQ_PORT_CAP_READ and #SND_SEQ_PORT_CAP_WRITE capabilities,
respectively.
Obviously, these flags have no influence
if \c READ or \c WRITE> capability is not set.

Note that these flags are not necessary if the client subscribes itself
to the specified port.
For example, when a port makes READ subscription
to MIDI input port, this port must have #SND_SEQ_PORT_CAP_WRITE capability,
but no #SND_SEQ_PORT_CAP_SUBS_WRITE capability is required.
Only MIDI input port must have #SND_SEQ_PORT_CAP_SUBS_READ capability.

As default, the connection of ports via the third client is always allowed
if proper read and write (subscription) capabilities are set both to the
source and destination ports.
For prohibiting this behavior, set a capability
#SND_SEQ_PORT_CAP_NO_EXPORT to the port.
If this flag is set, subscription must be done by sender or receiver
client itself.
It is useful to avoid unexpected disconnection.
The ports which won't accept subscription should have this capability
for better security.

\subsection seq_subs_handle Subscription handlers

In ALSA library, subscription is done via
#snd_seq_subscribe_port() function.
It takes the argument of #snd_seq_port_subscribe_t record pointer.
Suppose that you have a client which will receive data from
a MIDI input device.  The source and destination addresses
are like the below;
\code
snd_seq_addr_t sender, dest;
sender.client = MIDI_input_client;
sender.port = MIDI_input_port;
dest.client = my_client;
dest.port = my_port;
\endcode
To set these values as the connection call like this.
\code
snd_seq_port_subscribe_t *subs;
snd_seq_port_subscribe_alloca(&subs);
snd_seq_port_subscribe_set_sender(subs, &sender);
snd_seq_port_subscribe_set_dest(subs, &dest);
snd_seq_subscribe_port(handle, subs);
\endcode

When the connection should be exclusively done only between
a certain pair, set <i>exclusive</i> attribute to the subscription
record before calling #snd_seq_subscribe_port.
\code
snd_seq_port_subscribe_set_exclusive(subs, 1);
\endcode
The succeeding subscriptions will be refused.

The timestamp can be updated independently on each connection.
When set up, the timestamp of incoming queue to the destination port
is updated automatically to the time of the specified queue.
\code
snd_seq_port_subscribe_set_time_update(subs, 1);
snd_seq_port_subscribe_set_queue(subs, q);
\endcode
For getting the wallclock time (sec/nsec pair), set <i>real</i> attribute:
\code
snd_seq_port_subscribe_set_time_real(subs, 1);
\endcode
Otherwise, the timestamp is stored in tick unit.
This feature is useful when receiving events from MIDI input device.
The event time is automatically set in the event record.

Note that an outsider client may connect other ports.
In this case, however, the subscription may be refused
if #SND_SEQ_PORT_CAP_NO_EXPORT capability is set in either sender or receiver port.

\section seq_subs_ex Examples of subscription

\subsection seq_subs_ex_capt Capture from keyboard

Assume MIDI input port = 64:0, application port = 128:0, and
queue for timestamp = 1 with real-time stamp.
The application port must have capability #SND_SEQ_PORT_CAP_WRITE.
\code
void capture_keyboard(snd_seq_t *seq)
{
        snd_seq_addr_t sender, dest;
        snd_seq_port_subscribe_t *subs;
        sender.client = 64;
        sender.port = 0;
        dest.client = 128;
        dest.port = 0;
        snd_seq_port_subscribe_alloca(&subs);
        snd_seq_port_subscribe_set_sender(subs, &sender);
        snd_seq_port_subscribe_set_dest(subs, &dest);
        snd_seq_port_subscribe_set_queue(subs, 1);
        snd_seq_port_subscribe_set_time_update(subs, 1);
        snd_seq_port_subscribe_set_time_real(subs, 1);
        snd_seq_subscribe_port(seq, subs);
}
\endcode

\subsection seq_subs_ex_out Output to MIDI device

Assume MIDI output port = 65:1 and application port = 128:0.
The application port must have capability #SND_SEQ_PORT_CAP_READ.
\code
void subscribe_output(snd_seq_t *seq)
{
        snd_seq_addr_t sender, dest;
        snd_seq_port_subscribe_t *subs;
        sender.client = 128;
        sender.port = 0;
        dest.client = 65;
        dest.port = 1;
        snd_seq_port_subscribe_alloca(&subs);
        snd_seq_port_subscribe_set_sender(subs, &sender);
        snd_seq_port_subscribe_set_dest(subs, &dest);
        snd_seq_subscribe_port(seq, subs);
}
\endcode
This example can be simplified by using #snd_seq_connect_to() function.
\code
void subscribe_output(snd_seq_t *seq)
{
        snd_seq_connect_to(seq, 0, 65, 1);
}
\endcode

\subsection seq_subs_ex_arbit Arbitrary connection

Assume connection from application 128:0 to 129:0,
and that subscription is done by the third application (130:0).
The sender must have capabilities both
#SND_SEQ_PORT_CAP_READ and
#SND_SEQ_PORT_CAP_SUBS_READ,
and the receiver
#SND_SEQ_PORT_CAP_WRITE and
#SND_SEQ_PORT_CAP_SUBS_WRITE, respectively.
\code
// ..in the third application (130:0) ..
void coupling(snd_seq_t *seq)
{
        snd_seq_addr_t sender, dest;
        snd_seq_port_subscribe_t *subs;
        sender.client = 128;
        sender.port = 0;
        dest.client = 129;
        dest.port = 0;
        snd_seq_port_subscribe_alloca(&subs);
        snd_seq_port_subscribe_set_sender(subs, &sender);
        snd_seq_port_subscribe_set_dest(subs, &dest);
        snd_seq_subscribe_port(seq, subs);
}
\endcode

\section seq_ex_event Event Processing

\subsection seq_ex_address Addressing

Now, two ports are connected by subscription.  Then how to send events?

The subscribed port doesn't have to know the exact sender address.
Instead, there is a special address for subscribers,
#SND_SEQ_ADDRESS_SUBSCRIBERS.
The sender must set this value as the destination client.
Destination port is ignored.

The other values in source and destination addresses are identical with
the normal event record.
If the event is scheduled, proper queue and timestamp values must be set.

There is a convenient function to set the address in an event record.
In order to set destination as subscribers, use
#snd_seq_ev_set_subs().

\subsection Scheduled Delivery

If we send an event at the scheduled time <code>t</code> (tick)
on the queue <code>Q</code>,
the sender must set both schedule queue and time in the
event record.
The program appears like this:
\code
void schedule_event(snd_seq_t *seq)
{
        snd_seq_event_t ev;

        snd_seq_ev_clear(&ev);
        snd_seq_ev_set_source(&ev, my_port);
        snd_seq_ev_set_subs(&ev);
        snd_seq_ev_schedule_tick(&ev, Q, 0, t);
        ... // set event type, data, so on..

        snd_seq_event_output(seq, &ev);
        ...
        snd_seq_drain_output(seq);  // if necessary
}
\endcode
Of course, you can use realtime stamp, too.

\subsection seq_ex_direct Direct Delivery

If the event is sent immediately without enqueued, the sender doesn't take
care of queue and timestamp.
As well as the case above, there is a function to set the direct delivery,
#snd_seq_ev_set_direct().
The program can be more simplified as follows:
\code
void direct_delivery(snd_seq_t *seq)
{
        snd_seq_event_t ev;

        snd_seq_ev_clear(&ev);
        snd_seq_ev_set_source(&ev, port);
        snd_seq_ev_set_subs(&ev);
        snd_seq_ev_set_direct(&ev);
        ... // set event type, data, so on..

        snd_seq_event_output(seq, &ev);
        snd_seq_drain_output(seq);
}
\endcode
You should flush event soon after output event.
Otherwise, the event is enqueued on output queue of ALSA library
(not in the kernel!), and will be never processed until
this queue becomes full.

\subsection seq_ex_filter Filter Application

A typical filter program, which receives an event and sends it immediately
after some modification, will appear as following:
\code
void event_filter(snd_seq_t *seq, snd_seq_event_t *ev)
{
        while (snd_seq_event_input(seq, &ev) >= 0) {
                //.. modify input event ..

                snd_seq_ev_set_source(ev, my_port);
                snd_seq_ev_set_subs(ev);
                snd_seq_ev_set_direct(ev);
                snd_seq_event_output(seq, ev);
                snd_seq_drain_output(seq);
        }
}
\endcode

*/

#include <sys/poll.h>
#include "seq_local.h"

/****************************************************************************
 *                                                                          *
 *                                seq.h                                     *
 *                              Sequencer                                   *
 *                                                                          *
 ****************************************************************************/

/**
 * \brief get identifier of sequencer handle
 * \param seq sequencer handle
 * \return ASCII identifier of sequencer handle
 *
 * Returns the ASCII identifier of the given sequencer handle. It's the same
 * identifier specified in snd_seq_open().
 *
 * \sa snd_seq_open()
 */
const char *snd_seq_name(snd_seq_t *seq)
{
	assert(seq);
	return seq->name;
}

/**
 * \brief get type of sequencer handle
 * \param seq sequencer handle
 * \return type of sequencer handle
 *
 * Returns the type #snd_seq_type_t of the given sequencer handle.
 *
 * \sa snd_seq_open()
 */
snd_seq_type_t snd_seq_type(snd_seq_t *seq)
{
	assert(seq);
	return seq->type;
}

static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
			     snd_config_t *seq_root, snd_config_t *seq_conf,
			     int streams, int mode)
{
	const char *str;
	char buf[256];
	int err;
	snd_config_t *conf, *type_conf = NULL;
	snd_config_iterator_t i, next;
	const char *id;
	const char *lib = NULL, *open_name = NULL;
	int (*open_func)(snd_seq_t **, const char *,
			 snd_config_t *, snd_config_t *, 
			 int, int) = NULL;
#ifndef PIC
	extern void *snd_seq_open_symbols(void);
#endif
	void *h = NULL;
	if (snd_config_get_type(seq_conf) != SND_CONFIG_TYPE_COMPOUND) {
		if (name)
			SNDERR("Invalid type for SEQ %s definition", name);
		else
			SNDERR("Invalid type for SEQ definition");
		return -EINVAL;
	}
	err = snd_config_search(seq_conf, "type", &conf);
	if (err < 0) {
		SNDERR("type is not defined");
		return err;
	}
	err = snd_config_get_id(conf, &id);
	if (err < 0) {
		SNDERR("unable to get id");
		return err;
	}
	err = snd_config_get_string(conf, &str);
	if (err < 0) {
		SNDERR("Invalid type for %s", id);
		return err;
	}
	err = snd_config_search_definition(seq_root, "seq_type", str, &type_conf);
	if (err >= 0) {
		if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
			SNDERR("Invalid type for SEQ type %s definition", str);
			goto _err;
		}
		snd_config_for_each(i, next, type_conf) {
			snd_config_t *n = snd_config_iterator_entry(i);
			const char *id;
			if (snd_config_get_id(n, &id) < 0)
				continue;
			if (strcmp(id, "comment") == 0)
				continue;
			if (strcmp(id, "lib") == 0) {
				err = snd_config_get_string(n, &lib);
				if (err < 0) {
					SNDERR("Invalid type for %s", id);
					goto _err;
				}
				continue;
			}
			if (strcmp(id, "open") == 0) {
				err = snd_config_get_string(n, &open_name);
				if (err < 0) {
					SNDERR("Invalid type for %s", id);
					goto _err;
				}
				continue;
			}
			SNDERR("Unknown field %s", id);
			err = -EINVAL;
			goto _err;
		}
	}
	if (!open_name) {
		open_name = buf;
		snprintf(buf, sizeof(buf), "_snd_seq_%s_open", str);
	}
#ifndef PIC
	snd_seq_open_symbols();
#endif
	h = snd_dlopen(lib, RTLD_NOW);
	if (h)
		open_func = snd_dlsym(h, open_name, SND_DLSYM_VERSION(SND_SEQ_DLSYM_VERSION));
	err = 0;
	if (!h) {
		SNDERR("Cannot open shared library %s", lib);
		err = -ENOENT;
	} else if (!open_func) {
		SNDERR("symbol %s is not defined inside %s", open_name, lib);
		snd_dlclose(h);
		err = -ENXIO;
	}
       _err:
	if (type_conf)
		snd_config_delete(type_conf);
	if (! err) {
		err = open_func(seqp, name, seq_root, seq_conf, streams, mode);
		if (err < 0)
			snd_dlclose(h);
		else
			(*seqp)->dl_handle = h;
	}
	return err;
}

static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
				 const char *name, int streams, int mode,
				 int hop)
{
	int err;
	snd_config_t *seq_conf;
	err = snd_config_search_definition(root, "seq", name, &seq_conf);
	if (err < 0) {
		SNDERR("Unknown SEQ %s", name);
		return err;
	}
	snd_config_set_hop(seq_conf, hop);
	err = snd_seq_open_conf(seqp, name, root, seq_conf, streams, mode);
	snd_config_delete(seq_conf);
	return err;
}


/**
 * \brief Open the ALSA sequencer
 *
 * \param seqp Pointer to a snd_seq_t pointer.  This pointer must be
 * kept and passed to most of the other sequencer functions.
 * \param name The sequencer's "name".  This is \em not a name you make
 * up for your own purposes; it has special significance to the ALSA
 * library.  Usually you need to pass \c "default" here.
 * \param streams The read/write mode of the sequencer.  Can be one of
 * three values:
 * - #SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
 * - #SND_SEQ_OPEN_INPUT - open the sequencer for input only
 * - #SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
 * \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
 * \c O_RDWR respectively and used as the second argument to the C library
 * open() call.
 * \param mode Optional modifier.  Can be either 0, or
 * #SND_SEQ_NONBLOCK, which will make read/write operations
 * non-blocking.  This can also be set later using #snd_seq_nonblock().
 * \return 0 on success otherwise a negative error code
 *
 * Creates a new handle and opens a connection to the kernel
 * sequencer interface.
 * After a client is created successfully, an event
 * with #SND_SEQ_EVENT_CLIENT_START is broadcast to announce port.
 *
 * \sa snd_seq_open_lconf(), snd_seq_close(), snd_seq_type(), snd_seq_name(),
 *     snd_seq_nonblock(), snd_seq_client_id()
 */
int snd_seq_open(snd_seq_t **seqp, const char *name, 
		 int streams, int mode)
{
	snd_config_t *top;
	int err;

	assert(seqp && name);
	err = snd_config_update_ref(&top);
	if (err < 0)
		return err;
	err = snd_seq_open_noupdate(seqp, top, name, streams, mode, 0);
	snd_config_unref(top);
	return err;
}

/**
 * \brief Open the ALSA sequencer using local configuration
 *
 * \param seqp Pointer to a snd_seq_t pointer.
 * \param name The name to open
 * \param streams The read/write mode of the sequencer.
 * \param mode Optional modifier
 * \param lconf Local configuration
 * \return 0 on success otherwise a negative error code
 *
 * See the snd_seq_open() function for further details. The extension
 * is that the given configuration is used to resolve abstract name.
 *
 * \sa snd_seq_open()
 */
int snd_seq_open_lconf(snd_seq_t **seqp, const char *name, 
		       int streams, int mode, snd_config_t *lconf)
{
	assert(seqp && name && lconf);
	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, 0);
}

#ifndef DOC_HIDDEN
int _snd_seq_open_lconf(snd_seq_t **seqp, const char *name, 
			int streams, int mode, snd_config_t *lconf,
			snd_config_t *parent_conf)
{
	int hop;
	assert(seqp && name && lconf);
	if ((hop = snd_config_check_hop(parent_conf)) < 0)
		return hop;
	return snd_seq_open_noupdate(seqp, lconf, name, streams, mode, hop + 1);
}
#endif

/**
 * \brief Close the sequencer
 * \param seq Handle returned from #snd_seq_open()
 * \return 0 on success otherwise a negative error code
 *
 * Closes the sequencer client and releases its resources.
 * After a client is closed, an event with
 * #SND_SEQ_EVENT_CLIENT_EXIT is broadcast to announce port.
 * The connection between other clients are disconnected.
 * Call this just before exiting your program.
 *
 * \sa snd_seq_close()
 */
int snd_seq_close(snd_seq_t *seq)
{
	int err;
	assert(seq);
	err = seq->ops->close(seq);
	if (seq->dl_handle)
		snd_dlclose(seq->dl_handle);
	free(seq->obuf);
	free(seq->ibuf);
	free(seq->tmpbuf);
	free(seq->name);
	free(seq);
	return err;
}

/**
 * \brief Returns the number of poll descriptors
 * \param seq sequencer handle
 * \param events the poll events to be checked (\c POLLIN and \c POLLOUT)
 * \return the number of poll descriptors.
 *
 * Get the number of poll descriptors.  The polling events to be checked
 * can be specified by the second argument.  When both input and output
 * are checked, pass \c POLLIN|POLLOUT
 *
 * \sa snd_seq_poll_descriptors()
 */
int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
{
	int result = 0;
	assert(seq);
	if (events & POLLIN) {
		assert(seq->streams & SND_SEQ_OPEN_INPUT);
		result++;
	}
	if (events & POLLOUT) {
		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
		result++;
	}
	return result ? 1 : 0;
}

/**
 * \brief Get poll descriptors
 * \param seq sequencer handle
 * \param pfds array of poll descriptors
 * \param space space in the poll descriptor array
 * \param events polling events to be checked (\c POLLIN and \c POLLOUT)
 * \return count of filled descriptors
 *
 * Get poll descriptors assigned to the sequencer handle.
 * Since a sequencer handle can duplex streams, you need to set which direction(s)
 * is/are polled in \a events argument.  When \c POLLIN bit is specified,
 * the incoming events to the ports are checked.
 *
 * To check the returned poll-events, call #snd_seq_poll_descriptors_revents()
 * instead of reading the pollfd structs directly.
 *
 * \sa snd_seq_poll_descriptors_count(), snd_seq_poll_descriptors_revents()
 */
int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
{
	short revents = 0;

	assert(seq);
	if ((events & POLLIN) && space >= 1) {
		assert(seq->streams & SND_SEQ_OPEN_INPUT);
		revents |= POLLIN|POLLERR|POLLNVAL;
	}
	if ((events & POLLOUT) && space >= 1) {
		assert(seq->streams & SND_SEQ_OPEN_OUTPUT);
		revents |= POLLOUT|POLLERR|POLLNVAL;
	}
	if (!revents)
		return 0;
	pfds->fd = seq->poll_fd;
	pfds->events = revents;
	return 1;
}

/**
 * \brief get returned events from poll descriptors
 * \param seq sequencer handle
 * \param pfds array of poll descriptors
 * \param nfds count of poll descriptors
 * \param revents returned events
 * \return zero if success, otherwise a negative error code
 *
 * \sa snd_seq_poll_descriptors()
 */
int snd_seq_poll_descriptors_revents(snd_seq_t *seq, struct pollfd *pfds, unsigned int nfds, unsigned short *revents)
{
        assert(seq && pfds && revents);
        if (nfds == 1) {
                *revents = pfds->revents;
                return 0;
        }
        return -EINVAL;
}

/**
 * \brief Set nonblock mode
 * \param seq sequencer handle
 * \param nonblock 0 = block, 1 = nonblock mode
 * \return 0 on success otherwise a negative error code
 *
 * Change the blocking mode of the given client.
 * In block mode, the client falls into sleep when it fills the
 * output memory pool with full events.  The client will be woken up
 * after a certain amount of free space becomes available.
 *
 * \sa snd_seq_open()
 */
int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
{
	int err;
	assert(seq);
	err = seq->ops->nonblock(seq, nonblock);
	if (err < 0)
		return err;
	if (nonblock)
		seq->mode |= SND_SEQ_NONBLOCK;
	else
		seq->mode &= ~SND_SEQ_NONBLOCK;
	return 0;
}

/**
 * \brief Get the client id
 * \param seq sequencer handle
 * \return the client id
 *
 * Returns the id of the specified client.
 * If an error occurs, function returns the negative error code.
 * A client id is necessary to inquiry or to set the client information.
 * A user client is assigned from 128 to 191.
 *
 * \sa snd_seq_open()
 */
int snd_seq_client_id(snd_seq_t *seq)
{
	assert(seq);
	return seq->client;
}

/**
 * \brief Return the size of output buffer
 * \param seq sequencer handle
 * \return the size of output buffer in bytes
 *
 * Obtains the size of output buffer.
 * This buffer is used to store decoded byte-stream of output events
 * before transferring to sequencer.
 *
 * \sa snd_seq_set_output_buffer_size()
 */
size_t snd_seq_get_output_buffer_size(snd_seq_t *seq)
{
	assert(seq);
	if (!seq->obuf)
		return 0;
	return seq->obufsize;
}

/**
 * \brief Return the size of input buffer
 * \param seq sequencer handle
 * \return the size of input buffer in bytes
 *
 * Obtains the size of input buffer.
 * This buffer is used to read byte-stream of input events from sequencer.
 *
 * \sa snd_seq_set_input_buffer_size()
 */
size_t snd_seq_get_input_buffer_size(snd_seq_t *seq)
{
	assert(seq);
	if (!seq->ibuf)
		return 0;
	return seq->ibufsize * sizeof(snd_seq_event_t);
}

/**
 * \brief Change the size of output buffer
 * \param seq sequencer handle
 * \param size the size of output buffer to be changed in bytes
 * \return 0 on success otherwise a negative error code
 *
 * Changes the size of output buffer.
 *
 * \sa snd_seq_get_output_buffer_size()
 */
int snd_seq_set_output_buffer_size(snd_seq_t *seq, size_t size)
{
	assert(seq && seq->obuf);
	assert(size >= sizeof(snd_seq_event_t));
	snd_seq_drop_output(seq);
	if (size != seq->obufsize) {
		char *newbuf;
		newbuf = calloc(1, size);
		if (newbuf == NULL)
			return -ENOMEM;
		free(seq->obuf);
		seq->obuf = newbuf;
		seq->obufsize = size;
	}
	return 0;
}

/**
 * \brief Resize the input buffer
 * \param seq sequencer handle
 * \param size the size of input buffer to be changed in bytes
 * \return 0 on success otherwise a negative error code
 *
 * Changes the size of input buffer.
 *
 * \sa snd_seq_get_input_buffer_size()
 */
int snd_seq_set_input_buffer_size(snd_seq_t *seq, size_t size)
{
	assert(seq && seq->ibuf);
	assert(size >= sizeof(snd_seq_event_t));
	snd_seq_drop_input(seq);
	size = (size + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
	if (size != seq->ibufsize) {
		snd_seq_event_t *newbuf;
		newbuf = calloc(sizeof(snd_seq_event_t), size);
		if (newbuf == NULL)
			return -ENOMEM;
		free(seq->ibuf);
		seq->ibuf = newbuf;
		seq->ibufsize = size;
	}
	return 0;
}


/**
 * \brief Get size of #snd_seq_system_info_t
 * \return size in bytes
 */
size_t snd_seq_system_info_sizeof()
{
	return sizeof(snd_seq_system_info_t);
}

/**
 * \brief Allocate an empty #snd_seq_system_info_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_system_info_malloc(snd_seq_system_info_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_system_info_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief Frees a previously allocated #snd_seq_system_info_t
 * \param obj pointer to object to free
 */
void snd_seq_system_info_free(snd_seq_system_info_t *obj)
{
	free(obj);
}

/**
 * \brief Copy one #snd_seq_system_info_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_system_info_copy(snd_seq_system_info_t *dst, const snd_seq_system_info_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get maximum number of queues
 * \param info #snd_seq_system_info_t container
 * \return maximum number of queues
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_queues(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->queues;
}

/**
 * \brief Get maximum number of clients
 * \param info #snd_seq_system_info_t container
 * \return maximum number of clients
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_clients(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->clients;
}

/**
 * \brief Get maximum number of ports
 * \param info #snd_seq_system_info_t container
 * \return maximum number of ports
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_ports(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->ports;
}

/**
 * \brief Get maximum number of channels
 * \param info #snd_seq_system_info_t container
 * \return maximum number of channels
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_channels(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->channels;
}

/**
 * \brief Get the current number of clients
 * \param info #snd_seq_system_info_t container
 * \return current number of clients
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_cur_clients(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->cur_clients;
}

/**
 * \brief Get the current number of queues
 * \param info #snd_seq_system_info_t container
 * \return current number of queues
 *
 * \sa snd_seq_system_info()
 */
int snd_seq_system_info_get_cur_queues(const snd_seq_system_info_t *info)
{
	assert(info);
	return info->cur_queues;
}

/**
 * \brief obtain the sequencer system information
 * \param seq sequencer handle
 * \param info the pointer to be stored
 * \return 0 on success otherwise a negative error code
 *
 * Stores the global system information of ALSA sequencer system.
 * The returned data contains
 * the maximum available numbers of queues, clients, ports and channels.
 */
int snd_seq_system_info(snd_seq_t *seq, snd_seq_system_info_t * info)
{
	assert(seq && info);
	return seq->ops->system_info(seq, info);
}


/*----------------------------------------------------------------*/

/**
 * \brief get size of #snd_seq_client_info_t
 * \return size in bytes
 */
size_t snd_seq_client_info_sizeof()
{
	return sizeof(snd_seq_client_info_t);
}

/**
 * \brief allocate an empty #snd_seq_client_info_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_client_info_malloc(snd_seq_client_info_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_client_info_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_client_info_t
 * \param obj pointer to object to free
 */
void snd_seq_client_info_free(snd_seq_client_info_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_client_info_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_client_info_copy(snd_seq_client_info_t *dst, const snd_seq_client_info_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get client id of a client_info container
 * \param info client_info container
 * \return client id
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_client(), snd_seq_client_id()
 */
int snd_seq_client_info_get_client(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->client;
}

/**
 * \brief Get client type of a client_info container
 * \param info client_info container
 * \return client type
 *
 * The client type is either #SND_SEQ_KERNEL_CLIENT or #SND_SEQ_USER_CLIENT
 * for kernel or user client respectively.
 *
 * \sa snd_seq_get_client_info()
 */
snd_seq_client_type_t snd_seq_client_info_get_type(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->type;
}

/**
 * \brief Get the name of a client_info container
 * \param info client_info container
 * \return name string
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_name()
 */
const char *snd_seq_client_info_get_name(snd_seq_client_info_t *info)
{
	assert(info);
	return info->name;
}

/**
 * \brief Get the broadcast filter usage of a client_info container
 * \param info client_info container
 * \return 1 if broadcast is accepted
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_broadcast_filter()
 */
int snd_seq_client_info_get_broadcast_filter(const snd_seq_client_info_t *info)
{
	assert(info);
	return (info->filter & SNDRV_SEQ_FILTER_BROADCAST) ? 1 : 0;
}

/**
 * \brief Get the error-bounce usage of a client_info container
 * \param info client_info container
 * \return 1 if error-bounce is enabled
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_set_error_bounce()
 */
int snd_seq_client_info_get_error_bounce(const snd_seq_client_info_t *info)
{
	assert(info);
	return (info->filter & SNDRV_SEQ_FILTER_BOUNCE) ? 1 : 0;
}

/**
 * \brief Get the sound card number.
 * \param info client_info container
 * \return card number or -1 if value is not available.
 *
 * Only available for SND_SEQ_KERNEL_CLIENT clients.
 */
int snd_seq_client_info_get_card(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->card;
}

/**
 * \brief Get the owning PID.
 * \param info client_info container
 * \return pid or -1 if value is not available.
 *
 * Only available for SND_SEQ_USER_CLIENT clients.
 */
int snd_seq_client_info_get_pid(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->pid;
}

/**
 * \brief (DEPRECATED) Get the event filter bitmap of a client_info container
 * \param info client_info container
 * \return NULL if no event filter, or pointer to event filter bitmap
 *
 * Use #snd_seq_client_info_event_filter_check() instead.
 *
 * \sa snd_seq_client_info_event_filter_add(),
 *     snd_seq_client_info_event_filter_del(),
 *     snd_seq_client_info_event_filter_check(),
 *     snd_seq_client_info_event_filter_clear(),
 *     snd_seq_get_client_info()
 */
const unsigned char *snd_seq_client_info_get_event_filter(const snd_seq_client_info_t *info)
{
	assert(info);
	if (info->filter & SNDRV_SEQ_FILTER_USE_EVENT)
		return info->event_filter;
	else
		return NULL;
}

/**
 * \brief Disable event filtering of a client_info container
 * \param info client_info container
 *
 * Remove all event types added with #snd_seq_client_info_event_filter_add and clear
 * the event filtering flag of this client_info container.
 * 
 * \sa snd_seq_client_info_event_filter_add(),
 *     snd_seq_client_info_event_filter_del(),
 *     snd_seq_client_info_event_filter_check(),
 *     snd_seq_get_client_info(),
 *     snd_seq_set_client_info()
 */
void snd_seq_client_info_event_filter_clear(snd_seq_client_info_t *info)
{
       assert(info);
       info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
       memset(info->event_filter, 0, sizeof(info->event_filter));
}

/**
 * \brief Add an event type to the event filtering of a client_info container
 * \param info client_info container
 * \param event_type event type to be added
 * 
 * Set the event filtering flag of this client_info and add the specified event type to the 
 * filter bitmap of this client_info container.
 *
 * \sa snd_seq_get_client_info(),
 *     snd_seq_set_client_info(),
 *     snd_seq_client_info_event_filter_del(),
 *     snd_seq_client_info_event_filter_check(),
 *     snd_seq_client_info_event_filter_clear()
 */
void snd_seq_client_info_event_filter_add(snd_seq_client_info_t *info, int event_type)
{
       assert(info);
       info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
       snd_seq_set_bit(event_type, info->event_filter);
}

/**
 * \brief Remove an event type from the event filtering of a client_info container
 * \param info client_info container
 * \param event_type event type to be removed
 *
 * Removes the specified event from the filter bitmap of this client_info container. It will
 * not clear the event filtering flag, use #snd_seq_client_info_event_filter_clear instead.
 *
 * \sa snd_seq_get_client_info(),
 *     snd_seq_set_client_info(),
 *     snd_seq_client_info_event_filter_add(),
 *     snd_seq_client_info_event_filter_check(),
 *     snd_seq_client_info_event_filter_clear()
 */
void snd_seq_client_info_event_filter_del(snd_seq_client_info_t *info, int event_type)
{
       assert(info);
       snd_seq_unset_bit(event_type, info->event_filter);
}

/**
 * \brief Check if an event type is present in the event filtering of a client_info container
 * \param info client_info container
 * \param event_type event type to be checked
 * \return 1 if the event type is present, 0 otherwise
 *
 * Test if the event type is in the filter bitmap of this client_info container.
 *
 * \sa snd_seq_get_client_info(),
 *     snd_seq_set_client_info(),
 *     snd_seq_client_info_event_filter_add(),
 *     snd_seq_client_info_event_filter_del(),
 *     snd_seq_client_info_event_filter_clear()
 */
int snd_seq_client_info_event_filter_check(snd_seq_client_info_t *info, int event_type)
{
       assert(info);
       return snd_seq_get_bit(event_type, info->event_filter);
} 

/**
 * \brief Get the number of opened ports of a client_info container
 * \param info client_info container
 * \return number of opened ports
 *
 * \sa snd_seq_get_client_info()
 */
int snd_seq_client_info_get_num_ports(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->num_ports;
}

/**
 * \brief Get the number of lost events of a client_info container
 * \param info client_info container
 * \return number of lost events
 *
 * \sa snd_seq_get_client_info()
 */
int snd_seq_client_info_get_event_lost(const snd_seq_client_info_t *info)
{
	assert(info);
	return info->event_lost;
}

/**
 * \brief Set the client id of a client_info container
 * \param info client_info container
 * \param client client id
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_client()
 */
void snd_seq_client_info_set_client(snd_seq_client_info_t *info, int client)
{
	assert(info);
	info->client = client;
}

/**
 * \brief Set the name of a client_info container
 * \param info client_info container
 * \param name name string
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_name(),
 *     snd_seq_set_client_name()
 */
void snd_seq_client_info_set_name(snd_seq_client_info_t *info, const char *name)
{
	assert(info && name);
	strncpy(info->name, name, sizeof(info->name));
}

/**
 * \brief Set the broadcast filter usage of a client_info container
 * \param info client_info container
 * \param val non-zero if broadcast is accepted
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_broadcast_filter()
 */
void snd_seq_client_info_set_broadcast_filter(snd_seq_client_info_t *info, int val)
{
	assert(info);
	if (val)
		info->filter |= SNDRV_SEQ_FILTER_BROADCAST;
	else
		info->filter &= ~SNDRV_SEQ_FILTER_BROADCAST;
}

/**
 * \brief Set the error-bounce usage of a client_info container
 * \param info client_info container
 * \param val non-zero if error is bounced
 *
 * \sa snd_seq_get_client_info(), snd_seq_client_info_get_error_bounce()
 */
void snd_seq_client_info_set_error_bounce(snd_seq_client_info_t *info, int val)
{
	assert(info);
	if (val)
		info->filter |= SNDRV_SEQ_FILTER_BOUNCE;
	else
		info->filter &= ~SNDRV_SEQ_FILTER_BOUNCE;
}

/**
 * \brief (DEPRECATED) Set the event filter bitmap of a client_info container
 * \param info client_info container
 * \param filter event filter bitmap, pass NULL for no event filtering
 *
 * Use #snd_seq_client_info_event_filter_add instead.
 *
 * \sa snd_seq_client_info_event_filter_add(),
 *     snd_seq_client_info_event_filter_del(),
 *     snd_seq_client_info_event_filter_check(),
 *     snd_seq_client_info_event_filter_clear(),
 *     snd_seq_set_client_info()
 */
void snd_seq_client_info_set_event_filter(snd_seq_client_info_t *info, unsigned char *filter)
{
	assert(info);
	if (! filter)
		info->filter &= ~SNDRV_SEQ_FILTER_USE_EVENT;
	else {
		info->filter |= SNDRV_SEQ_FILTER_USE_EVENT;
		memcpy(info->event_filter, filter, sizeof(info->event_filter));
	}
}


/**
 * \brief obtain the information of the given client
 * \param seq sequencer handle
 * \param client client id
 * \param info the pointer to be stored
 * \return 0 on success otherwise a negative error code
 * 
 * Obtains the information of the client with a client id specified by
 * info argument.
 * The obtained information is written on info parameter.
 *
 * \sa snd_seq_get_client_info()
 */
int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t *info)
{
	assert(seq && info && client >= 0);
	memset(info, 0, sizeof(snd_seq_client_info_t));
	info->client = client;
	return seq->ops->get_client_info(seq, info);
}

/**
 * \brief obtain the current client information
 * \param seq sequencer handle
 * \param info the pointer to be stored
 * \return 0 on success otherwise a negative error code
 *
 * Obtains the information of the current client stored on info.
 * client and type fields are ignored.
 *
 * \sa snd_seq_get_any_client_info(), snd_seq_set_client_info(),
 *     snd_seq_query_next_client()
 */
int snd_seq_get_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
{
	return snd_seq_get_any_client_info(seq, seq->client, info);
}

/**
 * \brief set the current client information
 * \param seq sequencer handle
 * \param info the client info data to set
 * \return 0 on success otherwise a negative error code
 *
 * Obtains the information of the current client stored on info.
 * client and type fields are ignored.
 *
 * \sa snd_seq_get_client_info()
 */
int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t *info)
{
	assert(seq && info);
	info->client = seq->client;
	info->type = USER_CLIENT;
	return seq->ops->set_client_info(seq, info);
}

/**
 * \brief query the next client
 * \param seq sequencer handle
 * \param info query pattern and result
 *
 * Queries the next client.
 * The search begins at the client with an id one greater than
 * client field in info.
 * If a client is found, its attributes are stored in info,
 * and zero is returned.
 * Otherwise returns a negative error code.
 *
 * \sa snd_seq_get_any_client_info()
 */
int snd_seq_query_next_client(snd_seq_t *seq, snd_seq_client_info_t *info)
{
	assert(seq && info);
	return seq->ops->query_next_client(seq, info);
}


/*----------------------------------------------------------------*/


/*
 * Port
 */

/**
 * \brief get size of #snd_seq_port_info_t
 * \return size in bytes
 */
size_t snd_seq_port_info_sizeof()
{
	return sizeof(snd_seq_port_info_t);
}

/**
 * \brief allocate an empty #snd_seq_port_info_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_port_info_malloc(snd_seq_port_info_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_port_info_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_port_info_t
 * \param obj pointer to object to free
 */
void snd_seq_port_info_free(snd_seq_port_info_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_port_info_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_port_info_copy(snd_seq_port_info_t *dst, const snd_seq_port_info_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get client id of a port_info container
 * \param info port_info container
 * \return client id
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_client()
 */
int snd_seq_port_info_get_client(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->addr.client;
}

/**
 * \brief Get port id of a port_info container
 * \param info port_info container
 * \return port id
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port()
 */
int snd_seq_port_info_get_port(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->addr.port;
}

/**
 * \brief Get client/port address of a port_info container
 * \param info port_info container
 * \return client/port address pointer
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_addr()
 */
const snd_seq_addr_t *snd_seq_port_info_get_addr(const snd_seq_port_info_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *) &info->addr;
}

/**
 * \brief Get the name of a port_info container
 * \param info port_info container
 * \return name string
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_name()
 */
const char *snd_seq_port_info_get_name(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->name;
}

/**
 * \brief Get the capability bits of a port_info container
 * \param info port_info container
 * \return capability bits
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_capability()
 */
unsigned int snd_seq_port_info_get_capability(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->capability;
}

/**
 * \brief Get the type bits of a port_info container
 * \param info port_info container
 * \return port type bits
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_type()
 */
unsigned int snd_seq_port_info_get_type(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->type;
}

/**
 * \brief Get the number of read subscriptions of a port_info container
 * \param info port_info container
 * \return number of read subscriptions
 *
 * \sa snd_seq_get_port_info()
 */
int snd_seq_port_info_get_read_use(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->read_use;
}

/**
 * \brief Get the number of write subscriptions of a port_info container
 * \param info port_info container
 * \return number of write subscriptions
 *
 * \sa snd_seq_get_port_info()
 */
int snd_seq_port_info_get_write_use(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->write_use;
}

/**
 * \brief Get the midi channels of a port_info container
 * \param info port_info container
 * \return number of midi channels (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_channels()
 */
int snd_seq_port_info_get_midi_channels(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->midi_channels;
}

/**
 * \brief Get the midi voices of a port_info container
 * \param info port_info container
 * \return number of midi voices (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_midi_voices()
 */
int snd_seq_port_info_get_midi_voices(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->midi_voices;
}

/**
 * \brief Get the synth voices of a port_info container
 * \param info port_info container
 * \return number of synth voices (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_synth_voices()
 */
int snd_seq_port_info_get_synth_voices(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->synth_voices;
}

/**
 * \brief Get the port-specified mode of a port_info container
 * \param info port_info container
 * \return 1 if port id is specified at creation
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_port_specified()
 */
int snd_seq_port_info_get_port_specified(const snd_seq_port_info_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_FLG_GIVEN_PORT) ? 1 : 0;
}

/**
 * \brief Get the time-stamping mode of the given port in a port_info container
 * \param info port_info container
 * \return 1 if the port updates timestamps of incoming events
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamping()
 */
int snd_seq_port_info_get_timestamping(const snd_seq_port_info_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_FLG_TIMESTAMP) ? 1 : 0;
}

/**
 * \brief Get whether the time-stamping of the given port is real-time mode
 * \param info port_info container
 * \return 1 if the time-stamping is in the real-time mode
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_real()
 */
int snd_seq_port_info_get_timestamp_real(const snd_seq_port_info_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_FLG_TIME_REAL) ? 1 : 0;
}

/**
 * \brief Get the queue id to update timestamps
 * \param info port_info container
 * \return the queue id to get the timestamps
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_set_timestamp_queue()
 */
int snd_seq_port_info_get_timestamp_queue(const snd_seq_port_info_t *info)
{
	assert(info);
	return info->time_queue;
}

/**
 * \brief Set the client id of a port_info container
 * \param info port_info container
 * \param client client id
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_client()
 */
void snd_seq_port_info_set_client(snd_seq_port_info_t *info, int client)
{
	assert(info);
	info->addr.client = client;
}

/**
 * \brief Set the port id of a port_info container
 * \param info port_info container
 * \param port port id
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port()
 */
void snd_seq_port_info_set_port(snd_seq_port_info_t *info, int port)
{
	assert(info);
	info->addr.port = port;
}

/**
 * \brief Set the client/port address of a port_info container
 * \param info port_info container
 * \param addr client/port address
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_addr()
 */
void snd_seq_port_info_set_addr(snd_seq_port_info_t *info, const snd_seq_addr_t *addr)
{
	assert(info);
	info->addr = *(const struct sndrv_seq_addr *)addr;
}

/**
 * \brief Set the name of a port_info container
 * \param info port_info container
 * \param name name string
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_name()
 */
void snd_seq_port_info_set_name(snd_seq_port_info_t *info, const char *name)
{
	assert(info && name);
	strncpy(info->name, name, sizeof(info->name));
}

/**
 * \brief set the capability bits of a port_info container
 * \param info port_info container
 * \param capability capability bits
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_capability()
 */
void snd_seq_port_info_set_capability(snd_seq_port_info_t *info, unsigned int capability)
{
	assert(info);
	info->capability = capability;
}

/**
 * \brief Get the type bits of a port_info container
 * \param info port_info container
 * \param type port type bits
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_type()
 */
void snd_seq_port_info_set_type(snd_seq_port_info_t *info, unsigned int type)
{
	assert(info);
	info->type = type;
}

/**
 * \brief set the midi channels of a port_info container
 * \param info port_info container
 * \param channels midi channels (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_channels()
 */
void snd_seq_port_info_set_midi_channels(snd_seq_port_info_t *info, int channels)
{
	assert(info);
	info->midi_channels = channels;
}

/**
 * \brief set the midi voices of a port_info container
 * \param info port_info container
 * \param voices midi voices (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_midi_voices()
 */
void snd_seq_port_info_set_midi_voices(snd_seq_port_info_t *info, int voices)
{
	assert(info);
	info->midi_voices = voices;
}

/**
 * \brief set the synth voices of a port_info container
 * \param info port_info container
 * \param voices synth voices (default 0)
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_synth_voice()
 */
void snd_seq_port_info_set_synth_voices(snd_seq_port_info_t *info, int voices)
{
	assert(info);
	info->synth_voices = voices;
}

/**
 * \brief Set the port-specified mode of a port_info container
 * \param info port_info container
 * \param val non-zero if specifying the port id at creation
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_port_specified()
 */
void snd_seq_port_info_set_port_specified(snd_seq_port_info_t *info, int val)
{
	assert(info);
	if (val)
		info->flags |= SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
	else
		info->flags &= ~SNDRV_SEQ_PORT_FLG_GIVEN_PORT;
}

/**
 * \brief Set the time-stamping mode of the given port
 * \param info port_info container
 * \param enable non-zero if updating the timestamps of incoming events
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamping()
 */
void snd_seq_port_info_set_timestamping(snd_seq_port_info_t *info, int enable)
{
	assert(info);
	if (enable)
		info->flags |= SNDRV_SEQ_PORT_FLG_TIMESTAMP;
	else
		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIMESTAMP;
}

/**
 * \brief Set whether the timestime is updated in the real-time mode
 * \param info port_info container
 * \param enable non-zero if updating the timestamps in real-time mode
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_real()
 */
void snd_seq_port_info_set_timestamp_real(snd_seq_port_info_t *info, int enable)
{
	assert(info);
	if (enable)
		info->flags |= SNDRV_SEQ_PORT_FLG_TIME_REAL;
	else
		info->flags &= ~SNDRV_SEQ_PORT_FLG_TIME_REAL;
}

/**
 * \brief Set the queue id for timestamping
 * \param info port_info container
 * \param queue the queue id to get timestamps
 *
 * \sa snd_seq_get_port_info(), snd_seq_port_info_get_timestamp_queue()
 */
void snd_seq_port_info_set_timestamp_queue(snd_seq_port_info_t *info, int queue)
{
	assert(info);
	info->time_queue = queue;
}


/**
 * \brief create a sequencer port on the current client
 * \param seq sequencer handle
 * \param port port information for the new port
 * \return 0 on success otherwise a negative error code
 *
 * Creates a sequencer port on the current client.
 * The attributes of created port is specified in \a info argument.
 *
 * The client field in \a info argument is overwritten with the current client id.
 * The port id to be created can be specified via #snd_seq_port_info_set_port_specified.
 * You can get the created port id by reading the port pointer via #snd_seq_port_info_get_port.
 *
 * Each port has the capability bit-masks to specify the access capability
 * of the port from other clients.
 * The capability bit flags are defined as follows:
 * - #SND_SEQ_PORT_CAP_READ Readable from this port
 * - #SND_SEQ_PORT_CAP_WRITE Writable to this port.
 * - #SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
 * - #SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
 * - #SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
 * - #SND_SEQ_PORT_CAP_SUBS_READ Read subscription is allowed
 * - #SND_SEQ_PORT_CAP_SUBS_WRITE Write subscription is allowed
 * - #SND_SEQ_PORT_CAP_NO_EXPORT Subscription management from 3rd client is disallowed
 *
 * Each port has also the type bitmasks defined as follows:
 * - #SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
 * - #SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
 * - #SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
 * - #SND_SEQ_PORT_TYPE_MIDI_GM2 General MIDI 2 compatible device
 * - #SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
 * - #SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
 * - #SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
 * - #SND_SEQ_PORT_TYPE_HARDWARE Implemented in hardware
 * - #SND_SEQ_PORT_TYPE_SOFTWARE Implemented in software
 * - #SND_SEQ_PORT_TYPE_SYNTHESIZER Generates sound
 * - #SND_SEQ_PORT_TYPE_PORT Connects to other device(s)
 * - #SND_SEQ_PORT_TYPE_APPLICATION Application (sequencer/editor)
 *
 * A port may contain specific midi channels, midi voices and synth voices.
 * These values could be zero as default.
 *
 * \sa snd_seq_delete_port(), snd_seq_get_port_info(),
 *     snd_seq_create_simple_port()
 */
int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
{
	assert(seq && port);
	port->addr.client = seq->client;
	return seq->ops->create_port(seq, port);
}

/**
 * \brief delete a sequencer port on the current client
 * \param seq sequencer handle
 * \param port port to be deleted
 * \return 0 on success otherwise a negative error code
 *
 * Deletes the existing sequencer port on the current client.
 *
 * \sa snd_seq_create_port(), snd_seq_delete_simple_port()
 */
int snd_seq_delete_port(snd_seq_t *seq, int port)
{
	snd_seq_port_info_t pinfo;
	assert(seq);
	memset(&pinfo, 0, sizeof(pinfo));
	pinfo.addr.client = seq->client;
	pinfo.addr.port = port;
	return seq->ops->delete_port(seq, &pinfo);
}

/**
 * \brief obtain the information of a port on an arbitrary client
 * \param seq sequencer handle
 * \param client client id to get
 * \param port port id to get
 * \param info pointer information returns
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_get_port_info()
 */
int snd_seq_get_any_port_info(snd_seq_t *seq, int client, int port, snd_seq_port_info_t * info)
{
	assert(seq && info && client >= 0 && port >= 0);
	memset(info, 0, sizeof(snd_seq_port_info_t));
	info->addr.client = client;
	info->addr.port = port;
	return seq->ops->get_port_info(seq, info);
}

/**
 * \brief obtain the information of a port on the current client
 * \param seq sequencer handle
 * \param port port id to get
 * \param info pointer information returns
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_create_port(), snd_seq_get_any_port_info(), snd_seq_set_port_info(),
 *     snd_seq_query_next_port()
 */
int snd_seq_get_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
{
	return snd_seq_get_any_port_info(seq, seq->client, port, info);
}

/**
 * \brief set the information of a port on the current client
 * \param seq sequencer handle
 * \param port port to be set
 * \param info port information to be set
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_set_port_info()
 */
int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
{
	assert(seq && info && port >= 0);
	info->addr.client = seq->client;
	info->addr.port = port;
	return seq->ops->set_port_info(seq, info);
}

/**
 * \brief query the next matching port
 * \param seq sequencer handle
 * \param info query pattern and result

 * Queries the next matching port on the client specified in
 * \a info argument.
 * The search begins at the next port specified in
 * port field of \a info argument.
 * For finding the first port at a certain client, give -1.
 *
 * If a matching port is found, its attributes are stored on
 * \a info and function returns zero.
 * Otherwise, a negative error code is returned.
 *
 * \sa snd_seq_get_port_info()
 */
int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
{
	assert(seq && info);
	return seq->ops->query_next_port(seq, info);
}


/*----------------------------------------------------------------*/

/*
 * subscription
 */


/**
 * \brief get size of #snd_seq_port_subscribe_t
 * \return size in bytes
 */
size_t snd_seq_port_subscribe_sizeof()
{
	return sizeof(snd_seq_port_subscribe_t);
}

/**
 * \brief allocate an empty #snd_seq_port_subscribe_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_port_subscribe_malloc(snd_seq_port_subscribe_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_port_subscribe_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_port_subscribe_t
 * \param obj pointer to object to free
 */
void snd_seq_port_subscribe_free(snd_seq_port_subscribe_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_port_subscribe_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_port_subscribe_copy(snd_seq_port_subscribe_t *dst, const snd_seq_port_subscribe_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get sender address of a port_subscribe container
 * \param info port_subscribe container
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_sender()
 */
const snd_seq_addr_t *snd_seq_port_subscribe_get_sender(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *)&info->sender;
}

/**
 * \brief Get destination address of a port_subscribe container
 * \param info port_subscribe container
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_dest()
 */
const snd_seq_addr_t *snd_seq_port_subscribe_get_dest(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *)&info->dest;
}

/**
 * \brief Get the queue id of a port_subscribe container
 * \param info port_subscribe container
 * \return queue id
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_queue()
 */
int snd_seq_port_subscribe_get_queue(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the exclusive mode of a port_subscribe container
 * \param info port_subscribe container
 * \return 1 if exclusive mode
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_exclusive()
 */
int snd_seq_port_subscribe_get_exclusive(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
}

/**
 * \brief Get the time-update mode of a port_subscribe container
 * \param info port_subscribe container
 * \return 1 if update timestamp
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_update()
 */
int snd_seq_port_subscribe_get_time_update(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
}

/**
 * \brief Get the real-time update mode of a port_subscribe container
 * \param info port_subscribe container
 * \return 1 if real-time update mode
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_set_time_real()
 */
int snd_seq_port_subscribe_get_time_real(const snd_seq_port_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIME_REAL) ? 1 : 0;
}

/**
 * \brief Set sender address of a port_subscribe container
 * \param info port_subscribe container
 * \param addr sender address
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_sender()
 */
void snd_seq_port_subscribe_set_sender(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
{
	assert(info);
	memcpy(&info->sender, addr, sizeof(*addr));
}
      
/**
 * \brief Set destination address of a port_subscribe container
 * \param info port_subscribe container
 * \param addr destination address
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_dest()
 */
void snd_seq_port_subscribe_set_dest(snd_seq_port_subscribe_t *info, const snd_seq_addr_t *addr)
{
	assert(info);
	memcpy(&info->dest, addr, sizeof(*addr));
}

/**
 * \brief Set the queue id of a port_subscribe container
 * \param info port_subscribe container
 * \param q queue id
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_queue()
 */
void snd_seq_port_subscribe_set_queue(snd_seq_port_subscribe_t *info, int q)
{
	assert(info);
	info->queue = q;
}

/**
 * \brief Set the exclusive mode of a port_subscribe container
 * \param info port_subscribe container
 * \param val non-zero to enable
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_exclusive()
 */
void snd_seq_port_subscribe_set_exclusive(snd_seq_port_subscribe_t *info, int val)
{
	assert(info);
	if (val)
		info->flags |= SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
	else
		info->flags &= ~SNDRV_SEQ_PORT_SUBS_EXCLUSIVE;
}

/**
 * \brief Set the time-update mode of a port_subscribe container
 * \param info port_subscribe container
 * \param val non-zero to enable
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_update()
 */
void snd_seq_port_subscribe_set_time_update(snd_seq_port_subscribe_t *info, int val)
{
	assert(info);
	if (val)
		info->flags |= SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
	else
		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIMESTAMP;
}

/**
 * \brief Set the real-time mode of a port_subscribe container
 * \param info port_subscribe container
 * \param val non-zero to enable
 *
 * \sa snd_seq_subscribe_port(), snd_seq_port_subscribe_get_time_real()
 */
void snd_seq_port_subscribe_set_time_real(snd_seq_port_subscribe_t *info, int val)
{
	assert(info);
	if (val)
		info->flags |= SNDRV_SEQ_PORT_SUBS_TIME_REAL;
	else
		info->flags &= ~SNDRV_SEQ_PORT_SUBS_TIME_REAL;
}


/**
 * \brief obtain subscription information
 * \param seq sequencer handle
 * \param sub pointer to return the subscription information
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_subscribe_port(), snd_seq_query_port_subscribers()
 */
int snd_seq_get_port_subscription(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
{
	assert(seq && sub);
	return seq->ops->get_port_subscription(seq, sub);
}

/**
 * \brief subscribe a port connection
 * \param seq sequencer handle
 * \param sub subscription information
 * \return 0 on success otherwise a negative error code
 *
 * Subscribes a connection between two ports.
 * The subscription information is stored in sub argument.
 *
 * \sa snd_seq_get_port_subscription(), snd_seq_unsubscribe_port(),
 *     snd_seq_connect_from(), snd_seq_connect_to()
 */
int snd_seq_subscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
{
	assert(seq && sub);
	return seq->ops->subscribe_port(seq, sub);
}

/**
 * \brief unsubscribe a connection between ports
 * \param seq sequencer handle
 * \param sub subscription information to disconnect
 * \return 0 on success otherwise a negative error code
 *
 * Unsubscribes a connection between two ports,
 * described in sender and dest fields in sub argument.
 *
 * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from(), snd_seq_disconnect_to()
 */
int snd_seq_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t * sub)
{
	assert(seq && sub);
	return seq->ops->unsubscribe_port(seq, sub);
}


/**
 * \brief get size of #snd_seq_query_subscribe_t
 * \return size in bytes
 */
size_t snd_seq_query_subscribe_sizeof()
{
	return sizeof(snd_seq_query_subscribe_t);
}

/**
 * \brief allocate an empty #snd_seq_query_subscribe_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_query_subscribe_malloc(snd_seq_query_subscribe_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_query_subscribe_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_query_subscribe_t
 * \param obj pointer to object to free
 */
void snd_seq_query_subscribe_free(snd_seq_query_subscribe_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_query_subscribe_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_query_subscribe_copy(snd_seq_query_subscribe_t *dst, const snd_seq_query_subscribe_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the client id of a query_subscribe container
 * \param info query_subscribe container
 * \return client id
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_client()
 */
int snd_seq_query_subscribe_get_client(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->root.client;
}

/**
 * \brief Get the port id of a query_subscribe container
 * \param info query_subscribe container
 * \return port id
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_port()
 */
int snd_seq_query_subscribe_get_port(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->root.port;
}

/**
 * \brief Get the client/port address of a query_subscribe container
 * \param info query_subscribe container
 * \return client/port address pointer
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_root()
 */
const snd_seq_addr_t *snd_seq_query_subscribe_get_root(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *)&info->root;
}

/**
 * \brief Get the query type of a query_subscribe container
 * \param info query_subscribe container
 * \return query type
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_type()
 */
snd_seq_query_subs_type_t snd_seq_query_subscribe_get_type(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->type;
}

/**
 * \brief Get the index of subscriber of a query_subscribe container
 * \param info query_subscribe container
 * \return subscriber's index
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_set_index()
 */
int snd_seq_query_subscribe_get_index(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->index;
}

/**
 * \brief Get the number of subscriptions of a query_subscribe container
 * \param info query_subscribe container
 * \return number of subscriptions
 *
 * \sa snd_seq_query_port_subscribers()
 */
int snd_seq_query_subscribe_get_num_subs(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->num_subs;
}	

/**
 * \brief Get the address of subscriber of a query_subscribe container
 * \param info query_subscribe container
 * \return subscriber's address pointer
 *
 * \sa snd_seq_query_port_subscribers()
 */
const snd_seq_addr_t *snd_seq_query_subscribe_get_addr(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *)&info->addr;
}

/**
 * \brief Get the queue id of subscriber of a query_subscribe container
 * \param info query_subscribe container
 * \return subscriber's queue id
 *
 * \sa snd_seq_query_port_subscribers()
 */
int snd_seq_query_subscribe_get_queue(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the exclusive mode of a query_subscribe container
 * \param info query_subscribe container
 * \return 1 if exclusive mode
 *
 * \sa snd_seq_query_port_subscribers()
 */
int snd_seq_query_subscribe_get_exclusive(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_EXCLUSIVE) ? 1 : 0;
}

/**
 * \brief Get the time-update mode of a query_subscribe container
 * \param info query_subscribe container
 * \return 1 if update timestamp
 *
 * \sa snd_seq_query_port_subscribers()
 */
int snd_seq_query_subscribe_get_time_update(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
}

/**
 * \brief Get the real-time update mode of a query_subscribe container
 * \param info query_subscribe container
 * \return 1 if real-time update mode
 *
 * \sa snd_seq_query_port_subscribers()
 */
int snd_seq_query_subscribe_get_time_real(const snd_seq_query_subscribe_t *info)
{
	assert(info);
	return (info->flags & SNDRV_SEQ_PORT_SUBS_TIMESTAMP) ? 1 : 0;
}

/**
 * \brief Set the client id of a query_subscribe container
 * \param info query_subscribe container
 * \param client client id
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_client()
 */
void snd_seq_query_subscribe_set_client(snd_seq_query_subscribe_t *info, int client)
{
	assert(info);
	info->root.client = client;
}

/**
 * \brief Set the port id of a query_subscribe container
 * \param info query_subscribe container
 * \param port port id
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_port()
 */
void snd_seq_query_subscribe_set_port(snd_seq_query_subscribe_t *info, int port)
{
	assert(info);
	info->root.port = port;
}

/**
 * \brief Set the client/port address of a query_subscribe container
 * \param info query_subscribe container
 * \param addr client/port address pointer
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_root()
 */
void snd_seq_query_subscribe_set_root(snd_seq_query_subscribe_t *info, const snd_seq_addr_t *addr)
{
	assert(info);
	info->root = *(const struct snd_seq_addr *)addr;
}

/**
 * \brief Set the query type of a query_subscribe container
 * \param info query_subscribe container
 * \param type query type
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_type()
 */
void snd_seq_query_subscribe_set_type(snd_seq_query_subscribe_t *info, snd_seq_query_subs_type_t type)
{
	assert(info);
	info->type = type;
}

/**
 * \brief Set the subscriber's index to be queried
 * \param info query_subscribe container
 * \param index index to be queried
 *
 * \sa snd_seq_query_port_subscribers(), snd_seq_query_subscribe_get_index()
 */
void snd_seq_query_subscribe_set_index(snd_seq_query_subscribe_t *info, int index)
{
	assert(info);
	info->index = index;
}


/**
 * \brief query port subscriber list
 * \param seq sequencer handle
 * \param subs subscription to query
 * \return 0 on success otherwise a negative error code
 *
 * Queries the subscribers accessing to a port.
 * The query information is specified in subs argument.
 *
 * At least, the client id, the port id, the index number and
 * the query type must be set to perform a proper query.
 * As the query type, #SND_SEQ_QUERY_SUBS_READ or #SND_SEQ_QUERY_SUBS_WRITE
 * can be specified to check whether the readers or the writers to the port.
 * To query the first subscription, set 0 to the index number.  To list up
 * all the subscriptions, call this function with the index numbers from 0
 * until this returns a negative value.
 *
 * \sa snd_seq_get_port_subscription()
 */
int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
{
	assert(seq && subs);
	return seq->ops->query_port_subscribers(seq, subs);
}

/*----------------------------------------------------------------*/

/*
 * queue handlers
 */

/**
 * \brief get size of #snd_seq_queue_info_t
 * \return size in bytes
 */
size_t snd_seq_queue_info_sizeof()
{
	return sizeof(snd_seq_queue_info_t);
}

/**
 * \brief allocate an empty #snd_seq_queue_info_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_queue_info_malloc(snd_seq_queue_info_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_queue_info_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_queue_info_t
 * \param obj pointer to object to free
 */
void snd_seq_queue_info_free(snd_seq_queue_info_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_queue_info_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_queue_info_copy(snd_seq_queue_info_t *dst, const snd_seq_queue_info_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the queue id of a queue_info container
 * \param info queue_info container
 * \return queue id
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_queue()
 */
int snd_seq_queue_info_get_queue(const snd_seq_queue_info_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the name of a queue_info container
 * \param info queue_info container
 * \return name string
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_name()
 */
const char *snd_seq_queue_info_get_name(const snd_seq_queue_info_t *info)
{
	assert(info);
	return info->name;
}

/**
 * \brief Get the owner client id of a queue_info container
 * \param info queue_info container
 * \return owner client id
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_owner()
 */
int snd_seq_queue_info_get_owner(const snd_seq_queue_info_t *info)
{
	assert(info);
	return info->owner;
}

/**
 * \brief Get the lock status of a queue_info container
 * \param info queue_info container
 * \return lock status --- non-zero = locked
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_locked()
 */
int snd_seq_queue_info_get_locked(const snd_seq_queue_info_t *info)
{
	assert(info);
	return info->locked;
}

/**
 * \brief Get the conditional bit flags of a queue_info container
 * \param info queue_info container
 * \return conditional bit flags
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_set_flags()
 */
unsigned int snd_seq_queue_info_get_flags(const snd_seq_queue_info_t *info)
{
	assert(info);
	return info->flags;
}

/**
 * \brief Set the name of a queue_info container
 * \param info queue_info container
 * \param name name string
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_name()
 */
void snd_seq_queue_info_set_name(snd_seq_queue_info_t *info, const char *name)
{
	assert(info && name);
	strncpy(info->name, name, sizeof(info->name));
}

/**
 * \brief Set the owner client id of a queue_info container
 * \param info queue_info container
 * \param owner client id
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_owner()
 */
void snd_seq_queue_info_set_owner(snd_seq_queue_info_t *info, int owner)
{
	assert(info);
	info->owner = owner;
}

/**
 * \brief Set the lock status of a queue_info container
 * \param info queue_info container
 * \param locked lock status
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_locked()
 */
void snd_seq_queue_info_set_locked(snd_seq_queue_info_t *info, int locked)
{
	assert(info);
	info->locked = locked;
}

/**
 * \brief Set the conditional bit flags of a queue_info container
 * \param info queue_info container
 * \param flags conditional bit flags
 *
 * \sa snd_seq_get_queue_info(), snd_seq_queue_info_get_flags()
 */
void snd_seq_queue_info_set_flags(snd_seq_queue_info_t *info, unsigned int flags)
{
	assert(info);
	info->flags = flags;
}


/**
 * \brief create a queue
 * \param seq sequencer handle
 * \param info queue information to initialize
 * \return the queue id (zero or positive) on success otherwise a negative error code
 *
 * \sa snd_seq_alloc_queue()
 */
int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
{
	int err;
	assert(seq && info);
	info->owner = seq->client;
	err = seq->ops->create_queue(seq, info);
	if (err < 0)
		return err;
	return info->queue;
}

/**
 * \brief allocate a queue with the specified name
 * \param seq sequencer handle
 * \param name the name of the new queue
 * \return the queue id (zero or positive) on success otherwise a negative error code
 *
 * \sa snd_seq_alloc_queue()
 */ 
int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
{
	snd_seq_queue_info_t info;
	memset(&info, 0, sizeof(info));
	info.locked = 1;
	if (name)
		strncpy(info.name, name, sizeof(info.name) - 1);
	return snd_seq_create_queue(seq, &info);
}

/**
 * \brief allocate a queue
 * \param seq sequencer handle
 * \return the queue id (zero or positive) on success otherwise a negative error code
 *
 * \sa snd_seq_alloc_named_queue(), snd_seq_create_queue(), snd_seq_free_queue(),
 *     snd_seq_get_queue_info()
 */ 
int snd_seq_alloc_queue(snd_seq_t *seq)
{
	return snd_seq_alloc_named_queue(seq, NULL);
}

/**
 * \brief delete the specified queue
 * \param seq sequencer handle
 * \param q queue id to delete
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_alloc_queue()
 */
int snd_seq_free_queue(snd_seq_t *seq, int q)
{
	snd_seq_queue_info_t info;
	assert(seq);
	memset(&info, 0, sizeof(info));
	info.queue = q;
	return seq->ops->delete_queue(seq, &info);
}

/**
 * \brief obtain queue attributes
 * \param seq sequencer handle
 * \param q queue id to query
 * \param info information returned
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_alloc_queue(), snd_seq_set_queue_info(), snd_seq_query_named_queue()
 */
int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
{
	assert(seq && info);
	info->queue = q;
	return seq->ops->get_queue_info(seq, info);
}

/**
 * \brief change the queue attributes
 * \param seq sequencer handle
 * \param q queue id to change
 * \param info information changed
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_get_queue_info()
 */
int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
{
	assert(seq && info);
	info->queue = q;
	return seq->ops->set_queue_info(seq, info);
}

/**
 * \brief query the matching queue with the specified name
 * \param seq sequencer handle
 * \param name the name string to query
 * \return the queue id if found or negative error code
 *
 * Searches the matching queue with the specified name string.
 *
 * \sa snd_seq_get_queue_info()
 */
int snd_seq_query_named_queue(snd_seq_t *seq, const char *name)
{
	int err;
	snd_seq_queue_info_t info;
	assert(seq && name);
	strncpy(info.name, name, sizeof(info.name));
	err = seq->ops->get_named_queue(seq, &info);
	if (err < 0)
		return err;
	return info.queue;
}

/**
 * \brief Get the queue usage flag to the client
 * \param seq sequencer handle
 * \param q queue id
 * \return 1 = client is allowed to access the queue, 0 = not allowed, 
 *     otherwise a negative error code
 *
 * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
 */
int snd_seq_get_queue_usage(snd_seq_t *seq, int q)
{
	struct snd_seq_queue_client info;
	int err;
	assert(seq);
	memset(&info, 0, sizeof(info));
	info.queue = q;
	info.client = seq->client;
	if ((err = seq->ops->get_queue_client(seq, &info)) < 0)
		return err;
	return info.used;
}

/**
 * \brief Set the queue usage flag to the client
 * \param seq sequencer handle
 * \param q queue id
 * \param used non-zero if the client is allowed
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_get_queue_info(), snd_seq_set_queue_usage()
 */
int snd_seq_set_queue_usage(snd_seq_t *seq, int q, int used)
{
	struct snd_seq_queue_client info;
	assert(seq);
	memset(&info, 0, sizeof(info));
	info.queue = q;
	info.client = seq->client;
	info.used = used ? 1 : 0;
	return seq->ops->set_queue_client(seq, &info);
}


/**
 * \brief get size of #snd_seq_queue_status_t
 * \return size in bytes
 */
size_t snd_seq_queue_status_sizeof()
{
	return sizeof(snd_seq_queue_status_t);
}

/**
 * \brief allocate an empty #snd_seq_queue_status_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_queue_status_malloc(snd_seq_queue_status_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_queue_status_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_queue_status_t
 * \param obj pointer to object to free
 */
void snd_seq_queue_status_free(snd_seq_queue_status_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_queue_status_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_queue_status_copy(snd_seq_queue_status_t *dst, const snd_seq_queue_status_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the queue id of a queue_status container
 * \param info queue_status container
 * \return queue id
 *
 * \sa snd_seq_get_queue_status()
 */
int snd_seq_queue_status_get_queue(const snd_seq_queue_status_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the number of events of a queue_status container
 * \param info queue_status container
 * \return number of events
 *
 * \sa snd_seq_get_queue_status()
 */
int snd_seq_queue_status_get_events(const snd_seq_queue_status_t *info)
{
	assert(info);
	return info->events;
}

/**
 * \brief Get the tick time of a queue_status container
 * \param info queue_status container
 * \return tick time
 *
 * \sa snd_seq_get_queue_status()
 */
snd_seq_tick_time_t snd_seq_queue_status_get_tick_time(const snd_seq_queue_status_t *info)
{
	assert(info);
	return info->tick;
}

/**
 * \brief Get the real time of a queue_status container
 * \param info queue_status container
 *
 * \sa snd_seq_get_queue_status()
 */
const snd_seq_real_time_t *snd_seq_queue_status_get_real_time(const snd_seq_queue_status_t *info)
{
	assert(info);
	return (const snd_seq_real_time_t *)&info->time;
}

/**
 * \brief Get the running status bits of a queue_status container
 * \param info queue_status container
 * \return running status bits
 *
 * \sa snd_seq_get_queue_status()
 */
unsigned int snd_seq_queue_status_get_status(const snd_seq_queue_status_t *info)
{
	assert(info);
	return info->running;
}


/**
 * \brief obtain the running state of the queue
 * \param seq sequencer handle
 * \param q queue id to query
 * \param status pointer to store the current status
 * \return 0 on success otherwise a negative error code
 *
 * Obtains the running state of the specified queue q.
 */
int snd_seq_get_queue_status(snd_seq_t *seq, int q, snd_seq_queue_status_t * status)
{
	assert(seq && status);
	memset(status, 0, sizeof(snd_seq_queue_status_t));
	status->queue = q;
	return seq->ops->get_queue_status(seq, status);
}


/**
 * \brief get size of #snd_seq_queue_tempo_t
 * \return size in bytes
 */
size_t snd_seq_queue_tempo_sizeof()
{
	return sizeof(snd_seq_queue_tempo_t);
}

/**
 * \brief allocate an empty #snd_seq_queue_tempo_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_queue_tempo_malloc(snd_seq_queue_tempo_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_queue_tempo_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_queue_tempo_t
 * \param obj pointer to object to free
 */
void snd_seq_queue_tempo_free(snd_seq_queue_tempo_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_queue_tempo_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_queue_tempo_copy(snd_seq_queue_tempo_t *dst, const snd_seq_queue_tempo_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the queue id of a queue_status container
 * \param info queue_status container
 * \return queue id
 *
 * \sa snd_seq_get_queue_tempo()
 */
int snd_seq_queue_tempo_get_queue(const snd_seq_queue_tempo_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the tempo of a queue_status container
 * \param info queue_status container
 * \return tempo value
 *
 * \sa snd_seq_get_queue_tempo()
 */
unsigned int snd_seq_queue_tempo_get_tempo(const snd_seq_queue_tempo_t *info)
{
	assert(info);
	return info->tempo;
}

/**
 * \brief Get the ppq of a queue_status container
 * \param info queue_status container
 * \return ppq value
 *
 * \sa snd_seq_get_queue_tempo()
 */
int snd_seq_queue_tempo_get_ppq(const snd_seq_queue_tempo_t *info)
{
	assert(info);
	return info->ppq;
}

/**
 * \brief Get the timer skew value of a queue_status container
 * \param info queue_status container
 * \return timer skew value
 *
 * \sa snd_seq_get_queue_tempo()
 */
unsigned int snd_seq_queue_tempo_get_skew(const snd_seq_queue_tempo_t *info)
{
	assert(info);
	return info->skew_value;
}

/**
 * \brief Get the timer skew base value of a queue_status container
 * \param info queue_status container
 * \return timer skew base value
 *
 * \sa snd_seq_get_queue_tempo()
 */
unsigned int snd_seq_queue_tempo_get_skew_base(const snd_seq_queue_tempo_t *info)
{
	assert(info);
	return info->skew_base;
}

/**
 * \brief Set the tempo of a queue_status container
 * \param info queue_status container
 * \param tempo tempo value
 *
 * \sa snd_seq_get_queue_tempo()
 */
void snd_seq_queue_tempo_set_tempo(snd_seq_queue_tempo_t *info, unsigned int tempo)
{
	assert(info);
	info->tempo = tempo;
}

/**
 * \brief Set the ppq of a queue_status container
 * \param info queue_status container
 * \param ppq ppq value
 *
 * \sa snd_seq_get_queue_tempo()
 */
void snd_seq_queue_tempo_set_ppq(snd_seq_queue_tempo_t *info, int ppq)
{
	assert(info);
	info->ppq = ppq;
}

/**
 * \brief Set the timer skew value of a queue_status container
 * \param info queue_status container
 * \param skew timer skew value
 *
 * The skew of timer is calculated as skew / base.
 * For example, to play with double speed, pass base * 2 as the skew value.
 *
 * \sa snd_seq_get_queue_tempo()
 */
void snd_seq_queue_tempo_set_skew(snd_seq_queue_tempo_t *info, unsigned int skew)
{
	assert(info);
	info->skew_value = skew;
}

/**
 * \brief Set the timer skew base value of a queue_status container
 * \param info queue_status container
 * \param base timer skew base value
 *
 * \sa snd_seq_get_queue_tempo()
 */
void snd_seq_queue_tempo_set_skew_base(snd_seq_queue_tempo_t *info, unsigned int base)
{
	assert(info);
	info->skew_base = base;
}

/**
 * \brief obtain the current tempo of the queue
 * \param seq sequencer handle
 * \param q queue id to be queried
 * \param tempo pointer to store the current tempo
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_set_queue_tempo()
 */
int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
	assert(seq && tempo);
	memset(tempo, 0, sizeof(snd_seq_queue_tempo_t));
	tempo->queue = q;
	return seq->ops->get_queue_tempo(seq, tempo);
}

/**
 * \brief set the tempo of the queue
 * \param seq sequencer handle
 * \param q queue id to change the tempo
 * \param tempo tempo information
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_get_queue_tempo()
 */
int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
	assert(seq && tempo);
	tempo->queue = q;
	return seq->ops->set_queue_tempo(seq, tempo);
}


/*----------------------------------------------------------------*/

/**
 * \brief get size of #snd_seq_queue_timer_t
 * \return size in bytes
 */
size_t snd_seq_queue_timer_sizeof()
{
	return sizeof(snd_seq_queue_timer_t);
}

/**
 * \brief allocate an empty #snd_seq_queue_timer_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_queue_timer_malloc(snd_seq_queue_timer_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_queue_timer_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_queue_timer_t
 * \param obj pointer to object to free
 */
void snd_seq_queue_timer_free(snd_seq_queue_timer_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_queue_timer_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_queue_timer_copy(snd_seq_queue_timer_t *dst, const snd_seq_queue_timer_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the queue id of a queue_timer container
 * \param info queue_timer container
 * \return queue id
 *
 * \sa snd_seq_get_queue_timer()
 */
int snd_seq_queue_timer_get_queue(const snd_seq_queue_timer_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the timer type of a queue_timer container
 * \param info queue_timer container
 * \return timer type
 *
 * \sa snd_seq_get_queue_timer()
 */
snd_seq_queue_timer_type_t snd_seq_queue_timer_get_type(const snd_seq_queue_timer_t *info)
{
	assert(info);
	return (snd_seq_queue_timer_type_t)info->type;
}

/**
 * \brief Get the timer id of a queue_timer container
 * \param info queue_timer container
 * \return timer id pointer
 *
 * \sa snd_seq_get_queue_timer()
 */
const snd_timer_id_t *snd_seq_queue_timer_get_id(const snd_seq_queue_timer_t *info)
{
	assert(info);
	return &info->u.alsa.id;
}

/**
 * \brief Get the timer resolution of a queue_timer container
 * \param info queue_timer container
 * \return timer resolution
 *
 * \sa snd_seq_get_queue_timer()
 */
unsigned int snd_seq_queue_timer_get_resolution(const snd_seq_queue_timer_t *info)
{
	assert(info);
	return info->u.alsa.resolution;
}

/**
 * \brief Set the timer type of a queue_timer container
 * \param info queue_timer container
 * \param type timer type
 *
 * \sa snd_seq_get_queue_timer()
 */
void snd_seq_queue_timer_set_type(snd_seq_queue_timer_t *info, snd_seq_queue_timer_type_t type)
{
	assert(info);
	info->type = (int)type;
}
	
/**
 * \brief Set the timer id of a queue_timer container
 * \param info queue_timer container
 * \param id timer id pointer
 *
 * \sa snd_seq_get_queue_timer()
 */
void snd_seq_queue_timer_set_id(snd_seq_queue_timer_t *info, const snd_timer_id_t *id)
{
	assert(info && id);
	info->u.alsa.id = *id;
}

/**
 * \brief Set the timer resolution of a queue_timer container
 * \param info queue_timer container
 * \param resolution timer resolution
 *
 * \sa snd_seq_get_queue_timer()
 */
void snd_seq_queue_timer_set_resolution(snd_seq_queue_timer_t *info, unsigned int resolution)
{
	assert(info);
	info->u.alsa.resolution = resolution;
}


/**
 * \brief obtain the queue timer information
 * \param seq sequencer handle
 * \param q queue id to query
 * \param timer pointer to store the timer information
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_set_queue_timer()
 */
int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
{
	assert(seq && timer);
	memset(timer, 0, sizeof(snd_seq_queue_timer_t));
	timer->queue = q;
	return seq->ops->get_queue_timer(seq, timer);
}

/**
 * \brief set the queue timer information
 * \param seq sequencer handle
 * \param q queue id to change the timer
 * \param timer timer information
 * \return 0 on success otherwise a negative error code
 *
 * \sa snd_seq_get_queue_timer()
 */
int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
{
	assert(seq && timer);
	timer->queue = q;
	return seq->ops->set_queue_timer(seq, timer);
}

/*----------------------------------------------------------------*/

#ifndef DOC_HIDDEN
/**
 * \brief (DEPRECATED) create an event cell
 * \return the cell pointer allocated
 *
 * create an event cell via malloc.  the returned pointer must be released
 * by the application itself via normal free() call,
 * not via snd_seq_free_event().
 */
snd_seq_event_t *snd_seq_create_event(void)
{
	return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
}
#endif

/**
 * \brief (DEPRECATED) free an event
 *
 * In the former version, this function was used to
 * release the event pointer which was allocated by snd_seq_event_input().
 * In the current version, the event record is not allocated, so
 * you don't have to call this function any more.
 */
#ifndef DOXYGEN
int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
#else
int snd_seq_free_event(snd_seq_event_t *ev)
#endif
{
	return 0;
}

/**
 * \brief calculates the (encoded) byte-stream size of the event
 * \param ev the event
 * \return the size of decoded bytes
 */
ssize_t snd_seq_event_length(snd_seq_event_t *ev)
{
	ssize_t len = sizeof(snd_seq_event_t);
	assert(ev);
	if (snd_seq_ev_is_variable(ev))
		len += ev->data.ext.len;
	return len;
}

/*----------------------------------------------------------------*/

/*
 * output to sequencer
 */

/**
 * \brief output an event
 * \param seq sequencer handle
 * \param ev event to be output
 * \return the number of remaining events or a negative error code
 *
 * An event is once expanded on the output buffer.
 * The output buffer will be drained automatically if it becomes full.
 *
 * If events remain unprocessed on output buffer before drained,
 * the size of total byte data on output buffer is returned.
 * If the output buffer is empty, this returns zero.
 *
 * \sa snd_seq_event_output_direct(), snd_seq_event_output_buffer(),
 *    snd_seq_event_output_pending(), snd_seq_drain_output(),
 *    snd_seq_drop_output(), snd_seq_extract_output(),
 *    snd_seq_remove_events()
 */
int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
{
	int result;

	result = snd_seq_event_output_buffer(seq, ev);
	if (result == -EAGAIN) {
		result = snd_seq_drain_output(seq);
		if (result < 0)
			return result;
		return snd_seq_event_output_buffer(seq, ev);
	}
	return result;
}

/**
 * \brief output an event onto the lib buffer without draining buffer
 * \param seq sequencer handle
 * \param ev event to be output
 * \return the byte size of remaining events. \c -EAGAIN if the buffer becomes full.
 *
 * This function doesn't drain buffer unlike snd_seq_event_output().
 *
 * \sa snd_seq_event_output()
 */
int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
{
	int len;
	assert(seq && ev);
	len = snd_seq_event_length(ev);
	if (len < 0)
		return -EINVAL;
	if ((size_t) len >= seq->obufsize)
		return -EINVAL;
	if ((seq->obufsize - seq->obufused) < (size_t) len)
		return -EAGAIN;
	memcpy(seq->obuf + seq->obufused, ev, sizeof(snd_seq_event_t));
	seq->obufused += sizeof(snd_seq_event_t);
	if (snd_seq_ev_is_variable(ev)) {
		memcpy(seq->obuf + seq->obufused, ev->data.ext.ptr, ev->data.ext.len);
		seq->obufused += ev->data.ext.len;
	}
	return seq->obufused;
}

/*
 * allocate the temporary buffer
 */
static int alloc_tmpbuf(snd_seq_t *seq, size_t len)
{
	size_t size = ((len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t));
	if (seq->tmpbuf == NULL) {
		if (size > DEFAULT_TMPBUF_SIZE)
			seq->tmpbufsize = size;
		else
			seq->tmpbufsize = DEFAULT_TMPBUF_SIZE;
		seq->tmpbuf = malloc(seq->tmpbufsize * sizeof(snd_seq_event_t));
		if (seq->tmpbuf == NULL)
			return -ENOMEM;
	}  else if (len > seq->tmpbufsize) {
		seq->tmpbuf = realloc(seq->tmpbuf, size * sizeof(snd_seq_event_t));
		if (seq->tmpbuf == NULL)
			return -ENOMEM;
		seq->tmpbufsize = size;
	}
	return 0;
}

/**
 * \brief output an event directly to the sequencer NOT through output buffer
 * \param seq sequencer handle
 * \param ev event to be output
 * \return the byte size sent to sequencer or a negative error code
 *
 * This function sends an event to the sequencer directly not through the
 * output buffer.  When the event is a variable length event, a temporary
 * buffer is allocated inside alsa-lib and the data is copied there before
 * actually sent.
 *
 * \sa snd_seq_event_output()
 */
int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
{
	ssize_t len;
	void *buf;

	len = snd_seq_event_length(ev);
	if (len < 0)
		return len;
	else if (len == sizeof(*ev)) {
		buf = ev;
	} else {
		if (alloc_tmpbuf(seq, (size_t)len) < 0)
			return -ENOMEM;
		*seq->tmpbuf = *ev;
		memcpy(seq->tmpbuf + 1, ev->data.ext.ptr, ev->data.ext.len);
		buf = seq->tmpbuf;
	}
	return seq->ops->write(seq, buf, (size_t) len);
}

/**
 * \brief return the size of pending events on output buffer
 * \param seq sequencer handle
 * \return the byte size of total of pending events
 *
 * \sa snd_seq_event_output()
 */
int snd_seq_event_output_pending(snd_seq_t *seq)
{
	assert(seq);
	return seq->obufused;
}

/**
 * \brief drain output buffer to sequencer
 * \param seq sequencer handle
 * \return 0 when all events are drained and sent to sequencer.
 *         When events still remain on the buffer, the byte size of remaining
 *         events are returned.  On error a negative error code is returned.
 *
 * This function drains all pending events on the output buffer.
 * The function returns immediately after the events are sent to the queues
 * regardless whether the events are processed or not.
 * To get synchronization with the all event processes, use
 * #snd_seq_sync_output_queue() after calling this function.
 *
 * \sa snd_seq_event_output(), snd_seq_sync_output_queue()
 */
int snd_seq_drain_output(snd_seq_t *seq)
{
	ssize_t result, processed = 0;
	assert(seq);
	while (seq->obufused > 0) {
		result = seq->ops->write(seq, seq->obuf, seq->obufused);
		if (result < 0) {
			if (result == -EAGAIN && processed)
				return seq->obufused;
			return result;
		}
		if ((size_t)result < seq->obufused)
			memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
		seq->obufused -= result;
	}
	return 0;
}

/**
 * \brief extract the first event in output buffer
 * \param seq sequencer handle
 * \param ev_res event pointer to be extracted
 * \return 0 on success otherwise a negative error code
 *
 * Extracts the first event in output buffer.
 * If ev_res is NULL, just remove the event.
 *
 * \sa snd_seq_event_output()
 */
int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
{
	size_t len, olen;
	snd_seq_event_t ev;
	assert(seq);
	if (ev_res)
		*ev_res = NULL;
	if ((olen = seq->obufused) < sizeof(snd_seq_event_t))
		return -ENOENT;
	memcpy(&ev, seq->obuf, sizeof(snd_seq_event_t));
	len = snd_seq_event_length(&ev);
	if (ev_res) {
		/* extract the event */
		if (alloc_tmpbuf(seq, len) < 0)
			return -ENOMEM;
		memcpy(seq->tmpbuf, seq->obuf, len);
		*ev_res = seq->tmpbuf;
	}
	seq->obufused = olen - len;
	memmove(seq->obuf, seq->obuf + len, seq->obufused);
	return 0;
}

/*----------------------------------------------------------------*/

/*
 * input from sequencer
 */

/*
 * read from sequencer to input buffer
 */
static ssize_t snd_seq_event_read_buffer(snd_seq_t *seq)
{
	ssize_t len;
	len = (seq->ops->read)(seq, seq->ibuf, seq->ibufsize * sizeof(snd_seq_event_t));
	if (len < 0)
		return len;
	seq->ibuflen = len / sizeof(snd_seq_event_t);
	seq->ibufptr = 0;
	return seq->ibuflen;
}

static int snd_seq_event_retrieve_buffer(snd_seq_t *seq, snd_seq_event_t **retp)
{
	size_t ncells;
	snd_seq_event_t *ev;

	*retp = ev = &seq->ibuf[seq->ibufptr];
	seq->ibufptr++;
	seq->ibuflen--;
	if (! snd_seq_ev_is_variable(ev))
		return 1;
	ncells = (ev->data.ext.len + sizeof(snd_seq_event_t) - 1) / sizeof(snd_seq_event_t);
	if (seq->ibuflen < ncells) {
		seq->ibuflen = 0; /* clear buffer */
		*retp = NULL;
		return -EINVAL;
	}
	ev->data.ext.ptr = ev + 1;
	seq->ibuflen -= ncells;
	seq->ibufptr += ncells;
	return 1;
}

/**
 * \brief retrieve an event from sequencer
 * \param seq sequencer handle
 * \param ev event pointer to be stored
 * \return 
 *
 * Obtains an input event from sequencer.
 * The event is created via snd_seq_create_event(), and its pointer is stored on
 * ev argument.
 *
 * This function firstly receives the event byte-stream data from sequencer
 * as much as possible at once.  Then it retrieves the first event record
 * and store the pointer on ev.
 * By calling this function sequentially, events are extracted from the input buffer.
 *
 * If there is no input from sequencer, function falls into sleep
 * in blocking mode until an event is received,
 * or returns \c -EAGAIN error in non-blocking mode.
 * Occasionally, this function may return \c -ENOSPC error.
 * This means that the input FIFO of sequencer overran, and some events are
 * lost.
 * Once this error is returned, the input FIFO is cleared automatically.
 *
 * Function returns the byte size of remaining events on the input buffer
 * if an event is successfully received.
 * Application can determine from the returned value whether to call
 * input once more or not.
 *
 * \sa snd_seq_event_input_pending(), snd_seq_drop_input()
 */
int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
{
	int err;
	assert(seq);
	*ev = NULL;
	if (seq->ibuflen <= 0) {
		if ((err = snd_seq_event_read_buffer(seq)) < 0)
			return err;
	}

	return snd_seq_event_retrieve_buffer(seq, ev);
}

/*
 * read input data from sequencer if available
 */
static int snd_seq_event_input_feed(snd_seq_t *seq, int timeout)
{
	struct pollfd pfd;
	int err;
	pfd.fd = seq->poll_fd;
	pfd.events = POLLIN;
	err = poll(&pfd, 1, timeout);
	if (err < 0) {
		SYSERR("poll");
		return -errno;
	}
	if (pfd.revents & POLLIN) 
		return snd_seq_event_read_buffer(seq);
	return seq->ibuflen;
}

/**
 * \brief check events in input buffer
 * \return the byte size of remaining input events on input buffer.
 *
 * If events remain on the input buffer of user-space, function returns
 * the total byte size of events on it.
 * If fetch_sequencer argument is non-zero,
 * this function checks the presence of events on sequencer FIFO
 * When events exist, they are transferred to the input buffer,
 * and the number of received events are returned.
 * If fetch_sequencer argument is zero and
 * no events remain on the input buffer, function simply returns zero.
 *
 * \sa snd_seq_event_input()
 */
int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
{
	if (seq->ibuflen == 0 && fetch_sequencer) {
		return snd_seq_event_input_feed(seq, 0);
	}
	return seq->ibuflen;
}

/*----------------------------------------------------------------*/

/*
 * clear event buffers
 */

/**
 * \brief remove all events on user-space output buffer
 * \param seq sequencer handle
 *
 * Removes all events on user-space output buffer.
 * Unlike snd_seq_drain_output(), this function doesn't remove
 * events on output memory pool of sequencer.
 *
 * \sa snd_seq_drop_output()
 */
int snd_seq_drop_output_buffer(snd_seq_t *seq)
{
	assert(seq);
	seq->obufused = 0;
	return 0;
}

/**
 * \brief remove all events on user-space input FIFO
 * \param seq sequencer handle
 *
 * \sa snd_seq_drop_input()
 */
int snd_seq_drop_input_buffer(snd_seq_t *seq)
{
	assert(seq);
	seq->ibufptr = 0;
	seq->ibuflen = 0;
	return 0;
}

/**
 * \brief remove all events on output buffer
 * \param seq sequencer handle
 *
 * Removes all events on both user-space output buffer and
 * output memory pool on kernel.
 *
 * \sa snd_seq_drain_output(), snd_seq_drop_output_buffer(), snd_seq_remove_events()
 */
int snd_seq_drop_output(snd_seq_t *seq)
{
	snd_seq_remove_events_t rminfo;
	assert(seq);

	memset(&rminfo, 0, sizeof(rminfo));
	rminfo.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT;

	return snd_seq_remove_events(seq, &rminfo);
}

/**
 * \brief clear input buffer and and remove events in sequencer queue
 * \param seq sequencer handle
 *
 * \sa snd_seq_drop_input_buffer(), snd_seq_remove_events()
 */
int snd_seq_drop_input(snd_seq_t *seq)
{
	snd_seq_remove_events_t rminfo;
	assert(seq);

	memset(&rminfo, 0, sizeof(rminfo));
	rminfo.remove_mode = SNDRV_SEQ_REMOVE_INPUT;

	return snd_seq_remove_events(seq, &rminfo);
}


/**
 * \brief get size of #snd_seq_remove_events_t
 * \return size in bytes
 */
size_t snd_seq_remove_events_sizeof()
{
	return sizeof(snd_seq_remove_events_t);
}

/**
 * \brief allocate an empty #snd_seq_remove_events_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_remove_events_malloc(snd_seq_remove_events_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_remove_events_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_remove_events_t
 * \param obj pointer to object to free
 */
void snd_seq_remove_events_free(snd_seq_remove_events_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_remove_events_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_remove_events_copy(snd_seq_remove_events_t *dst, const snd_seq_remove_events_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the removal condition bits
 * \param info remove_events container
 * \return removal condition bits
 *
 * \sa snd_seq_remove_events()
 */
unsigned int snd_seq_remove_events_get_condition(const snd_seq_remove_events_t *info)
{
	assert(info);
	return info->remove_mode;
}

/**
 * \brief Get the queue as removal condition
 * \param info remove_events container
 * \return queue id
 *
 * \sa snd_seq_remove_events()
 */
int snd_seq_remove_events_get_queue(const snd_seq_remove_events_t *info)
{
	assert(info);
	return info->queue;
}

/**
 * \brief Get the event timestamp as removal condition
 * \param info remove_events container
 * \return time stamp
 *
 * \sa snd_seq_remove_events()
 */
const snd_seq_timestamp_t *snd_seq_remove_events_get_time(const snd_seq_remove_events_t *info)
{
	assert(info);
	return (const snd_seq_timestamp_t *)&info->time;
}

/**
 * \brief Get the event destination address as removal condition
 * \param info remove_events container
 * \return destination address
 *
 * \sa snd_seq_remove_events()
 */
const snd_seq_addr_t *snd_seq_remove_events_get_dest(const snd_seq_remove_events_t *info)
{
	assert(info);
	return (const snd_seq_addr_t *)&info->dest;
}

/**
 * \brief Get the event channel as removal condition
 * \param info remove_events container
 * \return channel number
 *
 * \sa snd_seq_remove_events()
 */
int snd_seq_remove_events_get_channel(const snd_seq_remove_events_t *info)
{
	assert(info);
	return info->channel;
}

/**
 * \brief Get the event type as removal condition
 * \param info remove_events container
 * \return event type
 *
 * \sa snd_seq_remove_events()
 */
int snd_seq_remove_events_get_event_type(const snd_seq_remove_events_t *info)
{
	assert(info);
	return info->type;
}

/**
 * \brief Get the event tag id as removal condition
 * \param info remove_events container
 * \return tag id
 *
 * \sa snd_seq_remove_events()
 */
int snd_seq_remove_events_get_tag(const snd_seq_remove_events_t *info)
{
	assert(info);
	return info->tag;
}

/**
 * \brief Set the removal condition bits
 * \param info remove_events container
 * \param flags removal condition bits
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_condition(snd_seq_remove_events_t *info, unsigned int flags)
{
	assert(info);
	info->remove_mode = flags;
}

/**
 * \brief Set the queue as removal condition
 * \param info remove_events container
 * \param queue queue id
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_queue(snd_seq_remove_events_t *info, int queue)
{
	assert(info);
	info->queue = queue;
}

/**
 * \brief Set the timestamp as removal condition
 * \param info remove_events container
 * \param time timestamp pointer
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_time(snd_seq_remove_events_t *info, const snd_seq_timestamp_t *time)
{
	assert(info);
	info->time = *(const union sndrv_seq_timestamp *)time;
}

/**
 * \brief Set the destination address as removal condition
 * \param info remove_events container
 * \param addr destination address
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_dest(snd_seq_remove_events_t *info, const snd_seq_addr_t *addr)
{
	assert(info);
	info->dest = *(const struct sndrv_seq_addr *)addr;
}

/**
 * \brief Set the channel as removal condition
 * \param info remove_events container
 * \param channel channel number
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_channel(snd_seq_remove_events_t *info, int channel)
{
	assert(info);
	info->channel = channel;
}

/**
 * \brief Set the event type as removal condition
 * \param info remove_events container
 * \param type event type
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_event_type(snd_seq_remove_events_t *info, int type)
{
	assert(info);
	info->type = type;
}

/**
 * \brief Set the event tag as removal condition
 * \param info remove_events container
 * \param tag tag id
 *
 * \sa snd_seq_remove_events()
 */
void snd_seq_remove_events_set_tag(snd_seq_remove_events_t *info, int tag)
{
	assert(info);
	info->tag = tag;
}


/* compare timestamp between events */
/* return 1 if a >= b; otherwise return 0 */
static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a, snd_seq_tick_time_t *b)
{
	/* compare ticks */
	return (*a >= *b);
}

static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a, snd_seq_real_time_t *b)
{
	/* compare real time */
	if (a->tv_sec > b->tv_sec)
		return 1;
	if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
		return 1;
	return 0;
}

/* Routine to match events to be removed */
static int remove_match(snd_seq_remove_events_t *info, snd_seq_event_t *ev)
{
	int res;

	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST) {
		if (ev->dest.client != info->dest.client ||
				ev->dest.port != info->dest.port)
			return 0;
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_DEST_CHANNEL) {
		if (! snd_seq_ev_is_channel_type(ev))
			return 0;
		/* data.note.channel and data.control.channel are identical */
		if (ev->data.note.channel != info->channel)
			return 0;
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_AFTER) {
		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
		else
			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
		if (!res)
			return 0;
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_BEFORE) {
		if (info->remove_mode & SNDRV_SEQ_REMOVE_TIME_TICK)
			res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
		else
			res = snd_seq_compare_real_time(&ev->time.time, (snd_seq_real_time_t *)&info->time.time);
		if (res)
			return 0;
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_EVENT_TYPE) {
		if (ev->type != info->type)
			return 0;
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_IGNORE_OFF) {
		/* Do not remove off events */
		switch (ev->type) {
		case SND_SEQ_EVENT_NOTEOFF:
		/* case SND_SEQ_EVENT_SAMPLE_STOP: */
			return 0;
		default:
			break;
		}
	}
	if (info->remove_mode & SNDRV_SEQ_REMOVE_TAG_MATCH) {
		if (info->tag != ev->tag)
			return 0;
	}

	return 1;
}

/**
 * \brief remove events on input/output buffers and pools
 * \param seq sequencer handle
 * \param rmp remove event container
 *
 * Removes matching events with the given condition from input/output buffers
 * and pools.
 * The removal condition is specified in \a rmp argument.
 *
 * \sa snd_seq_event_output(), snd_seq_drop_output(), snd_seq_reset_pool_output()
 */
int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
{
	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_INPUT) {
		/*
		 * First deal with any events that are still buffered
		 * in the library.
		 */
		snd_seq_drop_input_buffer(seq);
	}

	if (rmp->remove_mode & SNDRV_SEQ_REMOVE_OUTPUT) {
		/*
		 * First deal with any events that are still buffered
		 * in the library.
		 */
		 if (! (rmp->remove_mode & ~(SNDRV_SEQ_REMOVE_INPUT|SNDRV_SEQ_REMOVE_OUTPUT))) {
			 /* The simple case - remove all */
			 snd_seq_drop_output_buffer(seq);
		} else {
			char *ep;
			size_t len;
			snd_seq_event_t *ev;

			ep = seq->obuf;
			while (ep - seq->obuf < (ssize_t)seq->obufused) {

				ev = (snd_seq_event_t *)ep;
				len = snd_seq_event_length(ev);

				if (remove_match(rmp, ev)) {
					/* Remove event */
					seq->obufused -= len;
					memmove(ep, ep + len, seq->obufused - (ep - seq->obuf));
				} else {
					ep += len;
				}
			}
		}
	}

	return seq->ops->remove_events(seq, rmp);
}

/*----------------------------------------------------------------*/

/*
 * client memory pool
 */

/**
 * \brief get size of #snd_seq_client_pool_t
 * \return size in bytes
 */
size_t snd_seq_client_pool_sizeof()
{
	return sizeof(snd_seq_client_pool_t);
}

/**
 * \brief allocate an empty #snd_seq_client_pool_t using standard malloc
 * \param ptr returned pointer
 * \return 0 on success otherwise negative error code
 */
int snd_seq_client_pool_malloc(snd_seq_client_pool_t **ptr)
{
	assert(ptr);
	*ptr = calloc(1, sizeof(snd_seq_client_pool_t));
	if (!*ptr)
		return -ENOMEM;
	return 0;
}

/**
 * \brief frees a previously allocated #snd_seq_client_pool_t
 * \param obj pointer to object to free
 */
void snd_seq_client_pool_free(snd_seq_client_pool_t *obj)
{
	free(obj);
}

/**
 * \brief copy one #snd_seq_client_pool_t to another
 * \param dst pointer to destination
 * \param src pointer to source
 */
void snd_seq_client_pool_copy(snd_seq_client_pool_t *dst, const snd_seq_client_pool_t *src)
{
	assert(dst && src);
	*dst = *src;
}


/**
 * \brief Get the client id of a queue_info container
 * \param info client_pool container
 * \return client id
 */
int snd_seq_client_pool_get_client(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->client;
}

/**
 * \brief Get the output pool size of a queue_info container
 * \param info client_pool container
 * \return output pool size
 */
size_t snd_seq_client_pool_get_output_pool(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->output_pool;
}

/**
 * \brief Get the input pool size of a queue_info container
 * \param info client_pool container
 * \return input pool size
 */
size_t snd_seq_client_pool_get_input_pool(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->input_pool;
}

/**
 * \brief Get the output room size of a queue_info container
 * \param info client_pool container
 * \return output room size
 */
size_t snd_seq_client_pool_get_output_room(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->output_room;
}

/**
 * \brief Get the available size on output pool of a queue_info container
 * \param info client_pool container
 * \return available output size
 */
size_t snd_seq_client_pool_get_output_free(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->output_free;
}

/**
 * \brief Get the available size on input pool of a queue_info container
 * \param info client_pool container
 * \return available input size
 */
size_t snd_seq_client_pool_get_input_free(const snd_seq_client_pool_t *info)
{
	assert(info);
	return info->input_free;
}

/**
 * \brief Set the output pool size of a queue_info container
 * \param info client_pool container
 * \param size output pool size
 */
void snd_seq_client_pool_set_output_pool(snd_seq_client_pool_t *info, size_t size)
{
	assert(info);
	info->output_pool = size;
}

/**
 * \brief Set the input pool size of a queue_info container
 * \param info client_pool container
 * \param size input pool size
 */
void snd_seq_client_pool_set_input_pool(snd_seq_client_pool_t *info, size_t size)
{
	assert(info);
	info->input_pool = size;
}

/**
 * \brief Set the output room size of a queue_info container
 * \param info client_pool container
 * \param size output room size
 */
void snd_seq_client_pool_set_output_room(snd_seq_client_pool_t *info, size_t size)
{
	assert(info);
	info->output_room = size;
}


/**
 * \brief obtain the pool information of the current client
 * \param seq sequencer handle
 * \param info information to be stored
 */
int snd_seq_get_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
{
	assert(seq && info);
	info->client = seq->client;
	return seq->ops->get_client_pool(seq, info);
}

/**
 * \brief set the pool information
 * \param seq sequencer handle
 * \param info information to update
 *
 * Sets the pool information of the current client.
 * The client field in \a info is replaced automatically with the current id.
 */
int snd_seq_set_client_pool(snd_seq_t *seq, snd_seq_client_pool_t *info)
{
	assert(seq && info);
	info->client = seq->client;
	return seq->ops->set_client_pool(seq, info);
}

/*----------------------------------------------------------------*/

/*
 * misc.
 */

/**
 * \brief set a bit flag
 */
void snd_seq_set_bit(int nr, void *array)
{
	((unsigned int *)array)[nr >> 5] |= 1UL << (nr & 31);
}

/**
 * \brief unset a bit flag
 */
void snd_seq_unset_bit(int nr, void *array)
{
       ((unsigned int *)array)[nr >> 5] &= ~(1UL << (nr & 31));
}

/**
 * \brief change a bit flag
 */
int snd_seq_change_bit(int nr, void *array)
{
	int result;

	result = ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
	((unsigned int *)array)[nr >> 5] ^= 1UL << (nr & 31);
	return result;
}

/**
 * \brief get a bit flag state
 */
int snd_seq_get_bit(int nr, void *array)
{
	return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
}
