diff --git a/webrtc/modules/audio_processing/BUILD.gn b/webrtc/modules/audio_processing/BUILD.gn index a3434836d8..c18c1d80cf 100644 --- a/webrtc/modules/audio_processing/BUILD.gn +++ b/webrtc/modules/audio_processing/BUILD.gn @@ -81,9 +81,8 @@ source_set("audio_processing") { "intelligibility/intelligibility_utils.h", "level_estimator_impl.cc", "level_estimator_impl.h", - "logging/aec_logging.h", - "logging/aec_logging_file_handling.cc", - "logging/aec_logging_file_handling.h", + "logging/apm_data_dumper.cc", + "logging/apm_data_dumper.h", "noise_suppression_impl.cc", "noise_suppression_impl.h", "render_queue_item_verifier.h", @@ -149,7 +148,9 @@ source_set("audio_processing") { ] if (aec_debug_dump) { - defines += [ "WEBRTC_AEC_DEBUG_DUMP" ] + defines += [ "WEBRTC_AEC_DEBUG_DUMP=1" ] + } else { + defines += [ "WEBRTC_AEC_DEBUG_DUMP=0" ] } if (aec_untrusted_delay_for_testing) { @@ -250,6 +251,12 @@ if (current_cpu == "x86" || current_cpu == "x64") { configs += [ "../..:common_config" ] public_configs = [ "../..:common_inherited_config" ] + + if (aec_debug_dump) { + defines = [ "WEBRTC_AEC_DEBUG_DUMP=1" ] + } else { + defines = [ "WEBRTC_AEC_DEBUG_DUMP=0" ] + } } } @@ -285,5 +292,11 @@ if (rtc_build_with_neon) { deps = [ "../../common_audio", ] + + if (aec_debug_dump) { + defines = [ "WEBRTC_AEC_DEBUG_DUMP=1" ] + } else { + defines = [ "WEBRTC_AEC_DEBUG_DUMP=0" ] + } } } diff --git a/webrtc/modules/audio_processing/aec/aec_core.cc b/webrtc/modules/audio_processing/aec/aec_core.cc index aa6cfa8208..2a6adde961 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.cc +++ b/webrtc/modules/audio_processing/aec/aec_core.cc @@ -14,10 +14,6 @@ #include "webrtc/modules/audio_processing/aec/aec_core.h" -#ifdef WEBRTC_AEC_DEBUG_DUMP -#include -#endif - #include #include #include @@ -34,7 +30,6 @@ extern "C" { #include "webrtc/modules/audio_processing/aec/aec_common.h" #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" #include "webrtc/modules/audio_processing/aec/aec_rdft.h" -#include "webrtc/modules/audio_processing/logging/aec_logging.h" #include "webrtc/modules/audio_processing/utility/delay_estimator_wrapper.h" #include "webrtc/system_wrappers/include/cpu_features_wrapper.h" #include "webrtc/typedefs.h" @@ -133,10 +128,6 @@ const float WebRtcAec_kNormalSmoothingCoefficients[2][2] = {{0.9f, 0.1f}, // Number of partitions forming the NLP's "preferred" bands. enum { kPrefBandSize = 24 }; -#ifdef WEBRTC_AEC_DEBUG_DUMP -extern int webrtc_aec_instance_count; -#endif - WebRtcAecFilterFar WebRtcAec_FilterFar; WebRtcAecScaleErrorSignal WebRtcAec_ScaleErrorSignal; WebRtcAecFilterAdaptation WebRtcAec_FilterAdaptation; @@ -207,7 +198,10 @@ void DivergentFilterFraction::Clear() { } // TODO(minyue): Moving some initialization from WebRtcAec_CreateAec() to ctor. -AecCore::AecCore() = default; +AecCore::AecCore(int instance_index) + : data_dumper(new ApmDataDumper(instance_index)) {} + +AecCore::~AecCore() {} static int CmpFloat(const void* a, const void* b) { const float* da = (const float*)a; @@ -1269,15 +1263,10 @@ static void ProcessBlock(AecCore* aec) { WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast(&farend_ptr), farend, 1); -#ifdef WEBRTC_AEC_DEBUG_DUMP - { - // TODO(minyue): |farend_ptr| starts from buffered samples. This will be - // modified when |aec->far_time_buf| is revised. - RTC_AEC_DEBUG_WAV_WRITE(aec->farFile, &farend_ptr[PART_LEN], PART_LEN); - - RTC_AEC_DEBUG_WAV_WRITE(aec->nearFile, nearend_ptr, PART_LEN); - } -#endif + aec->data_dumper->DumpWav("aec_far", PART_LEN, &farend_ptr[PART_LEN], + std::min(aec->sampFreq, 16000), 1); + aec->data_dumper->DumpWav("aec_near", PART_LEN, nearend_ptr, + std::min(aec->sampFreq, 16000), 1); if (aec->metricsMode == 1) { // Update power levels @@ -1377,7 +1366,8 @@ static void ProcessBlock(AecCore* aec) { aec->xfBuf, nearend_ptr, aec->xPow, aec->wfBuf, echo_subtractor_output); - RTC_AEC_DEBUG_WAV_WRITE(aec->outLinearFile, echo_subtractor_output, PART_LEN); + aec->data_dumper->DumpWav("aec_out_linear", PART_LEN, echo_subtractor_output, + std::min(aec->sampFreq, 16000), 1); if (aec->metricsMode == 1) { UpdateLevel(&aec->linoutlevel, @@ -1399,12 +1389,14 @@ static void ProcessBlock(AecCore* aec) { WebRtc_WriteBuffer(aec->outFrBufH[i], outputH[i], PART_LEN); } - RTC_AEC_DEBUG_WAV_WRITE(aec->outFile, output, PART_LEN); + aec->data_dumper->DumpWav("aec_out", PART_LEN, output, + std::min(aec->sampFreq, 16000), 1); } -AecCore* WebRtcAec_CreateAec() { +AecCore* WebRtcAec_CreateAec(int instance_count) { int i; - AecCore* aec = new AecCore; + AecCore* aec = new AecCore(instance_count); + if (!aec) { return NULL; } @@ -1448,12 +1440,6 @@ AecCore* WebRtcAec_CreateAec() { return NULL; } -#ifdef WEBRTC_AEC_DEBUG_DUMP - aec->instance_index = webrtc_aec_instance_count; - - aec->farFile = aec->nearFile = aec->outFile = aec->outLinearFile = NULL; - aec->debug_dump_count = 0; -#endif aec->delay_estimator_farend = WebRtc_CreateDelayEstimatorFarend(PART_LEN1, kHistorySizeBlocks); if (aec->delay_estimator_farend == NULL) { @@ -1531,12 +1517,6 @@ void WebRtcAec_FreeAec(AecCore* aec) { WebRtc_FreeBuffer(aec->far_time_buf); - RTC_AEC_DEBUG_WAV_CLOSE(aec->farFile); - RTC_AEC_DEBUG_WAV_CLOSE(aec->nearFile); - RTC_AEC_DEBUG_WAV_CLOSE(aec->outFile); - RTC_AEC_DEBUG_WAV_CLOSE(aec->outLinearFile); - RTC_AEC_DEBUG_RAW_CLOSE(aec->e_fft_file); - WebRtc_FreeDelayEstimator(aec->delay_estimator); WebRtc_FreeDelayEstimatorFarend(aec->delay_estimator_farend); @@ -1581,6 +1561,7 @@ static void SetErrorThreshold(AecCore* aec) { int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { int i; + aec->data_dumper->InitiateNewSetOfRecordings(); aec->sampFreq = sampFreq; @@ -1603,27 +1584,6 @@ int WebRtcAec_InitAec(AecCore* aec, int sampFreq) { // Initialize far-end buffers. WebRtc_InitBuffer(aec->far_time_buf); -#ifdef WEBRTC_AEC_DEBUG_DUMP - { - int process_rate = sampFreq > 16000 ? 16000 : sampFreq; - RTC_AEC_DEBUG_WAV_REOPEN("aec_far", aec->instance_index, - aec->debug_dump_count, process_rate, - &aec->farFile); - RTC_AEC_DEBUG_WAV_REOPEN("aec_near", aec->instance_index, - aec->debug_dump_count, process_rate, - &aec->nearFile); - RTC_AEC_DEBUG_WAV_REOPEN("aec_out", aec->instance_index, - aec->debug_dump_count, process_rate, - &aec->outFile); - RTC_AEC_DEBUG_WAV_REOPEN("aec_out_linear", aec->instance_index, - aec->debug_dump_count, process_rate, - &aec->outLinearFile); - } - - RTC_AEC_DEBUG_RAW_OPEN("aec_e_fft", aec->debug_dump_count, &aec->e_fft_file); - - ++aec->debug_dump_count; -#endif aec->system_delay = 0; if (WebRtc_InitDelayEstimatorFarend(aec->delay_estimator_farend) != 0) { diff --git a/webrtc/modules/audio_processing/aec/aec_core.h b/webrtc/modules/audio_processing/aec/aec_core.h index 46b748ba83..1155bc38b0 100644 --- a/webrtc/modules/audio_processing/aec/aec_core.h +++ b/webrtc/modules/audio_processing/aec/aec_core.h @@ -53,7 +53,7 @@ typedef struct Stats { typedef struct AecCore AecCore; -AecCore* WebRtcAec_CreateAec(); // Returns NULL on error. +AecCore* WebRtcAec_CreateAec(int instance_count); // Returns NULL on error. void WebRtcAec_FreeAec(AecCore* aec); int WebRtcAec_InitAec(AecCore* aec, int sampFreq); void WebRtcAec_InitAec_SSE2(void); @@ -97,9 +97,6 @@ void WebRtcAec_GetEchoStats(AecCore* self, Stats* erle, Stats* a_nlp, float* divergent_filter_fraction); -#ifdef WEBRTC_AEC_DEBUG_DUMP -void* WebRtcAec_far_time_buf(AecCore* self); -#endif // Sets local configuration modes. void WebRtcAec_SetConfigCore(AecCore* self, diff --git a/webrtc/modules/audio_processing/aec/aec_core_internal.h b/webrtc/modules/audio_processing/aec/aec_core_internal.h index c7f91d7da3..11e5bb0c40 100644 --- a/webrtc/modules/audio_processing/aec/aec_core_internal.h +++ b/webrtc/modules/audio_processing/aec/aec_core_internal.h @@ -11,6 +11,8 @@ #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_ #define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_CORE_INTERNAL_H_ +#include + extern "C" { #include "webrtc/common_audio/ring_buffer.h" } @@ -18,6 +20,7 @@ extern "C" { #include "webrtc/common_audio/wav_file.h" #include "webrtc/modules/audio_processing/aec/aec_common.h" #include "webrtc/modules/audio_processing/aec/aec_core.h" +#include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" #include "webrtc/modules/audio_processing/utility/block_mean_calculator.h" #include "webrtc/typedefs.h" @@ -70,7 +73,10 @@ class DivergentFilterFraction { }; struct AecCore { - AecCore(); + explicit AecCore(int instance_index); + ~AecCore(); + + std::unique_ptr data_dumper; int farBufWritePos, farBufReadPos; @@ -182,22 +188,6 @@ struct AecCore { // Flag that extreme filter divergence has been detected by the Echo // Suppressor. int extreme_filter_divergence; - -#ifdef WEBRTC_AEC_DEBUG_DUMP - // Sequence number of this AEC instance, so that different instances can - // choose different dump file names. - int instance_index; - - // Number of times we've restarted dumping; used to pick new dump file names - // each time. - int debug_dump_count; - - rtc_WavWriter* farFile; - rtc_WavWriter* nearFile; - rtc_WavWriter* outFile; - rtc_WavWriter* outLinearFile; - FILE* e_fft_file; -#endif }; typedef void (*WebRtcAecFilterFar)( diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation.cc b/webrtc/modules/audio_processing/aec/echo_cancellation.cc index f963a4e1d3..6b1758a15a 100644 --- a/webrtc/modules/audio_processing/aec/echo_cancellation.cc +++ b/webrtc/modules/audio_processing/aec/echo_cancellation.cc @@ -14,7 +14,7 @@ #include "webrtc/modules/audio_processing/aec/echo_cancellation.h" #include -#ifdef WEBRTC_AEC_DEBUG_DUMP +#if WEBRTC_AEC_DEBUG_DUMP == 1 #include #endif #include @@ -29,6 +29,12 @@ extern "C" { #include "webrtc/modules/audio_processing/aec/echo_cancellation_internal.h" #include "webrtc/typedefs.h" +// Check to verify that the define is properly set. +#if !defined(WEBRTC_AEC_DEBUG_DUMP) || \ + (WEBRTC_AEC_DEBUG_DUMP != 0 && WEBRTC_AEC_DEBUG_DUMP != 1) +#error "Set WEBRTC_AEC_DEBUG_DUMP to either 0 or 1" +#endif + namespace webrtc { // Measured delays [ms] @@ -99,9 +105,7 @@ static const int kMaxBufSizeStart = 62; // In partitions static const int sampMsNb = 8; // samples per ms in nb static const int initCheck = 42; -#ifdef WEBRTC_AEC_DEBUG_DUMP -int webrtc_aec_instance_count = 0; -#endif +int Aec::instance_count = 0; // Estimates delay to set the position of the far-end buffer read pointer // (controlled by knownDelay) @@ -129,7 +133,7 @@ void* WebRtcAec_Create() { return NULL; } - aecpc->aec = WebRtcAec_CreateAec(); + aecpc->aec = WebRtcAec_CreateAec(aecpc->instance_count); if (!aecpc->aec) { WebRtcAec_Free(aecpc); return NULL; @@ -151,21 +155,17 @@ void* WebRtcAec_Create() { aecpc->initFlag = 0; -#ifdef WEBRTC_AEC_DEBUG_DUMP - { - char filename[64]; - snprintf(filename, sizeof(filename), "aec_buf%d.dat", - webrtc_aec_instance_count); - aecpc->bufFile = fopen(filename, "wb"); - snprintf(filename, sizeof(filename), "aec_skew%d.dat", - webrtc_aec_instance_count); - aecpc->skewFile = fopen(filename, "wb"); - snprintf(filename, sizeof(filename), "aec_delay%d.dat", - webrtc_aec_instance_count); - aecpc->delayFile = fopen(filename, "wb"); - webrtc_aec_instance_count++; - } +#if WEBRTC_AEC_DEBUG_DUMP == 1 + char filename[64]; + snprintf(filename, sizeof(filename), "aec_buf%d.dat", aecpc->instance_count); + aecpc->bufFile = fopen(filename, "wb"); + snprintf(filename, sizeof(filename), "aec_skew%d.dat", aecpc->instance_count); + aecpc->skewFile = fopen(filename, "wb"); + snprintf(filename, sizeof(filename), "aec_delay%d.dat", + aecpc->instance_count); + aecpc->delayFile = fopen(filename, "wb"); #endif + aecpc->instance_count++; return aecpc; } @@ -179,7 +179,7 @@ void WebRtcAec_Free(void* aecInst) { WebRtc_FreeBuffer(aecpc->far_pre_buf); -#ifdef WEBRTC_AEC_DEBUG_DUMP +#if WEBRTC_AEC_DEBUG_DUMP == 1 fclose(aecpc->bufFile); fclose(aecpc->skewFile); fclose(aecpc->delayFile); @@ -376,7 +376,7 @@ int32_t WebRtcAec_Process(void* aecInst, msInSndCardBuf, skew); } -#ifdef WEBRTC_AEC_DEBUG_DUMP +#if WEBRTC_AEC_DEBUG_DUMP == 1 { int16_t far_buf_size_ms = (int16_t)(WebRtcAec_system_delay(aecpc->aec) / (sampMsNb * aecpc->rate_factor)); @@ -603,7 +603,7 @@ static int ProcessNormal(Aec* aecpc, aecpc->skew = maxSkewEst; } -#ifdef WEBRTC_AEC_DEBUG_DUMP +#if WEBRTC_AEC_DEBUG_DUMP == 1 (void)fwrite(&aecpc->skew, sizeof(aecpc->skew), 1, aecpc->skewFile); #endif } diff --git a/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h b/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h index b4a6fd8390..188fb576f0 100644 --- a/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h +++ b/webrtc/modules/audio_processing/aec/echo_cancellation_internal.h @@ -18,7 +18,7 @@ extern "C" { namespace webrtc { -typedef struct { +typedef struct Aec { int delayCtr; int sampFreq; int splitSampFreq; @@ -45,7 +45,7 @@ typedef struct { int checkBuffSize; short lastDelayDiff; -#ifdef WEBRTC_AEC_DEBUG_DUMP +#if WEBRTC_AEC_DEBUG_DUMP FILE* bufFile; FILE* delayFile; FILE* skewFile; @@ -63,6 +63,8 @@ typedef struct { int farend_started; + // Aec instance counter. + static int instance_count; AecCore* aec; } Aec; diff --git a/webrtc/modules/audio_processing/audio_processing.gypi b/webrtc/modules/audio_processing/audio_processing.gypi index fd41eea48c..4ee6c5c3c1 100644 --- a/webrtc/modules/audio_processing/audio_processing.gypi +++ b/webrtc/modules/audio_processing/audio_processing.gypi @@ -9,6 +9,8 @@ { 'variables': { 'shared_generated_dir': '<(SHARED_INTERMEDIATE_DIR)/audio_processing/asm_offsets', + # Outputs some low-level debug files. + 'aec_debug_dump%': 0, }, 'targets': [ { @@ -16,7 +18,6 @@ 'type': 'static_library', 'variables': { # Outputs some low-level debug files. - 'aec_debug_dump%': 0, 'agc_debug_dump%': 0, # Disables the usual mode where we trust the reported system delay @@ -91,9 +92,8 @@ 'intelligibility/intelligibility_utils.h', 'level_estimator_impl.cc', 'level_estimator_impl.h', - 'logging/aec_logging.h', - 'logging/aec_logging_file_handling.cc', - 'logging/aec_logging_file_handling.h', + 'logging/apm_data_dumper.cc', + 'logging/apm_data_dumper.h', 'noise_suppression_impl.cc', 'noise_suppression_impl.h', 'render_queue_item_verifier.h', @@ -150,7 +150,9 @@ ], 'conditions': [ ['aec_debug_dump==1', { - 'defines': ['WEBRTC_AEC_DEBUG_DUMP',], + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=1',], + }, { + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=0',], }], ['aec_untrusted_delay_for_testing==1', { 'defines': ['WEBRTC_UNTRUSTED_DELAY',], @@ -249,6 +251,11 @@ 'aec/aec_rdft_sse2.cc', ], 'conditions': [ + ['aec_debug_dump==1', { + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=1',], + }, { + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=0',], + }], ['os_posix==1', { 'cflags': [ '-msse2', ], 'xcode_settings': { @@ -273,6 +280,14 @@ 'aecm/aecm_core_neon.cc', 'ns/nsx_core_neon.c', ], + 'conditions': [ + ['aec_debug_dump==1', { + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=1',], + }], + ['aec_debug_dump==0', { + 'defines': ['WEBRTC_AEC_DEBUG_DUMP=0',], + }], + ], }], }], ], diff --git a/webrtc/modules/audio_processing/logging/aec_logging.h b/webrtc/modules/audio_processing/logging/aec_logging.h deleted file mode 100644 index b062913be2..0000000000 --- a/webrtc/modules/audio_processing/logging/aec_logging.h +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_ -#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_ - -#include - -#include "webrtc/modules/audio_processing/logging/aec_logging_file_handling.h" - -// To enable AEC logging, invoke GYP with -Daec_debug_dump=1. -#ifdef WEBRTC_AEC_DEBUG_DUMP -// Dumps a wav data to file. -#define RTC_AEC_DEBUG_WAV_WRITE(file, data, num_samples) \ - do { \ - rtc_WavWriteSamples(file, data, num_samples); \ - } while (0) - -// (Re)opens a wav file for writing using the specified sample rate. -#define RTC_AEC_DEBUG_WAV_REOPEN(name, instance_index, process_rate, \ - sample_rate, wav_file) \ - do { \ - WebRtcAec_ReopenWav(name, instance_index, process_rate, sample_rate, \ - wav_file); \ - } while (0) - -// Closes a wav file. -#define RTC_AEC_DEBUG_WAV_CLOSE(wav_file) \ - do { \ - rtc_WavClose(wav_file); \ - } while (0) - -// Dumps a raw data to file. -#define RTC_AEC_DEBUG_RAW_WRITE(file, data, data_size) \ - do { \ - (void) fwrite(data, data_size, 1, file); \ - } while (0) - -// Dumps a raw scalar int32 to file. -#define RTC_AEC_DEBUG_RAW_WRITE_SCALAR_INT32(file, data) \ - do { \ - int32_t value_to_store = data; \ - (void) fwrite(&value_to_store, sizeof(value_to_store), 1, file); \ - } while (0) - -// Dumps a raw scalar double to file. -#define RTC_AEC_DEBUG_RAW_WRITE_SCALAR_DOUBLE(file, data) \ - do { \ - double value_to_store = data; \ - (void) fwrite(&value_to_store, sizeof(value_to_store), 1, file); \ - } while (0) - -// Opens a raw data file for writing using the specified sample rate. -#define RTC_AEC_DEBUG_RAW_OPEN(name, instance_counter, file) \ - do { \ - WebRtcAec_RawFileOpen(name, instance_counter, file); \ - } while (0) - -// Closes a raw data file. -#define RTC_AEC_DEBUG_RAW_CLOSE(file) \ - do { \ - fclose(file); \ - } while (0) - -#else // RTC_AEC_DEBUG_DUMP -#define RTC_AEC_DEBUG_WAV_WRITE(file, data, num_samples) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_WAV_REOPEN(wav_file, name, instance_index, process_rate, \ - sample_rate) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_WAV_CLOSE(wav_file) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_RAW_WRITE(file, data, data_size) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_RAW_WRITE_SCALAR_INT32(file, data) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_RAW_WRITE_SCALAR_DOUBLE(file, data) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_RAW_OPEN(file, name, instance_counter) \ - do { \ - } while (0) - -#define RTC_AEC_DEBUG_RAW_CLOSE(file) \ - do { \ - } while (0) - -#endif // WEBRTC_AEC_DEBUG_DUMP - -#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_ diff --git a/webrtc/modules/audio_processing/logging/aec_logging_file_handling.cc b/webrtc/modules/audio_processing/logging/aec_logging_file_handling.cc deleted file mode 100644 index 3a434714e1..0000000000 --- a/webrtc/modules/audio_processing/logging/aec_logging_file_handling.cc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#include "webrtc/modules/audio_processing/logging/aec_logging_file_handling.h" - -#include -#include - -#include "webrtc/base/checks.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/common_audio/wav_file.h" -#include "webrtc/typedefs.h" - -#ifdef WEBRTC_AEC_DEBUG_DUMP -void WebRtcAec_ReopenWav(const char* name, - int instance_index, - int process_rate, - int sample_rate, - rtc_WavWriter** wav_file) { - if (*wav_file) { - if (rtc_WavSampleRate(*wav_file) == sample_rate) - return; - rtc_WavClose(*wav_file); - } - char filename[64]; - int written = rtc::sprintfn(filename, sizeof(filename), "%s%d-%d.wav", name, - instance_index, process_rate); - - // Ensure there was no buffer output error. - RTC_DCHECK_GE(written, 0); - // Ensure that the buffer size was sufficient. - RTC_DCHECK_LT(static_cast(written), sizeof(filename)); - - *wav_file = rtc_WavOpen(filename, sample_rate, 1); -} - -void WebRtcAec_RawFileOpen(const char* name, int instance_index, FILE** file) { - char filename[64]; - int written = rtc::sprintfn(filename, sizeof(filename), "%s_%d.dat", name, - instance_index); - - // Ensure there was no buffer output error. - RTC_DCHECK_GE(written, 0); - // Ensure that the buffer size was sufficient. - RTC_DCHECK_LT(static_cast(written), sizeof(filename)); - - *file = fopen(filename, "wb"); -} - -#endif // WEBRTC_AEC_DEBUG_DUMP diff --git a/webrtc/modules/audio_processing/logging/aec_logging_file_handling.h b/webrtc/modules/audio_processing/logging/aec_logging_file_handling.h deleted file mode 100644 index 5ec8394872..0000000000 --- a/webrtc/modules/audio_processing/logging/aec_logging_file_handling.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved. - * - * Use of this source code is governed by a BSD-style license - * that can be found in the LICENSE file in the root of the source - * tree. An additional intellectual property rights grant can be found - * in the file PATENTS. All contributing project authors may - * be found in the AUTHORS file in the root of the source tree. - */ - -#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_FILE_HANDLING_ -#define WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_FILE_HANDLING_ - -#include - -#include "webrtc/common_audio/wav_file.h" -#include "webrtc/typedefs.h" - -#ifdef __cplusplus -extern "C" { -#endif - -#ifdef WEBRTC_AEC_DEBUG_DUMP -// Opens a new Wav file for writing. If it was already open with a different -// sample frequency, it closes it first. -void WebRtcAec_ReopenWav(const char* name, - int instance_index, - int process_rate, - int sample_rate, - rtc_WavWriter** wav_file); - -// Opens dumpfile with instance-specific filename. -void WebRtcAec_RawFileOpen(const char* name, int instance_index, FILE** file); - -#endif // WEBRTC_AEC_DEBUG_DUMP - -#ifdef __cplusplus -} -#endif - -#endif // WEBRTC_MODULES_AUDIO_PROCESSING_AEC_AEC_LOGGING_FILE_HANDLING_ diff --git a/webrtc/modules/audio_processing/logging/apm_data_dumper.cc b/webrtc/modules/audio_processing/logging/apm_data_dumper.cc new file mode 100644 index 0000000000..491196e097 --- /dev/null +++ b/webrtc/modules/audio_processing/logging/apm_data_dumper.cc @@ -0,0 +1,65 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#include "webrtc/modules/audio_processing/logging/apm_data_dumper.h" + +#include + +#include "webrtc/base/stringutils.h" + +// Check to verify that the define is properly set. +#if !defined(WEBRTC_AEC_DEBUG_DUMP) || \ + (WEBRTC_AEC_DEBUG_DUMP != 0 && WEBRTC_AEC_DEBUG_DUMP != 1) +#error "Set WEBRTC_AEC_DEBUG_DUMP to either 0 or 1" +#endif + +namespace webrtc { + +namespace { + +#if WEBRTC_AEC_DEBUG_DUMP == 1 +std::string FormFileName(const char* name, + int instance_index, + int reinit_index, + const std::string& suffix) { + std::stringstream ss; + ss << name << "_" << instance_index << "-" << reinit_index << suffix; + return ss.str(); +} +#endif + +} // namespace + +#if WEBRTC_AEC_DEBUG_DUMP == 1 +FILE* ApmDataDumper::GetRawFile(const char* name) { + std::string filename = + FormFileName(name, instance_index_, recording_set_index_, ".dat"); + auto& f = raw_files_[filename]; + if (!f) { + f.reset(fopen(filename.c_str(), "wb")); + } + return f.get(); +} + +WavWriter* ApmDataDumper::GetWavFile(const char* name, + int sample_rate_hz, + int num_channels) { + std::string filename = + FormFileName(name, instance_index_, recording_set_index_, ".wav"); + auto& f = wav_files_[filename]; + if (!f) { + f.reset(new WavWriter(filename.c_str(), sample_rate_hz, num_channels)); + } + return f.get(); +} + +#endif + +} // namespace webrtc diff --git a/webrtc/modules/audio_processing/logging/apm_data_dumper.h b/webrtc/modules/audio_processing/logging/apm_data_dumper.h new file mode 100644 index 0000000000..18f9e5e181 --- /dev/null +++ b/webrtc/modules/audio_processing/logging/apm_data_dumper.h @@ -0,0 +1,103 @@ +/* + * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be found + * in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + +#ifndef WEBRTC_MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_ +#define WEBRTC_MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_ + +#include + +#include +#include +#include + +#include "webrtc/base/array_view.h" +#include "webrtc/base/constructormagic.h" +#include "webrtc/common_audio/wav_file.h" + +// Check to verify that the define is properly set. +#if !defined(WEBRTC_AEC_DEBUG_DUMP) || \ + (WEBRTC_AEC_DEBUG_DUMP != 0 && WEBRTC_AEC_DEBUG_DUMP != 1) +#error "Set WEBRTC_AEC_DEBUG_DUMP to either 0 or 1" +#endif + +namespace webrtc { + +#if WEBRTC_AEC_DEBUG_DUMP == 1 +// Functor used to use as a custom deleter in the map of file pointers to raw +// files. +struct RawFileCloseFunctor { + void operator()(FILE* f) const { fclose(f); } +}; +#endif + +// Class that handles dumping of variables into files. +class ApmDataDumper { + public: +// Constructor that takes an instance index that may +// be used to distinguish data dumped from different +// instances of the code. +#if WEBRTC_AEC_DEBUG_DUMP == 1 + explicit ApmDataDumper(int instance_index) + : instance_index_(instance_index) {} +#else + explicit ApmDataDumper(int instance_index) {} +#endif + + // Reinitializes the data dumping such that new versions + // of all files being dumped to are created. + void InitiateNewSetOfRecordings() { +#if WEBRTC_AEC_DEBUG_DUMP == 1 + ++recording_set_index_; +#endif + } + + // Methods for performing dumping of data of various types into + // various formats. + void DumpRaw(const char* name, int v_length, const float* v) { +#if WEBRTC_AEC_DEBUG_DUMP == 1 + FILE* file = GetRawFile(name); + fwrite(v, sizeof(v[0]), v_length, file); +#endif + } + + void DumpRaw(const char* name, rtc::ArrayView v) { +#if WEBRTC_AEC_DEBUG_DUMP == 1 + DumpRaw(name, v.size(), v.data()); +#endif + } + + void DumpWav(const char* name, + int v_length, + const float* v, + int sample_rate_hz, + int num_channels) { +#if WEBRTC_AEC_DEBUG_DUMP == 1 + WavWriter* file = GetWavFile(name, sample_rate_hz, num_channels); + file->WriteSamples(v, v_length); +#endif + } + + private: +#if WEBRTC_AEC_DEBUG_DUMP == 1 + const int instance_index_; + int recording_set_index_ = 0; + std::unordered_map> + raw_files_; + std::unordered_map> wav_files_; + + FILE* GetRawFile(const char* name); + WavWriter* GetWavFile(const char* name, int sample_rate_hz, int num_channels); +#endif + RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(ApmDataDumper); +}; + +} // namespace webrtc + +#endif // WEBRTC_MODULES_AUDIO_PROCESSING_LOGGING_APM_DATA_DUMPER_H_