# [Fwd: Re: [ardour-dev] questions about panner.cc ...]

Marc Vinyes mvinyes at iua.upf.es
Fri Aug 26 01:45:07 PDT 2005

```fons adriaensen wrote:
> On Fri, Aug 26, 2005 at 12:32:58AM +0200, Marc Vinyes wrote:
>
>>>The scheme used is a (good) approximation to sin(), cos().
>>
>>Uow, during my degree I only used taylor series to aproximate sin() and
>>cos() and this aproximation is just fantastic in the range of [0,pi/2]!
>>Do you know how did they get it? (does it minimize the norm error
>>between the parabola and the sin() perhaps?)
>
>
> Yes, it is a very good approximation. How to compute it ? You want
> f(0) = 0 and f(1) = 1, so there's only one free parameter. The rest
> is 'an exercise for the reader' :-)
>
> An even simpler one, accurate enough for pannning, is x * (2 - x).
> Replace x by 1 - x for the other channel.
>
the reader finds out that the next forced point is (0.5,1/sqrt(2)) :-)

Now, my next question is "is it really worth approximating sin() by this
parabola?" does it improve significatively the performance? I suppose
that some day(or maybe they already do), processors will incorporate
sin()-in-one-instruction... isn't it?

anyway,after this, I'd suggest (I just "submit" my opinion) to replace
the code:

""
const float pan_law_attenuation = -3.0f;
const float scale = 2.0f - 4.0f * powf (10.0f,pan_law_attenuation/20.0f);

/* x == 0 => hard left
x == 1 => hard right
*/

float panR = x;
float panL = 1 - panR;

desired_left = panL * (scale * panL + 1.0f - scale);
desired_right = panR * (scale * panR + 1.0f - scale);
""

with:

""
// x == 0 => hard left
// x == 1 => hard right

// implementation of constant power panning:
// desired_left= cos(x*PI/2)
// desired_right = sin(x*PI/2)

// cos() and sin() are aproximated by parabolas
// the parabolas are found by forcing y(x)=a*x^2+bx+c to be:
// (desired_left)  y(1)=0, y(1)=0, y(0.5)=1/sqrt(2)
// (desired_right) y(0)=0, y(1)=1, y(0.5)=1/sqrt(2)

const float scale= 2.0f-2.0f*sqrt(2);
desired_left = (1-x) * (scale * (1-x) + 1.0f - scale);
desired_right = x * (scale * x + 1.0f - scale);
""

Thanks again fons,
MarC

```