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