Ogg Vorbis/Opus: Use correct channel output order for surround files
This commit is contained in:
parent
b13235ec5f
commit
73a356ad1d
2 changed files with 49 additions and 5 deletions
|
@ -14,6 +14,18 @@
|
||||||
|
|
||||||
@implementation OpusFile
|
@implementation OpusFile
|
||||||
|
|
||||||
|
static const int MAXCHANNELS = 8;
|
||||||
|
static const int chmap[MAXCHANNELS][MAXCHANNELS] = {
|
||||||
|
{ 0, }, // mono
|
||||||
|
{ 0, 1, }, // l, r
|
||||||
|
{ 0, 2, 1, }, // l, c, r -> l, r, c
|
||||||
|
{ 0, 1, 2, 3, }, // l, r, bl, br
|
||||||
|
{ 0, 2, 1, 3, 4, }, // l, c, r, bl, br -> l, r, c, bl, br
|
||||||
|
{ 0, 2, 1, 5, 3, 4 }, // l, c, r, bl, br, lfe -> l, r, c, lfe, bl, br
|
||||||
|
{ 0, 2, 1, 6, 5, 3, 4 }, // l, c, r, sl, sr, bc, lfe -> l, r, c, lfe, bc, sl, sr
|
||||||
|
{ 0, 2, 1, 7, 5, 6, 3, 4 } // l, c, r, sl, sr, bl, br, lfe -> l, r, c, lfe, bl, br, sl, sr
|
||||||
|
};
|
||||||
|
|
||||||
int sourceRead(void *_stream, unsigned char *_ptr, int _nbytes)
|
int sourceRead(void *_stream, unsigned char *_ptr, int _nbytes)
|
||||||
{
|
{
|
||||||
id source = (__bridge id)_stream;
|
id source = (__bridge id)_stream;
|
||||||
|
@ -100,8 +112,19 @@ opus_int64 sourceTell(void *_stream)
|
||||||
int size = frames * channels;
|
int size = frames * channels;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
|
float *out = ((float*)buf) + total;
|
||||||
|
float tempbuf[512 * channels];
|
||||||
lastSection = currentSection;
|
lastSection = currentSection;
|
||||||
numread = op_read_float( opusRef, &((float *)buf)[total], size - total, NULL );
|
int toread = size - total;
|
||||||
|
if (toread > 512) toread = 512;
|
||||||
|
numread = op_read_float( opusRef, (channels < MAXCHANNELS) ? tempbuf : out, toread, NULL );
|
||||||
|
if (numread > 0 && channels < MAXCHANNELS) {
|
||||||
|
for (int i = 0; i < numread; ++i) {
|
||||||
|
for (int j = 0; j < channels; ++j) {
|
||||||
|
out[i * channels + j] = tempbuf[i * channels + chmap[channels - 1][j]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
currentSection = op_current_link( opusRef );
|
currentSection = op_current_link( opusRef );
|
||||||
if (numread > 0) {
|
if (numread > 0) {
|
||||||
total += numread * channels;
|
total += numread * channels;
|
||||||
|
@ -111,7 +134,7 @@ opus_int64 sourceTell(void *_stream)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
} while (total != frames && numread != 0);
|
} while (total != size && numread != 0);
|
||||||
|
|
||||||
return total/channels;
|
return total/channels;
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,18 @@
|
||||||
|
|
||||||
@implementation VorbisDecoder
|
@implementation VorbisDecoder
|
||||||
|
|
||||||
|
static const int MAXCHANNELS = 8;
|
||||||
|
static const int chmap[MAXCHANNELS][MAXCHANNELS] = {
|
||||||
|
{ 0, }, // mono
|
||||||
|
{ 0, 1, }, // l, r
|
||||||
|
{ 0, 2, 1, }, // l, c, r -> l, r, c
|
||||||
|
{ 0, 1, 2, 3, }, // l, r, bl, br
|
||||||
|
{ 0, 2, 1, 3, 4, }, // l, c, r, bl, br -> l, r, c, bl, br
|
||||||
|
{ 0, 2, 1, 5, 3, 4 }, // l, c, r, bl, br, lfe -> l, r, c, lfe, bl, br
|
||||||
|
{ 0, 2, 1, 6, 5, 3, 4 }, // l, c, r, sl, sr, bc, lfe -> l, r, c, lfe, bc, sl, sr
|
||||||
|
{ 0, 2, 1, 7, 5, 6, 3, 4 } // l, c, r, sl, sr, bl, br, lfe -> l, r, c, lfe, bl, br, sl, sr
|
||||||
|
};
|
||||||
|
|
||||||
size_t sourceRead(void *buf, size_t size, size_t nmemb, void *datasource)
|
size_t sourceRead(void *buf, size_t size, size_t nmemb, void *datasource)
|
||||||
{
|
{
|
||||||
id source = (__bridge id)datasource;
|
id source = (__bridge id)datasource;
|
||||||
|
@ -94,9 +106,18 @@ long sourceTell(void *datasource)
|
||||||
float ** pcm;
|
float ** pcm;
|
||||||
numread = (int)ov_read_float(&vorbisRef, &pcm, frames - total, ¤tSection);
|
numread = (int)ov_read_float(&vorbisRef, &pcm, frames - total, ¤tSection);
|
||||||
if (numread > 0) {
|
if (numread > 0) {
|
||||||
for (int i = 0; i < channels; i++) {
|
if (channels < MAXCHANNELS) {
|
||||||
for (int j = 0; j < numread; j++) {
|
for (int i = 0; i < channels; i++) {
|
||||||
((float *)buf)[(total + j) * channels + i] = pcm[i][j];
|
for (int j = 0; j < numread; j++) {
|
||||||
|
((float *)buf)[(total + j) * channels + i] = pcm[chmap[channels-1][i]][j];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (int i = 0; i < channels; i++) {
|
||||||
|
for (int j = 0; j < numread; j++) {
|
||||||
|
((float *)buf)[(total + j) * channels + i] = pcm[i][j];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
total += numread;
|
total += numread;
|
||||||
|
|
Loading…
Reference in a new issue