diff options
author | Bartlomiej Moskal <bartlomiej.moskal@qt.io> | 2023-10-05 12:26:16 +0200 |
---|---|---|
committer | Qt Cherry-pick Bot <cherrypick_bot@qt-project.org> | 2023-10-05 23:10:43 +0000 |
commit | 7e1319a9bffda67b80a13db036faf123e58d1715 (patch) | |
tree | 060c312fcf31d61e1025a4c7e8065187453eb45c | |
parent | e382b2d12117893a87b015b7990a8be9e57f0f6e (diff) |
Android: Support more audio channels
The audio player configuraion (using OpenSL ES), expects channel mask to
be correctly set according the number of audio channels.
Before this change, channel mask was set to SL_SPEAKER_FRONT_CENTER (for
one channel) and to SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT for
more than one. That didn't work if there were more than two channels.
Configuration finishes with errors (for 6 channels):
E libOpenSLES: pAudioSrc: requested 6 channels but mask (0x3) has
2 channel bits set
W libOpenSLES: Leaving Engine::CreateAudioPlayer
(SL_RESULT_PARAMETER_INVALID)
W libapplearnplayer_armeabi-v7a.so: Unable to create AudioPlayer
We should handle more than 2 audio channels. To do that, channel mask
need to be correctly set.
Fixes: QTBUG-115444
Change-Id: I145a0068f7815edf67afcdf484cc41a046c71a0a
Reviewed-by: Artem Dyomin <artem.dyomin@qt.io>
(cherry picked from commit 10864c9b1f230c36d9ba6c497b2e8a38a279ceb4)
Reviewed-by: Qt Cherry-pick Bot <cherrypick_bot@qt-project.org>
(cherry picked from commit db1b01ef68a398b76d2f0c208705a20bcd703be9)
-rw-r--r-- | src/multimedia/android/qopenslesengine.cpp | 20 |
1 files changed, 17 insertions, 3 deletions
diff --git a/src/multimedia/android/qopenslesengine.cpp b/src/multimedia/android/qopenslesengine.cpp index 01a6828ba..90fa86a6f 100644 --- a/src/multimedia/android/qopenslesengine.cpp +++ b/src/multimedia/android/qopenslesengine.cpp @@ -47,6 +47,22 @@ QOpenSLESEngine *QOpenSLESEngine::instance() return openslesEngine(); } +static SLuint32 getChannelMask(unsigned channelCount) +{ + switch (channelCount) { + case 1: return SL_SPEAKER_FRONT_CENTER; + case 2: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; + case 3: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER; + case 4: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT + | SL_SPEAKER_BACK_LEFT | SL_SPEAKER_BACK_RIGHT; + case 5: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT + | SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_FRONT_CENTER; + case 6: return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_BACK_LEFT + | SL_SPEAKER_BACK_RIGHT | SL_SPEAKER_FRONT_CENTER | SL_SPEAKER_LOW_FREQUENCY; + default: return 0; // Default to 0 for an unsupported or unknown number of channels + } +} + SLAndroidDataFormat_PCM_EX QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudioFormat &format) { SLAndroidDataFormat_PCM_EX format_pcm; @@ -55,9 +71,7 @@ SLAndroidDataFormat_PCM_EX QOpenSLESEngine::audioFormatToSLFormatPCM(const QAudi format_pcm.sampleRate = format.sampleRate() * 1000; format_pcm.bitsPerSample = format.bytesPerSample() * 8; format_pcm.containerSize = format.bytesPerSample() * 8; - format_pcm.channelMask = (format.channelCount() == 1 ? - SL_SPEAKER_FRONT_CENTER : - SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT); + format_pcm.channelMask = getChannelMask(format_pcm.numChannels); format_pcm.endianness = (QSysInfo::ByteOrder == QSysInfo::LittleEndian ? SL_BYTEORDER_LITTLEENDIAN : SL_BYTEORDER_BIGENDIAN); |