From f464cdbaea16ebfccb56f33e775d78bc8dfc6b4a Mon Sep 17 00:00:00 2001 From: Jonathan Moore Liles Date: Sat, 30 Jan 2010 02:35:32 -0600 Subject: [PATCH] Mixer: Respond appropriately to JACK buffer size callback. --- Mixer/Chain.C | 28 ++++++++++++++++-- Mixer/Chain.H | 3 ++ Mixer/Controller_Module.C | 4 +-- Mixer/Controller_Module.H | 2 +- Mixer/Engine/Engine.C | 54 ++++++++++++++++++---------------- Mixer/Engine/Engine.H | 6 +++- Mixer/Gain_Module.C | 4 +-- Mixer/Gain_Module.H | 2 +- Mixer/JACK_Module.C | 10 +++---- Mixer/JACK_Module.H | 2 +- Mixer/Meter_Indicator_Module.H | 2 ++ Mixer/Meter_Module.C | 4 +-- Mixer/Meter_Module.H | 2 +- Mixer/Module.H | 23 ++++++++------- Mixer/Mono_Pan_Module.C | 8 ++--- Mixer/Mono_Pan_Module.H | 2 +- Mixer/Plugin_Module.C | 7 ++--- Mixer/Plugin_Module.H | 2 +- 18 files changed, 99 insertions(+), 66 deletions(-) diff --git a/Mixer/Chain.C b/Mixer/Chain.C index 89d58af..1a31824 100644 --- a/Mixer/Chain.C +++ b/Mixer/Chain.C @@ -412,6 +412,8 @@ Chain::name ( const char *name ) { _engine = new Engine( &Chain::process, this ); + engine()->buffer_size_callback( &Chain::buffer_size, this ); + engine()->init( ename ); } else @@ -711,8 +713,30 @@ Chain::process ( nframes_t nframes ) { Module *m = *i; - m->nframes( nframes ); if ( ! m->bypass() ) - m->process(); + m->process( nframes ); + } +} + +void +Chain::buffer_size ( nframes_t nframes, void *v ) +{ + ((Chain*)v)->buffer_size( nframes ); +} + +void +Chain::buffer_size ( nframes_t nframes ) +{ + for ( unsigned int i = scratch_port.size(); i--; ) + delete[] (sample_t*)scratch_port[i].buffer(); + scratch_port.clear(); + + configure_ports(); + + for ( int i = 0; i < modules(); ++i ) + { + Module *m = module(i); + + m->resize_buffers( nframes ); } } diff --git a/Mixer/Chain.H b/Mixer/Chain.H index d3467d4..1522add 100644 --- a/Mixer/Chain.H +++ b/Mixer/Chain.H @@ -67,6 +67,9 @@ private: static void process ( nframes_t, void * ); void process ( nframes_t ); + static void buffer_size ( nframes_t nframes, void *v ); + void buffer_size ( nframes_t nframes ); + protected: void get ( Log_Entry &e ) const; diff --git a/Mixer/Controller_Module.C b/Mixer/Controller_Module.C index 847332d..9a37047 100644 --- a/Mixer/Controller_Module.C +++ b/Mixer/Controller_Module.C @@ -395,7 +395,7 @@ Controller_Module::handle ( int m ) /**********/ void -Controller_Module::process ( void ) +Controller_Module::process ( nframes_t nframes ) { THREAD_ASSERT( RT ); @@ -405,7 +405,7 @@ Controller_Module::process ( void ) if ( mode() == CV ) { - f = *((float*)jack_input[0].buffer( chain()->engine()->nframes() )); + f = *((float*)jack_input[0].buffer( nframes )); const Port *p = control_output[0].connected_port(); diff --git a/Mixer/Controller_Module.H b/Mixer/Controller_Module.H index afccd98..5006d46 100644 --- a/Mixer/Controller_Module.H +++ b/Mixer/Controller_Module.H @@ -67,7 +67,7 @@ public: LOG_CREATE_FUNC( Controller_Module ); void resize ( int, int, int, int ); - void process ( void ); + void process ( nframes_t nframes ); void draw ( void ) { diff --git a/Mixer/Engine/Engine.C b/Mixer/Engine/Engine.C index 938675e..9ce1296 100644 --- a/Mixer/Engine/Engine.C +++ b/Mixer/Engine/Engine.C @@ -33,7 +33,8 @@ Engine::Engine ( void (*process_callback)(nframes_t nframes, void *), void *user_data ) : _thread( "RT" ) { _process_callback = process_callback; - _user_data = user_data; + _process_callback_user_data = user_data; + _buffer_size_callback = 0; _buffers_dropped = 0; } @@ -44,6 +45,13 @@ Engine::~Engine ( ) +void +Engine::buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void * ), void *user_data ) +{ + _buffer_size_callback = buffer_size_callback; + _buffer_size_callback_user_data = user_data; +} + /*************/ /* Callbacks */ /*************/ @@ -68,9 +76,17 @@ Engine::freewheel ( bool starting ) /* THREAD: RT (non-RT) */ int -Engine::buffer_size ( nframes_t ) +Engine::buffer_size ( nframes_t nframes ) { - // timeline->resize_buffers( nframes ); + /* JACK calls this in the RT thread, even though it's a + * non-realtime operation. This mucks up our ability to do + * THREAD_ASSERT, so just lie and say this is the UI thread... */ + + _thread.set( "UI" ); + + _buffer_size_callback( nframes, _buffer_size_callback_user_data ); + + _thread.set( "RT" ); return 0; } @@ -82,33 +98,19 @@ Engine::process ( nframes_t nframes ) /* FIXME: wrong place for this */ _thread.set( "RT" ); - if ( freewheeling() ) + if ( ! trylock() ) { -/* /\* freewheeling mode/export. We're actually running */ -/* non-RT. Assume that everything is quiescent, locking is */ -/* unecessary and do I/O synchronously *\/ */ -/* if ( timeline ) */ -/* timeline->process( nframes ); */ - -/* /\* because we're going faster than realtime. *\/ */ -/* timeline->wait_for_buffers(); */ + /* the data structures we need to access here (tracks and + * their ports, but not track contents) may be in an + * inconsistent state at the moment. Just punt and drop this + * buffer. */ + ++_buffers_dropped; + return 0; } - else - { - if ( ! trylock() ) - { - /* the data structures we need to access here (tracks and - * their ports, but not track contents) may be in an - * inconsistent state at the moment. Just punt and drop this - * buffer. */ - ++_buffers_dropped; - return 0; - } - _process_callback(nframes, _user_data); + _process_callback(nframes, _process_callback_user_data); - unlock(); - } + unlock(); return 0; } diff --git a/Mixer/Engine/Engine.H b/Mixer/Engine/Engine.H index ac6dddf..afdb7bc 100644 --- a/Mixer/Engine/Engine.H +++ b/Mixer/Engine/Engine.H @@ -35,7 +35,10 @@ class Engine : public JACK::Client, public Mutex /* int _buffers_dropped; /\* buffers dropped because of locking *\/ */ void ( * _process_callback ) ( nframes_t, void * ); - void *_user_data; + void *_process_callback_user_data; + + void ( * _buffer_size_callback ) ( nframes_t, void * ); + void *_buffer_size_callback_user_data; void shutdown ( void ); int process ( nframes_t nframes ); @@ -60,5 +63,6 @@ public: ~Engine ( ); int dropped ( void ) const { return _buffers_dropped; } + void buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void * ), void *user_data ); }; diff --git a/Mixer/Gain_Module.C b/Mixer/Gain_Module.C index f5aa524..e83316a 100644 --- a/Mixer/Gain_Module.C +++ b/Mixer/Gain_Module.C @@ -78,7 +78,7 @@ Gain_Module::configure_inputs ( int n ) /**********/ void -Gain_Module::process ( void ) +Gain_Module::process ( nframes_t nframes ) { float g = DB_CO( control_input[0].control_value() ); @@ -86,7 +86,7 @@ Gain_Module::process ( void ) { if ( audio_input[i].connected() && audio_output[i].connected() ) { - buffer_apply_gain( (sample_t*)audio_input[i].buffer(), nframes(), g ); + buffer_apply_gain( (sample_t*)audio_input[i].buffer(), nframes, g ); } } } diff --git a/Mixer/Gain_Module.H b/Mixer/Gain_Module.H index c1335e4..3f52ae1 100644 --- a/Mixer/Gain_Module.H +++ b/Mixer/Gain_Module.H @@ -37,6 +37,6 @@ public: protected: - virtual void process ( void ); + virtual void process ( nframes_t nframes ); }; diff --git a/Mixer/JACK_Module.C b/Mixer/JACK_Module.C index e53a60a..0b7bd24 100644 --- a/Mixer/JACK_Module.C +++ b/Mixer/JACK_Module.C @@ -203,13 +203,13 @@ JACK_Module::handle_chain_name_changed ( void ) /**********/ void -JACK_Module::process ( void ) +JACK_Module::process ( nframes_t nframes ) { - for ( int i = 0; i < audio_input.size(); ++i ) + for ( unsigned int i = 0; i < audio_input.size(); ++i ) if ( audio_input[i].connected() ) - buffer_copy( (sample_t*)jack_output[i].buffer( nframes() ), (sample_t*)audio_input[i].buffer(), nframes() ); + buffer_copy( (sample_t*)jack_output[i].buffer( nframes ), (sample_t*)audio_input[i].buffer(), nframes ); - for ( int i = 0; i < audio_output.size(); ++i ) + for ( unsigned int i = 0; i < audio_output.size(); ++i ) if ( audio_output[i].connected() ) - buffer_copy( (sample_t*)audio_output[i].buffer(), (sample_t*)jack_input[i].buffer( nframes() ), nframes() ); + buffer_copy( (sample_t*)audio_output[i].buffer(), (sample_t*)jack_input[i].buffer( nframes ), nframes ); } diff --git a/Mixer/JACK_Module.H b/Mixer/JACK_Module.H index 3dcc83f..91edd9f 100644 --- a/Mixer/JACK_Module.H +++ b/Mixer/JACK_Module.H @@ -51,6 +51,6 @@ public: protected: - virtual void process ( void ); + virtual void process ( nframes_t nframes ); }; diff --git a/Mixer/Meter_Indicator_Module.H b/Mixer/Meter_Indicator_Module.H index da1de6a..3bffd70 100644 --- a/Mixer/Meter_Indicator_Module.H +++ b/Mixer/Meter_Indicator_Module.H @@ -58,6 +58,8 @@ public: LOG_CREATE_FUNC( Meter_Indicator_Module ); + void process ( nframes_t ) { } + protected: void get ( Log_Entry &e ) const; diff --git a/Mixer/Meter_Module.C b/Mixer/Meter_Module.C index f617525..bace39d 100644 --- a/Mixer/Meter_Module.C +++ b/Mixer/Meter_Module.C @@ -206,13 +206,13 @@ get_peak_sample ( const sample_t* buf, nframes_t nframes ) } void -Meter_Module::process ( void ) +Meter_Module::process ( nframes_t nframes ) { for ( unsigned int i = 0; i < audio_input.size(); ++i ) { if ( audio_input[i].connected() ) { - float dB = 20 * log10( get_peak_sample( (float*)audio_input[i].buffer(), nframes() ) / 2.0f ); + float dB = 20 * log10( get_peak_sample( (float*)audio_input[i].buffer(), nframes ) / 2.0f ); ((float*)control_output[0].buffer())[i] = dB; control_value[i] = dB; diff --git a/Mixer/Meter_Module.H b/Mixer/Meter_Module.H index af07fe8..78e1b00 100644 --- a/Mixer/Meter_Module.H +++ b/Mixer/Meter_Module.H @@ -47,5 +47,5 @@ public: protected: virtual int handle ( int m ); - virtual void process ( void ); + virtual void process ( nframes_t nframes ); }; diff --git a/Mixer/Module.H b/Mixer/Module.H index 4299a62..e30edbe 100644 --- a/Mixer/Module.H +++ b/Mixer/Module.H @@ -29,6 +29,7 @@ #include "util/Thread.H" #include "Loggable.H" +#include "JACK/Port.H" class Chain; class Module_Parameter_Editor; @@ -41,7 +42,7 @@ class Module : public Fl_Group, public Loggable { int _ins; int _outs; int _instances; - unsigned long _nframes; + nframes_t _nframes; Chain *_chain; bool _is_default; bool _bypass; @@ -137,9 +138,9 @@ public: Direction direction ( void ) const { return _direction; } Module * module ( void ) const { return _module; } - unsigned long nframes ( void ) const { return _nframes; } + nframes_t nframes ( void ) const { return _nframes; } - void buffer ( void *buf, unsigned long nframes ) { _buf = buf; _nframes = nframes; }; + void buffer ( void *buf, nframes_t nframes ) { _buf = buf; _nframes = nframes; }; void *buffer ( void ) const { return _buf; } void control_value_no_callback ( float f ) @@ -206,7 +207,7 @@ public: Direction _direction; const char *_name; void *_buf; - unsigned long _nframes; + nframes_t _nframes; Module *_module; }; @@ -226,8 +227,8 @@ public: LOG_NAME_FUNC( Module ); - unsigned long nframes ( void ) const { return _nframes; } - void nframes ( unsigned long v ) { _nframes = v; } + nframes_t nframes ( void ) const { return _nframes; } + void resize_buffers ( nframes_t v ) { _nframes = v; } int instances ( void ) const { return _instances; } @@ -235,7 +236,7 @@ public: bool is_being_controlled ( void ) const { - for ( unsigned int i = control_input.size(); i--; ) + for ( nframes_t i = control_input.size(); i--; ) if ( control_input[i].connected() ) return true; return false; @@ -243,7 +244,7 @@ public: bool is_controlling ( void ) const { - for ( unsigned int i = control_output.size(); i--; ) + for ( nframes_t i = control_output.size(); i--; ) if ( control_output[i].connected() ) return true; return false; @@ -293,7 +294,7 @@ public: int control_input_port_index ( Port *p ) { - for ( unsigned int i = control_input.size(); i--; ) + for ( nframes_t i = control_input.size(); i--; ) if ( &control_input[i] == p ) return i; @@ -302,7 +303,7 @@ public: int control_output_port_index ( Port *p ) { - for ( unsigned int i = control_output.size(); i--; ) + for ( nframes_t i = control_output.size(); i--; ) if ( &control_output[i] == p ) return i; @@ -326,7 +327,7 @@ public: * true */ virtual bool configure_inputs ( int n ) = 0; - virtual void process ( void ) { } + virtual void process ( nframes_t ) = 0; /* called whenever the value of a control port is changed. This can be used to take appropriate action from the GUI thread */ diff --git a/Mixer/Mono_Pan_Module.C b/Mixer/Mono_Pan_Module.C index b897feb..441f689 100644 --- a/Mixer/Mono_Pan_Module.C +++ b/Mixer/Mono_Pan_Module.C @@ -58,7 +58,7 @@ Mono_Pan_Module::~Mono_Pan_Module ( ) bool -Mono_Pan_Module::configure_inputs ( int n ) +Mono_Pan_Module::configure_inputs ( int ) { return true; } @@ -70,7 +70,7 @@ Mono_Pan_Module::configure_inputs ( int n ) /**********/ void -Mono_Pan_Module::process ( void ) +Mono_Pan_Module::process ( nframes_t nframes ) { const float g = control_input[0].control_value(); @@ -81,8 +81,8 @@ Mono_Pan_Module::process ( void ) audio_output[0].connected() && audio_output[1].connected() ) { - buffer_copy_and_apply_gain( (sample_t*)audio_output[1].buffer(), (sample_t*)audio_input[0].buffer(), nframes(), rg ); + buffer_copy_and_apply_gain( (sample_t*)audio_output[1].buffer(), (sample_t*)audio_input[0].buffer(), nframes, rg ); - buffer_apply_gain( (sample_t*)audio_output[0].buffer(), nframes(), lg ); + buffer_apply_gain( (sample_t*)audio_output[0].buffer(), nframes, lg ); } } diff --git a/Mixer/Mono_Pan_Module.H b/Mixer/Mono_Pan_Module.H index db0a0bf..d7ec37a 100644 --- a/Mixer/Mono_Pan_Module.H +++ b/Mixer/Mono_Pan_Module.H @@ -37,6 +37,6 @@ public: protected: - virtual void process ( void ); + virtual void process ( nframes_t nframes ); }; diff --git a/Mixer/Plugin_Module.C b/Mixer/Plugin_Module.C index 6b8bec5..65f9cf7 100644 --- a/Mixer/Plugin_Module.C +++ b/Mixer/Plugin_Module.C @@ -684,16 +684,13 @@ Plugin_Module::handle_port_connection_change ( void ) /**********/ void -Plugin_Module::process ( ) +Plugin_Module::process ( nframes_t nframes ) { handle_port_connection_change(); if ( _active ) for ( unsigned int i = 0; i < _idata->handle.size(); ++i ) - { - volatile int n = i; - _idata->descriptor->run( _idata->handle[n], nframes() ); - } + _idata->descriptor->run( _idata->handle[i], nframes ); } diff --git a/Mixer/Plugin_Module.H b/Mixer/Plugin_Module.H index db97ba6..1764999 100644 --- a/Mixer/Plugin_Module.H +++ b/Mixer/Plugin_Module.H @@ -108,7 +108,7 @@ public: int can_support_inputs ( int ); bool configure_inputs ( int ); - void process ( void ); + void process ( nframes_t ); void handle_port_connection_change ( void );