blob: 4ecaa07118adb450c300c4c3611995dae547a04e [file] [log] [blame]
Shunkai Yaodba8ba32023-01-27 17:02:21 +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 "AidlConversionDp"
21//#define LOG_NDEBUG 0
22
23#include <error/expected_utils.h>
24#include <media/AidlConversionCppNdk.h>
25#include <media/AidlConversionNdk.h>
26#include <media/AidlConversionEffect.h>
27#include <media/audiohal/AudioEffectUuid.h>
28#include <system/audio_effect.h>
29#include <system/audio_effects/effect_dynamicsprocessing.h>
30
31#include <utils/Log.h>
32
33#include "AidlConversionDynamicsProcessing.h"
34
35namespace android {
36namespace effect {
37
38using ::aidl::android::convertIntegral;
39using ::aidl::android::aidl_utils::statusTFromBinderStatus;
40using ::aidl::android::hardware::audio::effect::Capability;
41using ::aidl::android::hardware::audio::effect::DynamicsProcessing;
42using ::aidl::android::hardware::audio::effect::Parameter;
43using ::aidl::android::hardware::audio::effect::toString;
44using ::android::status_t;
45using utils::EffectParamReader;
46using utils::EffectParamWriter;
47
48status_t AidlConversionDp::setParameter(EffectParamReader& param) {
49 uint32_t type = 0;
50 if (OK != param.readFromParameter(&type)) {
51 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
52 return BAD_VALUE;
53 }
54 Parameter aidlParam;
55 switch (type) {
56 case DP_PARAM_INPUT_GAIN: {
57 DynamicsProcessing::InputGain inputGainAidl;
58 if (OK != param.readFromParameter(&inputGainAidl.channel) ||
59 OK != param.readFromValue(&inputGainAidl.gainDb)) {
60 ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
61 return BAD_VALUE;
62 }
63 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, inputGain,
64 {inputGainAidl});
65 break;
66 }
67 case DP_PARAM_ENGINE_ARCHITECTURE: {
68 DynamicsProcessing::EngineArchitecture engine =
69 VALUE_OR_RETURN_STATUS(readEngineArchitectureFromParam(param));
70 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing,
71 engineArchitecture, engine);
72 mEngine = engine;
73 break;
74 }
75 case DP_PARAM_PRE_EQ: {
76 DynamicsProcessing::ChannelConfig chConfig =
77 VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
78 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, preEq,
79 {chConfig});
80 break;
81 }
82 case DP_PARAM_POST_EQ: {
83 DynamicsProcessing::ChannelConfig chConfig =
84 VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
85 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, postEq,
86 {chConfig});
87 break;
88 }
89 case DP_PARAM_MBC: {
90 DynamicsProcessing::ChannelConfig chConfig =
91 VALUE_OR_RETURN_STATUS(readChannelConfigFromParam(param));
92 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, mbc,
93 {chConfig});
94 break;
95 }
96 case DP_PARAM_PRE_EQ_BAND: {
97 DynamicsProcessing::EqBandConfig bandConfig =
98 VALUE_OR_RETURN_STATUS(readEqBandConfigFromParam(param));
99 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, preEqBand,
100 {bandConfig});
101 break;
102 }
103 case DP_PARAM_POST_EQ_BAND: {
104 DynamicsProcessing::EqBandConfig bandConfig =
105 VALUE_OR_RETURN_STATUS(readEqBandConfigFromParam(param));
106 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, postEqBand,
107 {bandConfig});
108 break;
109 }
110 case DP_PARAM_MBC_BAND: {
111 DynamicsProcessing::MbcBandConfig bandConfig =
112 VALUE_OR_RETURN_STATUS(readMbcBandConfigFromParam(param));
113 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, mbcBand,
114 {bandConfig});
115 break;
116 }
117 case DP_PARAM_LIMITER: {
118 DynamicsProcessing::LimiterConfig config =
119 VALUE_OR_RETURN_STATUS(readLimiterConfigFromParam(param));
120 aidlParam = MAKE_SPECIFIC_PARAMETER(DynamicsProcessing, dynamicsProcessing, limiter,
121 {config});
122 break;
123 }
124 default: {
125 ALOGW("%s unknown param %s", __func__, param.toString().c_str());
126 return BAD_VALUE;
127 }
128 }
129
130 return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
131}
132
133status_t AidlConversionDp::getParameter(EffectParamWriter& param) {
134 uint32_t type = 0;
135 if (OK != param.readFromParameter(&type)) {
136 ALOGE("%s invalid param %s", __func__, param.toString().c_str());
137 }
138 Parameter aidlParam;
139 switch (type) {
140 case DP_PARAM_INPUT_GAIN: {
141 int32_t channel;
142 if (OK != param.readFromParameter(&channel)) {
143 ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
144 return BAD_VALUE;
145 }
146 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
147 DynamicsProcessing::inputGain);
148 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
149
150 DynamicsProcessing::Capability cap =
151 mDesc.capability.get<Capability::dynamicsProcessing>();
152 std::vector<DynamicsProcessing::InputGain> gains =
153 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
154 aidlParam, DynamicsProcessing, dynamicsProcessing,
155 DynamicsProcessing::inputGain,
156 std::vector<DynamicsProcessing::InputGain>));
157 for (const auto& gain : gains) {
158 if (gain.channel == channel) {
159 return param.writeToValue(&gain.gainDb);
160 }
161 }
162 ALOGE("%s not able to find channel %d", __func__, channel);
163 return BAD_VALUE;
164 }
165 case DP_PARAM_ENGINE_ARCHITECTURE: {
166 int32_t channel;
167 if (OK != param.readFromParameter(&channel)) {
168 ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
169 return BAD_VALUE;
170 }
171 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
172 DynamicsProcessing::engineArchitecture);
173 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
174
175 DynamicsProcessing::EngineArchitecture engine =
176 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
177 aidlParam, DynamicsProcessing, dynamicsProcessing,
178 DynamicsProcessing::engineArchitecture,
179 DynamicsProcessing::EngineArchitecture));
180 int32_t resolution = VALUE_OR_RETURN_STATUS(
181 aidl::android::aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
182 engine.resolutionPreference));
183 int32_t preEqInUse =
184 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.preEqStage.inUse));
185 int32_t mbcInUse =
186 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.mbcStage.inUse));
187 int32_t postEqInUse =
188 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.postEqStage.inUse));
189 int32_t limiterInUse =
190 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.limiterInUse));
191 if (OK != param.writeToValue(&resolution) ||
192 OK != param.writeToValue(&engine.preferredProcessingDurationMs) ||
193 OK != param.writeToValue(&preEqInUse) ||
194 OK != param.writeToValue(&engine.preEqStage.bandCount) ||
195 OK != param.writeToValue(&mbcInUse) ||
196 OK != param.writeToValue(&engine.mbcStage.bandCount) ||
197 OK != param.writeToValue(&postEqInUse) ||
198 OK != param.writeToValue(&engine.postEqStage.bandCount) ||
199 OK != param.writeToValue(&limiterInUse)) {
200 ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
201 return BAD_VALUE;
202 }
203 mEngine = engine;
204 return OK;
205 }
206 case DP_PARAM_PRE_EQ: {
207 return getChannelConfig(DynamicsProcessing::preEq, param);
208 }
209 case DP_PARAM_POST_EQ: {
210 return getChannelConfig(DynamicsProcessing::postEq, param);
211 }
212 case DP_PARAM_MBC: {
213 return getChannelConfig(DynamicsProcessing::mbc, param);
214 }
215 case DP_PARAM_PRE_EQ_BAND: {
216 return getEqBandConfig(DynamicsProcessing::preEqBand, param);
217 }
218 case DP_PARAM_POST_EQ_BAND: {
219 return getEqBandConfig(DynamicsProcessing::postEqBand, param);
220 }
221 case DP_PARAM_MBC_BAND: {
222 return getMbcBandConfig(param);
223 }
224 case DP_PARAM_LIMITER: {
225 return getLimiterConfig(param);
226 }
227 case DP_PARAM_GET_CHANNEL_COUNT: {
228 uint32_t channel = VALUE_OR_RETURN_STATUS(
229 aidl::android::aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
230 mCommon.input.base.channelMask, true /* input */));
231 if (OK != param.writeToValue(&channel)) {
232 ALOGE("%s write channel number %d to param failed %s", __func__, channel,
233 param.toString().c_str());
234 return BAD_VALUE;
235 }
236 return OK;
237 }
238 default: {
239 ALOGW("%s unknown param %s", __func__, param.toString().c_str());
240 return BAD_VALUE;
241 }
242 }
243}
244
245aidl::ConversionResult<DynamicsProcessing::ChannelConfig>
246AidlConversionDp::readChannelConfigFromParam(EffectParamReader& param) {
247 int32_t enable, channel;
248 if (OK != param.readFromParameter(&channel) || OK != param.readFromValue(&enable)) {
249 ALOGE("%s invalid channel config param %s", __func__, param.toString().c_str());
250 return ::android::base::unexpected(::android::BAD_VALUE);
251 }
252 return DynamicsProcessing::ChannelConfig(
253 {.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable)), .channel = channel});
254}
255
256aidl::ConversionResult<DynamicsProcessing::EqBandConfig>
257AidlConversionDp::readEqBandConfigFromParam(EffectParamReader& param) {
258 DynamicsProcessing::EqBandConfig config;
259 int32_t enable;
260 if (OK != param.readFromParameter(&config.channel) ||
261 OK != param.readFromParameter(&config.band) ||
262 OK != param.readFromValue(&enable) ||
263 OK != param.readFromValue(&config.cutoffFrequencyHz) ||
264 OK != param.readFromValue(&config.gainDb)) {
265 ALOGE("%s invalid eq band param %s", __func__, param.toString().c_str());
266 return ::android::base::unexpected(::android::BAD_VALUE);
267 }
268 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
269 return config;
270}
271
272aidl::ConversionResult<DynamicsProcessing::MbcBandConfig>
273AidlConversionDp::readMbcBandConfigFromParam(EffectParamReader& param) {
274 DynamicsProcessing::MbcBandConfig config;
275 int32_t enable;
276 if (OK != param.readFromParameter(&config.channel) ||
277 OK != param.readFromParameter(&config.band) ||
278 OK != param.readFromValue(&enable) ||
279 OK != param.readFromValue(&config.cutoffFrequencyHz) ||
280 OK != param.readFromValue(&config.attackTimeMs) ||
281 OK != param.readFromValue(&config.releaseTimeMs) ||
282 OK != param.readFromValue(&config.ratio) ||
283 OK != param.readFromValue(&config.thresholdDb) ||
284 OK != param.readFromValue(&config.kneeWidthDb) ||
285 OK != param.readFromValue(&config.noiseGateThresholdDb) ||
286 OK != param.readFromValue(&config.expanderRatio) ||
287 OK != param.readFromValue(&config.preGainDb) ||
288 OK != param.readFromValue(&config.postGainDb)) {
289 ALOGE("%s invalid mbc band config param %s", __func__, param.toString().c_str());
290 return ::android::base::unexpected(::android::BAD_VALUE);
291 }
292 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
293 return config;
294}
295
296aidl::ConversionResult<DynamicsProcessing::LimiterConfig>
297AidlConversionDp::readLimiterConfigFromParam(EffectParamReader& param) {
298 DynamicsProcessing::LimiterConfig config;
299 int32_t enable, inUse;
300 if (OK != param.readFromParameter(&config.channel) ||
301 OK != param.readFromValue(&inUse) ||
302 OK != param.readFromValue(&enable) ||
303 OK != param.readFromValue(&config.linkGroup) ||
304 OK != param.readFromValue(&config.attackTimeMs) ||
305 OK != param.readFromValue(&config.releaseTimeMs) ||
306 OK != param.readFromValue(&config.ratio) ||
307 OK != param.readFromValue(&config.thresholdDb) ||
308 OK != param.readFromValue(&config.postGainDb)) {
309 ALOGE("%s invalid limiter config param %s", __func__, param.toString().c_str());
310 return ::android::base::unexpected(::android::BAD_VALUE);
311 }
312 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
313 return config;
314}
315
316aidl::ConversionResult<DynamicsProcessing::EngineArchitecture>
317AidlConversionDp::readEngineArchitectureFromParam(EffectParamReader& param) {
318 DynamicsProcessing::EngineArchitecture engine;
319 int32_t variant, preEqInUse, mbcInUse, postEqInUse, limiterInUse;
320 if (OK != param.readFromValue(&variant) &&
321 OK != param.readFromValue(&engine.preferredProcessingDurationMs) &&
322 OK != param.readFromValue(&preEqInUse) &&
323 OK != param.readFromValue(&engine.preEqStage.bandCount) &&
324 OK != param.readFromValue(&mbcInUse) &&
325 OK != param.readFromValue(&engine.mbcStage.bandCount) &&
326 OK != param.readFromValue(&postEqInUse) &&
327 OK != param.readFromValue(&engine.postEqStage.bandCount) &&
328 OK != param.readFromValue(&limiterInUse)) {
329 ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
330 return ::android::base::unexpected(::android::BAD_VALUE);
331 }
332
333 engine.resolutionPreference = VALUE_OR_RETURN(
334 aidl::android::legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(variant));
335 engine.preEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(preEqInUse));
336 engine.mbcStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(mbcInUse));
337 engine.postEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(postEqInUse));
338 engine.limiterInUse = VALUE_OR_RETURN(convertIntegral<bool>(limiterInUse));
339 return engine;
340}
341
342status_t AidlConversionDp::getChannelConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
343 int32_t channel;
344 if (OK != param.readFromParameter(&channel)) {
345 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
346 return BAD_VALUE;
347 }
348
349 Parameter aidlParam;
350 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
351 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
352
353 std::vector<DynamicsProcessing::ChannelConfig> channels;
354 int32_t inUse, bandCount;
355 switch (tag) {
356 case DynamicsProcessing::preEq: {
357 inUse = mEngine.preEqStage.inUse;
358 bandCount = mEngine.preEqStage.bandCount;
359 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
360 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::preEq,
361 std::vector<DynamicsProcessing::ChannelConfig>));
362 break;
363 }
364 case DynamicsProcessing::postEq: {
365 inUse = mEngine.postEqStage.inUse;
366 bandCount = mEngine.postEqStage.bandCount;
367 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
368 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::postEq,
369 std::vector<DynamicsProcessing::ChannelConfig>));
370 break;
371 }
372 case DynamicsProcessing::mbc: {
373 inUse = mEngine.mbcStage.inUse;
374 bandCount = mEngine.mbcStage.bandCount;
375 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
376 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::mbc,
377 std::vector<DynamicsProcessing::ChannelConfig>));
378 break;
379 }
380 default: {
381 ALOGE("%s unsupported tag %s", __func__, toString(tag).c_str());
382 return BAD_VALUE;
383 }
384 }
385
386 for (const auto& ch : channels) {
387 if (ch.channel == channel) {
388 int32_t enable = ch.enable;
389 if (OK != param.writeToValue(&inUse) ||
390 OK != param.writeToValue(&enable) ||
391 OK != param.writeToValue(&bandCount)) {
392 ALOGE("%s failed to write into param value %s", __func__,
393 param.toString().c_str());
394 return BAD_VALUE;
395 }
396 return OK;
397 }
398 }
399 ALOGE("%s not able to find channel %d", __func__, channel);
400 return BAD_VALUE;
401}
402
403status_t AidlConversionDp::getEqBandConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
404 int32_t channel, band;
405 if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
406 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
407 return BAD_VALUE;
408 }
409
410 Parameter aidlParam;
411 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
412 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
413
414 std::vector<DynamicsProcessing::EqBandConfig> bands;
415 if (tag == DynamicsProcessing::preEqBand) {
416 bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
417 aidlParam, DynamicsProcessing, dynamicsProcessing, preEqBand,
418 std::vector<DynamicsProcessing::EqBandConfig>));
419 } else if (tag == DynamicsProcessing::postEqBand) {
420 bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
421 aidlParam, DynamicsProcessing, dynamicsProcessing, postEqBand,
422 std::vector<DynamicsProcessing::EqBandConfig>));
423 } else {
424 return BAD_VALUE;
425 }
426
427 for (const auto& bandIt : bands) {
428 if (bandIt.channel == channel && bandIt.band == band) {
429 int32_t enable = bandIt.enable;
430 if (OK != param.writeToValue(&enable) ||
431 OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
432 OK != param.writeToValue(&bandIt.gainDb)) {
433 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
434 return BAD_VALUE;
435 }
436 return OK;
437 }
438 }
439 ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
440 return BAD_VALUE;
441}
442
443status_t AidlConversionDp::getMbcBandConfig(EffectParamWriter& param) {
444 int32_t channel, band;
445 if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
446 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
447 return BAD_VALUE;
448 }
449 Parameter aidlParam;
450 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
451 DynamicsProcessing::mbcBand);
452 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
453
454 std::vector<DynamicsProcessing::MbcBandConfig> bands =
455 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
456 aidlParam, DynamicsProcessing, dynamicsProcessing, mbcBand,
457 std::vector<DynamicsProcessing::MbcBandConfig>));
458
459 for (const auto& bandIt : bands) {
460 if (bandIt.channel == channel && bandIt.band == band) {
461 int32_t enable = bandIt.enable;
462 if (OK != param.writeToValue(&enable) ||
463 OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
464 OK != param.writeToValue(&bandIt.attackTimeMs) ||
465 OK != param.writeToValue(&bandIt.releaseTimeMs) ||
466 OK != param.writeToValue(&bandIt.ratio) ||
467 OK != param.writeToValue(&bandIt.thresholdDb) ||
468 OK != param.writeToValue(&bandIt.kneeWidthDb) ||
469 OK != param.writeToValue(&bandIt.noiseGateThresholdDb) ||
470 OK != param.writeToValue(&bandIt.expanderRatio) ||
471 OK != param.writeToValue(&bandIt.preGainDb) ||
472 OK != param.writeToValue(&bandIt.postGainDb)) {
473 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
474 return BAD_VALUE;
475 }
476 return OK;
477 }
478 }
479 ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
480 return BAD_VALUE;
481}
482
483status_t AidlConversionDp::getLimiterConfig(EffectParamWriter& param) {
484 int32_t channel;
485 if (OK != param.readFromParameter(&channel)) {
486 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
487 return BAD_VALUE;
488 }
489 Parameter aidlParam;
490 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
491 DynamicsProcessing::limiter);
492 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
493
494 std::vector<DynamicsProcessing::LimiterConfig> configs =
495 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
496 aidlParam, DynamicsProcessing, dynamicsProcessing, limiter,
497 std::vector<DynamicsProcessing::LimiterConfig>));
498
499 for (const auto& config : configs) {
500 if (config.channel == channel) {
501 int32_t inUse = mEngine.limiterInUse;
502 int32_t enable = config.enable;
503 if (OK != param.writeToValue(&inUse) ||
504 OK != param.writeToValue(&enable) ||
505 OK != param.writeToValue(&config.linkGroup) ||
506 OK != param.writeToValue(&config.attackTimeMs) ||
507 OK != param.writeToValue(&config.releaseTimeMs) ||
508 OK != param.writeToValue(&config.ratio) ||
509 OK != param.writeToValue(&config.thresholdDb) ||
510 OK != param.writeToValue(&config.postGainDb)) {
511 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
512 return BAD_VALUE;
513 }
514 return OK;
515 }
516 }
517 ALOGE("%s not able to find channel %d", __func__, channel);
518 return BAD_VALUE;
519}
520
521} // namespace effect
522} // namespace android