Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2018 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 #include "core/default/Conversions.h"
     18 
     19 #include <stdio.h>
     20 
     21 #include <log/log.h>
     22 
     23 namespace android {
     24 namespace hardware {
     25 namespace audio {
     26 namespace CPP_VERSION {
     27 namespace implementation {
     28 
     29 std::string deviceAddressToHal(const DeviceAddress& address) {
     30     // HAL assumes that the address is NUL-terminated.
     31     char halAddress[AUDIO_DEVICE_MAX_ADDRESS_LEN];
     32     memset(halAddress, 0, sizeof(halAddress));
     33     uint32_t halDevice = static_cast<uint32_t>(address.device);
     34     const bool isInput = (halDevice & AUDIO_DEVICE_BIT_IN) != 0;
     35     if (isInput) halDevice &= ~AUDIO_DEVICE_BIT_IN;
     36     if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
     37         (isInput && (halDevice & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
     38         snprintf(halAddress, sizeof(halAddress), "%02X:%02X:%02X:%02X:%02X:%02X",
     39                  address.address.mac[0], address.address.mac[1], address.address.mac[2],
     40                  address.address.mac[3], address.address.mac[4], address.address.mac[5]);
     41     } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_IP) != 0) ||
     42                (isInput && (halDevice & AUDIO_DEVICE_IN_IP) != 0)) {
     43         snprintf(halAddress, sizeof(halAddress), "%d.%d.%d.%d", address.address.ipv4[0],
     44                  address.address.ipv4[1], address.address.ipv4[2], address.address.ipv4[3]);
     45     } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_ALL_USB) != 0) ||
     46                (isInput && (halDevice & AUDIO_DEVICE_IN_ALL_USB) != 0)) {
     47         snprintf(halAddress, sizeof(halAddress), "card=%d;device=%d", address.address.alsa.card,
     48                  address.address.alsa.device);
     49     } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_BUS) != 0) ||
     50                (isInput && (halDevice & AUDIO_DEVICE_IN_BUS) != 0)) {
     51         snprintf(halAddress, sizeof(halAddress), "%s", address.busAddress.c_str());
     52     } else if ((!isInput && (halDevice & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
     53                (isInput && (halDevice & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
     54         snprintf(halAddress, sizeof(halAddress), "%s", address.rSubmixAddress.c_str());
     55     }
     56     return halAddress;
     57 }
     58 
     59 #if MAJOR_VERSION >= 4
     60 status_t deviceAddressFromHal(audio_devices_t device, const char* halAddress,
     61                               DeviceAddress* address) {
     62     if (address == nullptr) {
     63         return BAD_VALUE;
     64     }
     65     address->device = AudioDevice(device);
     66     if (halAddress == nullptr || strnlen(halAddress, AUDIO_DEVICE_MAX_ADDRESS_LEN) == 0) {
     67         return OK;
     68     }
     69 
     70     const bool isInput = (device & AUDIO_DEVICE_BIT_IN) != 0;
     71     if (isInput) device &= ~AUDIO_DEVICE_BIT_IN;
     72     if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_A2DP) != 0) ||
     73         (isInput && (device & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) != 0)) {
     74         int status =
     75             sscanf(halAddress, "%hhX:%hhX:%hhX:%hhX:%hhX:%hhX", &address->address.mac[0],
     76                    &address->address.mac[1], &address->address.mac[2], &address->address.mac[3],
     77                    &address->address.mac[4], &address->address.mac[5]);
     78         return status == 6 ? OK : BAD_VALUE;
     79     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_IP) != 0) ||
     80                (isInput && (device & AUDIO_DEVICE_IN_IP) != 0)) {
     81         int status =
     82             sscanf(halAddress, "%hhu.%hhu.%hhu.%hhu", &address->address.ipv4[0],
     83                    &address->address.ipv4[1], &address->address.ipv4[2], &address->address.ipv4[3]);
     84         return status == 4 ? OK : BAD_VALUE;
     85     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_ALL_USB)) != 0 ||
     86                (isInput && (device & AUDIO_DEVICE_IN_ALL_USB)) != 0) {
     87         int status = sscanf(halAddress, "card=%d;device=%d", &address->address.alsa.card,
     88                             &address->address.alsa.device);
     89         return status == 2 ? OK : BAD_VALUE;
     90     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_BUS) != 0) ||
     91                (isInput && (device & AUDIO_DEVICE_IN_BUS) != 0)) {
     92         address->busAddress = halAddress;
     93         return OK;
     94     } else if ((!isInput && (device & AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) != 0 ||
     95                (isInput && (device & AUDIO_DEVICE_IN_REMOTE_SUBMIX) != 0)) {
     96         address->rSubmixAddress = halAddress;
     97         return OK;
     98     }
     99     address->busAddress = halAddress;
    100     return OK;
    101 }
    102 
    103 AudioMicrophoneChannelMapping halToChannelMapping(audio_microphone_channel_mapping_t mapping) {
    104     switch (mapping) {
    105         case AUDIO_MICROPHONE_CHANNEL_MAPPING_UNUSED:
    106             return AudioMicrophoneChannelMapping::UNUSED;
    107         case AUDIO_MICROPHONE_CHANNEL_MAPPING_DIRECT:
    108             return AudioMicrophoneChannelMapping::DIRECT;
    109         case AUDIO_MICROPHONE_CHANNEL_MAPPING_PROCESSED:
    110             return AudioMicrophoneChannelMapping::PROCESSED;
    111         default:
    112             ALOGE("Invalid channel mapping type: %d", mapping);
    113             return AudioMicrophoneChannelMapping::UNUSED;
    114     }
    115 }
    116 
    117 AudioMicrophoneLocation halToLocation(audio_microphone_location_t location) {
    118     switch (location) {
    119         default:
    120         case AUDIO_MICROPHONE_LOCATION_UNKNOWN:
    121             return AudioMicrophoneLocation::UNKNOWN;
    122         case AUDIO_MICROPHONE_LOCATION_MAINBODY:
    123             return AudioMicrophoneLocation::MAINBODY;
    124         case AUDIO_MICROPHONE_LOCATION_MAINBODY_MOVABLE:
    125             return AudioMicrophoneLocation::MAINBODY_MOVABLE;
    126         case AUDIO_MICROPHONE_LOCATION_PERIPHERAL:
    127             return AudioMicrophoneLocation::PERIPHERAL;
    128     }
    129 }
    130 
    131 AudioMicrophoneDirectionality halToDirectionality(audio_microphone_directionality_t dir) {
    132     switch (dir) {
    133         default:
    134         case AUDIO_MICROPHONE_DIRECTIONALITY_UNKNOWN:
    135             return AudioMicrophoneDirectionality::UNKNOWN;
    136         case AUDIO_MICROPHONE_DIRECTIONALITY_OMNI:
    137             return AudioMicrophoneDirectionality::OMNI;
    138         case AUDIO_MICROPHONE_DIRECTIONALITY_BI_DIRECTIONAL:
    139             return AudioMicrophoneDirectionality::BI_DIRECTIONAL;
    140         case AUDIO_MICROPHONE_DIRECTIONALITY_CARDIOID:
    141             return AudioMicrophoneDirectionality::CARDIOID;
    142         case AUDIO_MICROPHONE_DIRECTIONALITY_HYPER_CARDIOID:
    143             return AudioMicrophoneDirectionality::HYPER_CARDIOID;
    144         case AUDIO_MICROPHONE_DIRECTIONALITY_SUPER_CARDIOID:
    145             return AudioMicrophoneDirectionality::SUPER_CARDIOID;
    146     }
    147 }
    148 
    149 bool halToMicrophoneCharacteristics(MicrophoneInfo* pDst,
    150                                     const struct audio_microphone_characteristic_t& src) {
    151     bool status = false;
    152     if (pDst != NULL) {
    153         pDst->deviceId = src.device_id;
    154 
    155         if (deviceAddressFromHal(src.device, src.address, &pDst->deviceAddress) != OK) {
    156             return false;
    157         }
    158         pDst->channelMapping.resize(AUDIO_CHANNEL_COUNT_MAX);
    159         for (size_t ch = 0; ch < pDst->channelMapping.size(); ch++) {
    160             pDst->channelMapping[ch] = halToChannelMapping(src.channel_mapping[ch]);
    161         }
    162         pDst->location = halToLocation(src.location);
    163         pDst->group = (AudioMicrophoneGroup)src.group;
    164         pDst->indexInTheGroup = (uint32_t)src.index_in_the_group;
    165         pDst->sensitivity = src.sensitivity;
    166         pDst->maxSpl = src.max_spl;
    167         pDst->minSpl = src.min_spl;
    168         pDst->directionality = halToDirectionality(src.directionality);
    169         pDst->frequencyResponse.resize(src.num_frequency_responses);
    170         for (size_t k = 0; k < src.num_frequency_responses; k++) {
    171             pDst->frequencyResponse[k].frequency = src.frequency_responses[0][k];
    172             pDst->frequencyResponse[k].level = src.frequency_responses[1][k];
    173         }
    174         pDst->position.x = src.geometric_location.x;
    175         pDst->position.y = src.geometric_location.y;
    176         pDst->position.z = src.geometric_location.z;
    177 
    178         pDst->orientation.x = src.orientation.x;
    179         pDst->orientation.y = src.orientation.y;
    180         pDst->orientation.z = src.orientation.z;
    181 
    182         status = true;
    183     }
    184     return status;
    185 }
    186 #endif
    187 
    188 }  // namespace implementation
    189 }  // namespace CPP_VERSION
    190 }  // namespace audio
    191 }  // namespace hardware
    192 }  // namespace android
    193