| Index: webrtc/voice_engine/test/auto_test/voe_output_test.cc
|
| diff --git a/webrtc/voice_engine/test/auto_test/voe_output_test.cc b/webrtc/voice_engine/test/auto_test/voe_output_test.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6a842b80b9a0819a3f2af0675387886aa32a8a71
|
| --- /dev/null
|
| +++ b/webrtc/voice_engine/test/auto_test/voe_output_test.cc
|
| @@ -0,0 +1,198 @@
|
| +/*
|
| + * Copyright (c) 2015 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
|
| + * tree. An additional intellectual property rights grant can be found
|
| + * in the file PATENTS. All contributing project authors may
|
| + * be found in the AUTHORS file in the root of the source tree.
|
| + */
|
| +
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +#include "webrtc/base/scoped_ptr.h"
|
| +#include "webrtc/base/timeutils.h"
|
| +#include "webrtc/system_wrappers/include/sleep.h"
|
| +#include "webrtc/test/channel_transport/include/channel_transport.h"
|
| +#include "webrtc/test/random.h"
|
| +#include "webrtc/test/testsupport/fileutils.h"
|
| +#include "webrtc/voice_engine/test/auto_test/voe_standard_test.h"
|
| +
|
| +namespace {
|
| +
|
| +const char kIp[] = "127.0.0.1";
|
| +const int kPort = 1234;
|
| +const webrtc::CodecInst kCodecInst = {120, "opus", 48000, 960, 2, 64000};
|
| +
|
| +} // namespace
|
| +
|
| +namespace voetest {
|
| +
|
| +using webrtc::test::Random;
|
| +using webrtc::test::VoiceChannelTransport;
|
| +
|
| +// This test allows a check on the output signal in an end-to-end call.
|
| +class OutputTest {
|
| + public:
|
| + OutputTest(int16_t lower_bound, int16_t upper_bound);
|
| + ~OutputTest();
|
| +
|
| + void Start();
|
| +
|
| + void EnableOutputCheck();
|
| + void DisableOutputCheck();
|
| + void SetOutputBound(int16_t lower_bound, int16_t upper_bound);
|
| + void Mute();
|
| + void Unmute();
|
| + void SetBitRate(int rate);
|
| +
|
| + private:
|
| + // This class checks all output values and count the number of samples that
|
| + // go out of a defined range.
|
| + class VoEOutputCheckMediaProcess : public VoEMediaProcess {
|
| + public:
|
| + VoEOutputCheckMediaProcess(int16_t lower_bound, int16_t upper_bound);
|
| +
|
| + void set_enabled(bool enabled) { enabled_ = enabled; }
|
| + void Process(int channel,
|
| + ProcessingTypes type,
|
| + int16_t audio10ms[],
|
| + size_t length,
|
| + int samplingFreq,
|
| + bool isStereo) override;
|
| +
|
| + private:
|
| + bool enabled_;
|
| + int16_t lower_bound_;
|
| + int16_t upper_bound_;
|
| + };
|
| +
|
| + VoETestManager manager_;
|
| + VoEOutputCheckMediaProcess output_checker_;
|
| +
|
| + int channel_;
|
| +};
|
| +
|
| +OutputTest::OutputTest(int16_t lower_bound, int16_t upper_bound)
|
| + : output_checker_(lower_bound, upper_bound) {
|
| + EXPECT_TRUE(manager_.Init());
|
| + manager_.GetInterfaces();
|
| +
|
| + VoEBase* base = manager_.BasePtr();
|
| + VoECodec* codec = manager_.CodecPtr();
|
| + VoENetwork* network = manager_.NetworkPtr();
|
| +
|
| + EXPECT_EQ(0, base->Init());
|
| +
|
| + channel_ = base->CreateChannel();
|
| +
|
| + // |network| will take care of the life time of |transport|.
|
| + VoiceChannelTransport* transport =
|
| + new VoiceChannelTransport(network, channel_);
|
| +
|
| + EXPECT_EQ(0, transport->SetSendDestination(kIp, kPort));
|
| + EXPECT_EQ(0, transport->SetLocalReceiver(kPort));
|
| +
|
| + EXPECT_EQ(0, codec->SetSendCodec(channel_, kCodecInst));
|
| + EXPECT_EQ(0, codec->SetOpusDtx(channel_, true));
|
| +
|
| + EXPECT_EQ(0, manager_.VolumeControlPtr()->SetSpeakerVolume(255));
|
| +
|
| + manager_.ExternalMediaPtr()->RegisterExternalMediaProcessing(
|
| + channel_, ProcessingTypes::kPlaybackPerChannel, output_checker_);
|
| +}
|
| +
|
| +OutputTest::~OutputTest() {
|
| + EXPECT_EQ(0, manager_.NetworkPtr()->DeRegisterExternalTransport(channel_));
|
| + EXPECT_EQ(0, manager_.ReleaseInterfaces());
|
| +}
|
| +
|
| +void OutputTest::Start() {
|
| + const std::string file_name =
|
| + webrtc::test::ResourcePath("audio_coding/testfile32kHz", "pcm");
|
| + const webrtc::FileFormats kInputFormat = webrtc::kFileFormatPcm32kHzFile;
|
| +
|
| + ASSERT_EQ(0, manager_.FilePtr()->StartPlayingFileAsMicrophone(
|
| + channel_, file_name.c_str(), true, false, kInputFormat, 1.0));
|
| +
|
| + VoEBase* base = manager_.BasePtr();
|
| + ASSERT_EQ(0, base->StartPlayout(channel_));
|
| + ASSERT_EQ(0, base->StartSend(channel_));
|
| +}
|
| +
|
| +void OutputTest::EnableOutputCheck() {
|
| + output_checker_.set_enabled(true);
|
| +}
|
| +
|
| +void OutputTest::DisableOutputCheck() {
|
| + output_checker_.set_enabled(false);
|
| +}
|
| +
|
| +void OutputTest::Mute() {
|
| + manager_.VolumeControlPtr()->SetInputMute(channel_, true);
|
| +}
|
| +
|
| +void OutputTest::Unmute() {
|
| + manager_.VolumeControlPtr()->SetInputMute(channel_, false);
|
| +}
|
| +
|
| +void OutputTest::SetBitRate(int rate) {
|
| + manager_.CodecPtr()->SetBitRate(channel_, rate);
|
| +}
|
| +
|
| +OutputTest::VoEOutputCheckMediaProcess::VoEOutputCheckMediaProcess(
|
| + int16_t lower_bound, int16_t upper_bound)
|
| + : enabled_(false),
|
| + lower_bound_(-lower_bound),
|
| + upper_bound_(upper_bound) {}
|
| +
|
| +void OutputTest::VoEOutputCheckMediaProcess::Process(int channel,
|
| + ProcessingTypes type,
|
| + int16_t* audio10ms,
|
| + size_t length,
|
| + int samplingFreq,
|
| + bool isStereo) {
|
| + if (!enabled_)
|
| + return;
|
| + const int num_channels = isStereo ? 2 : 1;
|
| + for (size_t i = 0; i < length; ++i) {
|
| + for (int c = 0; c < num_channels; ++c) {
|
| + ASSERT_GE(audio10ms[i * num_channels + c], lower_bound_);
|
| + ASSERT_LE(audio10ms[i * num_channels + c], upper_bound_);
|
| + }
|
| + }
|
| +}
|
| +
|
| +TEST(OutputTest, OpusDtxHasNoNoisePump) {
|
| + const int kRuntimeMs = 20000;
|
| + const uint32_t kUnmuteTimeMs = 1000;
|
| + const int kCheckAfterMute = 2000;
|
| + const uint32_t kCheckTimeMs = 2000;
|
| + const int kMinOpusRate = 6000;
|
| + const int kMaxOpusRate = 64000;
|
| +
|
| +#if defined(OPUS_FIXED_POINT)
|
| + const int16_t kDtxBoundForSilence = 20;
|
| +#else
|
| + const int16_t kDtxBoundForSilence = 2;
|
| +#endif
|
| +
|
| + OutputTest test(-kDtxBoundForSilence, kDtxBoundForSilence);
|
| + Random random(1234ull);
|
| +
|
| + uint32_t start_time = rtc::Time();
|
| + test.Start();
|
| + while (rtc::TimeSince(start_time) < kRuntimeMs) {
|
| + webrtc::SleepMs(random.Rand(kUnmuteTimeMs - kUnmuteTimeMs / 10,
|
| + kUnmuteTimeMs + kUnmuteTimeMs / 10));
|
| + test.Mute();
|
| + webrtc::SleepMs(kCheckAfterMute);
|
| + test.EnableOutputCheck();
|
| + webrtc::SleepMs(random.Rand(kCheckTimeMs - kCheckTimeMs / 10,
|
| + kCheckTimeMs + kCheckTimeMs / 10));
|
| + test.DisableOutputCheck();
|
| + test.SetBitRate(random.Rand(kMinOpusRate, kMaxOpusRate));
|
| + test.Unmute();
|
| + }
|
| +}
|
| +
|
| +} // namespace voetest
|
|
|