@@ -50,6 +50,8 @@ AUX_Module::AUX_Module ( ) : JACK_Module ( false ) | |||||
color( FL_DARK1 ); | color( FL_DARK1 ); | ||||
copy_label( "Aux" ); | copy_label( "Aux" ); | ||||
smoothing.sample_rate( sample_rate() ); | |||||
} | } | ||||
AUX_Module::~AUX_Module ( ) | AUX_Module::~AUX_Module ( ) | ||||
@@ -97,17 +99,39 @@ AUX_Module::number ( int n ) | |||||
copy_label( s ); | copy_label( s ); | ||||
} | } | ||||
void | |||||
AUX_Module::handle_sample_rate_change ( nframes_t n ) | |||||
{ | |||||
smoothing.sample_rate( n ); | |||||
} | |||||
void | void | ||||
AUX_Module::process ( nframes_t nframes ) | AUX_Module::process ( nframes_t nframes ) | ||||
{ | { | ||||
if ( !bypass() ) | 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 | else | ||||
@@ -20,11 +20,14 @@ | |||||
#pragma once | #pragma once | ||||
#include "JACK_Module.H" | #include "JACK_Module.H" | ||||
#include "dsp.h" | |||||
class AUX_Module : public JACK_Module | class AUX_Module : public JACK_Module | ||||
{ | { | ||||
int _number; | int _number; | ||||
Value_Smoothing_Filter smoothing; | |||||
protected: | protected: | ||||
virtual void get ( Log_Entry &e ) const; | virtual void get ( Log_Entry &e ) const; | ||||
@@ -44,6 +47,8 @@ public: | |||||
virtual ~AUX_Module ( ); | virtual ~AUX_Module ( ); | ||||
LOG_CREATE_FUNC( AUX_Module ); | LOG_CREATE_FUNC( AUX_Module ); | ||||
virtual void handle_sample_rate_change ( nframes_t n ); | |||||
protected: | protected: | ||||
@@ -250,13 +250,12 @@ Chain::initialize_with_default ( void ) | |||||
m->is_default( true ); | m->is_default( true ); | ||||
m->chain( this ); | m->chain( this ); | ||||
m->configure_outputs( 1 ); | m->configure_outputs( 1 ); | ||||
m->initialize(); | |||||
add( m ); | add( m ); | ||||
} | } | ||||
{ Module *m = new Gain_Module(); | { Module *m = new Gain_Module(); | ||||
m->is_default( true ); | m->is_default( true ); | ||||
m->initialize(); | |||||
m->chain(this); | |||||
add( m ); | add( m ); | ||||
} | } | ||||
@@ -268,7 +267,6 @@ Chain::initialize_with_default ( void ) | |||||
{ JACK_Module *m = new JACK_Module(); | { JACK_Module *m = new JACK_Module(); | ||||
m->is_default( true ); | m->is_default( true ); | ||||
m->chain( this ); | m->chain( this ); | ||||
m->initialize(); | |||||
add( m ); | add( m ); | ||||
} | } | ||||
} | } | ||||
@@ -462,7 +460,10 @@ Chain::name ( const char *name ) | |||||
engine()->buffer_size_callback( &Chain::buffer_size, this ); | engine()->buffer_size_callback( &Chain::buffer_size, this ); | ||||
engine()->port_connect_callback( &Chain::port_connect, 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 ); | const char *jack_name = engine()->init( ename ); | ||||
if ( ! jack_name ) | if ( ! jack_name ) | ||||
@@ -580,6 +581,7 @@ Chain::insert ( Module *m, Module *n ) | |||||
n->ncontrol_inputs(), | n->ncontrol_inputs(), | ||||
n->ncontrol_outputs() ); | n->ncontrol_outputs() ); | ||||
n->initialize(); | |||||
return true; | return true; | ||||
err: | 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 | void | ||||
Chain::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v ) | Chain::port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v ) | ||||
{ | { | ||||
@@ -74,6 +74,8 @@ private: | |||||
static void buffer_size ( nframes_t nframes, void *v ); | static void buffer_size ( nframes_t nframes, void *v ); | ||||
void buffer_size ( nframes_t nframes ); | 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 ); | static void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect, void *v ); | ||||
@@ -20,7 +20,7 @@ | |||||
#include "Engine.H" | #include "Engine.H" | ||||
#include "../Mixer.H" // for process() | |||||
// #include "../Mixer.H" // for process() | |||||
/* This is the home of the JACK process callback */ | /* 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; | _buffer_size_callback = 0; | ||||
_buffers_dropped = 0; | _buffers_dropped = 0; | ||||
_port_connect_callback = 0; | _port_connect_callback = 0; | ||||
_sample_rate_changed_callback = 0; | |||||
} | } | ||||
Engine::~Engine ( ) | Engine::~Engine ( ) | ||||
@@ -53,6 +54,13 @@ Engine::buffer_size_callback ( void ( *buffer_size_callback ) ( nframes_t, void | |||||
_buffer_size_callback_user_data = user_data; | _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 | 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 ) | 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; | 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 */ | /* TRHEAD: RT */ | ||||
void | void | ||||
@@ -40,9 +40,13 @@ class Engine : public JACK::Client, public Mutex | |||||
void ( * _buffer_size_callback ) ( nframes_t, void * ); | void ( * _buffer_size_callback ) ( nframes_t, void * ); | ||||
void *_buffer_size_callback_user_data; | 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 ) ( jack_port_id_t a, jack_port_id_t b, int connect, void * ); | ||||
void *_port_connect_callback_user_data; | void *_port_connect_callback_user_data; | ||||
int sample_rate_changed ( nframes_t srate ); | |||||
void shutdown ( void ); | void shutdown ( void ); | ||||
int process ( nframes_t nframes ); | int process ( nframes_t nframes ); | ||||
int xrun ( void ); | int xrun ( void ); | ||||
@@ -67,5 +71,6 @@ public: | |||||
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 ); | 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 ); | 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 ); | ||||
}; | }; |
@@ -45,6 +45,8 @@ Gain_Module::Gain_Module ( ) | |||||
end(); | end(); | ||||
log_create(); | log_create(); | ||||
smoothing.sample_rate( sample_rate() ); | |||||
} | } | ||||
Gain_Module::~Gain_Module ( ) | Gain_Module::~Gain_Module ( ) | ||||
@@ -71,6 +73,12 @@ Gain_Module::configure_inputs ( int n ) | |||||
return true; | 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 | void | ||||
Gain_Module::process ( nframes_t nframes ) | 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 ); | |||||
} | |||||
} | |||||
} | } |
@@ -20,9 +20,12 @@ | |||||
#pragma once | #pragma once | ||||
#include "Module.H" | #include "Module.H" | ||||
#include "dsp.h" | |||||
class Gain_Module : public Module | class Gain_Module : public Module | ||||
{ | { | ||||
Value_Smoothing_Filter smoothing; | |||||
public: | public: | ||||
Gain_Module ( ); | Gain_Module ( ); | ||||
@@ -38,6 +41,8 @@ public: | |||||
MODULE_CLONE_FUNC( Gain_Module ); | MODULE_CLONE_FUNC( Gain_Module ); | ||||
virtual void handle_sample_rate_change ( nframes_t n ); | |||||
protected: | protected: | ||||
virtual void process ( nframes_t nframes ); | virtual void process ( nframes_t nframes ); | ||||
@@ -47,6 +47,7 @@ | |||||
nframes_t Module::_sample_rate = 0; | |||||
Module *Module::_copied_module_empty = 0; | Module *Module::_copied_module_empty = 0; | ||||
char *Module::_copied_module_settings = 0; | char *Module::_copied_module_settings = 0; | ||||
@@ -49,6 +49,7 @@ class Module : public Fl_Group, public Loggable { | |||||
Module_Parameter_Editor *_editor; | Module_Parameter_Editor *_editor; | ||||
static nframes_t _sample_rate; | |||||
static Module *_copied_module_empty; | static Module *_copied_module_empty; | ||||
static char *_copied_module_settings; | static char *_copied_module_settings; | ||||
@@ -414,6 +415,9 @@ public: | |||||
virtual void process ( nframes_t ) = 0; | 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. | /* 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 */ | ||||
virtual void handle_control_changed ( Port * ); | virtual void handle_control_changed ( Port * ); | ||||
@@ -436,6 +440,8 @@ public: | |||||
protected: | protected: | ||||
nframes_t sample_rate ( void ) const { return Module::_sample_rate; } | |||||
void draw_connections ( void ); | void draw_connections ( void ); | ||||
void draw_label ( int X, int Y, int W, int H ); | void draw_label ( int X, int Y, int W, int H ); | ||||
void draw_box ( 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: | public: | ||||
static void set_sample_rate ( nframes_t srate ) { _sample_rate = srate; } | |||||
void command_open_parameter_editor(); | void command_open_parameter_editor(); | ||||
virtual void command_activate ( void ); | virtual void command_activate ( void ); | ||||
virtual void command_deactivate ( void ); | virtual void command_deactivate ( void ); | ||||
@@ -47,6 +47,8 @@ Mono_Pan_Module::Mono_Pan_Module ( ) | |||||
end(); | end(); | ||||
log_create(); | log_create(); | ||||
smoothing.sample_rate( sample_rate() ); | |||||
} | } | ||||
Mono_Pan_Module::~Mono_Pan_Module ( ) | 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 | bool | ||||
Mono_Pan_Module::configure_inputs ( int ) | Mono_Pan_Module::configure_inputs ( int ) | ||||
{ | { | ||||
@@ -72,10 +80,6 @@ Mono_Pan_Module::configure_inputs ( int ) | |||||
void | void | ||||
Mono_Pan_Module::process ( nframes_t nframes ) | 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() && | if ( audio_input[0].connected() && | ||||
audio_output[0].connected() && | audio_output[0].connected() && | ||||
@@ -87,9 +91,38 @@ Mono_Pan_Module::process ( nframes_t nframes ) | |||||
} | } | ||||
else | 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); | |||||
} | |||||
} | } | ||||
} | } | ||||
} | } |
@@ -20,9 +20,12 @@ | |||||
#pragma once | #pragma once | ||||
#include "Module.H" | #include "Module.H" | ||||
#include "dsp.h" | |||||
class Mono_Pan_Module : public Module | class Mono_Pan_Module : public Module | ||||
{ | { | ||||
Value_Smoothing_Filter smoothing; | |||||
public: | public: | ||||
Mono_Pan_Module ( ); | Mono_Pan_Module ( ); | ||||
@@ -37,6 +40,8 @@ public: | |||||
MODULE_CLONE_FUNC( Mono_Pan_Module ); | MODULE_CLONE_FUNC( Mono_Pan_Module ); | ||||
virtual void handle_sample_rate_change ( nframes_t n ); | |||||
protected: | protected: | ||||
virtual void process ( nframes_t nframes ); | virtual void process ( nframes_t nframes ); | ||||
@@ -341,7 +341,7 @@ Plugin_Module::plugin_instances ( unsigned int n ) | |||||
DMESSAGE( "Instantiating plugin..." ); | 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" ); | WARNING( "Failed to instantiate plugin" ); | ||||
return false; | return false; | ||||
@@ -474,7 +474,7 @@ Plugin_Module::load ( unsigned long id ) | |||||
p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound; | p.hints.minimum = _idata->descriptor->PortRangeHints[i].LowerBound; | ||||
if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) ) | 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) ) | 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; | p.hints.maximum = _idata->descriptor->PortRangeHints[i].UpperBound; | ||||
if ( LADSPA_IS_HINT_SAMPLE_RATE(hd) ) | 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; | Min=_idata->descriptor->PortRangeHints[Port].LowerBound; | ||||
if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) | if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) | ||||
{ | { | ||||
Min*=Engine::sample_rate(); | |||||
Min*=sample_rate(); | |||||
} | } | ||||
} | } | ||||
if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) | if (LADSPA_IS_HINT_BOUNDED_ABOVE(HintDesc)) | ||||
@@ -508,7 +508,7 @@ Plugin_Module::load ( unsigned long id ) | |||||
Max=_idata->descriptor->PortRangeHints[Port].UpperBound; | Max=_idata->descriptor->PortRangeHints[Port].UpperBound; | ||||
if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) | 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)) { | if (LADSPA_IS_HINT_SAMPLE_RATE(HintDesc)) { | ||||
Default *= Engine::sample_rate(); | |||||
Default *= sample_rate(); | |||||
} | } | ||||
if (LADSPA_IS_HINT_INTEGER(HintDesc)) { | if (LADSPA_IS_HINT_INTEGER(HintDesc)) { | ||||
if ( p.hints.ranged && | if ( p.hints.ranged && | ||||
@@ -29,7 +29,7 @@ | |||||
namespace JACK | namespace JACK | ||||
{ | { | ||||
nframes_t Client::_sample_rate = 0; | |||||
// nframes_t Client::_sample_rate = 0; | |||||
Client::Client ( ) | Client::Client ( ) | ||||
{ | { | ||||
@@ -114,6 +114,13 @@ namespace JACK | |||||
((Client*)arg)->port_connect( a, b, connect ); | ((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 | /** Connect to JACK using client name /client_name/. Return a static | ||||
* pointer to actual name as reported by JACK */ | * pointer to actual name as reported by JACK */ | ||||
const char * | const char * | ||||
@@ -131,6 +138,8 @@ namespace JACK | |||||
set_callback( buffer_size ); | set_callback( buffer_size ); | ||||
set_callback( port_connect ); | 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 | /* FIXME: should we wait to register this until after the project | ||||
has been loaded (and we have disk threads running)? */ | has been loaded (and we have disk threads running)? */ | ||||
if ( opts & SLOW_SYNC ) | if ( opts & SLOW_SYNC ) | ||||
@@ -143,7 +152,7 @@ namespace JACK | |||||
jack_activate( _client ); | jack_activate( _client ); | ||||
_sample_rate = frame_rate(); | |||||
// _sample_rate = frame_rate(); | |||||
return jack_get_client_name( _client ); | return jack_get_client_name( _client ); | ||||
} | } | ||||
@@ -35,11 +35,13 @@ namespace JACK | |||||
jack_client_t *_client; | jack_client_t *_client; | ||||
static nframes_t _sample_rate; | |||||
// nframes_t _sample_rate; | |||||
volatile int _xruns; | volatile int _xruns; | ||||
volatile bool _freewheeling; | volatile bool _freewheeling; | ||||
volatile bool _zombified; | 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 ); | 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 ) { } | virtual void port_connect ( jack_port_id_t a, jack_port_id_t b, int connect ) { } | ||||
static void shutdown ( void *arg ); | static void shutdown ( void *arg ); | ||||
@@ -93,15 +95,14 @@ namespace JACK | |||||
void close ( void ); | void close ( void ); | ||||
nframes_t nframes ( void ) const { return jack_get_buffer_size( _client ); } | 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; }; | int xruns ( void ) const { return _xruns; }; | ||||
bool freewheeling ( void ) const { return _freewheeling; } | bool freewheeling ( void ) const { return _freewheeling; } | ||||
void freewheeling ( bool yes ); | void freewheeling ( bool yes ); | ||||
bool zombified ( void ) const { return _zombified; } | bool zombified ( void ) const { return _zombified; } | ||||
float cpu_load ( void ) const { return jack_cpu_load( _client ); } | float cpu_load ( void ) const { return jack_cpu_load( _client ); } | ||||
void transport_stop ( void ); | void transport_stop ( void ); | ||||
void transport_start ( void ); | void transport_start ( void ); | ||||
void transport_locate ( nframes_t frame ); | void transport_locate ( nframes_t frame ); | ||||
@@ -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 ) ); | memcpy( dst, src, nframes * sizeof( sample_t ) ); | ||||
buffer_apply_gain( dst, nframes, gain ); | 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; | |||||
} |
@@ -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 ( 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 ); | 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. | // from SWH plugins. | ||||
// Convert a value in dB's to a coefficent | // Convert a value in dB's to a coefficent | ||||
#define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f) | #define DB_CO(g) ((g) > -90.0f ? powf(10.0f, (g) * 0.05f) : 0.0f) | ||||
@@ -64,7 +64,7 @@ public: | |||||
float frames_to_milliseconds ( nframes_t frames ) | float frames_to_milliseconds ( nframes_t frames ) | ||||
{ | { | ||||
return ( frames * 1000 ) / (float)frame_rate(); | |||||
return ( frames * 1000 ) / (float)sample_rate(); | |||||
} | } | ||||
}; | }; | ||||
@@ -109,7 +109,7 @@ Track::configure_outputs ( int n ) | |||||
} | } | ||||
if ( output.size() ) | 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 */ | /* FIXME: bogus */ | ||||
return true; | return true; | ||||
@@ -162,7 +162,7 @@ Track::configure_inputs ( int n ) | |||||
} | } | ||||
if ( input.size() ) | 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(); | // engine->unlock(); | ||||