mirror of
https://github.com/moonlight-stream/moonlight-qt
synced 2024-12-14 05:12:27 +00:00
Fix surround sound channel mapping on ALSA
This commit is contained in:
parent
b14a0fa2ce
commit
209b4a1b02
6 changed files with 58 additions and 7 deletions
|
@ -59,23 +59,27 @@ int Session::arInit(int /* audioConfiguration */,
|
||||||
|
|
||||||
SDL_memcpy(&s_ActiveSession->m_AudioConfig, opusConfig, sizeof(*opusConfig));
|
SDL_memcpy(&s_ActiveSession->m_AudioConfig, opusConfig, sizeof(*opusConfig));
|
||||||
|
|
||||||
|
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer();
|
||||||
|
if (s_ActiveSession->m_AudioRenderer == nullptr) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Allow the audio renderer to adjust the channel mapping to fit its
|
||||||
|
// preferred channel order
|
||||||
|
s_ActiveSession->m_AudioRenderer->adjustOpusChannelMapping(&s_ActiveSession->m_AudioConfig);
|
||||||
|
|
||||||
s_ActiveSession->m_OpusDecoder =
|
s_ActiveSession->m_OpusDecoder =
|
||||||
opus_multistream_decoder_create(opusConfig->sampleRate,
|
opus_multistream_decoder_create(opusConfig->sampleRate,
|
||||||
opusConfig->channelCount,
|
opusConfig->channelCount,
|
||||||
opusConfig->streams,
|
opusConfig->streams,
|
||||||
opusConfig->coupledStreams,
|
opusConfig->coupledStreams,
|
||||||
opusConfig->mapping,
|
s_ActiveSession->m_AudioConfig.mapping,
|
||||||
&error);
|
&error);
|
||||||
if (s_ActiveSession->m_OpusDecoder == NULL) {
|
if (s_ActiveSession->m_OpusDecoder == NULL) {
|
||||||
|
delete s_ActiveSession->m_AudioRenderer;
|
||||||
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
"Failed to create decoder: %d",
|
"Failed to create decoder: %d",
|
||||||
error);
|
error);
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
s_ActiveSession->m_AudioRenderer = s_ActiveSession->createAudioRenderer();
|
|
||||||
if (s_ActiveSession->m_AudioRenderer == nullptr) {
|
|
||||||
opus_multistream_decoder_destroy(s_ActiveSession->m_OpusDecoder);
|
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -194,6 +194,42 @@ int PortAudioRenderer::detectAudioConfiguration() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PortAudioRenderer::adjustOpusChannelMapping(OPUS_MULTISTREAM_CONFIGURATION* opusConfig) const
|
||||||
|
{
|
||||||
|
const OPUS_MULTISTREAM_CONFIGURATION origConfig = *opusConfig;
|
||||||
|
|
||||||
|
const PaDeviceInfo* deviceInfo = Pa_GetDeviceInfo(Pa_GetDefaultOutputDevice());
|
||||||
|
if (deviceInfo == nullptr) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Pa_GetDeviceInfo() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const PaHostApiInfo* hostApiInfo = Pa_GetHostApiInfo(deviceInfo->hostApi);
|
||||||
|
if (hostApiInfo == nullptr) {
|
||||||
|
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"Pa_GetHostApiInfo() failed");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_LogInfo(SDL_LOG_CATEGORY_APPLICATION,
|
||||||
|
"PortAudio host API: %s",
|
||||||
|
hostApiInfo->name);
|
||||||
|
|
||||||
|
if (hostApiInfo->type == paALSA) {
|
||||||
|
// The default mapping array has is: FL-FR-C-LFE-RL-RR
|
||||||
|
// ALSA expects: FL-FR-RL-RR-C-LFE
|
||||||
|
opusConfig->mapping[0] = origConfig.mapping[0];
|
||||||
|
opusConfig->mapping[1] = origConfig.mapping[1];
|
||||||
|
if (opusConfig->channelCount == 6) {
|
||||||
|
opusConfig->mapping[2] = origConfig.mapping[4];
|
||||||
|
opusConfig->mapping[3] = origConfig.mapping[5];
|
||||||
|
opusConfig->mapping[4] = origConfig.mapping[2];
|
||||||
|
opusConfig->mapping[5] = origConfig.mapping[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int PortAudioRenderer::paStreamCallback(const void*, void* output, unsigned long frameCount, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* userData)
|
int PortAudioRenderer::paStreamCallback(const void*, void* output, unsigned long frameCount, const PaStreamCallbackTimeInfo*, PaStreamCallbackFlags, void* userData)
|
||||||
{
|
{
|
||||||
auto me = reinterpret_cast<PortAudioRenderer*>(userData);
|
auto me = reinterpret_cast<PortAudioRenderer*>(userData);
|
||||||
|
|
|
@ -24,6 +24,8 @@ public:
|
||||||
|
|
||||||
virtual int detectAudioConfiguration() const;
|
virtual int detectAudioConfiguration() const;
|
||||||
|
|
||||||
|
virtual void adjustOpusChannelMapping(OPUS_MULTISTREAM_CONFIGURATION* opusConfig) const;
|
||||||
|
|
||||||
static int paStreamCallback(const void *input,
|
static int paStreamCallback(const void *input,
|
||||||
void *output,
|
void *output,
|
||||||
unsigned long frameCount,
|
unsigned long frameCount,
|
||||||
|
|
|
@ -10,6 +10,8 @@ class IAudioRenderer
|
||||||
public:
|
public:
|
||||||
virtual ~IAudioRenderer() {}
|
virtual ~IAudioRenderer() {}
|
||||||
|
|
||||||
|
virtual void adjustOpusChannelMapping(OPUS_MULTISTREAM_CONFIGURATION* opusConfig) const = 0;
|
||||||
|
|
||||||
virtual bool prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* opusConfig) = 0;
|
virtual bool prepareForPlayback(const OPUS_MULTISTREAM_CONFIGURATION* opusConfig) = 0;
|
||||||
|
|
||||||
virtual void submitAudio(short* audioBuffer, int audioSize) = 0;
|
virtual void submitAudio(short* audioBuffer, int audioSize) = 0;
|
||||||
|
|
|
@ -23,6 +23,8 @@ public:
|
||||||
|
|
||||||
virtual int detectAudioConfiguration() const;
|
virtual int detectAudioConfiguration() const;
|
||||||
|
|
||||||
|
virtual void adjustOpusChannelMapping(OPUS_MULTISTREAM_CONFIGURATION* opusConfig) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SDL_AudioDeviceID m_AudioDevice;
|
SDL_AudioDeviceID m_AudioDevice;
|
||||||
Uint32 m_ChannelCount;
|
Uint32 m_ChannelCount;
|
||||||
|
|
|
@ -51,6 +51,11 @@ int SdlAudioRenderer::detectAudioConfiguration() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SdlAudioRenderer::adjustOpusChannelMapping(OPUS_MULTISTREAM_CONFIGURATION*) const
|
||||||
|
{
|
||||||
|
// The default mapping is fine for SDL
|
||||||
|
}
|
||||||
|
|
||||||
bool SdlAudioRenderer::testAudio(int audioConfiguration) const
|
bool SdlAudioRenderer::testAudio(int audioConfiguration) const
|
||||||
{
|
{
|
||||||
SDL_AudioSpec want, have;
|
SDL_AudioSpec want, have;
|
||||||
|
|
Loading…
Reference in a new issue