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@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@xiph.org'
containing only the word 'unsubscribe' in the body. No subject is
needed.
Unsubscribe messages sent to the list will be ignored/filtered.