AudioPort.cpp revision cc750d3604b33a92374253b12dd739dc06440aad
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 <media/AudioResamplerPublic.h> 20#include "AudioPort.h" 21#include "HwModule.h" 22#include "AudioGain.h" 23#include "ConfigParsingUtils.h" 24#include "audio_policy_conf.h" 25#include <policy.h> 26 27namespace android { 28 29int32_t volatile AudioPort::mNextUniqueId = 1; 30 31// --- AudioPort class implementation 32 33AudioPort::AudioPort(const String8& name, audio_port_type_t type, 34 audio_port_role_t role) : 35 mName(name), mType(type), mRole(role), mFlags(0) 36{ 37 mUseInChannelMask = ((type == AUDIO_PORT_TYPE_DEVICE) && (role == AUDIO_PORT_ROLE_SOURCE)) || 38 ((type == AUDIO_PORT_TYPE_MIX) && (role == AUDIO_PORT_ROLE_SINK)); 39} 40 41void AudioPort::attach(const sp<HwModule>& module) 42{ 43 mModule = module; 44} 45 46audio_port_handle_t AudioPort::getNextUniqueId() 47{ 48 return static_cast<audio_port_handle_t>(android_atomic_inc(&mNextUniqueId)); 49} 50 51audio_module_handle_t AudioPort::getModuleHandle() const 52{ 53 if (mModule == 0) { 54 return 0; 55 } 56 return mModule->mHandle; 57} 58 59uint32_t AudioPort::getModuleVersion() const 60{ 61 if (mModule == 0) { 62 return 0; 63 } 64 return mModule->mHalVersion; 65} 66 67const char *AudioPort::getModuleName() const 68{ 69 if (mModule == 0) { 70 return ""; 71 } 72 return mModule->mName; 73} 74 75void AudioPort::toAudioPort(struct audio_port *port) const 76{ 77 port->role = mRole; 78 port->type = mType; 79 strlcpy(port->name, mName, AUDIO_PORT_MAX_NAME_LEN); 80 unsigned int i; 81 for (i = 0; i < mSamplingRates.size() && i < AUDIO_PORT_MAX_SAMPLING_RATES; i++) { 82 if (mSamplingRates[i] != 0) { 83 port->sample_rates[i] = mSamplingRates[i]; 84 } 85 } 86 port->num_sample_rates = i; 87 for (i = 0; i < mChannelMasks.size() && i < AUDIO_PORT_MAX_CHANNEL_MASKS; i++) { 88 if (mChannelMasks[i] != 0) { 89 port->channel_masks[i] = mChannelMasks[i]; 90 } 91 } 92 port->num_channel_masks = i; 93 for (i = 0; i < mFormats.size() && i < AUDIO_PORT_MAX_FORMATS; i++) { 94 if (mFormats[i] != 0) { 95 port->formats[i] = mFormats[i]; 96 } 97 } 98 port->num_formats = i; 99 100 ALOGV("AudioPort::toAudioPort() num gains %zu", mGains.size()); 101 102 for (i = 0; i < mGains.size() && i < AUDIO_PORT_MAX_GAINS; i++) { 103 port->gains[i] = mGains[i]->mGain; 104 } 105 port->num_gains = i; 106} 107 108void AudioPort::importAudioPort(const sp<AudioPort> port) { 109 for (size_t k = 0 ; k < port->mSamplingRates.size() ; k++) { 110 const uint32_t rate = port->mSamplingRates.itemAt(k); 111 if (rate != 0) { // skip "dynamic" rates 112 bool hasRate = false; 113 for (size_t l = 0 ; l < mSamplingRates.size() ; l++) { 114 if (rate == mSamplingRates.itemAt(l)) { 115 hasRate = true; 116 break; 117 } 118 } 119 if (!hasRate) { // never import a sampling rate twice 120 mSamplingRates.add(rate); 121 } 122 } 123 } 124 for (size_t k = 0 ; k < port->mChannelMasks.size() ; k++) { 125 const audio_channel_mask_t mask = port->mChannelMasks.itemAt(k); 126 if (mask != 0) { // skip "dynamic" masks 127 bool hasMask = false; 128 for (size_t l = 0 ; l < mChannelMasks.size() ; l++) { 129 if (mask == mChannelMasks.itemAt(l)) { 130 hasMask = true; 131 break; 132 } 133 } 134 if (!hasMask) { // never import a channel mask twice 135 mChannelMasks.add(mask); 136 } 137 } 138 } 139 for (size_t k = 0 ; k < port->mFormats.size() ; k++) { 140 const audio_format_t format = port->mFormats.itemAt(k); 141 if (format != 0) { // skip "dynamic" formats 142 bool hasFormat = false; 143 for (size_t l = 0 ; l < mFormats.size() ; l++) { 144 if (format == mFormats.itemAt(l)) { 145 hasFormat = true; 146 break; 147 } 148 } 149 if (!hasFormat) { // never import a format twice 150 mFormats.add(format); 151 } 152 } 153 } 154} 155 156void AudioPort::clearCapabilities() { 157 mChannelMasks.clear(); 158 mFormats.clear(); 159 mSamplingRates.clear(); 160} 161 162void AudioPort::loadSamplingRates(char *name) 163{ 164 char *str = strtok(name, "|"); 165 166 // by convention, "0' in the first entry in mSamplingRates indicates the supported sampling 167 // rates should be read from the output stream after it is opened for the first time 168 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 169 mSamplingRates.add(0); 170 return; 171 } 172 173 while (str != NULL) { 174 uint32_t rate = atoi(str); 175 if (rate != 0) { 176 ALOGV("loadSamplingRates() adding rate %d", rate); 177 mSamplingRates.add(rate); 178 } 179 str = strtok(NULL, "|"); 180 } 181} 182 183void AudioPort::loadFormats(char *name) 184{ 185 char *str = strtok(name, "|"); 186 187 // by convention, "0' in the first entry in mFormats indicates the supported formats 188 // should be read from the output stream after it is opened for the first time 189 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 190 mFormats.add(AUDIO_FORMAT_DEFAULT); 191 return; 192 } 193 194 while (str != NULL) { 195 audio_format_t format = (audio_format_t)ConfigParsingUtils::stringToEnum(sFormatNameToEnumTable, 196 ARRAY_SIZE(sFormatNameToEnumTable), 197 str); 198 if (format != AUDIO_FORMAT_DEFAULT) { 199 mFormats.add(format); 200 } 201 str = strtok(NULL, "|"); 202 } 203 // we sort from worst to best, so that AUDIO_FORMAT_DEFAULT is always the first entry. 204 // TODO: compareFormats could be a lambda to convert between pointer-to-format to format: 205 // [](const audio_format_t *format1, const audio_format_t *format2) { 206 // return compareFormats(*format1, *format2); 207 // } 208 mFormats.sort(compareFormats); 209} 210 211void AudioPort::loadInChannels(char *name) 212{ 213 const char *str = strtok(name, "|"); 214 215 ALOGV("loadInChannels() %s", name); 216 217 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 218 mChannelMasks.add(0); 219 return; 220 } 221 222 while (str != NULL) { 223 audio_channel_mask_t channelMask = 224 (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sInChannelsNameToEnumTable, 225 ARRAY_SIZE(sInChannelsNameToEnumTable), 226 str); 227 if (channelMask == 0) { // if not found, check the channel index table 228 channelMask = (audio_channel_mask_t) 229 ConfigParsingUtils::stringToEnum(sIndexChannelsNameToEnumTable, 230 ARRAY_SIZE(sIndexChannelsNameToEnumTable), 231 str); 232 } 233 if (channelMask != 0) { 234 ALOGV("loadInChannels() adding channelMask %#x", channelMask); 235 mChannelMasks.add(channelMask); 236 } 237 str = strtok(NULL, "|"); 238 } 239} 240 241void AudioPort::loadOutChannels(char *name) 242{ 243 const char *str = strtok(name, "|"); 244 245 ALOGV("loadOutChannels() %s", name); 246 247 // by convention, "0' in the first entry in mChannelMasks indicates the supported channel 248 // masks should be read from the output stream after it is opened for the first time 249 if (str != NULL && strcmp(str, DYNAMIC_VALUE_TAG) == 0) { 250 mChannelMasks.add(0); 251 return; 252 } 253 254 while (str != NULL) { 255 audio_channel_mask_t channelMask = 256 (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sOutChannelsNameToEnumTable, 257 ARRAY_SIZE(sOutChannelsNameToEnumTable), 258 str); 259 if (channelMask == 0) { // if not found, check the channel index table 260 channelMask = (audio_channel_mask_t) 261 ConfigParsingUtils::stringToEnum(sIndexChannelsNameToEnumTable, 262 ARRAY_SIZE(sIndexChannelsNameToEnumTable), 263 str); 264 } 265 if (channelMask != 0) { 266 mChannelMasks.add(channelMask); 267 } 268 str = strtok(NULL, "|"); 269 } 270 return; 271} 272 273audio_gain_mode_t AudioPort::loadGainMode(char *name) 274{ 275 const char *str = strtok(name, "|"); 276 277 ALOGV("loadGainMode() %s", name); 278 audio_gain_mode_t mode = 0; 279 while (str != NULL) { 280 mode |= (audio_gain_mode_t)ConfigParsingUtils::stringToEnum(sGainModeNameToEnumTable, 281 ARRAY_SIZE(sGainModeNameToEnumTable), 282 str); 283 str = strtok(NULL, "|"); 284 } 285 return mode; 286} 287 288void AudioPort::loadGain(cnode *root, int index) 289{ 290 cnode *node = root->first_child; 291 292 sp<AudioGain> gain = new AudioGain(index, mUseInChannelMask); 293 294 while (node) { 295 if (strcmp(node->name, GAIN_MODE) == 0) { 296 gain->mGain.mode = loadGainMode((char *)node->value); 297 } else if (strcmp(node->name, GAIN_CHANNELS) == 0) { 298 if (mUseInChannelMask) { 299 gain->mGain.channel_mask = 300 (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sInChannelsNameToEnumTable, 301 ARRAY_SIZE(sInChannelsNameToEnumTable), 302 (char *)node->value); 303 } else { 304 gain->mGain.channel_mask = 305 (audio_channel_mask_t)ConfigParsingUtils::stringToEnum(sOutChannelsNameToEnumTable, 306 ARRAY_SIZE(sOutChannelsNameToEnumTable), 307 (char *)node->value); 308 } 309 } else if (strcmp(node->name, GAIN_MIN_VALUE) == 0) { 310 gain->mGain.min_value = atoi((char *)node->value); 311 } else if (strcmp(node->name, GAIN_MAX_VALUE) == 0) { 312 gain->mGain.max_value = atoi((char *)node->value); 313 } else if (strcmp(node->name, GAIN_DEFAULT_VALUE) == 0) { 314 gain->mGain.default_value = atoi((char *)node->value); 315 } else if (strcmp(node->name, GAIN_STEP_VALUE) == 0) { 316 gain->mGain.step_value = atoi((char *)node->value); 317 } else if (strcmp(node->name, GAIN_MIN_RAMP_MS) == 0) { 318 gain->mGain.min_ramp_ms = atoi((char *)node->value); 319 } else if (strcmp(node->name, GAIN_MAX_RAMP_MS) == 0) { 320 gain->mGain.max_ramp_ms = atoi((char *)node->value); 321 } 322 node = node->next; 323 } 324 325 ALOGV("loadGain() adding new gain mode %08x channel mask %08x min mB %d max mB %d", 326 gain->mGain.mode, gain->mGain.channel_mask, gain->mGain.min_value, gain->mGain.max_value); 327 328 if (gain->mGain.mode == 0) { 329 return; 330 } 331 mGains.add(gain); 332} 333 334void AudioPort::loadGains(cnode *root) 335{ 336 cnode *node = root->first_child; 337 int index = 0; 338 while (node) { 339 ALOGV("loadGains() loading gain %s", node->name); 340 loadGain(node, index++); 341 node = node->next; 342 } 343} 344 345status_t AudioPort::checkExactSamplingRate(uint32_t samplingRate) const 346{ 347 if (mSamplingRates.isEmpty()) { 348 return NO_ERROR; 349 } 350 351 for (size_t i = 0; i < mSamplingRates.size(); i ++) { 352 if (mSamplingRates[i] == samplingRate) { 353 return NO_ERROR; 354 } 355 } 356 return BAD_VALUE; 357} 358 359status_t AudioPort::checkCompatibleSamplingRate(uint32_t samplingRate, 360 uint32_t *updatedSamplingRate) const 361{ 362 if (mSamplingRates.isEmpty()) { 363 if (updatedSamplingRate != NULL) { 364 *updatedSamplingRate = samplingRate; 365 } 366 return NO_ERROR; 367 } 368 369 // Search for the closest supported sampling rate that is above (preferred) 370 // or below (acceptable) the desired sampling rate, within a permitted ratio. 371 // The sampling rates do not need to be sorted in ascending order. 372 ssize_t maxBelow = -1; 373 ssize_t minAbove = -1; 374 uint32_t candidate; 375 for (size_t i = 0; i < mSamplingRates.size(); i++) { 376 candidate = mSamplingRates[i]; 377 if (candidate == samplingRate) { 378 if (updatedSamplingRate != NULL) { 379 *updatedSamplingRate = candidate; 380 } 381 return NO_ERROR; 382 } 383 // candidate < desired 384 if (candidate < samplingRate) { 385 if (maxBelow < 0 || candidate > mSamplingRates[maxBelow]) { 386 maxBelow = i; 387 } 388 // candidate > desired 389 } else { 390 if (minAbove < 0 || candidate < mSamplingRates[minAbove]) { 391 minAbove = i; 392 } 393 } 394 } 395 396 // Prefer to down-sample from a higher sampling rate, as we get the desired frequency spectrum. 397 if (minAbove >= 0) { 398 candidate = mSamplingRates[minAbove]; 399 if (candidate / AUDIO_RESAMPLER_DOWN_RATIO_MAX <= samplingRate) { 400 if (updatedSamplingRate != NULL) { 401 *updatedSamplingRate = candidate; 402 } 403 return NO_ERROR; 404 } 405 } 406 // But if we have to up-sample from a lower sampling rate, that's OK. 407 if (maxBelow >= 0) { 408 candidate = mSamplingRates[maxBelow]; 409 if (candidate * AUDIO_RESAMPLER_UP_RATIO_MAX >= samplingRate) { 410 if (updatedSamplingRate != NULL) { 411 *updatedSamplingRate = candidate; 412 } 413 return NO_ERROR; 414 } 415 } 416 // leave updatedSamplingRate unmodified 417 return BAD_VALUE; 418} 419 420status_t AudioPort::checkExactChannelMask(audio_channel_mask_t channelMask) const 421{ 422 if (mChannelMasks.isEmpty()) { 423 return NO_ERROR; 424 } 425 426 for (size_t i = 0; i < mChannelMasks.size(); i++) { 427 if (mChannelMasks[i] == channelMask) { 428 return NO_ERROR; 429 } 430 } 431 return BAD_VALUE; 432} 433 434status_t AudioPort::checkCompatibleChannelMask(audio_channel_mask_t channelMask, 435 audio_channel_mask_t *updatedChannelMask) const 436{ 437 if (mChannelMasks.isEmpty()) { 438 if (updatedChannelMask != NULL) { 439 *updatedChannelMask = channelMask; 440 } 441 return NO_ERROR; 442 } 443 444 const bool isRecordThread = mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK; 445 const bool isIndex = audio_channel_mask_get_representation(channelMask) 446 == AUDIO_CHANNEL_REPRESENTATION_INDEX; 447 int bestMatch = 0; 448 for (size_t i = 0; i < mChannelMasks.size(); i ++) { 449 audio_channel_mask_t supported = mChannelMasks[i]; 450 if (supported == channelMask) { 451 // Exact matches always taken. 452 if (updatedChannelMask != NULL) { 453 *updatedChannelMask = channelMask; 454 } 455 return NO_ERROR; 456 } 457 458 // AUDIO_CHANNEL_NONE (value: 0) is used for dynamic channel support 459 if (isRecordThread && supported != AUDIO_CHANNEL_NONE) { 460 // Approximate (best) match: 461 // The match score measures how well the supported channel mask matches the 462 // desired mask, where increasing-is-better. 463 // 464 // TODO: Some tweaks may be needed. 465 // Should be a static function of the data processing library. 466 // 467 // In priority: 468 // match score = 1000 if legacy channel conversion equivalent (always prefer this) 469 // OR 470 // match score += 100 if the channel mask representations match 471 // match score += number of channels matched. 472 // 473 // If there are no matched channels, the mask may still be accepted 474 // but the playback or record will be silent. 475 const bool isSupportedIndex = (audio_channel_mask_get_representation(supported) 476 == AUDIO_CHANNEL_REPRESENTATION_INDEX); 477 int match; 478 if (isIndex && isSupportedIndex) { 479 // index equivalence 480 match = 100 + __builtin_popcount( 481 audio_channel_mask_get_bits(channelMask) 482 & audio_channel_mask_get_bits(supported)); 483 } else if (isIndex && !isSupportedIndex) { 484 const uint32_t equivalentBits = 485 (1 << audio_channel_count_from_in_mask(supported)) - 1 ; 486 match = __builtin_popcount( 487 audio_channel_mask_get_bits(channelMask) & equivalentBits); 488 } else if (!isIndex && isSupportedIndex) { 489 const uint32_t equivalentBits = 490 (1 << audio_channel_count_from_in_mask(channelMask)) - 1; 491 match = __builtin_popcount( 492 equivalentBits & audio_channel_mask_get_bits(supported)); 493 } else { 494 // positional equivalence 495 match = 100 + __builtin_popcount( 496 audio_channel_mask_get_bits(channelMask) 497 & audio_channel_mask_get_bits(supported)); 498 switch (supported) { 499 case AUDIO_CHANNEL_IN_FRONT_BACK: 500 case AUDIO_CHANNEL_IN_STEREO: 501 if (channelMask == AUDIO_CHANNEL_IN_MONO) { 502 match = 1000; 503 } 504 break; 505 case AUDIO_CHANNEL_IN_MONO: 506 if (channelMask == AUDIO_CHANNEL_IN_FRONT_BACK 507 || channelMask == AUDIO_CHANNEL_IN_STEREO) { 508 match = 1000; 509 } 510 break; 511 default: 512 break; 513 } 514 } 515 if (match > bestMatch) { 516 bestMatch = match; 517 if (updatedChannelMask != NULL) { 518 *updatedChannelMask = supported; 519 } else { 520 return NO_ERROR; // any match will do in this case. 521 } 522 } 523 } 524 } 525 return bestMatch > 0 ? NO_ERROR : BAD_VALUE; 526} 527 528status_t AudioPort::checkExactFormat(audio_format_t format) const 529{ 530 if (mFormats.isEmpty()) { 531 return NO_ERROR; 532 } 533 534 for (size_t i = 0; i < mFormats.size(); i ++) { 535 if (mFormats[i] == format) { 536 return NO_ERROR; 537 } 538 } 539 return BAD_VALUE; 540} 541 542status_t AudioPort::checkCompatibleFormat(audio_format_t format, audio_format_t *updatedFormat) 543 const 544{ 545 if (mFormats.isEmpty()) { 546 if (updatedFormat != NULL) { 547 *updatedFormat = format; 548 } 549 return NO_ERROR; 550 } 551 552 const bool checkInexact = // when port is input and format is linear pcm 553 mType == AUDIO_PORT_TYPE_MIX && mRole == AUDIO_PORT_ROLE_SINK 554 && audio_is_linear_pcm(format); 555 556 // iterate from best format to worst format (reverse order) 557 for (ssize_t i = mFormats.size() - 1; i >= 0 ; --i) { 558 if (mFormats[i] == format || 559 (checkInexact 560 && mFormats[i] != AUDIO_FORMAT_DEFAULT 561 && audio_is_linear_pcm(mFormats[i]))) { 562 // for inexact checks we take the first linear pcm format due to sorting. 563 if (updatedFormat != NULL) { 564 *updatedFormat = mFormats[i]; 565 } 566 return NO_ERROR; 567 } 568 } 569 return BAD_VALUE; 570} 571 572uint32_t AudioPort::pickSamplingRate() const 573{ 574 // special case for uninitialized dynamic profile 575 if (mSamplingRates.size() == 1 && mSamplingRates[0] == 0) { 576 return 0; 577 } 578 579 // For direct outputs, pick minimum sampling rate: this helps ensuring that the 580 // channel count / sampling rate combination chosen will be supported by the connected 581 // sink 582 if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 583 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 584 uint32_t samplingRate = UINT_MAX; 585 for (size_t i = 0; i < mSamplingRates.size(); i ++) { 586 if ((mSamplingRates[i] < samplingRate) && (mSamplingRates[i] > 0)) { 587 samplingRate = mSamplingRates[i]; 588 } 589 } 590 return (samplingRate == UINT_MAX) ? 0 : samplingRate; 591 } 592 593 uint32_t samplingRate = 0; 594 uint32_t maxRate = MAX_MIXER_SAMPLING_RATE; 595 596 // For mixed output and inputs, use max mixer sampling rates. Do not 597 // limit sampling rate otherwise 598 // For inputs, also see checkCompatibleSamplingRate(). 599 if (mType != AUDIO_PORT_TYPE_MIX) { 600 maxRate = UINT_MAX; 601 } 602 // TODO: should mSamplingRates[] be ordered in terms of our preference 603 // and we return the first (and hence most preferred) match? This is of concern if 604 // we want to choose 96kHz over 192kHz for USB driver stability or resource constraints. 605 for (size_t i = 0; i < mSamplingRates.size(); i ++) { 606 if ((mSamplingRates[i] > samplingRate) && (mSamplingRates[i] <= maxRate)) { 607 samplingRate = mSamplingRates[i]; 608 } 609 } 610 return samplingRate; 611} 612 613audio_channel_mask_t AudioPort::pickChannelMask() const 614{ 615 // special case for uninitialized dynamic profile 616 if (mChannelMasks.size() == 1 && mChannelMasks[0] == 0) { 617 return AUDIO_CHANNEL_NONE; 618 } 619 audio_channel_mask_t channelMask = AUDIO_CHANNEL_NONE; 620 621 // For direct outputs, pick minimum channel count: this helps ensuring that the 622 // channel count / sampling rate combination chosen will be supported by the connected 623 // sink 624 if ((mType == AUDIO_PORT_TYPE_MIX) && (mRole == AUDIO_PORT_ROLE_SOURCE) && 625 (mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD))) { 626 uint32_t channelCount = UINT_MAX; 627 for (size_t i = 0; i < mChannelMasks.size(); i ++) { 628 uint32_t cnlCount; 629 if (mUseInChannelMask) { 630 cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 631 } else { 632 cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 633 } 634 if ((cnlCount < channelCount) && (cnlCount > 0)) { 635 channelMask = mChannelMasks[i]; 636 channelCount = cnlCount; 637 } 638 } 639 return channelMask; 640 } 641 642 uint32_t channelCount = 0; 643 uint32_t maxCount = MAX_MIXER_CHANNEL_COUNT; 644 645 // For mixed output and inputs, use max mixer channel count. Do not 646 // limit channel count otherwise 647 if (mType != AUDIO_PORT_TYPE_MIX) { 648 maxCount = UINT_MAX; 649 } 650 for (size_t i = 0; i < mChannelMasks.size(); i ++) { 651 uint32_t cnlCount; 652 if (mUseInChannelMask) { 653 cnlCount = audio_channel_count_from_in_mask(mChannelMasks[i]); 654 } else { 655 cnlCount = audio_channel_count_from_out_mask(mChannelMasks[i]); 656 } 657 if ((cnlCount > channelCount) && (cnlCount <= maxCount)) { 658 channelMask = mChannelMasks[i]; 659 channelCount = cnlCount; 660 } 661 } 662 return channelMask; 663} 664 665/* format in order of increasing preference */ 666const audio_format_t AudioPort::sPcmFormatCompareTable[] = { 667 AUDIO_FORMAT_DEFAULT, 668 AUDIO_FORMAT_PCM_16_BIT, 669 AUDIO_FORMAT_PCM_8_24_BIT, 670 AUDIO_FORMAT_PCM_24_BIT_PACKED, 671 AUDIO_FORMAT_PCM_32_BIT, 672 AUDIO_FORMAT_PCM_FLOAT, 673}; 674 675int AudioPort::compareFormats(audio_format_t format1, 676 audio_format_t format2) 677{ 678 // NOTE: AUDIO_FORMAT_INVALID is also considered not PCM and will be compared equal to any 679 // compressed format and better than any PCM format. This is by design of pickFormat() 680 if (!audio_is_linear_pcm(format1)) { 681 if (!audio_is_linear_pcm(format2)) { 682 return 0; 683 } 684 return 1; 685 } 686 if (!audio_is_linear_pcm(format2)) { 687 return -1; 688 } 689 690 int index1 = -1, index2 = -1; 691 for (size_t i = 0; 692 (i < ARRAY_SIZE(sPcmFormatCompareTable)) && ((index1 == -1) || (index2 == -1)); 693 i ++) { 694 if (sPcmFormatCompareTable[i] == format1) { 695 index1 = i; 696 } 697 if (sPcmFormatCompareTable[i] == format2) { 698 index2 = i; 699 } 700 } 701 // format1 not found => index1 < 0 => format2 > format1 702 // format2 not found => index2 < 0 => format2 < format1 703 return index1 - index2; 704} 705 706audio_format_t AudioPort::pickFormat() const 707{ 708 // special case for uninitialized dynamic profile 709 if (mFormats.size() == 1 && mFormats[0] == 0) { 710 return AUDIO_FORMAT_DEFAULT; 711 } 712 713 audio_format_t format = AUDIO_FORMAT_DEFAULT; 714 audio_format_t bestFormat = 715 AudioPort::sPcmFormatCompareTable[ 716 ARRAY_SIZE(AudioPort::sPcmFormatCompareTable) - 1]; 717 // For mixed output and inputs, use best mixer output format. Do not 718 // limit format otherwise 719 if ((mType != AUDIO_PORT_TYPE_MIX) || 720 ((mRole == AUDIO_PORT_ROLE_SOURCE) && 721 (((mFlags & (AUDIO_OUTPUT_FLAG_DIRECT | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)) != 0)))) { 722 bestFormat = AUDIO_FORMAT_INVALID; 723 } 724 725 for (size_t i = 0; i < mFormats.size(); i ++) { 726 if ((compareFormats(mFormats[i], format) > 0) && 727 (compareFormats(mFormats[i], bestFormat) <= 0)) { 728 format = mFormats[i]; 729 } 730 } 731 return format; 732} 733 734status_t AudioPort::checkGain(const struct audio_gain_config *gainConfig, 735 int index) const 736{ 737 if (index < 0 || (size_t)index >= mGains.size()) { 738 return BAD_VALUE; 739 } 740 return mGains[index]->checkConfig(gainConfig); 741} 742 743void AudioPort::dump(int fd, int spaces) const 744{ 745 const size_t SIZE = 256; 746 char buffer[SIZE]; 747 String8 result; 748 749 if (mName.length() != 0) { 750 snprintf(buffer, SIZE, "%*s- name: %s\n", spaces, "", mName.string()); 751 result.append(buffer); 752 } 753 754 if (mSamplingRates.size() != 0) { 755 snprintf(buffer, SIZE, "%*s- sampling rates: ", spaces, ""); 756 result.append(buffer); 757 for (size_t i = 0; i < mSamplingRates.size(); i++) { 758 if (i == 0 && mSamplingRates[i] == 0) { 759 snprintf(buffer, SIZE, "Dynamic"); 760 } else { 761 snprintf(buffer, SIZE, "%d", mSamplingRates[i]); 762 } 763 result.append(buffer); 764 result.append(i == (mSamplingRates.size() - 1) ? "" : ", "); 765 } 766 result.append("\n"); 767 } 768 769 if (mChannelMasks.size() != 0) { 770 snprintf(buffer, SIZE, "%*s- channel masks: ", spaces, ""); 771 result.append(buffer); 772 for (size_t i = 0; i < mChannelMasks.size(); i++) { 773 ALOGV("AudioPort::dump mChannelMasks %zu %08x", i, mChannelMasks[i]); 774 775 if (i == 0 && mChannelMasks[i] == 0) { 776 snprintf(buffer, SIZE, "Dynamic"); 777 } else { 778 snprintf(buffer, SIZE, "0x%04x", mChannelMasks[i]); 779 } 780 result.append(buffer); 781 result.append(i == (mChannelMasks.size() - 1) ? "" : ", "); 782 } 783 result.append("\n"); 784 } 785 786 if (mFormats.size() != 0) { 787 snprintf(buffer, SIZE, "%*s- formats: ", spaces, ""); 788 result.append(buffer); 789 for (size_t i = 0; i < mFormats.size(); i++) { 790 const char *formatStr = ConfigParsingUtils::enumToString(sFormatNameToEnumTable, 791 ARRAY_SIZE(sFormatNameToEnumTable), 792 mFormats[i]); 793 const bool isEmptyStr = formatStr[0] == 0; 794 if (i == 0 && isEmptyStr) { 795 snprintf(buffer, SIZE, "Dynamic"); 796 } else { 797 if (isEmptyStr) { 798 snprintf(buffer, SIZE, "%#x", mFormats[i]); 799 } else { 800 snprintf(buffer, SIZE, "%s", formatStr); 801 } 802 } 803 result.append(buffer); 804 result.append(i == (mFormats.size() - 1) ? "" : ", "); 805 } 806 result.append("\n"); 807 } 808 write(fd, result.string(), result.size()); 809 if (mGains.size() != 0) { 810 snprintf(buffer, SIZE, "%*s- gains:\n", spaces, ""); 811 write(fd, buffer, strlen(buffer) + 1); 812 for (size_t i = 0; i < mGains.size(); i++) { 813 mGains[i]->dump(fd, spaces + 2, i); 814 } 815 } 816} 817 818void AudioPort::log(const char* indent) const 819{ 820 ALOGI("%s Port[nm:%s, type:%d, role:%d]", indent, mName.string(), mType, mRole); 821} 822 823// --- AudioPortConfig class implementation 824 825AudioPortConfig::AudioPortConfig() 826{ 827 mSamplingRate = 0; 828 mChannelMask = AUDIO_CHANNEL_NONE; 829 mFormat = AUDIO_FORMAT_INVALID; 830 mGain.index = -1; 831} 832 833status_t AudioPortConfig::applyAudioPortConfig( 834 const struct audio_port_config *config, 835 struct audio_port_config *backupConfig) 836{ 837 struct audio_port_config localBackupConfig; 838 status_t status = NO_ERROR; 839 840 localBackupConfig.config_mask = config->config_mask; 841 toAudioPortConfig(&localBackupConfig); 842 843 sp<AudioPort> audioport = getAudioPort(); 844 if (audioport == 0) { 845 status = NO_INIT; 846 goto exit; 847 } 848 if (config->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 849 status = audioport->checkExactSamplingRate(config->sample_rate); 850 if (status != NO_ERROR) { 851 goto exit; 852 } 853 mSamplingRate = config->sample_rate; 854 } 855 if (config->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 856 status = audioport->checkExactChannelMask(config->channel_mask); 857 if (status != NO_ERROR) { 858 goto exit; 859 } 860 mChannelMask = config->channel_mask; 861 } 862 if (config->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 863 status = audioport->checkExactFormat(config->format); 864 if (status != NO_ERROR) { 865 goto exit; 866 } 867 mFormat = config->format; 868 } 869 if (config->config_mask & AUDIO_PORT_CONFIG_GAIN) { 870 status = audioport->checkGain(&config->gain, config->gain.index); 871 if (status != NO_ERROR) { 872 goto exit; 873 } 874 mGain = config->gain; 875 } 876 877exit: 878 if (status != NO_ERROR) { 879 applyAudioPortConfig(&localBackupConfig); 880 } 881 if (backupConfig != NULL) { 882 *backupConfig = localBackupConfig; 883 } 884 return status; 885} 886 887void AudioPortConfig::toAudioPortConfig(struct audio_port_config *dstConfig, 888 const struct audio_port_config *srcConfig) const 889{ 890 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE) { 891 dstConfig->sample_rate = mSamplingRate; 892 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_SAMPLE_RATE)) { 893 dstConfig->sample_rate = srcConfig->sample_rate; 894 } 895 } else { 896 dstConfig->sample_rate = 0; 897 } 898 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK) { 899 dstConfig->channel_mask = mChannelMask; 900 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_CHANNEL_MASK)) { 901 dstConfig->channel_mask = srcConfig->channel_mask; 902 } 903 } else { 904 dstConfig->channel_mask = AUDIO_CHANNEL_NONE; 905 } 906 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT) { 907 dstConfig->format = mFormat; 908 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_FORMAT)) { 909 dstConfig->format = srcConfig->format; 910 } 911 } else { 912 dstConfig->format = AUDIO_FORMAT_INVALID; 913 } 914 if (dstConfig->config_mask & AUDIO_PORT_CONFIG_GAIN) { 915 dstConfig->gain = mGain; 916 if ((srcConfig != NULL) && (srcConfig->config_mask & AUDIO_PORT_CONFIG_GAIN)) { 917 dstConfig->gain = srcConfig->gain; 918 } 919 } else { 920 dstConfig->gain.index = -1; 921 } 922 if (dstConfig->gain.index != -1) { 923 dstConfig->config_mask |= AUDIO_PORT_CONFIG_GAIN; 924 } else { 925 dstConfig->config_mask &= ~AUDIO_PORT_CONFIG_GAIN; 926 } 927} 928 929}; // namespace android 930