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

@ -1,6 +1,6 @@
EXTRA_LTLIBRARIES=libseq.la
libseq_la_SOURCES = seq_hw.c seq.c seqmid.c seq_midi_event.c
libseq_la_SOURCES = seq_hw.c seq.c seq_event.c seqmid.c seq_midi_event.c
noinst_HEADERS = seq_local.h
all: libseq.la

File diff suppressed because it is too large Load diff

55
src/seq/seq_event.c Normal file
View file

@ -0,0 +1,55 @@
/**
* \file seq/seq_event.c
* \author Takashi Iwai <tiwai@suse.de>
* \date 2001
*/
#include "../../include/asoundlib.h"
#define FIXED_EV(x) (_SND_SEQ_TYPE(SND_SEQ_EVFLG_FIXED) | _SND_SEQ_TYPE(x))
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_SAMPLE ... SND_SEQ_EVENT_SAMPLE_PRIVATE1]
= FIXED_EV(SND_SEQ_EVFLG_SAMPLE),
[SND_SEQ_EVENT_USR0 ... SND_SEQ_EVENT_USR9]
= FIXED_EV(SND_SEQ_EVFLG_RAW) | FIXED_EV(SND_SEQ_EVFLG_USERS),
[SND_SEQ_EVENT_INSTR_BEGIN ... SND_SEQ_EVENT_INSTR_CHANGE]
= _SND_SEQ_TYPE(SND_SEQ_EVFLG_INSTR) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_VARUSR),
[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),
#if 0 // NYI
[SND_SEQ_EVENT_IPCSHM]
= _SND_SEQ_TYPE(SND_SEQ_EVFLG_IPC),
[SND_SEQ_EVENT_USR_VARIPC0 ... SND_SEQ_EVENT_USR_VARIPC4]
= _SND_SEQ_TYPE(SND_SEQ_EVFLG_IPC) | _SND_SEQ_TYPE(SND_SEQ_EVFLG_USERS),
#endif
[SND_SEQ_EVENT_NONE]
= FIXED_EV(SND_SEQ_EVFLG_NONE),
};

View file

