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