denemo-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Denemo-devel] Getting MIDI over JACK to work


From: Tom Ivar Helbekkmo
Subject: [Denemo-devel] Getting MIDI over JACK to work
Date: Thu, 09 Feb 2012 20:34:51 +0100
User-agent: Gnus/5.110018 (No Gnus v0.18) Emacs/23.3 (berkeley-unix)

As promised,

I had to spend some time chasing down a bug that caused Denemo to crash
when I tried to use it with JACK on my NetBSD-current system.  It would
crash during startup, and the signal handler caused it to quietly exit
when this happened, so I started by putting an abort() statement in
there, to get a core dump to debug.  In the end, it turned out that the
primary reason for the crash was a malloc(sizeof()) situation with the
event queues, which Richard Shann has applied the patch for (we were
chatting on #denemo while I was debugging).  There are, however, a
couple of other changes I had to make, and I promised Richard I'd send
them along.

In audiointerface.c, I had to move the calls to event_queue_new() up one
level in the call tree, because the order of events during
initialization caused an event queue to be used before it had been
initialized, resulting in a crash.

In eventqueue.c, I reinstated Richard's variable length MIDI message
code, which I understand was #ifdef'ed away because of suspicions that
it was buggy - but the bug was probably the above mentioned error where
a struct was malloc'ed just the size of the pointer to it.

In jackbackend.c, I changed a memset() to a jack_midi_clear_buffer(),
just because it's cleaner...

Oh, and I removed the ringbuffer.[ch] files, as they really don't have
any reason to be there, being part of the JACK distribution.  I didn't
want to risk using an outdated ringbuffer.h after upgrading JACK.

Finally, Richard and I just figured out that the JACK ringbuffers need
to be emptied after being allocated, to avoid getting a lot of random
noise streamed to your synth or speakers when you first hit play...

Here's the diff:

diff --git a/src/audiointerface.c b/src/audiointerface.c
index c65e121..b024e0d 100644
--- a/src/audiointerface.c
+++ b/src/audiointerface.c
@@ -118,7 +118,7 @@ static int initialize_audio(DenemoPrefs *config) {
     backends[AUDIO_BACKEND] = &dummy_audio_backend;
   }
 
-  event_queues[AUDIO_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, 0);
+  //event_queues[AUDIO_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, 0);
 
   int ret = get_backend(AUDIO_BACKEND)->initialize(config);
 
@@ -165,7 +165,7 @@ static int initialize_midi(DenemoPrefs *config) {
     backends[MIDI_BACKEND] = &dummy_midi_backend;
   }
 
-  event_queues[MIDI_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, INPUT_QUEUE_SIZE);
+  //event_queues[MIDI_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, INPUT_QUEUE_SIZE);
 
   int ret = get_backend(MIDI_BACKEND)->initialize(config);
 
@@ -190,6 +190,9 @@ int audio_initialize(DenemoPrefs *config) {
   queue_cond = g_cond_new();
   queue_mutex = g_mutex_new();
 
+  event_queues[AUDIO_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, 0);
+  event_queues[MIDI_BACKEND] = event_queue_new(PLAYBACK_QUEUE_SIZE, 
IMMEDIATE_QUEUE_SIZE, INPUT_QUEUE_SIZE);
+
   if (initialize_audio(config)) {
     goto err;
   }
diff --git a/src/eventqueue.c b/src/eventqueue.c
index ef1152b..383a002 100644
--- a/src/eventqueue.c
+++ b/src/eventqueue.c
@@ -23,14 +23,17 @@ event_queue_t *event_queue_new(size_t playback_queue_size, 
size_t immediate_queu
 
   if (playback_queue_size) {
     queue->playback = jack_ringbuffer_create(playback_queue_size * 
sizeof(smf_event_t *));
+    jack_ringbuffer_reset(queue->playback);
   }
 
   if (immediate_queue_size) {
     queue->immediate = jack_ringbuffer_create(immediate_queue_size * 
sizeof(midi_event_t));
+    jack_ringbuffer_reset(queue->immediate);
   }
 
   if (input_queue_size) {
     queue->input = jack_ringbuffer_create(input_queue_size * 
sizeof(midi_event_t));
+    jack_ringbuffer_reset(queue->input);
   }
 
   return queue;
@@ -93,7 +96,7 @@ void page_for_time(gdouble time_seconds) {
 gboolean event_queue_read_output(event_queue_t *queue, unsigned char 
*event_buffer, size_t *event_length,
                                  double *event_time, double until_time) {
 
-#ifdef _HAVE_JACK_
+#if 0
 //old fixed length code                                   
   if (jack_ringbuffer_read_space(queue->immediate)) {
     midi_event_t event;
diff --git a/src/eventqueue.h b/src/eventqueue.h
index 7588c46..e55133f 100644
--- a/src/eventqueue.h
+++ b/src/eventqueue.h
@@ -15,7 +15,7 @@
 #define EVENTQUEUE_H
 
 #include "audiointerface.h"
-#include "ringbuffer.h"
+#include <jack/ringbuffer.h>
 
 #include "smf.h"
 
diff --git a/src/jackbackend.c b/src/jackbackend.c
index a6a1473..16868a9 100644
--- a/src/jackbackend.c
+++ b/src/jackbackend.c
@@ -63,7 +63,7 @@ static void process_audio(nframes_t nframes) {
 
   for (i = 0; i < num_audio_out_ports; ++i) {
     port_buffers[i] = jack_port_get_buffer(audio_out_ports[i], nframes);
-    memset(port_buffers[i], 0, nframes * sizeof(sample_t));
+    jack_midi_clear_buffer(port_buffers[i]);
   }
 
 #ifdef _HAVE_FLUIDSYNTH_

-- 
"The market" is a bunch of 28-year-olds who don't know anything. --Paul Krugman



reply via email to

[Prev in Thread] Current Thread [Next in Thread]