blob: 4555c9f49412dcbeb086f3f2205e0ea62dfd680d [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
Shunkai Yaodba8ba32023-01-27 17:02:21 +0000150 std::vector<DynamicsProcessing::InputGain> gains =
151 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
152 aidlParam, DynamicsProcessing, dynamicsProcessing,
153 DynamicsProcessing::inputGain,
154 std::vector<DynamicsProcessing::InputGain>));
155 for (const auto& gain : gains) {
156 if (gain.channel == channel) {
157 return param.writeToValue(&gain.gainDb);
158 }
159 }
160 ALOGE("%s not able to find channel %d", __func__, channel);
161 return BAD_VALUE;
162 }
163 case DP_PARAM_ENGINE_ARCHITECTURE: {
164 int32_t channel;
165 if (OK != param.readFromParameter(&channel)) {
166 ALOGE("%s invalid inputGain %s", __func__, param.toString().c_str());
167 return BAD_VALUE;
168 }
169 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
170 DynamicsProcessing::engineArchitecture);
171 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
172
173 DynamicsProcessing::EngineArchitecture engine =
174 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
175 aidlParam, DynamicsProcessing, dynamicsProcessing,
176 DynamicsProcessing::engineArchitecture,
177 DynamicsProcessing::EngineArchitecture));
178 int32_t resolution = VALUE_OR_RETURN_STATUS(
179 aidl::android::aidl2legacy_DynamicsProcessing_ResolutionPreference_int32(
180 engine.resolutionPreference));
181 int32_t preEqInUse =
182 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.preEqStage.inUse));
183 int32_t mbcInUse =
184 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.mbcStage.inUse));
185 int32_t postEqInUse =
186 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.postEqStage.inUse));
187 int32_t limiterInUse =
188 VALUE_OR_RETURN_STATUS(convertIntegral<int32_t>(engine.limiterInUse));
189 if (OK != param.writeToValue(&resolution) ||
190 OK != param.writeToValue(&engine.preferredProcessingDurationMs) ||
191 OK != param.writeToValue(&preEqInUse) ||
192 OK != param.writeToValue(&engine.preEqStage.bandCount) ||
193 OK != param.writeToValue(&mbcInUse) ||
194 OK != param.writeToValue(&engine.mbcStage.bandCount) ||
195 OK != param.writeToValue(&postEqInUse) ||
196 OK != param.writeToValue(&engine.postEqStage.bandCount) ||
197 OK != param.writeToValue(&limiterInUse)) {
198 ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
199 return BAD_VALUE;
200 }
201 mEngine = engine;
202 return OK;
203 }
204 case DP_PARAM_PRE_EQ: {
205 return getChannelConfig(DynamicsProcessing::preEq, param);
206 }
207 case DP_PARAM_POST_EQ: {
208 return getChannelConfig(DynamicsProcessing::postEq, param);
209 }
210 case DP_PARAM_MBC: {
211 return getChannelConfig(DynamicsProcessing::mbc, param);
212 }
213 case DP_PARAM_PRE_EQ_BAND: {
214 return getEqBandConfig(DynamicsProcessing::preEqBand, param);
215 }
216 case DP_PARAM_POST_EQ_BAND: {
217 return getEqBandConfig(DynamicsProcessing::postEqBand, param);
218 }
219 case DP_PARAM_MBC_BAND: {
220 return getMbcBandConfig(param);
221 }
222 case DP_PARAM_LIMITER: {
223 return getLimiterConfig(param);
224 }
225 case DP_PARAM_GET_CHANNEL_COUNT: {
226 uint32_t channel = VALUE_OR_RETURN_STATUS(
227 aidl::android::aidl2legacy_AudioChannelLayout_audio_channel_mask_t(
228 mCommon.input.base.channelMask, true /* input */));
229 if (OK != param.writeToValue(&channel)) {
230 ALOGE("%s write channel number %d to param failed %s", __func__, channel,
231 param.toString().c_str());
232 return BAD_VALUE;
233 }
234 return OK;
235 }
236 default: {
237 ALOGW("%s unknown param %s", __func__, param.toString().c_str());
238 return BAD_VALUE;
239 }
240 }
241}
242
243aidl::ConversionResult<DynamicsProcessing::ChannelConfig>
244AidlConversionDp::readChannelConfigFromParam(EffectParamReader& param) {
245 int32_t enable, channel;
246 if (OK != param.readFromParameter(&channel) || OK != param.readFromValue(&enable)) {
247 ALOGE("%s invalid channel config param %s", __func__, param.toString().c_str());
248 return ::android::base::unexpected(::android::BAD_VALUE);
249 }
250 return DynamicsProcessing::ChannelConfig(
251 {.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable)), .channel = channel});
252}
253
254aidl::ConversionResult<DynamicsProcessing::EqBandConfig>
255AidlConversionDp::readEqBandConfigFromParam(EffectParamReader& param) {
256 DynamicsProcessing::EqBandConfig config;
257 int32_t enable;
258 if (OK != param.readFromParameter(&config.channel) ||
259 OK != param.readFromParameter(&config.band) ||
260 OK != param.readFromValue(&enable) ||
261 OK != param.readFromValue(&config.cutoffFrequencyHz) ||
262 OK != param.readFromValue(&config.gainDb)) {
263 ALOGE("%s invalid eq band param %s", __func__, param.toString().c_str());
264 return ::android::base::unexpected(::android::BAD_VALUE);
265 }
266 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
267 return config;
268}
269
270aidl::ConversionResult<DynamicsProcessing::MbcBandConfig>
271AidlConversionDp::readMbcBandConfigFromParam(EffectParamReader& param) {
272 DynamicsProcessing::MbcBandConfig config;
273 int32_t enable;
274 if (OK != param.readFromParameter(&config.channel) ||
275 OK != param.readFromParameter(&config.band) ||
276 OK != param.readFromValue(&enable) ||
277 OK != param.readFromValue(&config.cutoffFrequencyHz) ||
278 OK != param.readFromValue(&config.attackTimeMs) ||
279 OK != param.readFromValue(&config.releaseTimeMs) ||
280 OK != param.readFromValue(&config.ratio) ||
281 OK != param.readFromValue(&config.thresholdDb) ||
282 OK != param.readFromValue(&config.kneeWidthDb) ||
283 OK != param.readFromValue(&config.noiseGateThresholdDb) ||
284 OK != param.readFromValue(&config.expanderRatio) ||
285 OK != param.readFromValue(&config.preGainDb) ||
286 OK != param.readFromValue(&config.postGainDb)) {
287 ALOGE("%s invalid mbc band config param %s", __func__, param.toString().c_str());
288 return ::android::base::unexpected(::android::BAD_VALUE);
289 }
290 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
291 return config;
292}
293
294aidl::ConversionResult<DynamicsProcessing::LimiterConfig>
295AidlConversionDp::readLimiterConfigFromParam(EffectParamReader& param) {
296 DynamicsProcessing::LimiterConfig config;
297 int32_t enable, inUse;
298 if (OK != param.readFromParameter(&config.channel) ||
299 OK != param.readFromValue(&inUse) ||
300 OK != param.readFromValue(&enable) ||
301 OK != param.readFromValue(&config.linkGroup) ||
302 OK != param.readFromValue(&config.attackTimeMs) ||
303 OK != param.readFromValue(&config.releaseTimeMs) ||
304 OK != param.readFromValue(&config.ratio) ||
305 OK != param.readFromValue(&config.thresholdDb) ||
306 OK != param.readFromValue(&config.postGainDb)) {
307 ALOGE("%s invalid limiter config param %s", __func__, param.toString().c_str());
308 return ::android::base::unexpected(::android::BAD_VALUE);
309 }
310 config.enable = VALUE_OR_RETURN(convertIntegral<bool>(enable));
311 return config;
312}
313
314aidl::ConversionResult<DynamicsProcessing::EngineArchitecture>
315AidlConversionDp::readEngineArchitectureFromParam(EffectParamReader& param) {
316 DynamicsProcessing::EngineArchitecture engine;
317 int32_t variant, preEqInUse, mbcInUse, postEqInUse, limiterInUse;
318 if (OK != param.readFromValue(&variant) &&
319 OK != param.readFromValue(&engine.preferredProcessingDurationMs) &&
320 OK != param.readFromValue(&preEqInUse) &&
321 OK != param.readFromValue(&engine.preEqStage.bandCount) &&
322 OK != param.readFromValue(&mbcInUse) &&
323 OK != param.readFromValue(&engine.mbcStage.bandCount) &&
324 OK != param.readFromValue(&postEqInUse) &&
325 OK != param.readFromValue(&engine.postEqStage.bandCount) &&
326 OK != param.readFromValue(&limiterInUse)) {
327 ALOGE("%s invalid engineArchitecture %s", __func__, param.toString().c_str());
328 return ::android::base::unexpected(::android::BAD_VALUE);
329 }
330
331 engine.resolutionPreference = VALUE_OR_RETURN(
332 aidl::android::legacy2aidl_int32_DynamicsProcessing_ResolutionPreference(variant));
333 engine.preEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(preEqInUse));
334 engine.mbcStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(mbcInUse));
335 engine.postEqStage.inUse = VALUE_OR_RETURN(convertIntegral<bool>(postEqInUse));
336 engine.limiterInUse = VALUE_OR_RETURN(convertIntegral<bool>(limiterInUse));
337 return engine;
338}
339
340status_t AidlConversionDp::getChannelConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
341 int32_t channel;
342 if (OK != param.readFromParameter(&channel)) {
343 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
344 return BAD_VALUE;
345 }
346
347 Parameter aidlParam;
348 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
349 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
350
351 std::vector<DynamicsProcessing::ChannelConfig> channels;
352 int32_t inUse, bandCount;
353 switch (tag) {
354 case DynamicsProcessing::preEq: {
355 inUse = mEngine.preEqStage.inUse;
356 bandCount = mEngine.preEqStage.bandCount;
357 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
358 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::preEq,
359 std::vector<DynamicsProcessing::ChannelConfig>));
360 break;
361 }
362 case DynamicsProcessing::postEq: {
363 inUse = mEngine.postEqStage.inUse;
364 bandCount = mEngine.postEqStage.bandCount;
365 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
366 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::postEq,
367 std::vector<DynamicsProcessing::ChannelConfig>));
368 break;
369 }
370 case DynamicsProcessing::mbc: {
371 inUse = mEngine.mbcStage.inUse;
372 bandCount = mEngine.mbcStage.bandCount;
373 channels = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
374 aidlParam, DynamicsProcessing, dynamicsProcessing, DynamicsProcessing::mbc,
375 std::vector<DynamicsProcessing::ChannelConfig>));
376 break;
377 }
378 default: {
379 ALOGE("%s unsupported tag %s", __func__, toString(tag).c_str());
380 return BAD_VALUE;
381 }
382 }
383
384 for (const auto& ch : channels) {
385 if (ch.channel == channel) {
386 int32_t enable = ch.enable;
387 if (OK != param.writeToValue(&inUse) ||
388 OK != param.writeToValue(&enable) ||
389 OK != param.writeToValue(&bandCount)) {
390 ALOGE("%s failed to write into param value %s", __func__,
391 param.toString().c_str());
392 return BAD_VALUE;
393 }
394 return OK;
395 }
396 }
397 ALOGE("%s not able to find channel %d", __func__, channel);
398 return BAD_VALUE;
399}
400
401status_t AidlConversionDp::getEqBandConfig(DynamicsProcessing::Tag tag, EffectParamWriter& param) {
402 int32_t channel, band;
403 if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
404 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
405 return BAD_VALUE;
406 }
407
408 Parameter aidlParam;
409 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag, tag);
410 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
411
412 std::vector<DynamicsProcessing::EqBandConfig> bands;
413 if (tag == DynamicsProcessing::preEqBand) {
414 bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
415 aidlParam, DynamicsProcessing, dynamicsProcessing, preEqBand,
416 std::vector<DynamicsProcessing::EqBandConfig>));
417 } else if (tag == DynamicsProcessing::postEqBand) {
418 bands = VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
419 aidlParam, DynamicsProcessing, dynamicsProcessing, postEqBand,
420 std::vector<DynamicsProcessing::EqBandConfig>));
421 } else {
422 return BAD_VALUE;
423 }
424
425 for (const auto& bandIt : bands) {
426 if (bandIt.channel == channel && bandIt.band == band) {
427 int32_t enable = bandIt.enable;
428 if (OK != param.writeToValue(&enable) ||
429 OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
430 OK != param.writeToValue(&bandIt.gainDb)) {
431 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
432 return BAD_VALUE;
433 }
434 return OK;
435 }
436 }
437 ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
438 return BAD_VALUE;
439}
440
441status_t AidlConversionDp::getMbcBandConfig(EffectParamWriter& param) {
442 int32_t channel, band;
443 if (OK != param.readFromParameter(&channel) || OK != param.readFromParameter(&band)) {
444 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
445 return BAD_VALUE;
446 }
447 Parameter aidlParam;
448 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
449 DynamicsProcessing::mbcBand);
450 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
451
452 std::vector<DynamicsProcessing::MbcBandConfig> bands =
453 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
454 aidlParam, DynamicsProcessing, dynamicsProcessing, mbcBand,
455 std::vector<DynamicsProcessing::MbcBandConfig>));
456
457 for (const auto& bandIt : bands) {
458 if (bandIt.channel == channel && bandIt.band == band) {
459 int32_t enable = bandIt.enable;
460 if (OK != param.writeToValue(&enable) ||
461 OK != param.writeToValue(&bandIt.cutoffFrequencyHz) ||
462 OK != param.writeToValue(&bandIt.attackTimeMs) ||
463 OK != param.writeToValue(&bandIt.releaseTimeMs) ||
464 OK != param.writeToValue(&bandIt.ratio) ||
465 OK != param.writeToValue(&bandIt.thresholdDb) ||
466 OK != param.writeToValue(&bandIt.kneeWidthDb) ||
467 OK != param.writeToValue(&bandIt.noiseGateThresholdDb) ||
468 OK != param.writeToValue(&bandIt.expanderRatio) ||
469 OK != param.writeToValue(&bandIt.preGainDb) ||
470 OK != param.writeToValue(&bandIt.postGainDb)) {
471 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
472 return BAD_VALUE;
473 }
474 return OK;
475 }
476 }
477 ALOGE("%s not able to find channel %d band %d", __func__, channel, band);
478 return BAD_VALUE;
479}
480
481status_t AidlConversionDp::getLimiterConfig(EffectParamWriter& param) {
482 int32_t channel;
483 if (OK != param.readFromParameter(&channel)) {
484 ALOGE("%s invalid parameter %s", __func__, param.toString().c_str());
485 return BAD_VALUE;
486 }
487 Parameter aidlParam;
488 Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(DynamicsProcessing, dynamicsProcessingTag,
489 DynamicsProcessing::limiter);
490 RETURN_STATUS_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
491
492 std::vector<DynamicsProcessing::LimiterConfig> configs =
493 VALUE_OR_RETURN_STATUS(aidl::android::GET_PARAMETER_SPECIFIC_FIELD(
494 aidlParam, DynamicsProcessing, dynamicsProcessing, limiter,
495 std::vector<DynamicsProcessing::LimiterConfig>));
496
497 for (const auto& config : configs) {
498 if (config.channel == channel) {
499 int32_t inUse = mEngine.limiterInUse;
500 int32_t enable = config.enable;
501 if (OK != param.writeToValue(&inUse) ||
502 OK != param.writeToValue(&enable) ||
503 OK != param.writeToValue(&config.linkGroup) ||
504 OK != param.writeToValue(&config.attackTimeMs) ||
505 OK != param.writeToValue(&config.releaseTimeMs) ||
506 OK != param.writeToValue(&config.ratio) ||
507 OK != param.writeToValue(&config.thresholdDb) ||
508 OK != param.writeToValue(&config.postGainDb)) {
509 ALOGE("%s failed to write into param value %s", __func__, param.toString().c_str());
510 return BAD_VALUE;
511 }
512 return OK;
513 }
514 }
515 ALOGE("%s not able to find channel %d", __func__, channel);
516 return BAD_VALUE;
517}
518
519} // namespace effect
520} // namespace android