Browse Source

Merge pull request #8 from adiknoth/fixes

FFADO buffersize patch and fix for segfault in jack_connect
tags/1.9.9.5
Stéphane Letz 13 years ago
parent
commit
f44f80e6b1
3 changed files with 98 additions and 18 deletions
  1. +4
    -1
      example-clients/connect.c
  2. +86
    -17
      linux/firewire/JackFFADODriver.cpp
  3. +8
    -0
      linux/firewire/JackFFADODriver.h

+ 4
- 1
example-clients/connect.c View File

@@ -128,7 +128,10 @@ main (int argc, char *argv[])
return 1;
}

if (argc < 3) show_usage(my_name);
if (argc < 3) {
show_usage(my_name);
return 1;
}

/* try to become a client of the JACK server */



+ 86
- 17
linux/firewire/JackFFADODriver.cpp View File

@@ -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
@@ -48,7 +49,10 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
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 +257,96 @@ JackFFADODriver::ffado_driver_restart (ffado_driver_t *driver)
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 +359,7 @@ JackFFADODriver::ffado_driver_new (const char *name,

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 +427,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 +512,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 +541,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 +584,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 +618,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 +626,8 @@ int JackFFADODriver::Attach()
}
}

UpdateLatencies();

assert(fCaptureChannels < DRIVER_PORT_NUM);
assert(fPlaybackChannels < DRIVER_PORT_NUM);



+ 8
- 0
linux/firewire/JackFFADODriver.h View File

@@ -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 JackAudioDriver

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 JackAudioDriver
int Read();
int Write();

// BufferSize can be changed
bool IsFixedBufferSize()
{
return false;
}

int SetBufferSize(jack_nframes_t nframes);
};



Loading…
Cancel
Save