You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
231 lines
9.4 KiB
231 lines
9.4 KiB
diff -rupN jack-1.9.8.old/linux/firewire/JackFFADODriver.cpp jack-1.9.8/linux/firewire/JackFFADODriver.cpp
|
|
--- jack-1.9.8.old/linux/firewire/JackFFADODriver.cpp 2011-12-19 06:54:27.000000000 -0500
|
|
+++ jack-1.9.8/linux/firewire/JackFFADODriver.cpp 2012-03-25 01:38:58.246513167 -0400
|
|
@@ -3,6 +3,7 @@ Copyright (C) 2001 Paul Davis
|
|
Copyright (C) 2004 Grame
|
|
Copyright (C) 2007 Pieter Palmers
|
|
Copyright (C) 2009 Devin Anderson
|
|
+Copyright (C) 2012 Jonathan Woithe, Adrian Knoth
|
|
|
|
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
|
|
@@ -45,10 +46,20 @@ Foundation, Inc., 675 Mass Ave, Cambridg
|
|
#include "JackCompilerDeps.h"
|
|
#include "JackLockedEngine.h"
|
|
|
|
+// FFADO_API_VERSION was first defined with API_VERSION 9, so all previous
|
|
+// headers do not provide this define.
|
|
+#ifndef FFADO_API_VERSION
|
|
+extern "C" int ffado_streaming_set_period_size(ffado_device_t *dev,
|
|
+ unsigned int period) __attribute__((__weak__));
|
|
+#endif
|
|
+
|
|
namespace Jack
|
|
{
|
|
|
|
+// 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
|
|
|
|
#define jack_get_microseconds GetMicroSeconds
|
|
|
|
@@ -253,22 +264,96 @@ JackFFADODriver::ffado_driver_restart (f
|
|
return Start();
|
|
}
|
|
|
|
+void
|
|
+JackFFADODriver::UpdateLatencies(void)
|
|
+{
|
|
+ jack_latency_range_t range;
|
|
+ ffado_driver_t* driver = (ffado_driver_t*)fDriver;
|
|
+
|
|
+ for (int i = 0; i < fCaptureChannels; i++) {
|
|
+ range.min = range.max = driver->period_size + driver->capture_frame_latency;
|
|
+ fGraphManager->GetPort(fCapturePortList[i])->SetLatencyRange(JackCaptureLatency, &range);
|
|
+ }
|
|
+
|
|
+ for (int i = 0; i < fPlaybackChannels; i++) {
|
|
+ // Add one buffer more latency if "async" mode is used...
|
|
+ range.min = range.max = (driver->period_size *
|
|
+ (driver->device_options.nb_buffers - 1)) +
|
|
+ ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
|
|
+ fGraphManager->GetPort(fPlaybackPortList[i])->SetLatencyRange(JackPlaybackLatency, &range);
|
|
+ // Monitor port
|
|
+ if (fWithMonitorPorts) {
|
|
+ range.min = range.max =driver->period_size;
|
|
+ fGraphManager->GetPort(fMonitorPortList[i])->SetLatencyRange(JackCaptureLatency, &range);
|
|
+ }
|
|
+ }
|
|
+}
|
|
+
|
|
int
|
|
JackFFADODriver::SetBufferSize (jack_nframes_t nframes)
|
|
{
|
|
- printError("Buffer size change requested but not supported!!!");
|
|
+ ffado_driver_t* driver = (ffado_driver_t*)fDriver;
|
|
+ signed int chn;
|
|
+
|
|
+ // 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 = (ffado_sample_t*) calloc(driver->period_size, sizeof(ffado_sample_t));
|
|
+ if(driver->nullbuffer == NULL) {
|
|
+ printError("could not allocate memory for null buffer");
|
|
+ return -1;
|
|
+ }
|
|
+ driver->scratchbuffer = (ffado_sample_t*) 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 = (ffado_sample_t*) 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 = (ffado_sample_t*) 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 */
|
|
- //driver->engine->set_buffer_size (driver->engine, nframes);
|
|
+ JackAudioDriver::SetBufferSize(nframes); // Generic change, never fails
|
|
+
|
|
+ UpdateLatencies();
|
|
|
|
- return -1; // unsupported
|
|
+ return 0;
|
|
}
|
|
|
|
typedef void (*JackDriverFinishFunction) (jack_driver_t *);
|
|
@@ -281,7 +366,7 @@ JackFFADODriver::ffado_driver_new (const
|
|
|
|
assert(params);
|
|
|
|
- if (ffado_get_api_version() != FIREWIRE_REQUIRED_FFADO_API_VERSION) {
|
|
+ if (ffado_get_api_version() < FIREWIRE_REQUIRED_FFADO_API_VERSION) {
|
|
printError("Incompatible libffado version! (%s)", ffado_get_version());
|
|
return NULL;
|
|
}
|
|
@@ -349,7 +434,6 @@ int JackFFADODriver::Attach()
|
|
jack_port_id_t port_index;
|
|
char buf[REAL_JACK_PORT_NAME_SIZE];
|
|
char portname[REAL_JACK_PORT_NAME_SIZE];
|
|
- jack_latency_range_t range;
|
|
|
|
ffado_driver_t* driver = (ffado_driver_t*)fDriver;
|
|
|
|
@@ -435,8 +519,6 @@ int JackFFADODriver::Attach()
|
|
ffado_streaming_capture_stream_onoff(driver->dev, chn, 0);
|
|
|
|
port = fGraphManager->GetPort(port_index);
|
|
- range.min = range.max = driver->period_size + driver->capture_frame_latency;
|
|
- port->SetLatencyRange(JackCaptureLatency, &range);
|
|
// capture port aliases (jackd1 style port names)
|
|
snprintf(buf, sizeof(buf), "%s:capture_%i", fClientControl.fName, (int) chn + 1);
|
|
port->SetAlias(buf);
|
|
@@ -466,9 +548,6 @@ int JackFFADODriver::Attach()
|
|
// setup the midi buffer
|
|
driver->capture_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
|
|
|
|
- port = fGraphManager->GetPort(port_index);
|
|
- range.min = range.max = driver->period_size + driver->capture_frame_latency;
|
|
- port->SetLatencyRange(JackCaptureLatency, &range);
|
|
fCapturePortList[chn] = port_index;
|
|
jack_log("JackFFADODriver::Attach fCapturePortList[i] %ld ", port_index);
|
|
fCaptureChannels++;
|
|
@@ -512,8 +591,6 @@ int JackFFADODriver::Attach()
|
|
|
|
port = fGraphManager->GetPort(port_index);
|
|
// Add one buffer more latency if "async" mode is used...
|
|
- range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
|
|
- port->SetLatencyRange(JackPlaybackLatency, &range);
|
|
// playback port aliases (jackd1 style port names)
|
|
snprintf(buf, sizeof(buf), "%s:playback_%i", fClientControl.fName, (int) chn + 1);
|
|
port->SetAlias(buf);
|
|
@@ -548,9 +625,6 @@ int JackFFADODriver::Attach()
|
|
|
|
driver->playback_channels[chn].midi_buffer = (uint32_t *)calloc(driver->period_size, sizeof(uint32_t));
|
|
|
|
- port = fGraphManager->GetPort(port_index);
|
|
- range.min = range.max = (driver->period_size * (driver->device_options.nb_buffers - 1)) + ((fEngineControl->fSyncMode) ? 0 : fEngineControl->fBufferSize) + driver->playback_frame_latency;
|
|
- port->SetLatencyRange(JackPlaybackLatency, &range);
|
|
fPlaybackPortList[chn] = port_index;
|
|
jack_log("JackFFADODriver::Attach fPlaybackPortList[i] %ld ", port_index);
|
|
fPlaybackChannels++;
|
|
@@ -559,6 +633,8 @@ int JackFFADODriver::Attach()
|
|
}
|
|
}
|
|
|
|
+ UpdateLatencies();
|
|
+
|
|
assert(fCaptureChannels < DRIVER_PORT_NUM);
|
|
assert(fPlaybackChannels < DRIVER_PORT_NUM);
|
|
|
|
diff -rupN jack-1.9.8.old/linux/firewire/JackFFADODriver.h jack-1.9.8/linux/firewire/JackFFADODriver.h
|
|
--- jack-1.9.8.old/linux/firewire/JackFFADODriver.h 2011-12-19 06:54:27.000000000 -0500
|
|
+++ jack-1.9.8/linux/firewire/JackFFADODriver.h 2012-03-25 01:38:05.708754669 -0400
|
|
@@ -2,6 +2,7 @@
|
|
Copyright (C) 2001 Paul Davis
|
|
Copyright (C) 2004 Grame
|
|
Copyright (C) 2007 Pieter Palmers
|
|
+Copyright (C) 2012 Adrian Knoth
|
|
|
|
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
|
|
@@ -59,6 +60,7 @@ class JackFFADODriver : public JackAudio
|
|
|
|
void jack_driver_init (jack_driver_t *driver);
|
|
void jack_driver_nt_init (jack_driver_nt_t * driver);
|
|
+ void UpdateLatencies();
|
|
|
|
public:
|
|
|
|
@@ -80,6 +82,12 @@ class JackFFADODriver : public JackAudio
|
|
int Read();
|
|
int Write();
|
|
|
|
+ // BufferSize can be changed
|
|
+ bool IsFixedBufferSize()
|
|
+ {
|
|
+ return false;
|
|
+ }
|
|
+
|
|
int SetBufferSize(jack_nframes_t nframes);
|
|
};
|
|
|