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