blob: 2c44e5cc13830f1ec38f76d31388e9a0da9d114b [file] [log] [blame]
Shraddha Basantwanice054522023-01-20 23:36:54 +05301/*
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 <cstddef>
18#define LOG_TAG "PreProcessingContext"
19#include <Utils.h>
20
21#include "PreProcessingContext.h"
22
23namespace aidl::android::hardware::audio::effect {
24
25using aidl::android::media::audio::common::AudioDeviceDescription;
26using aidl::android::media::audio::common::AudioDeviceType;
27
28RetCode PreProcessingContext::init(const Parameter::Common& common) {
29 std::lock_guard lg(mMutex);
30 webrtc::AudioProcessingBuilder apBuilder;
31 mAudioProcessingModule = apBuilder.Create();
32 if (mAudioProcessingModule == nullptr) {
33 LOG(ERROR) << "init could not get apm engine";
34 return RetCode::ERROR_EFFECT_LIB_ERROR;
35 }
36
37 updateConfigs(common);
38
39 mEnabledMsk = 0;
40 mProcessedMsk = 0;
41 mRevEnabledMsk = 0;
42 mRevProcessedMsk = 0;
43
44 auto config = mAudioProcessingModule->GetConfig();
45 switch (mType) {
46 case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
47 config.echo_canceller.mobile_mode = true;
48 break;
49 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
50 config.gain_controller1.target_level_dbfs = kAgcDefaultTargetLevel;
51 config.gain_controller1.compression_gain_db = kAgcDefaultCompGain;
52 config.gain_controller1.enable_limiter = kAgcDefaultLimiter;
53 break;
54 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
55 config.gain_controller2.fixed_digital.gain_db = 0.f;
56 break;
57 case PreProcessingEffectType::NOISE_SUPPRESSION:
58 config.noise_suppression.level = kNsDefaultLevel;
59 break;
60 }
61 mAudioProcessingModule->ApplyConfig(config);
62 mState = PRE_PROC_STATE_INITIALIZED;
63 return RetCode::SUCCESS;
64}
65
66RetCode PreProcessingContext::deInit() {
67 std::lock_guard lg(mMutex);
68 mAudioProcessingModule = nullptr;
69 mState = PRE_PROC_STATE_UNINITIALIZED;
70 return RetCode::SUCCESS;
71}
72
73RetCode PreProcessingContext::enable() {
74 if (mState != PRE_PROC_STATE_INITIALIZED) {
75 return RetCode::ERROR_EFFECT_LIB_ERROR;
76 }
77 int typeMsk = (1 << int(mType));
78 std::lock_guard lg(mMutex);
79 // Check if effect is already enabled.
80 if ((mEnabledMsk & typeMsk) == typeMsk) {
81 return RetCode::ERROR_ILLEGAL_PARAMETER;
82 }
83 mEnabledMsk |= typeMsk;
84 auto config = mAudioProcessingModule->GetConfig();
85 switch (mType) {
86 case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
87 config.echo_canceller.enabled = true;
88 // AEC has reverse stream
89 mRevEnabledMsk |= typeMsk;
90 mRevProcessedMsk = 0;
91 break;
92 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
93 config.gain_controller1.enabled = true;
94 break;
95 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
96 config.gain_controller2.enabled = true;
97 break;
98 case PreProcessingEffectType::NOISE_SUPPRESSION:
99 config.noise_suppression.enabled = true;
100 break;
101 }
102 mProcessedMsk = 0;
103 mAudioProcessingModule->ApplyConfig(config);
104 mState = PRE_PROC_STATE_ACTIVE;
105 return RetCode::SUCCESS;
106}
107
108RetCode PreProcessingContext::disable() {
109 if (mState != PRE_PROC_STATE_ACTIVE) {
110 return RetCode::ERROR_EFFECT_LIB_ERROR;
111 }
112 int typeMsk = (1 << int(mType));
113 std::lock_guard lg(mMutex);
114 // Check if effect is already disabled.
115 if ((mEnabledMsk & typeMsk) != typeMsk) {
116 return RetCode::ERROR_ILLEGAL_PARAMETER;
117 }
118 mEnabledMsk &= ~typeMsk;
119 auto config = mAudioProcessingModule->GetConfig();
120 switch (mType) {
121 case PreProcessingEffectType::ACOUSTIC_ECHO_CANCELLATION:
122 config.echo_canceller.enabled = false;
123 // AEC has reverse stream
124 mRevEnabledMsk &= ~typeMsk;
125 mRevProcessedMsk = 0;
126 break;
127 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V1:
128 config.gain_controller1.enabled = false;
129 break;
130 case PreProcessingEffectType::AUTOMATIC_GAIN_CONTROL_V2:
131 config.gain_controller2.enabled = false;
132 break;
133 case PreProcessingEffectType::NOISE_SUPPRESSION:
134 config.noise_suppression.enabled = false;
135 break;
136 }
137 mProcessedMsk = 0;
138 mAudioProcessingModule->ApplyConfig(config);
139 mState = PRE_PROC_STATE_INITIALIZED;
140 return RetCode::SUCCESS;
141}
142
143RetCode PreProcessingContext::setCommon(const Parameter::Common& common) {
Shunkai Yao1afb46c2024-01-09 20:40:45 +0000144 if(auto ret = updateIOFrameSize(common); ret != RetCode::SUCCESS) {
145 return ret;
146 }
Shraddha Basantwanice054522023-01-20 23:36:54 +0530147 mCommon = common;
148 updateConfigs(common);
149 return RetCode::SUCCESS;
150}
151
152void PreProcessingContext::updateConfigs(const Parameter::Common& common) {
153 mInputConfig.set_sample_rate_hz(common.input.base.sampleRate);
Mikhail Naganov6352e822023-03-09 18:22:36 -0800154 mInputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
155 common.input.base.channelMask));
Shraddha Basantwanice054522023-01-20 23:36:54 +0530156 mOutputConfig.set_sample_rate_hz(common.input.base.sampleRate);
Mikhail Naganov6352e822023-03-09 18:22:36 -0800157 mOutputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
158 common.output.base.channelMask));
Shraddha Basantwanice054522023-01-20 23:36:54 +0530159}
160
161RetCode PreProcessingContext::setAcousticEchoCancelerEchoDelay(int echoDelayUs) {
162 mEchoDelayUs = echoDelayUs;
163 std::lock_guard lg(mMutex);
164 mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
165 return RetCode::SUCCESS;
166}
167
168int PreProcessingContext::getAcousticEchoCancelerEchoDelay() const {
169 return mEchoDelayUs;
170}
171
172RetCode PreProcessingContext::setAcousticEchoCancelerMobileMode(bool mobileMode) {
173 mMobileMode = mobileMode;
174 std::lock_guard lg(mMutex);
175 auto config = mAudioProcessingModule->GetConfig();
176 config.echo_canceller.mobile_mode = mobileMode;
177 mAudioProcessingModule->ApplyConfig(config);
178 return RetCode::SUCCESS;
179}
180
181bool PreProcessingContext::getAcousticEchoCancelerMobileMode() const {
182 return mMobileMode;
183}
184
185RetCode PreProcessingContext::setAutomaticGainControlV1TargetPeakLevel(int targetPeakLevel) {
186 mTargetPeakLevel = targetPeakLevel;
187 std::lock_guard lg(mMutex);
188 auto config = mAudioProcessingModule->GetConfig();
189 config.gain_controller1.target_level_dbfs = -(mTargetPeakLevel / 100);
190 mAudioProcessingModule->ApplyConfig(config);
191 return RetCode::SUCCESS;
192}
193
194int PreProcessingContext::getAutomaticGainControlV1TargetPeakLevel() const {
195 return mTargetPeakLevel;
196}
197
198RetCode PreProcessingContext::setAutomaticGainControlV1MaxCompressionGain(int maxCompressionGain) {
199 mMaxCompressionGain = maxCompressionGain;
200 std::lock_guard lg(mMutex);
201 auto config = mAudioProcessingModule->GetConfig();
202 config.gain_controller1.compression_gain_db = mMaxCompressionGain / 100;
203 mAudioProcessingModule->ApplyConfig(config);
204 return RetCode::SUCCESS;
205}
206
207int PreProcessingContext::getAutomaticGainControlV1MaxCompressionGain() const {
208 return mMaxCompressionGain;
209}
210
211RetCode PreProcessingContext::setAutomaticGainControlV1EnableLimiter(bool enableLimiter) {
212 mEnableLimiter = enableLimiter;
213 std::lock_guard lg(mMutex);
214 auto config = mAudioProcessingModule->GetConfig();
215 config.gain_controller1.enable_limiter = mEnableLimiter;
216 mAudioProcessingModule->ApplyConfig(config);
217 return RetCode::SUCCESS;
218}
219
220bool PreProcessingContext::getAutomaticGainControlV1EnableLimiter() const {
221 return mEnableLimiter;
222}
223
224RetCode PreProcessingContext::setAutomaticGainControlV2DigitalGain(int gain) {
225 mDigitalGain = gain;
226 std::lock_guard lg(mMutex);
227 auto config = mAudioProcessingModule->GetConfig();
228 config.gain_controller2.fixed_digital.gain_db = mDigitalGain;
229 mAudioProcessingModule->ApplyConfig(config);
230 return RetCode::SUCCESS;
231}
232
233int PreProcessingContext::getAutomaticGainControlV2DigitalGain() const {
234 return mDigitalGain;
235}
236
237RetCode PreProcessingContext::setAutomaticGainControlV2LevelEstimator(
238 AutomaticGainControlV2::LevelEstimator levelEstimator) {
239 mLevelEstimator = levelEstimator;
240 return RetCode::SUCCESS;
241}
242
243AutomaticGainControlV2::LevelEstimator
244PreProcessingContext::getAutomaticGainControlV2LevelEstimator() const {
245 return mLevelEstimator;
246}
247
248RetCode PreProcessingContext::setAutomaticGainControlV2SaturationMargin(int saturationMargin) {
249 mSaturationMargin = saturationMargin;
250 return RetCode::SUCCESS;
251}
252
253int PreProcessingContext::getAutomaticGainControlV2SaturationMargin() const {
254 return mSaturationMargin;
255}
256
257RetCode PreProcessingContext::setNoiseSuppressionLevel(NoiseSuppression::Level level) {
258 mLevel = level;
259 std::lock_guard lg(mMutex);
260 auto config = mAudioProcessingModule->GetConfig();
261 config.noise_suppression.level =
262 (webrtc::AudioProcessing::Config::NoiseSuppression::Level)level;
263 mAudioProcessingModule->ApplyConfig(config);
264 return RetCode::SUCCESS;
265}
266
267NoiseSuppression::Level PreProcessingContext::getNoiseSuppressionLevel() const {
268 return mLevel;
269}
270
271IEffect::Status PreProcessingContext::lvmProcess(float* in, float* out, int samples) {
272 IEffect::Status status = {EX_NULL_POINTER, 0, 0};
273 RETURN_VALUE_IF(!in, status, "nullInput");
274 RETURN_VALUE_IF(!out, status, "nullOutput");
275 status = {EX_ILLEGAL_STATE, 0, 0};
276 int64_t inputFrameCount = getCommon().input.frameCount;
277 int64_t outputFrameCount = getCommon().output.frameCount;
278 RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
279 RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
280
281 LOG(DEBUG) << __func__ << " start processing";
282 std::lock_guard lg(mMutex);
283
284 mProcessedMsk |= (1 << int(mType));
285
286 // webrtc implementation clear out was_stream_delay_set every time after ProcessStream() call
287 mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
288
289 if ((mProcessedMsk & mEnabledMsk) == mEnabledMsk) {
290 mProcessedMsk = 0;
291 int processStatus = mAudioProcessingModule->ProcessStream(
292 (const int16_t* const)in, mInputConfig, mOutputConfig, (int16_t* const)out);
293 if (processStatus != 0) {
294 LOG(ERROR) << "Process stream failed with error " << processStatus;
295 return status;
296 }
297 }
298
299 mRevProcessedMsk |= (1 << int(mType));
300
301 if ((mRevProcessedMsk & mRevEnabledMsk) == mRevEnabledMsk) {
302 mRevProcessedMsk = 0;
303 int revProcessStatus = mAudioProcessingModule->ProcessReverseStream(
304 (const int16_t* const)in, mInputConfig, mInputConfig, (int16_t* const)out);
305 if (revProcessStatus != 0) {
306 LOG(ERROR) << "Process reverse stream failed with error " << revProcessStatus;
307 return status;
308 }
309 }
310
311 return {STATUS_OK, samples, samples};
312}
313
314} // namespace aidl::android::hardware::audio::effect