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