xref: /aosp_15_r20/external/webrtc/modules/audio_processing/test/wav_based_simulator.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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