1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 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 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 // Unit tests for Expand class. 12 13 #include "webrtc/modules/audio_coding/neteq/expand.h" 14 15 #include "testing/gtest/include/gtest/gtest.h" 16 #include "webrtc/base/safe_conversions.h" 17 #include "webrtc/common_audio/signal_processing/include/signal_processing_library.h" 18 #include "webrtc/modules/audio_coding/neteq/background_noise.h" 19 #include "webrtc/modules/audio_coding/neteq/random_vector.h" 20 #include "webrtc/modules/audio_coding/neteq/statistics_calculator.h" 21 #include "webrtc/modules/audio_coding/neteq/sync_buffer.h" 22 #include "webrtc/modules/audio_coding/neteq/tools/resample_input_audio_file.h" 23 #include "webrtc/test/testsupport/fileutils.h" 24 25 namespace webrtc { 26 27 TEST(Expand, CreateAndDestroy) { 28 int fs = 8000; 29 size_t channels = 1; 30 BackgroundNoise bgn(channels); 31 SyncBuffer sync_buffer(1, 1000); 32 RandomVector random_vector; 33 StatisticsCalculator statistics; 34 Expand expand(&bgn, &sync_buffer, &random_vector, &statistics, fs, channels); 35 } 36 37 TEST(Expand, CreateUsingFactory) { 38 int fs = 8000; 39 size_t channels = 1; 40 BackgroundNoise bgn(channels); 41 SyncBuffer sync_buffer(1, 1000); 42 RandomVector random_vector; 43 StatisticsCalculator statistics; 44 ExpandFactory expand_factory; 45 Expand* expand = expand_factory.Create(&bgn, &sync_buffer, &random_vector, 46 &statistics, fs, channels); 47 EXPECT_TRUE(expand != NULL); 48 delete expand; 49 } 50 51 namespace { 52 class FakeStatisticsCalculator : public StatisticsCalculator { 53 public: 54 void LogDelayedPacketOutageEvent(int outage_duration_ms) override { 55 last_outage_duration_ms_ = outage_duration_ms; 56 } 57 58 int last_outage_duration_ms() const { return last_outage_duration_ms_; } 59 60 private: 61 int last_outage_duration_ms_ = 0; 62 }; 63 64 // This is the same size that is given to the SyncBuffer object in NetEq. 65 const size_t kNetEqSyncBufferLengthMs = 720; 66 } // namespace 67 68 class ExpandTest : public ::testing::Test { 69 protected: 70 ExpandTest() 71 : input_file_(test::ResourcePath("audio_coding/testfile32kHz", "pcm"), 72 32000), 73 test_sample_rate_hz_(32000), 74 num_channels_(1), 75 background_noise_(num_channels_), 76 sync_buffer_(num_channels_, 77 kNetEqSyncBufferLengthMs * test_sample_rate_hz_ / 1000), 78 expand_(&background_noise_, 79 &sync_buffer_, 80 &random_vector_, 81 &statistics_, 82 test_sample_rate_hz_, 83 num_channels_) { 84 WebRtcSpl_Init(); 85 input_file_.set_output_rate_hz(test_sample_rate_hz_); 86 } 87 88 void SetUp() override { 89 // Fast-forward the input file until there is speech (about 1.1 second into 90 // the file). 91 const size_t speech_start_samples = 92 static_cast<size_t>(test_sample_rate_hz_ * 1.1f); 93 ASSERT_TRUE(input_file_.Seek(speech_start_samples)); 94 95 // Pre-load the sync buffer with speech data. 96 ASSERT_TRUE( 97 input_file_.Read(sync_buffer_.Size(), &sync_buffer_.Channel(0)[0])); 98 ASSERT_EQ(1u, num_channels_) << "Fix: Must populate all channels."; 99 } 100 101 test::ResampleInputAudioFile input_file_; 102 int test_sample_rate_hz_; 103 size_t num_channels_; 104 BackgroundNoise background_noise_; 105 SyncBuffer sync_buffer_; 106 RandomVector random_vector_; 107 FakeStatisticsCalculator statistics_; 108 Expand expand_; 109 }; 110 111 // This test calls the expand object to produce concealment data a few times, 112 // and then ends by calling SetParametersForNormalAfterExpand. This simulates 113 // the situation where the packet next up for decoding was just delayed, not 114 // lost. 115 TEST_F(ExpandTest, DelayedPacketOutage) { 116 AudioMultiVector output(num_channels_); 117 size_t sum_output_len_samples = 0; 118 for (int i = 0; i < 10; ++i) { 119 EXPECT_EQ(0, expand_.Process(&output)); 120 EXPECT_GT(output.Size(), 0u); 121 sum_output_len_samples += output.Size(); 122 EXPECT_EQ(0, statistics_.last_outage_duration_ms()); 123 } 124 expand_.SetParametersForNormalAfterExpand(); 125 // Convert |sum_output_len_samples| to milliseconds. 126 EXPECT_EQ(rtc::checked_cast<int>(sum_output_len_samples / 127 (test_sample_rate_hz_ / 1000)), 128 statistics_.last_outage_duration_ms()); 129 } 130 131 // This test is similar to DelayedPacketOutage, but ends by calling 132 // SetParametersForMergeAfterExpand. This simulates the situation where the 133 // packet next up for decoding was actually lost (or at least a later packet 134 // arrived before it). 135 TEST_F(ExpandTest, LostPacketOutage) { 136 AudioMultiVector output(num_channels_); 137 size_t sum_output_len_samples = 0; 138 for (int i = 0; i < 10; ++i) { 139 EXPECT_EQ(0, expand_.Process(&output)); 140 EXPECT_GT(output.Size(), 0u); 141 sum_output_len_samples += output.Size(); 142 EXPECT_EQ(0, statistics_.last_outage_duration_ms()); 143 } 144 expand_.SetParametersForMergeAfterExpand(); 145 EXPECT_EQ(0, statistics_.last_outage_duration_ms()); 146 } 147 148 // This test is similar to the DelayedPacketOutage test above, but with the 149 // difference that Expand::Reset() is called after 5 calls to Expand::Process(). 150 // This should reset the statistics, and will in the end lead to an outage of 151 // 5 periods instead of 10. 152 TEST_F(ExpandTest, CheckOutageStatsAfterReset) { 153 AudioMultiVector output(num_channels_); 154 size_t sum_output_len_samples = 0; 155 for (int i = 0; i < 10; ++i) { 156 EXPECT_EQ(0, expand_.Process(&output)); 157 EXPECT_GT(output.Size(), 0u); 158 sum_output_len_samples += output.Size(); 159 if (i == 5) { 160 expand_.Reset(); 161 sum_output_len_samples = 0; 162 } 163 EXPECT_EQ(0, statistics_.last_outage_duration_ms()); 164 } 165 expand_.SetParametersForNormalAfterExpand(); 166 // Convert |sum_output_len_samples| to milliseconds. 167 EXPECT_EQ(rtc::checked_cast<int>(sum_output_len_samples / 168 (test_sample_rate_hz_ / 1000)), 169 statistics_.last_outage_duration_ms()); 170 } 171 172 // TODO(hlundin): Write more tests. 173 174 } // namespace webrtc 175