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 #define LOG_TAG "APM::AudioPort" 18 //#define LOG_NDEBUG 0 19 #include "TypeConverter.h" 20 #include "AudioPort.h" 21 #include "HwModule.h" 22 #include "AudioGain.h" 23 #include <policy.h> 24 25 #ifndef ARRAY_SIZE 26 #define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0])) 27 #endif 28 29 namespace android { 30 31 int32_t volatile AudioPort::mNextUniqueId = 1; 32 33 // --- AudioPort class implementation 34 void AudioPort::attach(const sp<HwModule>& module) 35 { 36 mModule = module; 37 } 38 39 // Note that is a different namespace than AudioFlinger unique IDs 40 audio_port_handle_t AudioPort::getNextUniqueId() 41 { 42 return static_cast<audio_port_handle_t>(android_atomic_inc(&mNextUniqueId)); 43 } 44 45 audio_module_handle_t AudioPort::getModuleHandle() const 46 { 47 if (mModule == 0) { 48 return AUDIO_MODULE_HANDLE_NONE; 49 } 50 return mModule->mHandle; 51 } 52 53 uint32_t AudioPort::getModuleVersion() const 54 { 55 if (mModule == 0) { 56 return 0; 57 } 58 return mModule->getHalVersion(); 59 } 60 61 const char *AudioPort::getModuleName() const 62 { 63 if (mModule == 0) { 64 return "invalid module"; 65 } 66 return mModule->getName(); 67 } 68 69 void AudioPort::toAudioPort(struct audio_port *port) const 70 { 71 // TODO: update this function once audio_port structure reflects the new profile definition. 72 // For compatibility reason: flatening the AudioProfile into audio_port structure. 73 SortedVector<audio_format_t> flatenedFormats; 74 SampleRateVector flatenedRates; 75 ChannelsVector flatenedChannels; 76 for (size_t profileIndex = 0; profileIndex < mProfiles.size(); profileIndex++) { 77 if (mProfiles[profileIndex]->isValid()) { 78 audio_format_t formatToExport = mProfiles[profileIndex]->getFormat(); 79 const SampleRateVector &ratesToExport = mProfiles[profileIndex]->getSampleRates(); 80 const ChannelsVector &channelsToExport = mProfiles[profileIndex]->getChannels(); 81 82 if (flatenedFormats.indexOf(formatToExport) < 0) { 83 flatenedFormats.add(formatToExport); 84 } 85 for (size_t rateIndex = 0; rateIndex < ratesToExport.size(); rateIndex++) { 86 uint32_t rate = ratesToExport[rateIndex]; 87 if (flatenedRates.indexOf(rate) < 0) { 88 flatenedRates.add(rate); 89 } 90 } 91 for (size_t chanIndex = 0; chanIndex < channelsToExport.size(); chanIndex++) { 92 audio_channel_mask_t channels = channelsToExport[chanIndex]; 93 if (flatenedChannels.indexOf(channels) < 0) { 94 flatenedChannels.add(channels); 95 } 96 } 97 if (flatenedRates.size() > AUDIO_PORT_MAX_SAMPLING_RATES || 98 flatenedChannels.size() > AUDIO_PORT_MAX_CHANNEL_MASKS || 99 flatenedFormats.size() > AUDIO_PORT_MAX_FORMATS) { 100 ALOGE("%s: bailing out: cannot export profiles to port config", __FUNCTION__); 101 return; 102 } 103 } 104 } 105 port->role = mRole; 106 port->type = mType; 107 strlcpy(port->name, mName, AUDIO_PORT_MAX_NAME_LEN); 108 port->num_sample_rates = flatenedRates.size(); 109 port->num_channel_masks = flatenedChannels.size(); 110 port->num_formats = flatenedFormats.size(); 111 for (size_t i = 0; i < flatenedRates.size(); i++) { 112 port->sample_rates[i] = flatenedRates[i]; 113 } 114 for (size_t i = 0; i < flatenedChannels.size(); i++) { 115 port->channel_masks[i] = flatenedChannels[i]; 116 } 117 for (size_t i = 0; i < flatenedFormats.size(); i++) { 118 port->formats[i] = flatenedFormats[i]; 119 } 120 121 ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); 122 123 uint32_t i; 124 for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { 125 port->gains[i] = mGains[i]->getGain(); 126 } 127 port->num_gains = i; 128 } 129 130 void AudioPort::importAudioPort(const sp<AudioPort> port) 131 { 132 size_t indexToImport; 133 for (indexToImport = 0; indexToImport < port->mProfiles.size(); indexToImport++) { 134 const sp<AudioProfile> &profileToImport = port->mProfiles[indexToImport]; 135 if (profileToImport->isValid()) { 136 // Import only valid port, i.e. valid format, non empty rates and channels masks 137 bool hasSameProfile = false; 138 for (size_t profileIndex = 0; profileIndex < mProfiles.size(); profileIndex++) { 139 if (*mProfiles[profileIndex] == *profileToImport) { 140 // never import a profile twice 141 hasSameProfile = true; 142 break; 143 } 144 } 145 if (hasSameProfile) { // never import a same profile twice 146 continue; 147 } 148 addAudioProfile(profileToImport); 149 } 150 } 151 } 152 153 void AudioPort::pickSamplingRate(uint32_t &pickedRate,const SampleRateVector &samplingRates) const 154 { 155 pickedRate = 0; 156 // For direct outputs, pick minimum sampling rate: this helps ensuring that the 157 // channel count / sampling rate combination chosen will be supported by the connected 158 // sink 159 if (isDirectOutput()) { 160 uint32_t samplingRate = UINT_MAX; 161 for (size_t i = 0; i < samplingRates.size(); i ++) { 162 if ((samplingRates[i] < samplingRate) && (samplingRates[i] > 0)) { 163 samplingRate = samplingRates[i]; 164 } 165 } 166 pickedRate = (samplingRate == UINT_MAX) ? 0 : samplingRate; 167 } else { 168 uint32_t maxRate = SAMPLE_RATE_HZ_MAX; 169 170 // For mixed output and inputs, use max mixer sampling rates. Do not 171 // limit sampling rate otherwise 172 // For inputs, also see checkCompatibleSamplingRate(). 173 if (mType != AUDIO_PORT_TYPE_MIX) { 174 maxRate = UINT_MAX; 175 } 176 // TODO: should mSamplingRates[] be ordered in terms of our preference 177 // and we return the first (and hence most preferred) match? This is of concern if 178 // we want to choose 96kHz over 192kHz for USB driver stability or resource constraints. 179 for (size_t i = 0; i < samplingRates.size(); i ++) { 180 if ((samplingRates[i] > pickedRate) && (samplingRates[i] <= maxRate)) { 181 pickedRate = samplingRates[i]; 182 } 183 } 184 } 185 } 186 187 void AudioPort::pickChannelMask(audio_channel_mask_t &pickedChannelMask, 188 const ChannelsVector &channelMasks) const 189 { 190 pickedChannelMask = AUDIO_CHANNEL_NONE; 191 // For direct outputs, pick minimum channel count: this helps ensuring that the 192 // channel count / sampling rate combination chosen will be supported by the connected 193 // sink 194 if (isDirectOutput()) { 195 uint32_t channelCount = UINT_MAX; 196 for (size_t i = 0; i < channelMasks.size(); i ++) { 197 uint32_t cnlCount; 198 if (useInputChannelMask()) { 199 cnlCount = audio_channel_count_from_in_mask(channelMasks[i]); 200 } else { 201 cnlCount = audio_channel_count_from_out_mask(channelMasks[i]); 202 } 203 if ((cnlCount < channelCount) && (cnlCount > 0)) { 204 pickedChannelMask = channelMasks[i]; 205 channelCount = cnlCount; 206 } 207 } 208 } else { 209 uint32_t channelCount = 0; 210 uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; 211 212 // For mixed output and inputs, use max mixer channel count. Do not 213 // limit channel count otherwise 214 if (mType != AUDIO_PORT_TYPE_MIX) { 215 maxCount = UINT_MAX; 216 } 217 for (size_t i = 0; i < channelMasks.size(); i ++) { 218 uint32_t cnlCount; 219 if (useInputChannelMask()) { 220 cnlCount = audio_channel_count_from_in_mask(channelMasks[i]); 221 } else { 222 cnlCount = audio_channel_count_from_out_mask(channelMasks[i]); 223 } 224 if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { 225 pickedChannelMask = channelMasks[i]; 226 channelCount = cnlCount; 227 } 228 } 229 } 230 } 231 232 /* format in order of increasing preference */ 233 const audio_format_t AudioPort::sPcmFormatCompareTable[] = { 234 AUDIO_FORMAT_DEFAULT, 235 AUDIO_FORMAT_PCM_16_BIT, 236 AUDIO_FORMAT_PCM_8_24_BIT, 237 AUDIO_FORMAT_PCM_24_BIT_PACKED, 238 AUDIO_FORMAT_PCM_32_BIT, 239 AUDIO_FORMAT_PCM_FLOAT, 240 }; 241 242 int AudioPort::compareFormats(audio_format_t format1, audio_format_t format2) 243 { 244 // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any 245 // compressed format and better than any PCM format. This is by design of pickFormat() 246 if (!audio_is_linear_pcm(format1)) { 247 if (!audio_is_linear_pcm(format2)) { 248 return 0; 249 } 250 return 1; 251 } 252 if (!audio_is_linear_pcm(format2)) { 253 return -1; 254 } 255 256 int index1 = -1, index2 = -1; 257 for (size_t i = 0; 258 (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1)); 259 i ++) { 260 if (sPcmFormatCompareTable[i] == format1) { 261 index1 = i; 262 } 263 if (sPcmFormatCompareTable[i] == format2) { 264 index2 = i; 265 } 266 } 267 // format1 not found => index1 < 0 => format2 > format1 268 // format2 not found => index2 < 0 => format2 < format1 269 return index1 - index2; 270 } 271 272 bool AudioPort::isBetterFormatMatch(audio_format_t newFormat, 273 audio_format_t currentFormat, 274 audio_format_t targetFormat) 275 { 276 if (newFormat == currentFormat) { 277 return false; 278 } 279 if (currentFormat == AUDIO_FORMAT_INVALID) { 280 return true; 281 } 282 if (newFormat == targetFormat) { 283 return true; 284 } 285 int currentDiffBytes = (int)audio_bytes_per_sample(targetFormat) - 286 audio_bytes_per_sample(currentFormat); 287 int newDiffBytes = (int)audio_bytes_per_sample(targetFormat) - 288 audio_bytes_per_sample(newFormat); 289 290 if (abs(newDiffBytes) < abs(currentDiffBytes)) { 291 return true; 292 } else if (abs(newDiffBytes) == abs(currentDiffBytes)) { 293 return (newDiffBytes >= 0); 294 } 295 return false; 296 } 297 298 void AudioPort::pickAudioProfile(uint32_t &samplingRate, 299 audio_channel_mask_t &channelMask, 300 audio_format_t &format) const 301 { 302 format = AUDIO_FORMAT_DEFAULT; 303 samplingRate = 0; 304 channelMask = AUDIO_CHANNEL_NONE; 305 306 // special case for uninitialized dynamic profile 307 if (!mProfiles.hasValidProfile()) { 308 return; 309 } 310 audio_format_t bestFormat = sPcmFormatCompareTable[ARRAY_SIZE(sPcmFormatCompareTable) - 1]; 311 // For mixed output and inputs, use best mixer output format. 312 // Do not limit format otherwise 313 if ((mType != AUDIO_PORT_TYPE_MIX) || isDirectOutput()) { 314 bestFormat = AUDIO_FORMAT_INVALID; 315 } 316 317 for (size_t i = 0; i < mProfiles.size(); i ++) { 318 if (!mProfiles[i]->isValid()) { 319 continue; 320 } 321 audio_format_t formatToCompare = mProfiles[i]->getFormat(); 322 if ((compareFormats(formatToCompare, format) > 0) && 323 (compareFormats(formatToCompare, bestFormat) <= 0)) { 324 uint32_t pickedSamplingRate = 0; 325 audio_channel_mask_t pickedChannelMask = AUDIO_CHANNEL_NONE; 326 pickChannelMask(pickedChannelMask, mProfiles[i]->getChannels()); 327 pickSamplingRate(pickedSamplingRate, mProfiles[i]->getSampleRates()); 328 329 if (formatToCompare != AUDIO_FORMAT_DEFAULT && pickedChannelMask != AUDIO_CHANNEL_NONE 330 && pickedSamplingRate != 0) { 331 format = formatToCompare; 332 channelMask = pickedChannelMask; 333 samplingRate = pickedSamplingRate; 334 // TODO: shall we return on the first one or still trying to pick a better Profile? 335 } 336 } 337 } 338 ALOGV("%s Port[nm:%s] profile rate=%d, format=%d, channels=%d", __FUNCTION__, mName.string(), 339 samplingRate, channelMask, format); 340 } 341 342 status_t AudioPort::checkGain(const struct audio_gain_config *gainConfig, int index) const 343 { 344 if (index < 0 || (size_t)index >= mGains.size()) { 345 return BAD_VALUE; 346 } 347 return mGains[index]->checkConfig(gainConfig); 348 } 349 350 void AudioPort::dump(int fd, int spaces, bool verbose) const 351 { 352 const size_t SIZE = 256; 353 char buffer[SIZE]; 354 String8 result; 355 356 if (!mName.isEmpty()) { 357 snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string()); 358 result.append(buffer); 359 write(fd, result.string(), result.size()); 360 } 361 if (verbose) { 362 mProfiles.dump(fd, spaces); 363 364 if (mGains.size() != 0) { 365 snprintf(buffer, SIZE, "%*s- gains:\n", spaces, ""); 366 result = buffer; 367 write(fd, result.string(), result.size()); 368 for (size_t i = 0; i < mGains.size(); i++) { 369 mGains[i]->dump(fd, spaces + 2, i); 370 } 371 } 372 } 373 } 374 375 void AudioPort::log(const char* indent) const 376 { 377 ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.string(), mType, mRole); 378 } 379 380 // --- AudioPortConfig class implementation 381 382 AudioPortConfig::AudioPortConfig() 383 { 384 mSamplingRate = 0; 385 mChannelMask = AUDIO_CHANNEL_NONE; 386 mFormat = AUDIO_FORMAT_INVALID; 387 mGain.index = -1; 388 } 389 390 status_t AudioPortConfig::applyAudioPortConfig(const struct audio_port_config *config, 391 struct audio_port_config *backupConfig) 392 { 393 struct audio_port_config localBackupConfig; 394 status_t status = NO_ERROR; 395 396 localBackupConfig.config_mask = config->config_mask; 397 toAudioPortConfig(&localBackupConfig); 398 399 sp<AudioPort> audioport = getAudioPort(); 400 if (audioport == 0) { 401 status = NO_INIT; 402 goto exit; 403 } 404 status = audioport->checkExactAudioProfile(config->sample_rate, 405 config->channel_mask, 406 config->format); 407 if (status != NO_ERROR) { 408 goto exit; 409 } 410 if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 411 mSamplingRate = config->sample_rate; 412 } 413 if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 414 mChannelMask = config->channel_mask; 415 } 416 if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 417 mFormat = config->format; 418 } 419 if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { 420 status = audioport->checkGain(&config->gain, config->gain.index); 421 if (status != NO_ERROR) { 422 goto exit; 423 } 424 mGain = config->gain; 425 } 426 427 exit: 428 if (status != NO_ERROR) { 429 applyAudioPortConfig(&localBackupConfig); 430 } 431 if (backupConfig != NULL) { 432 *backupConfig = localBackupConfig; 433 } 434 return status; 435 } 436 437 void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig, 438 const struct audio_port_config *srcConfig) const 439 { 440 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 441 dstConfig->sample_rate = mSamplingRate; 442 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { 443 dstConfig->sample_rate = srcConfig->sample_rate; 444 } 445 } else { 446 dstConfig->sample_rate = 0; 447 } 448 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 449 dstConfig->channel_mask = mChannelMask; 450 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { 451 dstConfig->channel_mask = srcConfig->channel_mask; 452 } 453 } else { 454 dstConfig->channel_mask = AUDIO_CHANNEL_NONE; 455 } 456 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 457 dstConfig->format = mFormat; 458 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { 459 dstConfig->format = srcConfig->format; 460 } 461 } else { 462 dstConfig->format = AUDIO_FORMAT_INVALID; 463 } 464 sp<AudioPort> audioport = getAudioPort(); 465 if ((dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) && audioport != NULL) { 466 dstConfig->gain = mGain; 467 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) 468 && audioport->checkGain(&srcConfig->gain, srcConfig->gain.index) == OK) { 469 dstConfig->gain = srcConfig->gain; 470 } 471 } else { 472 dstConfig->gain.index = -1; 473 } 474 if (dstConfig->gain.index != -1) { 475 dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; 476 } else { 477 dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; 478 } 479 } 480 481 }; // namespace android 482