Mixer: Respond appropriately to JACK buffer size callback.
This commit is contained in:
parent
453d7bcd4e
commit
f464cdbaea
|
@ -412,6 +412,8 @@ Chain::name ( const char *name )
|
||||||
{
|
{
|
||||||
_engine = new Engine( &Chain::process, this );
|
_engine = new Engine( &Chain::process, this );
|
||||||
|
|
||||||
|
engine()->buffer_size_callback( &Chain::buffer_size, this );
|
||||||
|
|
||||||
engine()->init( ename );
|
engine()->init( ename );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -711,8 +713,30 @@ Chain::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
Module *m = *i;
|
Module *m = *i;
|
||||||
|
|
||||||
m->nframes( nframes );
|
|
||||||
if ( ! m->bypass() )
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,9 @@ private:
|
||||||
static void process ( nframes_t, void * );
|
static void process ( nframes_t, void * );
|
||||||
void process ( nframes_t );
|
void process ( nframes_t );
|
||||||
|
|
||||||
|
static void buffer_size ( nframes_t nframes, void *v );
|
||||||
|
void buffer_size ( nframes_t nframes );
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get ( Log_Entry &e ) const;
|
void get ( Log_Entry &e ) const;
|
||||||
|
|
|
@ -395,7 +395,7 @@ Controller_Module::handle ( int m )
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
void
|
void
|
||||||
Controller_Module::process ( void )
|
Controller_Module::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
THREAD_ASSERT( RT );
|
THREAD_ASSERT( RT );
|
||||||
|
|
||||||
|
@ -405,7 +405,7 @@ Controller_Module::process ( void )
|
||||||
|
|
||||||
if ( mode() == CV )
|
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();
|
const Port *p = control_output[0].connected_port();
|
||||||
|
|
||||||
|
|
|
@ -67,7 +67,7 @@ public:
|
||||||
LOG_CREATE_FUNC( Controller_Module );
|
LOG_CREATE_FUNC( Controller_Module );
|
||||||
|
|
||||||
void resize ( int, int, int, int );
|
void resize ( int, int, int, int );
|
||||||
void process ( void );
|
void process ( nframes_t nframes );
|
||||||
|
|
||||||
void draw ( void )
|
void draw ( void )
|
||||||
{
|
{
|
||||||
|
|
|
@ -33,7 +33,8 @@
|
||||||
Engine::Engine ( void (*process_callback)(nframes_t nframes, void *), void *user_data ) : _thread( "RT" )
|
Engine::Engine ( void (*process_callback)(nframes_t nframes, void *), void *user_data ) : _thread( "RT" )
|
||||||
{
|
{
|
||||||
_process_callback = process_callback;
|
_process_callback = process_callback;
|
||||||
_user_data = user_data;
|
_process_callback_user_data = user_data;
|
||||||
|
_buffer_size_callback = 0;
|
||||||
_buffers_dropped = 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 */
|
/* Callbacks */
|
||||||
/*************/
|
/*************/
|
||||||
|
@ -68,9 +76,17 @@ Engine::freewheel ( bool starting )
|
||||||
|
|
||||||
/* THREAD: RT (non-RT) */
|
/* THREAD: RT (non-RT) */
|
||||||
int
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -82,33 +98,19 @@ Engine::process ( nframes_t nframes )
|
||||||
/* FIXME: wrong place for this */
|
/* FIXME: wrong place for this */
|
||||||
_thread.set( "RT" );
|
_thread.set( "RT" );
|
||||||
|
|
||||||
if ( freewheeling() )
|
if ( ! trylock() )
|
||||||
{
|
{
|
||||||
/* /\* freewheeling mode/export. We're actually running */
|
/* the data structures we need to access here (tracks and
|
||||||
/* non-RT. Assume that everything is quiescent, locking is */
|
* their ports, but not track contents) may be in an
|
||||||
/* unecessary and do I/O synchronously *\/ */
|
* inconsistent state at the moment. Just punt and drop this
|
||||||
/* if ( timeline ) */
|
* buffer. */
|
||||||
/* timeline->process( nframes ); */
|
++_buffers_dropped;
|
||||||
|
return 0;
|
||||||
/* /\* because we're going faster than realtime. *\/ */
|
|
||||||
/* timeline->wait_for_buffers(); */
|
|
||||||
}
|
}
|
||||||
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,10 @@ class Engine : public JACK::Client, public Mutex
|
||||||
/* int _buffers_dropped; /\* buffers dropped because of locking *\/ */
|
/* int _buffers_dropped; /\* buffers dropped because of locking *\/ */
|
||||||
|
|
||||||
void ( * _process_callback ) ( nframes_t, void * );
|
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 );
|
void shutdown ( void );
|
||||||
int process ( nframes_t nframes );
|
int process ( nframes_t nframes );
|
||||||
|
@ -60,5 +63,6 @@ public:
|
||||||
~Engine ( );
|
~Engine ( );
|
||||||
|
|
||||||
int dropped ( void ) const { return _buffers_dropped; }
|
int dropped ( void ) const { return _buffers_dropped; }
|
||||||
|
void buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void * ), void *user_data );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -78,7 +78,7 @@ Gain_Module::configure_inputs ( int n )
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
void
|
void
|
||||||
Gain_Module::process ( void )
|
Gain_Module::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
float g = DB_CO( control_input[0].control_value() );
|
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() )
|
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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void process ( void );
|
virtual void process ( nframes_t nframes );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -203,13 +203,13 @@ JACK_Module::handle_chain_name_changed ( void )
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
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() )
|
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() )
|
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 );
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void process ( void );
|
virtual void process ( nframes_t nframes );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -58,6 +58,8 @@ public:
|
||||||
|
|
||||||
LOG_CREATE_FUNC( Meter_Indicator_Module );
|
LOG_CREATE_FUNC( Meter_Indicator_Module );
|
||||||
|
|
||||||
|
void process ( nframes_t ) { }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
void get ( Log_Entry &e ) const;
|
void get ( Log_Entry &e ) const;
|
||||||
|
|
|
@ -206,13 +206,13 @@ get_peak_sample ( const sample_t* buf, nframes_t nframes )
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Meter_Module::process ( void )
|
Meter_Module::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
for ( unsigned int i = 0; i < audio_input.size(); ++i )
|
for ( unsigned int i = 0; i < audio_input.size(); ++i )
|
||||||
{
|
{
|
||||||
if ( audio_input[i].connected() )
|
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;
|
((float*)control_output[0].buffer())[i] = dB;
|
||||||
control_value[i] = dB;
|
control_value[i] = dB;
|
||||||
|
|
|
@ -47,5 +47,5 @@ public:
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual int handle ( int m );
|
virtual int handle ( int m );
|
||||||
virtual void process ( void );
|
virtual void process ( nframes_t nframes );
|
||||||
};
|
};
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
#include "util/Thread.H"
|
#include "util/Thread.H"
|
||||||
|
|
||||||
#include "Loggable.H"
|
#include "Loggable.H"
|
||||||
|
#include "JACK/Port.H"
|
||||||
|
|
||||||
class Chain;
|
class Chain;
|
||||||
class Module_Parameter_Editor;
|
class Module_Parameter_Editor;
|
||||||
|
@ -41,7 +42,7 @@ class Module : public Fl_Group, public Loggable {
|
||||||
int _ins;
|
int _ins;
|
||||||
int _outs;
|
int _outs;
|
||||||
int _instances;
|
int _instances;
|
||||||
unsigned long _nframes;
|
nframes_t _nframes;
|
||||||
Chain *_chain;
|
Chain *_chain;
|
||||||
bool _is_default;
|
bool _is_default;
|
||||||
bool _bypass;
|
bool _bypass;
|
||||||
|
@ -137,9 +138,9 @@ public:
|
||||||
Direction direction ( void ) const { return _direction; }
|
Direction direction ( void ) const { return _direction; }
|
||||||
|
|
||||||
Module * module ( void ) const { return _module; }
|
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 *buffer ( void ) const { return _buf; }
|
||||||
|
|
||||||
void control_value_no_callback ( float f )
|
void control_value_no_callback ( float f )
|
||||||
|
@ -206,7 +207,7 @@ public:
|
||||||
Direction _direction;
|
Direction _direction;
|
||||||
const char *_name;
|
const char *_name;
|
||||||
void *_buf;
|
void *_buf;
|
||||||
unsigned long _nframes;
|
nframes_t _nframes;
|
||||||
Module *_module;
|
Module *_module;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -226,8 +227,8 @@ public:
|
||||||
|
|
||||||
LOG_NAME_FUNC( Module );
|
LOG_NAME_FUNC( Module );
|
||||||
|
|
||||||
unsigned long nframes ( void ) const { return _nframes; }
|
nframes_t nframes ( void ) const { return _nframes; }
|
||||||
void nframes ( unsigned long v ) { _nframes = v; }
|
void resize_buffers ( nframes_t v ) { _nframes = v; }
|
||||||
|
|
||||||
|
|
||||||
int instances ( void ) const { return _instances; }
|
int instances ( void ) const { return _instances; }
|
||||||
|
@ -235,7 +236,7 @@ public:
|
||||||
|
|
||||||
bool is_being_controlled ( void ) const
|
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() )
|
if ( control_input[i].connected() )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -243,7 +244,7 @@ public:
|
||||||
|
|
||||||
bool is_controlling ( void ) const
|
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() )
|
if ( control_output[i].connected() )
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
@ -293,7 +294,7 @@ public:
|
||||||
|
|
||||||
int control_input_port_index ( Port *p )
|
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 )
|
if ( &control_input[i] == p )
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
|
@ -302,7 +303,7 @@ public:
|
||||||
|
|
||||||
int control_output_port_index ( Port *p )
|
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 )
|
if ( &control_output[i] == p )
|
||||||
return i;
|
return i;
|
||||||
|
|
||||||
|
@ -326,7 +327,7 @@ public:
|
||||||
* true */
|
* true */
|
||||||
virtual bool configure_inputs ( int n ) = 0;
|
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.
|
/* called whenever the value of a control port is changed.
|
||||||
This can be used to take appropriate action from the GUI thread */
|
This can be used to take appropriate action from the GUI thread */
|
||||||
|
|
|
@ -58,7 +58,7 @@ Mono_Pan_Module::~Mono_Pan_Module ( )
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Mono_Pan_Module::configure_inputs ( int n )
|
Mono_Pan_Module::configure_inputs ( int )
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ Mono_Pan_Module::configure_inputs ( int n )
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
void
|
void
|
||||||
Mono_Pan_Module::process ( void )
|
Mono_Pan_Module::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
const float g = control_input[0].control_value();
|
const float g = control_input[0].control_value();
|
||||||
|
|
||||||
|
@ -81,8 +81,8 @@ Mono_Pan_Module::process ( void )
|
||||||
audio_output[0].connected() &&
|
audio_output[0].connected() &&
|
||||||
audio_output[1].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 );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,6 +37,6 @@ public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void process ( void );
|
virtual void process ( nframes_t nframes );
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
|
@ -684,16 +684,13 @@ Plugin_Module::handle_port_connection_change ( void )
|
||||||
/**********/
|
/**********/
|
||||||
|
|
||||||
void
|
void
|
||||||
Plugin_Module::process ( )
|
Plugin_Module::process ( nframes_t nframes )
|
||||||
{
|
{
|
||||||
handle_port_connection_change();
|
handle_port_connection_change();
|
||||||
|
|
||||||
if ( _active )
|
if ( _active )
|
||||||
for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
|
for ( unsigned int i = 0; i < _idata->handle.size(); ++i )
|
||||||
{
|
_idata->descriptor->run( _idata->handle[i], nframes );
|
||||||
volatile int n = i;
|
|
||||||
_idata->descriptor->run( _idata->handle[n], nframes() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -108,7 +108,7 @@ public:
|
||||||
int can_support_inputs ( int );
|
int can_support_inputs ( int );
|
||||||
bool configure_inputs ( int );
|
bool configure_inputs ( int );
|
||||||
|
|
||||||
void process ( void );
|
void process ( nframes_t );
|
||||||
|
|
||||||
void handle_port_connection_change ( void );
|
void handle_port_connection_change ( void );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue