This CL introduces a new data logging functionality
to use for the APM. It allows simple and rapid
additions of exploratory data logpoints to use
during bug investigations and module performance
analysis.
The new data logging functionality is also in this CL
used to replace the existing data logging functionality
present in the AEC.
Additional information:
As there was an issue with that the build flag for
activating this feature was not present in all
compilation units that included the feature additional
changes were needed. A summary of the changes are
-The build files were modified to ensure that the
logging build flag always is set to either 0 or 1
for compilation units that include the feature.
-Build-time checks in the appropriate places were added
to ensure that the above is fulfilled.
-The build object was added dynamically to the AEC state
as a pointer to ensure that the size of that state is not
dependent on whether the logging build flag is set or not.
-The constructor of the AEC class needed to be modified in
order to construct the logging object. For this a destructor
was also needed.
-An unused method without any declaration was removed in
order to avoid any issues with the logging flag being set to
0 or 1.
This CL will be immediately followed with an upcoming CL
that replaces the logging in echo_cancellation.cc with the
new functionality which will ensure that the logging flag
is only used in one place within WebRTC, which in turn will
fully ensure that all compilation units that uses the feature
also have the flag properly set.
BUG=webrtc:5201, webrtc:5298
Review-Url: https://codereview.webrtc.org/1877713002
Cr-Commit-Position: refs/heads/master@{#12607}
diff --git a/webrtc/modules/audio_processing/BUILD.gn b/webrtc/modules/audio_processing/BUILD.gn
index a343483..c18c1d8 100644
--- a/webrtc/modules/audio_processing/BUILD.gn
+++ b/webrtc/modules/audio_processing/BUILD.gn
@@ -81,9 +81,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",
@@ -149,7 +148,9 @@
]
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 @@
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 @@
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 aa6cfa8..2a6adde 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 <stdio.h>
-#endif
-
#include <algorithm>
#include <assert.h>
#include <math.h>
@@ -34,7 +30,6 @@
#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 @@
// 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 @@
}
// 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 @@
WebRtc_ReadBuffer(aec->far_time_buf, reinterpret_cast<void**>(&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 @@
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 @@
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 @@
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 @@
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 @@
int WebRtcAec_InitAec(AecCore* aec, int sampFreq) {
int i;
+ aec->data_dumper->InitiateNewSetOfRecordings();
aec->sampFreq = sampFreq;
@@ -1603,27 +1584,6 @@
// 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 46b748b..1155bc3 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 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 @@
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 c7f91d7..11e5bb0 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 <memory>
+
extern "C" {
#include "webrtc/common_audio/ring_buffer.h"
}
@@ -18,6 +20,7 @@
#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 @@
};
struct AecCore {
- AecCore();
+ explicit AecCore(int instance_index);
+ ~AecCore();
+
+ std::unique_ptr<ApmDataDumper> data_dumper;
int farBufWritePos, farBufReadPos;
@@ -182,22 +188,6 @@
// 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 f963a4e..6b1758a1 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 <math.h>
-#ifdef WEBRTC_AEC_DEBUG_DUMP
+#if WEBRTC_AEC_DEBUG_DUMP == 1
#include <stdio.h>
#endif
#include <stdlib.h>
@@ -29,6 +29,12 @@
#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 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 @@
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 @@
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 @@
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 @@
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 @@
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 b4a6fd8..188fb57 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 @@
namespace webrtc {
-typedef struct {
+typedef struct Aec {
int delayCtr;
int sampFreq;
int splitSampFreq;
@@ -45,7 +45,7 @@
int checkBuffSize;
short lastDelayDiff;
-#ifdef WEBRTC_AEC_DEBUG_DUMP
+#if WEBRTC_AEC_DEBUG_DUMP
FILE* bufFile;
FILE* delayFile;
FILE* skewFile;
@@ -63,6 +63,8 @@
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 fd41eea..4ee6c5c 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 b062913..0000000
--- 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 <stdio.h>
-
-#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 3a43471..0000000
--- 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 <stdint.h>
-#include <stdio.h>
-
-#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<size_t>(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<size_t>(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 5ec8394..0000000
--- 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 <stdio.h>
-
-#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 0000000..491196e
--- /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 <sstream>
+
+#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 0000000..18f9e5e
--- /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 <stdio.h>
+
+#include <memory>
+#include <string>
+#include <unordered_map>
+
+#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<const float> 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<std::string, std::unique_ptr<FILE, RawFileCloseFunctor>>
+ raw_files_;
+ std::unordered_map<std::string, std::unique_ptr<WavWriter>> 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_