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
releaseContext()270 RetCode EnvReverbSw::releaseContext() {
271 if (mContext) {
272 mContext.reset();
273 }
274 return RetCode::SUCCESS;
275 }
276
277 // Processing method running in EffectWorker thread.
effectProcessImpl(float * in,float * out,int samples)278 IEffect::Status EnvReverbSw::effectProcessImpl(float* in, float* out, int samples) {
279 // TODO: get data buffer and process.
280 LOG(DEBUG) << __func__ << " in " << in << " out " << out << " samples " << samples;
281 for (int i = 0; i < samples; i++) {
282 *out++ = *in++;
283 }
284 return {STATUS_OK, samples, samples};
285 }
286
setErRoomLevel(int roomLevel)287 RetCode EnvReverbSwContext::setErRoomLevel(int roomLevel) {
288 mRoomLevel = roomLevel;
289 return RetCode::SUCCESS;
290 }
291
setErRoomHfLevel(int roomHfLevel)292 RetCode EnvReverbSwContext::setErRoomHfLevel(int roomHfLevel) {
293 mRoomHfLevel = roomHfLevel;
294 return RetCode::SUCCESS;
295 }
296
setErDecayTime(int decayTime)297 RetCode EnvReverbSwContext::setErDecayTime(int decayTime) {
298 mDecayTime = decayTime;
299 return RetCode::SUCCESS;
300 }
301
setErDecayHfRatio(int decayHfRatio)302 RetCode EnvReverbSwContext::setErDecayHfRatio(int decayHfRatio) {
303 mDecayHfRatio = decayHfRatio;
304 return RetCode::SUCCESS;
305 }
306
setErLevel(int level)307 RetCode EnvReverbSwContext::setErLevel(int level) {
308 mLevel = level;
309 return RetCode::SUCCESS;
310 }
311
setErDelay(int delay)312 RetCode EnvReverbSwContext::setErDelay(int delay) {
313 mDelay = delay;
314 return RetCode::SUCCESS;
315 }
316
setErDiffusion(int diffusion)317 RetCode EnvReverbSwContext::setErDiffusion(int diffusion) {
318 mDiffusion = diffusion;
319 return RetCode::SUCCESS;
320 }
321
setErDensity(int density)322 RetCode EnvReverbSwContext::setErDensity(int density) {
323 mDensity = density;
324 return RetCode::SUCCESS;
325 }
326
327 } // namespace aidl::android::hardware::audio::effect
328