blob: 74d9c289a5310ad81e434722e2b9f0444be852ac [file] [log] [blame]
jiabin253bd322023-01-25 23:57:31 +00001/*
2 * Copyright (C) 2023 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 <map>
18#include <set>
19
20#include <Utils.h>
21#include <aidl/android/media/audio/common/AudioFormatType.h>
22#include <aidl/android/media/audio/common/PcmType.h>
23
24#include "UsbAlsaUtils.h"
25#include "core-impl/utils.h"
26
Mikhail Naganov872d4a62023-03-09 18:19:01 -080027using aidl::android::hardware::audio::common::getChannelCount;
jiabin253bd322023-01-25 23:57:31 +000028using aidl::android::media::audio::common::AudioChannelLayout;
29using aidl::android::media::audio::common::AudioFormatDescription;
30using aidl::android::media::audio::common::AudioFormatType;
31using aidl::android::media::audio::common::PcmType;
jiabin253bd322023-01-25 23:57:31 +000032
33namespace aidl::android::hardware::audio::core::usb {
34
35namespace {
36
37using AudioChannelCountToMaskMap = std::map<unsigned int, AudioChannelLayout>;
38using AudioFormatDescToPcmFormatMap = std::map<AudioFormatDescription, enum pcm_format>;
39using PcmFormatToAudioFormatDescMap = std::map<enum pcm_format, AudioFormatDescription>;
40
41static const AudioChannelLayout INVALID_CHANNEL_LAYOUT =
42 AudioChannelLayout::make<AudioChannelLayout::Tag::invalid>(0);
43
44#define DEFINE_CHANNEL_LAYOUT_MASK(n) \
45 AudioChannelLayout::make<AudioChannelLayout::Tag::layoutMask>(AudioChannelLayout::LAYOUT_##n)
46
47static const std::set<AudioChannelLayout> SUPPORTED_OUT_CHANNEL_LAYOUTS = {
48 DEFINE_CHANNEL_LAYOUT_MASK(MONO), DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
49 DEFINE_CHANNEL_LAYOUT_MASK(2POINT1), DEFINE_CHANNEL_LAYOUT_MASK(QUAD),
50 DEFINE_CHANNEL_LAYOUT_MASK(PENTA), DEFINE_CHANNEL_LAYOUT_MASK(5POINT1),
51 DEFINE_CHANNEL_LAYOUT_MASK(6POINT1), DEFINE_CHANNEL_LAYOUT_MASK(7POINT1),
52 DEFINE_CHANNEL_LAYOUT_MASK(7POINT1POINT4), DEFINE_CHANNEL_LAYOUT_MASK(22POINT2),
53};
54
55static const std::set<AudioChannelLayout> SUPPORTED_IN_CHANNEL_LAYOUTS = {
56 DEFINE_CHANNEL_LAYOUT_MASK(MONO),
57 DEFINE_CHANNEL_LAYOUT_MASK(STEREO),
58};
59
60#define DEFINE_CHANNEL_INDEX_MASK(n) \
61 AudioChannelLayout::make<AudioChannelLayout::Tag::indexMask>(AudioChannelLayout::INDEX_MASK_##n)
62
63static const std::set<AudioChannelLayout> SUPPORTED_INDEX_CHANNEL_LAYOUTS = {
64 DEFINE_CHANNEL_INDEX_MASK(1), DEFINE_CHANNEL_INDEX_MASK(2), DEFINE_CHANNEL_INDEX_MASK(3),
65 DEFINE_CHANNEL_INDEX_MASK(4), DEFINE_CHANNEL_INDEX_MASK(5), DEFINE_CHANNEL_INDEX_MASK(6),
66 DEFINE_CHANNEL_INDEX_MASK(7), DEFINE_CHANNEL_INDEX_MASK(8), DEFINE_CHANNEL_INDEX_MASK(9),
67 DEFINE_CHANNEL_INDEX_MASK(10), DEFINE_CHANNEL_INDEX_MASK(11), DEFINE_CHANNEL_INDEX_MASK(12),
68 DEFINE_CHANNEL_INDEX_MASK(13), DEFINE_CHANNEL_INDEX_MASK(14), DEFINE_CHANNEL_INDEX_MASK(15),
69 DEFINE_CHANNEL_INDEX_MASK(16), DEFINE_CHANNEL_INDEX_MASK(17), DEFINE_CHANNEL_INDEX_MASK(18),
70 DEFINE_CHANNEL_INDEX_MASK(19), DEFINE_CHANNEL_INDEX_MASK(20), DEFINE_CHANNEL_INDEX_MASK(21),
71 DEFINE_CHANNEL_INDEX_MASK(22), DEFINE_CHANNEL_INDEX_MASK(23), DEFINE_CHANNEL_INDEX_MASK(24),
72};
73
74static AudioChannelCountToMaskMap make_ChannelCountToMaskMap(
75 const std::set<AudioChannelLayout>& channelMasks) {
76 AudioChannelCountToMaskMap channelMaskToCountMap;
77 for (const auto& channelMask : channelMasks) {
78 channelMaskToCountMap.emplace(getChannelCount(channelMask), channelMask);
79 }
80 return channelMaskToCountMap;
81}
82
83const AudioChannelCountToMaskMap& getSupportedChannelOutLayoutMap() {
84 static const AudioChannelCountToMaskMap outLayouts =
85 make_ChannelCountToMaskMap(SUPPORTED_OUT_CHANNEL_LAYOUTS);
86 return outLayouts;
87}
88
89const AudioChannelCountToMaskMap& getSupportedChannelInLayoutMap() {
90 static const AudioChannelCountToMaskMap inLayouts =
91 make_ChannelCountToMaskMap(SUPPORTED_IN_CHANNEL_LAYOUTS);
92 return inLayouts;
93}
94
95const AudioChannelCountToMaskMap& getSupportedChannelIndexLayoutMap() {
96 static const AudioChannelCountToMaskMap indexLayouts =
97 make_ChannelCountToMaskMap(SUPPORTED_INDEX_CHANNEL_LAYOUTS);
98 return indexLayouts;
99}
100
101AudioFormatDescription make_AudioFormatDescription(AudioFormatType type) {
102 AudioFormatDescription result;
103 result.type = type;
104 return result;
105}
106
107AudioFormatDescription make_AudioFormatDescription(PcmType pcm) {
108 auto result = make_AudioFormatDescription(AudioFormatType::PCM);
109 result.pcm = pcm;
110 return result;
111}
112
113const AudioFormatDescToPcmFormatMap& getAudioFormatDescriptorToPcmFormatMap() {
114 static const AudioFormatDescToPcmFormatMap formatDescToPcmFormatMap = {
115 {make_AudioFormatDescription(PcmType::UINT_8_BIT), PCM_FORMAT_S8},
116 {make_AudioFormatDescription(PcmType::INT_16_BIT), PCM_FORMAT_S16_LE},
jiabin118c2612023-03-21 23:04:57 +0000117 {make_AudioFormatDescription(PcmType::FIXED_Q_8_24), PCM_FORMAT_S24_LE},
118 {make_AudioFormatDescription(PcmType::INT_24_BIT), PCM_FORMAT_S24_3LE},
jiabin253bd322023-01-25 23:57:31 +0000119 {make_AudioFormatDescription(PcmType::INT_32_BIT), PCM_FORMAT_S32_LE},
120 {make_AudioFormatDescription(PcmType::FLOAT_32_BIT), PCM_FORMAT_FLOAT_LE},
121 };
122 return formatDescToPcmFormatMap;
123}
124
125static PcmFormatToAudioFormatDescMap make_PcmFormatToAudioFormatDescMap(
126 const AudioFormatDescToPcmFormatMap& formatDescToPcmFormatMap) {
127 PcmFormatToAudioFormatDescMap result;
128 for (const auto& formatPair : formatDescToPcmFormatMap) {
129 result.emplace(formatPair.second, formatPair.first);
130 }
131 return result;
132}
133
134const PcmFormatToAudioFormatDescMap& getPcmFormatToAudioFormatDescMap() {
135 static const PcmFormatToAudioFormatDescMap pcmFormatToFormatDescMap =
136 make_PcmFormatToAudioFormatDescMap(getAudioFormatDescriptorToPcmFormatMap());
137 return pcmFormatToFormatDescMap;
138}
139
140} // namespace
141
142AudioChannelLayout getChannelLayoutMaskFromChannelCount(unsigned int channelCount, int isInput) {
143 return findValueOrDefault(
144 isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
145 channelCount, INVALID_CHANNEL_LAYOUT);
146}
147
148AudioChannelLayout getChannelIndexMaskFromChannelCount(unsigned int channelCount) {
149 return findValueOrDefault(getSupportedChannelIndexLayoutMap(), channelCount,
150 INVALID_CHANNEL_LAYOUT);
151}
152
153unsigned int getChannelCountFromChannelMask(const AudioChannelLayout& channelMask, bool isInput) {
154 switch (channelMask.getTag()) {
155 case AudioChannelLayout::Tag::layoutMask: {
156 return findKeyOrDefault(
157 isInput ? getSupportedChannelInLayoutMap() : getSupportedChannelOutLayoutMap(),
158 (unsigned int)getChannelCount(channelMask), 0u /*defaultValue*/);
159 }
160 case AudioChannelLayout::Tag::indexMask: {
161 return findKeyOrDefault(getSupportedChannelIndexLayoutMap(),
162 (unsigned int)getChannelCount(channelMask),
163 0u /*defaultValue*/);
164 }
165 case AudioChannelLayout::Tag::none:
166 case AudioChannelLayout::Tag::invalid:
167 case AudioChannelLayout::Tag::voiceMask:
168 default:
169 return 0;
170 }
171}
172
173AudioFormatDescription legacy2aidl_pcm_format_AudioFormatDescription(enum pcm_format legacy) {
174 return findValueOrDefault(getPcmFormatToAudioFormatDescMap(), legacy, AudioFormatDescription());
175}
176
177pcm_format aidl2legacy_AudioFormatDescription_pcm_format(const AudioFormatDescription& aidl) {
178 return findValueOrDefault(getAudioFormatDescriptorToPcmFormatMap(), aidl, PCM_FORMAT_INVALID);
179}
180
Mikhail Naganov872d4a62023-03-09 18:19:01 -0800181} // namespace aidl::android::hardware::audio::core::usb