Major change to sequencer API.

The sequencer API is totally recoded with the style of "encapsulation"
in other api.
The structure becomes opaque and accessed only via functions.

Other changes:
- There is no longer group in client and port info.
- snd_seq_query_subs_t is renamed to snd_seq_query_subscribe_t.
- snd_seq_delete_port takes only the port id argument instead of
  port_info structure.
- snd_seq_input/output_buffer_size are renamed
  as snd_seq_get_input/output_buffer_size.
  Similarly snd_seq_resize_input/output_buffer are renamed as
  snd_seq_set_input/output_buffer_size.
- snd_seq_get_named_queue is renamed to snd_seq_query_named_queue.
- Sync codes are removed temporarily from API.
- Subscription conditions are accessed via the corresponding functions.
  convert_time is named now as time_update.
- snd_seq_get/set_queue_owner are removed.
  Use snd_seq_get/set_queue_info instead.
- Instrument put/get/remove structure is unified as snd_instr_header_t.
This commit is contained in:
Jaroslav Kysela 2001-07-04 13:54:13 +00:00
parent d23ff765ad
commit 88e5e45151
20 changed files with 4410 additions and 1691 deletions

View file

@ -25,114 +25,10 @@
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <ctype.h>
#include <sys/ioctl.h>
#include "seq_local.h"
/**
* \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;
}
/**
* \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->flags &= ~(SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK);
ev->flags |= SND_SEQ_TIME_STAMP_TICK;
ev->flags |= relative ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS;
ev->time.tick = tick;
ev->queue = q;
}
/**
* \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->flags &= ~( SND_SEQ_TIME_STAMP_MASK | SND_SEQ_TIME_MODE_MASK);
ev->flags |= SND_SEQ_TIME_STAMP_REAL;
ev->flags |= relative ? SND_SEQ_TIME_MODE_REL : SND_SEQ_TIME_MODE_ABS;
ev->time.time = *_time;
ev->queue = q;
}
/**
* \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;
}
/**
* \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;
}
/**
* \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->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
ev->data.ext.len = len;
ev->data.ext.ptr = ptr;
}
/**
* \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;
ev->flags |= SND_SEQ_EVENT_LENGTH_VARUSR;
ev->data.ext.len = len;
ev->data.ext.ptr = ptr;
}
/**
* \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;
memset(&info, 0, sizeof(info));
info.used = use;
return snd_seq_set_queue_client(seq, q, &info);
}
/**
* \brief queue controls - start/stop/continue
* \param seq sequencer handle
@ -141,8 +37,11 @@ int snd_seq_use_queue(snd_seq_t *seq, int q, int use)
* \param value event value
* \param ev event instance
*
* if ev is NULL, send events immediately.
* otherwise, duplicate the given event data.
* 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_event
* apropriately to feed the event.
*/
int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_event_t *ev)
{
@ -156,38 +55,16 @@ int snd_seq_control_queue(snd_seq_t *seq, int q, int type, int value, snd_seq_ev
return snd_seq_event_output(seq, ev);
}
/**
* \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)
{
snd_seq_event_t tmpev;
int result;
if (ev == NULL) {
snd_seq_ev_clear(&tmpev);
ev = &tmpev;
snd_seq_ev_set_direct(ev);
}
/* stop the timer */
result = snd_seq_stop_queue(seq, q, ev);
/* reset queue position */
snd_seq_ev_set_queue_pos_real(ev, q, &rtime->time);
result = snd_seq_event_output(seq, ev);
snd_seq_ev_set_queue_pos_tick(ev, q, rtime->tick);
result = snd_seq_event_output(seq, ev);
/* continue the timer */
result = snd_seq_continue_queue(seq, q, ev);
return result;
}
/**
* \brief create a port - simple version
* \param seq sequencer handle
* \param name the name of the port
* \param caps capability bits
* \param type type bits
* \return the created port number or negative error code
*
* return the port number
* Creates a port with the given capability and type bits.
*/
int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
unsigned int caps, unsigned int type)
@ -199,35 +76,38 @@ int snd_seq_create_simple_port(snd_seq_t *seq, const char *name,
if (name)
strncpy(pinfo.name, name, sizeof(pinfo.name) - 1);
pinfo.capability = caps;
pinfo.cap_group = caps;
pinfo.type = type;
pinfo.midi_channels = 16;
pinfo.midi_voices = 64; /* XXX */
pinfo.synth_voices = 0; /* XXX */
pinfo.kernel = NULL;
result = snd_seq_create_port(seq, &pinfo);
if (result < 0)
return result;
else
return pinfo.port;
return pinfo.addr.port;
}
/**
* \brief delete the port
* \param seq sequencer handle
* \param port port id
* \return 0 on success or negavie error code
*/
int snd_seq_delete_simple_port(snd_seq_t *seq, int port)
{
snd_seq_port_info_t pinfo;
memset(&pinfo, 0, sizeof(pinfo));
pinfo.port = port;
return snd_seq_delete_port(seq, &pinfo);
return snd_seq_delete_port(seq, port);
}
/**
* \brief sipmle subscription (w/o exclusive & time conversion)
* \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.
*/
int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
@ -245,6 +125,13 @@ int snd_seq_connect_from(snd_seq_t *seq, int myport, int src_client, int src_por
/**
* \brief sipmle 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.
*/
int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
@ -261,7 +148,14 @@ int snd_seq_connect_to(snd_seq_t *seq, int myport, int dest_client, int dest_por
}
/**
* \brief sipmle disconnection (w/o exclusive & time conversion)
* \brief simple disconnection
* \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
*
* Remove connection from the given sender client:port
* to the given destination port in the current client.
*/
int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_port)
{
@ -278,7 +172,14 @@ int snd_seq_disconnect_from(snd_seq_t *seq, int myport, int src_client, int src_
}
/**
* \brief sipmle disconnection (w/o exclusive & time conversion)
* \brief simple disconnection
* \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
*
* Remove connection from the given sender client:port
* to the given destination port in the current client.
*/
int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_port)
{
@ -297,8 +198,12 @@ int snd_seq_disconnect_to(snd_seq_t *seq, int myport, int dest_client, int dest_
/*
* set client information
*/
/**
* \brief set client name
* \param seq sequencer handle
* \param name name string
* \return 0 on success or negative error code
*/
int snd_seq_set_client_name(snd_seq_t *seq, const char *name)
{
@ -312,35 +217,10 @@ int snd_seq_set_client_name(snd_seq_t *seq, const char *name)
}
/**
* \brief set client group
*/
int snd_seq_set_client_group(snd_seq_t *seq, const char *name)
{
snd_seq_client_info_t info;
int err;
if ((err = snd_seq_get_client_info(seq, &info)) < 0)
return err;
strncpy(info.group, name, sizeof(info.group) - 1);
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;
int err;
if ((err = snd_seq_get_client_info(seq, &info)) < 0)
return err;
info.filter = filter;
return snd_seq_set_client_info(seq, &info);
}
/**
* \brief set client event filter
* \brief add client event filter
* \param seq sequencer handle
* \param event_type event type to be added
* \return 0 on success or negative error code
*/
int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type)
{
@ -349,15 +229,18 @@ int snd_seq_set_client_event_filter(snd_seq_t *seq, int event_type)
if ((err = snd_seq_get_client_info(seq, &info)) < 0)
return err;
info.filter |= SND_SEQ_FILTER_USE_EVENT;
info.filter |= SNDRV_SEQ_FILTER_USE_EVENT;
snd_seq_set_bit(event_type, info.event_filter);
return snd_seq_set_client_info(seq, &info);
}
/**
* \brief change the output pool size of the given client
* \param seq sequencer handle
* \param size output pool size
* \return 0 on success or negative error code
*/
int snd_seq_set_client_pool_output(snd_seq_t *seq, int size)
int snd_seq_set_client_pool_output(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
@ -370,8 +253,11 @@ int snd_seq_set_client_pool_output(snd_seq_t *seq, int size)
/**
* \brief change the output room size of the given client
* \param seq sequencer handle
* \param size output room size
* \return 0 on success or negative error code
*/
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size)
int snd_seq_set_client_pool_output_room(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
@ -384,8 +270,11 @@ int snd_seq_set_client_pool_output_room(snd_seq_t *seq, int size)
/**
* \brief change the input pool size of the given client
* \param seq sequencer handle
* \param size input pool size
* \return 0 on success or negative error code
*/
int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
int snd_seq_set_client_pool_input(snd_seq_t *seq, size_t size)
{
snd_seq_client_pool_t info;
int err;
@ -398,27 +287,74 @@ int snd_seq_set_client_pool_input(snd_seq_t *seq, int size)
/**
* \brief reset client output pool
* \param seq sequencer handle
* \return 0 on success or negative error code
*/
int snd_seq_reset_pool_output(snd_seq_t *seq)
{
snd_seq_remove_events_t rmp;
struct sndrv_seq_remove_events rmp;
memset(&rmp, 0, sizeof(rmp));
rmp.output = 1;
rmp.remove_mode = 0; /* remove all */
rmp.remove_mode = SNDRV_SEQ_REMOVE_OUTPUT; /* remove all outputs */
return snd_seq_remove_events(seq, &rmp);
}
/**
* \brief reset client input pool
* \param seq sequencer handle
* \return 0 on success or negative error code
*/
int snd_seq_reset_pool_input(snd_seq_t *seq)
{
snd_seq_remove_events_t rmp;
memset(&rmp, 0, sizeof(rmp));
rmp.input = 1;
rmp.remove_mode = 0; /* remove all */
rmp.remove_mode = SNDRV_SEQ_REMOVE_INPUT; /* remove all inputs */
return snd_seq_remove_events(seq, &rmp);
}
/**
* \brief parse the given string and get the sequencer address
* \param seq sequencer handle
* \param addr the address pointer to be returned
* \param arg the string to be parsed
* \return 0 on success or negative error code
*/
int snd_seq_parse_address(snd_seq_t *seq, snd_seq_addr_t *addr, const char *arg)
{
char *p;
int client, port;
assert(seq && addr && arg);
if ((p = strpbrk(arg, ":.")) == NULL)
return -EINVAL;
if ((port = atoi(p + 1)) < 0)
return -EINVAL;
addr->port = port;
if (isdigit(*arg)) {
client = atoi(arg);
if (client < 0)
return -EINVAL;
addr->client = client;
} else {
/* convert from the name */
snd_seq_client_info_t cinfo;
int len;
*p = 0;
len = (int)(p - arg); /* length of client name */
if (len <= 0)
return -EINVAL;
cinfo.client = -1;
while (snd_seq_query_next_client(seq, &cinfo) >= 0) {
if (! strncmp(cinfo.name, arg, len)) {
addr->client = cinfo.client;
return 0;
}
}
return -ENOENT; /* not found */
}
return 0;
}