mirror of
https://github.com/alsa-project/alsa-utils
synced 2024-11-10 03:55:41 +01:00
aplaymidi: handle big SysEx commands
Make sure that the sequencer output buffer is big enough to handle all events that we send, and split large SysEx commands into one-second chunks so that the sequencer kernel code can handle them.
This commit is contained in:
parent
815fc4bea0
commit
4de3d5a273
1 changed files with 35 additions and 1 deletions
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* aplaymidi.c - play Standard MIDI Files to sequencer port(s)
|
* aplaymidi.c - play Standard MIDI Files to sequencer port(s)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2004 Clemens Ladisch <clemens@ladisch.de>
|
* Copyright (c) 2004-2006 Clemens Ladisch <clemens@ladisch.de>
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
@ -31,6 +31,8 @@
|
||||||
#include "aconfig.h"
|
#include "aconfig.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#define MIDI_BYTES_PER_SEC 3125
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A MIDI event after being parsed/loaded from the file.
|
* A MIDI event after being parsed/loaded from the file.
|
||||||
* There could be made a case for using snd_seq_event_t instead.
|
* There could be made a case for using snd_seq_event_t instead.
|
||||||
|
@ -601,6 +603,37 @@ static void cleanup_file_data(void)
|
||||||
tracks = NULL;
|
tracks = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_big_sysex(snd_seq_event_t *ev)
|
||||||
|
{
|
||||||
|
unsigned int length;
|
||||||
|
ssize_t event_size;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
length = ev->data.ext.len;
|
||||||
|
if (length > MIDI_BYTES_PER_SEC)
|
||||||
|
ev->data.ext.len = MIDI_BYTES_PER_SEC;
|
||||||
|
event_size = snd_seq_event_length(ev);
|
||||||
|
if (event_size + 1 > snd_seq_get_output_buffer_size(seq)) {
|
||||||
|
err = snd_seq_drain_output(seq);
|
||||||
|
check_snd("drain output", err);
|
||||||
|
err = snd_seq_set_output_buffer_size(seq, event_size + 1);
|
||||||
|
check_snd("set output buffer size", err);
|
||||||
|
}
|
||||||
|
while (length > MIDI_BYTES_PER_SEC) {
|
||||||
|
err = snd_seq_event_output(seq, ev);
|
||||||
|
check_snd("output event", err);
|
||||||
|
err = snd_seq_drain_output(seq);
|
||||||
|
check_snd("drain output", err);
|
||||||
|
err = snd_seq_sync_output_queue(seq);
|
||||||
|
check_snd("sync output", err);
|
||||||
|
if (sleep(1))
|
||||||
|
fatal("aborted");
|
||||||
|
ev->data.ext.ptr += MIDI_BYTES_PER_SEC;
|
||||||
|
length -= MIDI_BYTES_PER_SEC;
|
||||||
|
}
|
||||||
|
ev->data.ext.len = length;
|
||||||
|
}
|
||||||
|
|
||||||
static void play_midi(void)
|
static void play_midi(void)
|
||||||
{
|
{
|
||||||
snd_seq_event_t ev;
|
snd_seq_event_t ev;
|
||||||
|
@ -684,6 +717,7 @@ static void play_midi(void)
|
||||||
case SND_SEQ_EVENT_SYSEX:
|
case SND_SEQ_EVENT_SYSEX:
|
||||||
snd_seq_ev_set_variable(&ev, event->data.length,
|
snd_seq_ev_set_variable(&ev, event->data.length,
|
||||||
event->sysex);
|
event->sysex);
|
||||||
|
handle_big_sysex(&ev);
|
||||||
break;
|
break;
|
||||||
case SND_SEQ_EVENT_TEMPO:
|
case SND_SEQ_EVENT_TEMPO:
|
||||||
snd_seq_ev_set_fixed(&ev);
|
snd_seq_ev_set_fixed(&ev);
|
||||||
|
|
Loading…
Reference in a new issue