Support quad, 5.1, and 7.1 with OpenAL and ffmpeg

The other decoders don't guarantee any channel ordering, which makes them
useless.
actorid
Chris Robinson 12 years ago
parent 600494eed8
commit 1ea1407707

@ -333,6 +333,12 @@ public:
*chans = MWSound::ChannelConfig_Mono;
else if(is->audio_st->codec->channel_layout == AV_CH_LAYOUT_STEREO)
*chans = MWSound::ChannelConfig_Stereo;
else if(is->audio_st->codec->channel_layout == AV_CH_LAYOUT_QUAD)
*chans = MWSound::ChannelConfig_Quad;
else if(is->audio_st->codec->channel_layout == AV_CH_LAYOUT_5POINT1)
*chans = MWSound::ChannelConfig_5point1;
else if(is->audio_st->codec->channel_layout == AV_CH_LAYOUT_7POINT1)
*chans = MWSound::ChannelConfig_7point1;
else if(is->audio_st->codec->channel_layout == 0)
{
/* Unknown channel layout. Try to guess. */

@ -347,6 +347,12 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *
*chans = ChannelConfig_Mono;
else if(stream->mCodecCtx->channel_layout == AV_CH_LAYOUT_STEREO)
*chans = ChannelConfig_Stereo;
else if(stream->mCodecCtx->channel_layout == AV_CH_LAYOUT_QUAD)
*chans = ChannelConfig_Quad;
else if(stream->mCodecCtx->channel_layout == AV_CH_LAYOUT_5POINT1)
*chans = ChannelConfig_5point1;
else if(stream->mCodecCtx->channel_layout == AV_CH_LAYOUT_7POINT1)
*chans = ChannelConfig_7point1;
else if(stream->mCodecCtx->channel_layout == 0)
{
/* Unknown channel layout. Try to guess. */

@ -61,6 +61,34 @@ static ALenum getALFormat(ChannelConfig chans, SampleType type)
if(fmtlist[i].chans == chans && fmtlist[i].type == type)
return fmtlist[i].format;
}
if(alIsExtensionPresent("AL_EXT_MCFORMATS"))
{
static const struct {
char name[32];
ChannelConfig chans;
SampleType type;
} mcfmtlist[] = {
{ "AL_FORMAT_QUAD16", ChannelConfig_Quad, SampleType_Int16 },
{ "AL_FORMAT_QUAD8", ChannelConfig_Quad, SampleType_UInt8 },
{ "AL_FORMAT_51CHN16", ChannelConfig_5point1, SampleType_Int16 },
{ "AL_FORMAT_51CHN8", ChannelConfig_5point1, SampleType_UInt8 },
{ "AL_FORMAT_71CHN16", ChannelConfig_7point1, SampleType_Int16 },
{ "AL_FORMAT_71CHN8", ChannelConfig_7point1, SampleType_UInt8 },
};
static const size_t mcfmtlistsize = sizeof(mcfmtlist)/sizeof(mcfmtlist[0]);
for(size_t i = 0;i < mcfmtlistsize;i++)
{
if(mcfmtlist[i].chans == chans && mcfmtlist[i].type == type)
{
ALenum format = alGetEnumValue(mcfmtlist[i].name);
if(format != 0 && format != -1)
return format;
}
}
}
fail(std::string("Unsupported sound format (")+getChannelConfigName(chans)+", "+getSampleTypeName(type)+")");
return AL_NONE;
}

@ -15,7 +15,10 @@ namespace MWSound
enum ChannelConfig {
ChannelConfig_Mono,
ChannelConfig_Stereo
ChannelConfig_Stereo,
ChannelConfig_Quad,
ChannelConfig_5point1,
ChannelConfig_7point1
};
const char *getChannelConfigName(ChannelConfig config);

@ -622,8 +622,11 @@ namespace MWSound
{
switch(config)
{
case ChannelConfig_Mono: return "Mono";
case ChannelConfig_Stereo: return "Stereo";
case ChannelConfig_Mono: return "Mono";
case ChannelConfig_Stereo: return "Stereo";
case ChannelConfig_Quad: return "Quad";
case ChannelConfig_5point1: return "5.1 Surround";
case ChannelConfig_7point1: return "7.1 Surround";
}
return "(unknown channel config)";
}
@ -632,8 +635,11 @@ namespace MWSound
{
switch(config)
{
case ChannelConfig_Mono: frames *= 1; break;
case ChannelConfig_Stereo: frames *= 2; break;
case ChannelConfig_Mono: frames *= 1; break;
case ChannelConfig_Stereo: frames *= 2; break;
case ChannelConfig_Quad: frames *= 4; break;
case ChannelConfig_5point1: frames *= 6; break;
case ChannelConfig_7point1: frames *= 8; break;
}
switch(type)
{

Loading…
Cancel
Save