|
|
@@ -595,169 +595,166 @@ Spatializer_Module::draw ( void ) |
|
|
|
void |
|
|
|
Spatializer_Module::process ( nframes_t nframes ) |
|
|
|
{ |
|
|
|
if ( !bypass() ) |
|
|
|
{ |
|
|
|
float azimuth = control_input[0].control_value(); |
|
|
|
float elevation = control_input[1].control_value(); |
|
|
|
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(); |
|
|
|
float azimuth = control_input[0].control_value(); |
|
|
|
float elevation = control_input[1].control_value(); |
|
|
|
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() ); |
|
|
|
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; |
|
|
|
control_input[3].hints.visible = highpass_freq != 0.0f; |
|
|
|
|
|
|
|
float delay_seconds = 0.0f; |
|
|
|
float delay_seconds = 0.0f; |
|
|
|
|
|
|
|
if ( speed_of_sound && radius > 1.0f ) |
|
|
|
delay_seconds = ( radius - 1.0f ) / 340.29f; |
|
|
|
if ( speed_of_sound && radius > 1.0f ) |
|
|
|
delay_seconds = ( radius - 1.0f ) / 340.29f; |
|
|
|
|
|
|
|
/* direct sound follows inverse square law */ |
|
|
|
/* but it's just the inverse as far as SPL goes */ |
|
|
|
/* direct sound follows inverse square law */ |
|
|
|
/* but it's just the inverse as far as SPL goes */ |
|
|
|
|
|
|
|
/* let's not go nuts... */ |
|
|
|
if ( radius < 0.01f ) |
|
|
|
radius = 0.01f; |
|
|
|
/* let's not go nuts... */ |
|
|
|
if ( radius < 0.01f ) |
|
|
|
radius = 0.01f; |
|
|
|
|
|
|
|
float gain = 1.0f / radius; |
|
|
|
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]; |
|
|
|
sample_t gainbuf[nframes]; |
|
|
|
sample_t delaybuf[nframes]; |
|
|
|
|
|
|
|
bool use_gainbuf = false; |
|
|
|
bool use_delaybuf = delay_smoothing.apply( delaybuf, nframes, delay_seconds ); |
|
|
|
bool use_gainbuf = false; |
|
|
|
bool use_delaybuf = delay_smoothing.apply( delaybuf, nframes, delay_seconds ); |
|
|
|
|
|
|
|
for ( unsigned int i = 0; i < audio_input.size(); i++ ) |
|
|
|
{ |
|
|
|
sample_t *buf = (sample_t*) audio_input[i].buffer(); |
|
|
|
for ( unsigned int i = 0; i < audio_input.size(); i++ ) |
|
|
|
{ |
|
|
|
sample_t *buf = (sample_t*) audio_input[i].buffer(); |
|
|
|
|
|
|
|
/* frequency effects */ |
|
|
|
_highpass[i]->run_highpass( buf, highpass_freq, nframes ); |
|
|
|
/* frequency effects */ |
|
|
|
_highpass[i]->run_highpass( buf, highpass_freq, nframes ); |
|
|
|
|
|
|
|
/* send to late reverb */ |
|
|
|
if ( i == 0 ) |
|
|
|
buffer_copy( (sample_t*)aux_audio_output[0].jack_port()->buffer(nframes), buf, nframes ); |
|
|
|
else |
|
|
|
buffer_mix( (sample_t*)aux_audio_output[0].jack_port()->buffer(nframes), buf, nframes ); |
|
|
|
/* send to late reverb */ |
|
|
|
if ( i == 0 ) |
|
|
|
buffer_copy( (sample_t*)aux_audio_output[0].jack_port()->buffer(nframes), buf, nframes ); |
|
|
|
else |
|
|
|
buffer_mix( (sample_t*)aux_audio_output[0].jack_port()->buffer(nframes), buf, nframes ); |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
{ |
|
|
|
use_gainbuf = late_gain_smoothing.apply( gainbuf, nframes, late_gain ); |
|
|
|
{ |
|
|
|
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 ); |
|
|
|
} |
|
|
|
/* gain effects */ |
|
|
|
if ( unlikely( 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 ); |
|
|
|
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 ); |
|
|
|
} |
|
|
|
/* 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 ); |
|
|
|
{ |
|
|
|
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 ); |
|
|
|
} |
|
|
|
for ( int i = 1; i < 5; i++ ) |
|
|
|
{ |
|
|
|
/* gain effects */ |
|
|
|
if ( unlikely( 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); |
|
|
|
float corrected_angle = fabs( angle ) - (fabs( width ) * 0.5f); |
|
|
|
|
|
|
|
if ( corrected_angle < 0.0f ) |
|
|
|
corrected_angle = 0.0f; |
|
|
|
if ( corrected_angle < 0.0f ) |
|
|
|
corrected_angle = 0.0f; |
|
|
|
|
|
|
|
float cutoff_frequency = ( 1.0f / ( 1.0f + corrected_angle ) ) * 300000.0f; |
|
|
|
float cutoff_frequency = ( 1.0f / ( 1.0f + corrected_angle ) ) * 300000.0f; |
|
|
|
|
|
|
|
use_gainbuf = gain_smoothing.apply( gainbuf, nframes, gain ); |
|
|
|
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 ); |
|
|
|
for ( unsigned int i = 0; i < audio_input.size(); i++ ) |
|
|
|
{ |
|
|
|
/* gain effects */ |
|
|
|
if ( unlikely( 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 ); |
|
|
|
/* 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 ) |
|
|
|
/* delay effects */ |
|
|
|
if ( likely( speed_of_sound ) ) |
|
|
|
{ |
|
|
|
_panner->run_mono( (sample_t*)audio_input[0].buffer(), |
|
|
|
(sample_t*)audio_output[0].buffer(), |
|
|
|
(sample_t*)audio_output[1].buffer(), |
|
|
|
(sample_t*)audio_output[2].buffer(), |
|
|
|
(sample_t*)audio_output[3].buffer(), |
|
|
|
azimuth, |
|
|
|
elevation, |
|
|
|
nframes ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_panner->run_stereo( (sample_t*)audio_input[0].buffer(), |
|
|
|
(sample_t*)audio_input[1].buffer(), |
|
|
|
(sample_t*)audio_output[0].buffer(), |
|
|
|
(sample_t*)audio_output[1].buffer(), |
|
|
|
(sample_t*)audio_output[2].buffer(), |
|
|
|
(sample_t*)audio_output[3].buffer(), |
|
|
|
azimuth, |
|
|
|
elevation, |
|
|
|
width, |
|
|
|
nframes ); |
|
|
|
if ( unlikely( 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(), |
|
|
|
(sample_t*)audio_output[0].buffer(), |
|
|
|
(sample_t*)audio_output[1].buffer(), |
|
|
|
(sample_t*)audio_output[2].buffer(), |
|
|
|
(sample_t*)audio_output[3].buffer(), |
|
|
|
azimuth, |
|
|
|
elevation, |
|
|
|
nframes ); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
_panner->run_stereo( (sample_t*)audio_input[0].buffer(), |
|
|
|
(sample_t*)audio_input[1].buffer(), |
|
|
|
(sample_t*)audio_output[0].buffer(), |
|
|
|
(sample_t*)audio_output[1].buffer(), |
|
|
|
(sample_t*)audio_output[2].buffer(), |
|
|
|
(sample_t*)audio_output[3].buffer(), |
|
|
|
azimuth, |
|
|
|
elevation, |
|
|
|
width, |
|
|
|
nframes ); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
void |
|
|
|