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 DelayPeakDetector class.
12d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
139c55f0f957534144d2b8a64154f0a479249b34behenrik.lundin@webrtc.org#include "webrtc/modules/audio_coding/neteq/delay_peak_detector.h"
14d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
153c0aae17f0e3a70fe90ecc6835926b66a3de18fbkjellander@webrtc.org#include "testing/gtest/include/gtest/gtest.h"
16d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
17d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgnamespace webrtc {
18d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
19d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgTEST(DelayPeakDetector, CreateAndDestroy) {
20d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DelayPeakDetector* detector = new DelayPeakDetector();
21d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  EXPECT_FALSE(detector->peak_found());
22d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  delete detector;
23d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
24d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
25d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgTEST(DelayPeakDetector, EmptyHistory) {
26d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DelayPeakDetector detector;
27d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  EXPECT_EQ(-1, detector.MaxPeakHeight());
28d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  EXPECT_EQ(-1, detector.MaxPeakPeriod());
29d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
30d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
31d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Inject a series of packet arrivals into the detector. Three of the packets
32d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// have suffered delays. After the third delay peak, peak-mode is expected to
33d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// start. This should then continue until it is disengaged due to lack of peaks.
34d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgTEST(DelayPeakDetector, TriggerPeakMode) {
35d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DelayPeakDetector detector;
36d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kPacketSizeMs = 30;
37d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  detector.SetPacketAudioLength(kPacketSizeMs);
38d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
39d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Load up normal arrival times; 0 ms, 30 ms, 60 ms, 90 ms, ...
40d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kNumPackets = 1000;
41d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int arrival_times_ms[kNumPackets];
42d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  for (int i = 0; i < kNumPackets; ++i) {
43d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    arrival_times_ms[i] = i * kPacketSizeMs;
44d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
45d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
46d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Delay three packets.
47d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kPeakDelayMs = 100;
48d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // First delay peak.
49d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[100] += kPeakDelayMs;
50d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Second delay peak.
51d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[200] += kPeakDelayMs;
52d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Third delay peak. Trigger peak-mode after this packet.
53d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[400] += kPeakDelayMs;
54d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // The second peak period is the longest, 200 packets.
55d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kWorstPeakPeriod = 200 * kPacketSizeMs;
56d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int peak_mode_start_ms = arrival_times_ms[400];
57d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Expect to disengage after no peaks are observed for two period times.
58d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int peak_mode_end_ms = peak_mode_start_ms + 2 * kWorstPeakPeriod;
59d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
60d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Load into detector.
61d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int time = 0;
62d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int next = 1;  // Start with the second packet to get a proper IAT.
63d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (next < kNumPackets) {
6463464a935415ee0cd485bab84e763294e7201a35henrik.lundin@webrtc.org    while (next < kNumPackets && arrival_times_ms[next] <= time) {
65d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      int iat_packets = (arrival_times_ms[next] - arrival_times_ms[next - 1]) /
66d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org          kPacketSizeMs;
67d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      const int kTargetBufferLevel = 1;  // Define peaks to be iat > 2.
68d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      if (time < peak_mode_start_ms || time > peak_mode_end_ms) {
69d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        EXPECT_FALSE(detector.Update(iat_packets, kTargetBufferLevel));
70d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      } else {
71d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        EXPECT_TRUE(detector.Update(iat_packets, kTargetBufferLevel));
72d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        EXPECT_EQ(kWorstPeakPeriod, detector.MaxPeakPeriod());
73d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org        EXPECT_EQ(kPeakDelayMs / kPacketSizeMs + 1, detector.MaxPeakHeight());
74d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      }
75d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      ++next;
76d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
77d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    detector.IncrementCounter(10);
78d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    time += 10;  // Increase time 10 ms.
79d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
80d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
81d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
82d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// Same test as TriggerPeakMode, but with base target buffer level increased to
83d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// 2, in order to raise the bar for delay peaks to inter-arrival times > 4.
84d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org// The delay pattern has peaks with delay = 3, thus should not trigger.
85d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.orgTEST(DelayPeakDetector, DoNotTriggerPeakMode) {
86d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  DelayPeakDetector detector;
87d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kPacketSizeMs = 30;
88d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  detector.SetPacketAudioLength(kPacketSizeMs);
89d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
90d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Load up normal arrival times; 0 ms, 30 ms, 60 ms, 90 ms, ...
91d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kNumPackets = 1000;
92d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int arrival_times_ms[kNumPackets];
93d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  for (int i = 0; i < kNumPackets; ++i) {
94d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    arrival_times_ms[i] = i * kPacketSizeMs;
95d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
96d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
97d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Delay three packets.
98d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  const int kPeakDelayMs = 100;
99d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // First delay peak.
100d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[100] += kPeakDelayMs;
101d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Second delay peak.
102d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[200] += kPeakDelayMs;
103d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Third delay peak.
104d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  arrival_times_ms[400] += kPeakDelayMs;
105d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org
106d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  // Load into detector.
107d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int time = 0;
108d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  int next = 1;  // Start with the second packet to get a proper IAT.
109d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  while (next < kNumPackets) {
11063464a935415ee0cd485bab84e763294e7201a35henrik.lundin@webrtc.org    while (next < kNumPackets && arrival_times_ms[next] <= time) {
111d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      int iat_packets = (arrival_times_ms[next] - arrival_times_ms[next - 1]) /
112d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org          kPacketSizeMs;
113d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      const int kTargetBufferLevel = 2;  // Define peaks to be iat > 4.
114d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      EXPECT_FALSE(detector.Update(iat_packets, kTargetBufferLevel));
115d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org      ++next;
116d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    }
117d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    detector.IncrementCounter(10);
118d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org    time += 10;  // Increase time 10 ms.
119d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org  }
120d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}
121d94659dc279b86376c1a6470dc326fd342caaa93henrik.lundin@webrtc.org}  // namespace webrtc
122