1/*
2 * Copyright (C) 2015 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 "TypeConverter.h"
18
19namespace android {
20
21#define MAKE_STRING_FROM_ENUM(string) { #string, string }
22
23template <>
24const DeviceConverter::Table DeviceConverter::mTable[] = {
25        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_EARPIECE),
26        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPEAKER),
27        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPEAKER_SAFE),
28        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADSET),
29        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_WIRED_HEADPHONE),
30        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO),
31        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET),
32        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT),
33        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_SCO),
34        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP),
35        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES),
36        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER),
37        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_A2DP),
38        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_DIGITAL),
39        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HDMI),
40        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET),
41        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET),
42        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_ACCESSORY),
43        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_USB_DEVICE),
44        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_ALL_USB),
45        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_REMOTE_SUBMIX),
46        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_TELEPHONY_TX),
47        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_LINE),
48        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_HDMI_ARC),
49        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_SPDIF),
50        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_FM),
51        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_AUX_LINE),
52        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_IP),
53        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_BUS),
54        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_OUT_STUB),
55        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AMBIENT),
56        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUILTIN_MIC),
57        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET),
58        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ALL_SCO),
59        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_WIRED_HEADSET),
60        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_AUX_DIGITAL),
61        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_HDMI),
62        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TELEPHONY_RX),
63        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_VOICE_CALL),
64        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BACK_MIC),
65        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_REMOTE_SUBMIX),
66        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_ANLG_DOCK_HEADSET),
67        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_DGTL_DOCK_HEADSET),
68        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_ACCESSORY),
69        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_USB_DEVICE),
70        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_FM_TUNER),
71        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_TV_TUNER),
72        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LINE),
73        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_SPDIF),
74        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BLUETOOTH_A2DP),
75        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_LOOPBACK),
76        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_IP),
77        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_BUS),
78        MAKE_STRING_FROM_ENUM(AUDIO_DEVICE_IN_STUB),
79};
80
81template<>
82const size_t DeviceConverter::mSize = sizeof(DeviceConverter::mTable) /
83        sizeof(DeviceConverter::mTable[0]);
84
85
86template <>
87const OutputFlagConverter::Table OutputFlagConverter::mTable[] = {
88    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_DIRECT),
89    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_PRIMARY),
90    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_FAST),
91    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_DEEP_BUFFER),
92    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD),
93    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_NON_BLOCKING),
94    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_HW_AV_SYNC),
95    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_TTS),
96    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_RAW),
97    MAKE_STRING_FROM_ENUM(AUDIO_OUTPUT_FLAG_SYNC),
98};
99template<>
100const size_t OutputFlagConverter::mSize = sizeof(OutputFlagConverter::mTable) /
101        sizeof(OutputFlagConverter::mTable[0]);
102
103
104template <>
105const InputFlagConverter::Table InputFlagConverter::mTable[] = {
106    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_FAST),
107    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_HW_HOTWORD),
108    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_RAW),
109    MAKE_STRING_FROM_ENUM(AUDIO_INPUT_FLAG_SYNC),
110};
111template<>
112const size_t InputFlagConverter::mSize = sizeof(InputFlagConverter::mTable) /
113        sizeof(InputFlagConverter::mTable[0]);
114
115
116template <>
117const FormatConverter::Table FormatConverter::mTable[] = {
118    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_16_BIT),
119    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_8_BIT),
120    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_32_BIT),
121    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_8_24_BIT),
122    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_FLOAT),
123    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_PCM_24_BIT_PACKED),
124    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_MP3),
125    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC),
126    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_MAIN),
127    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LC),
128    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_SSR),
129    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LTP),
130    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_HE_V1),
131    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_SCALABLE),
132    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ERLC),
133    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_LD),
134    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_HE_V2),
135    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AAC_ELD),
136    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_VORBIS),
137    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V1),
138    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_HE_AAC_V2),
139    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_OPUS),
140    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_AC3),
141    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_E_AC3),
142    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_DTS),
143    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_DTS_HD),
144    MAKE_STRING_FROM_ENUM(AUDIO_FORMAT_IEC61937),
145};
146template<>
147const size_t FormatConverter::mSize = sizeof(FormatConverter::mTable) /
148        sizeof(FormatConverter::mTable[0]);
149
150
151template <>
152const OutputChannelConverter::Table OutputChannelConverter::mTable[] = {
153    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_MONO),
154    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_STEREO),
155    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_QUAD),
156    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_5POINT1),
157    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_OUT_7POINT1),
158};
159template<>
160const size_t OutputChannelConverter::mSize = sizeof(OutputChannelConverter::mTable) /
161        sizeof(OutputChannelConverter::mTable[0]);
162
163
164template <>
165const InputChannelConverter::Table InputChannelConverter::mTable[] = {
166    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_MONO),
167    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_STEREO),
168    MAKE_STRING_FROM_ENUM(AUDIO_CHANNEL_IN_FRONT_BACK),
169};
170template<>
171const size_t InputChannelConverter::mSize = sizeof(InputChannelConverter::mTable) /
172        sizeof(InputChannelConverter::mTable[0]);
173
174template <>
175const ChannelIndexConverter::Table ChannelIndexConverter::mTable[] = {
176    {"AUDIO_CHANNEL_INDEX_MASK_1", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_1)},
177    {"AUDIO_CHANNEL_INDEX_MASK_2", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_2)},
178    {"AUDIO_CHANNEL_INDEX_MASK_3", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_3)},
179    {"AUDIO_CHANNEL_INDEX_MASK_4", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_4)},
180    {"AUDIO_CHANNEL_INDEX_MASK_5", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_5)},
181    {"AUDIO_CHANNEL_INDEX_MASK_6", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_6)},
182    {"AUDIO_CHANNEL_INDEX_MASK_7", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_7)},
183    {"AUDIO_CHANNEL_INDEX_MASK_8", static_cast<audio_channel_mask_t>(AUDIO_CHANNEL_INDEX_MASK_8)},
184};
185template<>
186const size_t ChannelIndexConverter::mSize = sizeof(ChannelIndexConverter::mTable) /
187        sizeof(ChannelIndexConverter::mTable[0]);
188
189
190template <>
191const GainModeConverter::Table GainModeConverter::mTable[] = {
192    MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_JOINT),
193    MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_CHANNELS),
194    MAKE_STRING_FROM_ENUM(AUDIO_GAIN_MODE_RAMP),
195};
196
197template<>
198const size_t GainModeConverter::mSize = sizeof(GainModeConverter::mTable) /
199        sizeof(GainModeConverter::mTable[0]);
200
201template <>
202const DeviceCategoryConverter::Table DeviceCategoryConverter::mTable[] = {
203    MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_HEADSET),
204    MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_SPEAKER),
205    MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EARPIECE),
206    MAKE_STRING_FROM_ENUM(DEVICE_CATEGORY_EXT_MEDIA)
207};
208
209template<>
210const size_t DeviceCategoryConverter::mSize = sizeof(DeviceCategoryConverter::mTable) /
211        sizeof(DeviceCategoryConverter::mTable[0]);
212
213template <>
214const StreamTypeConverter::Table StreamTypeConverter::mTable[] = {
215    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_VOICE_CALL),
216    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_SYSTEM),
217    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_RING),
218    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_MUSIC),
219    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ALARM),
220    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_NOTIFICATION),
221    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_BLUETOOTH_SCO ),
222    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ENFORCED_AUDIBLE),
223    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_DTMF),
224    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_TTS),
225    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_ACCESSIBILITY),
226    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_REROUTING),
227    MAKE_STRING_FROM_ENUM(AUDIO_STREAM_PATCH),
228};
229
230template<>
231const size_t StreamTypeConverter::mSize = sizeof(StreamTypeConverter::mTable) /
232        sizeof(StreamTypeConverter::mTable[0]);
233
234template <class Traits>
235bool TypeConverter<Traits>::toString(const typename Traits::Type &value, std::string &str)
236{
237    for (size_t i = 0; i < mSize; i++) {
238        if (mTable[i].value == value) {
239            str = mTable[i].literal;
240            return true;
241        }
242    }
243    return false;
244}
245
246template <class Traits>
247bool TypeConverter<Traits>::fromString(const std::string &str, typename Traits::Type &result)
248{
249    for (size_t i = 0; i < mSize; i++) {
250        if (strcmp(mTable[i].literal, str.c_str()) == 0) {
251            ALOGV("stringToEnum() found %s", mTable[i].literal);
252            result = mTable[i].value;
253            return true;
254        }
255    }
256    return false;
257}
258
259template <class Traits>
260void TypeConverter<Traits>::collectionFromString(const std::string &str,
261                                                 typename Traits::Collection &collection,
262                                                 const char *del)
263{
264    char *literal = strdup(str.c_str());
265
266    for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
267        typename Traits::Type value;
268        if (fromString(cstr, value)) {
269            collection.add(value);
270        }
271    }
272    free(literal);
273}
274
275template <class Traits>
276uint32_t TypeConverter<Traits>::maskFromString(const std::string &str, const char *del)
277{
278    char *literal = strdup(str.c_str());
279    uint32_t value = 0;
280    for (const char *cstr = strtok(literal, del); cstr != NULL; cstr = strtok(NULL, del)) {
281        typename Traits::Type type;
282        if (fromString(cstr, type)) {
283            value |= static_cast<uint32_t>(type);
284        }
285    }
286    free(literal);
287    return value;
288}
289
290template class TypeConverter<DeviceTraits>;
291template class TypeConverter<OutputFlagTraits>;
292template class TypeConverter<InputFlagTraits>;
293template class TypeConverter<FormatTraits>;
294template class TypeConverter<OutputChannelTraits>;
295template class TypeConverter<InputChannelTraits>;
296template class TypeConverter<ChannelIndexTraits>;
297template class TypeConverter<GainModeTraits>;
298template class TypeConverter<StreamTraits>;
299template class TypeConverter<DeviceCategoryTraits>;
300
301}; // namespace android
302
303