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..521ed15c1036c070d0c69773dccaa570eaca7ef1 |
--- /dev/null |
+++ b/webrtc/voice_engine/test/auto_test/voe_output_test.cc |
@@ -0,0 +1,215 @@ |
+/* |
+ * 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/checks.h" |
+#include "webrtc/base/scoped_ptr.h" |
+#include "webrtc/base/timeutils.h" |
+#include "webrtc/system_wrappers/interface/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(); |
+ ~OutputTest(); |
+ |
+ void Start(); |
+ |
+ void EnableOutputCheck(); |
+ void DisableOutputCheck(); |
+ void SetOutputBound(int16_t lower_bound, int16_t upper_bound); |
+ size_t GetOutBoundCount(); |
+ 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(); |
+ void set_enabled(bool enabled) { enabled_ = enabled; } |
+ void set_lower_bound(int16_t lower_bound) { lower_bound_ = lower_bound; } |
+ void set_upper_bound(int16_t upper_bound) { upper_bound_ = upper_bound; } |
+ size_t out_bound_count() const { return out_bound_count_; } |
+ 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_; |
+ size_t out_bound_count_; |
+ }; |
+ |
+ VoETestManager manager_; |
+ VoEOutputCheckMediaProcess output_checker_; |
+ |
+ int channel_; |
+}; |
+ |
+OutputTest::OutputTest() { |
+ RTC_CHECK(manager_.Init()); |
+ manager_.GetInterfaces(); |
+ |
+ VoEBase* base = manager_.BasePtr(); |
+ VoECodec* codec = manager_.CodecPtr(); |
+ VoENetwork* network = manager_.NetworkPtr(); |
+ VoEVolumeControl* volume = manager_.VolumeControlPtr(); |
+ VoEExternalMedia* external = manager_.ExternalMediaPtr(); |
+ |
+ RTC_DCHECK_EQ(0, base->Init()); |
+ |
+ channel_ = base->CreateChannel(); |
+ |
+ // |network| will take care of the life time of |transport|. |
+ VoiceChannelTransport* transport = |
+ new VoiceChannelTransport(network, channel_); |
+ |
+ RTC_DCHECK_EQ(0, transport->SetSendDestination(kIp, kPort)); |
+ RTC_DCHECK_EQ(0, transport->SetLocalReceiver(kPort)); |
+ |
+ RTC_DCHECK_EQ(0, codec->SetSendCodec(channel_, kCodecInst)); |
+ RTC_DCHECK_EQ(0, codec->SetOpusDtx(channel_, true)); |
+ |
+ RTC_DCHECK_EQ(0, volume->SetSpeakerVolume(255)); |
+ |
+ external->RegisterExternalMediaProcessing( |
+ channel_, ProcessingTypes::kPlaybackPerChannel, output_checker_); |
+} |
+ |
+OutputTest::~OutputTest() { |
+ VoENetwork* network = manager_.NetworkPtr(); |
kwiberg-webrtc
2015/10/29 16:35:21
You don't need to bind this to a local variable.
minyue-webrtc
2015/10/30 14:06:46
you mean "manager_.NetworkPtr()->DeRegisterExterna
|
+ RTC_DCHECK_EQ(0, network->DeRegisterExternalTransport(channel_)); |
+ RTC_DCHECK_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; |
+ |
+ VoEFile* file = manager_.FilePtr(); |
+ RTC_DCHECK_EQ( |
+ 0, file->StartPlayingFileAsMicrophone(channel_, file_name.c_str(), true, |
+ false, kInputFormat, 1.0)); |
+ |
+ VoEBase* base = manager_.BasePtr(); |
+ RTC_DCHECK_EQ(0, base->StartPlayout(channel_)); |
+ RTC_DCHECK_EQ(0, base->StartSend(channel_)); |
+} |
+ |
+void OutputTest::EnableOutputCheck() { |
+ output_checker_.set_enabled(true); |
+} |
+ |
+void OutputTest::DisableOutputCheck() { |
+ output_checker_.set_enabled(false); |
+} |
+ |
+void OutputTest::SetOutputBound(int16_t lower_bound, int16_t upper_bound) { |
+ output_checker_.set_lower_bound(lower_bound); |
+ output_checker_.set_upper_bound(upper_bound); |
+} |
+ |
+size_t OutputTest::GetOutBoundCount() { |
+ return output_checker_.out_bound_count(); |
+} |
+ |
+void OutputTest::Mute() { |
+ VoEVolumeControl* volume = manager_.VolumeControlPtr(); |
+ volume->SetInputMute(channel_, true); |
+} |
+ |
+void OutputTest::Unmute() { |
+ VoEVolumeControl* volume = manager_.VolumeControlPtr(); |
+ volume->SetInputMute(channel_, false); |
+} |
+ |
+void OutputTest::SetBitRate(int rate) { |
+ VoECodec* codec = manager_.CodecPtr(); |
+ codec->SetBitRate(channel_, rate); |
+} |
+ |
+OutputTest::VoEOutputCheckMediaProcess::VoEOutputCheckMediaProcess() |
+ : enabled_(false), |
+ lower_bound_(-32768), |
+ upper_bound_(32767), |
+ out_bound_count_(0) {} |
+ |
+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, ++audio10ms) { |
+ if (*audio10ms < lower_bound_ || *audio10ms > upper_bound_) { |
+ ++out_bound_count_; |
+ } |
+ } |
+ } |
+} |
+ |
+TEST(OutputTest, OpusDtxHasNoNoisePump) { |
+ const int kRuntimeMs = 20000; |
+ const int kUnmuteTimeMs = 1000; |
+ const int kCheckAfterMute = 2000; |
+ const int kCheckTimeMs = 2000; |
+ const int kMinOpusRate = 6000; |
+ const int kMaxOpusRate = 64000; |
+ const int16_t kDtxBoundForSilence = 2; |
+ |
+ OutputTest test; |
+ Random random(1234ull); |
+ |
+ uint32_t start_time = rtc::Time(); |
+ test.Start(); |
+ test.SetOutputBound(-kDtxBoundForSilence, kDtxBoundForSilence); |
+ while (rtc::TimeSince(start_time) < kRuntimeMs) { |
+ webrtc::SleepMs(kUnmuteTimeMs + random.Gaussian(0, 100)); |
kwiberg-webrtc
2015/10/29 16:35:21
Replace 100 with e.g. kUnmuteTimeMs/10 here, to ma
minyue-webrtc
2015/10/30 14:06:46
To avoid unlucky, we can use a bounded distributio
|
+ test.Mute(); |
+ webrtc::SleepMs(kCheckAfterMute); |
+ test.EnableOutputCheck(); |
+ webrtc::SleepMs(kCheckTimeMs + random.Gaussian(0, 100)); |
+ test.DisableOutputCheck(); |
+ test.SetBitRate(random.Rand(kMinOpusRate, kMaxOpusRate)); |
+ test.Unmute(); |
+ } |
+ EXPECT_EQ(0u, test.GetOutBoundCount()); |
+} |
+ |
+} // namespace voetest |