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