1 /*
2 * Copyright (c) 2016 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 "modules/audio_processing/test/wav_based_simulator.h"
12
13 #include <stdio.h>
14
15 #include <iostream>
16
17 #include "absl/strings/string_view.h"
18 #include "modules/audio_processing/logging/apm_data_dumper.h"
19 #include "modules/audio_processing/test/test_utils.h"
20 #include "rtc_base/checks.h"
21 #include "rtc_base/system/file_wrapper.h"
22
23 namespace webrtc {
24 namespace test {
25
26 std::vector<WavBasedSimulator::SimulationEventType>
GetCustomEventChain(absl::string_view filename)27 WavBasedSimulator::GetCustomEventChain(absl::string_view filename) {
28 std::vector<WavBasedSimulator::SimulationEventType> call_chain;
29 FileWrapper file_wrapper = FileWrapper::OpenReadOnly(filename);
30
31 RTC_CHECK(file_wrapper.is_open())
32 << "Could not open the custom call order file, reverting "
33 "to using the default call order";
34
35 char c;
36 size_t num_read = file_wrapper.Read(&c, sizeof(char));
37 while (num_read > 0) {
38 switch (c) {
39 case 'r':
40 call_chain.push_back(SimulationEventType::kProcessReverseStream);
41 break;
42 case 'c':
43 call_chain.push_back(SimulationEventType::kProcessStream);
44 break;
45 case '\n':
46 break;
47 default:
48 RTC_FATAL() << "Incorrect custom call order file";
49 }
50
51 num_read = file_wrapper.Read(&c, sizeof(char));
52 }
53
54 return call_chain;
55 }
56
WavBasedSimulator(const SimulationSettings & settings,rtc::scoped_refptr<AudioProcessing> audio_processing,std::unique_ptr<AudioProcessingBuilder> ap_builder)57 WavBasedSimulator::WavBasedSimulator(
58 const SimulationSettings& settings,
59 rtc::scoped_refptr<AudioProcessing> audio_processing,
60 std::unique_ptr<AudioProcessingBuilder> ap_builder)
61 : AudioProcessingSimulator(settings,
62 std::move(audio_processing),
63 std::move(ap_builder)) {
64 if (settings_.call_order_input_filename) {
65 call_chain_ = WavBasedSimulator::GetCustomEventChain(
66 *settings_.call_order_input_filename);
67 } else {
68 call_chain_ = WavBasedSimulator::GetDefaultEventChain();
69 }
70 }
71
72 WavBasedSimulator::~WavBasedSimulator() = default;
73
74 std::vector<WavBasedSimulator::SimulationEventType>
GetDefaultEventChain()75 WavBasedSimulator::GetDefaultEventChain() {
76 std::vector<WavBasedSimulator::SimulationEventType> call_chain(2);
77 call_chain[0] = SimulationEventType::kProcessStream;
78 call_chain[1] = SimulationEventType::kProcessReverseStream;
79 return call_chain;
80 }
81
PrepareProcessStreamCall()82 void WavBasedSimulator::PrepareProcessStreamCall() {
83 if (settings_.fixed_interface) {
84 fwd_frame_.CopyFrom(*in_buf_);
85 }
86 ap_->set_stream_key_pressed(settings_.override_key_pressed.value_or(false));
87
88 if (!settings_.use_stream_delay || *settings_.use_stream_delay) {
89 RTC_CHECK_EQ(AudioProcessing::kNoError,
90 ap_->set_stream_delay_ms(
91 settings_.stream_delay ? *settings_.stream_delay : 0));
92 }
93 }
94
PrepareReverseProcessStreamCall()95 void WavBasedSimulator::PrepareReverseProcessStreamCall() {
96 if (settings_.fixed_interface) {
97 rev_frame_.CopyFrom(*reverse_in_buf_);
98 }
99 }
100
Process()101 void WavBasedSimulator::Process() {
102 ConfigureAudioProcessor();
103
104 Initialize();
105
106 bool samples_left_to_process = true;
107 int call_chain_index = 0;
108 int capture_frames_since_init = 0;
109 constexpr int kInitIndex = 1;
110 while (samples_left_to_process) {
111 switch (call_chain_[call_chain_index]) {
112 case SimulationEventType::kProcessStream:
113 SelectivelyToggleDataDumping(kInitIndex, capture_frames_since_init);
114
115 samples_left_to_process = HandleProcessStreamCall();
116 ++capture_frames_since_init;
117 break;
118 case SimulationEventType::kProcessReverseStream:
119 if (settings_.reverse_input_filename) {
120 samples_left_to_process = HandleProcessReverseStreamCall();
121 }
122 break;
123 default:
124 RTC_CHECK_NOTREACHED();
125 }
126
127 call_chain_index = (call_chain_index + 1) % call_chain_.size();
128 }
129
130 DetachAecDump();
131 }
132
Analyze()133 void WavBasedSimulator::Analyze() {
134 std::cout << "Inits:" << std::endl;
135 std::cout << "1: -->" << std::endl;
136 std::cout << " Time:" << std::endl;
137 std::cout << " Capture: 0 s (0 frames) " << std::endl;
138 std::cout << " Render: 0 s (0 frames)" << std::endl;
139 }
140
HandleProcessStreamCall()141 bool WavBasedSimulator::HandleProcessStreamCall() {
142 bool samples_left_to_process = buffer_reader_->Read(in_buf_.get());
143 if (samples_left_to_process) {
144 PrepareProcessStreamCall();
145 ProcessStream(settings_.fixed_interface);
146 }
147 return samples_left_to_process;
148 }
149
HandleProcessReverseStreamCall()150 bool WavBasedSimulator::HandleProcessReverseStreamCall() {
151 bool samples_left_to_process =
152 reverse_buffer_reader_->Read(reverse_in_buf_.get());
153 if (samples_left_to_process) {
154 PrepareReverseProcessStreamCall();
155 ProcessReverseStream(settings_.fixed_interface);
156 }
157 return samples_left_to_process;
158 }
159
Initialize()160 void WavBasedSimulator::Initialize() {
161 std::unique_ptr<WavReader> in_file(
162 new WavReader(settings_.input_filename->c_str()));
163 int input_sample_rate_hz = in_file->sample_rate();
164 int input_num_channels = in_file->num_channels();
165 buffer_reader_.reset(new ChannelBufferWavReader(std::move(in_file)));
166
167 int output_sample_rate_hz = settings_.output_sample_rate_hz
168 ? *settings_.output_sample_rate_hz
169 : input_sample_rate_hz;
170 int output_num_channels = settings_.output_num_channels
171 ? *settings_.output_num_channels
172 : input_num_channels;
173
174 int reverse_sample_rate_hz = 48000;
175 int reverse_num_channels = 1;
176 int reverse_output_sample_rate_hz = 48000;
177 int reverse_output_num_channels = 1;
178 if (settings_.reverse_input_filename) {
179 std::unique_ptr<WavReader> reverse_in_file(
180 new WavReader(settings_.reverse_input_filename->c_str()));
181 reverse_sample_rate_hz = reverse_in_file->sample_rate();
182 reverse_num_channels = reverse_in_file->num_channels();
183 reverse_buffer_reader_.reset(
184 new ChannelBufferWavReader(std::move(reverse_in_file)));
185
186 reverse_output_sample_rate_hz =
187 settings_.reverse_output_sample_rate_hz
188 ? *settings_.reverse_output_sample_rate_hz
189 : reverse_sample_rate_hz;
190 reverse_output_num_channels = settings_.reverse_output_num_channels
191 ? *settings_.reverse_output_num_channels
192 : reverse_num_channels;
193 }
194
195 SetupBuffersConfigsOutputs(
196 input_sample_rate_hz, output_sample_rate_hz, reverse_sample_rate_hz,
197 reverse_output_sample_rate_hz, input_num_channels, output_num_channels,
198 reverse_num_channels, reverse_output_num_channels);
199 }
200
201 } // namespace test
202 } // namespace webrtc
203