Chromium Code Reviews| 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 |