mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-29 05:40:25 -04:00
Sequencer queue remove events
This commit is contained in:
parent
b1ad5e3fcd
commit
3555271122
2 changed files with 133 additions and 4 deletions
|
|
@ -55,6 +55,7 @@ int snd_seq_event_input(snd_seq_t *handle, snd_seq_event_t **ev);
|
|||
int snd_seq_flush_output(snd_seq_t *handle);
|
||||
int snd_seq_drain_output(snd_seq_t *handle);
|
||||
int snd_seq_drain_input(snd_seq_t *handle);
|
||||
int snd_seq_remove_events(snd_seq_t *handle, snd_seq_remove_events_t *info);
|
||||
/* misc */
|
||||
void snd_seq_set_bit(int nr, void *array);
|
||||
int snd_seq_change_bit(int nr, void *array);
|
||||
|
|
|
|||
136
src/seq/seq.c
136
src/seq/seq.c
|
|
@ -630,10 +630,9 @@ int snd_seq_flush_output(snd_seq_t *seq)
|
|||
if (seq->obufused <= 0)
|
||||
return 0;
|
||||
result = write(seq->fd, seq->obuf, seq->obufused);
|
||||
if (result < 0) {
|
||||
snd_seq_drain_output(seq);
|
||||
if (result < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (result < seq->obufused)
|
||||
memmove(seq->obuf, seq->obuf + result, seq->obufused - result);
|
||||
seq->obufused -= result;
|
||||
|
|
@ -642,12 +641,140 @@ int snd_seq_flush_output(snd_seq_t *seq)
|
|||
|
||||
int snd_seq_drain_output(snd_seq_t *seq)
|
||||
{
|
||||
snd_seq_remove_events_t rminfo;
|
||||
|
||||
if (!seq)
|
||||
return -EINVAL;
|
||||
seq->obufused = 0;
|
||||
|
||||
memset(&rminfo, 0, sizeof(rminfo));
|
||||
rminfo.output = 1;
|
||||
|
||||
snd_seq_remove_events(seq, &rminfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* compare timestamp between events */
|
||||
/* return 1 if a >= b; otherwise return 0 */
|
||||
static inline int snd_seq_compare_tick_time(snd_seq_tick_time_t *a,
|
||||
snd_seq_tick_time_t *b)
|
||||
{
|
||||
/* compare ticks */
|
||||
return (*a >= *b);
|
||||
}
|
||||
|
||||
static inline int snd_seq_compare_real_time(snd_seq_real_time_t *a,
|
||||
snd_seq_real_time_t *b)
|
||||
{
|
||||
/* compare real time */
|
||||
if (a->tv_sec > b->tv_sec)
|
||||
return 1;
|
||||
if ((a->tv_sec == b->tv_sec) && (a->tv_nsec >= b->tv_nsec))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Routine to match events to be removed */
|
||||
static int remove_match(snd_seq_remove_events_t *info,
|
||||
snd_seq_event_t *ev)
|
||||
{
|
||||
int res;
|
||||
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_DEST) {
|
||||
if (ev->dest.client != info->dest.client ||
|
||||
ev->dest.port != info->dest.port)
|
||||
return 0;
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_DEST_CHANNEL) {
|
||||
if (ev->dest.channel != info->dest.channel)
|
||||
return 0;
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_TIME_AFTER) {
|
||||
if (info->tick)
|
||||
res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
|
||||
else
|
||||
res = snd_seq_compare_real_time(&ev->time.real, &info->time.real);
|
||||
if (!res)
|
||||
return 0;
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_TIME_BEFORE) {
|
||||
if (info->tick)
|
||||
res = snd_seq_compare_tick_time(&ev->time.tick, &info->time.tick);
|
||||
else
|
||||
res = snd_seq_compare_real_time(&ev->time.real, &info->time.real);
|
||||
if (res)
|
||||
return 0;
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_EVENT_TYPE) {
|
||||
if (ev->type != info->type)
|
||||
return 0;
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_IGNORE_OFF) {
|
||||
/* Do not remove off events */
|
||||
switch (ev->type) {
|
||||
case SND_SEQ_EVENT_NOTEOFF:
|
||||
/* case SND_SEQ_EVENT_SAMPLE_STOP: */
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (info->remove_mode & SND_SEQ_REMOVE_TAG_MATCH) {
|
||||
if (info->tag != ev->tag)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove events from the sequencer queues.
|
||||
*/
|
||||
int snd_seq_remove_events(snd_seq_t *seq, snd_seq_remove_events_t *rmp)
|
||||
{
|
||||
if (rmp->input) {
|
||||
/*
|
||||
* First deal with any events that are still buffered
|
||||
* in the library.
|
||||
*/
|
||||
/* Input not implemented */
|
||||
}
|
||||
|
||||
if (rmp->output) {
|
||||
/*
|
||||
* First deal with any events that are still buffered
|
||||
* in the library.
|
||||
*/
|
||||
if (rmp->remove_mode == 0) {
|
||||
/* The simple case - remove all */
|
||||
seq->obufused = 0;
|
||||
} else {
|
||||
char *ep;
|
||||
int len;
|
||||
snd_seq_event_t *ev;
|
||||
|
||||
ep = seq->obuf;
|
||||
while (ep - seq->obuf < seq->obufused) {
|
||||
|
||||
ev = (snd_seq_event_t *) ep;
|
||||
len = snd_seq_event_length(ev);
|
||||
|
||||
if (remove_match(rmp, ev)) {
|
||||
|
||||
/* Remove event */
|
||||
memcpy(ep, ep + len, len);
|
||||
seq->obufused -= len;
|
||||
} else {
|
||||
ep += len;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (ioctl(seq->fd, SND_SEQ_IOCTL_REMOVE_EVENTS, rmp) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
int snd_seq_drain_input(snd_seq_t *seq)
|
||||
{
|
||||
if (!seq)
|
||||
|
|
@ -696,3 +823,4 @@ int snd_seq_get_bit(int nr, void *array)
|
|||
return ((((unsigned int *)array)[nr >> 5]) & (1UL << (nr & 31))) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue