Audio: Drop the LFE/subwoofer channel from the decoded surround

DPL2Decode still doesn't decode 5.1 properly, leaving bass in all channels, but its 5.0 is pretty good, so leave it at that.
This commit is contained in:
Adam D. Moss 2015-01-18 23:11:45 +00:00
parent 37a770bb9f
commit 05d2bf6060
2 changed files with 27 additions and 8 deletions

View File

@ -251,6 +251,14 @@ void OpenALStream::SoundLoop()
{ {
float dpl2[OAL_MAX_SAMPLES * OAL_MAX_BUFFERS * SURROUND_CHANNELS]; float dpl2[OAL_MAX_SAMPLES * OAL_MAX_BUFFERS * SURROUND_CHANNELS];
DPL2Decode(sampleBuffer, nSamples, dpl2); DPL2Decode(sampleBuffer, nSamples, dpl2);
// zero-out the subwoofer channel - DPL2Decode generates a pretty
// good 5.0 but not a good 5.1 output. Sadly there is not a 5.0
// AL_FORMAT_50CHN32 to make this super-explicit.
// DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
for (u32 i=0; i < nSamples; ++i)
{
dpl2[i*SURROUND_CHANNELS + 3 /*sub/lfe*/] = 0.0f;
}
alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * FRAME_SURROUND_FLOAT, ulFrequency); alBufferData(uiBufferTemp[iBuffersFilled], AL_FORMAT_51CHN32, dpl2, nSamples * FRAME_SURROUND_FLOAT, ulFrequency);
ALenum err = alGetError(); ALenum err = alGetError();
if (err == AL_INVALID_ENUM) if (err == AL_INVALID_ENUM)

View File

@ -23,7 +23,7 @@ PulseAudio::PulseAudio(CMixer *mixer)
bool PulseAudio::Start() bool PulseAudio::Start()
{ {
m_stereo = !SConfig::GetInstance().m_LocalCoreStartupParameter.bDPL2Decoder; m_stereo = !SConfig::GetInstance().m_LocalCoreStartupParameter.bDPL2Decoder;
m_channels = m_stereo ? 2 : 6; // will tell PA we use a Stereo or 5.1 channel setup m_channels = m_stereo ? 2 : 5; // will tell PA we use a Stereo or 5.0 channel setup
NOTICE_LOG(AUDIO, "PulseAudio backend using %d channels", m_channels); NOTICE_LOG(AUDIO, "PulseAudio backend using %d channels", m_channels);
@ -103,15 +103,13 @@ bool PulseAudio::PulseInit()
ss.format = PA_SAMPLE_FLOAT32NE; ss.format = PA_SAMPLE_FLOAT32NE;
m_bytespersample = sizeof(float); m_bytespersample = sizeof(float);
// DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
channel_map_p = &channel_map; // explicit channel map: channel_map_p = &channel_map; // explicit channel map:
channel_map.channels = 6; channel_map.channels = 5;
channel_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT; channel_map.map[0] = PA_CHANNEL_POSITION_FRONT_LEFT;
channel_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT; channel_map.map[1] = PA_CHANNEL_POSITION_FRONT_RIGHT;
channel_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER; channel_map.map[2] = PA_CHANNEL_POSITION_FRONT_CENTER;
channel_map.map[3] = PA_CHANNEL_POSITION_LFE; channel_map.map[3] = PA_CHANNEL_POSITION_REAR_LEFT;
channel_map.map[4] = PA_CHANNEL_POSITION_REAR_LEFT; channel_map.map[4] = PA_CHANNEL_POSITION_REAR_RIGHT;
channel_map.map[5] = PA_CHANNEL_POSITION_REAR_RIGHT;
} }
ss.channels = m_channels; ss.channels = m_channels;
ss.rate = m_mixer->GetSampleRate(); ss.rate = m_mixer->GetSampleRate();
@ -202,9 +200,22 @@ void PulseAudio::WriteCallback(pa_stream* s, size_t length)
floatbuffer_stereo[i] = s16buffer_stereo[i] / float(1 << 15); floatbuffer_stereo[i] = s16buffer_stereo[i] / float(1 << 15);
} }
if (m_channels == 6) // Extract dpl2/5.1 Surround if (m_channels == 5) // Extract dpl2/5.0 Surround
{ {
DPL2Decode(floatbuffer_stereo, frames, (float*)buffer); float floatbuffer_6chan[frames * 6];
// DPL2Decode output: LEFTFRONT, RIGHTFRONT, CENTREFRONT, (sub), LEFTREAR, RIGHTREAR
DPL2Decode(floatbuffer_stereo, frames, floatbuffer_6chan);
// Discard the subwoofer channel - DPL2Decode generates a pretty
// good 5.0 but not a good 5.1 output.
const int dpl2_to_5chan[] = {0,1,2,4,5};
for (int i=0; i < frames; ++i)
{
for (int j=0; j < m_channels; ++j)
{
((float*)buffer)[m_channels * i + j] = floatbuffer_6chan[6 * i + dpl2_to_5chan[j]];
}
}
} }
else else
{ {