Fix 5.1 channel mapping on Steam Link

This commit is contained in:
Cameron Gutman 2019-11-17 12:22:57 -08:00
parent 6059c982cf
commit 1febe32e73
4 changed files with 52 additions and 12 deletions

View File

@ -145,29 +145,34 @@ int Session::arInit(int /* audioConfiguration */,
SDL_memcpy(&s_ActiveSession->m_AudioConfig, opusConfig, sizeof(*opusConfig));
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer(&s_ActiveSession->m_AudioConfig);
if (s_ActiveSession->m_AudioRenderer == nullptr) {
return -2;
}
// Allow the chosen renderer to remap Opus channels as needed to ensure proper output
s_ActiveSession->m_AudioRenderer->remapChannels(&s_ActiveSession->m_AudioConfig);
// Create the Opus decoder with the renderer's preferred channel mapping
s_ActiveSession->m_OpusDecoder =
opus_multistream_decoder_create(opusConfig->sampleRate,
opusConfig->channelCount,
opusConfig->streams,
opusConfig->coupledStreams,
opusConfig->mapping,
opus_multistream_decoder_create(s_ActiveSession->m_AudioConfig.sampleRate,
s_ActiveSession->m_AudioConfig.channelCount,
s_ActiveSession->m_AudioConfig.streams,
s_ActiveSession->m_AudioConfig.coupledStreams,
s_ActiveSession->m_AudioConfig.mapping,
&error);
if (s_ActiveSession->m_OpusDecoder == NULL) {
delete s_ActiveSession->m_AudioRenderer;
s_ActiveSession->m_AudioRenderer = nullptr;
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
"Failed to create decoder: %d",
error);
return -1;
}
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer(opusConfig);
if (s_ActiveSession->m_AudioRenderer == nullptr) {
opus_multistream_decoder_destroy(s_ActiveSession->m_OpusDecoder);
return -2;
}
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
"Audio stream has %d channels",
opusConfig->channelCount);
s_ActiveSession->m_AudioConfig.channelCount);
return 0;
}

View File

@ -15,4 +15,14 @@ public:
virtual bool submitAudio(int bytesWritten) = 0;
virtual int getCapabilities() = 0;
virtual void remapChannels(POPUS_MULTISTREAM_CONFIGURATION) {
// Use default channel mapping:
// 0 - Front Left
// 1 - Front Right
// 2 - Center
// 3 - LFE
// 4 - Surround Left
// 5 - Surround Right
}
};

View File

@ -43,6 +43,29 @@ bool SLAudioRenderer::prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* o
return true;
}
#define SWAP_CHANNEL(i, j) \
tmp = opusConfig->mapping[i]; \
opusConfig->mapping[i] = opusConfig->mapping[j]; \
opusConfig->mapping[j] = tmp
void SLAudioRenderer::remapChannels(POPUS_MULTISTREAM_CONFIGURATION opusConfig) {
unsigned char tmp;
if (opusConfig->channelCount == 6) {
// The Moonlight's default channel order is FL,FR,C,LFE,RL,RR
// SLAudio expects FL,C,FR,RL,RR,LFE so we swap the channels around to match
// Swap FR and C - now FL,C,FR,LFE,RL,RR
SWAP_CHANNEL(1, 2);
// Swap LFE and RR - now FL,C,FR,RR,RL,LFE
SWAP_CHANNEL(3, 5);
// Swap RR and RL - now FL,C,FR,RL,RR,LFE
SWAP_CHANNEL(4, 5);
}
}
void* SLAudioRenderer::getAudioBuffer(int* size)
{
SDL_assert(*size == m_AudioBufferSize);

View File

@ -18,6 +18,8 @@ public:
virtual int getCapabilities();
virtual void remapChannels(POPUS_MULTISTREAM_CONFIGURATION opusConfig);
private:
static void slLogCallback(void* context, ESLAudioLog logLevel, const char* message);