• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 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 <algorithm>
18 #include <cstddef>
19 #include <unordered_set>
20 
21 #define LOG_TAG "AHAL_EnvReverbSw"
22 #include <android-base/logging.h>
23 #include <fmq/AidlMessageQueue.h>
24 #include <system/audio_effects/effect_uuid.h>
25 
26 #include "EnvReverbSw.h"
27 
28 using aidl::android::hardware::audio::effect::Descriptor;
29 using aidl::android::hardware::audio::effect::EnvReverbSw;
30 using aidl::android::hardware::audio::effect::getEffectImplUuidEnvReverbSw;
31 using aidl::android::hardware::audio::effect::getEffectTypeUuidEnvReverb;
32 using aidl::android::hardware::audio::effect::IEffect;
33 using aidl::android::hardware::audio::effect::State;
34 using aidl::android::media::audio::common::AudioUuid;
35 
createEffect(const AudioUuid * in_impl_uuid,std::shared_ptr<IEffect> * instanceSpp)36 extern "C" binder_exception_t createEffect(const AudioUuid* in_impl_uuid,
37                                            std::shared_ptr<IEffect>* instanceSpp) {
38     if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
39         LOG(ERROR) << __func__ << "uuid not supported";
40         return EX_ILLEGAL_ARGUMENT;
41     }
42     if (instanceSpp) {
43         *instanceSpp = ndk::SharedRefBase::make<EnvReverbSw>();
44         LOG(DEBUG) << __func__ << " instance " << instanceSpp->get() << " created";
45         return EX_NONE;
46     } else {
47         LOG(ERROR) << __func__ << " invalid input parameter!";
48         return EX_ILLEGAL_ARGUMENT;
49     }
50 }
51 
queryEffect(const AudioUuid * in_impl_uuid,Descriptor * _aidl_return)52 extern "C" binder_exception_t queryEffect(const AudioUuid* in_impl_uuid, Descriptor* _aidl_return) {
53     if (!in_impl_uuid || *in_impl_uuid != getEffectImplUuidEnvReverbSw()) {
54         LOG(ERROR) << __func__ << "uuid not supported";
55         return EX_ILLEGAL_ARGUMENT;
56     }
57     *_aidl_return = EnvReverbSw::kDescriptor;
58     return EX_NONE;
59 }
60 
61 namespace aidl::android::hardware::audio::effect {
62 
63 const std::string EnvReverbSw::kEffectName = "EnvReverbSw";
64 
65 const std::vector<Range::EnvironmentalReverbRange> EnvReverbSw::kRanges = {
66         MAKE_RANGE(EnvironmentalReverb, roomLevelMb, -6000, 0),
67         MAKE_RANGE(EnvironmentalReverb, roomHfLevelMb, -4000, 0),
68         MAKE_RANGE(EnvironmentalReverb, decayTimeMs, 0, 7000),
69         MAKE_RANGE(EnvironmentalReverb, decayHfRatioPm, 100, 2000),
70         MAKE_RANGE(EnvironmentalReverb, reflectionsLevelMb, -6000, 0),
71         MAKE_RANGE(EnvironmentalReverb, reflectionsDelayMs, 0, 65),
72         MAKE_RANGE(EnvironmentalReverb, levelMb, -6000, 0),
73         MAKE_RANGE(EnvironmentalReverb, delayMs, 0, 65),
74         MAKE_RANGE(EnvironmentalReverb, diffusionPm, 0, 1000),
75         MAKE_RANGE(EnvironmentalReverb, densityPm, 0, 1000)};
76 
77 const Capability EnvReverbSw::kCapability = {
78         .range = Range::make<Range::environmentalReverb>(EnvReverbSw::kRanges)};
79 
80 const Descriptor EnvReverbSw::kDescriptor = {
81         .common = {.id = {.type = getEffectTypeUuidEnvReverb(),
82                           .uuid = getEffectImplUuidEnvReverbSw(),
83                           .proxy = std::nullopt},
84                    .flags = {.type = Flags::Type::INSERT,
85                              .insert = Flags::Insert::FIRST,
86                              .volume = Flags::Volume::CTRL},
87                    .name = EnvReverbSw::kEffectName,
88                    .implementor = "The Android Open Source Project"},
89         .capability = EnvReverbSw::kCapability};
90 
getDescriptor(Descriptor * _aidl_return)91 ndk::ScopedAStatus EnvReverbSw::getDescriptor(Descriptor* _aidl_return) {
92     LOG(DEBUG) << __func__ << kDescriptor.toString();
93     *_aidl_return = kDescriptor;
94     return ndk::ScopedAStatus::ok();
95 }
96 
setParameterSpecific(const Parameter::Specific & specific)97 ndk::ScopedAStatus EnvReverbSw::setParameterSpecific(const Parameter::Specific& specific) {
98     RETURN_IF(Parameter::Specific::environmentalReverb != specific.getTag(), EX_ILLEGAL_ARGUMENT,
99               "EffectNotSupported");
100 
101     auto& erParam = specific.get<Parameter::Specific::environmentalReverb>();
102     RETURN_IF(!inRange(erParam, kRanges), EX_ILLEGAL_ARGUMENT, "outOfRange");
103     auto tag = erParam.getTag();
104     switch (tag) {
105         case EnvironmentalReverb::roomLevelMb: {
106             RETURN_IF(mContext->setErRoomLevel(erParam.get<EnvironmentalReverb::roomLevelMb>()) !=
107                               RetCode::SUCCESS,
108                       EX_ILLEGAL_ARGUMENT, "setRoomLevelFailed");
109             return ndk::ScopedAStatus::ok();
110         }
111         case EnvironmentalReverb::roomHfLevelMb: {
112             RETURN_IF(
113                     mContext->setErRoomHfLevel(erParam.get<EnvironmentalReverb::roomHfLevelMb>()) !=
114                             RetCode::SUCCESS,
115                     EX_ILLEGAL_ARGUMENT, "setRoomHfLevelFailed");
116             return ndk::ScopedAStatus::ok();
117         }
118         case EnvironmentalReverb::decayTimeMs: {
119             RETURN_IF(mContext->setErDecayTime(erParam.get<EnvironmentalReverb::decayTimeMs>()) !=
120                               RetCode::SUCCESS,
121                       EX_ILLEGAL_ARGUMENT, "setDecayTimeFailed");
122             return ndk::ScopedAStatus::ok();
123         }
124         case EnvironmentalReverb::decayHfRatioPm: {
125             RETURN_IF(
126                     mContext->setErDecayHfRatio(
127                             erParam.get<EnvironmentalReverb::decayHfRatioPm>()) != RetCode::SUCCESS,
128                     EX_ILLEGAL_ARGUMENT, "setDecayHfRatioFailed");
129             return ndk::ScopedAStatus::ok();
130         }
131         case EnvironmentalReverb::reflectionsLevelMb: {
132             RETURN_IF(mContext->setErReflectionsLevel(
133                               erParam.get<EnvironmentalReverb::reflectionsLevelMb>()) !=
134                               RetCode::SUCCESS,
135                       EX_ILLEGAL_ARGUMENT, "setReflectionsLevelFailed");
136             return ndk::ScopedAStatus::ok();
137         }
138         case EnvironmentalReverb::reflectionsDelayMs: {
139             RETURN_IF(mContext->setErReflectionsDelay(
140                               erParam.get<EnvironmentalReverb::reflectionsDelayMs>()) !=
141                               RetCode::SUCCESS,
142                       EX_ILLEGAL_ARGUMENT, "setReflectionsDelayFailed");
143             return ndk::ScopedAStatus::ok();
144         }
145         case EnvironmentalReverb::levelMb: {
146             RETURN_IF(mContext->setErLevel(erParam.get<EnvironmentalReverb::levelMb>()) !=
147                               RetCode::SUCCESS,
148                       EX_ILLEGAL_ARGUMENT, "setLevelFailed");
149             return ndk::ScopedAStatus::ok();
150         }
151         case EnvironmentalReverb::delayMs: {
152             RETURN_IF(mContext->setErDelay(erParam.get<EnvironmentalReverb::delayMs>()) !=
153                               RetCode::SUCCESS,
154                       EX_ILLEGAL_ARGUMENT, "setDelayFailed");
155             return ndk::ScopedAStatus::ok();
156         }
157         case EnvironmentalReverb::diffusionPm: {
158             RETURN_IF(mContext->setErDiffusion(erParam.get<EnvironmentalReverb::diffusionPm>()) !=
159                               RetCode::SUCCESS,
160                       EX_ILLEGAL_ARGUMENT, "setDiffusionFailed");
161             return ndk::ScopedAStatus::ok();
162         }
163         case EnvironmentalReverb::densityPm: {
164             RETURN_IF(mContext->setErDensity(erParam.get<EnvironmentalReverb::densityPm>()) !=
165                               RetCode::SUCCESS,
166                       EX_ILLEGAL_ARGUMENT, "setDensityFailed");
167             return ndk::ScopedAStatus::ok();
168         }
169         case EnvironmentalReverb::bypass: {
170             RETURN_IF(mContext->setErBypass(erParam.get<EnvironmentalReverb::bypass>()) !=
171                               RetCode::SUCCESS,
172                       EX_ILLEGAL_ARGUMENT, "setBypassFailed");
173             return ndk::ScopedAStatus::ok();
174         }
175         default: {
176             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
177             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
178                     EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
179         }
180     }
181 }
182 
getParameterSpecific(const Parameter::Id & id,Parameter::Specific * specific)183 ndk::ScopedAStatus EnvReverbSw::getParameterSpecific(const Parameter::Id& id,
184                                                      Parameter::Specific* specific) {
185     auto tag = id.getTag();
186     RETURN_IF(Parameter::Id::environmentalReverbTag != tag, EX_ILLEGAL_ARGUMENT, "wrongIdTag");
187     auto erId = id.get<Parameter::Id::environmentalReverbTag>();
188     auto erIdTag = erId.getTag();
189     switch (erIdTag) {
190         case EnvironmentalReverb::Id::commonTag:
191             return getParameterEnvironmentalReverb(erId.get<EnvironmentalReverb::Id::commonTag>(),
192                                                    specific);
193         default:
194             LOG(ERROR) << __func__ << " unsupported tag: " << toString(erIdTag);
195             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
196                     EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
197     }
198 }
199 
getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag & tag,Parameter::Specific * specific)200 ndk::ScopedAStatus EnvReverbSw::getParameterEnvironmentalReverb(const EnvironmentalReverb::Tag& tag,
201                                                                 Parameter::Specific* specific) {
202     RETURN_IF(!mContext, EX_NULL_POINTER, "nullContext");
203     EnvironmentalReverb erParam;
204     switch (tag) {
205         case EnvironmentalReverb::roomLevelMb: {
206             erParam.set<EnvironmentalReverb::roomLevelMb>(mContext->getErRoomLevel());
207             break;
208         }
209         case EnvironmentalReverb::roomHfLevelMb: {
210             erParam.set<EnvironmentalReverb::roomHfLevelMb>(mContext->getErRoomHfLevel());
211             break;
212         }
213         case EnvironmentalReverb::decayTimeMs: {
214             erParam.set<EnvironmentalReverb::decayTimeMs>(mContext->getErDecayTime());
215             break;
216         }
217         case EnvironmentalReverb::decayHfRatioPm: {
218             erParam.set<EnvironmentalReverb::decayHfRatioPm>(mContext->getErDecayHfRatio());
219             break;
220         }
221         case EnvironmentalReverb::reflectionsLevelMb: {
222             erParam.set<EnvironmentalReverb::reflectionsLevelMb>(mContext->getErReflectionsLevel());
223             break;
224         }
225         case EnvironmentalReverb::reflectionsDelayMs: {
226             erParam.set<EnvironmentalReverb::reflectionsDelayMs>(mContext->getErReflectionsDelay());
227             break;
228         }
229         case EnvironmentalReverb::levelMb: {
230             erParam.set<EnvironmentalReverb::levelMb>(mContext->getErLevel());
231             break;
232         }
233         case EnvironmentalReverb::delayMs: {
234             erParam.set<EnvironmentalReverb::delayMs>(mContext->getErDelay());
235             break;
236         }
237         case EnvironmentalReverb::diffusionPm: {
238             erParam.set<EnvironmentalReverb::diffusionPm>(mContext->getErDiffusion());
239             break;
240         }
241         case EnvironmentalReverb::densityPm: {
242             erParam.set<EnvironmentalReverb::densityPm>(mContext->getErDensity());
243             break;
244         }
245         case EnvironmentalReverb::bypass: {
246             erParam.set<EnvironmentalReverb::bypass>(mContext->getErBypass());
247             break;
248         }
249         default: {
250             LOG(ERROR) << __func__ << " unsupported tag: " << toString(tag);
251             return ndk::ScopedAStatus::fromExceptionCodeWithMessage(
252                     EX_ILLEGAL_ARGUMENT, "EnvironmentalReverbTagNotSupported");
253         }
254     }
255 
256     specific->set<Parameter::Specific::environmentalReverb>(erParam);
257     return ndk::ScopedAStatus::ok();
258 }
259 
createContext(const Parameter::Common & common)260 std::shared_ptr<EffectContext> EnvReverbSw::createContext(const Parameter::Common& common) {
261     if (mContext) {
262         LOG(DEBUG) << __func__ << " context already exist";
263     } else {
264         mContext = std::make_shared<EnvReverbSwContext>(1 /* statusFmqDepth */, common);
265     }
266 
267     return mContext;
268 }
269 
getContext()270 std::shared_ptr<EffectContext> EnvReverbSw::getContext() {
271     return mContext;
272 }
273 
releaseContext()274 RetCode EnvReverbSw::releaseContext() {
275     if (mContext) {
276         mContext.reset();
277     }
278     return RetCode::SUCCESS;
279 }
280 
281 // Processing method running in EffectWorker thread.
effectProcessImpl(float * in,float * out,int samples)282 IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int samples) {
283     // TODO: get data buffer and process.
284     LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
285     for (int i = 0; i < samples; i++) {
286         *out++ = *in++;
287     }
288     return {STATUS_OK, samples, samples};
289 }
290 
setErRoomLevel(int roomLevel)291 RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
292     mRoomLevel = roomLevel;
293     return RetCode::SUCCESS;
294 }
295 
setErRoomHfLevel(int roomHfLevel)296 RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
297     mRoomHfLevel = roomHfLevel;
298     return RetCode::SUCCESS;
299 }
300 
setErDecayTime(int decayTime)301 RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
302     mDecayTime = decayTime;
303     return RetCode::SUCCESS;
304 }
305 
setErDecayHfRatio(int decayHfRatio)306 RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
307     mDecayHfRatio = decayHfRatio;
308     return RetCode::SUCCESS;
309 }
310 
setErLevel(int level)311 RetCode EnvReverbSwContext::setErLevel(int level) {
312     mLevel = level;
313     return RetCode::SUCCESS;
314 }
315 
setErDelay(int delay)316 RetCode EnvReverbSwContext::setErDelay(int delay) {
317     mDelay = delay;
318     return RetCode::SUCCESS;
319 }
320 
setErDiffusion(int diffusion)321 RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
322     mDiffusion = diffusion;
323     return RetCode::SUCCESS;
324 }
325 
setErDensity(int density)326 RetCode EnvReverbSwContext::setErDensity(int density) {
327     mDensity = density;
328     return RetCode::SUCCESS;
329 }
330 
331 }  // namespace aidl::android::hardware::audio::effect
332