[LAD] panning thoughts

Jens M Andreasen jens.andreasen at comhem.se
Sun Nov 14 18:16:46 UTC 2010


On Sun, 2010-11-14 at 15:38 +0000, Folderol wrote:

> I don't know if this is at all relevant (prolly not!) but I dimly remember,
> from my BBC B days, there was a way of drawing circles using Pythagoras. This
> was dramatically faster than using sin/cos.

It is actually very relevant since the algorithm you might have in
mind..
 http://en.wikipedia.org/wiki/Midpoint_circle_algorithm

.. is iterative and depends on that the previus step is known. If you
remember, the original poster wanted a /movement/ controlled by either
ENV or LFO - which boils down to a single complex mul. In case of LFO
this also serves as the LFO itself (shaving off even more instructions)
and in case of ENV, a test is needed to detect if speed and/or direction
of the rotation should be changed (say when x below becomes negative and
we have therefore passed the outer position of the speakers.)

Most of this discussion have instead become about finding an arbitrary
point, which is only needed to get the panning LFO/ENV started from a
point which is neither left nor right (ie: not 1.0,0.0) 

// Say we want a panning LFO at 0.2 Hz 

  float

    // left and right
    x = 0.0,
    y = 1.0,

    // speed
    w = 0.2 * (PI / SAMPLERATE),
    a = _sinf(w) * 2, // see below 


// Move it!

   for(;;) // for each sample, do
     x -= a*y, y += a*x;    // pure magic ...

// x and y at this point holds an oscillating sin/cos pair. 



The  GCC/GNU Libc combo can't vectorize Math - not even for vectors of
identical oscillators. A Taylor approximation will do the job for this
project:

// Inverse of the factorials (n!) 1 - 9

#define IF_1 (1.f)
#define IF_2 (1.f/2.f)
#define IF_3 (1.f/6.f)
#define IF_4 (1.f/24.f)
#define IF_5 (1.f/120.f)
#define IF_6 (1.f/720.f)
#define IF_7 (1.f/5040.f) 
#define IF_8 (1.f/40320.f) 
#define IF_9 (1.f/362880.f)

inline float _sinf(float x) 
{ 
  float x2 = x*x;
  float rt = IF_9;

  rt *= x2;
  rt -= IF_7;
  rt *= x2; 
  rt += IF_5;
  rt *= x2;
  rt -= IF_3;
  rt *= x2; 
  rt += IF_1;
  rt *= x;

  return rt;
}


-- 
jedes mal wenn du eine quintparallele verwendest
tötet bach ein kätzchen.

 http://www.youtube.com/watch?v=43RdmmNaGfQ




More information about the Linux-audio-dev mailing list