summaryrefslogtreecommitdiffstats
path: root/src/base/test/seq
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-03-01 18:37:05 +0000
commit145364a8af6a1fec06556221e66d4b724a62fc9a (patch)
tree53bd71a544008c518034f208d64c932dc2883f50 /src/base/test/seq
downloadrosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.tar.gz
rosegarden-145364a8af6a1fec06556221e66d4b724a62fc9a.zip
Added old abandoned KDE3 version of the RoseGarden MIDI tool
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/rosegarden@1097595 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/base/test/seq')
-rw-r--r--src/base/test/seq/Makefile6
-rw-r--r--src/base/test/seq/complainer.c74
-rw-r--r--src/base/test/seq/generator.c96
-rw-r--r--src/base/test/seq/queue-timer-jack.c166
-rw-r--r--src/base/test/seq/queue-timer.c123
5 files changed, 465 insertions, 0 deletions
diff --git a/src/base/test/seq/Makefile b/src/base/test/seq/Makefile
new file mode 100644
index 0000000..c32946e
--- /dev/null
+++ b/src/base/test/seq/Makefile
@@ -0,0 +1,6 @@
+
+all: complainer generator queue-timer queue-timer-jack
+
+%: %.c
+ cc $< -o $@ -ljack -lasound
+
diff --git a/src/base/test/seq/complainer.c b/src/base/test/seq/complainer.c
new file mode 100644
index 0000000..afe0a7f
--- /dev/null
+++ b/src/base/test/seq/complainer.c
@@ -0,0 +1,74 @@
+
+#include <alsa/asoundlib.h>
+#include <alsa/seq.h>
+#include <sys/time.h>
+#include <sched.h>
+
+void
+callback(snd_seq_t *handle)
+{
+ snd_seq_event_t *ev = 0;
+
+ do {
+ if (snd_seq_event_input(handle, &ev) > 0) {
+
+ if (ev->type == SND_SEQ_EVENT_NOTEON) {
+
+ struct timeval tv;
+ static long last_usec = 0;
+ int pitch = ev->data.note.note;
+
+ snd_seq_timestamp_t evt = ev->time;
+
+ gettimeofday(&tv, 0);
+ printf("pitch %d at %ld sec %ld usec, off by %ld usec\n",
+ pitch, tv.tv_sec, tv.tv_usec, tv.tv_usec - ((last_usec + 500000) % 1000000));
+
+ last_usec = tv.tv_usec;
+ }
+ }
+
+ } while (snd_seq_event_input_pending(handle, 0) > 0);
+}
+
+int
+main(int argc, char **argv)
+{
+ snd_seq_t *handle;
+ int portid;
+ int npfd;
+ struct pollfd *pfd;
+ struct sched_param param;
+
+ if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
+ fprintf(stderr, "failed to open ALSA sequencer interface\n");
+ return 1;
+ }
+
+ snd_seq_set_client_name(handle, "complainer");
+
+ if ((portid = snd_seq_create_simple_port
+ (handle, "complainer",
+ SND_SEQ_PORT_CAP_WRITE | SND_SEQ_PORT_CAP_SUBS_WRITE, 0)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer port\n");
+ return 1;
+ }
+
+ npfd = snd_seq_poll_descriptors_count(handle, POLLIN);
+ pfd = (struct pollfd *)alloca(npfd * sizeof(struct pollfd));
+ snd_seq_poll_descriptors(handle, pfd, npfd, POLLIN);
+
+ param.sched_priority = 99;
+ if (sched_setscheduler(0, SCHED_FIFO, &param)) {
+ perror("failed to set high-priority scheduler");
+ }
+
+ printf("ready\n", npfd);
+
+ while (1) {
+ if (poll(pfd, npfd, 100000) > 0) {
+ callback(handle);
+ }
+ }
+}
+
diff --git a/src/base/test/seq/generator.c b/src/base/test/seq/generator.c
new file mode 100644
index 0000000..9f64d61
--- /dev/null
+++ b/src/base/test/seq/generator.c
@@ -0,0 +1,96 @@
+
+#include <alsa/asoundlib.h>
+#include <alsa/seq.h>
+#include <sys/time.h>
+
+int
+main(int argc, char **argv)
+{
+ snd_seq_t *handle;
+ int portid;
+ int npfd;
+ struct pollfd *pfd;
+ int queue;
+ int i;
+ int rval;
+ int target;
+ snd_seq_queue_timer_t *timer;
+ snd_timer_id_t *timerid;
+
+ if (argc != 2) {
+ fprintf(stderr, "usage: generator <target-client-id>\n");
+ exit(2);
+ }
+ target = atoi(argv[1]);
+
+ if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
+ fprintf(stderr, "failed to open ALSA sequencer interface\n");
+ return 1;
+ }
+
+ snd_seq_set_client_name(handle, "generator");
+
+ if ((portid = snd_seq_create_simple_port
+ (handle, "generator",
+ SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, 0)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer port\n");
+ return 1;
+ }
+
+ if ((queue = snd_seq_alloc_queue(handle)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer queue\n");
+ return 1;
+ }
+/*
+ snd_seq_queue_timer_alloca(&timer);
+ snd_seq_get_queue_timer(handle, queue, timer);
+ snd_timer_id_alloca(&timerid);
+ snd_timer_id_set_class(timerid, SND_TIMER_CLASS_PCM);
+ snd_timer_id_set_sclass(timerid, SND_TIMER_SCLASS_NONE);
+ snd_timer_id_set_card(timerid, 0);
+ snd_timer_id_set_device(timerid, 0);
+ snd_timer_id_set_subdevice(timerid, 0);
+ snd_seq_queue_timer_set_id(timer, timerid);
+ snd_seq_set_queue_timer(handle, queue, timer);
+*/
+ snd_seq_start_queue(handle, queue, 0);
+
+ // stuff two minutes worth of events on the queue
+ for (i = 0; i < 240; ++i) {
+ snd_seq_real_time_t rtime;
+ rtime.tv_sec = i / 2;
+ rtime.tv_nsec = (i % 2) * 500000000;
+ snd_seq_event_t ev;
+ snd_seq_ev_clear(&ev);
+ snd_seq_ev_set_source(&ev, portid);
+ snd_seq_ev_set_dest(&ev, target, 0);
+ snd_seq_ev_schedule_real(&ev, queue, 0, &rtime);
+ snd_seq_ev_set_noteon(&ev, 0, 64, 127);
+ if ((rval = snd_seq_event_output(handle, &ev)) < 0) {
+ fprintf(stderr, "failed to write event: %s", snd_strerror(rval));
+ }
+ }
+
+ snd_seq_drain_output(handle);
+
+ for (i = 0; i < 120; ++i) {
+ snd_seq_queue_status_t *status;
+ const snd_seq_real_time_t *rtime;
+ struct timeval tv;
+
+ snd_seq_queue_status_alloca(&status);
+
+ snd_seq_get_queue_status(handle, queue, status);
+ rtime = snd_seq_queue_status_get_real_time(status);
+
+ gettimeofday(&tv, 0);
+
+ fprintf(stderr, " real time: %ld sec, %ld usec\nqueue time: %ld sec, %ld usec (diff to real time %ld sec %ld usec)\n",
+ tv.tv_sec, tv.tv_usec,
+ rtime->tv_sec, rtime->tv_nsec / 1000,
+ tv.tv_sec - rtime->tv_sec, tv.tv_usec - (rtime->tv_nsec / 1000));
+
+ sleep(1);
+ }
+}
+
diff --git a/src/base/test/seq/queue-timer-jack.c b/src/base/test/seq/queue-timer-jack.c
new file mode 100644
index 0000000..2648e94
--- /dev/null
+++ b/src/base/test/seq/queue-timer-jack.c
@@ -0,0 +1,166 @@
+
+#include <alsa/asoundlib.h>
+#include <alsa/seq.h>
+#include <jack/jack.h>
+#include <sys/time.h>
+
+static jack_nframes_t sample_frames = 0;
+
+void normalize(struct timeval *tv)
+{
+ if (tv->tv_sec == 0) {
+ while (tv->tv_usec <= -1000000) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ } else if (tv->tv_sec < 0) {
+ while (tv->tv_usec <= -1000000) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ while (tv->tv_usec > 0) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ } else {
+ while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ while (tv->tv_usec < 0) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ }
+}
+
+int
+jack_process(jack_nframes_t nframes, void *arg)
+{
+ sample_frames += nframes;
+}
+
+jack_nframes_t
+rt_to_frame(struct timeval tv, jack_nframes_t sample_rate)
+{
+ if (tv.tv_sec < 0) tv.tv_sec = -tv.tv_sec;
+ if (tv.tv_usec < 0) tv.tv_usec = -tv.tv_usec;
+ return
+ tv.tv_sec * sample_rate +
+ ((tv.tv_usec / 1000) * sample_rate) / 1000 +
+ ((tv.tv_usec - 1000 * (tv.tv_usec / 1000)) * sample_rate) / 1000000;
+}
+
+int
+main(int argc, char **argv)
+{
+ snd_seq_t *handle;
+ int portid;
+ int npfd;
+ struct pollfd *pfd;
+ int queue;
+ int i;
+ int rval;
+ struct timeval starttv;
+ int countdown = -1;
+ snd_seq_queue_timer_t *timer;
+ snd_timer_id_t *timerid;
+ jack_client_t *jclient;
+ jack_nframes_t sample_rate;
+
+ if ((jclient = jack_client_new("queue-timer-jack")) == 0) {
+ fprintf(stderr, "failed to connect to JACK server\n");
+ return 1;
+ }
+
+ jack_set_process_callback(jclient, jack_process, 0);
+
+ sample_rate = jack_get_sample_rate(jclient);
+
+ if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
+ fprintf(stderr, "failed to open ALSA sequencer interface\n");
+ return 1;
+ }
+
+ snd_seq_set_client_name(handle, "generator");
+
+ if ((portid = snd_seq_create_simple_port
+ (handle, "generator",
+ SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, 0)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer port\n");
+ return 1;
+ }
+
+ if ((queue = snd_seq_alloc_queue(handle)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer queue\n");
+ return 1;
+ }
+
+ snd_seq_queue_timer_alloca(&timer);
+ snd_seq_get_queue_timer(handle, queue, timer);
+ snd_timer_id_alloca(&timerid);
+
+ /* To test a PCM timer: */
+/*
+ snd_timer_id_set_class(timerid, SND_TIMER_CLASS_PCM);
+ snd_timer_id_set_sclass(timerid, SND_TIMER_SCLASS_NONE);
+ snd_timer_id_set_card(timerid, 0);
+ snd_timer_id_set_device(timerid, 0);
+ snd_timer_id_set_subdevice(timerid, 0);
+*/
+
+ /* To test the system timer: */
+ snd_timer_id_set_class(timerid, SND_TIMER_CLASS_GLOBAL);
+ snd_timer_id_set_sclass(timerid, SND_TIMER_SCLASS_NONE);
+ snd_timer_id_set_device(timerid, SND_TIMER_GLOBAL_SYSTEM);
+
+ snd_seq_queue_timer_set_id(timer, timerid);
+ snd_seq_set_queue_timer(handle, queue, timer);
+
+ if (jack_activate(jclient)) {
+ fprintf (stderr, "cannot activate jack client");
+ exit(1);
+ }
+
+ snd_seq_start_queue(handle, queue, 0);
+ snd_seq_drain_output(handle);
+
+ gettimeofday(&starttv, 0);
+
+ while (countdown != 0) {
+
+ snd_seq_queue_status_t *status;
+ const snd_seq_real_time_t *rtime;
+ struct timeval tv, qtv, jtv, diff, jdiff;
+ jack_nframes_t frames_now;
+
+ snd_seq_queue_status_alloca(&status);
+
+ snd_seq_get_queue_status(handle, queue, status);
+ rtime = snd_seq_queue_status_get_real_time(status);
+
+ gettimeofday(&tv, 0);
+
+ frames_now = sample_frames;
+ fprintf(stderr, " frames: %ld\n", frames_now);
+
+ qtv.tv_sec = rtime->tv_sec;
+ qtv.tv_usec = rtime->tv_nsec / 1000;
+
+ tv.tv_sec -= starttv.tv_sec;
+ tv.tv_usec -= starttv.tv_usec;
+ normalize(&tv);
+
+ jtv.tv_sec = frames_now / sample_rate;
+ frames_now -= jtv.tv_sec * sample_rate;
+ jtv.tv_usec = (int)(((float)frames_now * 1000000) / sample_rate);
+
+ diff.tv_sec = tv.tv_sec - qtv.tv_sec;
+ diff.tv_usec = tv.tv_usec - qtv.tv_usec;
+ normalize(&diff);
+
+ jdiff.tv_sec = jtv.tv_sec - qtv.tv_sec;
+ jdiff.tv_usec = jtv.tv_usec - qtv.tv_usec;
+ normalize(&jdiff);
+
+ fprintf(stderr, " real time: %12ld sec %8ld usec /%12ld frames\nqueue time: %12ld sec %8ld usec /%12ld frames\n jack time: %12ld sec %8ld usec /%12ld frames\n rq diff: %12ld sec %8ld usec /%12ld frames\n jq diff: %12ld sec %8ld usec /%12ld frames\n",
+ tv.tv_sec, tv.tv_usec, rt_to_frame(tv, sample_rate),
+ qtv.tv_sec, qtv.tv_usec, rt_to_frame(qtv, sample_rate),
+ jtv.tv_sec, jtv.tv_usec, rt_to_frame(jtv, sample_rate),
+ diff.tv_sec, diff.tv_usec, rt_to_frame(diff, sample_rate),
+ jdiff.tv_sec, jdiff.tv_usec, rt_to_frame(jdiff, sample_rate));
+
+ fprintf(stderr, "\n");
+ struct timespec ts;
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ nanosleep(&ts, 0);
+ }
+}
+
diff --git a/src/base/test/seq/queue-timer.c b/src/base/test/seq/queue-timer.c
new file mode 100644
index 0000000..2b7bac4
--- /dev/null
+++ b/src/base/test/seq/queue-timer.c
@@ -0,0 +1,123 @@
+
+#include <alsa/asoundlib.h>
+#include <alsa/seq.h>
+#include <sys/time.h>
+
+void normalize(struct timeval *tv)
+{
+ if (tv->tv_sec == 0) {
+ while (tv->tv_usec <= -1000000) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ } else if (tv->tv_sec < 0) {
+ while (tv->tv_usec <= -1000000) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ while (tv->tv_usec > 0) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ } else {
+ while (tv->tv_usec >= 1000000) { tv->tv_usec -= 1000000; ++tv->tv_sec; }
+ while (tv->tv_usec < 0) { tv->tv_usec += 1000000; --tv->tv_sec; }
+ }
+}
+
+int
+main(int argc, char **argv)
+{
+ snd_seq_t *handle;
+ int portid;
+ int npfd;
+ struct pollfd *pfd;
+ int queue;
+ int i;
+ int rval;
+ struct timeval starttv, prevdiff;
+ int countdown = -1;
+ snd_seq_queue_timer_t *timer;
+ snd_timer_id_t *timerid;
+
+ if (snd_seq_open(&handle, "hw", SND_SEQ_OPEN_DUPLEX, 0) < 0) {
+ fprintf(stderr, "failed to open ALSA sequencer interface\n");
+ return 1;
+ }
+
+ snd_seq_set_client_name(handle, "generator");
+
+ if ((portid = snd_seq_create_simple_port
+ (handle, "generator",
+ SND_SEQ_PORT_CAP_READ | SND_SEQ_PORT_CAP_SUBS_READ, 0)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer port\n");
+ return 1;
+ }
+
+ if ((queue = snd_seq_alloc_queue(handle)) < 0) {
+ fprintf(stderr, "failed to create ALSA sequencer queue\n");
+ return 1;
+ }
+/*
+ snd_seq_queue_timer_alloca(&timer);
+ snd_seq_get_queue_timer(handle, queue, timer);
+ snd_timer_id_alloca(&timerid);
+ snd_timer_id_set_class(timerid, SND_TIMER_CLASS_PCM);
+ snd_timer_id_set_sclass(timerid, SND_TIMER_SCLASS_NONE);
+ snd_timer_id_set_card(timerid, 0);
+ snd_timer_id_set_device(timerid, 0);
+ snd_timer_id_set_subdevice(timerid, 0);
+ snd_seq_queue_timer_set_id(timer, timerid);
+ snd_seq_set_queue_timer(handle, queue, timer);
+*/
+ snd_seq_start_queue(handle, queue, 0);
+ snd_seq_drain_output(handle);
+
+ gettimeofday(&starttv, 0);
+ prevdiff.tv_sec = 0;
+ prevdiff.tv_usec = 0;
+
+ while (countdown != 0) {
+
+ snd_seq_queue_status_t *status;
+ const snd_seq_real_time_t *rtime;
+ struct timeval tv, diff, diffdiff;
+
+ snd_seq_queue_status_alloca(&status);
+
+ snd_seq_get_queue_status(handle, queue, status);
+ rtime = snd_seq_queue_status_get_real_time(status);
+
+ gettimeofday(&tv, 0);
+
+ tv.tv_sec -= starttv.tv_sec;
+ tv.tv_usec -= starttv.tv_usec;
+ normalize(&tv);
+
+ diff.tv_sec = tv.tv_sec - rtime->tv_sec;
+ diff.tv_usec = tv.tv_usec - rtime->tv_nsec / 1000;
+ normalize(&diff);
+
+ diffdiff.tv_sec = diff.tv_sec - prevdiff.tv_sec;
+ diffdiff.tv_usec = diff.tv_usec - prevdiff.tv_usec;
+ normalize(&diffdiff);
+ prevdiff = diff;
+
+ fprintf(stderr, " real time: %12ld sec %8ld usec\nqueue time: %12ld sec %8ld usec\n diff: %12ld sec %8ld usec\n diffdiff: %12ld sec %8ld usec\n",
+ tv.tv_sec, tv.tv_usec,
+ rtime->tv_sec, rtime->tv_nsec / 1000,
+ diff.tv_sec, diff.tv_usec,
+ diffdiff.tv_sec, diffdiff.tv_usec);
+
+ if (diffdiff.tv_usec > 5000 ||
+ diffdiff.tv_usec < -5000) {
+ fprintf(stderr, "oops! queue slipped\n");
+ if (tv.tv_sec < 5) {
+ fprintf(stderr, "(ignoring in first few seconds)\n");
+ } else {
+ countdown = 2;
+ }
+ } else {
+ if (countdown > 0) --countdown;
+ }
+
+ fprintf(stderr, "\n");
+ struct timespec ts;
+ ts.tv_sec = 1;
+ ts.tv_nsec = 0;
+ nanosleep(&ts, 0);
+ }
+}
+