opensles: generate channel masks safely by OS version
Indexed channel masks were not supported before N.
Fixes #117
diff --git a/src/opensles/AudioInputStreamOpenSLES.cpp b/src/opensles/AudioInputStreamOpenSLES.cpp
index 71e27a1..ec47ed2 100644
--- a/src/opensles/AudioInputStreamOpenSLES.cpp
+++ b/src/opensles/AudioInputStreamOpenSLES.cpp
@@ -57,9 +57,6 @@
AudioInputStreamOpenSLES::~AudioInputStreamOpenSLES() {
}
-#define AUDIO_CHANNEL_COUNT_MAX 30u
-#define SL_ANDROID_UNKNOWN_CHANNELMASK 0
-
int AudioInputStreamOpenSLES::chanCountToChanMask(int channelCount) {
// from internal sles_channel_in_mask_from_count(chanCount);
switch (channelCount) {
@@ -67,14 +64,8 @@
return SL_SPEAKER_FRONT_LEFT;
case 2:
return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT;
- default: {
- if (channelCount > AUDIO_CHANNEL_COUNT_MAX) {
- return SL_ANDROID_UNKNOWN_CHANNELMASK;
- } else {
- SLuint32 bitfield = (1 << channelCount) - 1;
- return SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(bitfield);
- }
- }
+ default:
+ return chanCountToChanMaskDefault(channelCount);
}
}
diff --git a/src/opensles/AudioOutputStreamOpenSLES.cpp b/src/opensles/AudioOutputStreamOpenSLES.cpp
index 749b509..cf0edaf 100644
--- a/src/opensles/AudioOutputStreamOpenSLES.cpp
+++ b/src/opensles/AudioOutputStreamOpenSLES.cpp
@@ -46,10 +46,10 @@
constexpr int SL_ANDROID_SPEAKER_7DOT1 = (SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_SIDE_LEFT
| SL_SPEAKER_SIDE_RIGHT);
-int AudioOutputStreamOpenSLES::chanCountToChanMask(int chanCount) {
+int AudioOutputStreamOpenSLES::chanCountToChanMask(int channelCount) {
int channelMask = 0;
- switch (chanCount) {
+ switch (channelCount) {
case 1:
channelMask = SL_SPEAKER_FRONT_CENTER;
break;
@@ -69,6 +69,10 @@
case 8: // 7.1
channelMask = SL_ANDROID_SPEAKER_7DOT1;
break;
+
+ default:
+ channelMask = chanCountToChanMaskDefault(channelCount);
+ break;
}
return channelMask;
}
diff --git a/src/opensles/AudioStreamOpenSLES.cpp b/src/opensles/AudioStreamOpenSLES.cpp
index 6ca4bbf..4a69760 100644
--- a/src/opensles/AudioStreamOpenSLES.cpp
+++ b/src/opensles/AudioStreamOpenSLES.cpp
@@ -49,6 +49,29 @@
delete[] mCallbackBuffer;
}
+#define AUDIO_CHANNEL_COUNT_MAX 30u
+#define SL_ANDROID_UNKNOWN_CHANNELMASK 0
+
+int AudioStreamOpenSLES::chanCountToChanMaskDefault(int channelCount) {
+ if (channelCount > AUDIO_CHANNEL_COUNT_MAX) {
+ return SL_ANDROID_UNKNOWN_CHANNELMASK;
+ } else {
+ SLuint32 bitfield = (1 << channelCount) - 1;
+// Check for NDK at compile-time.
+#if __ANDROID_API__ >= __ANDROID_API_N__
+ // Check for OS at run-time.
+ if(getSdkVersion() >= __ANDROID_API_N__) {
+ return SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(bitfield);
+ } else
+#endif
+ {
+ // Indexed channels masks were added in N.
+ // For before N, the best we can do is use a positional channel mask.
+ return bitfield;
+ }
+ }
+}
+
static bool s_isLittleEndian() {
static uint32_t value = 1;
return *((uint8_t *) &value) == 1; // Does address point to LSB?
diff --git a/src/opensles/AudioStreamOpenSLES.h b/src/opensles/AudioStreamOpenSLES.h
index da4eac3..be9a332 100644
--- a/src/opensles/AudioStreamOpenSLES.h
+++ b/src/opensles/AudioStreamOpenSLES.h
@@ -74,6 +74,8 @@
protected:
+ int chanCountToChanMaskDefault(int channelCount);
+
virtual Result onBeforeDestroy() { return Result::OK; };
virtual Result onAfterDestroy() { return Result::OK; };