Index: webrtc/audio/test/low_bandwidth_audio_test.cc |
diff --git a/webrtc/audio/test/low_bandwidth_audio_test.cc b/webrtc/audio/test/low_bandwidth_audio_test.cc |
index c78e8897a824008e6336d676b7a3e5040c1ff5b5..9e55af72981f6e600c8f5d445e00e31e2dc75edb 100644 |
--- a/webrtc/audio/test/low_bandwidth_audio_test.cc |
+++ b/webrtc/audio/test/low_bandwidth_audio_test.cc |
@@ -1,5 +1,5 @@ |
/* |
- * Copyright 2017 The WebRTC Project Authors. All rights reserved. |
+ * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved. |
* |
* Use of this source code is governed by a BSD-style license |
* that can be found in the LICENSE file in the root of the source |
@@ -8,9 +8,198 @@ |
* be found in the AUTHORS file in the root of the source tree. |
*/ |
-// This is a placeholder for the work oprypin@ is doing on a low-bandwidth |
-// audio test executable. |
+#include <algorithm> |
-int main() { |
+#include "webrtc/audio/test/low_bandwidth_audio_test.h" |
+#include "webrtc/common_audio/wav_file.h" |
+#include "webrtc/test/gtest.h" |
+#include "webrtc/test/run_test.h" |
+#include "webrtc/system_wrappers/include/sleep.h" |
+#include "webrtc/test/testsupport/fileutils.h" |
+ |
+ |
+namespace webrtc { |
+namespace test { |
+ |
+// Writes to a WAV file, cutting off silence at the beginning and the end. |
+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
|
+ public: |
+ BoundedWavFileWriter(std::string filename, int sampling_frequency_in_hz) |
+ : sampling_frequency_in_hz_(sampling_frequency_in_hz), |
+ wav_writer_(filename, sampling_frequency_in_hz, 1), |
+ silent_audio_(test::FakeAudioDevice::SamplesPerFrame( |
+ sampling_frequency_in_hz), 0), |
+ started_writing_(false), |
+ trailing_zeros_(0) {} |
+ |
+ int SamplingFrequency() const override { |
+ return sampling_frequency_in_hz_; |
+ } |
+ |
+ bool Render(rtc::ArrayView<const int16_t> data) override { |
+ const int16_t kAmplitudeThreshold = 5; |
+ |
+ const int16_t* begin = data.begin(); |
+ const int16_t* end = data.end(); |
+ if (!started_writing_) { |
+ // Cut off silence at the beginning. |
+ while (begin < end) { |
+ if (*begin > kAmplitudeThreshold || *begin < -kAmplitudeThreshold) { |
+ started_writing_ = true; |
+ break; |
+ } |
+ ++begin; |
+ } |
+ } |
+ if (started_writing_) { |
+ // Cut off silence at the end. |
+ while (begin < end) { |
+ if (*(end - 1) != 0) { |
+ break; |
+ } |
+ --end; |
+ ++trailing_zeros_; |
+ } |
+ if (begin < end) { |
+ // If it turns out that the silence was not final, need to write all the |
+ // skipped zeros and continue writing audio. |
+ while (trailing_zeros_ > 0) { |
+ const size_t zeros_to_write = std::min(trailing_zeros_, |
+ silent_audio_.size()); |
+ wav_writer_.WriteSamples(silent_audio_.data(), zeros_to_write); |
+ trailing_zeros_ -= zeros_to_write; |
+ } |
+ wav_writer_.WriteSamples(begin, end - begin); |
+ } |
+ } |
+ return true; |
+ } |
+ |
+ private: |
+ int sampling_frequency_in_hz_; |
+ WavWriter wav_writer_; |
+ std::vector<int16_t> silent_audio_; |
+ bool started_writing_; |
+ size_t trailing_zeros_; |
+}; |
+ |
+ |
+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.
|
+ |
+size_t AudioQualityTest::GetNumVideoStreams() const { |
return 0; |
} |
+size_t AudioQualityTest::GetNumAudioStreams() const { |
+ return 1; |
+} |
+size_t AudioQualityTest::GetNumFlexfecStreams() const { |
+ return 0; |
+} |
+ |
+std::string AudioQualityTest::AudioInputFile() { |
+ return test::ResourcePath("voice_engine/audio_tiny16", "wav"); |
+} |
+ |
+std::string AudioQualityTest::AudioOutputFile() { |
+ const ::testing::TestInfo* const test_info = |
+ ::testing::UnitTest::GetInstance()->current_test_info(); |
+ return webrtc::test::OutputPath() + |
+ "LowBandwidth_" + test_info->name() + ".wav"; |
+} |
+ |
+std::unique_ptr<test::FakeAudioDevice::Capturer> |
+ AudioQualityTest::CreateCapturer() { |
+ return test::FakeAudioDevice::CreateWavFileReader(AudioInputFile()); |
+} |
+ |
+std::unique_ptr<test::FakeAudioDevice::Renderer> |
+ AudioQualityTest::CreateRenderer() { |
+ return std::unique_ptr<test::FakeAudioDevice::Renderer>( |
+ 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.
|
+} |
+ |
+void AudioQualityTest::OnFakeAudioDevicesCreated( |
+ test::FakeAudioDevice* send_audio_device, |
+ test::FakeAudioDevice* recv_audio_device) { |
+ send_audio_device_ = send_audio_device; |
+} |
+ |
+FakeNetworkPipe::Config AudioQualityTest::GetNetworkPipeConfig() { |
+ return FakeNetworkPipe::Config(); |
+} |
+ |
+test::PacketTransport* AudioQualityTest::CreateSendTransport( |
+ Call* sender_call) { |
+ return new test::PacketTransport( |
+ sender_call, this, test::PacketTransport::kSender, |
+ GetNetworkPipeConfig()); |
+} |
+ |
+test::PacketTransport* AudioQualityTest::CreateReceiveTransport() { |
+ return new test::PacketTransport(nullptr, this, |
+ test::PacketTransport::kReceiver, GetNetworkPipeConfig()); |
+} |
+ |
+void AudioQualityTest::ModifyAudioConfigs( |
+ AudioSendStream::Config* send_config, |
+ std::vector<AudioReceiveStream::Config>* receive_configs) { |
+ // Large bitrate by default. |
+ send_config->send_codec_spec.codec_inst = |
+ 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.
|
+} |
+ |
+void AudioQualityTest::PerformTest() { |
+ // Wait until the input audio file is done... |
+ send_audio_device_->WaitForRecordingEnd(); |
+ // and some extra time to account for network delay. |
+ 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.
|
+} |
+ |
+void AudioQualityTest::OnTestFinished() { |
+ const ::testing::TestInfo* const test_info = |
+ ::testing::UnitTest::GetInstance()->current_test_info(); |
+ |
+ // Output information about the input and output audio files so that further |
+ // processing can be done by an external process. |
+ printf("TEST %s %s:%s\n", test_info->name(), |
+ AudioInputFile().c_str(), AudioOutputFile().c_str()); |
+} |
+ |
+ |
+using LowBandwidthAudioTest = test::CallTest; |
+ |
+TEST_F(LowBandwidthAudioTest, GoodNetworkHighBitrate) { |
+ AudioQualityTest test; |
+ RunBaseTest(&test); |
+} |
+ |
+ |
+class Mobile2GNetworkTest : public AudioQualityTest { |
+ void ModifyAudioConfigs(AudioSendStream::Config* send_config, |
+ std::vector<AudioReceiveStream::Config>* receive_configs) override { |
+ send_config->send_codec_spec.codec_inst = CodecInst{ |
+ 120, // pltype |
+ "OPUS", // plname |
+ 48000, // plfreq |
+ 2880, // pacsize |
+ 1, // channels |
+ 6000 // rate bits/sec |
+ }; |
+ } |
+ |
+ FakeNetworkPipe::Config GetNetworkPipeConfig() override { |
+ FakeNetworkPipe::Config pipe_config; |
+ pipe_config.link_capacity_kbps = 12; |
+ 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
|
+ pipe_config.queue_delay_ms = 400; |
+ return pipe_config; |
+ } |
+}; |
+ |
+TEST_F(LowBandwidthAudioTest, Mobile2GNetwork) { |
+ Mobile2GNetworkTest test; |
+ RunBaseTest(&test); |
+} |
+ |
+} // namespace test |
+} // namespace webrtc |