Chromium Code Reviews| 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 |