OLD | NEW |
---|---|
(Empty) | |
1 /* | |
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. | |
3 * | |
4 * Use of this source code is governed by a BSD-style license | |
5 * that can be found in the LICENSE file in the root of the source | |
6 * tree. An additional intellectual property rights grant can be found | |
7 * in the file PATENTS. All contributing project authors may | |
8 * be found in the AUTHORS file in the root of the source tree. | |
9 */ | |
10 | |
11 #include "webrtc/media/engine/apm_helpers.h" | |
12 | |
13 #include "webrtc/base/logging.h" | |
14 #include "webrtc/modules/audio_processing/include/audio_processing.h" | |
15 #include "webrtc/modules/audio_device/include/audio_device.h" | |
hlundin-webrtc
2017/02/20 09:01:08
Wrong order
the sun
2017/02/20 19:37:57
Done.
| |
16 #include "webrtc/voice_engine/transmit_mixer.h" | |
17 | |
18 namespace webrtc { | |
19 namespace apm_helpers { | |
20 | |
21 AgcConfig GetAgcConfig(AudioProcessing* apm) { | |
22 RTC_DCHECK(apm); | |
23 AgcConfig result; | |
24 result.targetLeveldBOv = apm->gain_control()->target_level_dbfs(); | |
25 result.digitalCompressionGaindB = apm->gain_control()->compression_gain_db(); | |
26 result.limiterEnable = apm->gain_control()->is_limiter_enabled(); | |
27 return result; | |
28 } | |
29 | |
30 void SetAgcConfig(AudioProcessing* apm, | |
31 const AgcConfig& config) { | |
32 RTC_DCHECK(apm); | |
33 GainControl* gc = apm->gain_control(); | |
34 if (gc->set_target_level_dbfs(config.targetLeveldBOv) != 0) { | |
35 LOG(LS_ERROR) << "Failed to set target level: " << config.targetLeveldBOv; | |
36 } | |
37 if (gc->set_compression_gain_db(config.digitalCompressionGaindB) != 0) { | |
38 LOG(LS_ERROR) << "Failed to set compression gain: " | |
39 << config.digitalCompressionGaindB; | |
40 } | |
41 if (gc->enable_limiter(config.limiterEnable) != 0) { | |
42 LOG(LS_ERROR) << "Failed to set limiter on/off: " << config.limiterEnable; | |
43 } | |
44 } | |
45 | |
46 void SetAgcStatus(AudioProcessing* apm, | |
47 AudioDeviceModule* adm, | |
48 bool enable, | |
49 AgcModes mode) { | |
50 RTC_DCHECK(apm); | |
51 RTC_DCHECK(adm); | |
52 RTC_DCHECK(mode == kAgcFixedDigital || mode == kAgcAdaptiveAnalog); | |
hlundin-webrtc
2017/02/20 09:01:08
This DCHECK is superfluous, since you are checking
the sun
2017/02/20 19:37:57
Done.
| |
53 #if defined(WEBRTC_IOS) || defined(WEBRTC_ANDROID) | |
54 RTC_DCHECK_EQ(kAgcFixedDigital, mode); | |
55 GainControl::Mode agc_mode = GainControl::kFixedDigital; | |
56 #else | |
57 RTC_DCHECK_EQ(kAgcAdaptiveAnalog, mode); | |
58 GainControl::Mode agc_mode = GainControl::kAdaptiveAnalog; | |
59 #endif | |
60 GainControl* gc = apm->gain_control(); | |
61 if (gc->set_mode(agc_mode) != 0) { | |
62 LOG(LS_ERROR) << "Failed to set AGC mode: " << agc_mode; | |
63 return; | |
64 } | |
65 if (gc->Enable(enable) != 0) { | |
66 LOG(LS_ERROR) << "Failed to enable/disable AGC: " << enable; | |
67 return; | |
68 } | |
69 if (agc_mode != GainControl::kFixedDigital) { | |
hlundin-webrtc
2017/02/20 09:01:08
Are we somehow depending on that the ADM AGC is al
the sun
2017/02/20 19:37:57
Not sure what we depend on in reality - the SetAGC
| |
70 // Set Agc state in the ADM when adaptive Agc mode has been selected. | |
71 // Note that we also enable the ADM Agc when Adaptive Digital mode is | |
72 // used since we want to be able to provide the APM with updated mic | |
73 // levels when the user modifies the mic level manually. | |
74 if (adm->SetAGC(enable) != 0) { | |
75 LOG(LS_ERROR) << "Failed to set AGC mode in ADM: " << enable; | |
76 return; | |
77 } | |
78 } | |
79 LOG(LS_INFO) << "AGC set to " << enable << " with mode " << mode; | |
80 } | |
81 | |
82 void SetEcStatus(AudioProcessing* apm, | |
83 bool enable, | |
84 EcModes mode) { | |
85 RTC_DCHECK(apm); | |
86 RTC_DCHECK(mode == kEcConference || mode == kEcAecm); | |
hlundin-webrtc
2017/02/20 09:01:08
Consider RTC_DCHECK(...) << "mode: " << mode;
to g
the sun
2017/02/20 19:37:57
Done.
| |
87 EchoCancellation* ec = apm->echo_cancellation(); | |
88 EchoControlMobile* ecm = apm->echo_control_mobile(); | |
89 if (mode == kEcConference) { | |
90 // Disable the AECM before enabling the AEC. | |
91 if (enable && ecm->is_enabled() && ecm->Enable(false) != 0) { | |
92 LOG(LS_ERROR) << "Failed to disable AECM."; | |
93 return; | |
94 } | |
95 if (ec->Enable(enable) != 0) { | |
96 LOG(LS_ERROR) << "Failed to enable/disable AEC: " << enable; | |
97 return; | |
98 } | |
99 if (ec->set_suppression_level(EchoCancellation::kHighSuppression) | |
100 != 0) { | |
101 LOG(LS_ERROR) << "Failed to set high AEC aggressiveness."; | |
102 return; | |
103 } | |
104 } else { | |
105 // Disable the AEC before enabling the AECM. | |
106 if (enable && ec->is_enabled() && ec->Enable(false) != 0) { | |
107 LOG(LS_ERROR) << "Failed to disable AEC."; | |
108 return; | |
109 } | |
110 if (ecm->Enable(enable) != 0) { | |
111 LOG(LS_ERROR) << "Failed to enable/disable AECM: " << enable; | |
112 return; | |
113 } | |
114 } | |
115 LOG(LS_INFO) << "Echo control set to " << enable << " with mode " << mode; | |
116 } | |
117 | |
118 void SetEcMetricsStatus(AudioProcessing* apm, bool enable) { | |
119 RTC_DCHECK(apm); | |
120 if ((apm->echo_cancellation()->enable_metrics(enable) != 0) || | |
121 (apm->echo_cancellation()->enable_delay_logging(enable) != 0)) { | |
122 LOG(LS_ERROR) << "Failed to enable/disable EC metrics: " << enable; | |
123 } | |
124 } | |
125 | |
126 void SetAecmMode(AudioProcessing* apm, bool enable_cng) { | |
127 RTC_DCHECK(apm); | |
128 EchoControlMobile* ecm = apm->echo_control_mobile(); | |
129 RTC_DCHECK_EQ(EchoControlMobile::kSpeakerphone, ecm->routing_mode()); | |
130 if (ecm->enable_comfort_noise(enable_cng) != 0) { | |
131 LOG(LS_ERROR) << "Failed to enable/disable CNG: " << enable_cng; | |
hlundin-webrtc
2017/02/20 09:01:07
Alignment is off.
the sun
2017/02/20 19:37:57
Done.
| |
132 return; | |
hlundin-webrtc
2017/02/20 09:01:08
Unnecessary return statement.
the sun
2017/02/20 19:37:58
Added log statement in the success path instead.
| |
133 } | |
134 } | |
135 | |
136 void SetNsStatus(AudioProcessing* apm, bool enable) { | |
137 RTC_DCHECK(apm); | |
138 NoiseSuppression* ns = apm->noise_suppression(); | |
139 if (ns->set_level(NoiseSuppression::kHigh) != 0) { | |
140 LOG(LS_ERROR) << "Failed to set high NS level."; | |
141 return; | |
142 } | |
143 if (ns->Enable(enable) != 0) { | |
144 LOG(LS_ERROR) << "Failed to enable/disable NS: " << enable; | |
145 return; | |
146 } | |
147 LOG(LS_INFO) << "NS set to " << enable; | |
148 } | |
149 | |
150 void SetTypingDetectionStatus(AudioProcessing* apm, bool enable) { | |
151 RTC_DCHECK(apm); | |
152 #if WEBRTC_VOICE_ENGINE_TYPING_DETECTION | |
153 // Typing detection takes place in TransmitMixer::PrepareDemux() and | |
154 // TransmitMixer::TypingDetection(). The typing detection algorithm takes as | |
155 // input two booleans: | |
156 // 1. A signal whether a key was pressed during the audio frame. | |
157 // 2. Whether VAD is active or not. | |
158 // TransmitMixer will not even call the detector if APM has set kVadUnknown in | |
159 // the audio frame after near end processing, so enabling/disabling VAD is | |
160 // sufficient for turning typing detection on/off. | |
161 // TODO(solenberg): Rather than relying on a side effect, consider forcing the | |
162 // feature on/off in TransmitMixer. | |
163 VoiceDetection* vd = apm->voice_detection(); | |
164 if (vd->Enable(enable)) { | |
165 LOG(LS_ERROR) << "Failed to enable/disable VAD: " << enable; | |
166 return; | |
167 } | |
168 if (vd->set_likelihood(VoiceDetection::kVeryLowLikelihood)) { | |
169 LOG(LS_ERROR) << "Failed to set low VAD likelihood."; | |
170 return; | |
171 } | |
172 LOG(LS_INFO) << "VAD set to " << enable; | |
hlundin-webrtc
2017/02/20 09:01:08
Let the log text elaborate that VAD was set becaus
the sun
2017/02/20 19:37:57
Done.
| |
173 #endif | |
174 } | |
175 } // namespace apm_helpers | |
176 } // namespace webrtc | |
OLD | NEW |