├── .gitmodules ├── CMakeLists.txt ├── README.md ├── run-wav-aec.sh ├── run-wav-ns.sh └── webrtc-audioproc.cpp /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "webrtc"] 2 | path = webrtc 3 | url = https://chromium.googlesource.com/external/webrtc 4 | [submodule "gflags"] 5 | path = gflags 6 | url = https://github.com/gflags/gflags.git 7 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(wav-aec) 4 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11") 5 | set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) 6 | 7 | add_subdirectory(gflags) 8 | 9 | add_definitions("-DWEBRTC_LINUX -DWEBRTC_POSIX -DWEBRTC_NS_FLOAT") 10 | #-DWEBRTC_UNTRUSTED_DELAY 11 | 12 | include_directories( 13 | webrtc 14 | webrtc/webrtc/common_audio/signal_processing/include 15 | webrtc/webrtc/modules/audio_coding/codecs/isac/main/include 16 | ) 17 | 18 | set(WEBRTC_SRC_ 19 | base/buffer.cc 20 | base/checks.cc 21 | base/criticalsection.cc 22 | base/event.cc 23 | base/event_tracer.cc 24 | base/logging.cc 25 | base/platform_file.cc 26 | base/platform_thread.cc 27 | base/stringencode.cc 28 | base/thread_checker_impl.cc 29 | base/timeutils.cc 30 | common_audio/audio_converter.cc 31 | common_audio/audio_ring_buffer.cc 32 | common_audio/audio_util.cc 33 | common_audio/blocker.cc 34 | common_audio/channel_buffer.cc 35 | common_audio/fft4g.c 36 | common_audio/fir_filter.cc 37 | common_audio/fir_filter_sse.cc 38 | common_audio/lapped_transform.cc 39 | common_audio/real_fourier.cc 40 | common_audio/real_fourier_ooura.cc 41 | common_audio/resampler/push_resampler.cc 42 | common_audio/resampler/push_sinc_resampler.cc 43 | common_audio/resampler/resampler.cc 44 | common_audio/resampler/sinc_resampler.cc 45 | common_audio/resampler/sinc_resampler_sse.cc 46 | common_audio/resampler/sinusoidal_linear_chirp_source.cc 47 | common_audio/ring_buffer.c 48 | common_audio/signal_processing/auto_correlation.c 49 | common_audio/signal_processing/auto_corr_to_refl_coef.c 50 | common_audio/signal_processing/complex_bit_reverse.c 51 | common_audio/signal_processing/complex_fft.c 52 | common_audio/signal_processing/copy_set_operations.c 53 | common_audio/signal_processing/cross_correlation.c 54 | common_audio/signal_processing/division_operations.c 55 | common_audio/signal_processing/dot_product_with_scale.c 56 | common_audio/signal_processing/downsample_fast.c 57 | common_audio/signal_processing/energy.c 58 | common_audio/signal_processing/filter_ar.c 59 | common_audio/signal_processing/filter_ar_fast_q12.c 60 | common_audio/signal_processing/filter_ma_fast_q12.c 61 | common_audio/signal_processing/get_hanning_window.c 62 | common_audio/signal_processing/get_scaling_square.c 63 | common_audio/signal_processing/ilbc_specific_functions.c 64 | common_audio/signal_processing/levinson_durbin.c 65 | common_audio/signal_processing/lpc_to_refl_coef.c 66 | common_audio/signal_processing/min_max_operations.c 67 | common_audio/signal_processing/randomization_functions.c 68 | common_audio/signal_processing/real_fft.c 69 | common_audio/signal_processing/refl_coef_to_lpc.c 70 | common_audio/signal_processing/resample_48khz.c 71 | common_audio/signal_processing/resample_by_2.c 72 | common_audio/signal_processing/resample_by_2_internal.c 73 | common_audio/signal_processing/resample.c 74 | common_audio/signal_processing/resample_fractional.c 75 | common_audio/signal_processing/spl_init.c 76 | common_audio/signal_processing/splitting_filter.c 77 | common_audio/signal_processing/spl_sqrt.c 78 | common_audio/signal_processing/spl_sqrt_floor.c 79 | common_audio/signal_processing/sqrt_of_one_minus_x_squared.c 80 | common_audio/signal_processing/vector_scaling_operations.c 81 | common_audio/sparse_fir_filter.cc 82 | common_audio/vad/vad_core.c 83 | common_audio/vad/vad_filterbank.c 84 | common_audio/vad/vad_gmm.c 85 | common_audio/vad/vad_sp.c 86 | common_audio/vad/webrtc_vad.c 87 | common_audio/wav_file.cc 88 | common_audio/wav_header.cc 89 | common_audio/window_generator.cc 90 | common_types.cc 91 | modules/audio_coding/codecs/audio_decoder.cc 92 | modules/audio_coding/codecs/audio_encoder.cc 93 | modules/audio_coding/codecs/isac/locked_bandwidth_info.cc 94 | modules/audio_coding/codecs/isac/main/source/arith_routines.c 95 | modules/audio_coding/codecs/isac/main/source/arith_routines_hist.c 96 | modules/audio_coding/codecs/isac/main/source/arith_routines_logist.c 97 | modules/audio_coding/codecs/isac/main/source/audio_decoder_isac.cc 98 | modules/audio_coding/codecs/isac/main/source/audio_encoder_isac.cc 99 | modules/audio_coding/codecs/isac/main/source/bandwidth_estimator.c 100 | modules/audio_coding/codecs/isac/main/source/crc.c 101 | modules/audio_coding/codecs/isac/main/source/decode_bwe.c 102 | modules/audio_coding/codecs/isac/main/source/decode.c 103 | modules/audio_coding/codecs/isac/main/source/encode.c 104 | modules/audio_coding/codecs/isac/main/source/encode_lpc_swb.c 105 | modules/audio_coding/codecs/isac/main/source/entropy_coding.c 106 | modules/audio_coding/codecs/isac/main/source/fft.c 107 | modules/audio_coding/codecs/isac/main/source/filterbanks.c 108 | modules/audio_coding/codecs/isac/main/source/filterbank_tables.c 109 | modules/audio_coding/codecs/isac/main/source/filter_functions.c 110 | modules/audio_coding/codecs/isac/main/source/intialize.c 111 | modules/audio_coding/codecs/isac/main/source/isac.c 112 | modules/audio_coding/codecs/isac/main/source/lattice.c 113 | modules/audio_coding/codecs/isac/main/source/lpc_analysis.c 114 | modules/audio_coding/codecs/isac/main/source/lpc_gain_swb_tables.c 115 | modules/audio_coding/codecs/isac/main/source/lpc_shape_swb12_tables.c 116 | modules/audio_coding/codecs/isac/main/source/lpc_shape_swb16_tables.c 117 | modules/audio_coding/codecs/isac/main/source/lpc_tables.c 118 | modules/audio_coding/codecs/isac/main/source/pitch_estimator.c 119 | modules/audio_coding/codecs/isac/main/source/pitch_filter.c 120 | modules/audio_coding/codecs/isac/main/source/pitch_gain_tables.c 121 | modules/audio_coding/codecs/isac/main/source/pitch_lag_tables.c 122 | modules/audio_coding/codecs/isac/main/source/spectrum_ar_model_tables.c 123 | modules/audio_coding/codecs/isac/main/source/transform.c 124 | modules/audio_processing/aec/aec_core.cc 125 | modules/audio_processing/aec/aec_core_sse2.cc 126 | modules/audio_processing/aec/aec_rdft.cc 127 | modules/audio_processing/aec/aec_rdft_sse2.cc 128 | modules/audio_processing/aec/aec_resampler.cc 129 | modules/audio_processing/aec/echo_cancellation.cc 130 | modules/audio_processing/aecm/aecm_core.cc 131 | modules/audio_processing/aecm/aecm_core_c.cc 132 | modules/audio_processing/aecm/echo_control_mobile.cc 133 | modules/audio_processing/agc/agc.cc 134 | modules/audio_processing/agc/agc_manager_direct.cc 135 | modules/audio_processing/agc/histogram.cc 136 | modules/audio_processing/agc/legacy/analog_agc.c 137 | modules/audio_processing/agc/legacy/digital_agc.c 138 | modules/audio_processing/agc/utility.cc 139 | modules/audio_processing/audio_buffer.cc 140 | modules/audio_processing/audio_processing_impl.cc 141 | modules/audio_processing/beamformer/array_util.cc 142 | modules/audio_processing/beamformer/covariance_matrix_generator.cc 143 | modules/audio_processing/beamformer/nonlinear_beamformer.cc 144 | modules/audio_processing/echo_cancellation_impl.cc 145 | modules/audio_processing/echo_control_mobile_impl.cc 146 | modules/audio_processing/gain_control_for_experimental_agc.cc 147 | modules/audio_processing/gain_control_impl.cc 148 | modules/audio_processing/high_pass_filter_impl.cc 149 | modules/audio_processing/intelligibility/intelligibility_enhancer.cc 150 | modules/audio_processing/intelligibility/intelligibility_utils.cc 151 | modules/audio_processing/level_estimator_impl.cc 152 | modules/audio_processing/logging/aec_logging_file_handling.cc 153 | modules/audio_processing/noise_suppression_impl.cc 154 | modules/audio_processing/ns/noise_suppression.c 155 | modules/audio_processing/ns/ns_core.c 156 | modules/audio_processing/rms_level.cc 157 | modules/audio_processing/splitting_filter.cc 158 | modules/audio_processing/three_band_filter_bank.cc 159 | modules/audio_processing/transient/file_utils.cc 160 | modules/audio_processing/transient/moving_moments.cc 161 | modules/audio_processing/transient/transient_detector.cc 162 | modules/audio_processing/transient/transient_suppressor.cc 163 | modules/audio_processing/transient/wpd_node.cc 164 | modules/audio_processing/transient/wpd_tree.cc 165 | modules/audio_processing/typing_detection.cc 166 | modules/audio_processing/utility/block_mean_calculator.cc 167 | modules/audio_processing/utility/delay_estimator.cc 168 | modules/audio_processing/utility/delay_estimator_wrapper.cc 169 | modules/audio_processing/vad/gmm.cc 170 | modules/audio_processing/vad/pitch_based_vad.cc 171 | modules/audio_processing/vad/pitch_internal.cc 172 | modules/audio_processing/vad/pole_zero_filter.cc 173 | modules/audio_processing/vad/standalone_vad.cc 174 | modules/audio_processing/vad/vad_audio_proc.cc 175 | modules/audio_processing/vad/vad_circular_buffer.cc 176 | modules/audio_processing/vad/voice_activity_detector.cc 177 | modules/audio_processing/voice_detection_impl.cc 178 | system_wrappers/source/aligned_malloc.cc 179 | system_wrappers/source/cpu_features.cc 180 | system_wrappers/source/file_impl.cc 181 | system_wrappers/source/logging.cc 182 | system_wrappers/source/metrics_default.cc 183 | system_wrappers/source/rw_lock.cc 184 | system_wrappers/source/rw_lock_posix.cc 185 | system_wrappers/source/trace_impl.cc 186 | system_wrappers/source/trace_posix.cc 187 | ) 188 | 189 | function(prepend_path var prefix) 190 | set(listVar "") 191 | foreach(f ${ARGN}) 192 | list(APPEND listVar "${prefix}/${f}") 193 | endforeach(f) 194 | set(${var} "${listVar}" PARENT_SCOPE) 195 | endfunction(prepend_path) 196 | 197 | prepend_path(WEBRTC_SRC webrtc/webrtc ${WEBRTC_SRC_}) 198 | 199 | add_executable(webrtc-audioproc webrtc-audioproc.cpp ${WEBRTC_SRC}) 200 | target_link_libraries(webrtc-audioproc gflags pthread) 201 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # wav-aec 2 | 3 | * This tool applies [webrtc's](https://webrtc.org/) acoustic echo cancellation (AEC) functionality to audio files. 4 | * sox is used for wav, etc. -> raw conversion 5 | * Building a full webrtc release is avoided. Only the signal processing functions are needed. 6 | 7 | Cloning including the webrtc code: 8 | ```bash 9 | git clone --recursive https://github.com/lschilli/wav-aec.git 10 | ``` 11 | 12 | After cloning: 13 | ```bash 14 | git submodule update --init --recursive 15 | ``` 16 | -------------------------------------------------------------------------------- /run-wav-aec.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -ne 7 ]; then 4 | echo "Usage $(basename "$0") " 5 | exit 1 6 | fi 7 | 8 | in_sr="$6" 9 | out_sr="$7" 10 | builddir="${BASH_SOURCE[0]%/*}/build" 11 | 12 | "$builddir/webrtc-audioproc" -filter_aec -print_stats -aec_level=2 -filter_ns -ns_level=1 -in_sr "$in_sr" -out_sr "$out_sr" -near_in <(exec sox -DR "$1" -r $in_sr -t raw -e signed-integer -b 16 - remix "$2") -far_in <(exec sox -DR "$3" -r $in_sr -t raw -e signed-integer -b 16 - remix "$4") -near_out >(exec sox -DR -r $out_sr -t raw -e signed-integer -b 16 - "$5") 13 | -------------------------------------------------------------------------------- /run-wav-ns.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ "$#" -ne 5 ]; then 4 | echo "Usage $(basename "$0") " 5 | exit 1 6 | fi 7 | 8 | in_sr="$4" 9 | out_sr="$5" 10 | builddir="${BASH_SOURCE[0]%/*}/build" 11 | 12 | "$builddir/webrtc-audioproc" -filter_ns -ns_level 3 -in_sr "$in_sr" -out_sr "$out_sr" -near_in <(exec sox -DR "$1" -r $in_sr -t raw -e signed-integer -b 16 - remix "$2") -near_out >(exec sox -DR -r $out_sr -t raw -e signed-integer -b 16 - "$3") 13 | -------------------------------------------------------------------------------- /webrtc-audioproc.cpp: -------------------------------------------------------------------------------- 1 | #include "webrtc/modules/audio_processing/include/audio_processing.h" 2 | #include "webrtc/modules/audio_processing/audio_buffer.h" 3 | #include "webrtc/modules/audio_processing/echo_cancellation_impl.h" 4 | #include "webrtc/modules/audio_processing/aec/aec_core_internal.h" 5 | 6 | #include "gflags/gflags.h" 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | 14 | using namespace std; 15 | using namespace webrtc; 16 | 17 | DEFINE_string(near_in, "", "potentially distorted signal - REQUIRED"); 18 | DEFINE_int32(in_sr, 16000, "in sample rate"); 19 | DEFINE_string(far_in, "", "reverse signal / aec reference signal"); 20 | DEFINE_string(near_out, "", "cleaned near signal - REQUIRED"); 21 | DEFINE_int32(out_sr, 16000, "out sample rate"); 22 | DEFINE_string(far_out, "", "processed aec reference signal"); 23 | 24 | DEFINE_int32(sys_delay, 8, "delay between near and far end in ms"); 25 | DEFINE_int32(ns_level, -1, "noise supression level 0-3"); 26 | DEFINE_int32(aec_level, -1, "aec level 0-2"); 27 | 28 | //from audioproc_float.cc 29 | DEFINE_bool(filter_aec, false, "Enable echo cancellation."); 30 | DEFINE_bool(filter_agc, false, "Enable automatic gain control."); 31 | DEFINE_bool(filter_hp, false, "Enable high-pass filtering."); 32 | DEFINE_bool(filter_ns, false, "Enable noise suppression."); 33 | DEFINE_bool(filter_ts, false, "Enable transient suppression."); 34 | DEFINE_bool(filter_ie, false, "Enable intelligibility enhancer."); 35 | DEFINE_bool(filter_bf, false, "Enable beamforming."); 36 | 37 | DEFINE_bool(aec_delay_agnostic, true, "aec is delay agnostic."); 38 | DEFINE_bool(aec_extended_filter, true, "enable aec extended filter."); 39 | 40 | DEFINE_bool(print_stats, false, "print vad/echo/stats."); 41 | 42 | template 43 | void check_stream_error(const T& stream, const string& filename) { 44 | if (stream.fail()) { 45 | cerr << filename << ": " << strerror(errno) << endl; 46 | exit(1); 47 | } 48 | 49 | } 50 | 51 | std::shared_ptr configure_processing() { 52 | Config config; 53 | config.Set(new ExperimentalNs(FLAGS_filter_ts)); 54 | config.Set(new Intelligibility(FLAGS_filter_ie)); 55 | if (FLAGS_filter_bf) { 56 | std::vector array_geometry; 57 | array_geometry.push_back(webrtc::Point(-0.1, 0, 0)); 58 | array_geometry.push_back(webrtc::Point(0.1, 0, 0)); 59 | config.Set( 60 | new Beamforming(true, 61 | array_geometry, 62 | SphericalPointf(DegreesToRadians(90), 0.f, 1.f))); 63 | } 64 | std::shared_ptr ap(AudioProcessing::Create(config)); 65 | 66 | Config extraconfig; 67 | extraconfig.Set(new webrtc::DelayAgnostic(FLAGS_aec_delay_agnostic)); 68 | extraconfig.Set(new webrtc::ExtendedFilter(FLAGS_aec_extended_filter)); 69 | extraconfig.Set(new webrtc::EchoCanceller3(true)); 70 | //extraconfig.Set(new RefinedAdaptiveFilter(true)); 71 | ap->SetExtraOptions(extraconfig); 72 | 73 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->echo_cancellation()->Enable(FLAGS_filter_aec)); 74 | ap->echo_cancellation()->set_suppression_level(EchoCancellation::kHighSuppression); 75 | if (FLAGS_aec_level != -1) { 76 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->echo_cancellation()->set_suppression_level( 77 | static_cast(FLAGS_aec_level))); 78 | } 79 | ap->echo_cancellation()->enable_metrics(true); 80 | ap->echo_cancellation()->enable_delay_logging(true); 81 | 82 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->noise_suppression()->Enable(FLAGS_filter_ns)); 83 | if (FLAGS_ns_level != -1) { 84 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->noise_suppression()->set_level( 85 | static_cast(FLAGS_ns_level))); 86 | } 87 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->high_pass_filter()->Enable(FLAGS_filter_hp)); 88 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->gain_control()->Enable(FLAGS_filter_agc)); 89 | RTC_CHECK_EQ(AudioProcessing::kNoError, ap->gain_control()->set_mode(GainControl::kAdaptiveDigital)); 90 | 91 | ap->voice_detection()->Enable(true); 92 | ap->voice_detection()->set_likelihood(VoiceDetection::kVeryLowLikelihood); 93 | ap->voice_detection()->set_frame_size_ms(10); 94 | return ap; 95 | } 96 | 97 | void print_configuration(std::shared_ptr ap) { 98 | cerr << "aec enabled " << ap->echo_cancellation()->is_enabled() << "\n"; 99 | if (ap->echo_cancellation()->is_enabled()) { 100 | cerr << "aec 3 enabled " << ap->echo_cancellation()->aec_core()->aec3_enabled << "\n" 101 | << "aec extended filter " << ap->echo_cancellation()->aec_core()->extended_filter_enabled << "\n" 102 | << "aec delay agnostic " << ap->echo_cancellation()->aec_core()->delay_agnostic_enabled << "\n" 103 | << "aec level " << ap->echo_cancellation()->suppression_level() << "\n"; 104 | } 105 | cerr << "gain control enabled " << ap->gain_control()->is_enabled() << "\n" 106 | << "high pass filter_enabled " << ap->high_pass_filter()->is_enabled() << "\n" 107 | << "noise suppression enabled " << ap->noise_suppression()->is_enabled() << "\n" 108 | << "noise suppression level " << ap->noise_suppression()->level() << "\n" 109 | << "voice detection " << ap->voice_detection()->is_enabled() << endl; 110 | } 111 | 112 | int main(int argc, char** argv) { 113 | google::SetUsageMessage("runs webrtc's audio processing on raw audio files."); 114 | google::ParseCommandLineFlags(&argc, &argv, true); 115 | 116 | if (FLAGS_near_in.empty() || FLAGS_near_out.empty()) { 117 | cerr << google::ProgramInvocationShortName() << ": arguments near_in and near_out are required" << endl; 118 | exit(1); 119 | } 120 | if (argc > 1) { 121 | cerr << google::ProgramInvocationShortName() << ": excess arguments: " << argv[1] << endl; 122 | exit(1); 123 | } 124 | 125 | //todo: show aec delays, metrics, speech probability 126 | const size_t num_chunk_samples_in = FLAGS_in_sr / 100; 127 | const size_t num_chunk_samples_out = FLAGS_out_sr / 100; 128 | const int num_channels = 1; 129 | 130 | //near end is mixed signal 131 | std::ifstream near_in; 132 | near_in.open(FLAGS_near_in); 133 | check_stream_error(near_in, FLAGS_near_in); 134 | //far end is reference signal 135 | std::ifstream far_in; 136 | if (!FLAGS_far_in.empty()) { 137 | far_in.open(FLAGS_far_in); 138 | check_stream_error(far_in, FLAGS_far_in); 139 | } 140 | //filtered signal 141 | std::ofstream near_out; 142 | near_out.open(FLAGS_near_out, std::ofstream::out); 143 | check_stream_error(near_out, FLAGS_near_out); 144 | 145 | //filtered signal 146 | std::ofstream far_out; 147 | if (!FLAGS_far_out.empty()) { 148 | far_out.open(FLAGS_far_out, std::ofstream::out); 149 | check_stream_error(far_out, FLAGS_far_out); 150 | } 151 | 152 | std::shared_ptr ap = configure_processing(); 153 | print_configuration(ap); 154 | 155 | std::vector far_raw_data(num_chunk_samples_in * num_channels); 156 | std::vector near_raw_data(num_chunk_samples_in * num_channels); 157 | std::vector out_raw_data(num_chunk_samples_out * num_channels); 158 | std::vector far_out_raw_data(num_chunk_samples_out * num_channels); 159 | std::vector far_float_data(num_chunk_samples_in * num_channels); 160 | std::vector near_float_data(num_chunk_samples_in * num_channels); 161 | std::vector out_float_data(num_chunk_samples_out * num_channels); 162 | std::vector far_out_float_data(num_chunk_samples_out * num_channels); 163 | webrtc::ChannelBuffer far_chan_buf(num_chunk_samples_in, num_channels); 164 | webrtc::ChannelBuffer near_chan_buf(num_chunk_samples_in, num_channels); 165 | webrtc::ChannelBuffer out_chan_buf(num_chunk_samples_out, num_channels); 166 | webrtc::ChannelBuffer far_out_chan_buf(num_chunk_samples_out, num_channels); 167 | 168 | webrtc::StreamConfig stream_config_in(FLAGS_in_sr, num_channels); 169 | webrtc::StreamConfig stream_config_out(FLAGS_out_sr, num_channels); 170 | int buf_cnt = 0; 171 | while (true) { 172 | if (!FLAGS_far_in.empty()) { 173 | far_in.read((char*)far_raw_data.data(), far_raw_data.size()*sizeof(int16_t)); 174 | if (!far_in) break; 175 | webrtc::S16ToFloat(far_raw_data.data(), far_raw_data.size(), far_float_data.data()); 176 | webrtc::Deinterleave(far_float_data.data(), num_chunk_samples_in, num_channels, far_chan_buf.channels()); 177 | } 178 | near_in.read((char*)near_raw_data.data(), near_raw_data.size()*sizeof(int16_t)); 179 | if (!near_in) break; 180 | webrtc::S16ToFloat(near_raw_data.data(), near_raw_data.size(), near_float_data.data()); 181 | webrtc::Deinterleave(near_float_data.data(), num_chunk_samples_in, num_channels, near_chan_buf.channels()); 182 | if (!FLAGS_far_in.empty()) { 183 | RTC_CHECK_EQ(AudioProcessing::kNoError, 184 | ap->set_stream_delay_ms(FLAGS_sys_delay)); 185 | RTC_CHECK_EQ(AudioProcessing::kNoError, 186 | ap->ProcessReverseStream(far_chan_buf.channels(), stream_config_in, 187 | stream_config_out, far_out_chan_buf.channels())); 188 | } 189 | 190 | RTC_CHECK_EQ(AudioProcessing::kNoError, 191 | ap->ProcessStream(near_chan_buf.channels(), stream_config_in, 192 | stream_config_out, out_chan_buf.channels())); 193 | 194 | webrtc::Interleave(out_chan_buf.channels(), out_chan_buf.num_frames(), 195 | out_chan_buf.num_channels(), out_float_data.data()); 196 | 197 | webrtc::FloatToS16(out_float_data.data(), out_raw_data.size(), out_raw_data.data()); 198 | near_out.write((char*)out_raw_data.data(), out_raw_data.size()*sizeof(int16_t)); 199 | 200 | if (!FLAGS_far_out.empty()) { 201 | webrtc::Interleave(far_out_chan_buf.channels(), far_out_chan_buf.num_frames(), 202 | far_out_chan_buf.num_channels(), far_out_float_data.data()); 203 | webrtc::FloatToS16(far_out_float_data.data(), far_out_raw_data.size(), far_out_raw_data.data()); 204 | far_out.write((char*)far_out_raw_data.data(), far_out_raw_data.size()*sizeof(int16_t)); 205 | } 206 | buf_cnt++; 207 | 208 | if (FLAGS_print_stats) { 209 | int delay_std, delay_med; 210 | float delay_poor; 211 | ap->echo_cancellation()->GetDelayMetrics(&delay_med, &delay_std, &delay_poor); 212 | AecCore* aec = ap->echo_cancellation()->aec_core(); 213 | float nlpout = sqrt(aec->nlpoutlevel.framelevel.GetLatestMean() - aec->nlpoutlevel.minlevel); 214 | //float nlpout = static_cast(10 * log10(aec->nlpoutlevel.framelevel.GetLatestMean() - aec->nlpoutlevel.minlevel + 1e-10f)); 215 | 216 | cout << "t: " << showpoint << (buf_cnt*0.01) 217 | << " voice: " << ap->voice_detection()->stream_has_voice() 218 | << " echo: " << ap->echo_cancellation()->stream_has_echo() 219 | << " voiceprob: " << showpoint<< ap->noise_suppression()->speech_probability() 220 | << " nlplevel: " << showpoint<< nlpout 221 | << " delaymed: " << delay_med 222 | << " delaystd: " << delay_std 223 | << " delaypoor: " << delay_poor 224 | << endl; 225 | } 226 | 227 | } 228 | 229 | near_in.close(); 230 | far_in.close(); 231 | near_out.close(); 232 | 233 | } 234 | 235 | 236 | 237 | --------------------------------------------------------------------------------