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