xref: /aosp_15_r20/external/webrtc/modules/audio_coding/neteq/decision_logic_unittest.cc (revision d9f758449e529ab9291ac668be2861e7a55c2422)
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