@@ -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,34 +98,20 @@ Engine::process ( nframes_t nframes ) | |||||
/* FIXME: wrong place for this */ | /* FIXME: wrong place for this */ | ||||
_thread.set( "RT" ); | _thread.set( "RT" ); | ||||
if ( freewheeling() ) | |||||
{ | |||||
/* /\* 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(); */ | |||||
} | |||||
else | |||||
if ( ! trylock() ) | |||||
{ | { | ||||
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); | |||||
unlock(); | |||||
/* 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, _process_callback_user_data); | |||||
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; } | |||||
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; } | 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 ) | ||||
{ | |||||
volatile int n = i; | |||||
_idata->descriptor->run( _idata->handle[n], nframes() ); | |||||
} | |||||
_idata->descriptor->run( _idata->handle[i], 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 ); | ||||