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