diff options
author | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
---|---|---|
committer | Igor Pashev <pashev.igor@gmail.com> | 2013-05-03 21:08:42 +0400 |
commit | 1058def8e7827e56ce4a70afb4aeacb5dc44148f (patch) | |
tree | 4495d23e7b54ab5700e3839081e797c1eafe0db9 /lib/libsalsa/seq.c | |
download | oss4-upstream.tar.gz |
Imported Upstream version 4.2-build2006upstream/4.2-build2006upstream
Diffstat (limited to 'lib/libsalsa/seq.c')
-rw-r--r-- | lib/libsalsa/seq.c | 2230 |
1 files changed, 2230 insertions, 0 deletions
diff --git a/lib/libsalsa/seq.c b/lib/libsalsa/seq.c new file mode 100644 index 0000000..67f134b --- /dev/null +++ b/lib/libsalsa/seq.c @@ -0,0 +1,2230 @@ +/* + * Copyright (c) 2004 by Hannu Savolainen < hannu@opensound.com> + * + * This library is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 as + * published by the Free Software Foundation. + * + * 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 + * + */ +#include <stdio.h> +#include "local.h" + +static int nports = 0; + +typedef struct _snd_seq_port_subscribe +{ + int dummy; +} snd_seq_port_subscribe_t; + +typedef struct _snd_seq_queue_tempo +{ + int dummy; +} snd_seq_queue_tempo_t; + +typedef struct _snd_seq_system_info +{ + int dummy; +} snd_seq_system_info_t; + +struct _snd_seq_remove_events +{ + int dummy; +}; + +struct _snd_seq_query_subscribe +{ + int dummy; +}; + +/** + * \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_seq_t *seq; + int err, oss_mode; + static int instance = 0; + + char *fname = "/dev/midi", *envname = NULL, tmp[128]; + + ALIB_INIT (); + + dbg_printf ("snd_seq_open(name='%s', streams=%d, mode=%x)\n", name, streams, + mode); + + if (!alib_appcheck ()) + return -ENODEV; + + instance++; + + sprintf (tmp, "%s_mididev%d", alib_appname, instance); + + if ((envname = getenv (tmp)) != NULL) + { + fname = envname; + } +#if 0 + if (streams != 1) + { + fprintf (stderr, "salsa: snd_seq_open doesn't support streams=%d\n", + streams); + return -EIO; + } +#endif + + if ((seq = malloc (sizeof (*seq))) == NULL) + return -ENOMEM; + + dbg_printf ("Created sequencer seq=%x\n", seq); + + memset (seq, 0, sizeof (*seq)); + + switch (streams) + { + case SND_SEQ_OPEN_INPUT: + oss_mode = O_RDONLY; + dbg_printf ("Open SND_SEQ_OPEN_INPUT\n"); + break; + case SND_SEQ_OPEN_OUTPUT: + oss_mode = O_WRONLY; + dbg_printf ("Open SND_SEQ_OPEN_OUTPUT\n"); + break; + case SND_SEQ_OPEN_DUPLEX: + dbg_printf ("SND_SEQ_OPEN_DUPLEX\n"); + oss_mode = O_RDWR; + break; + + default: + fprintf (stderr, "snd_seq_open: Unknown stream %x\n", streams); + return -ENODEV; + } + + if ((seq->fd = open (fname, oss_mode, 0)) == -1) + { + err = errno; + perror (fname); + + if (envname == NULL) + { + fprintf (stderr, + "You can select another filename using environment variable %s_mididev%d\n", + alib_appname, instance); + } + return -err; + } + + seq->streams = streams; + seq->oss_mode = oss_mode; + + if (streams == SND_SEQ_OPEN_INPUT || streams == SND_SEQ_OPEN_DUPLEX) + { + seq->parser = midiparser_create (midiparser_callback, seq); + if (seq->parser == NULL) + { + fprintf (stderr, "libsalsa: Can't create MIDI parser\n"); + return -ENODEV; + } + } + + *seqp = seq; + return 0; +} + +/** + * \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 + * #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) +{ + dbg_printf ("snd_seq_close(seq=%x)\n", seq); + + close (seq->fd); + free (seq); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_nonblock(seq=%x, nonblock=%d)\n", seq, nonblock); + + seq->nonblock = nonblock; + return 0; +} + +/** + * \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_SUBS_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_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_SYNTH Synth device + * - #SND_SEQ_PORT_TYPE_DIRECT_SAMPLE Sampling device (supporting download) + * - #SND_SEQ_PORT_TYPE_SAMPLE Sampling device (sample can be downloaded at any time) + * - #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) +{ + dbg_printf ("snd_seq_create_port(seq=%x, port=%x)\n", seq, port); + + port->port = nports++; + 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) +{ + static int client_id = 128; + + dbg_printf ("snd_seq_client_id(seq=%x)=%d\n", seq, client_id); + + return client_id++; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_get_client()\n"); + + return 0; +} + +/** + * \brief Get client type of a client_info container + * \param info client_info container + * \return client type + * + * The client type is either #SEQ_CLIENT_TYPE_KERNEL or #SEQ_CLIENT_TYPE_USER + * 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) +{ + dbg_printf ("snd_seq_client_info_get_type(infp=%x)\n", info); + + return SND_SEQ_KERNEL_CLIENT; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_set_client(%x, %d)\n", info, client); + + info->client = client; +} + +/** + * \brief get size of #snd_seq_client_info_t + * \return size in bytes + */ +size_t +snd_seq_client_info_sizeof () +{ + dbg_printf ("snd_seq_client_info_sizeof()\n"); + + return sizeof (snd_seq_client_info_t); +} + +/** + * \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 ** evp) +{ + static snd_seq_event_t *ev; + unsigned char buf[256]; + int i, l; + + dbg_printf2 ("snd_seq_event_input(seq=%x)\n", seq); + + while (1) + { + + if (seq->nextevent < seq->nevents) + { + *evp = &seq->events[seq->nextevent++]; + + return (seq->nevents - seq->nextevent) * sizeof (snd_seq_event_t); + } + + seq->nextevent = seq->nevents = 0; + memset (seq->events, 0, sizeof (seq->events)); + + // TODO Handling of nonblocking mode + if ((l = read (seq->fd, buf, sizeof (buf))) == -1) + return -errno; + + midiparser_input_buf (seq->parser, buf, l); + + } + +} + +/** + * \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) +{ + int err; + + dbg_printf3 ("snd_seq_event_output_direct()\n"); + + if ((err = convert_event (seq, ev)) < 0) + return err; + if ((err = snd_seq_drain_output (seq)) < 0) + return err; + + return 0; +} + +/** + * \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. + */ +int +snd_seq_free_event (snd_seq_event_t * ev) +{ + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_client_info(seq=%x, info=%x)\n", seq, info); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_next_port()\n"); + + return -EINVAL; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_set_name(%s)\n", name); + + strncpy (info->name, name, sizeof (info->name) - 1); + info->name[sizeof (info->name) - 1] = 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_subscribe_port()\n"); + + return -EINVAL; +} + +/** + * \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 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) +{ + dbg_printf ("snd_seq_port_subscribe_set_sender()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_subscribe_set_dest()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_subscribe_set_queue()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_subscribe_set_time_real()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_subscribe_set_time_update()\n"); +} + +/* + * 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 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) +{ + dbg_printf ("snd_seq_port_info_get_capability()\n"); + + return info->capability; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_addr(info=%x)\n", info); + + return NULL; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_capability()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_port_specified()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_midi_channels(info=%x)=%d\n", + info, info->midi_channels); + + return info->midi_channels; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_midi_channels(info=%x, channels=%d)\n", + info, channels); + info->midi_channels = channels; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_timestamp_queue(info=%x)\n", info); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_timestamp_queue(info=%x, queue=%d)\n", + info, queue); + + // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_timestamp_real(info=%x)\n", info); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_timestamp_real(infp=%x, enable=%d)\n", + info, enable); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_timestamping(info=%x)\n", info); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_timestamping(info=%x, enable=%d)\n", + info, enable); + + // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_name()\n"); + + strncpy (info->name, name, sizeof (info->name)); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_name()\n"); + + return "Port Name"; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_port()\n"); + + return -EIO; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_type()\n"); + + return info->type; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_client()\n"); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_set_port()\n"); +} + +/** + * \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. + * + * \sa snd_seq_get_any_client_info() + */ +int +snd_seq_query_next_client (snd_seq_t * seq, snd_seq_client_info_t * info) +{ + dbg_printf ("snd_seq_query_next_client()\n"); + + return -EIO; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_set_client_info(seq=%x, info=%x)\n", seq, info); + + if (*info->name) + { + strcpy (seq->name, info->name); + ioctl (seq->fd, SNDCTL_SETNAME, seq->name); + ioctl (seq->fd, SNDCTL_SETSONG, seq->name); + } + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_event_input_pending()\n"); + + return 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) +{ + dbg_printf ("snd_seq_poll_descriptors(seq=%x)\n", seq); + + pfds->fd = seq->fd; + pfds->events = 0; + pfds->revents = 0; + + if (seq->oss_mode == O_WRONLY || seq->oss_mode == O_RDWR) + pfds->events = POLLOUT; + if (seq->oss_mode == O_RDONLY || seq->oss_mode == O_RDWR) + pfds->events = POLLIN; + + return 1; +} + + +/** + * \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) +{ + dbg_printf ("snd_seq_poll_descriptors_count(seq=%x, events=%x)\n", + seq, events); + return 1; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_create_queue()\n"); + + return 0; +} + +/** + * \brief simple subscription (w/o exclusive & time conversion) + * \param myport the port id as sender + * \param dest_client destination client id + * \param dest_port destination port id + * \return 0 on success or negative error code + * + * Connect from the given receiver port in the current client + * to the given destination client:port. + * + * \sa snd_seq_subscribe_port(), snd_seq_disconnect_to() + */ +int +snd_seq_connect_to (snd_seq_t * seq, int myport, int dest_client, + int dest_port) +{ + dbg_printf ("snd_seq_connect_to(%d->%d/%d)\n", myport, dest_client, + dest_port); + + return 0; +} + +/** + * \brief simple subscription (w/o exclusive & time conversion) + * \param myport the port id as receiver + * \param src_client sender client id + * \param src_port sender port id + * \return 0 on success or negative error code + * + * Connect from the given sender client:port to the given destination port in the + * current client. + * + * \sa snd_seq_subscribe_port(), snd_seq_disconnect_from() + */ +int +snd_seq_connect_from (snd_seq_t * seq, int myport, int src_client, + int src_port) +{ + dbg_printf + ("snd_seq_connect_from(seq=%x, myport=%d, src_client=%d, src_port=%d)\n", + seq, myport, src_client, src_port); + + return 0; +} + +/** + * \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 + * + * This function sets up general queue control event and sends it. + * To send at scheduled time, set the schedule in \a ev. + * If \a ev is NULL, the event is composed locally and sent immediately + * to the specified queue. In any cases, you need to call #snd_seq_drain_output() + * appropriately to feed the event. + * + * \sa snd_seq_alloc_queue() + */ +int +snd_seq_control_queue (snd_seq_t * seq, int q, int type, int value, + snd_seq_event_t * ev) +{ + dbg_printf ("snd_seq_control_queue()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf3 ("snd_seq_drain_output(seq=%x)\n", seq); + + 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) +{ + dbg_printf ("snd_seq_drop_output()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf3 ("snd_seq_event_output(seq=%x, ev=%x)\n", seq, ev); + + return convert_event (seq, ev); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_free_queue()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_any_client_info()\n"); + + strcpy (info->name, seq->name); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_any_port_info()\n"); + + return 0; +} + +/** + * \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) +{ + snd_seq_port_info_t *p; + + dbg_printf ("snd_seq_port_info_malloc()\n"); + + if ((p = malloc (sizeof (*p))) == NULL) + return -ENOMEM; + + *ptr = p; + + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_port_info_t + * \param pointer to object to free + */ +void +snd_seq_port_info_free (snd_seq_port_info_t * obj) +{ + free (obj); +} + +/** + * \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)); + dbg_printf ("snd_seq_queue_tempo_malloc()=%x\n", *ptr); + if (!*ptr) + return -ENOMEM; + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_queue_tempo_t + * \param pointer to object to free + */ +void +snd_seq_queue_tempo_free (snd_seq_queue_tempo_t * obj) +{ + dbg_printf ("snd_seq_queue_tempo_free(%x)\n", obj); + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_tempo_set_ppq(info=%x, %d)\n", info, ppq); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_tempo_set_tempo(info=%x, %d)\n", info, tempo); +} + +/** + * \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 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) +{ + dbg_printf ("snd_seq_get_queue_timer(seq=%x, q=%d, timer=%X)\n", seq, q, + timer); + return -ENXIO; // TODO +} + + +/** + * \brief Opens a new connection to the timer query interface. + * \param timer Returned handle (NULL if not wanted) + * \param name ASCII identifier of the RawMidi handle + * \param mode Open mode + * \return 0 on success otherwise a negative error code + * + * Opens a new connection to the RawMidi interface specified with + * an ASCII identifier and mode. + */ +int +snd_timer_query_open (snd_timer_query_t ** timer, const char *name, int mode) +{ + dbg_printf ("snd_timer_query_open(name=%s, mode=%x)\n", name, mode); + return -ENXIO; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_queue_tempo(seq=%x, q=%d, tempo=%x)\n", seq, q, + tempo); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_malloc()\n"); + + *ptr = malloc (sizeof (snd_seq_client_info_t)); + if (!*ptr) + return -ENOMEM; + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_client_info_t + * \param pointer to object to free + */ +void +snd_seq_client_info_free (snd_seq_client_info_t * obj) +{ + dbg_printf ("snd_seq_client_info_free()\n"); + + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_get_name()\n"); + return "OSS seq client"; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_client_info_get_num_ports()\n"); + + return 1; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_system_info_malloc()\n"); + + *ptr = malloc (sizeof (snd_seq_system_info_t)); + if (*ptr == NULL) + return -ENOMEM; + return 0; +} + +/** + * \brief Frees a previously allocated #snd_seq_system_info_t + * \param pointer to object to free + */ +void +snd_seq_system_info_free (snd_seq_system_info_t * obj) +{ + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_system_info()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_system_info_get_clients()\n"); + + return 4; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_system_info_get_queues(info=%x)\n", info); + + return 1; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_system_info_get_ports()\n"); + + return 4; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_alloc_named_queue(seq=%x, name=%s)\n", seq, name); + + return 0; +} + + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_client()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_port_info_get_port_specified()\n"); + + return 0; +} + +/** + * \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_get_type() + */ +void +snd_seq_port_info_set_type (snd_seq_port_info_t * info, unsigned int type) +{ + dbg_printf ("snd_seq_port_info_set_type(%u)\n", type); +} + + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_tempo_get_ppq()\n"); + + return 0; +} + + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_tempo_get_tempo()\n"); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_set_queue_tempo(seq=%x, q=%d, tempo=%x)\n", seq, q, + tempo); + + return 0; +} + +/** + * \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) +{ + static int queue_num = 0; + dbg_printf ("snd_seq_alloc_queue(seq=%x)=%d\n", seq, queue_num); + + return queue_num++; +} + +#define FIXED_EV(x) (_SND_SEQ_TYPE(SND_SEQ_EVFLG_FIXED) | _SND_SEQ_TYPE(x)) + +/** Event types conversion array */ +const unsigned int snd_seq_event_types[256] = { + [SND_SEQ_EVENT_SYSTEM...SND_SEQ_EVENT_RESULT] + = FIXED_EV (SND_SEQ_EVFLG_RESULT), + [SND_SEQ_EVENT_NOTE] + = + FIXED_EV (SND_SEQ_EVFLG_NOTE) | + _SND_SEQ_TYPE_OPT (SND_SEQ_EVFLG_NOTE_TWOARG), + [SND_SEQ_EVENT_NOTEON...SND_SEQ_EVENT_KEYPRESS] = + FIXED_EV (SND_SEQ_EVFLG_NOTE), + [SND_SEQ_EVENT_CONTROLLER...SND_SEQ_EVENT_REGPARAM] = + FIXED_EV (SND_SEQ_EVFLG_CONTROL), + [SND_SEQ_EVENT_START...SND_SEQ_EVENT_STOP] = FIXED_EV (SND_SEQ_EVFLG_QUEUE), + [SND_SEQ_EVENT_SETPOS_TICK] + = + FIXED_EV (SND_SEQ_EVFLG_QUEUE) | + _SND_SEQ_TYPE_OPT (SND_SEQ_EVFLG_QUEUE_TICK), + [SND_SEQ_EVENT_SETPOS_TIME] = + FIXED_EV (SND_SEQ_EVFLG_QUEUE) | + _SND_SEQ_TYPE_OPT (SND_SEQ_EVFLG_QUEUE_TIME), + [SND_SEQ_EVENT_TEMPO...SND_SEQ_EVENT_SYNC_POS] = + FIXED_EV (SND_SEQ_EVFLG_QUEUE) | + _SND_SEQ_TYPE_OPT (SND_SEQ_EVFLG_QUEUE_VALUE), + [SND_SEQ_EVENT_TUNE_REQUEST...SND_SEQ_EVENT_SENSING] = + FIXED_EV (SND_SEQ_EVFLG_NONE), + [SND_SEQ_EVENT_ECHO...SND_SEQ_EVENT_OSS] = + FIXED_EV (SND_SEQ_EVFLG_RAW) | FIXED_EV (SND_SEQ_EVFLG_SYSTEM), + [SND_SEQ_EVENT_CLIENT_START...SND_SEQ_EVENT_PORT_CHANGE] = + FIXED_EV (SND_SEQ_EVFLG_MESSAGE), + [SND_SEQ_EVENT_PORT_SUBSCRIBED...SND_SEQ_EVENT_PORT_UNSUBSCRIBED] = + FIXED_EV (SND_SEQ_EVFLG_CONNECTION), + [SND_SEQ_EVENT_USR0...SND_SEQ_EVENT_USR9] = + FIXED_EV (SND_SEQ_EVFLG_RAW) | FIXED_EV (SND_SEQ_EVFLG_USERS), + [SND_SEQ_EVENT_SYSEX...SND_SEQ_EVENT_BOUNCE] = + _SND_SEQ_TYPE (SND_SEQ_EVFLG_VARIABLE), + [SND_SEQ_EVENT_USR_VAR0...SND_SEQ_EVENT_USR_VAR4] = + _SND_SEQ_TYPE (SND_SEQ_EVFLG_VARIABLE) | + _SND_SEQ_TYPE (SND_SEQ_EVFLG_USERS), + [SND_SEQ_EVENT_NONE] = FIXED_EV (SND_SEQ_EVFLG_NONE), +}; + +/** + * \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) +{ + dbg_printf ("snd_seq_get_queue_status(seq=%x. q=%d)\n", seq, q); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_status_malloc()\n"); + *ptr = calloc (1, sizeof (snd_seq_queue_status_t)); + dbg_printf ("snd_seq_queue_status_malloc()=%x\n", *ptr); + if (!*ptr) + return -ENOMEM; + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_queue_status_t + * \param pointer to object to free + */ +void +snd_seq_queue_status_free (snd_seq_queue_status_t * obj) +{ + dbg_printf ("snd_seq_queue_status_free(%x)\n", obj); + + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_status_get_tick_time(info=%x)\n", info); + + return 0; +} + +/** + * \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)); + dbg_printf ("snd_seq_remove_events_malloc()=%x\n", *ptr); + if (!*ptr) + return -ENOMEM; + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_remove_events_t + * \param pointer to object to free + */ +void +snd_seq_remove_events_free (snd_seq_remove_events_t * obj) +{ + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_remove_events_set_condition(rmp=%x, flags=%lu)\n", + info, 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) +{ + dbg_printf ("snd_seq_remove_events_set_queue(rmp=%x, q=%d)\n", info, queue); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_remove_events(seq=%x, rmp=%x)\n", seq, rmp); + + return 1; +} + + +/** + * \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) +{ + dbg_printf ("snd_seq_drop_input(seq=%x)\n", seq); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_drop_output_buffer(seq=%x)\n", seq); + + 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) +{ + dbg_printf ("snd_seq_extract_output(seq=%x)\n", seq); + + return -EIO; +} + +/** + * \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 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) +{ + dbg_printf ("snd_seq_get_output_buffer_size(seq=%x)\n", seq); + + return 1024; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_set_output_buffer_size(seq=%x, size=%d)\n", seq, size); + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_unsubscribe_port(seq=%x, sub=%x)\n", seq, sub); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_timer_get_queue(timer=%x)\n", info); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_queue_timer(seq=%x, q=%d, timer=%x)\n", + seq, 1, timer); + + return 0; +} + +/** + * \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) +{ + dbg_printf ("snd_seq_queue_timer_set_id(timer=%x, id=%x)\n", info, id); +} + +/** + * \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 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) +{ + *ptr = calloc (1, sizeof (snd_seq_query_subscribe_t)); + + dbg_printf ("snd_seq_query_subscribe_malloc()=%x\n", *ptr); + if (!*ptr) + return -ENOMEM; + return 0; +} + +/** + * \brief frees a previously allocated #snd_seq_query_subscribe_t + * \param pointer to object to free + */ +void +snd_seq_query_subscribe_free (snd_seq_query_subscribe_t * obj) +{ + dbg_printf ("snd_seq_query_subscribe_free(obj=%x)\n", obj); + free (obj); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_get_addr(info=%x)\n", info); + + return NULL; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_get_index(info=%x)\n", info); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_t(info=%x, index=%d)\n", info, index); + + // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_get_root(info=%x)\n", info); + + return NULL; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_set_root(info=%d, addr=%x)\n", + info, addr); +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_get_type(info=%x)\n", info); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_subscribe_set_type(info=%x, type=%x)\n", + info, type); + + // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_get_port_subscription(seq=%x, sub=%x)\n", seq, sub); + + return 0; // TODO +} + +/** + * \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) +{ + dbg_printf ("snd_seq_query_port_subscribers(seq=%x, subs=%x)\n", seq, subs); + + return 0; // TODO +} + +/** + * \brief Get the real time of a queue_status container + * \param info queue_status container + * \param time real time + * + * \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) +{ + dbg_printf ("snd_seq_queue_status_get_real_time(info=%x)\n", info); + + return NULL; // TODO +} |