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