diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-03-01 18:37:05 +0000 |
commit | 145364a8af6a1fec06556221e66d4b724a62fc9a (patch) | |
tree | 53bd71a544008c518034f208d64c932dc2883f50 /src/base/test/seq | |
download | rosegarden-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/Makefile | 6 | ||||
-rw-r--r-- | src/base/test/seq/complainer.c | 74 | ||||
-rw-r--r-- | src/base/test/seq/generator.c | 96 | ||||
-rw-r--r-- | src/base/test/seq/queue-timer-jack.c | 166 | ||||
-rw-r--r-- | src/base/test/seq/queue-timer.c | 123 |
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, ¶m)) { + 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); + } +} + |