[FFADO-devel] [PATCH] v1.1 of setbufsize support for firewire driver

PrevNext  Index
DateMon, 12 Mar 2012 21:55:30 +1030
From Jonathan Woithe <[hidden] at just42 dot net>
To[hidden] at lists dot jackaudio dot org
Cc[hidden] at lists dot sf dot net
Here's a slightly revised version (v1.1) of the patch to the firewire driver
to support setbufsize.  Differences from the previous version (1.0):

 - updated copyright notice

 - check ffado API version from ffado_driver_bufsize() and proceed if it's 9
   or higher.  Note that ffado_streaming_set_period_size() is exported
   weakly with FFADO API version 9.  This should smooth the transition for
   users of binary jack distributions, especially those who don't use the
   firewire driver and therefore won't really want to upgrade ffado just to
   upgrade jack.  Please let me know if I've managed to stuff this up.

One will still need an upgraded ffado (r2081 or later) to compile this.  If
it's desirably to avoid this using FFADO API version macros please drop me a
line (presently the FFADO API version is only available at runtime via a
function).

Regards
  jonathan


--- jack-audio-connection-kit-0.121.3-orig/drivers/firewire/ffado_driver.c	2011-06-09 09:24:49.000000000 +0930
+++ jack-audio-connection-kit-0.121.3/drivers/firewire/ffado_driver.c	2012-03-12 21:44:08.511830794 +1030
@@ -7,6 +7,7 @@
  *   http://www.jackaudio.org
  *
  *   Copyright (C) 2005-2007 Pieter Palmers
+ *   Copyright (C) 2012 Jonathan Woithe
  *
  *   This program is free software; you can redistribute it and/or modify
  *   it under the terms of the GNU General Public License as published by
@@ -50,7 +51,10 @@
 
 static int ffado_driver_stop (ffado_driver_t *driver);
 
+// Basic functionality requires API version 8.  If version 9 or later
+// is present the buffers can be resized at runtime.
 #define FIREWIRE_REQUIRED_FFADO_API_VERSION 8
+#define FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE 9
 
 // enable verbose messages
 static int g_verbose=0;
@@ -675,24 +679,71 @@
 static int
 ffado_driver_bufsize (ffado_driver_t* driver, jack_nframes_t nframes)
 {
-	printError("Buffer size change requested but not supported!!!");
+	signed int chn;
 
-	/*
-	 driver->period_size = nframes;  
+	// The speed of this function isn't critical; we can afford the
+	// time to check the FFADO API version.
+	if (ffado_get_api_version() != FIREWIRE_REQUIRED_FFADO_API_VERSION_FOR_SETBUFSIZE ||
+            ffado_streaming_set_period_size == NULL) {
+	        printError("unsupported on current version of FFADO; please upgrade FFADO");
+	        return -1;
+	}
+
+	driver->period_size = nframes;  
 	driver->period_usecs =
 		(jack_time_t) floor ((((float) nframes) / driver->sample_rate)
 				     * 1000000.0f);
-	*/
-	
+
+	// Reallocate the null and scratch buffers.
+	driver->nullbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
+	if(driver->nullbuffer == NULL) {
+		printError("could not allocate memory for null buffer");
+		return -1;
+	}
+	driver->scratchbuffer = calloc(driver->period_size, sizeof(ffado_sample_t));
+	if(driver->scratchbuffer == NULL) {
+		printError("could not allocate memory for scratch buffer");
+		return -1;
+	}
+
+	// MIDI buffers need reallocating
+	for (chn = 0; chn < driver->capture_nchannels; chn++) {
+		if(driver->capture_channels[chn].stream_type == ffado_stream_type_midi) {
+			// setup the midi buffer
+			if (driver->capture_channels[chn].midi_buffer != NULL)
+			        free(driver->capture_channels[chn].midi_buffer);
+			driver->capture_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t));
+		}
+	}
+	for (chn = 0; chn < driver->playback_nchannels; chn++) {
+		if(driver->playback_channels[chn].stream_type == ffado_stream_type_midi) {
+		        if (driver->playback_channels[chn].midi_buffer != NULL)
+		                free(driver->playback_channels[chn].midi_buffer);
+			driver->playback_channels[chn].midi_buffer = calloc(driver->period_size, sizeof(uint32_t));
+		}
+	}
+
+	// Notify FFADO of the period size change
+	if (ffado_streaming_set_period_size(driver->dev, nframes) != 0) {
+	        printError("could not alter FFADO device period size");
+	        return -1;
+	}
+
+	// This is needed to give the shadow variables a chance to
+	// properly update to the changes.
+	sleep(1);
+
 	/* tell the engine to change its buffer size */
-#if 0
 	if (driver->engine->set_buffer_size (driver->engine, nframes)) {
 		jack_error ("FFADO: cannot set engine buffer size to %d (check MIDI)", nframes);
 		return -1;
 	}
-#endif
 
-	return -1; // unsupported
+	// Other drivers (eg: ALSA) don't seem to adjust latencies via
+	// jack_port_set_latency_range() from the bufsize() callback, so we
+	// won't either.  Is this right?
+
+        return 0;
 }
 
 typedef void (*JackDriverFinishFunction) (jack_driver_t *);

------------------------------------------------------------------------------
Try before you buy = See our experts in action!
The most comprehensive online learning library for Microsoft developers
is just $99.99! Visual Studio, SharePoint, SQL - plus HTML5, CSS3, MVC3,
Metro Style Apps, more. Free future releases when you subscribe now!
http://p.sf.net/sfu/learndevnow-dev2

FFADO-devel mailing list
[hidden]
https://lists.sourceforge.net/lists/listinfo/ffado-devel
PrevNext  Index

1331551586.29990_0.ltw:2, <20120312112530.GC13052 at marvin dot atrad dot com dot au>