1
0
Fork 0
mirror of https://github.com/OpenMW/openmw.git synced 2025-01-21 07:23:54 +00:00

Support quad, 5.1, and 7.1 with OpenAL and ffmpeg

The other decoders don't guarantee any channel ordering, which makes them
useless.
This commit is contained in:
Chris Robinson 2012-12-13 04:10:19 -08:00
parent 600494eed8
commit 1ea1407707
5 changed files with 54 additions and 5 deletions

View file

@ -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. */

View file

@ -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. */

View file

@ -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;
}

View file

@ -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);

View file

@ -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)
{