1ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten/* 2ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * Copyright (C) 2015 The Android Open Source Project 3ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * 4ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License"); 5ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * you may not use this file except in compliance with the License. 6ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * You may obtain a copy of the License at 7ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * 8ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * http://www.apache.org/licenses/LICENSE-2.0 9ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * 10ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * Unless required by applicable law or agreed to in writing, software 11ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS, 12ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * See the License for the specific language governing permissions and 14ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten * limitations under the License. 15ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten */ 16ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten 174e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include "sles_allinclusive.h" 18680943a4c349712f641b7577e5b0a3fdf49e39d9Glenn Kasten#include <system/audio.h> 194e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean#include <SLES/OpenSLES_Android.h> 20ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten#include "channels.h" 21ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten 224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Return the default OpenSL ES output channel mask (as used in SLDataFormat_PCM.channelMask) 254e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * for the specified channel count. 264e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * 274e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * OpenSL ES makes no distinction between input and output channel masks, but 284e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Android does. This is the OUTPUT version of this function. 294e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 304e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanSLuint32 sles_channel_out_mask_from_count(unsigned channelCount) 31ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten{ 32ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten // FIXME channel mask is not yet implemented by Stagefright, so use a reasonable default 33ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten // that is computed from the channel count 34680943a4c349712f641b7577e5b0a3fdf49e39d9Glenn Kasten if (channelCount > FCC_8) { 354e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_ANDROID_UNKNOWN_CHANNELMASK; 36680943a4c349712f641b7577e5b0a3fdf49e39d9Glenn Kasten } 37ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten switch (channelCount) { 38ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten case 1: 39ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten // see explanation in data.c re: default channel mask for mono 40ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten return SL_SPEAKER_FRONT_LEFT; 41ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten case 2: 42ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 43ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten // Android-specific 4484bbadf848f606ff28273baf26fc246cf967059aAndy Hung case 3: 4584bbadf848f606ff28273baf26fc246cf967059aAndy Hung return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER; 46ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten case 4: 47ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten return SL_ANDROID_SPEAKER_QUAD; 4884bbadf848f606ff28273baf26fc246cf967059aAndy Hung case 5: 4984bbadf848f606ff28273baf26fc246cf967059aAndy Hung return SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER; 50ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten case 6: 51ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten return SL_ANDROID_SPEAKER_5DOT1; 5284bbadf848f606ff28273baf26fc246cf967059aAndy Hung case 7: 5384bbadf848f606ff28273baf26fc246cf967059aAndy Hung return SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER; 54ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten case 8: 55ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten return SL_ANDROID_SPEAKER_7DOT1; 564e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // FIXME FCC_8 57ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten default: 584e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_ANDROID_UNKNOWN_CHANNELMASK; 594e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 604e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 614e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 624e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 634e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Return the default OpenSL ES input channel mask (as used in SLDataFormat_PCM.channelMask) 644e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * for the specified channel count. 654e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * 664e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * OpenSL ES makes no distinction between input and output channel masks, but 674e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Android does. This is the INPUT version of this function. 684e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 694e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanSLuint32 sles_channel_in_mask_from_count(unsigned channelCount) { 704e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean switch (channelCount) { 714e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean case 1: 724e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_SPEAKER_FRONT_LEFT; 734e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean case 2: 744e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 754e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean default: { 764e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (channelCount > AUDIO_CHANNEL_COUNT_MAX) { 774e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_ANDROID_UNKNOWN_CHANNELMASK; 784e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else { 794e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 bitfield = (1 << channelCount) - 1; 804e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(bitfield); 814e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 824e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 834e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 844e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 854e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 864e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 874e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 884e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Get the number of active channels in an OpenSL ES channel mask. 894e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * 904e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * This function is valid for both input and output 914e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * masks. 924e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 934e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanSLuint32 sles_channel_count_from_mask(SLuint32 mask) { 944e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean audio_channel_representation_t rep 954e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean = sles_to_audio_channel_mask_representation(mask); 964e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 974e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (rep == AUDIO_CHANNEL_REPRESENTATION_INDEX) { 984e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean mask &= SL_ANDROID_INDEXED_SPEAKER_MASK_ALL; 994e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return popcount(mask); 1004e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else if (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION){ 1014e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean mask &= SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 1024e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return popcount(mask); 1034e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else { 1044e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return 0; 1054e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1064e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 1074e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1084e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 1094e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Helper to determine whether a channel mask is indexed or not. 1104e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * 1114e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * This is the OpenSL ES analog to audio_channel_mask_get_representation(). 1124e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 1134e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanaudio_channel_representation_t sles_to_audio_channel_mask_representation(SLuint32 mask) { 1144e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (mask & SL_ANDROID_SPEAKER_NON_POSITIONAL) { 1154e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return AUDIO_CHANNEL_REPRESENTATION_INDEX; 1164e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else { 1174e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return AUDIO_CHANNEL_REPRESENTATION_POSITION; 1184e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1194e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 1204e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1214e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// helper struct for the two static arrays which follow. 1224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstruct channel_map { 1234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 sles; 1244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean audio_channel_mask_t android; 1254e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean}; 1264e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1274e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// In practice this map is unnecessary, because the SL definitions just 1284e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// happen to match the android definitions perfectly, but we can't rely 1294e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// on that fact since the two sets of definitions have different API 1304e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// contracts. 1314e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstatic const struct channel_map output_map[] = { 1324e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_LEFT, AUDIO_CHANNEL_OUT_FRONT_LEFT }, 1334e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_RIGHT, AUDIO_CHANNEL_OUT_FRONT_RIGHT }, 1344e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_CENTER, AUDIO_CHANNEL_OUT_FRONT_CENTER }, 1354e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_LOW_FREQUENCY, AUDIO_CHANNEL_OUT_LOW_FREQUENCY }, 1364e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_BACK_LEFT, AUDIO_CHANNEL_OUT_BACK_LEFT }, 1374e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_BACK_RIGHT, AUDIO_CHANNEL_OUT_BACK_RIGHT }, 1384e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_LEFT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER }, 1394e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_RIGHT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER }, 1404e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_BACK_CENTER, AUDIO_CHANNEL_OUT_BACK_CENTER }, 1414e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_SIDE_LEFT, AUDIO_CHANNEL_OUT_SIDE_LEFT }, 1424e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_SIDE_RIGHT, AUDIO_CHANNEL_OUT_SIDE_RIGHT }, 1434e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_CENTER, AUDIO_CHANNEL_OUT_TOP_CENTER }, 1444e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_FRONT_LEFT, AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT }, 1454e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_FRONT_CENTER, AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER }, 1464e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_FRONT_RIGHT, AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT }, 1474e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_BACK_LEFT, AUDIO_CHANNEL_OUT_TOP_BACK_LEFT }, 1484e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_BACK_CENTER, AUDIO_CHANNEL_OUT_TOP_BACK_CENTER }, 1494e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_TOP_BACK_RIGHT, AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT }, 1504e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean}; 1514e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstatic const unsigned int nOutputChannelMappings = sizeof(output_map) / sizeof(output_map[0]); 1524e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1534e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// This map is quite sparse, because there really isn't a reasonable mapping 1544e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// between most of the SL_SPEAKER bits and the android input map. It's probably 1554e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// best to use channel indices instead. 1564e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstatic const struct channel_map input_map[] = { 1574e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_LEFT, AUDIO_CHANNEL_IN_LEFT }, 1584e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean { SL_SPEAKER_FRONT_RIGHT, AUDIO_CHANNEL_IN_RIGHT }, 1594e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean}; 1604e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstatic const unsigned int nInputChannelMappings = sizeof(input_map) / sizeof(input_map[0]); 1614e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1624e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean// Core channel mask mapper; implementation common to both input and output 1634e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanstatic audio_channel_mask_t sles_to_android_mask_helper( 1644e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 mask, 1654e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean const struct channel_map* map, 1664e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean unsigned int nMappings) { 1674e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (!sles_is_channel_mask_valid(mask)) { 1684e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGW("Channel mask %#x is invalid because it uses bits that are undefined.", mask); 1694e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return AUDIO_CHANNEL_INVALID; 1704e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1714e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1724e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // determine whether this mask uses positional or indexed representation 1734e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean audio_channel_representation_t rep = sles_to_audio_channel_mask_representation(mask); 1744e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 1754e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean uint32_t bitsOut = 0; 1764e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean uint32_t bitsIn = mask; 1774e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (rep == AUDIO_CHANNEL_REPRESENTATION_INDEX) { 1784e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // Indexed masks need no mapping 1794e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean bitsIn &= SL_ANDROID_INDEXED_SPEAKER_MASK_ALL; 1804e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean bitsOut = bitsIn; 1814e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else if (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION){ 1824e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // positional masks get mapped from OpenSLES speaker definitions 1834e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // to the channel definitions we use internally. 1844e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean bitsIn &= SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 1854e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean for (unsigned int i = 0; i < nMappings; ++i) { 1864e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (bitsIn & map[i].sles) { 1874e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean bitsOut |= map[i].android; 1884e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1894e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1904e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else { 1914e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SL_LOGE("Unrecognized channel representation %#x", rep); 1924e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 1934e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 19433f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis uint32_t result = audio_channel_mask_from_representation_and_bits( 19533f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis rep, 19633f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis bitsOut); 19733f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis 1984e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (popcount(bitsIn) != popcount(bitsOut)) { 1994e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // At this point mask has already been stripped of the 2004e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // representation bitsOut, so its bitcount should equal the number 2014e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // of channels requested. If the bitcount of 'bitsOut' isn't 2024e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // the same, then we're unable to provide the number of 2034e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // channels that the app requested. That will cause an 2044e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // error downstream if the app doesn't correct it, so 2054e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean // issue a warning here. 20633f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis SL_LOGW("Conversion from OpenSL ES %s channel mask %#x to Android mask %#x %s channels", 20733f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION) ? "positional" : "indexed", 2084e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean mask, 20933f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis result, 21033f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis (popcount(bitsIn) < popcount(bitsOut)) ? "gains" : "loses"); 2114e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } 2124e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 21333f46b8cd9ece650736a4aa5294318c6b51b2ffdilewis return result; 2144e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 2154e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 2164e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 2174e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Return an android output channel mask, as used in the AudioTrack constructor. 2184e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 2194e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanaudio_channel_mask_t sles_to_audio_output_channel_mask(SLuint32 mask) { 2204e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return sles_to_android_mask_helper(mask, output_map, nOutputChannelMappings); 2214e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 2224e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 2234e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 2244e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Return an android input channel mask, as used in the AudioRecord constructor. 2254e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 2264e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanaudio_channel_mask_t sles_to_audio_input_channel_mask(SLuint32 mask) { 2274e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return sles_to_android_mask_helper(mask, input_map, nInputChannelMappings); 2284e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean} 2294e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean 2304e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean/* 2314e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Check the mask for undefined bits (that is, set bits that don't correspond to a channel). 2324e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * 2334e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean * Returns SL_BOOLEAN_TRUE if no undefined bits are set; SL_BOOLEAN_FALSE otherwise. 2344e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean */ 2354e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLeanSLboolean sles_is_channel_mask_valid(SLuint32 mask) { 2364e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean SLuint32 undefinedMask; 2374e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean if (sles_to_audio_channel_mask_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_POSITION) { 2384e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean undefinedMask = ~SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 2394e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean } else { 2404e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean undefinedMask 2414e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean = ~(SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(SL_ANDROID_INDEXED_SPEAKER_MASK_ALL)); 242ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten } 2434e8fe8a60c3aa8085918f15f281e0979682aefdcPaul McLean return (mask & undefinedMask) ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE; 244ff25010cb77455a46357d6dd012631a2599d7bf4Glenn Kasten} 245