ardour export + jamin

Kees van Veen <[email protected]> Wed, 13 Jan 2010 09:40:13 +0100
Newsgroups gmane.comp.audio.jamin.devel
Message-ID <[email protected]>
Hi,

I've joined the mailing list because of topic 
http://ardour.org/node/3016 concerning Ardour export with Jamin as an 
insert on the master bus, which (on all Ubuntu versions I've tried: 
Hardy, Jaunty and Karmic) causes Jamin to abort mostly at the very end 
of the export. I have no problem with running Jamin as an insert in 
'normal' mode.

When debugging I found that the condition upon a Jack ringbuffer write 
of io_queue() in io.c, causes Jamin to panic and abort() when the number 
of bytes to write does not correspond to the bytes written.

I am not familiar with audio programming, so I maybe completely off 
track, but I wondered why Jamin doesn't do a retry. For normal operation 
(as I gather from the comment before the abort()) that would probably 
not be a good idea, but when Ardour exports it goes into freewheeling 
mode, and I gather that in that case 'different rules' apply, i.e. Jack 
tries to run as fast as it can, but it waits for children to complete 
their task, if I'm phrasing that correctly.

I fiddled around with retrying to write the remaining bytes to the ring 
buffer (in freewheeling mode), and from the several times I've tried it, 
it seems to work properly, i.e. Jamin does not abort and eventually 
succeeds in writing all the bytes to the ring buffer, without (to me) 
audible effects in the export. I've attached the io.c diff to the latest 
CVS tree.

 From the Ardour forum I was told that I could get away with it, but I 
was solving the problem by the wrong means, which very well may be true.

This problem seems to have been around for quite some time, and keeps 
being reported. Would be nice to get that fixed.

Could any of you comment or help me in the right direction ?

Regards,
Kees

------------------------------------------------------------------------------
This SF.Net email is sponsored by the Verizon Developer Community
Take advantage of Verizon's best-in-class app development support
A streamlined, 14 day to market process makes app distribution fast and easy
Join now and get one step closer to millions of Verizon customers
http://p.sf.net/sfu/verizon-dev2dev

_______________________________________________
Jamin-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/jamin-devel
io.c.diff (text/x-patch, 1.8 KB)
--- io.c_orig	2010-01-13 09:28:47.000000000 +0100
+++ io.c	2010-01-13 09:29:59.000000000 +0100
@@ -123,6 +123,7 @@
 
 static int have_dsp_thread = 0;		/* DSP thread exists? */
 static size_t dsp_block_bytes;		/* DSP chunk size in bytes */
+static int freewheeling = 0;		/* in freewheeling mode ? */
 
 #define DSP_PRIORITY_DIFF 1	/* DSP thread priority difference */
 static pthread_t dsp_thread;	/* DSP thread handle */
@@ -468,6 +469,22 @@
     /* queue JACK input buffers for DSP thread */
     for (chan = 0; chan < nchannels; chan++) {
 	count = jack_ringbuffer_write(in_rb[chan], (void *) in[chan], nbytes);
+
+	if (freewheeling && count < nbytes) {
+
+	    /* In freewheeling mode, try to write the remaining bytes.
+	     * Sometimes a count of 0 is returned, wait a small while
+	     * and try again. */
+	    int try;
+	    for (try=0; try<10 && count < nbytes; try++) {
+		int cnt, nbt = nbytes - count;
+		cnt = jack_ringbuffer_write(in_rb[chan], (void *) in[chan]+count, nbt);
+		if (cnt==0) {
+			usleep(100);
+		}
+		count += cnt;
+	    }
+	}
 	if (count != nbytes) {		/* buffer overflow? */
 
 	    /* This is a realtime bug.  We have input audio with no
@@ -602,6 +619,16 @@
 }
 
 
+/* io_freewheel -- JACK freewheel callback.
+ *
+ *  Called in the JACK process thread.
+ */
+void io_freewheel(int starting, void *arg)
+{
+    freewheeling = starting;
+}
+
+
 /* io_free_heap -- free heap entry, if allocated. */
 static inline void io_free_heap(char **p)
 {
@@ -917,6 +944,7 @@
     jack_on_shutdown(client, io_shutdown, NULL);
     jack_set_xrun_callback(client, io_xrun, NULL);
     jack_set_buffer_size_callback(client, io_bufsize, NULL);
+    jack_set_freewheel_callback (client, io_freewheel, NULL);
 
     /* set initial buffer size and sample rate */
     dsp_block_bytes = dsp_block_size * sizeof(jack_default_audio_sample_t);