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
27 namespace android {
28
29 int32_t volatile AudioPort::mNextUniqueId = 1;
30
31 // --- AudioPort class implementation
32
AudioPort(const String8 & name,audio_port_type_t type,audio_port_role_t role)33 AudioPort::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
attach(const sp<HwModule> & module)41 void AudioPort::attach(const sp<HwModule>& module)
42 {
43 mModule = module;
44 }
45
getNextUniqueId()46 audio_port_handle_t AudioPort::getNextUniqueId()
47 {
48 return static_cast<audio_port_handle_t>(android_atomic_inc(&mNextUniqueId));
49 }
50
getModuleHandle() const51 audio_module_handle_t AudioPort::getModuleHandle() const
52 {
53 if (mModule == 0) {
54 return 0;
55 }
56 return mModule->mHandle;
57 }
58
getModuleVersion() const59 uint32_t AudioPort::getModuleVersion() const
60 {
61 if (mModule == 0) {
62 return 0;
63 }
64 return mModule->mHalVersion;
65 }
66
getModuleName() const67 const char *AudioPort::getModuleName() const
68 {
69 if (mModule == 0) {
70 return "";
71 }
72 return mModule->mName;
73 }
74
toAudioPort(struct audio_port * port) const75 void 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
importAudioPort(const sp<AudioPort> port)108 void 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
clearCapabilities()156 void AudioPort::clearCapabilities() {
157 mChannelMasks.clear();
158 mFormats.clear();
159 mSamplingRates.clear();
160 }
161
loadSamplingRates(char * name)162 void 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
loadFormats(char * name)183 void 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
loadInChannels(char * name)211 void 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
loadOutChannels(char * name)241 void 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
loadGainMode(char * name)273 audio_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
loadGain(cnode * root,int index)288 void 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
loadGains(cnode * root)334 void 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
checkExactSamplingRate(uint32_t samplingRate) const345 status_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
checkCompatibleSamplingRate(uint32_t samplingRate,uint32_t * updatedSamplingRate) const359 status_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
checkExactChannelMask(audio_channel_mask_t channelMask) const420 status_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
checkCompatibleChannelMask(audio_channel_mask_t channelMask,audio_channel_mask_t * updatedChannelMask) const434 status_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
checkExactFormat(audio_format_t format) const528 status_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
checkCompatibleFormat(audio_format_t format,audio_format_t * updatedFormat) const542 status_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
pickSamplingRate() const572 uint32_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
pickChannelMask() const613 audio_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 */
666 const 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
compareFormats(audio_format_t format1,audio_format_t format2)675 int 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
pickFormat() const706 audio_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
checkGain(const struct audio_gain_config * gainConfig,int index) const734 status_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
dump(int fd,int spaces) const743 void 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
log(const char * indent) const818 void 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
AudioPortConfig()825 AudioPortConfig::AudioPortConfig()
826 {
827 mSamplingRate = 0;
828 mChannelMask = AUDIO_CHANNEL_NONE;
829 mFormat = AUDIO_FORMAT_INVALID;
830 mGain.index = -1;
831 }
832
applyAudioPortConfig(const struct audio_port_config * config,struct audio_port_config * backupConfig)833 status_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
877 exit:
878 if (status != NO_ERROR) {
879 applyAudioPortConfig(&localBackupConfig);
880 }
881 if (backupConfig != NULL) {
882 *backupConfig = localBackupConfig;
883 }
884 return status;
885 }
886
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const887 void 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