-/*
- * Sequencer Interface - main file
- * Copyright (c) 2000 by Jaroslav Kysela <perex@suse.cz>
- * Abramo Bagnara <abramo@alsa-project.org>
+/**
+ * \file seq/seq.c
+ * \author Jaroslav Kysela <perex@suse.cz>
+ * \author Abramo Bagnara <abramo@alsa-project.org>
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2000-2001
*
+ * THE SEQUENCER INTERFACE WILL BE CHANGED IN NEAR FUTURE.
+ * This interface is still not compliant to alsa 1.0 encapsulation.
+ *
+ */
+
+/*
+ * Sequencer Interface - main file
*
* This library is free software; you can redistribute it and/or modify
* it under the terms of the GNU Library General Public License as
#include <dlfcn.h>
#include "seq_local.h"
+/**
+ * \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().
+ */
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.
+ */
snd_seq_type_t snd_seq_type(snd_seq_t *seq)
{
assert(seq);
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. So far only \c "hw" type is supported.
+ * Just pass \c "hw" for this.
+ * \param streams The read/write mode of the sequencer. Can be one of
+ * three values:
+ * - \c SND_SEQ_OPEN_OUTPUT - open the sequencer for output only
+ * - \c SND_SEQ_OPEN_INPUT - open the sequencer for input only
+ * - \c SND_SEQ_OPEN_DUPLEX - open the sequencer for output and input
+ * I suppose that you'd always want to use \c SND_SEQ_OPEN_DUPLEX here;
+ * I can't think of a reason for using either of the other two.
+ * \note Internally, these are translated to \c O_WRONLY, \c O_RDONLY and
+ * \O_RDWR respectively and used as the second argument to the C library
+ * open() call.
+ * \param mode Optional modifier. Can be either 0, or \c
+ * 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 \c SND_SEQ_EVENT_CLIENT_START is broadcasted to announce port.
+ */
int snd_seq_open(snd_seq_t **seqp, const char *name,
int streams, int mode)
{
return snd_seq_open_noupdate(seqp, name, streams, mode);
}
-/*
- * release sequencer client
+/**
+ * \brief Close the sequencer
+ * \param handle 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
+ * \c SND_SEQ_EVENT_CLIENT_EXIT is broadcasted to announce port.
+ * The connection between other clients are disconnected.
+ * Call this just before exiting your program.
*/
int snd_seq_close(snd_seq_t *seq)
{
return 0;
}
-/*
- * returns the file descriptor of the client
+/**
+ * \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 specifed by the second argument. When both input and output
+ * are checked, pass \c POLLIN|POLLOUT
*/
int snd_seq_poll_descriptors_count(snd_seq_t *seq, short events)
{
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.
+ */
int snd_seq_poll_descriptors(snd_seq_t *seq, struct pollfd *pfds, unsigned int space, short events)
{
short revents = 0;
return 1;
}
-/*
- * set blocking behavior
+/**
+ * \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.
*/
int snd_seq_nonblock(snd_seq_t *seq, int nonblock)
{
return 0;
}
-/*
- * return the client id
+/**
+ * \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.
*/
int snd_seq_client_id(snd_seq_t *seq)
{
return seq->client;
}
-/*
- * return buffer size
+/**
+ * \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.
*/
int snd_seq_output_buffer_size(snd_seq_t *seq)
{
return seq->obufsize;
}
-/*
- * return buffer size
+/**
+ * \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.
*/
int snd_seq_input_buffer_size(snd_seq_t *seq)
{
return seq->ibufsize * sizeof(snd_seq_event_t);
}
-/*
- * resize output buffer
+/**
+ * \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.
*/
int snd_seq_resize_output_buffer(snd_seq_t *seq, size_t size)
{
return 0;
}
-/*
- * resize input buffer
+/**
+ * \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.
*/
int snd_seq_resize_input_buffer(snd_seq_t *seq, size_t size)
{
return 0;
}
-/*
- * obtain system information
+/**
+ * \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)
{
return seq->ops->system_info(seq, info);
}
-/*
- * obtain the information of given client
+/**
+ * \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.
*/
int snd_seq_get_any_client_info(snd_seq_t *seq, int client, snd_seq_client_info_t * info)
{
return seq->ops->get_client_info(seq, info);
}
-/*
- * obtain the current client information
+/**
+ * \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.
*/
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);
}
-/*
- * set the current client information
+/**
+ * \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.
*/
int snd_seq_set_client_info(snd_seq_t *seq, snd_seq_client_info_t * info)
{
/*----------------------------------------------------------------*/
-/*
- * sequencer port handlers
+/**
+ * \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 info argument.
+ *
+ * The client field in info argument is overwritten with the current client id.
+ * Behavior of port creation depends on a flag defined in
+ * flags field. The flags field is a bit mask containing
+ * miscellaneous conditions.
+ * If \c SND_SEQ_PORT_FLG_GIVEN_PORT is included in flags field,
+ * the port number in port field in info argument
+ * is used as the id of created port.
+ * Otherwise, the first empty port id is searched and used.
+ * The obtained id index of the created port is stored on
+ * port field in return.
+ *
+ * The capability and cap_group are bit-masks to specify the access
+ * capability of the port from other clients and from the same group,
+ * respectively. The capability bit flags are defined as follows:
+ * - \c SND_SEQ_PORT_CAP_READ Readable from this port
+ * - \c SND_SEQ_PORT_CAP_WRITE Writable to this port.
+ * - \c SND_SEQ_PORT_CAP_SYNC_READ For synchronization (not implemented)
+ * - \c SND_SEQ_PORT_CAP_SYNC_WRITE For synchronization (not implemented)
+ * - \c SND_SEQ_PORT_CAP_DUPLEX Read/write duplex access is supported
+ * - \c SND_SEQ_PORT_SUBS_READ Read subscription is allowed
+ * - \c SND_SEQ_PORT_SUBS_WRITE Write subscription is allowed
+ * - \c SND_SEQ_PORT_SUBS_NO_EXPORT Subscription management from 3rd client is disallowed
+ *
+ * The type field is used to specify the type of the port.
+ * It is a bitmask defined as follows:
+ * - \c SND_SEQ_PORT_TYPE_SPECIFIC Hardware specific port
+ * - \c SND_SEQ_PORT_TYPE_MIDI_GENERIC Generic MIDI device
+ * - \c SND_SEQ_PORT_TYPE_MIDI_GM General MIDI compatible device
+ * - \c SND_SEQ_PORT_TYPE_MIDI_GS GS compatible device
+ * - \c SND_SEQ_PORT_TYPE_MIDI_XG XG compatible device
+ * - \c SND_SEQ_PORT_TYPE_MIDI_MT32 MT-32 compatible device
+ * - \c SND_SEQ_PORT_TYPE_SYNTH Synth device
+ * - \c SND_SEQ_PORT_TYPE_DIRECT_SAMPLE Sampling device (supporting download)
+ * - \c SND_SEQ_PORT_TYPE_SAMPLE Sampling device (sample can be downloaded at any time)
+ * - \c SND_SEQ_PORT_TYPE_APPLICATION Application (suquencer/editor)
+ *
+ * The midi_channels, midi_voices and synth_voices fields are number of channels and
+ * voices of this port. These values could be zero as default.
+ * The read_use, write_use and kernel fields are at creation.
+ * They should be zero-cleared.
*/
-
int snd_seq_create_port(snd_seq_t *seq, snd_seq_port_info_t * port)
{
assert(seq && port);
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.
+ * The port id must be specified in port field in info argument.
+ * The client field is ignored.
+ */
int snd_seq_delete_port(snd_seq_t *seq, snd_seq_port_info_t * port)
{
assert(seq && port);
return seq->ops->delete_port(seq, port);
}
+/**
+ * \brief obatin 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
+ */
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);
return seq->ops->get_port_info(seq, info);
}
+/**
+ * \brief obatin 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
+ */
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
+ */
int snd_seq_set_port_info(snd_seq_t *seq, int port, snd_seq_port_info_t * info)
{
assert(seq && info && port >= 0);
* subscription
*/
+/**
+ * \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
+ */
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.
+ */
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.
+ */
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 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.
+ *
+ */
int snd_seq_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
{
assert(seq && subs);
* queue handlers
*/
+/**
+ * \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);
return seq->ops->get_queue_status(seq, status);
}
+/**
+ * \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
+ */
int snd_seq_get_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
assert(seq && tempo);
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
+ */
int snd_seq_set_queue_tempo(snd_seq_t *seq, int q, snd_seq_queue_tempo_t * tempo)
{
assert(seq && tempo);
return seq->ops->set_queue_tempo(seq, tempo);
}
+/**
+ * \brief obtain the owner information of the queue
+ * \param seq sequencer handle
+ * \param q queue id to query
+ * \param owner pointer to store the owner information
+ * \return 0 on success otherwise a negative error code
+ */
int snd_seq_get_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
{
assert(seq && owner);
return seq->ops->get_queue_owner(seq, owner);
}
+/**
+ * \biref set the owner information of the queue
+ * \param seq sequencer handle
+ * \param q queue id to change the ownership
+ * \param owner owner information
+ * \return 0 on success otherwise a negative error code
+ */
int snd_seq_set_queue_owner(snd_seq_t *seq, int q, snd_seq_queue_owner_t * owner)
{
assert(seq && owner);
return seq->ops->set_queue_owner(seq, owner);
}
+/**
+ * \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
+ */
int snd_seq_get_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
{
assert(seq && timer);
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
+ */
int snd_seq_set_queue_timer(snd_seq_t *seq, int q, snd_seq_queue_timer_t * timer)
{
assert(seq && timer);
return seq->ops->set_queue_timer(seq, timer);
}
+/**
+ * \brief obtain queue access information
+ * \param seq sequencer handle
+ * \param q queue id to query
+ * \param info pointer to store the queue access information
+ * \return 0 on success otherwise a negative error code
+ */
int snd_seq_get_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
{
assert(seq && info);
return seq->ops->get_queue_client(seq, info);
}
+/**
+ * \brief set queue access information
+ * \param seq sequencer handle
+ * \param q queue id to change access information
+ * \param info access information
+ * \return 0 on success otherwise a negative error code
+ */
int snd_seq_set_queue_client(snd_seq_t *seq, int q, snd_seq_queue_client_t * info)
{
assert(seq && info);
return seq->ops->set_queue_client(seq, info);
}
+/**
+ * \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
+ */
int snd_seq_create_queue(snd_seq_t *seq, snd_seq_queue_info_t *info)
{
int err;
return info->queue;
}
+/**
+ * \brief allocate a queue with the speicified 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
+ */
int snd_seq_alloc_named_queue(snd_seq_t *seq, const char *name)
{
snd_seq_queue_info_t info;
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
+ */
int snd_seq_alloc_queue(snd_seq_t *seq)
{
return snd_seq_alloc_named_queue(seq, NULL);
}
#ifdef SND_SEQ_SYNC_SUPPORT
-int snd_seq_alloc_sync_queue(snd_seq_t *seq, char *name)
+/**
+ * \brief allocate a synchronizable queue
+ * \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
+ */
+int snd_seq_alloc_sync_queue(snd_seq_t *seq, const char *name)
{
snd_seq_queue_info_t info;
memset(&info, 0, sizeof(info));
}
#endif
+/**
+ * \breif delete the specified queue
+ * \param seq sequencer handle
+ * \param q queue id to delete
+ * \return 0 on success otherwise a negative error code
+ */
int snd_seq_free_queue(snd_seq_t *seq, int q)
{
snd_seq_queue_info_t info;
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
+ */
int snd_seq_get_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
{
assert(seq && info);
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
+ */
int snd_seq_set_queue_info(snd_seq_t *seq, int q, snd_seq_queue_info_t *info)
{
assert(seq && info);
return seq->ops->set_queue_info(seq, info);
}
+/**
+ * \brief query the queue with the specified name
+ * \param seq sequencer handle
+ * \param name name to query
+ * \return the queue id if found or a negative error code
+ */
int snd_seq_get_named_queue(snd_seq_t *seq, const char *name)
{
int err;
* sync stuff
*/
+/**
+ * \brief add sync master
+ * \param seq sequencer handle
+ * \param queue queue id to change
+ * \param dest destination of the sync slave
+ * \param info sync information
+ */
int snd_seq_add_sync_master(snd_seq_t *seq,
int queue,
snd_seq_addr_t *dest,
return snd_seq_subscribe_port(seq, &subs);
}
+/**
+ * \brief add a standard sync master
+ * \param seq sequencer handle
+ * \param queue queue id
+ * \param dest destination of the sync slave
+ * \param format sync format
+ * \param time_format time format
+ * \param optinfo optional information
+ */
int snd_seq_add_sync_std_master(snd_seq_t *seq,
int queue,
snd_seq_addr_t *dest,
return snd_seq_add_sync_master(seq, queue, dest, &sync_info);
}
-
+/**
+ * \brief remove the specified sync master
+ */
int snd_seq_remove_sync_master(snd_seq_t *seq, int queue, snd_seq_addr_t *dest)
{
snd_seq_port_subscribe_t subs;
}
+/**
+ * \brief set the sync slave mode
+ */
int snd_seq_set_sync_slave(snd_seq_t *seq,
int queue,
snd_seq_addr_t *src,
return snd_seq_subscribe_port(seq, &subs);
}
+/**
+ * \brief reset the sync slave mode
+ */
int snd_seq_reset_sync_slave(snd_seq_t *seq, int queue, snd_seq_addr_t *src)
{
snd_seq_port_subscribe_t subs;
/*----------------------------------------------------------------*/
-/*
- * create an event cell
+/**
+ * \brief create an event cell
+ * \return the cell pointer allocated
*/
snd_seq_event_t *snd_seq_create_event(void)
{
return (snd_seq_event_t *) calloc(1, sizeof(snd_seq_event_t));
}
-/*
- * free an event - only for compatibility
+/**
+ * \brief free an event
+ *
+ * this is obsolete. only for compatibility
*/
int snd_seq_free_event(snd_seq_event_t *ev ATTRIBUTE_UNUSED)
{
return 0;
}
-/*
- * calculates the (encoded) byte-stream size of the event
+/**
+ * \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)
{
* output to sequencer
*/
-/*
- * output an event - an event is once expanded on the output buffer.
+/**
+ * \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.
* output buffer may be flushed if it becomes full.
+ *
+ * If events remain unprocessed on output buffer before flush,
+ * the size of total byte data on output buffer is returned.
+ * If the output buffer is empty, this returns zero.
*/
int snd_seq_event_output(snd_seq_t *seq, snd_seq_event_t *ev)
{
return result;
}
-/*
- * output an event onto the lib buffer without flushing buffer.
- * returns -EAGAIN if the buffer becomes full.
+/**
+ * \brief output an event onto the lib buffer without flushing buffer
+ * \param seq sequencer handle
+ * \param ev event ot be output
+ * \return the number of remaining events. \c -EAGAIN if the buffer becomes full.
*/
int snd_seq_event_output_buffer(snd_seq_t *seq, snd_seq_event_t *ev)
{
return 0;
}
-/*
- * output an event directly to the sequencer NOT through output buffer.
+/**
+ * \brief output an event directly to the sequencer NOT through output buffer
+ * \param seq sequencer handle
+ * \param ev event to be output
+ * \return the number of remaining events or a negative error code
*/
int snd_seq_event_output_direct(snd_seq_t *seq, snd_seq_event_t *ev)
{
return seq->ops->write(seq, buf, (size_t) len);
}
-/*
- * return the size of pending events on output buffer
+/**
+ * \brief return the size of pending events on output buffer
+ * \param seq sequencer handle
+ * \return the number of pending events
*/
int snd_seq_event_output_pending(snd_seq_t *seq)
{
return seq->obufused;
}
-/*
- * drain output buffer to sequencer
+/**
+ * \brief drain output buffer to sequencer
+ * \param seq sequencer handle
*/
int snd_seq_drain_output(snd_seq_t *seq)
{
return 0;
}
-/*
- * extract the first event in output buffer
- * if ev_res is NULL, just remove the event.
+/**
+ * \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.
*/
int snd_seq_extract_output(snd_seq_t *seq, snd_seq_event_t **ev_res)
{
return 1;
}
-/*
- * retrieve an event from sequencer
+/**
+ * \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 recives 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 succeedingly, events are extract 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 number of remaining event sizes 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.
*/
int snd_seq_event_input(snd_seq_t *seq, snd_seq_event_t **ev)
{
return seq->ibuflen;
}
-/*
- * check events in input queue
+/**
+ * \brief check events in input queue
+ *
+ * Returns the number of remaining input events.
+ * If events remain on the input buffer of user-space, function returns
+ * the number of events on it.
+ * If fetch_sequencer argument is non-zero,
+ * this function checks the presence of events on sequencer FIFO via
+ * select syscall. 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 simplly returns zero.
*/
int snd_seq_event_input_pending(snd_seq_t *seq, int fetch_sequencer)
{
* clear event buffers
*/
-/*
- * clear output buffer
+/**
+ * \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(0, this function doesn't remove
+ * events on output memory pool of sequencer.
*/
int snd_seq_drop_output_buffer(snd_seq_t *seq)
{
return 0;
}
-/*
- * clear input buffer
+/**
+ * \brief remove all events on user-space input FIFO
+ * \param seq sequencer handle
*/
int snd_seq_drop_input_buffer(snd_seq_t *seq)
{
return 0;
}
-/*
- * clear output buffer and remove events in sequencer queue
+/**
+ * \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.
*/
int snd_seq_drop_output(snd_seq_t *seq)
{
return snd_seq_remove_events(seq, &rminfo);
}
-/*
- * clear input buffer and and remove events in sequencer queue
+/**
+ * \brief clear input buffer and and remove events in sequencer queue
+ * \param seq sequencer handle
*/
int snd_seq_drop_input(snd_seq_t *seq)
{
return 1;
}
-/*
- * Remove events from the sequencer queues.
+/**
+ * \brief remove events on input/output buffers
+ * \param seq sequencer handle
+ *
+ * Removes matching events with the given condition from input/output buffers.
+ * The removal condition is specified in rmp argument.
*/
int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
{
* client memory pool
*/
+/**
+ * \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);
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 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);
* query functions
*/
+/**
+ * \brief query the next matching client
+ * \param seq sequencer handle
+ * \param info query pattern and result
+ *
+ * Queries the next matching client with the given condition in
+ * info argument.
+ * The search begins at the client with an id one greater than
+ * client field in info.
+ * If name field in info is not empty, the client name is compared.
+ * If a matching client is found, its attributes are stored o
+ * info and returns zero.
+ * Otherwise returns a negative error code.
+ */
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);
}
+/**
+ * \brief query the next matching port
+ * \param seq sequencer handle
+ * \param info query pattern and result
+
+ * Queries the next matching port from the port
+ * on the client given in info argument.
+ * The search begins at the next port specified in
+ * port field of info.
+ * For finding the first port at a certain client, give -1 to
+ * port field.
+ * If name field is not empty, the name is checked.
+ * If a matching port is found, its attributes are stored on
+ * info and function returns zero.
+ * Otherwise, a negative error code is returned.
+ */
int snd_seq_query_next_port(snd_seq_t *seq, snd_seq_port_info_t *info)
{
assert(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 change a bit flag
+ */
int snd_seq_change_bit(int nr, void *array)
{
int result;
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;
/*
* Sequencer Interface - middle-level routines
*
- * Copyright (c) 1999 by Takashi Iwai <iwai@ww.uni-erlangen.de>
+ * Copyright (c) 1999 by Takashi Iwai <tiwai@suse.de>
*
*
* This library is free software; you can redistribute it and/or modify
#include <sys/ioctl.h>
#include "seq_local.h"
-/* direct passing (without queued) */
+/**
+ * \brief set direct passing mode (without queued)
+ * \param ev event instance
+ */
void snd_seq_ev_set_direct(snd_seq_event_t *ev)
{
ev->queue = SND_SEQ_QUEUE_DIRECT;
}
-/* queued on tick */
+/**
+ * \brief set tick-scheduling mode on queue
+ * \param ev event instance
+ * \param q queue id to schedule
+ * \param relative relative time-stamp if non-zero
+ * \param tick tick time-stap to be delivered
+ */
void snd_seq_ev_schedule_tick(snd_seq_event_t *ev, int q, int relative,
snd_seq_tick_time_t tick)
{
ev->queue = q;
}
-/* queued on real-time */
+/**
+ * \brief set real-time-scheduling mode on queue
+ * \param ev event instance
+ * \param q queue id to schedule
+ * \param relative relative time-stamp if non-zero
+ * \param _time time-stamp to be delivered
+ */
void snd_seq_ev_schedule_real(snd_seq_event_t *ev, int q, int relative,
snd_seq_real_time_t *_time)
{
ev->queue = q;
}
-/* set event priority */
+/**
+ * \brief set event priority
+ * \param ev event instance
+ * \param high_prior 1 for high priority mode
+ */
void snd_seq_ev_set_priority(snd_seq_event_t *ev, int high_prior)
{
ev->flags &= ~SND_SEQ_PRIORITY_MASK;
ev->flags |= high_prior ? SND_SEQ_PRIORITY_HIGH : SND_SEQ_PRIORITY_NORMAL;
}
-/* set fixed data */
+/**
+ * \brief set fixed data
+ *
+ * Sets the event length mode as fixed size.
+ */
void snd_seq_ev_set_fixed(snd_seq_event_t *ev)
{
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
}
-/* set variable data */
+/**
+ * \brief set variable data
+ *
+ * Sets the event length mode as variable length and stores the data.
+ */
void snd_seq_ev_set_variable(snd_seq_event_t *ev, int len, void *ptr)
{
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev->data.ext.ptr = ptr;
}
-/* set varusr data */
+/**
+ * \brief set varusr data
+ *
+ * Sets the event length mode as variable user-space data and stores the data.
+ */
void snd_seq_ev_set_varusr(snd_seq_event_t *ev, int len, void *ptr)
{
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
}
-/* use or unuse a queue */
+/**
+ * \brief use or unuse a queue
+ */
int snd_seq_use_queue(snd_seq_t *seq, int q, int use)
{
snd_seq_queue_client_t info;
}
-/* queue controls - start/stop/continue */
-/* if ev is NULL, send events immediately.
- otherwise, duplicate the given event data. */
+/**
+ * \brief queue controls - start/stop/continue
+ * \param seq sequencer handle
+ * \param q queue id to control
+ * \param type event type
+ * \param value event value
+ * \param ev event instance
+ *
+ * if ev is NULL, send events immediately.
+ * otherwise, duplicate the given event data.
+ */
int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev)
{
snd_seq_event_t tmpev;
return snd_seq_event_output(seq, ev);
}
-/* reset queue position:
+/**
+ * \brief reset queue position
+ *
* new values of both real-time and tick values must be given.
*/
int snd_seq_setpos_queue(snd_seq_t *seq, int q, snd_seq_timestamp_t *rtime, snd_seq_event_t *ev)
return result;
}
-/* create a port - simple version
+/**
+ * \brief create a port - simple version
+ *
* return the port number
*/
int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
return pinfo.port;
}
-/* delete the port */
+/**
+ * \brief delete the port
+ */
int snd_seq_delete_simple_port(snd_seq_t *seq, int port)
{
snd_seq_port_info_t pinfo;
return snd_seq_delete_port(seq, &pinfo);
}
-/*
- * sipmle subscription (w/o exclusive & time conversion)
+/**
+ * \brief sipmle subscription (w/o exclusive & time conversion)
*/
int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
return snd_seq_subscribe_port(seq, &subs);
}
+/**
+ * \brief sipmle subscription (w/o exclusive & time conversion)
+ */
int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
snd_seq_port_subscribe_t subs;
return snd_seq_subscribe_port(seq, &subs);
}
+/**
+ * \brief sipmle disconnection (w/o exclusive & time conversion)
+ */
int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
snd_seq_port_subscribe_t subs;
return snd_seq_unsubscribe_port(seq, &subs);
}
+/**
+ * \brief sipmle disconnection (w/o exclusive & time conversion)
+ */
int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
snd_seq_port_subscribe_t subs;
/*
* set client information
*/
+/**
+ * \brief set client name
+ */
int snd_seq_set_client_name(snd_seq_t *seq, const char *name)
{
snd_seq_client_info_t info;
return snd_seq_set_client_info(seq, &info);
}
+/**
+ * \brief set client group
+ */
int snd_seq_set_client_group(snd_seq_t *seq, const char *name)
{
snd_seq_client_info_t info;
return snd_seq_set_client_info(seq, &info);
}
+/**
+ * \brief set client filter
+ */
int snd_seq_set_client_filter(snd_seq_t *seq, unsigned int filter)
{
snd_seq_client_info_t info;
return snd_seq_set_client_info(seq, &info);
}
+/**
+ * \brief set client event filter
+ */
int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type)
{
snd_seq_client_info_t info;
return snd_seq_set_client_info(seq, &info);
}
+/**
+ * \brief change the output pool size of the given client
+ */
int snd_seq_set_client_pool_output(snd_seq_t *seq, int size)
{
snd_seq_client_pool_t info;
return snd_seq_set_client_pool(seq, &info);
}
+/**
+ * \brief change the output room size of the given client
+ */
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size)
{
snd_seq_client_pool_t info;
return snd_seq_set_client_pool(seq, &info);
}
+/**
+ * \brief change the input pool size of the given client
+ */
int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
{
snd_seq_client_pool_t info;
return snd_seq_set_client_pool(seq, &info);
}
-/*
- * reset client input/output pool
- * use REMOVE_EVENTS ioctl
+/**
+ * \brief reset client output pool
*/
int snd_seq_reset_pool_output(snd_seq_t *seq)
{
return snd_seq_remove_events(seq, &rmp);
}
+/**
+ * \brief reset client input pool
+ */
int snd_seq_reset_pool_input(snd_seq_t *seq)
{
snd_seq_remove_events_t rmp;