[vorbis-dev] About lossless and point stereo

Stephen So s.so at griffith.edu.au
Mon Feb 23 17:45:51 PST 2004



Hi,

I've read the Vorbis stereo documentation on square polar mapping and 
currently reading the source code to understand it.  But there are some 
things which I don't quite understand and hope I can get some guidance on.

I understand the decoding/decoupling part as it is the same as the one 
described in the stereo docs:

 From mapping0.c:

/* channel coupling */
  for(i=info->coupling_steps-1;i>=0;i--){
    float *pcmM=vb->pcm[info->coupling_mag[i]];
    float *pcmA=vb->pcm[info->coupling_ang[i]];

    for(j=0;j<n/2;j++){
      float mag=pcmM[j];
      float ang=pcmA[j];

      if(mag>0)
    if(ang>0){
      pcmM[j]=mag;
      pcmA[j]=mag-ang;
    }else{
      pcmA[j]=mag;
      pcmM[j]=mag+ang;
    }
      else
    if(ang>0){
      pcmM[j]=mag;
      pcmA[j]=mag+ang;
    }else{
      pcmA[j]=mag;
      pcmM[j]=mag-ang;
    }
    }
  }

But when I look at the (rather messy) lossless coupling function  
(couple_lossless) in psy.c:

tatic void couple_lossless(float A, float B, float *qA, float *qB)
{
    int test1 = fabs(*qA) > fabs(*qB);
    test1 -= fabs(*qA) < fabs(*qB);

    if (!test1)
    test1 = ((fabs(A) > fabs(B)) << 1) - 1;
    if (test1 == 1) {
    *qB = (*qA > 0.f ? *qA - *qB : *qB - *qA);
    } else {
    float temp = *qB;
    *qB = (*qB > 0.f ? *qA - *qB : *qB - *qA);
    *qA = temp;
    }

    if (*qB > fabs(*qA) * 1.9999f) {
    *qB = -fabs(*qA) * 2.f;
    *qA = -*qA;
    }
}

There are some things which I don't understand.  I think I understand 
the first half where we decide which channel is larger and swapping them 
if B is larger than A, etc.  

If swapping B with A was needed in the decoder, how does the decoder 
know to swap them back when uncoupling?

Secondly, I dont quite get how we can uncouple losslessly if that last 
if statement were true.  That is:

    if (*qB > fabs(*qA) * 1.9999f) {
    *qB = -fabs(*qA) * 2.f;
    *qA = -*qA;
    }

I used some test cases of qA and qB but it seems the uncoupling routine 
in mapping0.c can't get the original A/B back.  Also, I seem to get the 
feeling that stereo coupling is rather messy in Vorbis 1.0.

My second question is about point stereo.  From my understanding, in 
Vorbis 1.0,  at medium to low quality levels, we use a mix of lossless 
stereo and point stereo for different frequency bands, depending on the 
values of the adj_stereo structure.  Looking at the 
precomputed_couple_point function in psy.c, the last two statements:

*mag = premag * floormag;
*ang = 0.f;

eem to imply the angle (diffuse sounds) is set to zero.  So point 
stereo is essentially monaural, since angle=A-B so if angle is 0, A=B?  
Hence Vorbis "joint" stereo is essentially a mix of lossless stereo and 
mono, right?  It seems like a very strange way of coupling as I would 
have expected point stereo to at least have a heavily quantised 
angle.....that is, not many bits go into encoding the angle but we do 
have at least a rough angle/diffuse sounds.  Also, why not implement 
mid/side stereo instead of this mix of lossless and intensity stereo?

I apologise for the very large e-mail but I am very interested in the 
internals of Vorbis :)

Best regards,

Steve.


-- 
--------------------------------------------------
Stephen So, BEng(Hons)

PhD Student, 
Signal Processing Laboratory,
School of Microelectronic Engineering,
Faculty of Engineering and Information Technology,
Griffith University, Nathan Campus,
Brisbane, QLD, Australia, 4111.

Phone: +61-7-3875 3754
E-mail: s.so at griffith.edu.au
--------------------------------------------------

--- >8 ----
List archives:  http://www.xiph.org/archives/
Ogg project homepage: http://www.xiph.org/ogg/
To unsubscribe from this list, send a message to 'vorbis-dev-request at xiph.org'
containing only the word 'unsubscribe' in the body.  No subject is needed.
Unsubscribe messages sent to the list will be ignored/filtered.




More information about the Vorbis-dev mailing list