Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1289)

Side by Side Diff: webrtc/modules/audio_processing/test/audio_processing_simulator.cc

Issue 2486763002: Add support to audioproc_f for running the residual echo detector and producing an echo likelihood … (Closed)
Patch Set: Added missing include. Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2016 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2016 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 #include "webrtc/modules/audio_processing/test/audio_processing_simulator.h" 11 #include "webrtc/modules/audio_processing/test/audio_processing_simulator.h"
12 12
13 #include <algorithm> 13 #include <algorithm>
14 #include <iostream> 14 #include <iostream>
15 #include <sstream> 15 #include <sstream>
16 #include <string> 16 #include <string>
17 #include <vector> 17 #include <vector>
18 18
19 #include "webrtc/base/checks.h"
19 #include "webrtc/base/stringutils.h" 20 #include "webrtc/base/stringutils.h"
20 #include "webrtc/common_audio/include/audio_util.h" 21 #include "webrtc/common_audio/include/audio_util.h"
21 #include "webrtc/modules/audio_processing/include/audio_processing.h" 22 #include "webrtc/modules/audio_processing/include/audio_processing.h"
22 23
23 namespace webrtc { 24 namespace webrtc {
24 namespace test { 25 namespace test {
25 namespace { 26 namespace {
26 27
27 void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) { 28 void CopyFromAudioFrame(const AudioFrame& src, ChannelBuffer<float>* dest) {
28 RTC_CHECK_EQ(src.num_channels_, dest->num_channels()); 29 RTC_CHECK_EQ(src.num_channels_, dest->num_channels());
29 RTC_CHECK_EQ(src.samples_per_channel_, dest->num_frames()); 30 RTC_CHECK_EQ(src.samples_per_channel_, dest->num_frames());
30 // Copy the data from the input buffer. 31 // Copy the data from the input buffer.
31 std::vector<float> tmp(src.samples_per_channel_ * src.num_channels_); 32 std::vector<float> tmp(src.samples_per_channel_ * src.num_channels_);
32 S16ToFloat(src.data_, tmp.size(), tmp.data()); 33 S16ToFloat(src.data_, tmp.size(), tmp.data());
33 Deinterleave(tmp.data(), src.samples_per_channel_, src.num_channels_, 34 Deinterleave(tmp.data(), src.samples_per_channel_, src.num_channels_,
34 dest->channels()); 35 dest->channels());
35 } 36 }
36 37
37 std::string GetIndexedOutputWavFilename(const std::string& wav_name, 38 std::string GetIndexedOutputWavFilename(const std::string& wav_name,
38 int counter) { 39 int counter) {
39 std::stringstream ss; 40 std::stringstream ss;
40 ss << wav_name.substr(0, wav_name.size() - 4) << "_" << counter 41 ss << wav_name.substr(0, wav_name.size() - 4) << "_" << counter
41 << wav_name.substr(wav_name.size() - 4); 42 << wav_name.substr(wav_name.size() - 4);
42 return ss.str(); 43 return ss.str();
43 } 44 }
44 45
46 void WriteEchoLikelihoodGraphFileHeader(std::ofstream* output_file) {
47 (*output_file) << "import numpy as np" << std::endl
48 << "import matplotlib.pyplot as plt" << std::endl
49 << "y = np.array([";
50 }
51
52 void WriteEchoLikelihoodGraphFileFooter(std::ofstream* output_file) {
53 (*output_file) << "])" << std::endl
54 << "x = np.arange(len(y))*.01" << std::endl
55 << "plt.plot(x, y)" << std::endl
56 << "plt.ylabel('Echo likelihood')" << std::endl
57 << "plt.xlabel('Time (s)')" << std::endl
58 << "plt.ylim([0,1])" << std::endl
59 << "plt.show()" << std::endl;
60 }
61
45 } // namespace 62 } // namespace
46 63
47 SimulationSettings::SimulationSettings() = default; 64 SimulationSettings::SimulationSettings() = default;
48 SimulationSettings::SimulationSettings(const SimulationSettings&) = default; 65 SimulationSettings::SimulationSettings(const SimulationSettings&) = default;
49 SimulationSettings::~SimulationSettings() = default; 66 SimulationSettings::~SimulationSettings() = default;
50 67
51 void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest) { 68 void CopyToAudioFrame(const ChannelBuffer<float>& src, AudioFrame* dest) {
52 RTC_CHECK_EQ(src.num_channels(), dest->num_channels_); 69 RTC_CHECK_EQ(src.num_channels(), dest->num_channels_);
53 RTC_CHECK_EQ(src.num_frames(), dest->samples_per_channel_); 70 RTC_CHECK_EQ(src.num_frames(), dest->samples_per_channel_);
54 for (size_t ch = 0; ch < dest->num_channels_; ++ch) { 71 for (size_t ch = 0; ch < dest->num_channels_; ++ch) {
55 for (size_t sample = 0; sample < dest->samples_per_channel_; ++sample) { 72 for (size_t sample = 0; sample < dest->samples_per_channel_; ++sample) {
56 dest->data_[sample * dest->num_channels_ + ch] = 73 dest->data_[sample * dest->num_channels_ + ch] =
57 src.channels()[ch][sample] * 32767; 74 src.channels()[ch][sample] * 32767;
58 } 75 }
59 } 76 }
60 } 77 }
61 78
62 AudioProcessingSimulator::AudioProcessingSimulator( 79 AudioProcessingSimulator::AudioProcessingSimulator(
63 const SimulationSettings& settings) 80 const SimulationSettings& settings)
64 : settings_(settings) {} 81 : settings_(settings) {
82 if (settings_.red_graph_output_filename &&
83 settings_.red_graph_output_filename->size() > 0) {
84 residual_echo_likelihood_graph_writer_.open(
85 *settings_.red_graph_output_filename);
86 RTC_CHECK(residual_echo_likelihood_graph_writer_.is_open());
87 WriteEchoLikelihoodGraphFileHeader(&residual_echo_likelihood_graph_writer_);
88 }
89 }
65 90
66 AudioProcessingSimulator::~AudioProcessingSimulator() = default; 91 AudioProcessingSimulator::~AudioProcessingSimulator() {
92 if (residual_echo_likelihood_graph_writer_.is_open()) {
93 WriteEchoLikelihoodGraphFileFooter(&residual_echo_likelihood_graph_writer_);
94 residual_echo_likelihood_graph_writer_.close();
95 }
96 }
67 97
68 AudioProcessingSimulator::ScopedTimer::~ScopedTimer() { 98 AudioProcessingSimulator::ScopedTimer::~ScopedTimer() {
69 int64_t interval = rtc::TimeNanos() - start_time_; 99 int64_t interval = rtc::TimeNanos() - start_time_;
70 proc_time_->sum += interval; 100 proc_time_->sum += interval;
71 proc_time_->max = std::max(proc_time_->max, interval); 101 proc_time_->max = std::max(proc_time_->max, interval);
72 proc_time_->min = std::min(proc_time_->min, interval); 102 proc_time_->min = std::min(proc_time_->min, interval);
73 } 103 }
74 104
75 void AudioProcessingSimulator::ProcessStream(bool fixed_interface) { 105 void AudioProcessingSimulator::ProcessStream(bool fixed_interface) {
76 if (fixed_interface) { 106 if (fixed_interface) {
77 { 107 {
78 const auto st = ScopedTimer(mutable_proc_time()); 108 const auto st = ScopedTimer(mutable_proc_time());
79 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&fwd_frame_)); 109 RTC_CHECK_EQ(AudioProcessing::kNoError, ap_->ProcessStream(&fwd_frame_));
80 } 110 }
81 CopyFromAudioFrame(fwd_frame_, out_buf_.get()); 111 CopyFromAudioFrame(fwd_frame_, out_buf_.get());
82 } else { 112 } else {
83 const auto st = ScopedTimer(mutable_proc_time()); 113 const auto st = ScopedTimer(mutable_proc_time());
84 RTC_CHECK_EQ(AudioProcessing::kNoError, 114 RTC_CHECK_EQ(AudioProcessing::kNoError,
85 ap_->ProcessStream(in_buf_->channels(), in_config_, 115 ap_->ProcessStream(in_buf_->channels(), in_config_,
86 out_config_, out_buf_->channels())); 116 out_config_, out_buf_->channels()));
87 } 117 }
88 118
89 if (buffer_writer_) { 119 if (buffer_writer_) {
90 buffer_writer_->Write(*out_buf_); 120 buffer_writer_->Write(*out_buf_);
91 } 121 }
92 122
123 if (residual_echo_likelihood_graph_writer_.is_open()) {
124 auto stats = ap_->GetStatistics();
125 residual_echo_likelihood_graph_writer_ << stats.residual_echo_likelihood
126 << ", ";
127 }
128
93 ++num_process_stream_calls_; 129 ++num_process_stream_calls_;
94 } 130 }
95 131
96 void AudioProcessingSimulator::ProcessReverseStream(bool fixed_interface) { 132 void AudioProcessingSimulator::ProcessReverseStream(bool fixed_interface) {
97 if (fixed_interface) { 133 if (fixed_interface) {
98 const auto st = ScopedTimer(mutable_proc_time()); 134 const auto st = ScopedTimer(mutable_proc_time());
99 RTC_CHECK_EQ(AudioProcessing::kNoError, 135 RTC_CHECK_EQ(AudioProcessing::kNoError,
100 ap_->ProcessReverseStream(&rev_frame_)); 136 ap_->ProcessReverseStream(&rev_frame_));
101 CopyFromAudioFrame(rev_frame_, reverse_out_buf_.get()); 137 CopyFromAudioFrame(rev_frame_, reverse_out_buf_.get());
102 138
(...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after
238 apm_config.level_controller.enabled = *settings_.use_lc; 274 apm_config.level_controller.enabled = *settings_.use_lc;
239 } 275 }
240 if (settings_.use_refined_adaptive_filter) { 276 if (settings_.use_refined_adaptive_filter) {
241 config.Set<RefinedAdaptiveFilter>( 277 config.Set<RefinedAdaptiveFilter>(
242 new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter)); 278 new RefinedAdaptiveFilter(*settings_.use_refined_adaptive_filter));
243 } 279 }
244 config.Set<ExtendedFilter>(new ExtendedFilter( 280 config.Set<ExtendedFilter>(new ExtendedFilter(
245 !settings_.use_extended_filter || *settings_.use_extended_filter)); 281 !settings_.use_extended_filter || *settings_.use_extended_filter));
246 config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic || 282 config.Set<DelayAgnostic>(new DelayAgnostic(!settings_.use_delay_agnostic ||
247 *settings_.use_delay_agnostic)); 283 *settings_.use_delay_agnostic));
284 if (settings_.use_red) {
285 apm_config.residual_echo_detector.enabled = *settings_.use_red;
286 }
248 287
249 ap_.reset(AudioProcessing::Create(config)); 288 ap_.reset(AudioProcessing::Create(config));
250 RTC_CHECK(ap_); 289 RTC_CHECK(ap_);
251 290
252 ap_->ApplyConfig(apm_config); 291 ap_->ApplyConfig(apm_config);
253 292
254 if (settings_.use_aec) { 293 if (settings_.use_aec) {
255 RTC_CHECK_EQ(AudioProcessing::kNoError, 294 RTC_CHECK_EQ(AudioProcessing::kNoError,
256 ap_->echo_cancellation()->Enable(*settings_.use_aec)); 295 ap_->echo_cancellation()->Enable(*settings_.use_aec));
257 } 296 }
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
343 size_t kMaxFilenameSize = AudioProcessing::kMaxFilenameSize; 382 size_t kMaxFilenameSize = AudioProcessing::kMaxFilenameSize;
344 RTC_CHECK_LE(settings_.aec_dump_output_filename->size(), kMaxFilenameSize); 383 RTC_CHECK_LE(settings_.aec_dump_output_filename->size(), kMaxFilenameSize);
345 RTC_CHECK_EQ(AudioProcessing::kNoError, 384 RTC_CHECK_EQ(AudioProcessing::kNoError,
346 ap_->StartDebugRecording( 385 ap_->StartDebugRecording(
347 settings_.aec_dump_output_filename->c_str(), -1)); 386 settings_.aec_dump_output_filename->c_str(), -1));
348 } 387 }
349 } 388 }
350 389
351 } // namespace test 390 } // namespace test
352 } // namespace webrtc 391 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698