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