• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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