• 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 <cstddef>
18 #define LOG_TAG "PreProcessingContext"
19 #include <Utils.h>
20 
21 #include "PreProcessingContext.h"
22 
23 namespace aidl::android::hardware::audio::effect {
24 
25 using aidl::android::media::audio::common::AudioDeviceDescription;
26 using aidl::android::media::audio::common::AudioDeviceType;
27 
init(const Parameter::Common & common)28 RetCode 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 
deInit()66 RetCode PreProcessingContext::deInit() {
67     std::lock_guard lg(mMutex);
68     mAudioProcessingModule = nullptr;
69     mState = PRE_PROC_STATE_UNINITIALIZED;
70     return RetCode::SUCCESS;
71 }
72 
enable()73 RetCode 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 
disable()108 RetCode 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 
setCommon(const Parameter::Common & common)143 RetCode PreProcessingContext::setCommon(const Parameter::Common& common) {
144     mCommon = common;
145     updateConfigs(common);
146     return RetCode::SUCCESS;
147 }
148 
updateConfigs(const Parameter::Common & common)149 void PreProcessingContext::updateConfigs(const Parameter::Common& common) {
150     mInputConfig.set_sample_rate_hz(common.input.base.sampleRate);
151     mInputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
152                     common.input.base.channelMask));
153     mOutputConfig.set_sample_rate_hz(common.input.base.sampleRate);
154     mOutputConfig.set_num_channels(::aidl::android::hardware::audio::common::getChannelCount(
155                     common.output.base.channelMask));
156 }
157 
setAcousticEchoCancelerEchoDelay(int echoDelayUs)158 RetCode PreProcessingContext::setAcousticEchoCancelerEchoDelay(int echoDelayUs) {
159     mEchoDelayUs = echoDelayUs;
160     std::lock_guard lg(mMutex);
161     mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
162     return RetCode::SUCCESS;
163 }
164 
getAcousticEchoCancelerEchoDelay() const165 int PreProcessingContext::getAcousticEchoCancelerEchoDelay() const {
166     return mEchoDelayUs;
167 }
168 
setAcousticEchoCancelerMobileMode(bool mobileMode)169 RetCode PreProcessingContext::setAcousticEchoCancelerMobileMode(bool mobileMode) {
170     mMobileMode = mobileMode;
171     std::lock_guard lg(mMutex);
172     auto config = mAudioProcessingModule->GetConfig();
173     config.echo_canceller.mobile_mode = mobileMode;
174     mAudioProcessingModule->ApplyConfig(config);
175     return RetCode::SUCCESS;
176 }
177 
getAcousticEchoCancelerMobileMode() const178 bool PreProcessingContext::getAcousticEchoCancelerMobileMode() const {
179     return mMobileMode;
180 }
181 
setAutomaticGainControlV1TargetPeakLevel(int targetPeakLevel)182 RetCode PreProcessingContext::setAutomaticGainControlV1TargetPeakLevel(int targetPeakLevel) {
183     mTargetPeakLevel = targetPeakLevel;
184     std::lock_guard lg(mMutex);
185     auto config = mAudioProcessingModule->GetConfig();
186     config.gain_controller1.target_level_dbfs = -(mTargetPeakLevel / 100);
187     mAudioProcessingModule->ApplyConfig(config);
188     return RetCode::SUCCESS;
189 }
190 
getAutomaticGainControlV1TargetPeakLevel() const191 int PreProcessingContext::getAutomaticGainControlV1TargetPeakLevel() const {
192     return mTargetPeakLevel;
193 }
194 
setAutomaticGainControlV1MaxCompressionGain(int maxCompressionGain)195 RetCode PreProcessingContext::setAutomaticGainControlV1MaxCompressionGain(int maxCompressionGain) {
196     mMaxCompressionGain = maxCompressionGain;
197     std::lock_guard lg(mMutex);
198     auto config = mAudioProcessingModule->GetConfig();
199     config.gain_controller1.compression_gain_db = mMaxCompressionGain / 100;
200     mAudioProcessingModule->ApplyConfig(config);
201     return RetCode::SUCCESS;
202 }
203 
getAutomaticGainControlV1MaxCompressionGain() const204 int PreProcessingContext::getAutomaticGainControlV1MaxCompressionGain() const {
205     return mMaxCompressionGain;
206 }
207 
setAutomaticGainControlV1EnableLimiter(bool enableLimiter)208 RetCode PreProcessingContext::setAutomaticGainControlV1EnableLimiter(bool enableLimiter) {
209     mEnableLimiter = enableLimiter;
210     std::lock_guard lg(mMutex);
211     auto config = mAudioProcessingModule->GetConfig();
212     config.gain_controller1.enable_limiter = mEnableLimiter;
213     mAudioProcessingModule->ApplyConfig(config);
214     return RetCode::SUCCESS;
215 }
216 
getAutomaticGainControlV1EnableLimiter() const217 bool PreProcessingContext::getAutomaticGainControlV1EnableLimiter() const {
218     return mEnableLimiter;
219 }
220 
setAutomaticGainControlV2DigitalGain(int gain)221 RetCode PreProcessingContext::setAutomaticGainControlV2DigitalGain(int gain) {
222     mDigitalGain = gain;
223     std::lock_guard lg(mMutex);
224     auto config = mAudioProcessingModule->GetConfig();
225     config.gain_controller2.fixed_digital.gain_db = mDigitalGain;
226     mAudioProcessingModule->ApplyConfig(config);
227     return RetCode::SUCCESS;
228 }
229 
getAutomaticGainControlV2DigitalGain() const230 int PreProcessingContext::getAutomaticGainControlV2DigitalGain() const {
231     return mDigitalGain;
232 }
233 
setAutomaticGainControlV2LevelEstimator(AutomaticGainControlV2::LevelEstimator levelEstimator)234 RetCode PreProcessingContext::setAutomaticGainControlV2LevelEstimator(
235         AutomaticGainControlV2::LevelEstimator levelEstimator) {
236     mLevelEstimator = levelEstimator;
237     return RetCode::SUCCESS;
238 }
239 
240 AutomaticGainControlV2::LevelEstimator
getAutomaticGainControlV2LevelEstimator() const241 PreProcessingContext::getAutomaticGainControlV2LevelEstimator() const {
242     return mLevelEstimator;
243 }
244 
setAutomaticGainControlV2SaturationMargin(int saturationMargin)245 RetCode PreProcessingContext::setAutomaticGainControlV2SaturationMargin(int saturationMargin) {
246     mSaturationMargin = saturationMargin;
247     return RetCode::SUCCESS;
248 }
249 
getAutomaticGainControlV2SaturationMargin() const250 int PreProcessingContext::getAutomaticGainControlV2SaturationMargin() const {
251     return mSaturationMargin;
252 }
253 
setNoiseSuppressionLevel(NoiseSuppression::Level level)254 RetCode PreProcessingContext::setNoiseSuppressionLevel(NoiseSuppression::Level level) {
255     mLevel = level;
256     std::lock_guard lg(mMutex);
257     auto config = mAudioProcessingModule->GetConfig();
258     config.noise_suppression.level =
259             (webrtc::AudioProcessing::Config::NoiseSuppression::Level)level;
260     mAudioProcessingModule->ApplyConfig(config);
261     return RetCode::SUCCESS;
262 }
263 
getNoiseSuppressionLevel() const264 NoiseSuppression::Level PreProcessingContext::getNoiseSuppressionLevel() const {
265     return mLevel;
266 }
267 
lvmProcess(float * in,float * out,int samples)268 IEffect::Status PreProcessingContext::lvmProcess(float* in, float* out, int samples) {
269     IEffect::Status status = {EX_NULL_POINTER, 0, 0};
270     RETURN_VALUE_IF(!in, status, "nullInput");
271     RETURN_VALUE_IF(!out, status, "nullOutput");
272     status = {EX_ILLEGAL_STATE, 0, 0};
273     int64_t inputFrameCount = getCommon().input.frameCount;
274     int64_t outputFrameCount = getCommon().output.frameCount;
275     RETURN_VALUE_IF(inputFrameCount != outputFrameCount, status, "FrameCountMismatch");
276     RETURN_VALUE_IF(0 == getInputFrameSize(), status, "zeroFrameSize");
277 
278     LOG(DEBUG) << __func__ << " start processing";
279     std::lock_guard lg(mMutex);
280 
281     mProcessedMsk |= (1 << int(mType));
282 
283     // webrtc implementation clear out was_stream_delay_set every time after ProcessStream() call
284     mAudioProcessingModule->set_stream_delay_ms(mEchoDelayUs / 1000);
285 
286     if ((mProcessedMsk & mEnabledMsk) == mEnabledMsk) {
287         mProcessedMsk = 0;
288         int processStatus = mAudioProcessingModule->ProcessStream(
289                 (const int16_t* const)in, mInputConfig, mOutputConfig, (int16_t* const)out);
290         if (processStatus != 0) {
291             LOG(ERROR) << "Process stream failed with error " << processStatus;
292             return status;
293         }
294     }
295 
296     mRevProcessedMsk |= (1 << int(mType));
297 
298     if ((mRevProcessedMsk & mRevEnabledMsk) == mRevEnabledMsk) {
299         mRevProcessedMsk = 0;
300         int revProcessStatus = mAudioProcessingModule->ProcessReverseStream(
301                 (const int16_t* const)in, mInputConfig, mInputConfig, (int16_t* const)out);
302         if (revProcessStatus != 0) {
303             LOG(ERROR) << "Process reverse stream failed with error " << revProcessStatus;
304             return status;
305         }
306     }
307 
308     return {STATUS_OK, samples, samples};
309 }
310 
311 }  // namespace aidl::android::hardware::audio::effect
312