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