OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. | 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
11 /* | 11 /* |
12 * Contains the API functions for the AEC. | 12 * Contains the API functions for the AEC. |
13 */ | 13 */ |
14 #include "webrtc/modules/audio_processing/aec/echo_cancellation.h" | 14 #include "webrtc/modules/audio_processing/aec/echo_cancellation.h" |
15 | 15 |
16 #include <math.h> | 16 #include <math.h> |
17 #ifdef WEBRTC_AEC_DEBUG_DUMP | 17 #if WEBRTC_AEC_DEBUG_DUMP == 1 |
18 #include <stdio.h> | 18 #include <stdio.h> |
19 #endif | 19 #endif |
20 #include <stdlib.h> | 20 #include <stdlib.h> |
21 #include <string.h> | 21 #include <string.h> |
22 | 22 |
23 extern "C" { | 23 extern "C" { |
24 #include "webrtc/common_audio/ring_buffer.h" | 24 #include "webrtc/common_audio/ring_buffer.h" |
25 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" | 25 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar
y.h" |
26 } | 26 } |
27 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 27 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
28 #include "webrtc/modules/audio_processing/aec/aec_resampler.h" | 28 #include "webrtc/modules/audio_processing/aec/aec_resampler.h" |
29 #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h" | 29 #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h" |
30 #include "webrtc/typedefs.h" | 30 #include "webrtc/typedefs.h" |
31 | 31 |
| 32 // Check to verify that the define is properly set. |
| 33 #if !defined(WEBRTC_AEC_DEBUG_DUMP) || \ |
| 34 (WEBRTC_AEC_DEBUG_DUMP != 0 && WEBRTC_AEC_DEBUG_DUMP != 1) |
| 35 #error "Set WEBRTC_AEC_DEBUG_DUMP to either 0 or 1" |
| 36 #endif |
| 37 |
32 namespace webrtc { | 38 namespace webrtc { |
33 | 39 |
34 // Measured delays [ms] | 40 // Measured delays [ms] |
35 // Device Chrome GTP | 41 // Device Chrome GTP |
36 // MacBook Air 10 | 42 // MacBook Air 10 |
37 // MacBook Retina 10 100 | 43 // MacBook Retina 10 100 |
38 // MacPro 30? | 44 // MacPro 30? |
39 // | 45 // |
40 // Win7 Desktop 70 80? | 46 // Win7 Desktop 70 80? |
41 // Win7 T430s 110 | 47 // Win7 T430s 110 |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
92 // Maximum length of resampled signal. Must be an integer multiple of frames | 98 // Maximum length of resampled signal. Must be an integer multiple of frames |
93 // (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN | 99 // (ceil(1/(1 + MIN_SKEW)*2) + 1)*FRAME_LEN |
94 // The factor of 2 handles wb, and the + 1 is as a safety margin | 100 // The factor of 2 handles wb, and the + 1 is as a safety margin |
95 // TODO(bjornv): Replace with kResamplerBufferSize | 101 // TODO(bjornv): Replace with kResamplerBufferSize |
96 #define MAX_RESAMP_LEN (5 * FRAME_LEN) | 102 #define MAX_RESAMP_LEN (5 * FRAME_LEN) |
97 | 103 |
98 static const int kMaxBufSizeStart = 62; // In partitions | 104 static const int kMaxBufSizeStart = 62; // In partitions |
99 static const int sampMsNb = 8; // samples per ms in nb | 105 static const int sampMsNb = 8; // samples per ms in nb |
100 static const int initCheck = 42; | 106 static const int initCheck = 42; |
101 | 107 |
102 #ifdef WEBRTC_AEC_DEBUG_DUMP | 108 int Aec::instance_count = 0; |
103 int webrtc_aec_instance_count = 0; | |
104 #endif | |
105 | 109 |
106 // Estimates delay to set the position of the far-end buffer read pointer | 110 // Estimates delay to set the position of the far-end buffer read pointer |
107 // (controlled by knownDelay) | 111 // (controlled by knownDelay) |
108 static void EstBufDelayNormal(Aec* aecInst); | 112 static void EstBufDelayNormal(Aec* aecInst); |
109 static void EstBufDelayExtended(Aec* aecInst); | 113 static void EstBufDelayExtended(Aec* aecInst); |
110 static int ProcessNormal(Aec* self, | 114 static int ProcessNormal(Aec* self, |
111 const float* const* near, | 115 const float* const* near, |
112 size_t num_bands, | 116 size_t num_bands, |
113 float* const* out, | 117 float* const* out, |
114 size_t num_samples, | 118 size_t num_samples, |
115 int16_t reported_delay_ms, | 119 int16_t reported_delay_ms, |
116 int32_t skew); | 120 int32_t skew); |
117 static void ProcessExtended(Aec* self, | 121 static void ProcessExtended(Aec* self, |
118 const float* const* near, | 122 const float* const* near, |
119 size_t num_bands, | 123 size_t num_bands, |
120 float* const* out, | 124 float* const* out, |
121 size_t num_samples, | 125 size_t num_samples, |
122 int16_t reported_delay_ms, | 126 int16_t reported_delay_ms, |
123 int32_t skew); | 127 int32_t skew); |
124 | 128 |
125 void* WebRtcAec_Create() { | 129 void* WebRtcAec_Create() { |
126 Aec* aecpc = reinterpret_cast<Aec*>(malloc(sizeof(Aec))); | 130 Aec* aecpc = reinterpret_cast<Aec*>(malloc(sizeof(Aec))); |
127 | 131 |
128 if (!aecpc) { | 132 if (!aecpc) { |
129 return NULL; | 133 return NULL; |
130 } | 134 } |
131 | 135 |
132 aecpc->aec = WebRtcAec_CreateAec(); | 136 aecpc->aec = WebRtcAec_CreateAec(aecpc->instance_count); |
133 if (!aecpc->aec) { | 137 if (!aecpc->aec) { |
134 WebRtcAec_Free(aecpc); | 138 WebRtcAec_Free(aecpc); |
135 return NULL; | 139 return NULL; |
136 } | 140 } |
137 aecpc->resampler = WebRtcAec_CreateResampler(); | 141 aecpc->resampler = WebRtcAec_CreateResampler(); |
138 if (!aecpc->resampler) { | 142 if (!aecpc->resampler) { |
139 WebRtcAec_Free(aecpc); | 143 WebRtcAec_Free(aecpc); |
140 return NULL; | 144 return NULL; |
141 } | 145 } |
142 // Create far-end pre-buffer. The buffer size has to be large enough for | 146 // Create far-end pre-buffer. The buffer size has to be large enough for |
143 // largest possible drift compensation (kResamplerBufferSize) + "almost" an | 147 // largest possible drift compensation (kResamplerBufferSize) + "almost" an |
144 // FFT buffer (PART_LEN2 - 1). | 148 // FFT buffer (PART_LEN2 - 1). |
145 aecpc->far_pre_buf = | 149 aecpc->far_pre_buf = |
146 WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float)); | 150 WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float)); |
147 if (!aecpc->far_pre_buf) { | 151 if (!aecpc->far_pre_buf) { |
148 WebRtcAec_Free(aecpc); | 152 WebRtcAec_Free(aecpc); |
149 return NULL; | 153 return NULL; |
150 } | 154 } |
151 | 155 |
152 aecpc->initFlag = 0; | 156 aecpc->initFlag = 0; |
153 | 157 |
154 #ifdef WEBRTC_AEC_DEBUG_DUMP | 158 #if WEBRTC_AEC_DEBUG_DUMP == 1 |
155 { | 159 char filename[64]; |
156 char filename[64]; | 160 snprintf(filename, sizeof(filename), "aec_buf%d.dat", aecpc->instance_count); |
157 snprintf(filename, sizeof(filename), "aec_buf%d.dat", | 161 aecpc->bufFile = fopen(filename, "wb"); |
158 webrtc_aec_instance_count); | 162 snprintf(filename, sizeof(filename), "aec_skew%d.dat", aecpc->instance_count); |
159 aecpc->bufFile = fopen(filename, "wb"); | 163 aecpc->skewFile = fopen(filename, "wb"); |
160 snprintf(filename, sizeof(filename), "aec_skew%d.dat", | 164 snprintf(filename, sizeof(filename), "aec_delay%d.dat", |
161 webrtc_aec_instance_count); | 165 aecpc->instance_count); |
162 aecpc->skewFile = fopen(filename, "wb"); | 166 aecpc->delayFile = fopen(filename, "wb"); |
163 snprintf(filename, sizeof(filename), "aec_delay%d.dat", | |
164 webrtc_aec_instance_count); | |
165 aecpc->delayFile = fopen(filename, "wb"); | |
166 webrtc_aec_instance_count++; | |
167 } | |
168 #endif | 167 #endif |
| 168 aecpc->instance_count++; |
169 | 169 |
170 return aecpc; | 170 return aecpc; |
171 } | 171 } |
172 | 172 |
173 void WebRtcAec_Free(void* aecInst) { | 173 void WebRtcAec_Free(void* aecInst) { |
174 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); | 174 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); |
175 | 175 |
176 if (aecpc == NULL) { | 176 if (aecpc == NULL) { |
177 return; | 177 return; |
178 } | 178 } |
179 | 179 |
180 WebRtc_FreeBuffer(aecpc->far_pre_buf); | 180 WebRtc_FreeBuffer(aecpc->far_pre_buf); |
181 | 181 |
182 #ifdef WEBRTC_AEC_DEBUG_DUMP | 182 #if WEBRTC_AEC_DEBUG_DUMP == 1 |
183 fclose(aecpc->bufFile); | 183 fclose(aecpc->bufFile); |
184 fclose(aecpc->skewFile); | 184 fclose(aecpc->skewFile); |
185 fclose(aecpc->delayFile); | 185 fclose(aecpc->delayFile); |
186 #endif | 186 #endif |
187 | 187 |
188 WebRtcAec_FreeAec(aecpc->aec); | 188 WebRtcAec_FreeAec(aecpc->aec); |
189 WebRtcAec_FreeResampler(aecpc->resampler); | 189 WebRtcAec_FreeResampler(aecpc->resampler); |
190 free(aecpc); | 190 free(aecpc); |
191 } | 191 } |
192 | 192 |
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
369 | 369 |
370 // This returns the value of aec->extended_filter_enabled. | 370 // This returns the value of aec->extended_filter_enabled. |
371 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { | 371 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { |
372 ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf, | 372 ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf, |
373 skew); | 373 skew); |
374 } else { | 374 } else { |
375 retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples, | 375 retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples, |
376 msInSndCardBuf, skew); | 376 msInSndCardBuf, skew); |
377 } | 377 } |
378 | 378 |
379 #ifdef WEBRTC_AEC_DEBUG_DUMP | 379 #if WEBRTC_AEC_DEBUG_DUMP == 1 |
380 { | 380 { |
381 int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / | 381 int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / |
382 (sampMsNb * aecpc->rate_factor)); | 382 (sampMsNb * aecpc->rate_factor)); |
383 (void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile); | 383 (void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile); |
384 (void)fwrite(&aecpc->knownDelay, sizeof(aecpc->knownDelay), 1, | 384 (void)fwrite(&aecpc->knownDelay, sizeof(aecpc->knownDelay), 1, |
385 aecpc->delayFile); | 385 aecpc->delayFile); |
386 } | 386 } |
387 #endif | 387 #endif |
388 | 388 |
389 return retVal; | 389 return retVal; |
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
596 } else { | 596 } else { |
597 aecpc->resample = kAecTrue; | 597 aecpc->resample = kAecTrue; |
598 } | 598 } |
599 | 599 |
600 if (aecpc->skew < minSkewEst) { | 600 if (aecpc->skew < minSkewEst) { |
601 aecpc->skew = minSkewEst; | 601 aecpc->skew = minSkewEst; |
602 } else if (aecpc->skew > maxSkewEst) { | 602 } else if (aecpc->skew > maxSkewEst) { |
603 aecpc->skew = maxSkewEst; | 603 aecpc->skew = maxSkewEst; |
604 } | 604 } |
605 | 605 |
606 #ifdef WEBRTC_AEC_DEBUG_DUMP | 606 #if WEBRTC_AEC_DEBUG_DUMP == 1 |
607 (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile); | 607 (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile); |
608 #endif | 608 #endif |
609 } | 609 } |
610 } | 610 } |
611 | 611 |
612 nBlocks10ms = nrOfSamples / (FRAME_LEN * aecpc->rate_factor); | 612 nBlocks10ms = nrOfSamples / (FRAME_LEN * aecpc->rate_factor); |
613 | 613 |
614 if (aecpc->startup_phase) { | 614 if (aecpc->startup_phase) { |
615 for (i = 0; i < num_bands; ++i) { | 615 for (i = 0; i < num_bands; ++i) { |
616 // Only needed if they don't already point to the same place. | 616 // Only needed if they don't already point to the same place. |
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
878 } else { | 878 } else { |
879 self->timeForDelayChange = 0; | 879 self->timeForDelayChange = 0; |
880 } | 880 } |
881 self->lastDelayDiff = delay_difference; | 881 self->lastDelayDiff = delay_difference; |
882 | 882 |
883 if (self->timeForDelayChange > 25) { | 883 if (self->timeForDelayChange > 25) { |
884 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); | 884 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); |
885 } | 885 } |
886 } | 886 } |
887 } // namespace webrtc | 887 } // namespace webrtc |
OLD | NEW |