From 72a1e2a5cf26026d43838cdecd2e39866023eeee Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sat, 15 Jun 2013 17:51:50 -0700 Subject: [PATCH] Mixer: Implement de-zippering for controls of all built-in modules. --- mixer/src/AUX_Module.C | 32 +++++++++++++++++++++---- mixer/src/AUX_Module.H | 5 ++++ mixer/src/Chain.C | 28 +++++++++++++++++++--- mixer/src/Chain.H | 2 ++ mixer/src/Engine/Engine.C | 18 ++++++++++++++- mixer/src/Engine/Engine.H | 5 ++++ mixer/src/Gain_Module.C | 33 ++++++++++++++++++++++---- mixer/src/Gain_Module.H | 5 ++++ mixer/src/Module.C | 1 + mixer/src/Module.H | 8 +++++++ mixer/src/Mono_Pan_Module.C | 45 +++++++++++++++++++++++++++++++----- mixer/src/Mono_Pan_Module.H | 5 ++++ mixer/src/Plugin_Module.C | 12 +++++----- nonlib/JACK/Client.C | 13 +++++++++-- nonlib/JACK/Client.H | 9 ++++---- nonlib/dsp.C | 34 +++++++++++++++++++++++++++ nonlib/dsp.h | 21 +++++++++++++++++ timeline/src/Engine/Engine.H | 2 +- timeline/src/Engine/Track.C | 4 ++-- 19 files changed, 249 insertions(+), 33 deletions(-) diff --git a/mixer/src/AUX_Module.C b/mixer/src/AUX_Module.C index 33ee619..81b3593 100644 --- a/mixer/src/AUX_Module.C +++ b/mixer/src/AUX_Module.C @@ -50,6 +50,8 @@ AUX_Module::AUX_Module ( ) : JACK_Module ( false ) color( FL_DARK1 ); copy_label( "Aux" ); + + smoothing.sample_rate( sample_rate() ); } AUX_Module::~AUX_Module ( ) @@ -97,17 +99,39 @@ AUX_Module::number ( int n ) copy_label( s ); } +void +AUX_Module::handle_sample_rate_change ( nframes_t n ) +{ + smoothing.sample_rate( n ); +} + void AUX_Module::process ( nframes_t nframes ) { if ( !bypass() ) { - float g = DB_CO( control_input[0].control_value() ); + float gt = DB_CO( control_input[0].control_value() ); - for ( unsigned int i = 0; i < audio_input.size(); ++i ) + if ( !smoothing.target_reached( gt ) ) { - if ( audio_input[i].connected() ) - buffer_copy_and_apply_gain( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), nframes, g ); + sample_t gainbuf[nframes]; + + smoothing.apply( gainbuf, nframes, gt ); + + for ( unsigned int i = 0; i < audio_input.size(); ++i ) + { + if ( audio_input[i].connected() ) + buffer_copy_and_apply_gain_buffer( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), gainbuf, nframes ); + } + + } + else + { + for ( unsigned int i = 0; i < audio_input.size(); ++i ) + { + if ( audio_input[i].connected() ) + buffer_copy_and_apply_gain( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), nframes, gt ); + } } } else diff --git a/mixer/src/AUX_Module.H b/mixer/src/AUX_Module.H index 86f5994..aadfb3a 100644 --- a/mixer/src/AUX_Module.H +++ b/mixer/src/AUX_Module.H @@ -20,11 +20,14 @@ #pragma once #include "JACK_Module.H" +#include "dsp.h" class AUX_Module : public JACK_Module { int _number; + Value_Smoothing_Filter smoothing; + protected: virtual void get ( Log_Entry &e ) const; @@ -44,6 +47,8 @@ public: virtual ~AUX_Module ( ); LOG_CREATE_FUNC( AUX_Module ); + + virtual void handle_sample_rate_change ( nframes_t n ); protected: diff --git a/mixer/src/Chain.C b/mixer/src/Chain.C index 58794e2..31382ba 100644 --- a/mixer/src/Chain.C +++ b/mixer/src/Chain.C @@ -250,13 +250,12 @@ Chain::initialize_with_default ( void ) m->is_default( true ); m->chain( this ); m->configure_outputs( 1 ); - m->initialize(); add( m ); } { Module *m = new Gain_Module(); m->is_default( true ); - m->initialize(); + m->chain(this); add( m ); } @@ -268,7 +267,6 @@ Chain::initialize_with_default ( void ) { JACK_Module *m = new JACK_Module(); m->is_default( true ); m->chain( this ); - m->initialize(); add( m ); } } @@ -462,7 +460,10 @@ Chain::name ( const char *name ) engine()->buffer_size_callback( &Chain::buffer_size, this ); engine()->port_connect_callback( &Chain::port_connect, this ); + engine()->sample_rate_changed_callback( &Chain::sample_rate_change, this ); + Module::set_sample_rate( engine()->sample_rate() ); + const char *jack_name = engine()->init( ename ); if ( ! jack_name ) @@ -580,6 +581,7 @@ Chain::insert ( Module *m, Module *n ) n->ncontrol_inputs(), n->ncontrol_outputs() ); + n->initialize(); return true; err: @@ -829,6 +831,26 @@ Chain::buffer_size ( nframes_t nframes ) } } +int +Chain::sample_rate_change ( nframes_t nframes, void *v ) +{ + ((Chain*)v)->sample_rate_change( nframes ); +} + +int +Chain::sample_rate_change ( nframes_t nframes ) +{ + Module::set_sample_rate ( nframes ); + for ( int i = 0; i < modules(); ++i ) + { + Module *m = module(i); + + m->handle_sample_rate_change( nframes ); + } + + return 0; +} + void Chain::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v ) { diff --git a/mixer/src/Chain.H b/mixer/src/Chain.H index 8638c00..680633a 100644 --- a/mixer/src/Chain.H +++ b/mixer/src/Chain.H @@ -74,6 +74,8 @@ private: static void buffer_size ( nframes_t nframes, void *v ); void buffer_size ( nframes_t nframes ); + static int sample_rate_change ( nframes_t nframes, void *v ); + int sample_rate_change ( nframes_t nframes ); static void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v ); diff --git a/mixer/src/Engine/Engine.C b/mixer/src/Engine/Engine.C index 71874d8..8e24a2c 100644 --- a/mixer/src/Engine/Engine.C +++ b/mixer/src/Engine/Engine.C @@ -20,7 +20,7 @@ #include "Engine.H" -#include "../Mixer.H" // for process() +// #include "../Mixer.H" // for process() /* This is the home of the JACK process callback */ @@ -37,6 +37,7 @@ Engine::Engine ( void (*process_callback)(nframes_t nframes, void *), void *user _buffer_size_callback = 0; _buffers_dropped = 0; _port_connect_callback = 0; + _sample_rate_changed_callback = 0; } Engine::~Engine ( ) @@ -53,6 +54,13 @@ Engine::buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void _buffer_size_callback_user_data = user_data; } +void +Engine::sample_rate_changed_callback ( int ( *sample_rate_changed_callback ) ( nframes_t, void * ), void *user_data ) +{ + _sample_rate_changed_callback = sample_rate_changed_callback; + _sample_rate_changed_callback_user_data = user_data; +} + void Engine::port_connect_callback ( void ( *port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg), void *user_data ) { @@ -132,6 +140,14 @@ Engine::process ( nframes_t nframes ) return 0; } +int +Engine::sample_rate_changed ( nframes_t srate ) +{ + if ( _sample_rate_changed_callback ) + return _sample_rate_changed_callback( srate, _sample_rate_changed_callback_user_data ); + + return 0; +} /* TRHEAD: RT */ void diff --git a/mixer/src/Engine/Engine.H b/mixer/src/Engine/Engine.H index 83bbaf6..3b3f528 100644 --- a/mixer/src/Engine/Engine.H +++ b/mixer/src/Engine/Engine.H @@ -40,9 +40,13 @@ class Engine : public JACK::Client, public Mutex void ( * _buffer_size_callback ) ( nframes_t, void * ); void *_buffer_size_callback_user_data; + int ( * _sample_rate_changed_callback ) ( nframes_t, void * ); + void *_sample_rate_changed_callback_user_data; + void ( * _port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void * ); void *_port_connect_callback_user_data; + int sample_rate_changed ( nframes_t srate ); void shutdown ( void ); int process ( nframes_t nframes ); int xrun ( void ); @@ -67,5 +71,6 @@ public: int dropped ( void ) const { return _buffers_dropped; } void buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void * ), void *user_data ); + void sample_rate_changed_callback ( int ( *sample_rate_changed_callback ) ( nframes_t, void * ), void *user_data ); void port_connect_callback ( void ( *port_connect_callback ) ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg), void *user_data ); }; diff --git a/mixer/src/Gain_Module.C b/mixer/src/Gain_Module.C index e83316a..b900392 100644 --- a/mixer/src/Gain_Module.C +++ b/mixer/src/Gain_Module.C @@ -45,6 +45,8 @@ Gain_Module::Gain_Module ( ) end(); log_create(); + + smoothing.sample_rate( sample_rate() ); } Gain_Module::~Gain_Module ( ) @@ -71,6 +73,12 @@ Gain_Module::configure_inputs ( int n ) return true; } +void +Gain_Module::handle_sample_rate_change ( nframes_t n ) +{ + smoothing.sample_rate( n ); +} + /**********/ @@ -80,13 +88,30 @@ Gain_Module::configure_inputs ( int n ) void Gain_Module::process ( nframes_t nframes ) { - float g = DB_CO( control_input[0].control_value() ); + const float gt = DB_CO( control_input[0].control_value() ); - for ( int i = audio_input.size(); i--; ) + if ( !smoothing.target_reached( gt ) ) { - if ( audio_input[i].connected() && audio_output[i].connected() ) + sample_t gainbuf[nframes]; + + smoothing.apply( gainbuf, nframes, gt ); + + for ( int i = audio_input.size(); i--; ) { - buffer_apply_gain( (sample_t*)audio_input[i].buffer(), nframes, g ); + if ( audio_input[i].connected() && audio_output[i].connected() ) + { + sample_t *out = (sample_t*)audio_input[i].buffer(); + + buffer_apply_gain_buffer( out, gainbuf, nframes ); + } } } + else + for ( int i = audio_input.size(); i--; ) + { + if ( audio_input[i].connected() && audio_output[i].connected() ) + { + buffer_apply_gain( (sample_t*)audio_input[i].buffer(), nframes, gt ); + } + } } diff --git a/mixer/src/Gain_Module.H b/mixer/src/Gain_Module.H index 6988788..a8bf764 100644 --- a/mixer/src/Gain_Module.H +++ b/mixer/src/Gain_Module.H @@ -20,9 +20,12 @@ #pragma once #include "Module.H" +#include "dsp.h" class Gain_Module : public Module { + Value_Smoothing_Filter smoothing; + public: Gain_Module ( ); @@ -38,6 +41,8 @@ public: MODULE_CLONE_FUNC( Gain_Module ); + virtual void handle_sample_rate_change ( nframes_t n ); + protected: virtual void process ( nframes_t nframes ); diff --git a/mixer/src/Module.C b/mixer/src/Module.C index e9de8df..24ceac4 100644 --- a/mixer/src/Module.C +++ b/mixer/src/Module.C @@ -47,6 +47,7 @@ +nframes_t Module::_sample_rate = 0; Module *Module::_copied_module_empty = 0; char *Module::_copied_module_settings = 0; diff --git a/mixer/src/Module.H b/mixer/src/Module.H index 5ea2319..d3fb259 100644 --- a/mixer/src/Module.H +++ b/mixer/src/Module.H @@ -49,6 +49,7 @@ class Module : public Fl_Group, public Loggable { Module_Parameter_Editor *_editor; + static nframes_t _sample_rate; static Module *_copied_module_empty; static char *_copied_module_settings; @@ -414,6 +415,9 @@ public: virtual void process ( nframes_t ) = 0; + /* called whenever the module is initialized or when the sample rate is changed at runtime */ + virtual void handle_sample_rate_change ( nframes_t sample_rate ) {} + /* called whenever the value of a control port is changed. This can be used to take appropriate action from the GUI thread */ virtual void handle_control_changed ( Port * ); @@ -436,6 +440,8 @@ public: protected: + nframes_t sample_rate ( void ) const { return Module::_sample_rate; } + void draw_connections ( void ); void draw_label ( int X, int Y, int W, int H ); void draw_box ( int X, int Y, int W, int H ); @@ -448,6 +454,8 @@ protected: public: + static void set_sample_rate ( nframes_t srate ) { _sample_rate = srate; } + void command_open_parameter_editor(); virtual void command_activate ( void ); virtual void command_deactivate ( void ); diff --git a/mixer/src/Mono_Pan_Module.C b/mixer/src/Mono_Pan_Module.C index 2108289..86688d1 100644 --- a/mixer/src/Mono_Pan_Module.C +++ b/mixer/src/Mono_Pan_Module.C @@ -47,6 +47,8 @@ Mono_Pan_Module::Mono_Pan_Module ( ) end(); log_create(); + + smoothing.sample_rate( sample_rate() ); } Mono_Pan_Module::~Mono_Pan_Module ( ) @@ -57,6 +59,12 @@ Mono_Pan_Module::~Mono_Pan_Module ( ) +void +Mono_Pan_Module::handle_sample_rate_change ( nframes_t n ) +{ + smoothing.sample_rate( n ); +} + bool Mono_Pan_Module::configure_inputs ( int ) { @@ -72,10 +80,6 @@ Mono_Pan_Module::configure_inputs ( int ) void Mono_Pan_Module::process ( nframes_t nframes ) { - const float g = control_input[0].control_value(); - - const float lg = (0.0f - g) + 1.0f; - const float rg = g + 1.0f; if ( audio_input[0].connected() && audio_output[0].connected() && @@ -87,9 +91,38 @@ Mono_Pan_Module::process ( nframes_t nframes ) } else { - buffer_copy_and_apply_gain( (sample_t*)audio_output[1].buffer(), (sample_t*)audio_input[0].buffer(), nframes, rg ); + const float gt = (control_input[0].control_value() + 1.0f) * 0.5f; + + if ( ! smoothing.target_reached( gt ) ) + { + sample_t gainbuf[nframes]; - buffer_apply_gain( (sample_t*)audio_output[0].buffer(), nframes, lg ); + smoothing.apply( gainbuf, nframes, gt ); + + /* right channel */ + + buffer_copy_and_apply_gain_buffer( (sample_t*)audio_output[1].buffer(), + (sample_t*)audio_input[0].buffer(), + gainbuf, + nframes ); + + /* left channel */ + for ( nframes_t i = 0; i < nframes; i++ ) + gainbuf[i] = 1.0f - gainbuf[i]; + + buffer_apply_gain_buffer( (sample_t*)audio_output[0].buffer(), gainbuf, nframes ); + } + else + { + /* right channel */ + buffer_copy_and_apply_gain( (sample_t*)audio_output[1].buffer(), + (sample_t*)audio_input[0].buffer(), + nframes, + gt ); + + /* left channel */ + buffer_apply_gain( (sample_t*)audio_output[0].buffer(), nframes, 1.0f - gt); + } } } } diff --git a/mixer/src/Mono_Pan_Module.H b/mixer/src/Mono_Pan_Module.H index f585aac..7ede987 100644 --- a/mixer/src/Mono_Pan_Module.H +++ b/mixer/src/Mono_Pan_Module.H @@ -20,9 +20,12 @@ #pragma once #include "Module.H" +#include "dsp.h" class Mono_Pan_Module : public Module { + Value_Smoothing_Filter smoothing; + public: Mono_Pan_Module ( ); @@ -37,6 +40,8 @@ public: MODULE_CLONE_FUNC( Mono_Pan_Module ); + virtual void handle_sample_rate_change ( nframes_t n ); + protected: virtual void process ( nframes_t nframes ); diff --git a/mixer/src/Plugin_Module.C b/mixer/src/Plugin_Module.C index fc7f09d..fbe4ae2 100644 --- a/mixer/src/Plugin_Module.C +++ b/mixer/src/Plugin_Module.C @@ -341,7 +341,7 @@ Plugin_Module::plugin_instances ( unsigned int n ) DMESSAGE( "Instantiating plugin..." ); - if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, Engine::sample_rate() ) ) ) + if ( ! (h = _idata->descriptor->instantiate( _idata->descriptor, sample_rate() ) ) ) { WARNING( "Failed to instantiate plugin" ); return false; @@ -474,7 +474,7 @@ Plugin_Module::load ( unsigned long id ) p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound; if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) ) { - p.hints.minimum *= Engine::sample_rate(); + p.hints.minimum *= sample_rate(); } } if ( LADSPA_IS_HINT_BOUNDED_ABOVE(hd) ) @@ -483,7 +483,7 @@ Plugin_Module::load ( unsigned long id ) p.hints.maximum = _idata->descriptor->PortRangeHints[i].UpperBound; if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) ) { - p.hints.maximum *= Engine::sample_rate(); + p.hints.maximum *= sample_rate(); } } @@ -500,7 +500,7 @@ Plugin_Module::load ( unsigned long id ) Min=_idata->descriptor->PortRangeHints[Port].LowerBound; if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) { - Min*=Engine::sample_rate(); + Min*=sample_rate(); } } if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) @@ -508,7 +508,7 @@ Plugin_Module::load ( unsigned long id ) Max=_idata->descriptor->PortRangeHints[Port].UpperBound; if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) { - Max*=Engine::sample_rate(); + Max*=sample_rate(); } } @@ -576,7 +576,7 @@ Plugin_Module::load ( unsigned long id ) } } if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) { - Default *= Engine::sample_rate(); + Default *= sample_rate(); } if (LADSPA_IS_HINT_INTEGER(HintDesc)) { if ( p.hints.ranged && diff --git a/nonlib/JACK/Client.C b/nonlib/JACK/Client.C index 02a9316..5bab251 100644 --- a/nonlib/JACK/Client.C +++ b/nonlib/JACK/Client.C @@ -29,7 +29,7 @@ namespace JACK { - nframes_t Client::_sample_rate = 0; +// nframes_t Client::_sample_rate = 0; Client::Client ( ) { @@ -114,6 +114,13 @@ namespace JACK ((Client*)arg)->port_connect( a, b, connect ); } + int + Client::sample_rate_changed ( nframes_t srate, void *arg ) + { +// ((Client*)arg)->_sample_rate = srate; + return ((Client*)arg)->sample_rate_changed( srate ); + } + /** Connect to JACK using client name /client_name/. Return a static * pointer to actual name as reported by JACK */ const char * @@ -131,6 +138,8 @@ namespace JACK set_callback( buffer_size ); set_callback( port_connect ); + jack_set_sample_rate_callback( _client, &Client::sample_rate_changed, this ); + /* FIXME: should we wait to register this until after the project has been loaded (and we have disk threads running)? */ if ( opts & SLOW_SYNC ) @@ -143,7 +152,7 @@ namespace JACK jack_activate( _client ); - _sample_rate = frame_rate(); +// _sample_rate = frame_rate(); return jack_get_client_name( _client ); } diff --git a/nonlib/JACK/Client.H b/nonlib/JACK/Client.H index 93f804b..cd94fa9 100644 --- a/nonlib/JACK/Client.H +++ b/nonlib/JACK/Client.H @@ -35,11 +35,13 @@ namespace JACK jack_client_t *_client; - static nframes_t _sample_rate; +// nframes_t _sample_rate; volatile int _xruns; volatile bool _freewheeling; volatile bool _zombified; + static int sample_rate_changed ( nframes_t srate, void *arg ); + virtual int sample_rate_changed ( nframes_t srate ) { return 0; } static void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *arg ); virtual void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect ) { } static void shutdown ( void *arg ); @@ -93,15 +95,14 @@ namespace JACK void close ( void ); nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); } - float frame_rate ( void ) const { return jack_get_sample_rate( _client ); } - static nframes_t sample_rate ( void ) { return _sample_rate; } +// float frame_rate ( void ) const { return jack_get_sample_rate( _client ); } + nframes_t sample_rate ( void ) const { return jack_get_sample_rate( _client ); } int xruns ( void ) const { return _xruns; }; bool freewheeling ( void ) const { return _freewheeling; } void freewheeling ( bool yes ); bool zombified ( void ) const { return _zombified; } float cpu_load ( void ) const { return jack_cpu_load( _client ); } - void transport_stop ( void ); void transport_start ( void ); void transport_locate ( nframes_t frame ); diff --git a/nonlib/dsp.C b/nonlib/dsp.C index e599e2e..fd9bbd3 100644 --- a/nonlib/dsp.C +++ b/nonlib/dsp.C @@ -127,3 +127,37 @@ buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nfram memcpy( dst, src, nframes * sizeof( sample_t ) ); buffer_apply_gain( dst, nframes, gain ); } + +void +Value_Smoothing_Filter::sample_rate ( nframes_t n ) +{ + const float FS = n; + const float T = 0.05f; + + w = 10.0f / (FS * T); +} + +void +Value_Smoothing_Filter::apply( sample_t *dst, nframes_t nframes, float gt ) +{ + const float a = 0.07f; + const float b = 1 + a; + + const float gm = b * gt; + + float g1 = this->g1; + float g2 = this->g2; + + for (nframes_t i = 0; i < nframes; i++) + { + g1 += w * (gm - g1 - a * g2); + g2 += w * (g1 - g2); + dst[i] = g2; + } + + if ( fabsf( gt - g2 ) < 0.0001f ) + g2 = gt; + + this->g1 = g1; + this->g2 = g2; +} diff --git a/nonlib/dsp.h b/nonlib/dsp.h index b76d47d..746c0e0 100644 --- a/nonlib/dsp.h +++ b/nonlib/dsp.h @@ -35,6 +35,27 @@ bool buffer_is_digital_black ( sample_t *buf, nframes_t nframes ); void buffer_copy ( sample_t *dst, const sample_t *src, nframes_t nframes ); void buffer_copy_and_apply_gain ( sample_t *dst, const sample_t *src, nframes_t nframes, float gain ); +class Value_Smoothing_Filter +{ + float w, g1, g2; + + +public: + + Value_Smoothing_Filter ( ) + { + g1 = g2 = 0; + } + + void sample_rate ( nframes_t v ); + + inline bool target_reached ( float gt ) const { return gt == g2; } + + void apply ( sample_t *dst, nframes_t nframes, float target ); + +}; + + // from SWH plugins. // Convert a value in dB's to a coefficent #define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f) diff --git a/timeline/src/Engine/Engine.H b/timeline/src/Engine/Engine.H index 569f91b..703990a 100644 --- a/timeline/src/Engine/Engine.H +++ b/timeline/src/Engine/Engine.H @@ -64,7 +64,7 @@ public: float frames_to_milliseconds ( nframes_t frames ) { - return ( frames * 1000 ) / (float)frame_rate(); + return ( frames * 1000 ) / (float)sample_rate(); } }; diff --git a/timeline/src/Engine/Track.C b/timeline/src/Engine/Track.C index ee52be9..56b692a 100644 --- a/timeline/src/Engine/Track.C +++ b/timeline/src/Engine/Track.C @@ -109,7 +109,7 @@ Track::configure_outputs ( int n ) } if ( output.size() ) - playback_ds = new Playback_DS( this, engine->frame_rate(), engine->nframes(), output.size() ); + playback_ds = new Playback_DS( this, engine->sample_rate(), engine->nframes(), output.size() ); /* FIXME: bogus */ return true; @@ -162,7 +162,7 @@ Track::configure_inputs ( int n ) } if ( input.size() ) - record_ds = new Record_DS( this, engine->frame_rate(), engine->nframes(), input.size() ); + record_ds = new Record_DS( this, engine->sample_rate(), engine->nframes(), input.size() ); // engine->unlock();