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 DecisionLogic class and derived classes.
12
13 #include "modules/audio_coding/neteq/decision_logic.h"
14
15 #include "api/neteq/neteq_controller.h"
16 #include "api/neteq/tick_timer.h"
17 #include "modules/audio_coding/neteq/buffer_level_filter.h"
18 #include "modules/audio_coding/neteq/delay_manager.h"
19 #include "modules/audio_coding/neteq/mock/mock_buffer_level_filter.h"
20 #include "modules/audio_coding/neteq/mock/mock_delay_manager.h"
21 #include "test/gtest.h"
22
23 namespace webrtc {
24
25 namespace {
26
27 constexpr int kSampleRate = 8000;
28 constexpr int kSamplesPerMs = kSampleRate / 1000;
29 constexpr int kOutputSizeSamples = kSamplesPerMs * 10;
30 constexpr int kMinTimescaleInterval = 5;
31
CreateNetEqStatus(NetEq::Mode last_mode,int current_delay_ms)32 NetEqController::NetEqStatus CreateNetEqStatus(NetEq::Mode last_mode,
33 int current_delay_ms) {
34 NetEqController::NetEqStatus status;
35 status.play_dtmf = false;
36 status.last_mode = last_mode;
37 status.target_timestamp = 1234;
38 status.generated_noise_samples = 0;
39 status.expand_mutefactor = 0;
40 status.packet_buffer_info.num_samples = current_delay_ms * kSamplesPerMs;
41 status.packet_buffer_info.span_samples = current_delay_ms * kSamplesPerMs;
42 status.packet_buffer_info.span_samples_no_dtx =
43 current_delay_ms * kSamplesPerMs;
44 status.packet_buffer_info.dtx_or_cng = false;
45 status.next_packet = {status.target_timestamp, false, false};
46 return status;
47 }
48
49 using ::testing::Return;
50
51 } // namespace
52
53 class DecisionLogicTest : public ::testing::Test {
54 protected:
DecisionLogicTest()55 DecisionLogicTest() {
56 NetEqController::Config config;
57 config.tick_timer = &tick_timer_;
58 config.allow_time_stretching = true;
59 auto delay_manager = std::make_unique<MockDelayManager>(
60 DelayManager::Config(), config.tick_timer);
61 mock_delay_manager_ = delay_manager.get();
62 auto buffer_level_filter = std::make_unique<MockBufferLevelFilter>();
63 mock_buffer_level_filter_ = buffer_level_filter.get();
64 decision_logic_ = std::make_unique<DecisionLogic>(
65 config, std::move(delay_manager), std::move(buffer_level_filter));
66 decision_logic_->SetSampleRate(kSampleRate, kOutputSizeSamples);
67 }
68
69 TickTimer tick_timer_;
70 std::unique_ptr<DecisionLogic> decision_logic_;
71 MockDelayManager* mock_delay_manager_;
72 MockBufferLevelFilter* mock_buffer_level_filter_;
73 };
74
TEST_F(DecisionLogicTest,NormalOperation)75 TEST_F(DecisionLogicTest, NormalOperation) {
76 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
77 .WillRepeatedly(Return(100));
78 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
79 .WillRepeatedly(Return(90 * kSamplesPerMs));
80
81 bool reset_decoder = false;
82 tick_timer_.Increment(kMinTimescaleInterval + 1);
83 EXPECT_EQ(decision_logic_->GetDecision(
84 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
85 NetEq::Operation::kNormal);
86 EXPECT_FALSE(reset_decoder);
87 }
88
TEST_F(DecisionLogicTest,Accelerate)89 TEST_F(DecisionLogicTest, Accelerate) {
90 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
91 .WillRepeatedly(Return(100));
92 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
93 .WillRepeatedly(Return(110 * kSamplesPerMs));
94
95 bool reset_decoder = false;
96 tick_timer_.Increment(kMinTimescaleInterval + 1);
97 EXPECT_EQ(decision_logic_->GetDecision(
98 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
99 NetEq::Operation::kAccelerate);
100 EXPECT_FALSE(reset_decoder);
101 }
102
TEST_F(DecisionLogicTest,FastAccelerate)103 TEST_F(DecisionLogicTest, FastAccelerate) {
104 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
105 .WillRepeatedly(Return(100));
106 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
107 .WillRepeatedly(Return(400 * kSamplesPerMs));
108
109 bool reset_decoder = false;
110 tick_timer_.Increment(kMinTimescaleInterval + 1);
111 EXPECT_EQ(decision_logic_->GetDecision(
112 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
113 NetEq::Operation::kFastAccelerate);
114 EXPECT_FALSE(reset_decoder);
115 }
116
TEST_F(DecisionLogicTest,PreemptiveExpand)117 TEST_F(DecisionLogicTest, PreemptiveExpand) {
118 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
119 .WillRepeatedly(Return(100));
120 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
121 .WillRepeatedly(Return(50 * kSamplesPerMs));
122
123 bool reset_decoder = false;
124 tick_timer_.Increment(kMinTimescaleInterval + 1);
125 EXPECT_EQ(decision_logic_->GetDecision(
126 CreateNetEqStatus(NetEq::Mode::kNormal, 100), &reset_decoder),
127 NetEq::Operation::kPreemptiveExpand);
128 EXPECT_FALSE(reset_decoder);
129 }
130
TEST_F(DecisionLogicTest,DecelerationTargetLevelOffset)131 TEST_F(DecisionLogicTest, DecelerationTargetLevelOffset) {
132 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
133 .WillRepeatedly(Return(500));
134 EXPECT_CALL(*mock_buffer_level_filter_, filtered_current_level())
135 .WillRepeatedly(Return(400 * kSamplesPerMs));
136
137 bool reset_decoder = false;
138 tick_timer_.Increment(kMinTimescaleInterval + 1);
139 EXPECT_EQ(decision_logic_->GetDecision(
140 CreateNetEqStatus(NetEq::Mode::kNormal, 400), &reset_decoder),
141 NetEq::Operation::kPreemptiveExpand);
142 EXPECT_FALSE(reset_decoder);
143 }
144
TEST_F(DecisionLogicTest,PostponeDecodeAfterExpand)145 TEST_F(DecisionLogicTest, PostponeDecodeAfterExpand) {
146 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
147 .WillRepeatedly(Return(500));
148
149 // Below 50% target delay threshold.
150 bool reset_decoder = false;
151 EXPECT_EQ(decision_logic_->GetDecision(
152 CreateNetEqStatus(NetEq::Mode::kExpand, 200), &reset_decoder),
153 NetEq::Operation::kExpand);
154 EXPECT_FALSE(reset_decoder);
155
156 // Above 50% target delay threshold.
157 EXPECT_EQ(decision_logic_->GetDecision(
158 CreateNetEqStatus(NetEq::Mode::kExpand, 250), &reset_decoder),
159 NetEq::Operation::kNormal);
160 EXPECT_FALSE(reset_decoder);
161 }
162
TEST_F(DecisionLogicTest,TimeStrechComfortNoise)163 TEST_F(DecisionLogicTest, TimeStrechComfortNoise) {
164 EXPECT_CALL(*mock_delay_manager_, TargetDelayMs())
165 .WillRepeatedly(Return(500));
166
167 {
168 bool reset_decoder = false;
169 // Below target window.
170 auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 400);
171 status.generated_noise_samples = 400 * kSamplesPerMs;
172 status.next_packet->timestamp =
173 status.target_timestamp + 400 * kSamplesPerMs;
174 EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
175 NetEq::Operation::kCodecInternalCng);
176 EXPECT_FALSE(reset_decoder);
177 }
178
179 {
180 bool reset_decoder = false;
181 // Above target window.
182 auto status = CreateNetEqStatus(NetEq::Mode::kCodecInternalCng, 600);
183 status.generated_noise_samples = 200 * kSamplesPerMs;
184 status.next_packet->timestamp =
185 status.target_timestamp + 400 * kSamplesPerMs;
186 EXPECT_EQ(decision_logic_->GetDecision(status, &reset_decoder),
187 NetEq::Operation::kNormal);
188 EXPECT_FALSE(reset_decoder);
189
190 // The buffer level filter should be adjusted with the number of samples
191 // that was skipped.
192 int timestamp_leap = status.next_packet->timestamp -
193 status.target_timestamp -
194 status.generated_noise_samples;
195 EXPECT_CALL(*mock_buffer_level_filter_,
196 Update(400 * kSamplesPerMs, timestamp_leap));
197 EXPECT_EQ(decision_logic_->GetDecision(
198 CreateNetEqStatus(NetEq::Mode::kNormal, 400), &reset_decoder),
199 NetEq::Operation::kNormal);
200 EXPECT_FALSE(reset_decoder);
201 }
202 }
203
204 } // namespace webrtc
205