diff options
Diffstat (limited to 'libs/panners/vbap/vbap.cc')
-rw-r--r-- | libs/panners/vbap/vbap.cc | 51 |
1 files changed, 41 insertions, 10 deletions
diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index 0de8d3a29a..454d04f7f4 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -118,7 +118,12 @@ VBAPanner::configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */ void VBAPanner::update () { - /* recompute signal directions based on panner azimuth and, if relevant, width (diffusion) and elevation parameters */ + /* recompute signal directions based on panner azimuth and, if relevant, width (diffusion) parameters) + */ + + /* panner azimuth control is [0 .. 1.0] which we interpret as [0 .. 360] degrees + */ + double center = _pannable->pan_azimuth_control->get_value() * 360.0; double elevation = _pannable->pan_elevation_control->get_value() * 90.0; if (_signals.size() > 1) { @@ -127,15 +132,45 @@ VBAPanner::update () double grd_step_per_signal = w / (_signals.size() - 1); for (vector<Signal*>::iterator s = _signals.begin(); s != _signals.end(); ++s) { - Signal* signal = *s; + double max_dir = center + (w/2.0); + if (max_dir > 360.0) { + max_dir = max_dir - 360.0; + } + max_dir = max (min (max_dir, 360.0), 0.0); + + if (max_dir < min_dir) { + swap (max_dir, min_dir); + } + + double degree_step_per_signal = (max_dir - min_dir) / (_signals.size() - 1); + double signal_direction = min_dir; + + if (w >= 0.0) { + + /* positive width - normal order of signal spread */ + + for (vector<Signal*>::iterator s = _signals.begin(); s != _signals.end(); ++s) { + + Signal* signal = *s; + + signal->direction = AngularVector (signal_direction, elevation); + compute_gains (signal->desired_gains, signal->desired_outputs, signal->direction.azi, signal->direction.ele); + signal_direction += degree_step_per_signal; + } + } else { int over = signal_direction; over -= (signal_direction >= 0) ? 0 : 1; signal_direction -= (double)over; - signal->direction = AngularVector (signal_direction * 360.0, elevation); - compute_gains (signal->desired_gains, signal->desired_outputs, signal->direction.azi, signal->direction.ele); - signal_direction += grd_step_per_signal; + for (vector<Signal*>::reverse_iterator s = _signals.rbegin(); s != _signals.rend(); ++s) { + + Signal* signal = *s; + + signal->direction = AngularVector (signal_direction, elevation); + compute_gains (signal->desired_gains, signal->desired_outputs, signal->direction.azi, signal->direction.ele); + signal_direction += degree_step_per_signal; + } } } else if (_signals.size() == 1) { double center = _pannable->pan_azimuth_control->get_value() * 360.0; @@ -477,11 +512,7 @@ void VBAPanner::reset () { set_position (0); - if (_signals.size() > 1) { - set_width (1.0 - (1.0 / (double)_signals.size())); - } else { - set_width (0); - } + set_width (1); set_elevation (0); update (); |