1 /* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #include "sles_allinclusive.h" 18 #include <cutils/bitops.h> 19 #include <system/audio.h> 20 #include <SLES/OpenSLES_Android.h> 21 #include "channels.h" 22 23 24 /* 25 * Return the default OpenSL ES output channel mask (as used in SLDataFormat_PCM.channelMask) 26 * for the specified channel count. 27 * 28 * OpenSL ES makes no distinction between input and output channel masks, but 29 * Android does. This is the OUTPUT version of this function. 30 */ 31 SLuint32 sles_channel_out_mask_from_count(unsigned channelCount) 32 { 33 // FIXME channel mask is not yet implemented by Stagefright, so use a reasonable default 34 // that is computed from the channel count 35 if (channelCount > FCC_8) { 36 return SL_ANDROID_UNKNOWN_CHANNELMASK; 37 } 38 switch (channelCount) { 39 case 1: 40 // see explanation in data.c re: default channel mask for mono 41 return SL_SPEAKER_FRONT_LEFT; 42 case 2: 43 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 44 // Android-specific 45 case 3: 46 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT | SL_SPEAKER_FRONT_CENTER; 47 case 4: 48 return SL_ANDROID_SPEAKER_QUAD; 49 case 5: 50 return SL_ANDROID_SPEAKER_QUAD | SL_SPEAKER_FRONT_CENTER; 51 case 6: 52 return SL_ANDROID_SPEAKER_5DOT1; 53 case 7: 54 return SL_ANDROID_SPEAKER_5DOT1 | SL_SPEAKER_BACK_CENTER; 55 case 8: 56 return SL_ANDROID_SPEAKER_7DOT1; 57 // FIXME FCC_8 58 default: 59 return SL_ANDROID_UNKNOWN_CHANNELMASK; 60 } 61 } 62 63 /* 64 * Return the default OpenSL ES input channel mask (as used in SLDataFormat_PCM.channelMask) 65 * for the specified channel count. 66 * 67 * OpenSL ES makes no distinction between input and output channel masks, but 68 * Android does. This is the INPUT version of this function. 69 */ 70 SLuint32 sles_channel_in_mask_from_count(unsigned channelCount) { 71 switch (channelCount) { 72 case 1: 73 return SL_SPEAKER_FRONT_LEFT; 74 case 2: 75 return SL_SPEAKER_FRONT_LEFT | SL_SPEAKER_FRONT_RIGHT; 76 default: { 77 if (channelCount > AUDIO_CHANNEL_COUNT_MAX) { 78 return SL_ANDROID_UNKNOWN_CHANNELMASK; 79 } else { 80 SLuint32 bitfield = (1 << channelCount) - 1; 81 return SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(bitfield); 82 } 83 } 84 85 } 86 } 87 88 /* 89 * Get the number of active channels in an OpenSL ES channel mask. 90 * 91 * This function is valid for both input and output 92 * masks. 93 */ 94 SLuint32 sles_channel_count_from_mask(SLuint32 mask) { 95 audio_channel_representation_t rep 96 = sles_to_audio_channel_mask_representation(mask); 97 98 if (rep == AUDIO_CHANNEL_REPRESENTATION_INDEX) { 99 mask &= SL_ANDROID_INDEXED_SPEAKER_MASK_ALL; 100 return popcount(mask); 101 } else if (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION){ 102 mask &= SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 103 return popcount(mask); 104 } else { 105 return 0; 106 } 107 } 108 109 /* 110 * Helper to determine whether a channel mask is indexed or not. 111 * 112 * This is the OpenSL ES analog to audio_channel_mask_get_representation(). 113 */ 114 audio_channel_representation_t sles_to_audio_channel_mask_representation(SLuint32 mask) { 115 if (mask & SL_ANDROID_SPEAKER_NON_POSITIONAL) { 116 return AUDIO_CHANNEL_REPRESENTATION_INDEX; 117 } else { 118 return AUDIO_CHANNEL_REPRESENTATION_POSITION; 119 } 120 } 121 122 // helper struct for the two static arrays which follow. 123 struct channel_map { 124 SLuint32 sles; 125 audio_channel_mask_t android; 126 }; 127 128 // In practice this map is unnecessary, because the SL definitions just 129 // happen to match the android definitions perfectly, but we can't rely 130 // on that fact since the two sets of definitions have different API 131 // contracts. 132 static const struct channel_map output_map[] = { 133 { SL_SPEAKER_FRONT_LEFT, AUDIO_CHANNEL_OUT_FRONT_LEFT }, 134 { SL_SPEAKER_FRONT_RIGHT, AUDIO_CHANNEL_OUT_FRONT_RIGHT }, 135 { SL_SPEAKER_FRONT_CENTER, AUDIO_CHANNEL_OUT_FRONT_CENTER }, 136 { SL_SPEAKER_LOW_FREQUENCY, AUDIO_CHANNEL_OUT_LOW_FREQUENCY }, 137 { SL_SPEAKER_BACK_LEFT, AUDIO_CHANNEL_OUT_BACK_LEFT }, 138 { SL_SPEAKER_BACK_RIGHT, AUDIO_CHANNEL_OUT_BACK_RIGHT }, 139 { SL_SPEAKER_FRONT_LEFT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_LEFT_OF_CENTER }, 140 { SL_SPEAKER_FRONT_RIGHT_OF_CENTER, AUDIO_CHANNEL_OUT_FRONT_RIGHT_OF_CENTER }, 141 { SL_SPEAKER_BACK_CENTER, AUDIO_CHANNEL_OUT_BACK_CENTER }, 142 { SL_SPEAKER_SIDE_LEFT, AUDIO_CHANNEL_OUT_SIDE_LEFT }, 143 { SL_SPEAKER_SIDE_RIGHT, AUDIO_CHANNEL_OUT_SIDE_RIGHT }, 144 { SL_SPEAKER_TOP_CENTER, AUDIO_CHANNEL_OUT_TOP_CENTER }, 145 { SL_SPEAKER_TOP_FRONT_LEFT, AUDIO_CHANNEL_OUT_TOP_FRONT_LEFT }, 146 { SL_SPEAKER_TOP_FRONT_CENTER, AUDIO_CHANNEL_OUT_TOP_FRONT_CENTER }, 147 { SL_SPEAKER_TOP_FRONT_RIGHT, AUDIO_CHANNEL_OUT_TOP_FRONT_RIGHT }, 148 { SL_SPEAKER_TOP_BACK_LEFT, AUDIO_CHANNEL_OUT_TOP_BACK_LEFT }, 149 { SL_SPEAKER_TOP_BACK_CENTER, AUDIO_CHANNEL_OUT_TOP_BACK_CENTER }, 150 { SL_SPEAKER_TOP_BACK_RIGHT, AUDIO_CHANNEL_OUT_TOP_BACK_RIGHT }, 151 }; 152 static const unsigned int nOutputChannelMappings = sizeof(output_map) / sizeof(output_map[0]); 153 154 // This map is quite sparse, because there really isn't a reasonable mapping 155 // between most of the SL_SPEAKER bits and the android input map. It's probably 156 // best to use channel indices instead. 157 static const struct channel_map input_map[] = { 158 { SL_SPEAKER_FRONT_LEFT, AUDIO_CHANNEL_IN_LEFT }, 159 { SL_SPEAKER_FRONT_RIGHT, AUDIO_CHANNEL_IN_RIGHT }, 160 }; 161 static const unsigned int nInputChannelMappings = sizeof(input_map) / sizeof(input_map[0]); 162 163 // Core channel mask mapper; implementation common to both input and output 164 static audio_channel_mask_t sles_to_android_mask_helper( 165 SLuint32 mask, 166 const struct channel_map* map, 167 unsigned int nMappings) { 168 if (!sles_is_channel_mask_valid(mask)) { 169 SL_LOGW("Channel mask %#x is invalid because it uses bits that are undefined.", mask); 170 return AUDIO_CHANNEL_INVALID; 171 } 172 173 // determine whether this mask uses positional or indexed representation 174 audio_channel_representation_t rep = sles_to_audio_channel_mask_representation(mask); 175 176 uint32_t bitsOut = 0; 177 uint32_t bitsIn = mask; 178 if (rep == AUDIO_CHANNEL_REPRESENTATION_INDEX) { 179 // Indexed masks need no mapping 180 bitsIn &= SL_ANDROID_INDEXED_SPEAKER_MASK_ALL; 181 bitsOut = bitsIn; 182 } else if (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION){ 183 // positional masks get mapped from OpenSLES speaker definitions 184 // to the channel definitions we use internally. 185 bitsIn &= SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 186 for (unsigned int i = 0; i < nMappings; ++i) { 187 if (bitsIn & map[i].sles) { 188 bitsOut |= map[i].android; 189 } 190 } 191 } else { 192 SL_LOGE("Unrecognized channel representation %#x", rep); 193 } 194 195 audio_channel_mask_t result = audio_channel_mask_from_representation_and_bits( 196 rep, 197 bitsOut); 198 199 if (popcount(bitsIn) != popcount(bitsOut)) { 200 // At this point mask has already been stripped of the 201 // representation bitsOut, so its bitcount should equal the number 202 // of channels requested. If the bitcount of 'bitsOut' isn't 203 // the same, then we're unable to provide the number of 204 // channels that the app requested. That will cause an 205 // error downstream if the app doesn't correct it, so 206 // issue a warning here. 207 SL_LOGW("Conversion from OpenSL ES %s channel mask %#x to Android mask %#x %s channels", 208 (rep == AUDIO_CHANNEL_REPRESENTATION_POSITION) ? "positional" : "indexed", 209 mask, 210 result, 211 (popcount(bitsIn) < popcount(bitsOut)) ? "gains" : "loses"); 212 } 213 214 return result; 215 } 216 217 /* 218 * Return an android output channel mask, as used in the AudioTrack constructor. 219 */ 220 audio_channel_mask_t sles_to_audio_output_channel_mask(SLuint32 mask) { 221 return sles_to_android_mask_helper(mask, output_map, nOutputChannelMappings); 222 } 223 224 /* 225 * Return an android input channel mask, as used in the AudioRecord constructor. 226 */ 227 audio_channel_mask_t sles_to_audio_input_channel_mask(SLuint32 mask) { 228 return sles_to_android_mask_helper(mask, input_map, nInputChannelMappings); 229 } 230 231 /* 232 * Check the mask for undefined bits (that is, set bits that don't correspond to a channel). 233 * 234 * Returns SL_BOOLEAN_TRUE if no undefined bits are set; SL_BOOLEAN_FALSE otherwise. 235 */ 236 SLboolean sles_is_channel_mask_valid(SLuint32 mask) { 237 SLuint32 undefinedMask; 238 if (sles_to_audio_channel_mask_representation(mask) == AUDIO_CHANNEL_REPRESENTATION_POSITION) { 239 undefinedMask = ~SL_ANDROID_POSITIONAL_SPEAKER_MASK_ALL; 240 } else { 241 undefinedMask 242 = ~(SL_ANDROID_MAKE_INDEXED_CHANNEL_MASK(SL_ANDROID_INDEXED_SPEAKER_MASK_ALL)); 243 } 244 return (mask & undefinedMask) ? SL_BOOLEAN_FALSE : SL_BOOLEAN_TRUE; 245 } 246