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
deviceAddressToHal(const DeviceAddress & address)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
deviceAddressFromHal(audio_devices_t device,const char * halAddress,DeviceAddress * address)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
halToChannelMapping(audio_microphone_channel_mapping_t mapping)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
halToLocation(audio_microphone_location_t location)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
halToDirectionality(audio_microphone_directionality_t dir)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
halToMicrophoneCharacteristics(MicrophoneInfo * pDst,const struct audio_microphone_characteristic_t & src)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