Home | History | Annotate | Download | only in src
      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
     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 
     38 void AudioPort::detach()
     39 {
     40     mModule = nullptr;
     41 }
     42 
     43 // Note that is a different namespace than AudioFlinger unique IDs
     44 audio_port_handle_t AudioPort::getNextUniqueId()
     45 {
     46     return getNextHandle();
     47 }
     48 
     49 audio_module_handle_t AudioPort::getModuleHandle() const
     50 {
     51     return mModule != 0 ? mModule->getHandle() : AUDIO_MODULE_HANDLE_NONE;
     52 }
     53 
     54 uint32_t AudioPort::getModuleVersionMajor() const
     55 {
     56     return mModule != 0 ? mModule->getHalVersionMajor() : 0;
     57 }
     58 
     59 const char *AudioPort::getModuleName() const
     60 {
     61     return mModule != 0 ? mModule->getName() : "invalid module";
     62 }
     63 
     64 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 
    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 
    146 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 
    166 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 
    200 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 
    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 
    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 
    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 
    306 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 
    350 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 
    358 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 
    375 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 
    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>
    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 
    446 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 
    477 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