1 /*
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 <cstdint>
18 #include <cstring>
19 #include <optional>
20 #define LOG_TAG "AidlConversionEQ"
21 //#define LOG_NDEBUG 0
22
23 #include <error/expected_utils.h>
24 #include <media/AidlConversionNdk.h>
25 #include <media/AidlConversionEffect.h>
26 #include <system/audio_effects/effect_equalizer.h>
27
28 #include <utils/Log.h>
29
30 #include "AidlConversionEq.h"
31
32 namespace android {
33 namespace effect {
34
35 using ::aidl::android::getParameterSpecificField;
36 using ::aidl::android::aidl_utils::statusTFromBinderStatus;
37 using ::aidl::android::hardware::audio::effect::Equalizer;
38 using ::aidl::android::hardware::audio::effect::Parameter;
39 using ::aidl::android::hardware::audio::effect::Range;
40 using ::aidl::android::hardware::audio::effect::VendorExtension;
41 using ::android::base::unexpected;
42 using ::android::status_t;
43 using utils::EffectParamReader;
44 using utils::EffectParamWriter;
45
setParameter(EffectParamReader & param)46 status_t AidlConversionEq::setParameter(EffectParamReader& param) {
47 uint32_t type;
48 if (OK != param.readFromParameter(&type)) {
49 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
50 return BAD_VALUE;
51 }
52
53 Parameter aidlParam;
54 switch (type) {
55 case EQ_PARAM_CUR_PRESET: {
56 uint16_t value = 0;
57 if (OK != param.readFromValue(&value)) {
58 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
59 return BAD_VALUE;
60 }
61 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)value);
62 break;
63 }
64 case EQ_PARAM_BAND_LEVEL: {
65 int32_t band;
66 int16_t level;
67 if (OK != param.readFromParameter(&band) || OK != param.readFromValue(&level)) {
68 ALOGE("%s invalid bandLevel param %s", __func__, param.toString().c_str());
69 return BAD_VALUE;
70 }
71 std::vector<Equalizer::BandLevel> bandLevels = {{.index = band, .levelMb = level}};
72 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, bandLevels, bandLevels);
73 break;
74 }
75 case EQ_PARAM_PROPERTIES: {
76 int16_t num;
77 if (OK != param.readFromValue(&num)) {
78 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
79 return BAD_VALUE;
80 }
81 // set preset if it's valid
82 if (num >= 0) {
83 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)num);
84 break;
85 }
86 // set bandLevel if no preset was set
87 if (OK != param.readFromValue(&num)) {
88 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
89 return BAD_VALUE;
90 }
91 std::vector<Equalizer::BandLevel> bandLevels;
92 for (int i = 0; i < num; i++) {
93 Equalizer::BandLevel level({.index = i});
94 if (OK != param.readFromValue((uint16_t*)&level.levelMb)) {
95 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
96 return BAD_VALUE;
97 }
98 bandLevels.push_back(level);
99 }
100 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, bandLevels, bandLevels);
101 break;
102 }
103 default: {
104 // for vendor extension, copy data area to the DefaultExtension, parameter ignored
105 VendorExtension ext = VALUE_OR_RETURN_STATUS(
106 aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
107 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, vendor, ext);
108 break;
109 }
110 }
111
112 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
113 }
114
getAidlParameter(Equalizer::Tag tag)115 ConversionResult<Parameter> AidlConversionEq::getAidlParameter(Equalizer::Tag tag) {
116 Parameter aidlParam;
117 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Equalizer, equalizerTag, tag);
118 RETURN_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
119 return aidlParam;
120 }
121
getParameterPreset()122 ConversionResult<int32_t> AidlConversionEq::getParameterPreset() {
123 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::preset));
124 return VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Equalizer, equalizer,
125 Equalizer::preset, int32_t));
126 }
127
getParameterPresetName(EffectParamWriter & param)128 ConversionResult<std::string> AidlConversionEq::getParameterPresetName(
129 EffectParamWriter& param) {
130 int32_t presetIdx;
131 if (OK != param.readFromParameter(&presetIdx)) {
132 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
133 return unexpected(BAD_VALUE);
134 }
135 Parameter aidlParam = VALUE_OR_RETURN(getAidlParameter(Equalizer::presets));
136 const auto& presets = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
137 aidlParam, Equalizer, equalizer, Equalizer::presets, std::vector<Equalizer::Preset>));
138 for (const auto& preset : presets) {
139 if (presetIdx == preset.index) {
140 return preset.name;
141 }
142 }
143 return unexpected(BAD_VALUE);
144 }
145
getParameter(EffectParamWriter & param)146 status_t AidlConversionEq::getParameter(EffectParamWriter& param) {
147 uint32_t type = 0;
148 if (OK != param.readFromParameter(&type)) {
149 param.setStatus(BAD_VALUE);
150 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
151 return BAD_VALUE;
152 }
153
154 switch (type) {
155 case EQ_PARAM_NUM_BANDS: {
156 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
157 const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
158 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
159 std::vector<Equalizer::BandLevel>));
160 uint16_t bands = bandLevels.size();
161 return param.writeToValue(&bands);
162 }
163 case EQ_PARAM_LEVEL_RANGE: {
164 if (mDesc.capability.range.getTag() != Range::equalizer) {
165 return OK;
166 }
167 const auto& ranges = mDesc.capability.range.get<Range::equalizer>();
168 for (const auto& r : ranges) {
169 if (r.min.getTag() == Equalizer::bandLevels &&
170 r.max.getTag() == Equalizer::bandLevels) {
171 const auto& aidlMin = r.min.get<Equalizer::bandLevels>();
172 const auto& aidlMax = r.max.get<Equalizer::bandLevels>();
173 int16_t min =
174 std::min_element(aidlMin.begin(), aidlMin.end(), [](auto& a, auto& b) {
175 return a.levelMb < b.levelMb;
176 })->levelMb;
177 int16_t max =
178 std::max_element(aidlMax.begin(), aidlMax.end(), [](auto& a, auto& b) {
179 return a.levelMb < b.levelMb;
180 })->levelMb;
181 return (OK == param.writeToValue(&min) && OK == param.writeToValue(&max))
182 ? OK
183 : BAD_VALUE;
184 }
185 }
186 break;
187 }
188 case EQ_PARAM_BAND_LEVEL: {
189 int32_t bandIdx;
190 if (OK != param.readFromParameter(&bandIdx)) {
191 break;
192 }
193
194 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
195 const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
196 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
197 std::vector<Equalizer::BandLevel>));
198 for (const auto& band : bandLevels) {
199 if (band.index == bandIdx) {
200 return param.writeToValue((uint16_t *)&band.levelMb);
201 }
202 }
203 break;
204 }
205 case EQ_PARAM_CENTER_FREQ: {
206 int32_t index;
207 if (OK != param.readFromParameter(&index)) {
208 break;
209 }
210
211 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::centerFreqMh));
212 const auto& freqs = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
213 aidlParam, Equalizer, equalizer, Equalizer::centerFreqMh, std::vector<int>));
214 if ((size_t)index >= freqs.size()) {
215 ALOGE("%s index %d exceed size %zu", __func__, index, freqs.size());
216 break;
217 }
218 return param.writeToValue(&freqs[index]);
219 }
220 case EQ_PARAM_BAND_FREQ_RANGE: {
221 int32_t index;
222 if (OK != param.readFromParameter(&index)) {
223 break;
224 }
225
226 Parameter aidlParam =
227 VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
228 const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
229 aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
230 std::vector<Equalizer::BandFrequency>));
231 for (const auto& band : bands) {
232 if (band.index == index) {
233 return (OK == param.writeToValue(&band.minMh) &&
234 OK == param.writeToValue(&band.maxMh))
235 ? OK
236 : BAD_VALUE;
237 }
238 }
239 break;
240 }
241 case EQ_PARAM_GET_BAND: {
242 int32_t freq;
243 if (OK != param.readFromParameter(&freq)) {
244 break;
245 }
246
247 Parameter aidlParam =
248 VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
249 const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
250 aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
251 std::vector<Equalizer::BandFrequency>));
252 for (const auto& band : bands) {
253 if (freq >= band.minMh && freq <= band.maxMh) {
254 return param.writeToValue((uint16_t*)&band.index);
255 }
256 }
257 break;
258 }
259 case EQ_PARAM_CUR_PRESET: {
260 int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
261 return param.writeToValue((uint16_t*)&preset);
262 }
263 case EQ_PARAM_GET_NUM_OF_PRESETS: {
264 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::presets));
265 const auto& presets = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
266 aidlParam, Equalizer, equalizer, Equalizer::presets,
267 std::vector<Equalizer::Preset>));
268 uint16_t num = presets.size();
269 return param.writeToValue(&num);
270 }
271 case EQ_PARAM_GET_PRESET_NAME: {
272 std::string name = VALUE_OR_RETURN_STATUS(getParameterPresetName(param));
273 return param.writeToValue(name.c_str(), name.length());
274 }
275 case EQ_PARAM_PROPERTIES: {
276 int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
277 if (OK != param.writeToValue((uint16_t*)&preset)) {
278 break;
279 }
280 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
281 std::vector<Equalizer::BandLevel> bandLevels =
282 VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
283 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
284 std::vector<Equalizer::BandLevel>));
285 uint16_t bands = bandLevels.size();
286 if (OK != param.writeToValue(&bands)) {
287 break;
288 }
289 std::sort(bandLevels.begin(), bandLevels.end(),
290 [](const auto& a, const auto& b) { return a.index < b.index; });
291 for (const auto& level : bandLevels) {
292 if (status_t status = param.writeToValue((uint16_t*)&level.levelMb); status != OK) {
293 return status;
294 }
295 }
296 return OK;
297 }
298 default: {
299 VENDOR_EXTENSION_GET_AND_RETURN(Equalizer, equalizer, param);
300 }
301 }
302
303 param.setStatus(BAD_VALUE);
304 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
305 return BAD_VALUE;
306 }
307
308 } // namespace effect
309 } // namespace android
310