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

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

Issue 1409943002: Add aecdump support to audioproc_f. (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Add TickIntervalStats and clarify some documentation. Created 5 years, 2 months 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
(Empty)
1 /*
2 * Copyright (c) 2015 The WebRTC project authors. All Rights Reserved.
3 *
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
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "webrtc/modules/audio_processing/test/audio_file_processor.h"
12
13 #include <algorithm>
14
15 #include "webrtc/base/checks.h"
16 #include "webrtc/modules/audio_processing/test/protobuf_utils.h"
17
18 using rtc::scoped_ptr;
19 using rtc::CheckedDivExact;
20 using std::vector;
21 using webrtc::audioproc::Event;
22 using webrtc::audioproc::Init;
23 using webrtc::audioproc::ReverseStream;
24 using webrtc::audioproc::Stream;
25
26 namespace webrtc {
27 namespace {
28
29 // Returns a StreamConfig corresponding to file.
30 StreamConfig GetStreamConfig(const WavFile& file) {
31 return StreamConfig(file.sample_rate(), file.num_channels());
32 }
33
34 // Returns a ChannelBuffer corresponding to file.
35 ChannelBuffer<float> GetChannelBuffer(const WavFile& file) {
36 return ChannelBuffer<float>(
37 CheckedDivExact(file.sample_rate(), AudioFileProcessor::kChunksPerSecond),
38 file.num_channels());
39 }
40
41 } // namespace
42
43 WavFileProcessor::WavFileProcessor(scoped_ptr<AudioProcessing> ap,
44 scoped_ptr<WavReader> in_file,
45 scoped_ptr<WavWriter> out_file)
46 : ap_(ap.Pass()),
47 in_file_(in_file.Pass()),
48 in_buf_(GetChannelBuffer(*in_file_)),
49 out_buf_(GetChannelBuffer(*out_file)),
50 in_interleaved_(in_buf_.size()),
51 input_config_(GetStreamConfig(*in_file_)),
52 output_config_(GetStreamConfig(*out_file)),
53 buffer_writer_(out_file.Pass()) {}
54
55 bool WavFileProcessor::ProcessAndWriteChunk() {
56 if (in_file_->ReadSamples(in_interleaved_.size(), &in_interleaved_[0]) !=
57 in_interleaved_.size()) {
58 return false;
59 }
60
61 FloatS16ToFloat(&in_interleaved_[0], in_interleaved_.size(),
62 &in_interleaved_[0]);
63 Deinterleave(&in_interleaved_[0], in_buf_.num_frames(),
64 in_buf_.num_channels(), in_buf_.channels());
65
66 {
67 const auto st = ScopedTimer(mutable_proc_time());
68 RTC_CHECK_EQ(kNoErr,
69 ap_->ProcessStream(in_buf_.channels(), input_config_,
70 output_config_, out_buf_.channels()));
71 }
72
73 buffer_writer_.Write(out_buf_);
74 return true;
75 }
76
77 AecDumpFileProcessor::AecDumpFileProcessor(scoped_ptr<AudioProcessing> ap,
peah-webrtc 2015/10/23 07:42:40 One more comment on this: Would it be possible to
78 FILE* dump_file,
79 scoped_ptr<WavWriter> out_file)
80 : ap_(ap.Pass()),
81 dump_file_(dump_file),
82 out_buf_(GetChannelBuffer(*out_file)),
83 output_config_(GetStreamConfig(*out_file)),
84 buffer_writer_(out_file.Pass()) {
85 RTC_CHECK(dump_file_) << "Could not open dump file for reading.";
86 }
87
88 AecDumpFileProcessor::~AecDumpFileProcessor() {
89 fclose(dump_file_);
90 }
91
92 bool AecDumpFileProcessor::ProcessAndWriteChunk() {
93 Event event_msg;
94
95 // Continue until we process our first Stream message.
96 do {
97 if (!ReadMessageFromFile(dump_file_, &event_msg)) {
98 return false;
99 }
100
101 if (event_msg.type() == Event::INIT) {
102 RTC_CHECK(event_msg.has_init());
103 HandleMessage(event_msg.init());
104
105 } else if (event_msg.type() == Event::STREAM) {
106 RTC_CHECK(event_msg.has_stream());
107 HandleMessage(event_msg.stream());
108 break;
109
110 } else if (event_msg.type() == Event::REVERSE_STREAM) {
111 RTC_CHECK(event_msg.has_reverse_stream());
112 HandleMessage(event_msg.reverse_stream());
113 }
114 } while (event_msg.type() != Event::STREAM);
115
116 return true;
117 }
118
119 void AecDumpFileProcessor::HandleMessage(const Init& msg) {
120 RTC_CHECK(msg.has_sample_rate());
121 RTC_CHECK(msg.has_num_input_channels());
122 RTC_CHECK(msg.has_num_reverse_channels());
123
124 in_buf_.reset(new ChannelBuffer<float>(
125 CheckedDivExact(msg.sample_rate(), kChunksPerSecond),
126 msg.num_input_channels()));
127 const int reverse_sample_rate = msg.has_reverse_sample_rate()
128 ? msg.reverse_sample_rate()
129 : msg.sample_rate();
130 reverse_buf_.reset(new ChannelBuffer<float>(
131 CheckedDivExact(reverse_sample_rate, kChunksPerSecond),
132 msg.num_reverse_channels()));
133 input_config_ = StreamConfig(msg.sample_rate(), msg.num_input_channels());
134 reverse_config_ =
135 StreamConfig(msg.reverse_sample_rate(), msg.num_reverse_channels());
136
137 const ProcessingConfig config = {
138 {input_config_, output_config_, reverse_config_, reverse_config_}};
139 RTC_CHECK_EQ(kNoErr, ap_->Initialize(config));
140 }
141
142 void AecDumpFileProcessor::HandleMessage(const Stream& msg) {
143 RTC_CHECK(!msg.has_input_data());
144 RTC_CHECK_EQ(in_buf_->num_channels(), msg.input_channel_size());
145
146 for (int i = 0; i < msg.input_channel_size(); ++i) {
147 RTC_CHECK_EQ(in_buf_->num_frames() * sizeof(*in_buf_->channels()[i]),
148 msg.input_channel(i).size());
149 std::memcpy(in_buf_->channels()[i], msg.input_channel(i).data(),
150 msg.input_channel(i).size());
151 }
152 {
153 const auto st = ScopedTimer(mutable_proc_time());
154 RTC_CHECK_EQ(kNoErr, ap_->set_stream_delay_ms(msg.delay()));
155 ap_->echo_cancellation()->set_stream_drift_samples(msg.drift());
156 if (msg.has_keypress()) {
157 ap_->set_stream_key_pressed(msg.keypress());
158 }
159 RTC_CHECK_EQ(kNoErr,
160 ap_->ProcessStream(in_buf_->channels(), input_config_,
161 output_config_, out_buf_.channels()));
162 }
163
164 buffer_writer_.Write(out_buf_);
165 }
166
167 void AecDumpFileProcessor::HandleMessage(const ReverseStream& msg) {
168 RTC_CHECK(!msg.has_data());
169 RTC_CHECK_EQ(reverse_buf_->num_channels(), msg.channel_size());
170
171 for (int i = 0; i < msg.channel_size(); ++i) {
172 RTC_CHECK_EQ(reverse_buf_->num_frames() * sizeof(*in_buf_->channels()[i]),
173 msg.channel(i).size());
174 std::memcpy(reverse_buf_->channels()[i], msg.channel(i).data(),
175 msg.channel(i).size());
176 }
177 {
178 const auto st = ScopedTimer(mutable_proc_time());
179 // TODO(ajm): This currently discards the processed output, which is needed
180 // for e.g. intelligibility enhancement.
181 RTC_CHECK_EQ(kNoErr, ap_->ProcessReverseStream(
182 reverse_buf_->channels(), reverse_config_,
183 reverse_config_, reverse_buf_->channels()));
184 }
185 }
186
187 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698