From 4780a0fd60a5f62eb02efec82ddfcd27e9d3bffe Mon Sep 17 00:00:00 2001 From: Robin Gareus Date: Mon, 23 Mar 2020 16:46:03 +0100 Subject: NO-OP: whitespace --- libs/panners/1in2out/panner_1in2out.cc | 245 +++++++-------- libs/panners/1in2out/panner_1in2out.h | 39 ++- libs/panners/2in2out/panner_2in2out.cc | 415 ++++++++++++------------- libs/panners/2in2out/panner_2in2out.h | 34 +- libs/panners/stereobalance/panner_balance.cc | 120 ++++--- libs/panners/stereobalance/panner_balance.h | 46 +-- libs/panners/vbap/vbap.cc | 427 +++++++++++++------------ libs/panners/vbap/vbap.h | 56 ++-- libs/panners/vbap/vbap_speakers.cc | 447 +++++++++++++-------------- libs/panners/vbap/vbap_speakers.h | 95 +++--- 10 files changed, 958 insertions(+), 966 deletions(-) (limited to 'libs/panners') diff --git a/libs/panners/1in2out/panner_1in2out.cc b/libs/panners/1in2out/panner_1in2out.cc index dade3286ba..8cf6b70e0c 100644 --- a/libs/panners/1in2out/panner_1in2out.cc +++ b/libs/panners/1in2out/panner_1in2out.cc @@ -21,40 +21,38 @@ #include -#include #include -#include -#include +#include #include +#include +#include #include +#include #include -#include #include #include "pbd/cartesian.h" #include "pbd/convert.h" +#include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/failed_constructor.h" #include "pbd/xml++.h" -#include "pbd/enumwriter.h" #include "evoral/Curve.h" -#include "ardour/session.h" -#include "ardour/panner.h" -#include "ardour/utils.h" #include "ardour/audio_buffer.h" - -#include "ardour/debug.h" -#include "ardour/runtime_functions.h" #include "ardour/buffer_set.h" -#include "ardour/audio_buffer.h" +#include "ardour/debug.h" #include "ardour/pannable.h" +#include "ardour/panner.h" #include "ardour/profile.h" +#include "ardour/runtime_functions.h" +#include "ardour/session.h" +#include "ardour/utils.h" -#include "pbd/i18n.h" #include "panner_1in2out.h" +#include "pbd/i18n.h" #include "pbd/mathfix.h" @@ -63,15 +61,19 @@ using namespace ARDOUR; using namespace PBD; static PanPluginDescriptor _descriptor = { - "Mono to Stereo Panner", - "http://ardour.org/plugin/panner_1in2out", - "http://ardour.org/plugin/panner_1in2out#ui", - 1, 2, - 20, - Panner1in2out::factory + "Mono to Stereo Panner", + "http://ardour.org/plugin/panner_1in2out", + "http://ardour.org/plugin/panner_1in2out#ui", + 1, 2, + 20, + Panner1in2out::factory }; -extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } +extern "C" ARDOURPANNER_API PanPluginDescriptor* +panner_descriptor () +{ + return &_descriptor; +} Panner1in2out::Panner1in2out (boost::shared_ptr p) : Panner (p) @@ -80,16 +82,16 @@ Panner1in2out::Panner1in2out (boost::shared_ptr p) _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); } - _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); + _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); - update (); + update (); - left = desired_left; - right = desired_right; - left_interp = left; - right_interp = right; + left = desired_left; + right = desired_right; + left_interp = left; + right_interp = right; - _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&Panner1in2out::update, this)); + _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&Panner1in2out::update, this)); } Panner1in2out::~Panner1in2out () @@ -99,32 +101,32 @@ Panner1in2out::~Panner1in2out () void Panner1in2out::update () { - float panR, panL; - float const pan_law_attenuation = -3.0f; - float const scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); + float panR, panL; + float const pan_law_attenuation = -3.0f; + float const scale = 2.0f - 4.0f * powf (10.0f, pan_law_attenuation / 20.0f); - panR = _pannable->pan_azimuth_control->get_value(); - panL = 1 - panR; + panR = _pannable->pan_azimuth_control->get_value (); + panL = 1 - panR; - desired_left = panL * (scale * panL + 1.0f - scale); - desired_right = panR * (scale * panR + 1.0f - scale); + desired_left = panL * (scale * panL + 1.0f - scale); + desired_right = panR * (scale * panR + 1.0f - scale); } void Panner1in2out::set_position (double p) { - if (clamp_position (p)) { - _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); - } + if (clamp_position (p)) { + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); + } } bool Panner1in2out::clamp_position (double& p) { - /* any position between 0.0 and 1.0 is legal */ - DEBUG_TRACE (DEBUG::Panning, string_compose ("want to move panner to %1 - always allowed in 0.0-1.0 range\n", p)); - p = max (min (p, 1.0), 0.0); - return true; + /* any position between 0.0 and 1.0 is legal */ + DEBUG_TRACE (DEBUG::Panning, string_compose ("want to move panner to %1 - always allowed in 0.0-1.0 range\n", p)); + p = max (min (p, 1.0), 0.0); + return true; } pair @@ -136,37 +138,37 @@ Panner1in2out::position_range () const double Panner1in2out::position () const { - return _pannable->pan_azimuth_control->get_value (); + return _pannable->pan_azimuth_control->get_value (); } void Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t /* not used */) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - pan_t delta; + pan_t delta; Sample* dst; - pan_t pan; + pan_t pan; - Sample* const src = srcbuf.data(); + Sample* const src = srcbuf.data (); /* LEFT OUTPUT */ - dst = obufs.get_audio(0).data(); + dst = obufs.get_audio (0).data (); if (fabsf ((delta = (left - desired_left))) > 0.002) { // about 1 degree of arc /* we've moving the pan by an appreciable amount, so we must - interpolate over 64 samples or nframes, whichever is smaller */ + * interpolate over 64 samples or nframes, whichever is smaller */ - pframes_t const limit = min ((pframes_t) 64, nframes); - pframes_t n; + pframes_t const limit = min ((pframes_t)64, nframes); + pframes_t n; - delta = -(delta / (float) (limit)); + delta = -(delta / (float)(limit)); for (n = 0; n < limit; n++) { left_interp = left_interp + delta; - left = left_interp + 0.9 * (left - left_interp); + left = left_interp + 0.9 * (left - left_interp); dst[n] += src[n] * left * gain_coeff; } @@ -174,32 +176,25 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai pan = left * gain_coeff; - mix_buffers_with_gain (dst+n,src+n,nframes-n,pan); + mix_buffers_with_gain (dst + n, src + n, nframes - n, pan); } else { - - left = desired_left; + left = desired_left; left_interp = left; if ((pan = (left * gain_coeff)) != 1.0f) { - if (pan != 0.0f) { - /* pan is 1 but also not 0, so we must do it "properly" */ - mix_buffers_with_gain(dst,src,nframes,pan); - - /* mark that we wrote into the buffer */ - - // obufs[0] = 0; + mix_buffers_with_gain (dst, src, nframes, pan); + /* XXX it would be nice to mark that we wrote into the buffer */ } } else { - /* pan is 1 so we can just copy the input samples straight in */ - mix_buffers_no_gain(dst,src,nframes); + mix_buffers_no_gain (dst, src, nframes); /* XXX it would be nice to mark that we wrote into the buffer */ } @@ -207,21 +202,21 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai /* RIGHT OUTPUT */ - dst = obufs.get_audio(1).data(); + dst = obufs.get_audio (1).data (); if (fabsf ((delta = (right - desired_right))) > 0.002) { // about 1 degree of arc /* we're moving the pan by an appreciable amount, so we must - interpolate over 64 samples or nframes, whichever is smaller */ + * interpolate over 64 samples or nframes, whichever is smaller */ - pframes_t const limit = min ((pframes_t) 64, nframes); - pframes_t n; + pframes_t const limit = min ((pframes_t)64, nframes); + pframes_t n; - delta = -(delta / (float) (limit)); + delta = -(delta / (float)(limit)); for (n = 0; n < limit; n++) { right_interp = right_interp + delta; - right = right_interp + 0.9 * (right - right_interp); + right = right_interp + 0.9 * (right - right_interp); dst[n] += src[n] * right * gain_coeff; } @@ -229,36 +224,31 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai pan = right * gain_coeff; - mix_buffers_with_gain(dst+n,src+n,nframes-n,pan); + mix_buffers_with_gain (dst + n, src + n, nframes - n, pan); /* XXX it would be nice to mark the buffer as written to */ } else { - - right = desired_right; + right = desired_right; right_interp = right; if ((pan = (right * gain_coeff)) != 1.0f) { - if (pan != 0.0f) { - /* pan is not 1 but also not 0, so we must do it "properly" */ - mix_buffers_with_gain(dst,src,nframes,pan); + mix_buffers_with_gain (dst, src, nframes, pan); /* XXX it would be nice to mark the buffer as written to */ } } else { - /* pan is 1 so we can just copy the input samples straight in */ - mix_buffers_no_gain(dst,src,nframes); + mix_buffers_no_gain (dst, src, nframes); /* XXX it would be nice to mark the buffer as written to */ } } - } void @@ -266,18 +256,18 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, samplepos_t start, samplepos_t end, pframes_t nframes, pan_t** buffers, uint32_t which) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - Sample* dst; - pan_t* pbuf; - Sample* const src = srcbuf.data(); - pan_t* const position = buffers[0]; + Sample* dst; + pan_t* pbuf; + Sample* const src = srcbuf.data (); + pan_t* const position = buffers[0]; /* fetch positional data */ - if (!_pannable->pan_azimuth_control->list()->curve().rt_safe_get_vector (start, end, position, nframes)) { + if (!_pannable->pan_azimuth_control->list ()->curve ().rt_safe_get_vector (start, end, position, nframes)) { /* fallback */ - distribute_one (srcbuf, obufs, 1.0, nframes, which); + distribute_one (srcbuf, obufs, 1.0, nframes, which); return; } @@ -286,27 +276,26 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, */ const float pan_law_attenuation = -3.0f; - const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); + const float scale = 2.0f - 4.0f * powf (10.0f, pan_law_attenuation / 20.0f); for (pframes_t n = 0; n < nframes; ++n) { - - float panR = position[n]; - const float panL = 1 - panR; - - /* note that are overwriting buffers, but its OK - because we're finished with their old contents - (position automation data) and are - replacing it with panning/gain coefficients - that we need to actually process the data. - */ - - buffers[0][n] = panL * (scale * panL + 1.0f - scale); - buffers[1][n] = panR * (scale * panR + 1.0f - scale); - } + float panR = position[n]; + const float panL = 1 - panR; + + /* note that are overwriting buffers, but its OK + * because we're finished with their old contents + * (position automation data) and are + * replacing it with panning/gain coefficients + * that we need to actually process the data. + */ + + buffers[0][n] = panL * (scale * panL + 1.0f - scale); + buffers[1][n] = panR * (scale * panR + 1.0f - scale); + } /* LEFT OUTPUT */ - dst = obufs.get_audio(0).data(); + dst = obufs.get_audio (0).data (); pbuf = buffers[0]; for (pframes_t n = 0; n < nframes; ++n) { @@ -317,7 +306,7 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, /* RIGHT OUTPUT */ - dst = obufs.get_audio(1).data(); + dst = obufs.get_audio (1).data (); pbuf = buffers[1]; for (pframes_t n = 0; n < nframes; ++n) { @@ -327,7 +316,6 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, /* XXX it would be nice to mark the buffer as written to */ } - Panner* Panner1in2out::factory (boost::shared_ptr p, boost::shared_ptr /* ignored */) { @@ -338,38 +326,37 @@ XMLNode& Panner1in2out::get_state () { XMLNode& root (Panner::get_state ()); - root.set_property (X_("uri"), _descriptor.panner_uri); + root.set_property (X_ ("uri"), _descriptor.panner_uri); /* this is needed to allow new sessions to load with old Ardour: */ - root.set_property (X_("type"), _descriptor.name); + root.set_property (X_ ("type"), _descriptor.name); return root; } string Panner1in2out::value_as_string (boost::shared_ptr ac) const { - /* DO NOT USE LocaleGuard HERE */ - double val = ac->get_value(); - - switch (ac->parameter().type()) { - case PanAzimuthAutomation: - /* We show the position of the center of the image relative to the left & right. - This is expressed as a pair of percentage values that ranges from (100,0) - (hard left) through (50,50) (hard center) to (0,100) (hard right). - - This is pretty wierd, but its the way audio engineers expect it. Just remember that - the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. - - This is designed to be as narrow as possible. Dedicated - panner GUIs can do their own version of this if they need - something less compact. - */ - - return string_compose (_("L%1R%2"), (int) rint (100.0 * (1.0 - val)), - (int) rint (100.0 * val)); - - default: - return _("unused"); - } + double val = ac->get_value (); + + switch (ac->parameter ().type ()) { + case PanAzimuthAutomation: + /* We show the position of the center of the image relative to the left & right. + * This is expressed as a pair of percentage values that ranges from (100,0) + * (hard left) through (50,50) (hard center) to (0,100) (hard right). + * + * This is pretty wierd, but its the way audio engineers expect it. Just remember that + * the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. + * + * This is designed to be as narrow as possible. Dedicated + * panner GUIs can do their own version of this if they need + * something less compact. + */ + + return string_compose (_ ("L%1R%2"), (int)rint (100.0 * (1.0 - val)), + (int)rint (100.0 * val)); + + default: + return _ ("unused"); + } } void diff --git a/libs/panners/1in2out/panner_1in2out.h b/libs/panners/1in2out/panner_1in2out.h index 55ec3ffae3..2681541575 100644 --- a/libs/panners/1in2out/panner_1in2out.h +++ b/libs/panners/1in2out/panner_1in2out.h @@ -21,36 +21,43 @@ #ifndef __ardour_panner_1in2out_h__ #define __ardour_panner_1in2out_h__ -#include #include -#include -#include +#include #include +#include +#include -#include "pbd/stateful.h" -#include "pbd/controllable.h" #include "pbd/cartesian.h" +#include "pbd/controllable.h" +#include "pbd/stateful.h" -#include "ardour/types.h" #include "ardour/panner.h" +#include "ardour/types.h" - -namespace ARDOUR { +namespace ARDOUR +{ class Panner1in2out : public Panner { - public: +public: Panner1in2out (boost::shared_ptr); ~Panner1in2out (); - void set_position (double); - bool clamp_position (double&); + void set_position (double); + bool clamp_position (double&); std::pair position_range () const; - double position() const; + double position () const; + + ChanCount in () const + { + return ChanCount (DataType::AUDIO, 1); + } - ChanCount in() const { return ChanCount (DataType::AUDIO, 1); } - ChanCount out() const { return ChanCount (DataType::AUDIO, 2); } + ChanCount out () const + { + return ChanCount (DataType::AUDIO, 2); + } static Panner* factory (boost::shared_ptr, boost::shared_ptr); @@ -60,7 +67,7 @@ class Panner1in2out : public Panner void reset (); - protected: +protected: float left; float right; float desired_left; @@ -76,6 +83,6 @@ class Panner1in2out : public Panner void update (); }; -} // namespace +} // namespace ARDOUR #endif /* __ardour_panner_1in2out_h__ */ diff --git a/libs/panners/2in2out/panner_2in2out.cc b/libs/panners/2in2out/panner_2in2out.cc index e6127194c4..e7c1365e46 100644 --- a/libs/panners/2in2out/panner_2in2out.cc +++ b/libs/panners/2in2out/panner_2in2out.cc @@ -20,35 +20,34 @@ #include -#include #include -#include -#include +#include #include +#include +#include #include +#include #include -#include #include #include "pbd/cartesian.h" #include "pbd/convert.h" +#include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/failed_constructor.h" #include "pbd/xml++.h" -#include "pbd/enumwriter.h" #include "evoral/Curve.h" -#include "ardour/audio_buffer.h" #include "ardour/audio_buffer.h" #include "ardour/buffer_set.h" +#include "ardour/mix.h" #include "ardour/pan_controllable.h" #include "ardour/pannable.h" #include "ardour/runtime_functions.h" #include "ardour/session.h" #include "ardour/utils.h" -#include "ardour/mix.h" #include "panner_2in2out.h" @@ -61,45 +60,49 @@ using namespace ARDOUR; using namespace PBD; static PanPluginDescriptor _descriptor = { - "Equal Power Stereo", - "http://ardour.org/plugin/panner_2in2out", - "http://ardour.org/plugin/panner_2in2out#ui", - 2, 2, - 20, - Panner2in2out::factory + "Equal Power Stereo", + "http://ardour.org/plugin/panner_2in2out", + "http://ardour.org/plugin/panner_2in2out#ui", + 2, 2, + 20, + Panner2in2out::factory }; -extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } +extern "C" ARDOURPANNER_API PanPluginDescriptor* +panner_descriptor () +{ + return &_descriptor; +} Panner2in2out::Panner2in2out (boost::shared_ptr p) : Panner (p) { - if (!_pannable->has_state()) { - _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); - _pannable->pan_width_control->set_value (1.0, Controllable::NoGroup); - } + if (!_pannable->has_state ()) { + _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); + _pannable->pan_width_control->set_value (1.0, Controllable::NoGroup); + } - double const w = width(); - double const wrange = min (position(), (1 - position())) * 2; - if (fabs(w) > wrange) { - set_width(w > 0 ? wrange : -wrange); - } + double const w = width (); + double const wrange = min (position (), (1 - position ())) * 2; + if (fabs (w) > wrange) { + set_width (w > 0 ? wrange : -wrange); + } - _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); - _can_automate_list.insert (Evoral::Parameter (PanWidthAutomation)); + _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); + _can_automate_list.insert (Evoral::Parameter (PanWidthAutomation)); - update (); + update (); - /* LEFT SIGNAL */ - left_interp[0] = left[0] = desired_left[0]; - right_interp[0] = right[0] = desired_right[0]; + /* LEFT SIGNAL */ + left_interp[0] = left[0] = desired_left[0]; + right_interp[0] = right[0] = desired_right[0]; - /* RIGHT SIGNAL */ - left_interp[1] = left[1] = desired_left[1]; - right_interp[1] = right[1] = desired_right[1]; + /* RIGHT SIGNAL */ + left_interp[1] = left[1] = desired_left[1]; + right_interp[1] = right[1] = desired_right[1]; - _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&Panner2in2out::update, this)); - _pannable->pan_width_control->Changed.connect_same_thread (*this, boost::bind (&Panner2in2out::update, this)); + _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&Panner2in2out::update, this)); + _pannable->pan_width_control->Changed.connect_same_thread (*this, boost::bind (&Panner2in2out::update, this)); } Panner2in2out::~Panner2in2out () @@ -109,29 +112,29 @@ Panner2in2out::~Panner2in2out () double Panner2in2out::position () const { - return _pannable->pan_azimuth_control->get_value(); + return _pannable->pan_azimuth_control->get_value (); } double Panner2in2out::width () const { - return _pannable->pan_width_control->get_value(); + return _pannable->pan_width_control->get_value (); } void Panner2in2out::set_position (double p) { - if (clamp_position (p)) { - _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); - } + if (clamp_position (p)) { + _pannable->pan_azimuth_control->set_value (p, Controllable::NoGroup); + } } void Panner2in2out::set_width (double p) { - if (clamp_width (p)) { - _pannable->pan_width_control->set_value (p, Controllable::NoGroup); - } + if (clamp_width (p)) { + _pannable->pan_width_control->set_value (p, Controllable::NoGroup); + } } void @@ -150,149 +153,148 @@ Panner2in2out::update () return; } - /* it would be very nice to split this out into a virtual function - that can be accessed from BaseStereoPanner and used in do_distribute_automated(). - - but the place where its used in do_distribute_automated() is a tight inner loop, - and making "nframes" virtual function calls to compute values is an absurd - overhead. - */ - - /* x == 0 => hard left = 180.0 degrees - x == 1 => hard right = 0.0 degrees - */ - - float pos[2]; - double width = this->width (); - const double direction_as_lr_fract = position (); - - double const wrange = min (position(), (1 - position())) * 2; - if (fabs(width) > wrange) { - width = (width > 0 ? wrange : -wrange); - } + /* it would be very nice to split this out into a virtual function + * that can be accessed from BaseStereoPanner and used in do_distribute_automated(). + * + * but the place where its used in do_distribute_automated() is a tight inner loop, + * and making "nframes" virtual function calls to compute values is an absurd + * overhead. + */ + + /* x == 0 => hard left = 180.0 degrees + * x == 1 => hard right = 0.0 degrees + */ + + float pos[2]; + double width = this->width (); + const double direction_as_lr_fract = position (); + + double const wrange = min (position (), (1 - position ())) * 2; + if (fabs (width) > wrange) { + width = (width > 0 ? wrange : -wrange); + } - if (width < 0.0) { - width = -width; - pos[0] = direction_as_lr_fract + (width/2.0); // left signal lr_fract - pos[1] = direction_as_lr_fract - (width/2.0); // right signal lr_fract - } else { - pos[1] = direction_as_lr_fract + (width/2.0); // right signal lr_fract - pos[0] = direction_as_lr_fract - (width/2.0); // left signal lr_fract - } + if (width < 0.0) { + width = -width; + pos[0] = direction_as_lr_fract + (width / 2.0); // left signal lr_fract + pos[1] = direction_as_lr_fract - (width / 2.0); // right signal lr_fract + } else { + pos[1] = direction_as_lr_fract + (width / 2.0); // right signal lr_fract + pos[0] = direction_as_lr_fract - (width / 2.0); // left signal lr_fract + } - /* compute target gain coefficients for both input signals */ + /* compute target gain coefficients for both input signals */ - float const pan_law_attenuation = -3.0f; - float const scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); - float panR; - float panL; + float const pan_law_attenuation = -3.0f; + float const scale = 2.0f - 4.0f * powf (10.0f, pan_law_attenuation / 20.0f); + float panR; + float panL; - /* left signal */ + /* left signal */ - panR = pos[0]; - panL = 1 - panR; - desired_left[0] = panL * (scale * panL + 1.0f - scale); - desired_right[0] = panR * (scale * panR + 1.0f - scale); + panR = pos[0]; + panL = 1 - panR; + desired_left[0] = panL * (scale * panL + 1.0f - scale); + desired_right[0] = panR * (scale * panR + 1.0f - scale); - /* right signal */ + /* right signal */ - panR = pos[1]; - panL = 1 - panR; - desired_left[1] = panL * (scale * panL + 1.0f - scale); - desired_right[1] = panR * (scale * panR + 1.0f - scale); + panR = pos[1]; + panL = 1 - panR; + desired_left[1] = panL * (scale * panL + 1.0f - scale); + desired_right[1] = panR * (scale * panR + 1.0f - scale); } bool Panner2in2out::clamp_position (double& p) { - double w = width (); - return clamp_stereo_pan (p, w); + double w = width (); + return clamp_stereo_pan (p, w); } bool Panner2in2out::clamp_width (double& w) { - double p = position (); - return clamp_stereo_pan (p, w); + double p = position (); + return clamp_stereo_pan (p, w); } pair Panner2in2out::position_range () const { - return make_pair (0.5 - (1 - width()) / 2, 0.5 + (1 - width()) / 2); + return make_pair (0.5 - (1 - width ()) / 2, 0.5 + (1 - width ()) / 2); } pair Panner2in2out::width_range () const { - double const w = min (position(), (1 - position())) * 2; + double const w = min (position (), (1 - position ())) * 2; return make_pair (-w, w); } bool Panner2in2out::clamp_stereo_pan (double& direction_as_lr_fract, double& width) { - double r_pos; - double l_pos; + double r_pos; + double l_pos; - width = max (min (width, 1.0), -1.0); - direction_as_lr_fract = max (min (direction_as_lr_fract, 1.0), 0.0); + width = max (min (width, 1.0), -1.0); + direction_as_lr_fract = max (min (direction_as_lr_fract, 1.0), 0.0); - r_pos = direction_as_lr_fract + (width/2.0); - l_pos = direction_as_lr_fract - (width/2.0); + r_pos = direction_as_lr_fract + (width / 2.0); + l_pos = direction_as_lr_fract - (width / 2.0); - if (width < 0.0) { - swap (r_pos, l_pos); - } - - /* if the new left position is less than or equal to zero (hard left) and the left panner - is already there, we're not moving the left signal. - */ + if (width < 0.0) { + swap (r_pos, l_pos); + } - if (l_pos < 0.0) { - return false; - } + /* if the new left position is less than or equal to zero (hard left) + * and the left panner is already there, we're not moving the left signal. + */ - /* if the new right position is less than or equal to 1.0 (hard right) and the right panner - is already there, we're not moving the right signal. - */ + if (l_pos < 0.0) { + return false; + } - if (r_pos > 1.0) { - return false; + /* if the new right position is less than or equal to 1.0 (hard right) + * and the right panner is already there, we're not moving the right signal. + */ - } + if (r_pos > 1.0) { + return false; + } - return true; + return true; } void Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - pan_t delta; + pan_t delta; Sample* dst; - pan_t pan; + pan_t pan; - Sample* const src = srcbuf.data(); + Sample* const src = srcbuf.data (); /* LEFT OUTPUT */ - dst = obufs.get_audio(0).data(); + dst = obufs.get_audio (0).data (); if (fabsf ((delta = (left[which] - desired_left[which]))) > 0.002) { // about 1 degree of arc /* we've moving the pan by an appreciable amount, so we must - interpolate over 64 samples or nframes, whichever is smaller */ + * interpolate over 64 samples or nframes, whichever is smaller */ - pframes_t const limit = min ((pframes_t) 64, nframes); - pframes_t n; + pframes_t const limit = min ((pframes_t)64, nframes); + pframes_t n; - delta = -(delta / (float) (limit)); + delta = -(delta / (float)(limit)); for (n = 0; n < limit; n++) { left_interp[which] = left_interp[which] + delta; - left[which] = left_interp[which] + 0.9 * (left[which] - left_interp[which]); + left[which] = left_interp[which] + 0.9 * (left[which] - left_interp[which]); dst[n] += src[n] * left[which] * gain_coeff; } @@ -300,33 +302,25 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai pan = left[which] * gain_coeff; - mix_buffers_with_gain (dst+n,src+n,nframes-n,pan); + mix_buffers_with_gain (dst + n, src + n, nframes - n, pan); } else { - - left[which] = desired_left[which]; + left[which] = desired_left[which]; left_interp[which] = left[which]; if ((pan = (left[which] * gain_coeff)) != 1.0f) { - if (pan != 0.0f) { - /* pan is 1 but also not 0, so we must do it "properly" */ - //obufs.get_audio(1).read_from (srcbuf, nframes); - mix_buffers_with_gain(dst,src,nframes,pan); - - /* mark that we wrote into the buffer */ - - // obufs[0] = 0; + mix_buffers_with_gain (dst, src, nframes, pan); + /* XXX it would be nice to mark that we wrote into the buffer */ } } else { - /* pan is 1 so we can just copy the input samples straight in */ - mix_buffers_no_gain(dst,src,nframes); + mix_buffers_no_gain (dst, src, nframes); /* XXX it would be nice to mark that we wrote into the buffer */ } @@ -334,21 +328,21 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai /* RIGHT OUTPUT */ - dst = obufs.get_audio(1).data(); + dst = obufs.get_audio (1).data (); if (fabsf ((delta = (right[which] - desired_right[which]))) > 0.002) { // about 1 degree of arc /* we're moving the pan by an appreciable amount, so we must - interpolate over 64 samples or nframes, whichever is smaller */ + * interpolate over 64 samples or nframes, whichever is smaller */ - pframes_t const limit = min ((pframes_t) 64, nframes); - pframes_t n; + pframes_t const limit = min ((pframes_t)64, nframes); + pframes_t n; - delta = -(delta / (float) (limit)); + delta = -(delta / (float)(limit)); for (n = 0; n < limit; n++) { right_interp[which] = right_interp[which] + delta; - right[which] = right_interp[which] + 0.9 * (right[which] - right_interp[which]); + right[which] = right_interp[which] + 0.9 * (right[which] - right_interp[which]); dst[n] += src[n] * right[which] * gain_coeff; } @@ -356,32 +350,27 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai pan = right[which] * gain_coeff; - mix_buffers_with_gain(dst+n,src+n,nframes-n,pan); + mix_buffers_with_gain (dst + n, src + n, nframes - n, pan); /* XXX it would be nice to mark the buffer as written to */ } else { - - right[which] = desired_right[which]; + right[which] = desired_right[which]; right_interp[which] = right[which]; if ((pan = (right[which] * gain_coeff)) != 1.0f) { - if (pan != 0.0f) { - /* pan is not 1 but also not 0, so we must do it "properly" */ - mix_buffers_with_gain(dst,src,nframes,pan); - // obufs.get_audio(1).read_from (srcbuf, nframes); + mix_buffers_with_gain (dst, src, nframes, pan); /* XXX it would be nice to mark the buffer as written to */ } } else { - /* pan is 1 so we can just copy the input samples straight in */ - mix_buffers_no_gain(dst,src,nframes); + mix_buffers_no_gain (dst, src, nframes); /* XXX it would be nice to mark the buffer as written to */ } @@ -393,65 +382,64 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, samplepos_t start, samplepos_t end, pframes_t nframes, pan_t** buffers, uint32_t which) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - Sample* dst; - pan_t* pbuf; - Sample* const src = srcbuf.data(); - pan_t* const position = buffers[0]; - pan_t* const width = buffers[1]; + Sample* dst; + pan_t* pbuf; + Sample* const src = srcbuf.data (); + pan_t* const position = buffers[0]; + pan_t* const width = buffers[1]; /* fetch positional data */ - if (!_pannable->pan_azimuth_control->list()->curve().rt_safe_get_vector (start, end, position, nframes)) { + if (!_pannable->pan_azimuth_control->list ()->curve ().rt_safe_get_vector (start, end, position, nframes)) { /* fallback */ - distribute_one (srcbuf, obufs, 1.0, nframes, which); + distribute_one (srcbuf, obufs, 1.0, nframes, which); return; } - if (!_pannable->pan_width_control->list()->curve().rt_safe_get_vector (start, end, width, nframes)) { + if (!_pannable->pan_width_control->list ()->curve ().rt_safe_get_vector (start, end, width, nframes)) { /* fallback */ - distribute_one (srcbuf, obufs, 1.0, nframes, which); + distribute_one (srcbuf, obufs, 1.0, nframes, which); return; } /* apply pan law to convert positional data into pan coefficients for - each buffer (output) + * each buffer (output) */ const float pan_law_attenuation = -3.0f; - const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f); + const float scale = 2.0f - 4.0f * powf (10.0f, pan_law_attenuation / 20.0f); for (pframes_t n = 0; n < nframes; ++n) { + float panR; - float panR; - - if (which == 0) { - // panning left signal - panR = position[n] - (width[n]/2.0f); // center - width/2 - } else { - // panning right signal - panR = position[n] + (width[n]/2.0f); // center - width/2 - } + if (which == 0) { + /* panning left signal */ + panR = position[n] - (width[n] / 2.0f); // center - width/2 + } else { + /* panning right signal */ + panR = position[n] + (width[n] / 2.0f); // center - width/2 + } - panR = max(0.f, min(1.f, panR)); + panR = max (0.f, min (1.f, panR)); - const float panL = 1 - panR; + const float panL = 1 - panR; - /* note that are overwriting buffers, but its OK - because we're finished with their old contents - (position/width automation data) and are - replacing it with panning/gain coefficients - that we need to actually process the data. - */ + /* note that are overwriting buffers, but its OK + * because we're finished with their old contents + * (position/width automation data) and are + * replacing it with panning/gain coefficients + * that we need to actually process the data. + */ - buffers[0][n] = panL * (scale * panL + 1.0f - scale); - buffers[1][n] = panR * (scale * panR + 1.0f - scale); - } + buffers[0][n] = panL * (scale * panL + 1.0f - scale); + buffers[1][n] = panR * (scale * panR + 1.0f - scale); + } /* LEFT OUTPUT */ - dst = obufs.get_audio(0).data(); + dst = obufs.get_audio (0).data (); pbuf = buffers[0]; for (pframes_t n = 0; n < nframes; ++n) { @@ -462,7 +450,7 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, /* RIGHT OUTPUT */ - dst = obufs.get_audio(1).data(); + dst = obufs.get_audio (1).data (); pbuf = buffers[1]; for (pframes_t n = 0; n < nframes; ++n) { @@ -482,41 +470,40 @@ XMLNode& Panner2in2out::get_state () { XMLNode& root (Panner::get_state ()); - root.set_property (X_("uri"), _descriptor.panner_uri); + root.set_property (X_ ("uri"), _descriptor.panner_uri); /* this is needed to allow new sessions to load with old Ardour: */ - root.set_property (X_("type"), _descriptor.name); + root.set_property (X_ ("type"), _descriptor.name); return root; } string Panner2in2out::value_as_string (boost::shared_ptr ac) const { - /* DO NOT USE LocaleGuard HERE */ - double val = ac->get_value(); - - switch (ac->parameter().type()) { - case PanAzimuthAutomation: - /* We show the position of the center of the image relative to the left & right. - This is expressed as a pair of percentage values that ranges from (100,0) - (hard left) through (50,50) (hard center) to (0,100) (hard right). - - This is pretty wierd, but its the way audio engineers expect it. Just remember that - the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. - - This is designed to be as narrow as possible. Dedicated - panner GUIs can do their own version of this if they need - something less compact. - */ - - return string_compose (_("L%1R%2"), (int) rint (100.0 * (1.0 - val)), - (int) rint (100.0 * val)); - - case PanWidthAutomation: - return string_compose (_("Width: %1%%"), (int) floor (100.0 * val)); - - default: - return _("unused"); - } + double val = ac->get_value (); + + switch (ac->parameter ().type ()) { + case PanAzimuthAutomation: + /* We show the position of the center of the image relative to the left & right. + * This is expressed as a pair of percentage values that ranges from (100,0) + * (hard left) through (50,50) (hard center) to (0,100) (hard right). + * + * This is pretty wierd, but its the way audio engineers expect it. Just remember that + * the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. + * + * This is designed to be as narrow as possible. Dedicated + * panner GUIs can do their own version of this if they need + * something less compact. + */ + + return string_compose (_ ("L%1R%2"), (int)rint (100.0 * (1.0 - val)), + (int)rint (100.0 * val)); + + case PanWidthAutomation: + return string_compose (_ ("Width: %1%%"), (int)floor (100.0 * val)); + + default: + return _ ("unused"); + } } void diff --git a/libs/panners/2in2out/panner_2in2out.h b/libs/panners/2in2out/panner_2in2out.h index 4816be7734..cbf6d88e4c 100644 --- a/libs/panners/2in2out/panner_2in2out.h +++ b/libs/panners/2in2out/panner_2in2out.h @@ -20,31 +20,37 @@ #ifndef __ardour_panner_2in2out_h__ #define __ardour_panner_2in2out_h__ -#include #include -#include -#include +#include #include +#include +#include -#include "pbd/stateful.h" -#include "pbd/controllable.h" #include "pbd/cartesian.h" +#include "pbd/controllable.h" +#include "pbd/stateful.h" -#include "ardour/automation_control.h" #include "ardour/automatable.h" +#include "ardour/automation_control.h" #include "ardour/panner.h" #include "ardour/types.h" -namespace ARDOUR { - +namespace ARDOUR +{ class Panner2in2out : public Panner { - public: +public: Panner2in2out (boost::shared_ptr); ~Panner2in2out (); - ChanCount in() const { return ChanCount (DataType::AUDIO, 2); } - ChanCount out() const { return ChanCount (DataType::AUDIO, 2); } + ChanCount in () const + { + return ChanCount (DataType::AUDIO, 2); + } + ChanCount out () const + { + return ChanCount (DataType::AUDIO, 2); + } bool clamp_position (double&); bool clamp_width (double&); @@ -69,7 +75,7 @@ class Panner2in2out : public Panner void reset (); void thaw (); - protected: +protected: float left[2]; float right[2]; float desired_left[2]; @@ -77,7 +83,7 @@ class Panner2in2out : public Panner float left_interp[2]; float right_interp[2]; - private: +private: bool clamp_stereo_pan (double& direction_as_lr_fract, double& width); void distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which); @@ -86,6 +92,6 @@ class Panner2in2out : public Panner pan_t** buffers, uint32_t which); }; -} // namespace +} // namespace ARDOUR #endif /* __ardour_panner_2in2out_h__ */ diff --git a/libs/panners/stereobalance/panner_balance.cc b/libs/panners/stereobalance/panner_balance.cc index 701f081951..4502bf1f09 100644 --- a/libs/panners/stereobalance/panner_balance.cc +++ b/libs/panners/stereobalance/panner_balance.cc @@ -19,35 +19,34 @@ #include -#include #include -#include -#include +#include #include +#include +#include #include +#include #include -#include #include #include "pbd/cartesian.h" #include "pbd/convert.h" +#include "pbd/enumwriter.h" #include "pbd/error.h" #include "pbd/failed_constructor.h" #include "pbd/xml++.h" -#include "pbd/enumwriter.h" #include "evoral/Curve.h" -#include "ardour/audio_buffer.h" #include "ardour/audio_buffer.h" #include "ardour/buffer_set.h" +#include "ardour/mix.h" #include "ardour/pan_controllable.h" #include "ardour/pannable.h" #include "ardour/runtime_functions.h" #include "ardour/session.h" #include "ardour/utils.h" -#include "ardour/mix.h" #include "panner_balance.h" @@ -68,12 +67,16 @@ static PanPluginDescriptor _descriptor = { Pannerbalance::factory }; -extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } +extern "C" ARDOURPANNER_API PanPluginDescriptor* +panner_descriptor () +{ + return &_descriptor; +} Pannerbalance::Pannerbalance (boost::shared_ptr p) : Panner (p) { - if (!_pannable->has_state()) { + if (!_pannable->has_state ()) { _pannable->pan_azimuth_control->set_value (0.5, Controllable::NoGroup); } @@ -96,10 +99,10 @@ Pannerbalance::~Pannerbalance () double Pannerbalance::position () const { - return _pannable->pan_azimuth_control->get_value(); + return _pannable->pan_azimuth_control->get_value (); } - void +void Pannerbalance::set_position (double p) { if (clamp_position (p)) { @@ -107,7 +110,7 @@ Pannerbalance::set_position (double p) } } - void +void Pannerbalance::thaw () { Panner::thaw (); @@ -123,7 +126,7 @@ Pannerbalance::update () return; } - float const pos = _pannable->pan_azimuth_control->get_value(); + float const pos = _pannable->pan_azimuth_control->get_value (); if (pos == .5) { desired_pos[0] = 1.0; @@ -153,29 +156,29 @@ Pannerbalance::position_range () const void Pannerbalance::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - pan_t delta; + pan_t delta; Sample* dst; - pan_t pan; + pan_t pan; - Sample* const src = srcbuf.data(); + Sample* const src = srcbuf.data (); - dst = obufs.get_audio(which).data(); + dst = obufs.get_audio (which).data (); if (fabsf ((delta = (pos[which] - desired_pos[which]))) > 0.002) { // about 1 degree of arc /* we've moving the pan by an appreciable amount, so we must - interpolate over 64 samples or nframes, whichever is smaller */ + * interpolate over 64 samples or nframes, whichever is smaller */ - pframes_t const limit = min ((pframes_t) 64, nframes); - pframes_t n; + pframes_t const limit = min ((pframes_t)64, nframes); + pframes_t n; - delta = -(delta / (float) (limit)); + delta = -(delta / (float)(limit)); for (n = 0; n < limit; n++) { pos_interp[which] = pos_interp[which] + delta; - pos[which] = pos_interp[which] + 0.9 * (pos[which] - pos_interp[which]); + pos[which] = pos_interp[which] + 0.9 * (pos[which] - pos_interp[which]); dst[n] += src[n] * pos[which] * gain_coeff; } @@ -183,31 +186,24 @@ Pannerbalance::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai pan = pos[which] * gain_coeff; - mix_buffers_with_gain (dst+n,src+n,nframes-n,pan); + mix_buffers_with_gain (dst + n, src + n, nframes - n, pan); } else { - - pos[which] = desired_pos[which]; + pos[which] = desired_pos[which]; pos_interp[which] = pos[which]; if ((pan = (pos[which] * gain_coeff)) != 1.0f) { - if (pan != 0.0f) { - /* pan is 1 but also not 0, so we must do it "properly" */ - //obufs.get_audio(1).read_from (srcbuf, nframes); - mix_buffers_with_gain(dst,src,nframes,pan); - - /* mark that we wrote into the buffer */ - - // obufs[0] = 0; + mix_buffers_with_gain (dst, src, nframes, pan); + /* XXX it would be nice to mark the buffer as written to */ } } else { /* pan is 1 so we can just copy the input samples straight in */ - mix_buffers_no_gain(dst,src,nframes); + mix_buffers_no_gain (dst, src, nframes); } } } @@ -217,23 +213,22 @@ Pannerbalance::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, samplepos_t start, samplepos_t end, pframes_t nframes, pan_t** buffers, uint32_t which) { - assert (obufs.count().n_audio() == 2); + assert (obufs.count ().n_audio () == 2); - Sample* dst; - pan_t* pbuf; - Sample* const src = srcbuf.data(); - pan_t* const position = buffers[0]; + Sample* dst; + pan_t* pbuf; + Sample* const src = srcbuf.data (); + pan_t* const position = buffers[0]; /* fetch positional data */ - if (!_pannable->pan_azimuth_control->list()->curve().rt_safe_get_vector (start, end, position, nframes)) { + if (!_pannable->pan_azimuth_control->list ()->curve ().rt_safe_get_vector (start, end, position, nframes)) { /* fallback */ distribute_one (srcbuf, obufs, 1.0, nframes, which); return; } for (pframes_t n = 0; n < nframes; ++n) { - float const pos = position[n]; if (which == 0) { // Left @@ -251,7 +246,7 @@ Pannerbalance::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, } } - dst = obufs.get_audio(which).data(); + dst = obufs.get_audio (which).data (); pbuf = buffers[which]; for (pframes_t n = 0; n < nframes; ++n) { @@ -267,41 +262,40 @@ Pannerbalance::factory (boost::shared_ptr p, boost::shared_ptr ac) const { - /* DO NOT USE LocaleGuard HERE */ - double val = ac->get_value(); + double val = ac->get_value (); - switch (ac->parameter().type()) { + switch (ac->parameter ().type ()) { case PanAzimuthAutomation: /* We show the position of the center of the image relative to the left & right. - This is expressed as a pair of percentage values that ranges from (100,0) - (hard left) through (50,50) (hard center) to (0,100) (hard right). - - This is pretty wierd, but its the way audio engineers expect it. Just remember that - the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. - - This is designed to be as narrow as possible. Dedicated - panner GUIs can do their own version of this if they need - something less compact. - */ - - return string_compose (_("L%1R%2"), (int) rint (100.0 * (1.0 - val)), - (int) rint (100.0 * val)); + * This is expressed as a pair of percentage values that ranges from (100,0) + * (hard left) through (50,50) (hard center) to (0,100) (hard right). + * + * This is pretty wierd, but its the way audio engineers expect it. Just remember that + * the center of the USA isn't Kansas, its (50LA, 50NY) and it will all make sense. + * + * This is designed to be as narrow as possible. Dedicated + * panner GUIs can do their own version of this if they need + * something less compact. + */ + + return string_compose (_ ("L%1R%2"), (int)rint (100.0 * (1.0 - val)), + (int)rint (100.0 * val)); default: - return _("unused"); + return _ ("unused"); } } diff --git a/libs/panners/stereobalance/panner_balance.h b/libs/panners/stereobalance/panner_balance.h index 9ce5519759..b95a234a87 100644 --- a/libs/panners/stereobalance/panner_balance.h +++ b/libs/panners/stereobalance/panner_balance.h @@ -19,36 +19,42 @@ #ifndef __ardour_panner_balance_h__ #define __ardour_panner_balance_h__ -#include #include -#include -#include +#include #include +#include +#include -#include "pbd/stateful.h" -#include "pbd/controllable.h" #include "pbd/cartesian.h" +#include "pbd/controllable.h" +#include "pbd/stateful.h" -#include "ardour/automation_control.h" #include "ardour/automatable.h" +#include "ardour/automation_control.h" #include "ardour/panner.h" #include "ardour/types.h" -namespace ARDOUR { - +namespace ARDOUR +{ class Pannerbalance : public Panner { - public: +public: Pannerbalance (boost::shared_ptr); ~Pannerbalance (); - ChanCount in() const { return ChanCount (DataType::AUDIO, 2); } - ChanCount out() const { return ChanCount (DataType::AUDIO, 2); } - - void set_position (double); - bool clamp_position (double&); + ChanCount in () const + { + return ChanCount (DataType::AUDIO, 2); + } + ChanCount out () const + { + return ChanCount (DataType::AUDIO, 2); + } + + void set_position (double); + bool clamp_position (double&); std::pair position_range () const; - double position () const; + double position () const; static Panner* factory (boost::shared_ptr, boost::shared_ptr); @@ -59,20 +65,20 @@ class Pannerbalance : public Panner void reset (); void thaw (); - protected: +protected: float pos[2]; float desired_pos[2]; float pos_interp[2]; void update (); - private: +private: void distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which); void distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs, - samplepos_t start, samplepos_t end, pframes_t nframes, - pan_t** buffers, uint32_t which); + samplepos_t start, samplepos_t end, pframes_t nframes, + pan_t** buffers, uint32_t which); }; -} // namespace +} // namespace ARDOUR #endif /* __ardour_panner_balance_h__ */ diff --git a/libs/panners/vbap/vbap.cc b/libs/panners/vbap/vbap.cc index 0bf9e34255..fbb33c53a0 100644 --- a/libs/panners/vbap/vbap.cc +++ b/libs/panners/vbap/vbap.cc @@ -20,8 +20,8 @@ */ #include -#include #include +#include #include #include @@ -51,131 +51,132 @@ using namespace ARDOUR; using namespace std; static PanPluginDescriptor _descriptor = { - "VBAP 2D panner", - "http://ardour.org/plugin/panner_vbap", - "http://ardour.org/plugin/panner_vbap#ui", - -1, -1, - 10, - VBAPanner::factory + "VBAP 2D panner", + "http://ardour.org/plugin/panner_vbap", + "http://ardour.org/plugin/panner_vbap#ui", + -1, -1, + 10, + VBAPanner::factory }; -extern "C" ARDOURPANNER_API PanPluginDescriptor* panner_descriptor () { return &_descriptor; } +extern "C" ARDOURPANNER_API PanPluginDescriptor* +panner_descriptor () +{ + return &_descriptor; +} VBAPanner::Signal::Signal (VBAPanner&, uint32_t, uint32_t n_speakers) { - resize_gains (n_speakers); + resize_gains (n_speakers); - desired_gains[0] = desired_gains[1] = desired_gains[2] = 0; - outputs[0] = outputs[1] = outputs[2] = -1; - desired_outputs[0] = desired_outputs[1] = desired_outputs[2] = -1; + desired_gains[0] = desired_gains[1] = desired_gains[2] = 0; + outputs[0] = outputs[1] = outputs[2] = -1; + desired_outputs[0] = desired_outputs[1] = desired_outputs[2] = -1; } void VBAPanner::Signal::resize_gains (uint32_t n) { - gains.assign (n, 0.0); + gains.assign (n, 0.0); } VBAPanner::VBAPanner (boost::shared_ptr p, boost::shared_ptr s) : Panner (p) , _speakers (new VBAPSpeakers (s)) { - _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); - _pannable->pan_elevation_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); - _pannable->pan_width_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); - if (!_pannable->has_state()) { - reset(); - } - - update (); + _pannable->pan_azimuth_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); + _pannable->pan_elevation_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); + _pannable->pan_width_control->Changed.connect_same_thread (*this, boost::bind (&VBAPanner::update, this)); + if (!_pannable->has_state ()) { + reset (); + } + + update (); } VBAPanner::~VBAPanner () { - clear_signals (); + clear_signals (); } void VBAPanner::clear_signals () { - for (vector::iterator i = _signals.begin(); i != _signals.end(); ++i) { - delete *i; - } - _signals.clear (); + for (vector::iterator i = _signals.begin (); i != _signals.end (); ++i) { + delete *i; + } + _signals.clear (); } void VBAPanner::configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */) { - uint32_t n = in.n_audio(); - - clear_signals (); + uint32_t n = in.n_audio (); - for (uint32_t i = 0; i < n; ++i) { - Signal* s = new Signal (*this, i, _speakers->n_speakers()); - _signals.push_back (s); + clear_signals (); - } + for (uint32_t i = 0; i < n; ++i) { + Signal* s = new Signal (*this, i, _speakers->n_speakers ()); + _signals.push_back (s); + } - update (); + update (); } void VBAPanner::update () { + _can_automate_list.clear (); + _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); + if (_signals.size () > 1) { + _can_automate_list.insert (Evoral::Parameter (PanWidthAutomation)); + } + if (_speakers->dimension () == 3) { + _can_automate_list.insert (Evoral::Parameter (PanElevationAutomation)); + } - _can_automate_list.clear (); - _can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation)); - if (_signals.size() > 1) { - _can_automate_list.insert (Evoral::Parameter (PanWidthAutomation)); - } - if (_speakers->dimension() == 3) { - _can_automate_list.insert (Evoral::Parameter (PanElevationAutomation)); - } - - /* recompute signal directions based on panner azimuth and, if relevant, width (diffusion) and elevation parameters */ - double elevation = _pannable->pan_elevation_control->get_value() * 90.0; - - if (_signals.size() > 1) { - double w = - (_pannable->pan_width_control->get_value()); - double signal_direction = 1.0 - (_pannable->pan_azimuth_control->get_value() + (w/2)); - double grd_step_per_signal = w / (_signals.size() - 1); - for (vector::iterator s = _signals.begin(); s != _signals.end(); ++s) { - - Signal* signal = *s; - - 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; - } - } else if (_signals.size() == 1) { - double center = (1.0 - _pannable->pan_azimuth_control->get_value()) * 360.0; - - /* width has no role to play if there is only 1 signal: VBAP does not do "diffusion" of a single channel */ - - Signal* s = _signals.front(); - s->direction = AngularVector (center, elevation); - compute_gains (s->desired_gains, s->desired_outputs, s->direction.azi, s->direction.ele); - } - - SignalPositionChanged(); /* emit */ + /* recompute signal directions based on panner azimuth and, if relevant, width (diffusion) and elevation parameters */ + double elevation = _pannable->pan_elevation_control->get_value () * 90.0; + + if (_signals.size () > 1) { + double w = -(_pannable->pan_width_control->get_value ()); + double signal_direction = 1.0 - (_pannable->pan_azimuth_control->get_value () + (w / 2)); + double grd_step_per_signal = w / (_signals.size () - 1); + for (vector::iterator s = _signals.begin (); s != _signals.end (); ++s) { + Signal* signal = *s; + + 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; + } + } else if (_signals.size () == 1) { + double center = (1.0 - _pannable->pan_azimuth_control->get_value ()) * 360.0; + + /* width has no role to play if there is only 1 signal: VBAP does not do "diffusion" of a single channel */ + + Signal* s = _signals.front (); + s->direction = AngularVector (center, elevation); + compute_gains (s->desired_gains, s->desired_outputs, s->direction.azi, s->direction.ele); + } + + SignalPositionChanged (); /* emit */ } void VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) { /* calculates gain factors using loudspeaker setup and given direction */ - double cartdir[3]; - double power; - int i,j,k; - double small_g; - double big_sm_g, gtmp[3]; - const int dimension = _speakers->dimension(); - assert(dimension == 2 || dimension == 3); + double cartdir[3]; + double power; + int i, j, k; + double small_g; + double big_sm_g, gtmp[3]; + const int dimension = _speakers->dimension (); + assert (dimension == 2 || dimension == 3); spherical_to_cartesian (azi, ele, 1.0, cartdir[0], cartdir[1], cartdir[2]); big_sm_g = -100000.0; @@ -183,16 +184,14 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) gains[0] = gains[1] = gains[2] = 0; speaker_ids[0] = speaker_ids[1] = speaker_ids[2] = 0; - for (i = 0; i < _speakers->n_tuples(); i++) { - + for (i = 0; i < _speakers->n_tuples (); i++) { small_g = 10000000.0; for (j = 0; j < dimension; j++) { - gtmp[j] = 0.0; for (k = 0; k < dimension; k++) { - gtmp[j] += cartdir[k] * _speakers->matrix(i)[j * dimension + k]; + gtmp[j] += cartdir[k] * _speakers->matrix (i)[j * dimension + k]; } if (gtmp[j] < small_g) { @@ -201,7 +200,6 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) } if (small_g > big_sm_g) { - big_sm_g = small_g; gains[0] = gtmp[0]; @@ -210,17 +208,17 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) speaker_ids[0] = _speakers->speaker_for_tuple (i, 0); speaker_ids[1] = _speakers->speaker_for_tuple (i, 1); - if (_speakers->dimension() == 3) { - gains[2] = gtmp[2]; + if (_speakers->dimension () == 3) { + gains[2] = gtmp[2]; speaker_ids[2] = _speakers->speaker_for_tuple (i, 2); } else { - gains[2] = 0.0; + gains[2] = 0.0; speaker_ids[2] = -1; } } } - power = sqrt (gains[0]*gains[0] + gains[1]*gains[1] + gains[2]*gains[2]); + power = sqrt (gains[0] * gains[0] + gains[1] * gains[1] + gains[2] * gains[2]); if (power > 0) { gains[0] /= power; @@ -232,144 +230,136 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele) void VBAPanner::distribute (BufferSet& inbufs, BufferSet& obufs, gain_t gain_coefficient, pframes_t nframes) { - uint32_t n; - vector::iterator s; - - assert (inbufs.count().n_audio() == _signals.size()); + uint32_t n; + vector::iterator s; - for (s = _signals.begin(), n = 0; s != _signals.end(); ++s, ++n) { + assert (inbufs.count ().n_audio () == _signals.size ()); - Signal* signal (*s); + for (s = _signals.begin (), n = 0; s != _signals.end (); ++s, ++n) { + Signal* signal (*s); - distribute_one (inbufs.get_audio (n), obufs, gain_coefficient, nframes, n); + distribute_one (inbufs.get_audio (n), obufs, gain_coefficient, nframes, n); - memcpy (signal->outputs, signal->desired_outputs, sizeof (signal->outputs)); - } + memcpy (signal->outputs, signal->desired_outputs, sizeof (signal->outputs)); + } } void VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_coefficient, pframes_t nframes, uint32_t which) { - Sample* const src = srcbuf.data(); - Signal* signal (_signals[which]); + Sample* const src = srcbuf.data (); + Signal* signal (_signals[which]); /* VBAP may distribute the signal across up to 3 speakers depending on - the configuration of the speakers. - - But the set of speakers in use "this time" may be different from - the set of speakers "the last time". So we have up to 6 speakers - involved, and we have to interpolate so that those no longer - in use are rapidly faded to silence and those newly in use - are rapidly faded to their correct level. This prevents clicks - as we change the set of speakers used to put the signal in - a given position. - - However, the speakers are represented by output buffers, and other - speakers may write to the same buffers, so we cannot use - anything here that will simply assign new (sample) values - to the output buffers - everything must be done via mixing - functions and not assignment/copying. - */ - - vector::size_type sz = signal->gains.size(); - - assert (sz == obufs.count().n_audio()); - - int8_t *outputs = (int8_t*)alloca(sz); // on the stack, no malloc - - /* set initial state of each output "record" + * the configuration of the speakers. + * + * But the set of speakers in use "this time" may be different from + * the set of speakers "the last time". So we have up to 6 speakers + * involved, and we have to interpolate so that those no longer + * in use are rapidly faded to silence and those newly in use + * are rapidly faded to their correct level. This prevents clicks + * as we change the set of speakers used to put the signal in + * a given position. + * + * However, the speakers are represented by output buffers, and other + * speakers may write to the same buffers, so we cannot use + * anything here that will simply assign new (sample) values + * to the output buffers - everything must be done via mixing + * functions and not assignment/copying. + */ + + vector::size_type sz = signal->gains.size (); + + assert (sz == obufs.count ().n_audio ()); + + int8_t* outputs = (int8_t*)alloca (sz); // on the stack, no malloc + + /* set initial state of each output "record" */ - for (uint32_t o = 0; o < sz; ++o) { - outputs[o] = 0; - } - - /* for all outputs used this time and last time, - change the output record to show what has - happened. - */ - - - for (int o = 0; o < 3; ++o) { - if (signal->outputs[o] != -1) { - /* used last time */ - outputs[signal->outputs[o]] |= 1; - } + for (uint32_t o = 0; o < sz; ++o) { + outputs[o] = 0; + } - if (signal->desired_outputs[o] != -1) { - /* used this time */ - outputs[signal->desired_outputs[o]] |= 1<<1; - } - } + /* for all outputs used this time and last time, + * change the output record to show what has + * happened. + */ - /* at this point, we can test a speaker's status: + for (int o = 0; o < 3; ++o) { + if (signal->outputs[o] != -1) { + /* used last time */ + outputs[signal->outputs[o]] |= 1; + } - (*outputs[o] & 1) <= in use before - (*outputs[o] & 2) <= in use this time - (*outputs[o] & 3) == 3 <= in use both times - *outputs[o] == 0 <= not in use either time + if (signal->desired_outputs[o] != -1) { + /* used this time */ + outputs[signal->desired_outputs[o]] |= 1 << 1; + } + } - */ + /* at this point, we can test a speaker's status: + * + * (*outputs[o] & 1) <= in use before + * (*outputs[o] & 2) <= in use this time + * (*outputs[o] & 3) == 3 <= in use both times + * *outputs[o] == 0 <= not in use either time + * + */ for (int o = 0; o < 3; ++o) { - pan_t pan; - int output = signal->desired_outputs[o]; + pan_t pan; + int output = signal->desired_outputs[o]; if (output == -1) { - continue; - } - - pan = gain_coefficient * signal->desired_gains[o]; + continue; + } - if (pan == 0.0 && signal->gains[output] == 0.0) { + pan = gain_coefficient * signal->desired_gains[o]; - /* nothing deing delivered to this output */ + if (pan == 0.0 && signal->gains[output] == 0.0) { + /* nothing deing delivered to this output */ - signal->gains[output] = 0.0; + signal->gains[output] = 0.0; - } else if (fabs (pan - signal->gains[output]) > 0.00001) { + } else if (fabs (pan - signal->gains[output]) > 0.00001) { + /* signal to this output but the gain coefficient has changed, so + * interpolate between them. + */ - /* signal to this output but the gain coefficient has changed, so - interpolate between them. - */ + AudioBuffer& buf (obufs.get_audio (output)); + buf.accumulate_with_ramped_gain_from (srcbuf.data (), nframes, signal->gains[output], pan, 0); + signal->gains[output] = pan; - AudioBuffer& buf (obufs.get_audio (output)); - buf.accumulate_with_ramped_gain_from (srcbuf.data(), nframes, signal->gains[output], pan, 0); - signal->gains[output] = pan; + } else { + /* signal to this output, same gain as before so just copy with gain */ - } else { + mix_buffers_with_gain (obufs.get_audio (output).data (), src, nframes, pan); + signal->gains[output] = pan; + } + } - /* signal to this output, same gain as before so just copy with gain - */ + /* clean up the outputs that were used last time but not this time */ - mix_buffers_with_gain (obufs.get_audio (output).data(),src,nframes,pan); - signal->gains[output] = pan; - } + for (uint32_t o = 0; o < sz; ++o) { + if (outputs[o] == 1) { + /* take signal and deliver with a rapid fade out */ + AudioBuffer& buf (obufs.get_audio (o)); + buf.accumulate_with_ramped_gain_from (srcbuf.data (), nframes, signal->gains[o], 0.0, 0); + signal->gains[o] = 0.0; + } } - /* clean up the outputs that were used last time but not this time - */ - - for (uint32_t o = 0; o < sz; ++o) { - if (outputs[o] == 1) { - /* take signal and deliver with a rapid fade out - */ - AudioBuffer& buf (obufs.get_audio (o)); - buf.accumulate_with_ramped_gain_from (srcbuf.data(), nframes, signal->gains[o], 0.0, 0); - signal->gains[o] = 0.0; - } - } - - /* note that the output buffers were all silenced at some point - so anything we didn't write to with this signal (or any others) - is just as it should be. - */ + /* note that the output buffers were all silenced at some point + * so anything we didn't write to with this signal (or any others) + * is just as it should be. + */ } void VBAPanner::distribute_one_automated (AudioBuffer& /*src*/, BufferSet& /*obufs*/, samplepos_t /*start*/, samplepos_t /*end*/, - pframes_t /*nframes*/, pan_t** /*buffers*/, uint32_t /*which*/) + pframes_t /*nframes*/, pan_t** /*buffers*/, uint32_t /*which*/) { /* XXX to be implemented */ } @@ -377,10 +367,10 @@ VBAPanner::distribute_one_automated (AudioBuffer& /*src*/, BufferSet& /*obufs*/, XMLNode& VBAPanner::get_state () { - XMLNode& node (Panner::get_state()); - node.set_property (X_("uri"), _descriptor.panner_uri); + XMLNode& node (Panner::get_state ()); + node.set_property (X_ ("uri"), _descriptor.panner_uri); /* this is needed to allow new sessions to load with old Ardour: */ - node.set_property (X_("type"), _descriptor.name); + node.set_property (X_ ("type"), _descriptor.name); return node; } @@ -391,52 +381,51 @@ VBAPanner::factory (boost::shared_ptr p, boost::shared_ptr s } ChanCount -VBAPanner::in() const +VBAPanner::in () const { - return ChanCount (DataType::AUDIO, _signals.size()); + return ChanCount (DataType::AUDIO, _signals.size ()); } ChanCount -VBAPanner::out() const +VBAPanner::out () const { - return ChanCount (DataType::AUDIO, _speakers->n_speakers()); + return ChanCount (DataType::AUDIO, _speakers->n_speakers ()); } string VBAPanner::value_as_string (boost::shared_ptr ac) const { - /* DO NOT USE LocaleGuard HERE */ - double val = ac->get_value(); + double val = ac->get_value (); - switch (ac->parameter().type()) { - case PanAzimuthAutomation: /* direction */ - return string_compose (_("%1\u00B0"), (int (rint (val * 360.0))+180)%360); + switch (ac->parameter ().type ()) { + case PanAzimuthAutomation: /* direction */ + return string_compose (_ ("%1\u00B0"), (int(rint (val * 360.0)) + 180) % 360); - case PanWidthAutomation: /* diffusion */ - return string_compose (_("%1%%"), (int) floor (100.0 * fabs(val))); + case PanWidthAutomation: /* diffusion */ + return string_compose (_ ("%1%%"), (int)floor (100.0 * fabs (val))); - case PanElevationAutomation: /* elevation */ - return string_compose (_("%1\u00B0"), (int) floor (90.0 * fabs(val))); + case PanElevationAutomation: /* elevation */ + return string_compose (_ ("%1\u00B0"), (int)floor (90.0 * fabs (val))); - default: - return _("unused"); - } + default: + return _ ("unused"); + } } AngularVector VBAPanner::signal_position (uint32_t n) const { - if (n < _signals.size()) { - return _signals[n]->direction; - } + if (n < _signals.size ()) { + return _signals[n]->direction; + } - return AngularVector(); + return AngularVector (); } boost::shared_ptr VBAPanner::get_speakers () const { - return _speakers->parent(); + return _speakers->parent (); } void @@ -465,11 +454,11 @@ void VBAPanner::reset () { set_position (.5); - if (_signals.size() > 1) { - set_width (1.0 - (1.0 / (double)_signals.size())); - } else { - set_width (1.0); - } + if (_signals.size () > 1) { + set_width (1.0 - (1.0 / (double)_signals.size ())); + } else { + set_width (1.0); + } set_elevation (0); update (); diff --git a/libs/panners/vbap/vbap.h b/libs/panners/vbap/vbap.h index 2a3c0ea8e3..584cd29f4b 100644 --- a/libs/panners/vbap/vbap.h +++ b/libs/panners/vbap/vbap.h @@ -20,8 +20,8 @@ #ifndef __libardour_vbap_h__ #define __libardour_vbap_h__ -#include #include +#include #include "pbd/cartesian.h" @@ -30,8 +30,8 @@ #include "vbap_speakers.h" -namespace ARDOUR { - +namespace ARDOUR +{ class Speakers; class Pannable; @@ -41,13 +41,13 @@ public: VBAPanner (boost::shared_ptr, boost::shared_ptr); ~VBAPanner (); - void configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */); - ChanCount in() const; - ChanCount out() const; + void configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */); + ChanCount in () const; + ChanCount out () const; - void set_position (double); - void set_width (double); - void set_elevation (double); + void set_position (double); + void set_width (double); + void set_elevation (double); static Panner* factory (boost::shared_ptr, boost::shared_ptr); @@ -55,41 +55,41 @@ public: void set_azimuth_elevation (double azimuth, double elevation); - std::string value_as_string (boost::shared_ptr) const; + std::string value_as_string (boost::shared_ptr) const; XMLNode& get_state (); - PBD::AngularVector signal_position (uint32_t n) const; - boost::shared_ptr get_speakers() const; + PBD::AngularVector signal_position (uint32_t n) const; + boost::shared_ptr get_speakers () const; void reset (); private: - struct Signal { - PBD::AngularVector direction; - std::vector gains; /* most recently used gain for all speakers */ + struct Signal { + PBD::AngularVector direction; + std::vector gains; /* most recently used gain for all speakers */ - int outputs[3]; /* most recent set of outputs used (2 or 3, depending on dimension) */ - int desired_outputs[3]; /* outputs to use the next time we distribute */ - double desired_gains[3]; /* target gains for desired_outputs */ + int outputs[3]; /* most recent set of outputs used (2 or 3, depending on dimension) */ + int desired_outputs[3]; /* outputs to use the next time we distribute */ + double desired_gains[3]; /* target gains for desired_outputs */ - Signal (VBAPanner&, uint32_t which, uint32_t n_speakers); - void resize_gains (uint32_t n_speakers); - }; + Signal (VBAPanner&, uint32_t which, uint32_t n_speakers); + void resize_gains (uint32_t n_speakers); + }; - std::vector _signals; - boost::shared_ptr _speakers; + std::vector _signals; + boost::shared_ptr _speakers; void compute_gains (double g[3], int ls[3], int azi, int ele); - void update (); - void clear_signals (); + void update (); + void clear_signals (); void distribute_one (AudioBuffer& src, BufferSet& obufs, gain_t gain_coeff, pframes_t nframes, uint32_t which); void distribute_one_automated (AudioBuffer& src, BufferSet& obufs, - samplepos_t start, samplepos_t end, pframes_t nframes, - pan_t** buffers, uint32_t which); + samplepos_t start, samplepos_t end, pframes_t nframes, + pan_t** buffers, uint32_t which); }; -} /* namespace */ +} // namespace ARDOUR #endif /* __libardour_vbap_h__ */ diff --git a/libs/panners/vbap/vbap_speakers.cc b/libs/panners/vbap/vbap_speakers.cc index 898a95de51..24022f0f52 100644 --- a/libs/panners/vbap/vbap_speakers.cc +++ b/libs/panners/vbap/vbap_speakers.cc @@ -31,8 +31,8 @@ of the software. */ -#include #include +#include #include #include "pbd/cartesian.h" @@ -47,10 +47,10 @@ const double VBAPSpeakers::MIN_VOL_P_SIDE_LGTH = 0.01; VBAPSpeakers::VBAPSpeakers (boost::shared_ptr s) : _dimension (2) - , _parent (s) + , _parent (s) { _parent->Changed.connect_same_thread (speaker_connection, boost::bind (&VBAPSpeakers::update, this)); - update (); + update (); } VBAPSpeakers::~VBAPSpeakers () @@ -62,10 +62,10 @@ VBAPSpeakers::update () { int dim = 2; - _speakers = _parent->speakers(); + _speakers = _parent->speakers (); - for (vector::const_iterator i = _speakers.begin(); i != _speakers.end(); ++i) { - if ((*i).angles().ele != 0.0) { + for (vector::const_iterator i = _speakers.begin (); i != _speakers.end (); ++i) { + if ((*i).angles ().ele != 0.0) { dim = 3; break; } @@ -73,13 +73,13 @@ VBAPSpeakers::update () _dimension = dim; - if (_speakers.size() < 2) { + if (_speakers.size () < 2) { /* nothing to be done with less than two speakers */ return; } - if (_dimension == 3) { - ls_triplet_chain *ls_triplets = 0; + if (_dimension == 3) { + ls_triplet_chain* ls_triplets = 0; choose_speaker_triplets (&ls_triplets); if (ls_triplets) { calculate_3x3_matrixes (ls_triplets); @@ -91,16 +91,16 @@ VBAPSpeakers::update () } void -VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) +VBAPSpeakers::choose_speaker_triplets (struct ls_triplet_chain** ls_triplets) { /* Selects the loudspeaker triplets, and - calculates the inversion matrices for each selected triplet. - A line (connection) is drawn between each loudspeaker. The lines - denote the sides of the triangles. The triangles should not be - intersecting. All crossing connections are searched and the - longer connection is erased. This yields non-intesecting triangles, - which can be used in panning. - */ + * calculates the inversion matrices for each selected triplet. + * A line (connection) is drawn between each loudspeaker. The lines + * denote the sides of the triangles. The triangles should not be + * intersecting. All crossing connections are searched and the + * longer connection is erased. This yields non-intesecting triangles, + * which can be used in panning. + */ #if 0 // DEVEL/DEBUG for (vector::iterator i = _speakers.begin(); i != _speakers.end(); ++i) { @@ -113,23 +113,24 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) } #endif - int i,j,k,l,table_size; + int i, j, k, l, table_size; int n_speakers = _speakers.size (); if (n_speakers < 3) { - fprintf(stderr, "VBAP: at least 3 speakers need to be defined."); + fprintf (stderr, "VBAP: at least 3 speakers need to be defined."); return; } /* variable length arrays arrived in C99, became optional in C11, and - are only planned for C++14. Use alloca which is functionally - identical (but uglier to read). - */ - int* connections = (int*) alloca (sizeof (int) * n_speakers * n_speakers); - float* distance_table = (float *) alloca (sizeof (float) * ((n_speakers * (n_speakers - 1)) / 2)); - int* distance_table_i = (int *) alloca (sizeof (int) * ((n_speakers * (n_speakers - 1)) / 2)); - int* distance_table_j = (int *) alloca (sizeof (int) * ((n_speakers * (n_speakers - 1)) / 2)); - float distance; + * are only planned for C++14. Use alloca which is functionally + * identical (but uglier to read). + */ + int* connections = (int*)alloca (sizeof (int) * n_speakers * n_speakers); + float* distance_table = (float*)alloca (sizeof (float) * ((n_speakers * (n_speakers - 1)) / 2)); + int* distance_table_i = (int*)alloca (sizeof (int) * ((n_speakers * (n_speakers - 1)) / 2)); + int* distance_table_j = (int*)alloca (sizeof (int) * ((n_speakers * (n_speakers - 1)) / 2)); + float distance; + struct ls_triplet_chain *trip_ptr, *prev, *tmp_ptr; for (i = 0; i < n_speakers * n_speakers; i++) { @@ -137,41 +138,41 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) } for (i = 0; i < n_speakers; i++) { - for (j = i+1; j < n_speakers; j++) { - for(k = j+1; k < n_speakers; k++) { - if (vol_p_side_lgth(i, j, k, _speakers) > MIN_VOL_P_SIDE_LGTH) { - connections[(i*n_speakers)+j]=1; - connections[(j*n_speakers)+i]=1; - connections[(i*n_speakers)+k]=1; - connections[(k*n_speakers)+i]=1; - connections[(j*n_speakers)+k]=1; - connections[(k*n_speakers)+j]=1; - add_ldsp_triplet(i,j,k,ls_triplets); + for (j = i + 1; j < n_speakers; j++) { + for (k = j + 1; k < n_speakers; k++) { + if (vol_p_side_lgth (i, j, k, _speakers) > MIN_VOL_P_SIDE_LGTH) { + connections[(i * n_speakers) + j] = 1; + connections[(j * n_speakers) + i] = 1; + connections[(i * n_speakers) + k] = 1; + connections[(k * n_speakers) + i] = 1; + connections[(j * n_speakers) + k] = 1; + connections[(k * n_speakers) + j] = 1; + add_ldsp_triplet (i, j, k, ls_triplets); } } } } /*calculate distancies between all speakers and sorting them*/ - table_size =(((n_speakers - 1) * (n_speakers)) / 2); + table_size = (((n_speakers - 1) * (n_speakers)) / 2); for (i = 0; i < table_size; i++) { distance_table[i] = 100000.0; } - for (i = 0;i < n_speakers; i++) { - for (j = i+1; j < n_speakers; j++) { - if (connections[(i*n_speakers)+j] == 1) { - distance = fabs(vec_angle(_speakers[i].coords(),_speakers[j].coords())); - k=0; - while(distance_table[k] < distance) { + for (i = 0; i < n_speakers; i++) { + for (j = i + 1; j < n_speakers; j++) { + if (connections[(i * n_speakers) + j] == 1) { + distance = fabs (vec_angle (_speakers[i].coords (), _speakers[j].coords ())); + k = 0; + while (distance_table[k] < distance) { k++; } - for (l = table_size - 1; l > k ; l--) { - distance_table[l] = distance_table[l-1]; - distance_table_i[l] = distance_table_i[l-1]; - distance_table_j[l] = distance_table_j[l-1]; + for (l = table_size - 1; l > k; l--) { + distance_table[l] = distance_table[l - 1]; + distance_table_i[l] = distance_table_i[l - 1]; + distance_table_j[l] = distance_table_j[l - 1]; } - distance_table[k] = distance; + distance_table[k] = distance; distance_table_i[k] = i; distance_table_j[k] = j; } else @@ -180,18 +181,18 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) } /* disconnecting connections which are crossing shorter ones, - starting from shortest one and removing all that cross it, - and proceeding to next shortest */ + * starting from shortest one and removing all that cross it, + * and proceeding to next shortest */ for (i = 0; i < table_size; i++) { int fst_ls = distance_table_i[i]; int sec_ls = distance_table_j[i]; - if (connections[(fst_ls*n_speakers)+sec_ls] == 1) { + if (connections[(fst_ls * n_speakers) + sec_ls] == 1) { for (j = 0; j < n_speakers; j++) { - for (k = j+1; k < n_speakers; k++) { + for (k = j + 1; k < n_speakers; k++) { if ((j != fst_ls) && (k != sec_ls) && (k != fst_ls) && (j != sec_ls)) { - if (lines_intersect(fst_ls, sec_ls, j, k) == 1){ - connections[(j*n_speakers)+k] = 0; - connections[(k*n_speakers)+j] = 0; + if (lines_intersect (fst_ls, sec_ls, j, k) == 1) { + connections[(j * n_speakers) + k] = 0; + connections[(k * n_speakers) + j] = 0; } } } @@ -200,59 +201,58 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets) } /* remove triangles which had crossing sides - with smaller triangles or include loudspeakers*/ + * with smaller triangles or include loudspeakers*/ trip_ptr = *ls_triplets; - prev = 0; - while (trip_ptr != 0){ + prev = 0; + while (trip_ptr != 0) { i = trip_ptr->ls_nos[0]; j = trip_ptr->ls_nos[1]; k = trip_ptr->ls_nos[2]; - if (connections[(i*n_speakers)+j] == 0 || - connections[(i*n_speakers)+k] == 0 || - connections[(j*n_speakers)+k] == 0 || - any_ls_inside_triplet(i,j,k) == 1 ){ + if (connections[(i * n_speakers) + j] == 0 || + connections[(i * n_speakers) + k] == 0 || + connections[(j * n_speakers) + k] == 0 || + any_ls_inside_triplet (i, j, k) == 1) { if (prev != 0) { prev->next = trip_ptr->next; - tmp_ptr = trip_ptr; - trip_ptr = trip_ptr->next; - free(tmp_ptr); + tmp_ptr = trip_ptr; + trip_ptr = trip_ptr->next; + free (tmp_ptr); } else { *ls_triplets = trip_ptr->next; - tmp_ptr = trip_ptr; - trip_ptr = trip_ptr->next; - free(tmp_ptr); + tmp_ptr = trip_ptr; + trip_ptr = trip_ptr->next; + free (tmp_ptr); } } else { - prev = trip_ptr; + prev = trip_ptr; trip_ptr = trip_ptr->next; - } } } int -VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c) +VBAPSpeakers::any_ls_inside_triplet (int a, int b, int c) { /* returns 1 if there is loudspeaker(s) inside given ls triplet */ - float invdet; + float invdet; const CartesianVector* lp1; const CartesianVector* lp2; const CartesianVector* lp3; - float invmx[9]; - int i,j; - float tmp; - bool any_ls_inside; - bool this_inside; - int n_speakers = _speakers.size(); + float invmx[9]; + int i, j; + float tmp; + bool any_ls_inside; + bool this_inside; + int n_speakers = _speakers.size (); - lp1 = &(_speakers[a].coords()); - lp2 = &(_speakers[b].coords()); - lp3 = &(_speakers[c].coords()); + lp1 = &(_speakers[a].coords ()); + lp2 = &(_speakers[b].coords ()); + lp3 = &(_speakers[c].coords ()); /* matrix inversion */ invdet = 1.0 / ( lp1->x * ((lp2->y * lp3->z) - (lp2->z * lp3->y)) - - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x)) - + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x))); + - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x)) + + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x))); invmx[0] = ((lp2->y * lp3->z) - (lp2->z * lp3->y)) * invdet; invmx[3] = ((lp1->y * lp3->z) - (lp1->z * lp3->y)) * -invdet; @@ -266,12 +266,12 @@ VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c) any_ls_inside = false; for (i = 0; i < n_speakers; i++) { - if (i != a && i!=b && i != c) { + if (i != a && i != b && i != c) { this_inside = true; for (j = 0; j < 3; j++) { - tmp = _speakers[i].coords().x * invmx[0 + j*3]; - tmp += _speakers[i].coords().y * invmx[1 + j*3]; - tmp += _speakers[i].coords().z * invmx[2 + j*3]; + tmp = _speakers[i].coords ().x * invmx[0 + j * 3]; + tmp += _speakers[i].coords ().y * invmx[1 + j * 3]; + tmp += _speakers[i].coords ().z * invmx[2 + j * 3]; if (tmp < -0.001) { this_inside = false; } @@ -285,22 +285,21 @@ VBAPSpeakers::any_ls_inside_triplet(int a, int b, int c) return any_ls_inside; } - void -VBAPSpeakers::add_ldsp_triplet(int i, int j, int k, struct ls_triplet_chain **ls_triplets) +VBAPSpeakers::add_ldsp_triplet (int i, int j, int k, struct ls_triplet_chain** ls_triplets) { /* adds i,j,k triplet to triplet chain*/ struct ls_triplet_chain *trip_ptr, *prev; trip_ptr = *ls_triplets; - prev = 0; + prev = 0; - while (trip_ptr != 0){ - prev = trip_ptr; + while (trip_ptr != 0) { + prev = trip_ptr; trip_ptr = trip_ptr->next; } - trip_ptr = (struct ls_triplet_chain*) malloc (sizeof (struct ls_triplet_chain)); + trip_ptr = (struct ls_triplet_chain*)malloc (sizeof (struct ls_triplet_chain)); if (prev == 0) { *ls_triplets = trip_ptr; @@ -308,17 +307,17 @@ VBAPSpeakers::add_ldsp_triplet(int i, int j, int k, struct ls_triplet_chain **ls prev->next = trip_ptr; } - trip_ptr->next = 0; + trip_ptr->next = 0; trip_ptr->ls_nos[0] = i; trip_ptr->ls_nos[1] = j; trip_ptr->ls_nos[2] = k; } double -VBAPSpeakers::vec_angle(CartesianVector v1, CartesianVector v2) +VBAPSpeakers::vec_angle (CartesianVector v1, CartesianVector v2) { - double inner= ((v1.x*v2.x + v1.y*v2.y + v1.z*v2.z)/ - (vec_length(v1) * vec_length(v2))); + double inner = ((v1.x * v2.x + v1.y * v2.y + v1.z * v2.z) / + (vec_length (v1) * vec_length (v2))); if (inner > 1.0) { inner = 1.0; @@ -328,37 +327,36 @@ VBAPSpeakers::vec_angle(CartesianVector v1, CartesianVector v2) inner = -1.0; } - return fabs(acos(inner)); + return fabs (acos (inner)); } double -VBAPSpeakers::vec_length(CartesianVector v1) +VBAPSpeakers::vec_length (CartesianVector v1) { - double rv = sqrt(v1.x*v1.x + v1.y*v1.y + v1.z*v1.z); - if (rv > 1e-14) return rv; + double rv = sqrt (v1.x * v1.x + v1.y * v1.y + v1.z * v1.z); + if (rv > 1e-14) + return rv; return 0; } double -VBAPSpeakers::vec_prod(CartesianVector v1, CartesianVector v2) +VBAPSpeakers::vec_prod (CartesianVector v1, CartesianVector v2) { - return (v1.x*v2.x + v1.y*v2.y + v1.z*v2.z); + return (v1.x * v2.x + v1.y * v2.y + v1.z * v2.z); } double -VBAPSpeakers::vol_p_side_lgth(int i, int j, int k, const vector& speakers) +VBAPSpeakers::vol_p_side_lgth (int i, int j, int k, const vector& speakers) { /* calculate volume of the parallelepiped defined by the loudspeaker - direction vectors and divide it with total length of the triangle sides. - This is used when removing too narrow triangles. */ + * direction vectors and divide it with total length of the triangle sides. + * This is used when removing too narrow triangles. */ - double volper, lgth; + double volper, lgth; CartesianVector xprod; - cross_prod (speakers[i].coords(), speakers[j].coords(), &xprod); - volper = fabs (vec_prod(xprod, speakers[k].coords())); - lgth = ( fabs (vec_angle(speakers[i].coords(), speakers[j].coords())) - + fabs (vec_angle(speakers[i].coords(), speakers[k].coords())) - + fabs (vec_angle(speakers[j].coords(), speakers[k].coords()))); + cross_prod (speakers[i].coords (), speakers[j].coords (), &xprod); + volper = fabs (vec_prod (xprod, speakers[k].coords ())); + lgth = (fabs (vec_angle (speakers[i].coords (), speakers[j].coords ())) + fabs (vec_angle (speakers[i].coords (), speakers[k].coords ())) + fabs (vec_angle (speakers[j].coords (), speakers[k].coords ()))); if (lgth > 0.00001) { return volper / lgth; } else { @@ -367,7 +365,7 @@ VBAPSpeakers::vol_p_side_lgth(int i, int j, int k, const vector& speake } void -VBAPSpeakers::cross_prod(CartesianVector v1,CartesianVector v2, CartesianVector *res) +VBAPSpeakers::cross_prod (CartesianVector v1, CartesianVector v2, CartesianVector* res) { double length; @@ -375,7 +373,7 @@ VBAPSpeakers::cross_prod(CartesianVector v1,CartesianVector v2, CartesianVector res->y = (v1.z * v2.x) - (v1.x * v2.z); res->z = (v1.x * v2.y) - (v1.y * v2.x); - length = vec_length(*res); + length = vec_length (*res); if (length > 0) { res->x /= length; res->y /= length; @@ -391,51 +389,52 @@ int VBAPSpeakers::lines_intersect (int i, int j, int k, int l) { /* checks if two lines intersect on 3D sphere - see theory in paper Pulkki, V. Lokki, T. "Creating Auditory Displays - with Multiple Loudspeakers Using VBAP: A Case Study with - DIVA Project" in International Conference on - Auditory Displays -98. E-mail Ville.Pulkki@hut.fi - if you want to have that paper. - */ + * see theory in paper Pulkki, V. Lokki, T. "Creating Auditory Displays + * with Multiple Loudspeakers Using VBAP: A Case Study with + * DIVA Project" in International Conference on + * Auditory Displays -98. E-mail Ville.Pulkki@hut.fi + * if you want to have that paper. + */ CartesianVector v1; CartesianVector v2; CartesianVector v3, neg_v3; - float dist_ij,dist_kl,dist_iv3,dist_jv3,dist_inv3,dist_jnv3; - float dist_kv3,dist_lv3,dist_knv3,dist_lnv3; - - cross_prod(_speakers[i].coords(),_speakers[j].coords(),&v1); - cross_prod(_speakers[k].coords(),_speakers[l].coords(),&v2); - cross_prod(v1,v2,&v3); - - neg_v3.x= 0.0 - v3.x; - neg_v3.y= 0.0 - v3.y; - neg_v3.z= 0.0 - v3.z; - - dist_ij = (vec_angle(_speakers[i].coords(),_speakers[j].coords())); - dist_kl = (vec_angle(_speakers[k].coords(),_speakers[l].coords())); - dist_iv3 = (vec_angle(_speakers[i].coords(),v3)); - dist_jv3 = (vec_angle(v3,_speakers[j].coords())); - dist_inv3 = (vec_angle(_speakers[i].coords(),neg_v3)); - dist_jnv3 = (vec_angle(neg_v3,_speakers[j].coords())); - dist_kv3 = (vec_angle(_speakers[k].coords(),v3)); - dist_lv3 = (vec_angle(v3,_speakers[l].coords())); - dist_knv3 = (vec_angle(_speakers[k].coords(),neg_v3)); - dist_lnv3 = (vec_angle(neg_v3,_speakers[l].coords())); + + float dist_ij, dist_kl, dist_iv3, dist_jv3, dist_inv3, dist_jnv3; + float dist_kv3, dist_lv3, dist_knv3, dist_lnv3; + + cross_prod (_speakers[i].coords (), _speakers[j].coords (), &v1); + cross_prod (_speakers[k].coords (), _speakers[l].coords (), &v2); + cross_prod (v1, v2, &v3); + + neg_v3.x = 0.0 - v3.x; + neg_v3.y = 0.0 - v3.y; + neg_v3.z = 0.0 - v3.z; + + dist_ij = (vec_angle (_speakers[i].coords (), _speakers[j].coords ())); + dist_kl = (vec_angle (_speakers[k].coords (), _speakers[l].coords ())); + dist_iv3 = (vec_angle (_speakers[i].coords (), v3)); + dist_jv3 = (vec_angle (v3, _speakers[j].coords ())); + dist_inv3 = (vec_angle (_speakers[i].coords (), neg_v3)); + dist_jnv3 = (vec_angle (neg_v3, _speakers[j].coords ())); + dist_kv3 = (vec_angle (_speakers[k].coords (), v3)); + dist_lv3 = (vec_angle (v3, _speakers[l].coords ())); + dist_knv3 = (vec_angle (_speakers[k].coords (), neg_v3)); + dist_lnv3 = (vec_angle (neg_v3, _speakers[l].coords ())); /* if one of loudspeakers is close to crossing point, don't do anything*/ - if(fabsf(dist_iv3) <= 0.01 || fabsf(dist_jv3) <= 0.01 || - fabsf(dist_kv3) <= 0.01 || fabsf(dist_lv3) <= 0.01 || - fabsf(dist_inv3) <= 0.01 || fabsf(dist_jnv3) <= 0.01 || - fabsf(dist_knv3) <= 0.01 || fabsf(dist_lnv3) <= 0.01 ) { - return(0); + if (fabsf (dist_iv3) <= 0.01 || fabsf (dist_jv3) <= 0.01 || + fabsf (dist_kv3) <= 0.01 || fabsf (dist_lv3) <= 0.01 || + fabsf (dist_inv3) <= 0.01 || fabsf (dist_jnv3) <= 0.01 || + fabsf (dist_knv3) <= 0.01 || fabsf (dist_lnv3) <= 0.01) { + return (0); } /* if crossing point is on line between both loudspeakers return 1 */ - if (((fabsf(dist_ij - (dist_iv3 + dist_jv3)) <= 0.01 ) && - (fabsf(dist_kl - (dist_kv3 + dist_lv3)) <= 0.01)) || - ((fabsf(dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01) && - (fabsf(dist_kl - (dist_knv3 + dist_lnv3)) <= 0.01 ))) { + if (((fabsf (dist_ij - (dist_iv3 + dist_jv3)) <= 0.01) && + (fabsf (dist_kl - (dist_kv3 + dist_lv3)) <= 0.01)) || + ((fabsf (dist_ij - (dist_inv3 + dist_jnv3)) <= 0.01) && + (fabsf (dist_kl - (dist_knv3 + dist_lnv3)) <= 0.01))) { return (1); } else { return (0); @@ -443,17 +442,17 @@ VBAPSpeakers::lines_intersect (int i, int j, int k, int l) } void -VBAPSpeakers::calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets) +VBAPSpeakers::calculate_3x3_matrixes (struct ls_triplet_chain* ls_triplets) { /* Calculates the inverse matrices for 3D */ - float invdet; - const CartesianVector* lp1; - const CartesianVector* lp2; - const CartesianVector* lp3; - float *invmx; - struct ls_triplet_chain *tr_ptr = ls_triplets; - int triplet_count = 0; - int triplet; + float invdet; + const CartesianVector* lp1; + const CartesianVector* lp2; + const CartesianVector* lp3; + float* invmx; + struct ls_triplet_chain* tr_ptr = ls_triplets; + int triplet_count = 0; + int triplet; assert (tr_ptr); @@ -474,21 +473,21 @@ VBAPSpeakers::calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets) _speaker_tuples.clear (); for (int n = 0; n < triplet_count; ++n) { - _matrices.push_back (threeDmatrix()); - _speaker_tuples.push_back (tmatrix()); + _matrices.push_back (threeDmatrix ()); + _speaker_tuples.push_back (tmatrix ()); } tr_ptr = ls_triplets; while (tr_ptr != 0) { - lp1 = &(_speakers[tr_ptr->ls_nos[0]].coords()); - lp2 = &(_speakers[tr_ptr->ls_nos[1]].coords()); - lp3 = &(_speakers[tr_ptr->ls_nos[2]].coords()); + lp1 = &(_speakers[tr_ptr->ls_nos[0]].coords ()); + lp2 = &(_speakers[tr_ptr->ls_nos[1]].coords ()); + lp3 = &(_speakers[tr_ptr->ls_nos[2]].coords ()); /* matrix inversion */ - invmx = tr_ptr->inv_mx; + invmx = tr_ptr->inv_mx; invdet = 1.0 / ( lp1->x * ((lp2->y * lp3->z) - (lp2->z * lp3->y)) - - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x)) - + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x))); + - lp1->y * ((lp2->x * lp3->z) - (lp2->z * lp3->x)) + + lp1->z * ((lp2->x * lp3->y) - (lp2->y * lp3->x))); invmx[0] = ((lp2->y * lp3->z) - (lp2->z * lp3->y)) * invdet; invmx[3] = ((lp1->y * lp3->z) - (lp1->z * lp3->y)) * -invdet; @@ -530,29 +529,29 @@ VBAPSpeakers::calculate_3x3_matrixes(struct ls_triplet_chain *ls_triplets) } void -VBAPSpeakers::choose_speaker_pairs (){ - +VBAPSpeakers::choose_speaker_pairs () +{ /* selects the loudspeaker pairs, calculates the inversion - matrices and stores the data to a global array + * matrices and stores the data to a global array */ - const int n_speakers = _speakers.size(); + const int n_speakers = _speakers.size (); if (n_speakers < 2) { - fprintf(stderr, "VBAP: at least 2 speakers need to be defined."); + fprintf (stderr, "VBAP: at least 2 speakers need to be defined."); return; } - const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0/M_PI) * (M_PI - 0.175); + const double AZIMUTH_DELTA_THRESHOLD_DEGREES = (180.0 / M_PI) * (M_PI - 0.175); /* variable length arrays arrived in C99, became optional in C11, and - are only planned for C++14. Use alloca which is functionally - identical (but uglier to read). - */ - int* sorted_speakers = (int*) alloca (sizeof (int) * n_speakers); - bool* exists = (bool*) alloca (sizeof(bool) * n_speakers); - double* inverse_matrix = (double*) alloca (sizeof (double) * n_speakers * 4); - int expected_pairs = 0; - int pair; - int speaker; + * are only planned for C++14. Use alloca which is functionally + * identical (but uglier to read). + */ + int* sorted_speakers = (int*)alloca (sizeof (int) * n_speakers); + bool* exists = (bool*)alloca (sizeof (bool) * n_speakers); + double* inverse_matrix = (double*)alloca (sizeof (double) * n_speakers * 4); + int expected_pairs = 0; + int pair; + int speaker; for (speaker = 0; speaker < n_speakers; ++speaker) { exists[speaker] = false; @@ -562,30 +561,28 @@ VBAPSpeakers::choose_speaker_pairs (){ #ifdef __clang_analyzer__ // sort_2D_lss() assigns values to all of sorted_speakers // "uninitialized value" - memset(sorted_speakers, 0, sizeof(*sorted_speakers)); + memset (sorted_speakers, 0, sizeof (*sorted_speakers)); #endif sort_2D_lss (sorted_speakers); /* adjacent loudspeakers are the loudspeaker pairs to be used.*/ - for (speaker = 0; speaker < n_speakers-1; speaker++) { - - if ((_speakers[sorted_speakers[speaker+1]].angles().azi - - _speakers[sorted_speakers[speaker]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { - if (calc_2D_inv_tmatrix( _speakers[sorted_speakers[speaker]].angles().azi, - _speakers[sorted_speakers[speaker+1]].angles().azi, - &inverse_matrix[4 * speaker]) != 0){ + for (speaker = 0; speaker < n_speakers - 1; speaker++) { + if ((_speakers[sorted_speakers[speaker + 1]].angles ().azi - + _speakers[sorted_speakers[speaker]].angles ().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { + if (calc_2D_inv_tmatrix (_speakers[sorted_speakers[speaker]].angles ().azi, + _speakers[sorted_speakers[speaker + 1]].angles ().azi, + &inverse_matrix[4 * speaker]) != 0) { exists[speaker] = true; expected_pairs++; } } } - if (((6.283 - _speakers[sorted_speakers[n_speakers-1]].angles().azi) - +_speakers[sorted_speakers[0]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { - if (calc_2D_inv_tmatrix(_speakers[sorted_speakers[n_speakers-1]].angles().azi, - _speakers[sorted_speakers[0]].angles().azi, - &inverse_matrix[4*(n_speakers-1)]) != 0) { - exists[n_speakers-1] = true; + if (((6.283 - _speakers[sorted_speakers[n_speakers - 1]].angles ().azi) + _speakers[sorted_speakers[0]].angles ().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) { + if (calc_2D_inv_tmatrix (_speakers[sorted_speakers[n_speakers - 1]].angles ().azi, + _speakers[sorted_speakers[0]].angles ().azi, + &inverse_matrix[4 * (n_speakers - 1)]) != 0) { + exists[n_speakers - 1] = true; expected_pairs++; } } @@ -596,31 +593,31 @@ VBAPSpeakers::choose_speaker_pairs (){ _speaker_tuples.clear (); for (int n = 0; n < expected_pairs; ++n) { - _matrices.push_back (twoDmatrix()); - _speaker_tuples.push_back (tmatrix()); + _matrices.push_back (twoDmatrix ()); + _speaker_tuples.push_back (tmatrix ()); } for (speaker = 0; speaker < n_speakers - 1; speaker++) { if (exists[speaker]) { - _matrices[pair][0] = inverse_matrix[(speaker*4)+0]; - _matrices[pair][1] = inverse_matrix[(speaker*4)+1]; - _matrices[pair][2] = inverse_matrix[(speaker*4)+2]; - _matrices[pair][3] = inverse_matrix[(speaker*4)+3]; + _matrices[pair][0] = inverse_matrix[(speaker * 4) + 0]; + _matrices[pair][1] = inverse_matrix[(speaker * 4) + 1]; + _matrices[pair][2] = inverse_matrix[(speaker * 4) + 2]; + _matrices[pair][3] = inverse_matrix[(speaker * 4) + 3]; _speaker_tuples[pair][0] = sorted_speakers[speaker]; - _speaker_tuples[pair][1] = sorted_speakers[speaker+1]; + _speaker_tuples[pair][1] = sorted_speakers[speaker + 1]; pair++; } } - if (exists[n_speakers-1]) { - _matrices[pair][0] = inverse_matrix[(speaker*4)+0]; - _matrices[pair][1] = inverse_matrix[(speaker*4)+1]; - _matrices[pair][2] = inverse_matrix[(speaker*4)+2]; - _matrices[pair][3] = inverse_matrix[(speaker*4)+3]; + if (exists[n_speakers - 1]) { + _matrices[pair][0] = inverse_matrix[(speaker * 4) + 0]; + _matrices[pair][1] = inverse_matrix[(speaker * 4) + 1]; + _matrices[pair][2] = inverse_matrix[(speaker * 4) + 2]; + _matrices[pair][3] = inverse_matrix[(speaker * 4) + 3]; - _speaker_tuples[pair][0] = sorted_speakers[n_speakers-1]; + _speaker_tuples[pair][0] = sorted_speakers[n_speakers - 1]; _speaker_tuples[pair][1] = sorted_speakers[0]; } } @@ -628,33 +625,32 @@ VBAPSpeakers::choose_speaker_pairs (){ void VBAPSpeakers::sort_2D_lss (int* sorted_speakers) { - vector tmp = _speakers; + vector tmp = _speakers; vector::iterator s; - azimuth_sorter sorter; - unsigned int n; + azimuth_sorter sorter; + unsigned int n; - sort (tmp.begin(), tmp.end(), sorter); + sort (tmp.begin (), tmp.end (), sorter); - for (n = 0, s = tmp.begin(); s != tmp.end(); ++s, ++n) { + for (n = 0, s = tmp.begin (); s != tmp.end (); ++s, ++n) { sorted_speakers[n] = (*s).id; } - assert(n == _speakers.size ()); + assert (n == _speakers.size ()); } int VBAPSpeakers::calc_2D_inv_tmatrix (double azi1, double azi2, double* inverse_matrix) { - double x1,x2,x3,x4; + double x1, x2, x3, x4; double det; - x1 = cos (azi1 * (M_PI/180.0)); - x2 = sin (azi1 * (M_PI/180.0)); - x3 = cos (azi2 * (M_PI/180.0)); - x4 = sin (azi2 * (M_PI/180.0)); - det = (x1 * x4) - ( x3 * x2 ); - - if (fabs(det) <= 0.001) { + x1 = cos (azi1 * (M_PI / 180.0)); + x2 = sin (azi1 * (M_PI / 180.0)); + x3 = cos (azi2 * (M_PI / 180.0)); + x4 = sin (azi2 * (M_PI / 180.0)); + det = (x1 * x4) - (x3 * x2); + if (fabs (det) <= 0.001) { inverse_matrix[0] = 0.0; inverse_matrix[1] = 0.0; inverse_matrix[2] = 0.0; @@ -663,7 +659,6 @@ VBAPSpeakers::calc_2D_inv_tmatrix (double azi1, double azi2, double* inverse_mat return 0; } else { - inverse_matrix[0] = x4 / det; inverse_matrix[1] = -x3 / det; inverse_matrix[2] = -x2 / det; @@ -672,5 +667,3 @@ VBAPSpeakers::calc_2D_inv_tmatrix (double azi1, double azi2, double* inverse_mat return 1; } } - - diff --git a/libs/panners/vbap/vbap_speakers.h b/libs/panners/vbap/vbap_speakers.h index ed3429e6d0..4abc87dee1 100644 --- a/libs/panners/vbap/vbap_speakers.h +++ b/libs/panners/vbap/vbap_speakers.h @@ -29,79 +29,102 @@ #include "ardour/panner.h" #include "ardour/speakers.h" -namespace ARDOUR { - +namespace ARDOUR +{ class Speakers; -class VBAPSpeakers : public boost::noncopyable { +class VBAPSpeakers : public boost::noncopyable +{ public: VBAPSpeakers (boost::shared_ptr); typedef std::vector dvector; - const dvector matrix (int tuple) const { return _matrices[tuple]; } - int speaker_for_tuple (int tuple, int which) const { return _speaker_tuples[tuple][which]; } - int n_tuples () const { return _matrices.size(); } - int dimension() const { return _dimension; } + const dvector matrix (int tuple) const + { + return _matrices[tuple]; + } + + int speaker_for_tuple (int tuple, int which) const + { + return _speaker_tuples[tuple][which]; + } + + int n_tuples () const + { + return _matrices.size (); + } - uint32_t n_speakers() const { return _speakers.size(); } - boost::shared_ptr parent() const { return _parent; } + int dimension () const + { + return _dimension; + } + + uint32_t n_speakers () const + { + return _speakers.size (); + } + + boost::shared_ptr parent () const + { + return _parent; + } ~VBAPSpeakers (); private: - static const double MIN_VOL_P_SIDE_LGTH; - int _dimension; - boost::shared_ptr _parent; - std::vector _speakers; - PBD::ScopedConnection speaker_connection; + static const double MIN_VOL_P_SIDE_LGTH; + int _dimension; + boost::shared_ptr _parent; + std::vector _speakers; + PBD::ScopedConnection speaker_connection; struct azimuth_sorter { - bool operator() (const Speaker& s1, const Speaker& s2) { - return s1.angles().azi < s2.angles().azi; + bool operator() (const Speaker& s1, const Speaker& s2) + { + return s1.angles ().azi < s2.angles ().azi; } }; struct twoDmatrix : public dvector { - twoDmatrix() : dvector (4, 0.0) {} + twoDmatrix () : dvector (4, 0.0) { } }; struct threeDmatrix : public dvector { - threeDmatrix() : dvector (9, 0.0) {} + threeDmatrix () : dvector (9, 0.0) { } }; struct tmatrix : public dvector { - tmatrix() : dvector (3, 0.0) {} + tmatrix () : dvector (3, 0.0) { } }; - std::vector _matrices; /* holds matrices for a given speaker combinations */ - std::vector _speaker_tuples; /* holds speakers IDs for a given combination */ + std::vector _matrices; /* holds matrices for a given speaker combinations */ + std::vector _speaker_tuples; /* holds speakers IDs for a given combination */ /* A struct for all loudspeakers */ struct ls_triplet_chain { - int ls_nos[3]; - float inv_mx[9]; - struct ls_triplet_chain *next; + int ls_nos[3]; + float inv_mx[9]; + struct ls_triplet_chain* next; }; - static double vec_angle(PBD::CartesianVector v1, PBD::CartesianVector v2); - static double vec_length(PBD::CartesianVector v1); - static double vec_prod(PBD::CartesianVector v1, PBD::CartesianVector v2); - static double vol_p_side_lgth(int i, int j,int k, const std::vector&); - static void cross_prod(PBD::CartesianVector v1,PBD::CartesianVector v2, PBD::CartesianVector *res); + static double vec_angle (PBD::CartesianVector v1, PBD::CartesianVector v2); + static double vec_length (PBD::CartesianVector v1); + static double vec_prod (PBD::CartesianVector v1, PBD::CartesianVector v2); + static double vol_p_side_lgth (int i, int j, int k, const std::vector&); + static void cross_prod (PBD::CartesianVector v1, PBD::CartesianVector v2, PBD::CartesianVector* res); void update (); int any_ls_inside_triplet (int a, int b, int c); - void add_ldsp_triplet (int i, int j, int k, struct ls_triplet_chain **ls_triplets); - int lines_intersect (int i,int j,int k,int l); - void calculate_3x3_matrixes (struct ls_triplet_chain *ls_triplets); - void choose_speaker_triplets (struct ls_triplet_chain **ls_triplets); + void add_ldsp_triplet (int i, int j, int k, struct ls_triplet_chain** ls_triplets); + int lines_intersect (int i, int j, int k, int l); + void calculate_3x3_matrixes (struct ls_triplet_chain* ls_triplets); + void choose_speaker_triplets (struct ls_triplet_chain** ls_triplets); void choose_speaker_pairs (); void sort_2D_lss (int* sorted_lss); - int calc_2D_inv_tmatrix (double azi1,double azi2, double* inv_mat); - + int calc_2D_inv_tmatrix (double azi1, double azi2, double* inv_mat); }; -} /* namespace */ +} // namespace ARDOUR #endif /* __libardour_vbap_speakers_h__ */ -- cgit v1.2.3