@ -21,11 +21,9 @@
# include <FL/Fl_Box.H>
# include "Spatializer_Module.H"
# include "dsp.h"
# include "Module_Parameter_Editor.H"
static const float max_distance = 15.0f ;
static const float HIGHPASS_FREQ = 200.0f ;
//static const float LOWPASS_FREQ = 70000.0f;
static const float LOWPASS_FREQ = 22000.0f ;
# include <math.h>
@ -381,6 +379,7 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
is_default ( false ) ;
_panner = 0 ;
_early_panner = 0 ;
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Azimuth " ) ;
@ -424,7 +423,6 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Highpass (Hz) " ) ;
p . hints . type = Port : : Hints : : LINEAR ;
@ -432,6 +430,7 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
p . hints . minimum = 0.0f ;
p . hints . maximum = 600.0f ;
p . hints . default_value = 0.0f ;
p . hints . visible = false ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
@ -446,6 +445,73 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
p . hints . minimum = - 90.0f ;
p . hints . maximum = 90.0f ;
p . hints . default_value = 90.0f ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Angle " ) ;
p . hints . type = Port : : Hints : : LINEAR ;
p . hints . ranged = true ;
p . hints . minimum = - 180.0f ;
p . hints . maximum = + 180.0f ;
p . hints . default_value = 0.0f ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Advanced Options " ) ;
p . hints . type = Port : : Hints : : BOOLEAN ;
p . hints . ranged = true ;
p . hints . minimum = 0.0f ;
p . hints . maximum = 1.0f ;
p . hints . default_value = 0.0f ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Speed of Sound " ) ;
p . hints . type = Port : : Hints : : BOOLEAN ;
p . hints . ranged = true ;
p . hints . minimum = 0.0f ;
p . hints . maximum = 1.0f ;
p . hints . default_value = 1.0f ;
p . hints . visible = false ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Late Gain (dB) " ) ;
p . hints . type = Port : : Hints : : LOGARITHMIC ;
p . hints . ranged = true ;
p . hints . minimum = - 70.0f ;
p . hints . maximum = 6.0f ;
p . hints . default_value = 0.0f ;
p . hints . visible = false ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
add_port ( p ) ;
}
{
Port p ( this , Port : : INPUT , Port : : CONTROL , " Early Gain (dB) " ) ;
p . hints . type = Port : : Hints : : LOGARITHMIC ;
p . hints . ranged = true ;
p . hints . minimum = - 70.0f ;
p . hints . maximum = 6.0f ;
p . hints . default_value = 0.0f ;
p . hints . visible = false ;
p . connect_to ( new float ) ;
p . control_value ( p . hints . default_value ) ;
@ -456,6 +522,7 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
log_create ( ) ;
_panner = new ambisonic_panner ( ) ;
_early_panner = new ambisonic_panner ( ) ;
labelsize ( 9 ) ;
@ -465,6 +532,8 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
align ( FL_ALIGN_LEFT | FL_ALIGN_TOP | FL_ALIGN_INSIDE ) ;
gain_smoothing . sample_rate ( sample_rate ( ) ) ;
late_gain_smoothing . sample_rate ( sample_rate ( ) ) ;
early_gain_smoothing . sample_rate ( sample_rate ( ) ) ;
delay_smoothing . cutoff ( 0.5f ) ;
delay_smoothing . sample_rate ( sample_rate ( ) ) ;
}
@ -472,12 +541,10 @@ Spatializer_Module::Spatializer_Module ( ) : JACK_Module ( false )
Spatializer_Module : : ~ Spatializer_Module ( )
{
configure_inputs ( 0 ) ;
delete _early_panner ;
delete _panner ;
delete ( float * ) control_input [ 0 ] . buffer ( ) ;
delete ( float * ) control_input [ 1 ] . buffer ( ) ;
delete ( float * ) control_input [ 2 ] . buffer ( ) ;
delete ( float * ) control_input [ 3 ] . buffer ( ) ;
delete ( float * ) control_input [ 4 ] . buffer ( ) ;
for ( unsigned int i = 0 ; i < control_input . size ( ) ; i + + )
delete ( float * ) control_input [ i ] . buffer ( ) ;
}
@ -488,6 +555,8 @@ Spatializer_Module::handle_sample_rate_change ( nframes_t n )
{
gain_smoothing . sample_rate ( n ) ;
delay_smoothing . sample_rate ( n ) ;
early_gain_smoothing . sample_rate ( n ) ;
late_gain_smoothing . sample_rate ( n ) ;
for ( unsigned int i = 0 ; i < audio_input . size ( ) ; i + + )
{
@ -533,10 +602,17 @@ Spatializer_Module::process ( nframes_t nframes )
float radius = control_input [ 2 ] . control_value ( ) ;
float highpass_freq = control_input [ 3 ] . control_value ( ) ;
float width = control_input [ 4 ] . control_value ( ) ;
float angle = control_input [ 5 ] . control_value ( ) ;
// bool more_options = control_input[6].control_value();
bool speed_of_sound = control_input [ 7 ] . control_value ( ) > 0.5f ;
float late_gain = DB_CO ( control_input [ 8 ] . control_value ( ) ) ;
float early_gain = DB_CO ( control_input [ 9 ] . control_value ( ) ) ;
control_input [ 3 ] . hints . visible = highpass_freq ! = 0.0f ;
float delay_seconds = 0.0f ;
if ( radius > 1.0f )
if ( speed_of_sound & & radius > 1.0f )
delay_seconds = ( radius - 1.0f ) / 340.29f ;
/* direct sound follows inverse square law */
@ -548,12 +624,12 @@ Spatializer_Module::process ( nframes_t nframes )
float gain = 1.0f / radius ;
float cutoff_frequency = gain * LOWPASS_FREQ ;
/* float cutoff_frequency = gain * LOWPASS_FREQ; */
sample_t gainbuf [ nframes ] ;
sample_t delaybuf [ nframes ] ;
bool use_gainbuf = gain_smoothing . apply ( gainbuf , nframes , gain ) ;
bool use_gainbuf = false ;
bool use_delaybuf = delay_smoothing . apply ( delaybuf , nframes , delay_seconds ) ;
for ( unsigned int i = 0 ; i < audio_input . size ( ) ; i + + )
@ -562,7 +638,6 @@ Spatializer_Module::process ( nframes_t nframes )
/* frequency effects */
_highpass [ i ] - > run_highpass ( buf , highpass_freq , nframes ) ;
_lowpass [ i ] - > run_lowpass ( buf , cutoff_frequency , nframes ) ;
/* send to late reverb */
if ( i = = 0 )
@ -570,15 +645,94 @@ Spatializer_Module::process ( nframes_t nframes )
else
buffer_mix ( ( sample_t * ) aux_audio_output [ 0 ] . jack_port ( ) - > buffer ( nframes ) , buf , nframes ) ;
/* /\* FIXME: use smoothed value... *\/ */
/* buffer_apply_gain( (sample_t*)jack_output[0].buffer(nframes), nframes, 1.0f / sqrt(D) ); */
if ( use_delaybuf )
_delay [ i ] - > run ( buf , delaybuf , 0 , nframes ) ;
else
_delay [ i ] - > run ( buf , 0 , delay_seconds , nframes ) ;
}
{
use_gainbuf = late_gain_smoothing . apply ( gainbuf , nframes , late_gain ) ;
/* gain effects */
if ( use_gainbuf )
buffer_apply_gain_buffer ( ( sample_t * ) aux_audio_output [ 0 ] . jack_port ( ) - > buffer ( nframes ) , gainbuf , nframes ) ;
else
buffer_apply_gain ( ( sample_t * ) aux_audio_output [ 0 ] . jack_port ( ) - > buffer ( nframes ) , nframes , late_gain ) ;
}
float early_angle = azimuth - angle ;
if ( early_angle > 180.0f )
early_angle = - 180 - ( early_angle - 180 ) ;
else if ( early_angle < - 180.0f )
early_angle = 180 - ( early_angle + 180 ) ;
/* send to early reverb */
if ( audio_input . size ( ) = = 1 )
{
_early_panner - > run_mono ( ( sample_t * ) audio_input [ 0 ] . buffer ( ) ,
( sample_t * ) aux_audio_output [ 1 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 2 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 3 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 4 ] . jack_port ( ) - > buffer ( nframes ) ,
azimuth + angle ,
elevation ,
nframes ) ;
}
else
{
_early_panner - > run_stereo ( ( sample_t * ) audio_input [ 0 ] . buffer ( ) ,
( sample_t * ) audio_input [ 1 ] . buffer ( ) ,
( sample_t * ) aux_audio_output [ 1 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 2 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 3 ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) aux_audio_output [ 4 ] . jack_port ( ) - > buffer ( nframes ) ,
azimuth + angle ,
elevation ,
width ,
nframes ) ;
}
{
use_gainbuf = early_gain_smoothing . apply ( gainbuf , nframes , early_gain ) ;
for ( int i = 1 ; i < 5 ; i + + )
{
/* gain effects */
if ( use_gainbuf )
buffer_apply_gain_buffer ( ( sample_t * ) aux_audio_output [ i ] . jack_port ( ) - > buffer ( nframes ) , gainbuf , nframes ) ;
else
buffer_apply_gain ( ( sample_t * ) aux_audio_output [ i ] . jack_port ( ) - > buffer ( nframes ) , nframes , early_gain ) ;
}
}
float corrected_angle = fabs ( angle ) - ( fabs ( width ) * 0.5f ) ;
if ( corrected_angle < 0.0f )
corrected_angle = 0.0f ;
float cutoff_frequency = ( 1.0f / ( 1.0f + corrected_angle ) ) * 300000.0f ;
use_gainbuf = gain_smoothing . apply ( gainbuf , nframes , gain ) ;
for ( unsigned int i = 0 ; i < audio_input . size ( ) ; i + + )
{
/* gain effects */
if ( use_gainbuf )
buffer_apply_gain_buffer ( ( sample_t * ) audio_input [ i ] . buffer ( ) , gainbuf , nframes ) ;
else
buffer_apply_gain ( ( sample_t * ) audio_input [ i ] . buffer ( ) , nframes , gain ) ;
/* frequency effects */
_lowpass [ i ] - > run_lowpass ( ( sample_t * ) audio_input [ i ] . buffer ( ) , cutoff_frequency , nframes ) ;
/* delay effects */
if ( speed_of_sound )
{
if ( use_delaybuf )
_delay [ i ] - > run ( ( sample_t * ) audio_input [ i ] . buffer ( ) , delaybuf , 0 , nframes ) ;
else
_delay [ i ] - > run ( ( sample_t * ) audio_input [ i ] . buffer ( ) , 0 , delay_seconds , nframes ) ;
}
}
/* now do direct outputs */
if ( audio_input . size ( ) = = 1 )
{
_panner - > run_mono ( ( sample_t * ) audio_input [ 0 ] . buffer ( ) ,
@ -603,24 +757,23 @@ Spatializer_Module::process ( nframes_t nframes )
width ,
nframes ) ;
}
/* send to early reverb */
for ( int i = 4 ; i - - ; )
buffer_copy ( ( sample_t * ) aux_audio_output [ 1 + i ] . jack_port ( ) - > buffer ( nframes ) ,
( sample_t * ) audio_output [ 0 + i ] . buffer ( ) ,
nframes ) ;
/* gain effects */
if ( use_gainbuf )
{
for ( int i = 4 ; i - - ; )
buffer_apply_gain_buffer ( ( sample_t * ) audio_output [ i ] . buffer ( ) , gainbuf , nframes ) ;
}
else
}
void
Spatializer_Module : : handle_control_changed ( Port * p )
{
if ( p = = & control_input [ 6 ] )
{
for ( int i = 4 ; i - - ; )
buffer_apply_gain ( ( sample_t * ) audio_output [ i ] . buffer ( ) , nframes , gain ) ;
}
bool v = p - > control_value ( ) ;
control_input [ 7 ] . hints . visible = v ;
control_input [ 8 ] . hints . visible = v ;
control_input [ 9 ] . hints . visible = v ;
DMESSAGE ( " reloading " ) ;
if ( _editor )
_editor - > reload ( ) ;
}
}
@ -673,8 +826,9 @@ Spatializer_Module::configure_inputs ( int n )
}
}
control_input [ 4 ] . hints . visible = audio_input . size ( ) = = 2 ;
// control_input[4].hints.visible = audio_input.size() == 2;
control_input [ 4 ] . hints . default_value = audio_input . size ( ) = = 2 ? 90.0f : 0.0f ;
if ( n = = 0 )
{