blob: 916ed4092af9817f8b224d94c54ad3234aa0839d [file] [log] [blame]
Shunkai Yao242521c2023-01-29 18:08:09 +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 <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 <media/audiohal/AudioEffectUuid.h>
27#include <system/audio_effects/effect_equalizer.h>
28
29#include <utils/Log.h>
30
31#include "AidlConversionEq.h"
32
33namespace android {
34namespace effect {
35
36using ::aidl::android::getParameterSpecificField;
37using ::aidl::android::aidl_utils::statusTFromBinderStatus;
38using ::aidl::android::hardware::audio::effect::Equalizer;
39using ::aidl::android::hardware::audio::effect::Parameter;
Shunkai Yao5a6f5442023-02-21 17:58:46 +000040using ::aidl::android::hardware::audio::effect::Range;
41using ::android::base::unexpected;
Shunkai Yao242521c2023-01-29 18:08:09 +000042using ::android::status_t;
43using utils::EffectParamReader;
44using utils::EffectParamWriter;
45
46status_t AidlConversionEq::setParameter(EffectParamReader& param) {
47 uint32_t type;
Shunkai Yao5a6f5442023-02-21 17:58:46 +000048 if (OK != param.readFromParameter(&type)) {
Shunkai Yao242521c2023-01-29 18:08:09 +000049 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: {
Shunkai Yao5a6f5442023-02-21 17:58:46 +000056 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 }
Shunkai Yao242521c2023-01-29 18:08:09 +000061 aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)value);
Shunkai Yao5a6f5442023-02-21 17:58:46 +000062 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
Shunkai Yao242521c2023-01-29 18:08:09 +000063 }
64 case EQ_PARAM_BAND_LEVEL: {
65 int32_t band;
Shunkai Yao5a6f5442023-02-21 17:58:46 +000066 int16_t level;
67 if (OK != param.readFromParameter(&band) || OK != param.readFromValue(&level)) {
Shunkai Yao242521c2023-01-29 18:08:09 +000068 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);
Shunkai Yao5a6f5442023-02-21 17:58:46 +000073 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
Shunkai Yao242521c2023-01-29 18:08:09 +000074 }
75 case EQ_PARAM_PROPERTIES: {
Shunkai Yao5a6f5442023-02-21 17:58:46 +000076 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 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
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 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
Shunkai Yao242521c2023-01-29 18:08:09 +0000102 }
103 default: {
104 // TODO: implement vendor extension parameters
105 ALOGW("%s unknown param %s", __func__, param.toString().c_str());
106 return BAD_VALUE;
107 }
108 }
Shunkai Yao242521c2023-01-29 18:08:09 +0000109}
110
111aidl::ConversionResult<Parameter> AidlConversionEq::getAidlParameter(Equalizer::Tag tag) {
112 Parameter aidlParam;
113 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Equalizer, equalizerTag, tag);
114 RETURN_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
115 return aidlParam;
116}
117
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000118aidl::ConversionResult<int32_t> AidlConversionEq::getParameterPreset() {
119 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::preset));
120 return VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Equalizer, equalizer,
121 Equalizer::preset, int32_t));
122}
123
124aidl::ConversionResult<std::string> AidlConversionEq::getParameterPresetName(
125 EffectParamWriter& param) {
126 int32_t presetIdx;
127 if (OK != param.readFromParameter(&presetIdx)) {
128 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
129 return unexpected(BAD_VALUE);
130 }
131 Parameter aidlParam = VALUE_OR_RETURN(getAidlParameter(Equalizer::presets));
132 const auto& presets = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
133 aidlParam, Equalizer, equalizer, Equalizer::presets, std::vector<Equalizer::Preset>));
134 for (const auto& preset : presets) {
135 if (presetIdx == preset.index) {
136 return preset.name;
137 }
138 }
139 return unexpected(BAD_VALUE);
140}
141
Shunkai Yao242521c2023-01-29 18:08:09 +0000142status_t AidlConversionEq::getParameter(EffectParamWriter& param) {
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000143 uint32_t type = 0;
144 if (OK != param.readFromParameter(&type)) {
Shunkai Yao242521c2023-01-29 18:08:09 +0000145 param.setStatus(BAD_VALUE);
146 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
147 return BAD_VALUE;
148 }
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000149
Shunkai Yao242521c2023-01-29 18:08:09 +0000150 switch (type) {
151 case EQ_PARAM_NUM_BANDS: {
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000152 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
153 const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
Shunkai Yao242521c2023-01-29 18:08:09 +0000154 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
155 std::vector<Equalizer::BandLevel>));
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000156 uint16_t bands = bandLevels.size();
157 return param.writeToValue(&bands);
158 }
159 case EQ_PARAM_LEVEL_RANGE: {
160 const auto& ranges = mDesc.capability.range.get<Range::equalizer>();
161 for (const auto& r : ranges) {
162 if (r.min.getTag() == Equalizer::bandLevels &&
163 r.max.getTag() == Equalizer::bandLevels) {
164 const auto& aidlMin = r.min.get<Equalizer::bandLevels>();
165 const auto& aidlMax = r.max.get<Equalizer::bandLevels>();
166 int16_t min =
167 std::min_element(aidlMin.begin(), aidlMin.end(), [](auto& a, auto& b) {
168 return a.levelMb < b.levelMb;
169 })->levelMb;
170 int16_t max =
171 std::max_element(aidlMax.begin(), aidlMax.end(), [](auto& a, auto& b) {
172 return a.levelMb < b.levelMb;
173 })->levelMb;
174 return (OK == param.writeToValue(&min) && OK == param.writeToValue(&max))
175 ? OK
176 : BAD_VALUE;
177 }
178 }
179 break;
180 }
181 case EQ_PARAM_BAND_LEVEL: {
182 int32_t bandIdx;
183 if (OK != param.readFromParameter(&bandIdx)) {
184 break;
185 }
186
187 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
188 const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
189 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
190 std::vector<Equalizer::BandLevel>));
191 for (const auto& band : bandLevels) {
192 if (band.index == bandIdx) {
193 return param.writeToValue((uint16_t *)&band.levelMb);
194 }
195 }
196 break;
197 }
198 case EQ_PARAM_CENTER_FREQ: {
199 int32_t index;
200 if (OK != param.readFromParameter(&index)) {
201 break;
202 }
203
204 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::centerFreqMh));
205 const auto& freqs = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
206 aidlParam, Equalizer, equalizer, Equalizer::centerFreqMh, std::vector<int>));
207 if ((size_t)index >= freqs.size()) {
208 ALOGE("%s index %d exceed size %zu", __func__, index, freqs.size());
209 break;
210 }
211 return param.writeToValue(&freqs[index]);
212 }
213 case EQ_PARAM_BAND_FREQ_RANGE: {
214 int32_t index;
215 if (OK != param.readFromParameter(&index)) {
216 break;
217 }
218
219 Parameter aidlParam =
220 VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
221 const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
222 aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
223 std::vector<Equalizer::BandFrequency>));
224 for (const auto& band : bands) {
225 if (band.index == index) {
226 return (OK == param.writeToValue(&band.minMh) &&
227 OK == param.writeToValue(&band.maxMh))
228 ? OK
229 : BAD_VALUE;
230 }
231 }
232 break;
233 }
234 case EQ_PARAM_GET_BAND: {
235 int32_t freq;
236 if (OK != param.readFromParameter(&freq)) {
237 break;
238 }
239
240 Parameter aidlParam =
241 VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
242 const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
243 aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
244 std::vector<Equalizer::BandFrequency>));
245 for (const auto& band : bands) {
246 if (freq >= band.minMh && freq <= band.maxMh) {
247 return param.writeToValue((uint16_t*)&band.index);
248 }
249 }
250 break;
251 }
252 case EQ_PARAM_CUR_PRESET: {
253 int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
254 return param.writeToValue((uint16_t*)&preset);
255 }
256 case EQ_PARAM_GET_NUM_OF_PRESETS: {
257 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::presets));
258 const auto& presets = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
259 aidlParam, Equalizer, equalizer, Equalizer::presets,
260 std::vector<Equalizer::Preset>));
261 uint16_t num = presets.size();
Shunkai Yao242521c2023-01-29 18:08:09 +0000262 return param.writeToValue(&num);
263 }
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000264 case EQ_PARAM_GET_PRESET_NAME: {
265 std::string name = VALUE_OR_RETURN_STATUS(getParameterPresetName(param));
266 return param.writeToValue(name.c_str(), name.length());
267 }
268 case EQ_PARAM_PROPERTIES: {
269 int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
270 if (OK != param.writeToValue((uint16_t*)&preset)) {
271 break;
272 }
273 Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
274 std::vector<Equalizer::BandLevel> bandLevels =
275 VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
276 aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
277 std::vector<Equalizer::BandLevel>));
278 uint16_t bands = bandLevels.size();
279 if (OK != param.writeToValue(&bands)) {
280 break;
281 }
282 std::sort(bandLevels.begin(), bandLevels.end(),
283 [](const auto& a, const auto& b) { return a.index < b.index; });
284 for (const auto& level : bandLevels) {
285 if (status_t status = param.writeToValue((uint16_t*)&level.levelMb); status != OK) {
286 return status;
287 }
288 }
289 return OK;
290 }
291 default: {
Shunkai Yao242521c2023-01-29 18:08:09 +0000292 ALOGW("%s unknown param %s", __func__, param.toString().c_str());
293 return BAD_VALUE;
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000294 }
Shunkai Yao242521c2023-01-29 18:08:09 +0000295 }
Shunkai Yao5a6f5442023-02-21 17:58:46 +0000296
297 param.setStatus(BAD_VALUE);
298 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
299 return BAD_VALUE;
Shunkai Yao242521c2023-01-29 18:08:09 +0000300}
301
302} // namespace effect
303} // namespace android