• 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 "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 <system/audio_effects/effect_equalizer.h>
27 
28 #include <utils/Log.h>
29 
30 #include "AidlConversionEq.h"
31 
32 namespace android {
33 namespace effect {
34 
35 using ::aidl::android::getParameterSpecificField;
36 using ::aidl::android::aidl_utils::statusTFromBinderStatus;
37 using ::aidl::android::hardware::audio::effect::Equalizer;
38 using ::aidl::android::hardware::audio::effect::Parameter;
39 using ::aidl::android::hardware::audio::effect::Range;
40 using ::aidl::android::hardware::audio::effect::VendorExtension;
41 using ::android::base::unexpected;
42 using ::android::status_t;
43 using utils::EffectParamReader;
44 using utils::EffectParamWriter;
45 
setParameter(EffectParamReader & param)46 status_t AidlConversionEq::setParameter(EffectParamReader& param) {
47     uint32_t type;
48     if (OK != param.readFromParameter(&type)) {
49         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: {
56             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             }
61             aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, preset, (int)value);
62             break;
63         }
64         case EQ_PARAM_BAND_LEVEL: {
65             int32_t band;
66             int16_t level;
67             if (OK != param.readFromParameter(&band) || OK != param.readFromValue(&level)) {
68                 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);
73             break;
74         }
75         case EQ_PARAM_PROPERTIES: {
76             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                 break;
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             break;
102         }
103         default: {
104             // for vendor extension, copy data area to the DefaultExtension, parameter ignored
105             VendorExtension ext = VALUE_OR_RETURN_STATUS(
106                     aidl::android::legacy2aidl_EffectParameterReader_VendorExtension(param));
107             aidlParam = MAKE_SPECIFIC_PARAMETER(Equalizer, equalizer, vendor, ext);
108             break;
109         }
110     }
111 
112     return statusTFromBinderStatus(mEffect->setParameter(aidlParam));
113 }
114 
getAidlParameter(Equalizer::Tag tag)115 ConversionResult<Parameter> AidlConversionEq::getAidlParameter(Equalizer::Tag tag) {
116     Parameter aidlParam;
117     Parameter::Id id = MAKE_SPECIFIC_PARAMETER_ID(Equalizer, equalizerTag, tag);
118     RETURN_IF_ERROR(statusTFromBinderStatus(mEffect->getParameter(id, &aidlParam)));
119     return aidlParam;
120 }
121 
getParameterPreset()122 ConversionResult<int32_t> AidlConversionEq::getParameterPreset() {
123     Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::preset));
124     return VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(aidlParam, Equalizer, equalizer,
125                                                                Equalizer::preset, int32_t));
126 }
127 
getParameterPresetName(EffectParamWriter & param)128 ConversionResult<std::string> AidlConversionEq::getParameterPresetName(
129         EffectParamWriter& param) {
130     int32_t presetIdx;
131     if (OK != param.readFromParameter(&presetIdx)) {
132         ALOGE("%s invalid param %s", __func__, param.toString().c_str());
133         return unexpected(BAD_VALUE);
134     }
135     Parameter aidlParam = VALUE_OR_RETURN(getAidlParameter(Equalizer::presets));
136     const auto& presets = VALUE_OR_RETURN(GET_PARAMETER_SPECIFIC_FIELD(
137             aidlParam, Equalizer, equalizer, Equalizer::presets, std::vector<Equalizer::Preset>));
138     for (const auto& preset : presets) {
139         if (presetIdx == preset.index) {
140             return preset.name;
141         }
142     }
143     return unexpected(BAD_VALUE);
144 }
145 
getParameter(EffectParamWriter & param)146 status_t AidlConversionEq::getParameter(EffectParamWriter& param) {
147     uint32_t type = 0;
148     if (OK != param.readFromParameter(&type)) {
149         param.setStatus(BAD_VALUE);
150         ALOGE("%s invalid param %s", __func__, param.toString().c_str());
151         return BAD_VALUE;
152     }
153 
154     switch (type) {
155         case EQ_PARAM_NUM_BANDS: {
156             Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
157             const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
158                     aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
159                     std::vector<Equalizer::BandLevel>));
160             uint16_t bands = bandLevels.size();
161             return param.writeToValue(&bands);
162         }
163         case EQ_PARAM_LEVEL_RANGE: {
164             if (mDesc.capability.range.getTag() != Range::equalizer) {
165                 return OK;
166             }
167             const auto& ranges = mDesc.capability.range.get<Range::equalizer>();
168             for (const auto& r : ranges) {
169                 if (r.min.getTag() == Equalizer::bandLevels &&
170                     r.max.getTag() == Equalizer::bandLevels) {
171                     const auto& aidlMin = r.min.get<Equalizer::bandLevels>();
172                     const auto& aidlMax = r.max.get<Equalizer::bandLevels>();
173                     int16_t min =
174                             std::min_element(aidlMin.begin(), aidlMin.end(), [](auto& a, auto& b) {
175                                 return a.levelMb < b.levelMb;
176                             })->levelMb;
177                     int16_t max =
178                             std::max_element(aidlMax.begin(), aidlMax.end(), [](auto& a, auto& b) {
179                                 return a.levelMb < b.levelMb;
180                             })->levelMb;
181                     return (OK == param.writeToValue(&min) && OK == param.writeToValue(&max))
182                                    ? OK
183                                    : BAD_VALUE;
184                 }
185             }
186             break;
187         }
188         case EQ_PARAM_BAND_LEVEL: {
189             int32_t bandIdx;
190             if (OK != param.readFromParameter(&bandIdx)) {
191                 break;
192             }
193 
194             Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
195             const auto& bandLevels = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
196                     aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
197                     std::vector<Equalizer::BandLevel>));
198             for (const auto& band : bandLevels) {
199                 if (band.index == bandIdx) {
200                     return param.writeToValue((uint16_t *)&band.levelMb);
201                 }
202             }
203             break;
204         }
205         case EQ_PARAM_CENTER_FREQ: {
206             int32_t index;
207             if (OK != param.readFromParameter(&index)) {
208                 break;
209             }
210 
211             Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::centerFreqMh));
212             const auto& freqs = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
213                     aidlParam, Equalizer, equalizer, Equalizer::centerFreqMh, std::vector<int>));
214             if ((size_t)index >= freqs.size()) {
215                 ALOGE("%s index %d exceed size %zu", __func__, index, freqs.size());
216                 break;
217             }
218             return param.writeToValue(&freqs[index]);
219         }
220         case EQ_PARAM_BAND_FREQ_RANGE: {
221             int32_t index;
222             if (OK != param.readFromParameter(&index)) {
223                 break;
224             }
225 
226             Parameter aidlParam =
227                     VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
228             const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
229                     aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
230                     std::vector<Equalizer::BandFrequency>));
231             for (const auto& band : bands) {
232                 if (band.index == index) {
233                     return (OK == param.writeToValue(&band.minMh) &&
234                             OK == param.writeToValue(&band.maxMh))
235                                    ? OK
236                                    : BAD_VALUE;
237                 }
238             }
239             break;
240         }
241         case EQ_PARAM_GET_BAND: {
242             int32_t freq;
243             if (OK != param.readFromParameter(&freq)) {
244                 break;
245             }
246 
247             Parameter aidlParam =
248                     VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandFrequencies));
249             const auto& bands = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
250                     aidlParam, Equalizer, equalizer, Equalizer::bandFrequencies,
251                     std::vector<Equalizer::BandFrequency>));
252             for (const auto& band : bands) {
253                 if (freq >= band.minMh && freq <= band.maxMh) {
254                     return param.writeToValue((uint16_t*)&band.index);
255                 }
256             }
257             break;
258         }
259         case EQ_PARAM_CUR_PRESET: {
260             int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
261             return param.writeToValue((uint16_t*)&preset);
262         }
263         case EQ_PARAM_GET_NUM_OF_PRESETS: {
264             Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::presets));
265             const auto& presets = VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
266                     aidlParam, Equalizer, equalizer, Equalizer::presets,
267                     std::vector<Equalizer::Preset>));
268             uint16_t num = presets.size();
269             return param.writeToValue(&num);
270         }
271         case EQ_PARAM_GET_PRESET_NAME: {
272             std::string name = VALUE_OR_RETURN_STATUS(getParameterPresetName(param));
273             return param.writeToValue(name.c_str(), name.length());
274         }
275         case EQ_PARAM_PROPERTIES: {
276             int32_t preset = VALUE_OR_RETURN_STATUS(getParameterPreset());
277             if (OK != param.writeToValue((uint16_t*)&preset)) {
278                 break;
279             }
280             Parameter aidlParam = VALUE_OR_RETURN_STATUS(getAidlParameter(Equalizer::bandLevels));
281             std::vector<Equalizer::BandLevel> bandLevels =
282                     VALUE_OR_RETURN_STATUS(GET_PARAMETER_SPECIFIC_FIELD(
283                             aidlParam, Equalizer, equalizer, Equalizer::bandLevels,
284                             std::vector<Equalizer::BandLevel>));
285             uint16_t bands = bandLevels.size();
286             if (OK != param.writeToValue(&bands)) {
287                 break;
288             }
289             std::sort(bandLevels.begin(), bandLevels.end(),
290                       [](const auto& a, const auto& b) { return a.index < b.index; });
291             for (const auto& level : bandLevels) {
292                 if (status_t status = param.writeToValue((uint16_t*)&level.levelMb); status != OK) {
293                     return status;
294                 }
295             }
296             return OK;
297         }
298         default: {
299             VENDOR_EXTENSION_GET_AND_RETURN(Equalizer, equalizer, param);
300         }
301     }
302 
303     param.setStatus(BAD_VALUE);
304     ALOGE("%s invalid param %s", __func__, param.toString().c_str());
305     return BAD_VALUE;
306 }
307 
308 } // namespace effect
309 } // namespace android
310