blob: 7a887c80ce22aefb3b68d36ec9b5cf9bc554da59 [file] [log] [blame]
Jakob Ivarsson1eb3d7e2019-02-21 15:42:31 +01001/*
2 * Copyright (c) 2019 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#include <cmath>
12
13#include "modules/audio_coding/neteq/histogram.h"
14#include "test/gtest.h"
15
16namespace webrtc {
17
18TEST(HistogramTest, Initialization) {
19 Histogram histogram(65, 32440);
20 histogram.Reset();
21 const auto& buckets = histogram.buckets();
22 double sum = 0.0;
23 for (size_t i = 0; i < buckets.size(); i++) {
24 EXPECT_NEAR(ldexp(std::pow(0.5, static_cast<int>(i + 1)), 30), buckets[i],
25 65537);
26 // Tolerance 65537 in Q30 corresponds to a delta of approximately 0.00006.
27 sum += buckets[i];
28 }
29 EXPECT_EQ(1 << 30, static_cast<int>(sum)); // Should be 1 in Q30.
30}
31
32TEST(HistogramTest, Add) {
33 Histogram histogram(10, 32440);
34 histogram.Reset();
35 const std::vector<int> before = histogram.buckets();
36 const int index = 5;
37 histogram.Add(index);
38 const std::vector<int> after = histogram.buckets();
39 EXPECT_GT(after[index], before[index]);
40 int sum = 0;
41 for (int bucket : after) {
42 sum += bucket;
43 }
44 EXPECT_EQ(1 << 30, sum);
45}
46
47TEST(HistogramTest, ForgetFactor) {
48 Histogram histogram(10, 32440);
49 histogram.Reset();
50 const std::vector<int> before = histogram.buckets();
51 const int index = 4;
52 histogram.Add(index);
53 const std::vector<int> after = histogram.buckets();
54 for (int i = 0; i < histogram.NumBuckets(); ++i) {
55 if (i != index) {
56 EXPECT_LT(after[i], before[i]);
57 }
58 }
59}
60
61// Test if the histogram is scaled correctly if the bucket width is decreased.
62TEST(HistogramTest, DownScale) {
63 // Test a straightforward 60 to 20 change.
64 std::vector<int> buckets = {12, 0, 0, 0, 0, 0};
65 std::vector<int> expected_result = {4, 4, 4, 0, 0, 0};
66 std::vector<int> stretched_buckets = Histogram::ScaleBuckets(buckets, 60, 20);
67 EXPECT_EQ(stretched_buckets, expected_result);
68
69 // Test an example where the last bin in the stretched histogram should
70 // contain the sum of the elements that don't fit into the new histogram.
71 buckets = {18, 15, 12, 9, 6, 3, 0};
72 expected_result = {6, 6, 6, 5, 5, 5, 30};
73 stretched_buckets = Histogram::ScaleBuckets(buckets, 60, 20);
74 EXPECT_EQ(stretched_buckets, expected_result);
75
76 // Test a 120 to 60 change.
77 buckets = {18, 16, 14, 4, 0};
78 expected_result = {9, 9, 8, 8, 18};
79 stretched_buckets = Histogram::ScaleBuckets(buckets, 120, 60);
80 EXPECT_EQ(stretched_buckets, expected_result);
81
82 // Test a 120 to 20 change.
83 buckets = {19, 12, 0, 0, 0, 0, 0, 0};
84 expected_result = {3, 3, 3, 3, 3, 3, 2, 11};
85 stretched_buckets = Histogram::ScaleBuckets(buckets, 120, 20);
86 EXPECT_EQ(stretched_buckets, expected_result);
87
88 // Test a 70 to 40 change.
89 buckets = {13, 7, 5, 3, 1, 5, 12, 11, 3, 0, 0, 0};
90 expected_result = {7, 5, 5, 3, 3, 2, 2, 1, 2, 2, 6, 22};
91 stretched_buckets = Histogram::ScaleBuckets(buckets, 70, 40);
92 EXPECT_EQ(stretched_buckets, expected_result);
93
94 // Test a 30 to 20 change.
95 buckets = {13, 7, 5, 3, 1, 5, 12, 11, 3, 0, 0, 0};
96 expected_result = {8, 6, 6, 3, 2, 2, 1, 3, 3, 8, 7, 11};
97 stretched_buckets = Histogram::ScaleBuckets(buckets, 30, 20);
98 EXPECT_EQ(stretched_buckets, expected_result);
99}
100
101// Test if the histogram is scaled correctly if the bucket width is increased.
102TEST(HistogramTest, UpScale) {
103 // Test a 20 to 60 change.
104 std::vector<int> buckets = {12, 11, 10, 3, 2, 1};
105 std::vector<int> expected_result = {33, 6, 0, 0, 0, 0};
106 std::vector<int> compressed_buckets =
107 Histogram::ScaleBuckets(buckets, 20, 60);
108 EXPECT_EQ(compressed_buckets, expected_result);
109
110 // Test a 60 to 120 change.
111 buckets = {18, 16, 14, 4, 1};
112 expected_result = {34, 18, 1, 0, 0};
113 compressed_buckets = Histogram::ScaleBuckets(buckets, 60, 120);
114 EXPECT_EQ(compressed_buckets, expected_result);
115
116 // Test a 20 to 120 change.
117 buckets = {18, 12, 5, 4, 4, 3, 5, 1};
118 expected_result = {46, 6, 0, 0, 0, 0, 0, 0};
119 compressed_buckets = Histogram::ScaleBuckets(buckets, 20, 120);
120 EXPECT_EQ(compressed_buckets, expected_result);
121
122 // Test a 70 to 80 change.
123 buckets = {13, 7, 5, 3, 1, 5, 12, 11, 3};
124 expected_result = {11, 8, 6, 2, 5, 12, 13, 3, 0};
125 compressed_buckets = Histogram::ScaleBuckets(buckets, 70, 80);
126 EXPECT_EQ(compressed_buckets, expected_result);
127
128 // Test a 50 to 110 change.
129 buckets = {13, 7, 5, 3, 1, 5, 12, 11, 3};
130 expected_result = {18, 8, 16, 16, 2, 0, 0, 0, 0};
131 compressed_buckets = Histogram::ScaleBuckets(buckets, 50, 110);
132 EXPECT_EQ(compressed_buckets, expected_result);
133}
134
135// Test if the histogram scaling function handles overflows correctly.
136TEST(HistogramTest, OverflowTest) {
137 // Test a upscale operation that can cause overflow.
138 std::vector<int> buckets = {733544448, 0, 0, 0, 0, 0, 0,
139 340197376, 0, 0, 0, 0, 0, 0};
140 std::vector<int> expected_result = {733544448, 340197376, 0, 0, 0, 0, 0,
141 0, 0, 0, 0, 0, 0, 0};
142 std::vector<int> scaled_buckets = Histogram::ScaleBuckets(buckets, 10, 60);
143 EXPECT_EQ(scaled_buckets, expected_result);
144
145 buckets = {655591163, 39962288, 360736736, 1930514, 4003853, 1782764,
146 114119, 2072996, 0, 2149354, 0};
147 expected_result = {1056290187, 7717131, 2187115, 2149354, 0, 0,
148 0, 0, 0, 0, 0};
149 scaled_buckets = Histogram::ScaleBuckets(buckets, 20, 60);
150 EXPECT_EQ(scaled_buckets, expected_result);
151
152 // In this test case we will not be able to add everything to the final bin in
153 // the scaled histogram. Check that the last bin doesn't overflow.
154 buckets = {2000000000, 2000000000, 2000000000,
155 2000000000, 2000000000, 2000000000};
156 expected_result = {666666666, 666666666, 666666666,
157 666666667, 666666667, 2147483647};
158 scaled_buckets = Histogram::ScaleBuckets(buckets, 60, 20);
159 EXPECT_EQ(scaled_buckets, expected_result);
160
161 // In this test case we will not be able to add enough to each of the bins,
162 // so the values should be smeared out past the end of the normal range.
163 buckets = {2000000000, 2000000000, 2000000000,
164 2000000000, 2000000000, 2000000000};
165 expected_result = {2147483647, 2147483647, 2147483647,
166 2147483647, 2147483647, 1262581765};
167 scaled_buckets = Histogram::ScaleBuckets(buckets, 20, 60);
168 EXPECT_EQ(scaled_buckets, expected_result);
169}
170
171} // namespace webrtc