mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-11-04 13:30:08 -05:00
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:
parent
d23ff765ad
commit
88e5e45151
20 changed files with 4410 additions and 1691 deletions
306
src/seq/seqmid.c
306
src/seq/seqmid.c
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue