mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-16 11:46:25 +01:00
NO-OP: whitespace
This commit is contained in:
parent
ac9e16f0b8
commit
4780a0fd60
10 changed files with 948 additions and 956 deletions
|
|
@ -21,40 +21,38 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdlib>
|
||||
#include <float.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
#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"
|
||||
|
||||
|
|
@ -71,7 +69,11 @@ static PanPluginDescriptor _descriptor = {
|
|||
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<Pannable> p)
|
||||
: Panner (p)
|
||||
|
|
@ -157,7 +159,7 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
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;
|
||||
|
|
@ -177,26 +179,19 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
mix_buffers_with_gain (dst + n, src + n, nframes - n, pan);
|
||||
|
||||
} else {
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
|
@ -212,7 +207,7 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
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;
|
||||
|
|
@ -234,14 +229,11 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
/* XXX it would be nice to mark the buffer as written to */
|
||||
|
||||
} else {
|
||||
|
||||
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);
|
||||
|
|
@ -250,7 +242,6 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
}
|
||||
|
||||
} else {
|
||||
|
||||
/* pan is 1 so we can just copy the input samples straight in */
|
||||
|
||||
mix_buffers_no_gain (dst, src, nframes);
|
||||
|
|
@ -258,7 +249,6 @@ Panner1in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
/* XXX it would be nice to mark the buffer as written to */
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -289,15 +279,14 @@ Panner1in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
|
|||
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.
|
||||
* 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);
|
||||
|
|
@ -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<Pannable> p, boost::shared_ptr<Speakers> /* ignored */)
|
||||
{
|
||||
|
|
@ -347,21 +335,20 @@ Panner1in2out::get_state ()
|
|||
string
|
||||
Panner1in2out::value_as_string (boost::shared_ptr<const AutomationControl> 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.
|
||||
* 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)),
|
||||
|
|
|
|||
|
|
@ -21,21 +21,21 @@
|
|||
#ifndef __ardour_panner_1in2out_h__
|
||||
#define __ardour_panner_1in2out_h__
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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
|
||||
{
|
||||
|
|
@ -49,8 +49,15 @@ class Panner1in2out : public Panner
|
|||
|
||||
double position () const;
|
||||
|
||||
ChanCount in() const { return ChanCount (DataType::AUDIO, 1); }
|
||||
ChanCount out() const { return ChanCount (DataType::AUDIO, 2); }
|
||||
ChanCount in () const
|
||||
{
|
||||
return ChanCount (DataType::AUDIO, 1);
|
||||
}
|
||||
|
||||
ChanCount out () const
|
||||
{
|
||||
return ChanCount (DataType::AUDIO, 2);
|
||||
}
|
||||
|
||||
static Panner* factory (boost::shared_ptr<Pannable>, boost::shared_ptr<Speakers>);
|
||||
|
||||
|
|
@ -76,6 +83,6 @@ class Panner1in2out : public Panner
|
|||
void update ();
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_panner_1in2out_h__ */
|
||||
|
|
|
|||
|
|
@ -20,35 +20,34 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdlib>
|
||||
#include <float.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
#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"
|
||||
|
||||
|
|
@ -69,7 +68,11 @@ static PanPluginDescriptor _descriptor = {
|
|||
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<Pannable> p)
|
||||
: Panner (p)
|
||||
|
|
@ -151,15 +154,15 @@ Panner2in2out::update ()
|
|||
}
|
||||
|
||||
/* 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.
|
||||
* 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
|
||||
* x == 1 => hard right = 0.0 degrees
|
||||
*/
|
||||
|
||||
float pos[2];
|
||||
|
|
@ -245,21 +248,20 @@ Panner2in2out::clamp_stereo_pan (double& direction_as_lr_fract, double& width)
|
|||
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 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 (l_pos < 0.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 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;
|
||||
|
|
@ -283,7 +285,7 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
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;
|
||||
|
|
@ -303,27 +305,19 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
mix_buffers_with_gain (dst + n, src + n, nframes - n, pan);
|
||||
|
||||
} else {
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
|
@ -339,7 +333,7 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
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;
|
||||
|
|
@ -361,24 +355,19 @@ Panner2in2out::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
/* XXX it would be nice to mark the buffer as written to */
|
||||
|
||||
} else {
|
||||
|
||||
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);
|
||||
|
||||
/* 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);
|
||||
|
|
@ -416,21 +405,20 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
|
|||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
for (pframes_t n = 0; n < nframes; ++n) {
|
||||
|
||||
float panR;
|
||||
|
||||
if (which == 0) {
|
||||
// panning left signal
|
||||
/* panning left signal */
|
||||
panR = position[n] - (width[n] / 2.0f); // center - width/2
|
||||
} else {
|
||||
// panning right signal
|
||||
/* panning right signal */
|
||||
panR = position[n] + (width[n] / 2.0f); // center - width/2
|
||||
}
|
||||
|
||||
|
|
@ -439,10 +427,10 @@ Panner2in2out::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
|
|||
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.
|
||||
* 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);
|
||||
|
|
@ -491,21 +479,20 @@ Panner2in2out::get_state ()
|
|||
string
|
||||
Panner2in2out::value_as_string (boost::shared_ptr<const AutomationControl> 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.
|
||||
* 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)),
|
||||
|
|
|
|||
|
|
@ -20,31 +20,37 @@
|
|||
#ifndef __ardour_panner_2in2out_h__
|
||||
#define __ardour_panner_2in2out_h__
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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:
|
||||
Panner2in2out (boost::shared_ptr<Pannable>);
|
||||
~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&);
|
||||
|
|
@ -86,6 +92,6 @@ class Panner2in2out : public Panner
|
|||
pan_t** buffers, uint32_t which);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_panner_2in2out_h__ */
|
||||
|
|
|
|||
|
|
@ -19,35 +19,34 @@
|
|||
|
||||
#include <inttypes.h>
|
||||
|
||||
#include <cmath>
|
||||
#include <cerrno>
|
||||
#include <cstdlib>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <locale.h>
|
||||
#include <unistd.h>
|
||||
#include <cstdlib>
|
||||
#include <float.h>
|
||||
#include <locale.h>
|
||||
#include <string>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <glibmm.h>
|
||||
|
||||
#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,7 +67,11 @@ 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<Pannable> p)
|
||||
: Panner (p)
|
||||
|
|
@ -166,7 +169,7 @@ Pannerbalance::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
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;
|
||||
|
|
@ -186,23 +189,16 @@ Pannerbalance::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gai
|
|||
mix_buffers_with_gain (dst + n, src + n, nframes - n, pan);
|
||||
|
||||
} else {
|
||||
|
||||
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;
|
||||
|
||||
/* XXX it would be nice to mark the buffer as written to */
|
||||
}
|
||||
|
||||
} else {
|
||||
|
|
@ -233,7 +229,6 @@ Pannerbalance::distribute_one_automated (AudioBuffer& srcbuf, BufferSet& obufs,
|
|||
}
|
||||
|
||||
for (pframes_t n = 0; n < nframes; ++n) {
|
||||
|
||||
float const pos = position[n];
|
||||
|
||||
if (which == 0) { // Left
|
||||
|
|
@ -280,21 +275,20 @@ Pannerbalance::get_state ()
|
|||
string
|
||||
Pannerbalance::value_as_string (boost::shared_ptr<const AutomationControl> 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.
|
||||
* 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)),
|
||||
|
|
|
|||
|
|
@ -19,31 +19,37 @@
|
|||
#ifndef __ardour_panner_balance_h__
|
||||
#define __ardour_panner_balance_h__
|
||||
|
||||
#include <cmath>
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <cmath>
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#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:
|
||||
Pannerbalance (boost::shared_ptr<Pannable>);
|
||||
~Pannerbalance ();
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
void set_position (double);
|
||||
bool clamp_position (double&);
|
||||
|
|
@ -73,6 +79,6 @@ class Pannerbalance : public Panner
|
|||
pan_t** buffers, uint32_t which);
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __ardour_panner_balance_h__ */
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#include <iostream>
|
||||
|
|
@ -59,7 +59,11 @@ static PanPluginDescriptor _descriptor = {
|
|||
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)
|
||||
{
|
||||
|
|
@ -114,7 +118,6 @@ VBAPanner::configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */
|
|||
for (uint32_t i = 0; i < n; ++i) {
|
||||
Signal* s = new Signal (*this, i, _speakers->n_speakers ());
|
||||
_signals.push_back (s);
|
||||
|
||||
}
|
||||
|
||||
update ();
|
||||
|
|
@ -123,7 +126,6 @@ VBAPanner::configure_io (ChanCount in, ChanCount /* ignored - we use Speakers */
|
|||
void
|
||||
VBAPanner::update ()
|
||||
{
|
||||
|
||||
_can_automate_list.clear ();
|
||||
_can_automate_list.insert (Evoral::Parameter (PanAzimuthAutomation));
|
||||
if (_signals.size () > 1) {
|
||||
|
|
@ -141,7 +143,6 @@ VBAPanner::update ()
|
|||
double signal_direction = 1.0 - (_pannable->pan_azimuth_control->get_value () + (w / 2));
|
||||
double grd_step_per_signal = w / (_signals.size () - 1);
|
||||
for (vector<Signal*>::iterator s = _signals.begin (); s != _signals.end (); ++s) {
|
||||
|
||||
Signal* signal = *s;
|
||||
|
||||
int over = signal_direction;
|
||||
|
|
@ -184,11 +185,9 @@ VBAPanner::compute_gains (double gains[3], int speaker_ids[3], int azi, int ele)
|
|||
speaker_ids[0] = speaker_ids[1] = speaker_ids[2] = 0;
|
||||
|
||||
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++) {
|
||||
|
|
@ -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];
|
||||
|
|
@ -238,7 +236,6 @@ VBAPanner::distribute (BufferSet& inbufs, BufferSet& obufs, gain_t gain_coeffici
|
|||
assert (inbufs.count ().n_audio () == _signals.size ());
|
||||
|
||||
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);
|
||||
|
|
@ -254,21 +251,21 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
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.
|
||||
* 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<double>::size_type sz = signal->gains.size ();
|
||||
|
|
@ -285,11 +282,10 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
}
|
||||
|
||||
/* for all outputs used this time and last time,
|
||||
change the output record to show what has
|
||||
happened.
|
||||
* change the output record to show what has
|
||||
* happened.
|
||||
*/
|
||||
|
||||
|
||||
for (int o = 0; o < 3; ++o) {
|
||||
if (signal->outputs[o] != -1) {
|
||||
/* used last time */
|
||||
|
|
@ -303,12 +299,12 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
}
|
||||
|
||||
/* 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
|
||||
|
||||
*
|
||||
* (*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) {
|
||||
|
|
@ -322,15 +318,13 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
pan = gain_coefficient * signal->desired_gains[o];
|
||||
|
||||
if (pan == 0.0 && signal->gains[output] == 0.0) {
|
||||
|
||||
/* nothing deing delivered to this output */
|
||||
|
||||
signal->gains[output] = 0.0;
|
||||
|
||||
} else if (fabs (pan - signal->gains[output]) > 0.00001) {
|
||||
|
||||
/* signal to this output but the gain coefficient has changed, so
|
||||
interpolate between them.
|
||||
* interpolate between them.
|
||||
*/
|
||||
|
||||
AudioBuffer& buf (obufs.get_audio (output));
|
||||
|
|
@ -338,22 +332,18 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
signal->gains[output] = pan;
|
||||
|
||||
} else {
|
||||
|
||||
/* signal to this output, same gain as before so just copy with gain
|
||||
*/
|
||||
/* signal to this output, same gain as before so just copy with gain */
|
||||
|
||||
mix_buffers_with_gain (obufs.get_audio (output).data (), src, nframes, pan);
|
||||
signal->gains[output] = pan;
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up the outputs that were used last time but not this time
|
||||
*/
|
||||
/* 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
|
||||
*/
|
||||
/* 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;
|
||||
|
|
@ -361,8 +351,8 @@ VBAPanner::distribute_one (AudioBuffer& srcbuf, BufferSet& obufs, gain_t gain_co
|
|||
}
|
||||
|
||||
/* 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.
|
||||
* so anything we didn't write to with this signal (or any others)
|
||||
* is just as it should be.
|
||||
*/
|
||||
}
|
||||
|
||||
|
|
@ -405,7 +395,6 @@ VBAPanner::out() const
|
|||
string
|
||||
VBAPanner::value_as_string (boost::shared_ptr<const AutomationControl> ac) const
|
||||
{
|
||||
/* DO NOT USE LocaleGuard HERE */
|
||||
double val = ac->get_value ();
|
||||
|
||||
switch (ac->parameter ().type ()) {
|
||||
|
|
|
|||
|
|
@ -20,8 +20,8 @@
|
|||
#ifndef __libardour_vbap_h__
|
||||
#define __libardour_vbap_h__
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
#include "pbd/cartesian.h"
|
||||
|
||||
|
|
@ -30,8 +30,8 @@
|
|||
|
||||
#include "vbap_speakers.h"
|
||||
|
||||
namespace ARDOUR {
|
||||
|
||||
namespace ARDOUR
|
||||
{
|
||||
class Speakers;
|
||||
class Pannable;
|
||||
|
||||
|
|
@ -90,6 +90,6 @@ private:
|
|||
pan_t** buffers, uint32_t which);
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __libardour_vbap_h__ */
|
||||
|
|
|
|||
|
|
@ -31,8 +31,8 @@
|
|||
of the software.
|
||||
*/
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "pbd/cartesian.h"
|
||||
|
|
@ -94,12 +94,12 @@ void
|
|||
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
|
||||
|
|
@ -122,14 +122,15 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets)
|
|||
}
|
||||
|
||||
/* 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).
|
||||
* 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++) {
|
||||
|
|
@ -180,8 +181,8 @@ 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];
|
||||
|
|
@ -200,7 +201,7 @@ 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) {
|
||||
|
|
@ -225,7 +226,6 @@ VBAPSpeakers::choose_speaker_triplets(struct ls_triplet_chain **ls_triplets)
|
|||
} else {
|
||||
prev = trip_ptr;
|
||||
trip_ptr = trip_ptr->next;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -285,7 +285,6 @@ 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)
|
||||
{
|
||||
|
|
@ -335,7 +334,8 @@ double
|
|||
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;
|
||||
if (rv > 1e-14)
|
||||
return rv;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -349,16 +349,14 @@ double
|
|||
VBAPSpeakers::vol_p_side_lgth (int i, int j, int k, const vector<Speaker>& 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;
|
||||
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())));
|
||||
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 {
|
||||
|
|
@ -391,16 +389,17 @@ 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;
|
||||
|
||||
|
|
@ -530,10 +529,10 @@ 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 ();
|
||||
|
||||
|
|
@ -544,8 +543,8 @@ VBAPSpeakers::choose_speaker_pairs (){
|
|||
|
||||
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).
|
||||
* 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);
|
||||
|
|
@ -568,7 +567,6 @@ VBAPSpeakers::choose_speaker_pairs (){
|
|||
|
||||
/* 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,
|
||||
|
|
@ -580,8 +578,7 @@ VBAPSpeakers::choose_speaker_pairs (){
|
|||
}
|
||||
}
|
||||
|
||||
if (((6.283 - _speakers[sorted_speakers[n_speakers-1]].angles().azi)
|
||||
+_speakers[sorted_speakers[0]].angles().azi) <= AZIMUTH_DELTA_THRESHOLD_DEGREES) {
|
||||
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) {
|
||||
|
|
@ -654,7 +651,6 @@ VBAPSpeakers::calc_2D_inv_tmatrix (double azi1, double azi2, double* inverse_mat
|
|||
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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -29,23 +29,46 @@
|
|||
#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<Speakers>);
|
||||
|
||||
typedef std::vector<double> 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];
|
||||
}
|
||||
|
||||
uint32_t n_speakers() const { return _speakers.size(); }
|
||||
boost::shared_ptr<Speakers> parent() const { return _parent; }
|
||||
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;
|
||||
}
|
||||
|
||||
uint32_t n_speakers () const
|
||||
{
|
||||
return _speakers.size ();
|
||||
}
|
||||
|
||||
boost::shared_ptr<Speakers> parent () const
|
||||
{
|
||||
return _parent;
|
||||
}
|
||||
|
||||
~VBAPSpeakers ();
|
||||
|
||||
|
|
@ -57,7 +80,8 @@ private:
|
|||
PBD::ScopedConnection speaker_connection;
|
||||
|
||||
struct azimuth_sorter {
|
||||
bool operator() (const Speaker& s1, const Speaker& s2) {
|
||||
bool operator() (const Speaker& s1, const Speaker& s2)
|
||||
{
|
||||
return s1.angles ().azi < s2.angles ().azi;
|
||||
}
|
||||
};
|
||||
|
|
@ -99,9 +123,8 @@ private:
|
|||
void choose_speaker_pairs ();
|
||||
void sort_2D_lss (int* sorted_lss);
|
||||
int calc_2D_inv_tmatrix (double azi1, double azi2, double* inv_mat);
|
||||
|
||||
};
|
||||
|
||||
} /* namespace */
|
||||
} // namespace ARDOUR
|
||||
|
||||
#endif /* __libardour_vbap_speakers_h__ */
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue