oggdec channel ordering bug
Nicolas George <[email protected]> Wed, 4 Jul 2012 12:18:12 +0200
| Newsgroups | gmane.comp.multimedia.ogg.vorbis.devel |
|---|---|
| Message-ID | <[email protected]> |
Hi.
I just noticed that oggdec channel reordering for WAV is bogus.
With irrelevant clutter removed, oggenc has the following code:
permute = {0,2,1,4,5,3} // oggenc/audio.c:401
for (j)
to_vorbis[j] = from_wav[permute[j]] // oggenc/audio.c:619
While oggdec has the following code:
permute = {0,2,1,5,3,4} // oggdec/oggdec.c:229
for (j)
to_wav[permute[j]] = from_vorbis[j] // oggdec/oggdec.c:240
You can notice the permutation vectors are reciprocal to each other and that
the code apply them in the opposite direction. Both inversions cancel
each-other.
After more careful checking with the specs, oggenc is right and oggdec is
wrong.
Note that this is for 5.1; 5.0 seems even wronger and 6.1 and 7.1 are not
implemented.
The obvious fix is to copy-paste the matrix from oggenc to oggdec. Patch
attached.
Regards,
--
Nicolas George
_______________________________________________
Vorbis-dev mailing list
[email protected]
http://lists.xiph.org/mailman/listinfo/vorbis-dev
0001-oggdec-import-permute-matrix-from-oggenc.patch
(text/x-diff, 1.5 KB)
From e4e4981af99e13b4676cc4763ab191189cf07467 Mon Sep 17 00:00:00 2001 From: Nicolas George <[email protected]> Date: Wed, 4 Jul 2012 12:15:01 +0200 Subject: [PATCH] oggdec: import permute matrix from oggenc. The previous permutations were inverted while the code assumes they are not. Also, the matrix from oggenc goes to 8 channels. Signed-off-by: Nicolas George <[email protected]> --- oggdec/oggdec.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/oggdec/oggdec.c b/oggdec/oggdec.c index 5ffb125..f7ff208 100644 --- a/oggdec/oggdec.c +++ b/oggdec/oggdec.c @@ -225,13 +225,21 @@ static FILE *open_output(char *outfile) static void permute_channels(char *in, char *out, int len, int channels, int bytespersample) { - int permute[6][6] = {{0}, {0,1}, {0,2,1}, {0,1,2,3}, {0,1,2,3,4}, - {0,2,1,5,3,4}}; + int permute[6][6] = { + {0}, /* 1.0 mono */ + {0,1}, /* 2.0 stereo */ + {0,2,1}, /* 3.0 channel ('wide') stereo */ + {0,1,2,3}, /* 4.0 discrete quadraphonic */ + {0,2,1,3,4}, /* 5.0 surround */ + {0,2,1,4,5,3}, /* 5.1 surround */ + {0,2,1,5,6,4,3}, /* 6.1 surround */ + {0,2,1,6,7,4,5,3} /* 7.1 surround (classic theater 8-track) */ + }; int i,j,k; int samples = len/channels/bytespersample; /* Can't handle, don't try */ - if (channels > 6) + if (channels > 8) return; for (i=0; i < samples; i++) { -- 1.7.10
signature.asc
(application/pgp-signature, 198 B)
-----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.12 (GNU/Linux) iEYEARECAAYFAk/0GGQACgkQsGPZlzblTJMaZACgh7YmwT1jaW2WgpbooQD7XVw7 XOEAnR0t0yTdmRPVdfR49t01IT5UaWHG =yHjN -----END PGP SIGNATURE-----