OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright 2017 The WebRTC Project Authors. All rights reserved. | 2 * Copyright (c) 2017 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 // This is a placeholder for the work oprypin@ is doing on a low-bandwidth | 11 #include <algorithm> |
12 // audio test executable. | |
13 | 12 |
14 int main() { | 13 #include "webrtc/audio/test/low_bandwidth_audio_test.h" |
14 #include "webrtc/common_audio/wav_file.h" | |
15 #include "webrtc/test/gtest.h" | |
16 #include "webrtc/test/run_test.h" | |
17 #include "webrtc/system_wrappers/include/sleep.h" | |
18 #include "webrtc/test/testsupport/fileutils.h" | |
19 | |
20 | |
21 namespace webrtc { | |
22 namespace test { | |
23 | |
24 // Writes to a WAV file, cutting off silence at the beginning and the end. | |
25 class BoundedWavFileWriter : public test::FakeAudioDevice::Renderer { | |
kjellander_webrtc
2017/03/17 07:11:41
I think BoundedWavFileWriter is large enough for i
oprypin_webrtc
2017/03/20 10:39:27
We discussed this and came to conclusion that it's
kjellander_webrtc
2017/03/21 08:31:49
Actually, I thought we just agreed on where it wou
kjellander_webrtc
2017/03/21 08:43:41
I've now been convinced this is fine. Let's keep i
| |
26 public: | |
27 BoundedWavFileWriter(std::string filename, int sampling_frequency_in_hz) | |
28 : sampling_frequency_in_hz_(sampling_frequency_in_hz), | |
29 wav_writer_(filename, sampling_frequency_in_hz, 1), | |
30 silent_audio_(test::FakeAudioDevice::SamplesPerFrame( | |
31 sampling_frequency_in_hz), 0), | |
32 started_writing_(false), | |
33 trailing_zeros_(0) {} | |
34 | |
35 int SamplingFrequency() const override { | |
36 return sampling_frequency_in_hz_; | |
37 } | |
38 | |
39 bool Render(rtc::ArrayView<const int16_t> data) override { | |
40 const int16_t kAmplitudeThreshold = 5; | |
41 | |
42 const int16_t* begin = data.begin(); | |
43 const int16_t* end = data.end(); | |
44 if (!started_writing_) { | |
45 // Cut off silence at the beginning. | |
46 while (begin < end) { | |
47 if (*begin > kAmplitudeThreshold || *begin < -kAmplitudeThreshold) { | |
48 started_writing_ = true; | |
49 break; | |
50 } | |
51 ++begin; | |
52 } | |
53 } | |
54 if (started_writing_) { | |
55 // Cut off silence at the end. | |
56 while (begin < end) { | |
57 if (*(end - 1) != 0) { | |
58 break; | |
59 } | |
60 --end; | |
61 ++trailing_zeros_; | |
62 } | |
63 if (begin < end) { | |
64 // If it turns out that the silence was not final, need to write all the | |
65 // skipped zeros and continue writing audio. | |
66 while (trailing_zeros_ > 0) { | |
67 const size_t zeros_to_write = std::min(trailing_zeros_, | |
68 silent_audio_.size()); | |
69 wav_writer_.WriteSamples(silent_audio_.data(), zeros_to_write); | |
70 trailing_zeros_ -= zeros_to_write; | |
71 } | |
72 wav_writer_.WriteSamples(begin, end - begin); | |
73 } | |
74 } | |
75 return true; | |
76 } | |
77 | |
78 private: | |
79 int sampling_frequency_in_hz_; | |
80 WavWriter wav_writer_; | |
81 std::vector<int16_t> silent_audio_; | |
82 bool started_writing_; | |
83 size_t trailing_zeros_; | |
84 }; | |
85 | |
86 | |
87 AudioQualityTest::AudioQualityTest() : EndToEndTest(1000) {} | |
kjellander_webrtc
2017/03/17 07:11:41
It's not clear what 1000 is here. Move into a cons
oprypin_webrtc
2017/03/17 10:16:51
Done.
| |
88 | |
89 size_t AudioQualityTest::GetNumVideoStreams() const { | |
15 return 0; | 90 return 0; |
16 } | 91 } |
92 size_t AudioQualityTest::GetNumAudioStreams() const { | |
93 return 1; | |
94 } | |
95 size_t AudioQualityTest::GetNumFlexfecStreams() const { | |
96 return 0; | |
97 } | |
98 | |
99 std::string AudioQualityTest::AudioInputFile() { | |
100 return test::ResourcePath("voice_engine/audio_tiny16", "wav"); | |
101 } | |
102 | |
103 std::string AudioQualityTest::AudioOutputFile() { | |
104 const ::testing::TestInfo* const test_info = | |
105 ::testing::UnitTest::GetInstance()->current_test_info(); | |
106 return webrtc::test::OutputPath() + | |
107 "LowBandwidth_" + test_info->name() + ".wav"; | |
108 } | |
109 | |
110 std::unique_ptr<test::FakeAudioDevice::Capturer> | |
111 AudioQualityTest::CreateCapturer() { | |
112 return test::FakeAudioDevice::CreateWavFileReader(AudioInputFile()); | |
113 } | |
114 | |
115 std::unique_ptr<test::FakeAudioDevice::Renderer> | |
116 AudioQualityTest::CreateRenderer() { | |
117 return std::unique_ptr<test::FakeAudioDevice::Renderer>( | |
118 new BoundedWavFileWriter(AudioOutputFile(), 16000)); | |
kjellander_webrtc
2017/03/17 07:11:41
Extract into a constant or even a gflags flag, sin
oprypin_webrtc
2017/03/17 10:16:51
PESQ has "Sample rate [...] Must select either +80
kjellander_webrtc
2017/03/17 10:37:18
Yes, let's keep it as a constant.
| |
119 } | |
120 | |
121 void AudioQualityTest::OnFakeAudioDevicesCreated( | |
122 test::FakeAudioDevice* send_audio_device, | |
123 test::FakeAudioDevice* recv_audio_device) { | |
124 send_audio_device_ = send_audio_device; | |
125 } | |
126 | |
127 FakeNetworkPipe::Config AudioQualityTest::GetNetworkPipeConfig() { | |
128 return FakeNetworkPipe::Config(); | |
129 } | |
130 | |
131 test::PacketTransport* AudioQualityTest::CreateSendTransport( | |
132 Call* sender_call) { | |
133 return new test::PacketTransport( | |
134 sender_call, this, test::PacketTransport::kSender, | |
135 GetNetworkPipeConfig()); | |
136 } | |
137 | |
138 test::PacketTransport* AudioQualityTest::CreateReceiveTransport() { | |
139 return new test::PacketTransport(nullptr, this, | |
140 test::PacketTransport::kReceiver, GetNetworkPipeConfig()); | |
141 } | |
142 | |
143 void AudioQualityTest::ModifyAudioConfigs( | |
144 AudioSendStream::Config* send_config, | |
145 std::vector<AudioReceiveStream::Config>* receive_configs) { | |
146 // Large bitrate by default. | |
147 send_config->send_codec_spec.codec_inst = | |
148 CodecInst{120, "OPUS", 48000, 960, 2, 64000}; | |
kjellander_webrtc
2017/03/17 07:11:41
This default is kind of hidden. Can you store it a
oprypin_webrtc
2017/03/17 10:16:51
Done.
| |
149 } | |
150 | |
151 void AudioQualityTest::PerformTest() { | |
152 // Wait until the input audio file is done... | |
153 send_audio_device_->WaitForRecordingEnd(); | |
154 // and some extra time to account for network delay. | |
155 SleepMs(GetNetworkPipeConfig().queue_delay_ms + 500); | |
kjellander_webrtc
2017/03/17 07:11:41
Extract 500 into a constant.
oprypin_webrtc
2017/03/17 10:16:51
Done.
| |
156 } | |
157 | |
158 void AudioQualityTest::OnTestFinished() { | |
159 const ::testing::TestInfo* const test_info = | |
160 ::testing::UnitTest::GetInstance()->current_test_info(); | |
161 | |
162 // Output information about the input and output audio files so that further | |
163 // processing can be done by an external process. | |
164 printf("TEST %s %s:%s\n", test_info->name(), | |
165 AudioInputFile().c_str(), AudioOutputFile().c_str()); | |
166 } | |
167 | |
168 | |
169 using LowBandwidthAudioTest = test::CallTest; | |
170 | |
171 TEST_F(LowBandwidthAudioTest, GoodNetworkHighBitrate) { | |
172 AudioQualityTest test; | |
173 RunBaseTest(&test); | |
174 } | |
175 | |
176 | |
177 class Mobile2GNetworkTest : public AudioQualityTest { | |
178 void ModifyAudioConfigs(AudioSendStream::Config* send_config, | |
179 std::vector<AudioReceiveStream::Config>* receive_configs) override { | |
180 send_config->send_codec_spec.codec_inst = CodecInst{ | |
181 120, // pltype | |
182 "OPUS", // plname | |
183 48000, // plfreq | |
184 2880, // pacsize | |
185 1, // channels | |
186 6000 // rate bits/sec | |
187 }; | |
188 } | |
189 | |
190 FakeNetworkPipe::Config GetNetworkPipeConfig() override { | |
191 FakeNetworkPipe::Config pipe_config; | |
192 pipe_config.link_capacity_kbps = 12; | |
193 pipe_config.queue_length_packets = 1500; | |
stefan-webrtc
2017/03/20 14:40:10
I think a longer queue should be used as thats wha
| |
194 pipe_config.queue_delay_ms = 400; | |
195 return pipe_config; | |
196 } | |
197 }; | |
198 | |
199 TEST_F(LowBandwidthAudioTest, Mobile2GNetwork) { | |
200 Mobile2GNetworkTest test; | |
201 RunBaseTest(&test); | |
202 } | |
203 | |
204 } // namespace test | |
205 } // namespace webrtc | |
OLD | NEW |