@ -174,7 +174,7 @@ static int snd_seq_hw_unsubscribe_port(snd_seq_t *seq, snd_seq_port_subscribe_t
return 0;
}
static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subs_t * subs)
static int snd_seq_hw_query_port_subscribers(snd_seq_t *seq, snd_seq_query_subscribe_t * subs)
{
snd_seq_hw_t *hw = seq->private_data;
if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_QUERY_SUBS, subs) < 0) {
@ -214,26 +214,6 @@ static int snd_seq_hw_set_queue_tempo(snd_seq_t *seq, snd_seq_queue_tempo_t * te
return 0;
}
static int snd_seq_hw_get_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
{
snd_seq_hw_t *hw = seq->private_data;
if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER, owner) < 0) {
SYSERR("SNDRV_SEQ_IOCTL_GET_QUEUE_OWNER failed");
return -errno;
}
return 0;
}
static int snd_seq_hw_set_queue_owner(snd_seq_t *seq, snd_seq_queue_owner_t * owner)
{
snd_seq_hw_t *hw = seq->private_data;
if (ioctl(hw->fd, SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER, owner) < 0) {
SYSERR("SNDRV_SEQ_IOCTL_SET_QUEUE_OWNER failed");
return -errno;
}
return 0;
}
static int snd_seq_hw_get_queue_timer(snd_seq_t *seq, snd_seq_queue_timer_t * timer)
{
snd_seq_hw_t *hw = seq->private_data;
@ -409,8 +389,6 @@ snd_seq_ops_t snd_seq_hw_ops = {
get_queue_status: snd_seq_hw_get_queue_status,
get_queue_tempo: snd_seq_hw_get_queue_tempo,
set_queue_tempo: snd_seq_hw_set_queue_tempo,
get_queue_owner: snd_seq_hw_get_queue_owner,
set_queue_owner: snd_seq_hw_set_queue_owner,
get_queue_timer: snd_seq_hw_get_queue_timer,
set_queue_timer: snd_seq_hw_set_queue_timer,
get_queue_client: snd_seq_hw_get_queue_client,

View file

@ -32,6 +32,9 @@
#define SND_SEQ_IBUF_SIZE 500 /* in event_size aligned */
#define DEFAULT_TMPBUF_SIZE 20
typedef struct sndrv_seq_queue_client snd_seq_queue_client_t;
typedef struct {
int (*close)(snd_seq_t *seq);
int (*nonblock)(snd_seq_t *seq, int nonblock);
@ -45,12 +48,10 @@ typedef struct {
int (*get_port_subscription)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
int (*subscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
int (*unsubscribe_port)(snd_seq_t *seq, snd_seq_port_subscribe_t * sub);
int (*query_port_subscribers)(snd_seq_t *seq, snd_seq_query_subs_t * subs);
int (*query_port_subscribers)(snd_seq_t *seq, snd_seq_query_subscribe_t * subs);
int (*get_queue_status)(snd_seq_t *seq, snd_seq_queue_status_t * status);
int (*get_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
int (*set_queue_tempo)(snd_seq_t *seq, snd_seq_queue_tempo_t * tempo);
int (*get_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
int (*set_queue_owner)(snd_seq_t *seq, snd_seq_queue_owner_t * owner);
int (*get_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
int (*set_queue_timer)(snd_seq_t *seq, snd_seq_queue_timer_t * timer);
int (*get_queue_client)(snd_seq_t *seq, snd_seq_queue_client_t * client);

View file

@ -72,31 +72,31 @@ static struct status_event_list_t {
event_decode_t decode;
} status_event[] = {
/* 0x80 - 0xf0 */
{SND_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
{SND_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
{SND_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
{SND_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
{SND_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
{SND_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
{SND_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */
{SNDRV_SEQ_EVENT_NOTEOFF, 2, note_event, note_decode},
{SNDRV_SEQ_EVENT_NOTEON, 2, note_event, note_decode},
{SNDRV_SEQ_EVENT_KEYPRESS, 2, note_event, note_decode},
{SNDRV_SEQ_EVENT_CONTROLLER, 2, two_param_ctrl_event, two_param_decode},
{SNDRV_SEQ_EVENT_PGMCHANGE, 1, one_param_ctrl_event, one_param_decode},
{SNDRV_SEQ_EVENT_CHANPRESS, 1, one_param_ctrl_event, one_param_decode},
{SNDRV_SEQ_EVENT_PITCHBEND, 2, pitchbend_ctrl_event, pitchbend_decode},
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf0 */
/* 0xf0 - 0xff */
{SND_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
{SND_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
{SND_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
{SND_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */
{SND_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */
{SND_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */
{SND_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
{SND_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
{SND_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
{SND_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */
{SND_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
{SND_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
{SNDRV_SEQ_EVENT_SYSEX, 1, NULL, NULL}, /* sysex: 0xf0 */
{SNDRV_SEQ_EVENT_QFRAME, 1, one_param_event, one_param_decode}, /* 0xf1 */
{SNDRV_SEQ_EVENT_SONGPOS, 2, songpos_event, songpos_decode}, /* 0xf2 */
{SNDRV_SEQ_EVENT_SONGSEL, 1, one_param_event, one_param_decode}, /* 0xf3 */
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf4 */
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf5 */
{SNDRV_SEQ_EVENT_TUNE_REQUEST, 0, NULL, NULL}, /* 0xf6 */
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf7 */
{SNDRV_SEQ_EVENT_CLOCK, 0, NULL, NULL}, /* 0xf8 */
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xf9 */
{SNDRV_SEQ_EVENT_START, 0, NULL, NULL}, /* 0xfa */
{SNDRV_SEQ_EVENT_CONTINUE, 0, NULL, NULL}, /* 0xfb */
{SNDRV_SEQ_EVENT_STOP, 0, NULL, NULL}, /* 0xfc */
{SNDRV_SEQ_EVENT_NONE, 0, NULL, NULL}, /* 0xfd */
{SNDRV_SEQ_EVENT_SENSING, 0, NULL, NULL}, /* 0xfe */
{SNDRV_SEQ_EVENT_RESET, 0, NULL, NULL}, /* 0xff */
};
static int extra_decode_ctrl14(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
@ -105,9 +105,9 @@ static struct extra_event_list_t {
int event;
int (*decode)(snd_midi_event_t *dev, unsigned char *buf, int len, snd_seq_event_t *ev);
} extra_event[] = {
{SND_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
/*{SND_SEQ_EVENT_NONREGPARAM, extra_decode_nrpn},*/
/*{SND_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/
{SNDRV_SEQ_EVENT_CONTROL14, extra_decode_ctrl14},
/*{SNDRV_SEQ_EVENT_NONREGPARAM, extra_decode_nrpn},*/
/*{SNDRV_SEQ_EVENT_REGPARAM, extra_decode_rpn},*/
};
#define numberof(ary) (sizeof(ary)/sizeof(ary[0]))
@ -201,7 +201,7 @@ long snd_midi_event_encode(snd_midi_event_t *dev, unsigned char *buf, long count
long result = 0;
int rc;
ev->type = SND_SEQ_EVENT_NONE;
ev->type = SNDRV_SEQ_EVENT_NONE;
while (count-- > 0) {
rc = snd_midi_event_encode_byte(dev, *buf++, ev);
@ -230,8 +230,8 @@ int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev
if (c >= MIDI_CMD_COMMON_CLOCK) {
/* real-time event */
ev->type = status_event[ST_SPECIAL + c - 0xf0].event;
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
return 1;
}
@ -258,16 +258,16 @@ int snd_midi_event_encode_byte(snd_midi_event_t *dev, int c, snd_seq_event_t *ev
}
if (dev->qlen == 0) {
ev->type = status_event[dev->type].event;
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SND_SEQ_EVENT_LENGTH_FIXED;
ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SNDRV_SEQ_EVENT_LENGTH_FIXED;
if (status_event[dev->type].encode) /* set data values */
status_event[dev->type].encode(dev, ev);
rc = 1;
} else if (dev->type == ST_SYSEX) {
if (c == MIDI_CMD_COMMON_SYSEX_END ||
dev->read >= dev->bufsize) {
ev->flags &= ~SND_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SND_SEQ_EVENT_LENGTH_VARIABLE;
ev->flags &= ~SNDRV_SEQ_EVENT_LENGTH_MASK;
ev->flags |= SNDRV_SEQ_EVENT_LENGTH_VARIABLE;
ev->data.ext.len = dev->read;
ev->data.ext.ptr = dev->buf;
if (c != MIDI_CMD_COMMON_SYSEX_END)
@ -333,7 +333,7 @@ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count
long qlen;
unsigned int type;
if (ev->type == SND_SEQ_EVENT_NONE)
if (ev->type == SNDRV_SEQ_EVENT_NONE)
return -ENOENT;
for (type = 0; type < numberof(status_event); type++) {
@ -358,9 +358,9 @@ long snd_midi_event_decode(snd_midi_event_t *dev, unsigned char *buf, long count
qlen = ev->data.ext.len;
if (count < qlen)
return -ENOMEM;
switch (ev->flags & SND_SEQ_EVENT_LENGTH_MASK) {
case SND_SEQ_EVENT_LENGTH_FIXED:
case SND_SEQ_EVENT_LENGTH_VARIPC:
switch (ev->flags & SNDRV_SEQ_EVENT_LENGTH_MASK) {
case SNDRV_SEQ_EVENT_LENGTH_FIXED:
case SNDRV_SEQ_EVENT_LENGTH_VARIPC:
return -EINVAL; /* invalid event */
}
memcpy(dev->buf, ev->data.ext.ptr, qlen);

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;
}