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