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 #if WEBRTC_AEC_DEBUG_DUMP == 1 | |
18 #include <stdio.h> | |
19 #endif | |
20 #include <stdlib.h> | 17 #include <stdlib.h> |
21 #include <string.h> | 18 #include <string.h> |
22 | 19 |
23 extern "C" { | 20 extern "C" { |
24 #include "webrtc/common_audio/ring_buffer.h" | 21 #include "webrtc/common_audio/ring_buffer.h" |
25 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" | 22 #include "webrtc/common_audio/signal_processing/include/signal_processing_librar y.h" |
26 } | 23 } |
27 #include "webrtc/modules/audio_processing/aec/aec_core.h" | 24 #include "webrtc/modules/audio_processing/aec/aec_core.h" |
28 #include "webrtc/modules/audio_processing/aec/aec_resampler.h" | 25 #include "webrtc/modules/audio_processing/aec/aec_resampler.h" |
29 #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h" | 26 #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h" |
27 #include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" | |
30 #include "webrtc/typedefs.h" | 28 #include "webrtc/typedefs.h" |
31 | 29 |
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 | |
38 namespace webrtc { | 30 namespace webrtc { |
39 | 31 |
40 // Measured delays [ms] | 32 // Measured delays [ms] |
41 // Device Chrome GTP | 33 // Device Chrome GTP |
42 // MacBook Air 10 | 34 // MacBook Air 10 |
43 // MacBook Retina 10 100 | 35 // MacBook Retina 10 100 |
44 // MacPro 30? | 36 // MacPro 30? |
45 // | 37 // |
46 // Win7 Desktop 70 80? | 38 // Win7 Desktop 70 80? |
47 // Win7 T430s 110 | 39 // Win7 T430s 110 |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
121 static void ProcessExtended(Aec* self, | 113 static void ProcessExtended(Aec* self, |
122 const float* const* near, | 114 const float* const* near, |
123 size_t num_bands, | 115 size_t num_bands, |
124 float* const* out, | 116 float* const* out, |
125 size_t num_samples, | 117 size_t num_samples, |
126 int16_t reported_delay_ms, | 118 int16_t reported_delay_ms, |
127 int32_t skew); | 119 int32_t skew); |
128 | 120 |
129 void* WebRtcAec_Create() { | 121 void* WebRtcAec_Create() { |
130 Aec* aecpc = reinterpret_cast<Aec*>(malloc(sizeof(Aec))); | 122 Aec* aecpc = reinterpret_cast<Aec*>(malloc(sizeof(Aec))); |
123 aecpc->data_dumper.reset(new ApmDataDumper(aecpc->instance_count)); | |
131 | 124 |
132 if (!aecpc) { | 125 if (!aecpc) { |
133 return NULL; | 126 return NULL; |
134 } | 127 } |
135 | 128 |
136 aecpc->aec = WebRtcAec_CreateAec(aecpc->instance_count); | 129 aecpc->aec = WebRtcAec_CreateAec(aecpc->instance_count); |
137 if (!aecpc->aec) { | 130 if (!aecpc->aec) { |
138 WebRtcAec_Free(aecpc); | 131 WebRtcAec_Free(aecpc); |
139 return NULL; | 132 return NULL; |
140 } | 133 } |
141 aecpc->resampler = WebRtcAec_CreateResampler(); | 134 aecpc->resampler = WebRtcAec_CreateResampler(); |
142 if (!aecpc->resampler) { | 135 if (!aecpc->resampler) { |
143 WebRtcAec_Free(aecpc); | 136 WebRtcAec_Free(aecpc); |
144 return NULL; | 137 return NULL; |
145 } | 138 } |
146 // Create far-end pre-buffer. The buffer size has to be large enough for | 139 // Create far-end pre-buffer. The buffer size has to be large enough for |
147 // largest possible drift compensation (kResamplerBufferSize) + "almost" an | 140 // largest possible drift compensation (kResamplerBufferSize) + "almost" an |
148 // FFT buffer (PART_LEN2 - 1). | 141 // FFT buffer (PART_LEN2 - 1). |
149 aecpc->far_pre_buf = | 142 aecpc->far_pre_buf = |
150 WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float)); | 143 WebRtc_CreateBuffer(PART_LEN2 + kResamplerBufferSize, sizeof(float)); |
151 if (!aecpc->far_pre_buf) { | 144 if (!aecpc->far_pre_buf) { |
152 WebRtcAec_Free(aecpc); | 145 WebRtcAec_Free(aecpc); |
153 return NULL; | 146 return NULL; |
154 } | 147 } |
155 | 148 |
156 aecpc->initFlag = 0; | 149 aecpc->initFlag = 0; |
157 | 150 |
158 #if WEBRTC_AEC_DEBUG_DUMP == 1 | |
159 char filename[64]; | |
160 snprintf(filename, sizeof(filename), "aec_buf%d.dat", aecpc->instance_count); | |
161 aecpc->bufFile = fopen(filename, "wb"); | |
162 snprintf(filename, sizeof(filename), "aec_skew%d.dat", aecpc->instance_count); | |
163 aecpc->skewFile = fopen(filename, "wb"); | |
164 snprintf(filename, sizeof(filename), "aec_delay%d.dat", | |
165 aecpc->instance_count); | |
166 aecpc->delayFile = fopen(filename, "wb"); | |
167 #endif | |
168 aecpc->instance_count++; | 151 aecpc->instance_count++; |
169 | |
170 return aecpc; | 152 return aecpc; |
171 } | 153 } |
172 | 154 |
173 void WebRtcAec_Free(void* aecInst) { | 155 void WebRtcAec_Free(void* aecInst) { |
174 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); | 156 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); |
175 | 157 |
176 if (aecpc == NULL) { | 158 if (aecpc == NULL) { |
177 return; | 159 return; |
178 } | 160 } |
179 | 161 |
180 WebRtc_FreeBuffer(aecpc->far_pre_buf); | 162 WebRtc_FreeBuffer(aecpc->far_pre_buf); |
181 | 163 |
182 #if WEBRTC_AEC_DEBUG_DUMP == 1 | |
183 fclose(aecpc->bufFile); | |
184 fclose(aecpc->skewFile); | |
185 fclose(aecpc->delayFile); | |
186 #endif | |
187 | |
188 WebRtcAec_FreeAec(aecpc->aec); | 164 WebRtcAec_FreeAec(aecpc->aec); |
189 WebRtcAec_FreeResampler(aecpc->resampler); | 165 WebRtcAec_FreeResampler(aecpc->resampler); |
190 free(aecpc); | 166 free(aecpc); |
191 } | 167 } |
192 | 168 |
193 int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { | 169 int32_t WebRtcAec_Init(void* aecInst, int32_t sampFreq, int32_t scSampFreq) { |
194 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); | 170 Aec* aecpc = reinterpret_cast<Aec*>(aecInst); |
171 aecpc->data_dumper->InitiateNewSetOfRecordings(); | |
195 AecConfig aecConfig; | 172 AecConfig aecConfig; |
196 | 173 |
197 if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 && | 174 if (sampFreq != 8000 && sampFreq != 16000 && sampFreq != 32000 && |
198 sampFreq != 48000) { | 175 sampFreq != 48000) { |
199 return AEC_BAD_PARAMETER_ERROR; | 176 return AEC_BAD_PARAMETER_ERROR; |
200 } | 177 } |
201 aecpc->sampFreq = sampFreq; | 178 aecpc->sampFreq = sampFreq; |
202 | 179 |
203 if (scSampFreq < 1 || scSampFreq > 96000) { | 180 if (scSampFreq < 1 || scSampFreq > 96000) { |
204 return AEC_BAD_PARAMETER_ERROR; | 181 return AEC_BAD_PARAMETER_ERROR; |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
369 | 346 |
370 // This returns the value of aec->extended_filter_enabled. | 347 // This returns the value of aec->extended_filter_enabled. |
371 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { | 348 if (WebRtcAec_extended_filter_enabled(aecpc->aec)) { |
372 ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf, | 349 ProcessExtended(aecpc, nearend, num_bands, out, nrOfSamples, msInSndCardBuf, |
373 skew); | 350 skew); |
374 } else { | 351 } else { |
375 retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples, | 352 retVal = ProcessNormal(aecpc, nearend, num_bands, out, nrOfSamples, |
376 msInSndCardBuf, skew); | 353 msInSndCardBuf, skew); |
377 } | 354 } |
378 | 355 |
379 #if WEBRTC_AEC_DEBUG_DUMP == 1 | 356 int far_buf_size_samples = WebRtcAec_system_delay(aecpc->aec); |
380 { | 357 aecpc->data_dumper->DumpRaw("aec_buf", 1, &far_buf_size_samples); |
hlundin-webrtc
2016/05/04 07:20:35
I don't know if the logged variable names are up f
peah-webrtc
2016/05/04 11:38:04
Absolutely! I for now kept the name that was there
| |
381 int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / | 358 aecpc->data_dumper->DumpRaw("aec_delay", 1, &aecpc->knownDelay); |
382 (sampMsNb * aecpc->rate_factor)); | |
383 (void)fwrite(&far_buf_size_ms, 2, 1, aecpc->bufFile); | |
384 (void)fwrite(&aecpc->knownDelay, sizeof(aecpc->knownDelay), 1, | |
385 aecpc->delayFile); | |
386 } | |
387 #endif | |
388 | 359 |
389 return retVal; | 360 return retVal; |
390 } | 361 } |
391 | 362 |
392 int WebRtcAec_set_config(void* handle, AecConfig config) { | 363 int WebRtcAec_set_config(void* handle, AecConfig config) { |
393 Aec* self = reinterpret_cast<Aec*>(handle); | 364 Aec* self = reinterpret_cast<Aec*>(handle); |
394 if (self->initFlag != initCheck) { | 365 if (self->initFlag != initCheck) { |
395 return AEC_UNINITIALIZED_ERROR; | 366 return AEC_UNINITIALIZED_ERROR; |
396 } | 367 } |
397 | 368 |
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
596 } else { | 567 } else { |
597 aecpc->resample = kAecTrue; | 568 aecpc->resample = kAecTrue; |
598 } | 569 } |
599 | 570 |
600 if (aecpc->skew < minSkewEst) { | 571 if (aecpc->skew < minSkewEst) { |
601 aecpc->skew = minSkewEst; | 572 aecpc->skew = minSkewEst; |
602 } else if (aecpc->skew > maxSkewEst) { | 573 } else if (aecpc->skew > maxSkewEst) { |
603 aecpc->skew = maxSkewEst; | 574 aecpc->skew = maxSkewEst; |
604 } | 575 } |
605 | 576 |
606 #if WEBRTC_AEC_DEBUG_DUMP == 1 | 577 aecpc->data_dumper->DumpRaw("aec_skew", 1, &aecpc->skew); |
607 (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile); | |
608 #endif | |
609 } | 578 } |
610 } | 579 } |
611 | 580 |
612 nBlocks10ms = nrOfSamples / (FRAME_LEN * aecpc->rate_factor); | 581 nBlocks10ms = nrOfSamples / (FRAME_LEN * aecpc->rate_factor); |
613 | 582 |
614 if (aecpc->startup_phase) { | 583 if (aecpc->startup_phase) { |
615 for (i = 0; i < num_bands; ++i) { | 584 for (i = 0; i < num_bands; ++i) { |
616 // Only needed if they don't already point to the same place. | 585 // Only needed if they don't already point to the same place. |
617 if (nearend[i] != out[i]) { | 586 if (nearend[i] != out[i]) { |
618 memcpy(out[i], nearend[i], sizeof(nearend[i][0]) * nrOfSamples); | 587 memcpy(out[i], nearend[i], sizeof(nearend[i][0]) * nrOfSamples); |
(...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
878 } else { | 847 } else { |
879 self->timeForDelayChange = 0; | 848 self->timeForDelayChange = 0; |
880 } | 849 } |
881 self->lastDelayDiff = delay_difference; | 850 self->lastDelayDiff = delay_difference; |
882 | 851 |
883 if (self->timeForDelayChange > 25) { | 852 if (self->timeForDelayChange > 25) { |
884 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); | 853 self->knownDelay = WEBRTC_SPL_MAX((int)self->filtDelay - 256, 0); |
885 } | 854 } |
886 } | 855 } |
887 } // namespace webrtc | 856 } // namespace webrtc |
OLD | NEW |