blob: 03007196374ad2207fda699320adb0470bf25ee6 [file] [log] [blame]
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +00001/*
2 * Copyright (c) 2011 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
Sam Zackrisson9da7c742017-10-30 10:05:10 +010011#include <array>
12
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020013#include "common_audio/resampler/include/resampler.h"
14#include "test/gtest.h"
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000015
16// TODO(andrew): this is a work-in-progress. Many more tests are needed.
17
18namespace webrtc {
19namespace {
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070020
21const int kNumChannels[] = {1, 2};
22const size_t kNumChannelsSize = sizeof(kNumChannels) / sizeof(*kNumChannels);
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000023
24// Rates we must support.
25const int kMaxRate = 96000;
26const int kRates[] = {
27 8000,
28 16000,
29 32000,
30 44000,
31 48000,
32 kMaxRate
33};
34const size_t kRatesSize = sizeof(kRates) / sizeof(*kRates);
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +000035const int kMaxChannels = 2;
36const size_t kDataSize = static_cast<size_t> (kMaxChannels * kMaxRate / 100);
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000037
38// TODO(andrew): should we be supporting these combinations?
39bool ValidRates(int in_rate, int out_rate) {
40 // Not the most compact notation, for clarity.
41 if ((in_rate == 44000 && (out_rate == 48000 || out_rate == 96000)) ||
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +000042 (out_rate == 44000 && (in_rate == 48000 || in_rate == 96000))) {
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000043 return false;
44 }
45
46 return true;
47}
48
49class ResamplerTest : public testing::Test {
50 protected:
51 ResamplerTest();
52 virtual void SetUp();
53 virtual void TearDown();
54
Sam Zackrisson9da7c742017-10-30 10:05:10 +010055 void ResetIfNeededAndPush(int in_rate, int out_rate, int num_channels);
56
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000057 Resampler rs_;
58 int16_t data_in_[kDataSize];
59 int16_t data_out_[kDataSize];
60};
61
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +000062ResamplerTest::ResamplerTest() {}
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000063
bjornv@webrtc.org0edb25d2011-12-13 09:06:54 +000064void ResamplerTest::SetUp() {
65 // Initialize input data with anything. The tests are content independent.
66 memset(data_in_, 1, sizeof(data_in_));
67}
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000068
bjornv@webrtc.org48b68c02011-11-23 13:50:41 +000069void ResamplerTest::TearDown() {}
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000070
Sam Zackrisson9da7c742017-10-30 10:05:10 +010071void ResamplerTest::ResetIfNeededAndPush(int in_rate,
72 int out_rate,
73 int num_channels) {
74 std::ostringstream ss;
75 ss << "Input rate: " << in_rate << ", output rate: " << out_rate
76 << ", channel count: " << num_channels;
77 SCOPED_TRACE(ss.str());
78
79 if (ValidRates(in_rate, out_rate)) {
80 size_t in_length = static_cast<size_t>(in_rate / 100);
81 size_t out_length = 0;
82 EXPECT_EQ(0, rs_.ResetIfNeeded(in_rate, out_rate, num_channels));
83 EXPECT_EQ(0,
84 rs_.Push(data_in_, in_length, data_out_, kDataSize, out_length));
85 EXPECT_EQ(static_cast<size_t>(out_rate / 100), out_length);
86 } else {
87 EXPECT_EQ(-1, rs_.ResetIfNeeded(in_rate, out_rate, num_channels));
88 }
89}
90
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +000091TEST_F(ResamplerTest, Reset) {
92 // The only failure mode for the constructor is if Reset() fails. For the
93 // time being then (until an Init function is added), we rely on Reset()
94 // to test the constructor.
95
96 // Check that all required combinations are supported.
97 for (size_t i = 0; i < kRatesSize; ++i) {
98 for (size_t j = 0; j < kRatesSize; ++j) {
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -070099 for (size_t k = 0; k < kNumChannelsSize; ++k) {
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000100 std::ostringstream ss;
101 ss << "Input rate: " << kRates[i] << ", output rate: " << kRates[j]
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700102 << ", channels: " << kNumChannels[k];
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000103 SCOPED_TRACE(ss.str());
104 if (ValidRates(kRates[i], kRates[j]))
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700105 EXPECT_EQ(0, rs_.Reset(kRates[i], kRates[j], kNumChannels[k]));
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000106 else
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700107 EXPECT_EQ(-1, rs_.Reset(kRates[i], kRates[j], kNumChannels[k]));
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000108 }
109 }
110 }
111}
112
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000113// TODO(tlegrand): Replace code inside the two tests below with a function
114// with number of channels and ResamplerType as input.
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700115TEST_F(ResamplerTest, Mono) {
116 const int kChannels = 1;
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000117 for (size_t i = 0; i < kRatesSize; ++i) {
118 for (size_t j = 0; j < kRatesSize; ++j) {
119 std::ostringstream ss;
120 ss << "Input rate: " << kRates[i] << ", output rate: " << kRates[j];
121 SCOPED_TRACE(ss.str());
122
123 if (ValidRates(kRates[i], kRates[j])) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700124 size_t in_length = static_cast<size_t>(kRates[i] / 100);
125 size_t out_length = 0;
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700126 EXPECT_EQ(0, rs_.Reset(kRates[i], kRates[j], kChannels));
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000127 EXPECT_EQ(0, rs_.Push(data_in_, in_length, data_out_, kDataSize,
128 out_length));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700129 EXPECT_EQ(static_cast<size_t>(kRates[j] / 100), out_length);
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000130 } else {
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700131 EXPECT_EQ(-1, rs_.Reset(kRates[i], kRates[j], kChannels));
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000132 }
133 }
134 }
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000135}
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000136
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700137TEST_F(ResamplerTest, Stereo) {
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000138 const int kChannels = 2;
139 for (size_t i = 0; i < kRatesSize; ++i) {
140 for (size_t j = 0; j < kRatesSize; ++j) {
141 std::ostringstream ss;
142 ss << "Input rate: " << kRates[i] << ", output rate: " << kRates[j];
143 SCOPED_TRACE(ss.str());
144
145 if (ValidRates(kRates[i], kRates[j])) {
Peter Kastingdce40cf2015-08-24 14:52:23 -0700146 size_t in_length = static_cast<size_t>(kChannels * kRates[i] / 100);
147 size_t out_length = 0;
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000148 EXPECT_EQ(0, rs_.Reset(kRates[i], kRates[j],
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700149 kChannels));
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000150 EXPECT_EQ(0, rs_.Push(data_in_, in_length, data_out_, kDataSize,
151 out_length));
Peter Kastingdce40cf2015-08-24 14:52:23 -0700152 EXPECT_EQ(static_cast<size_t>(kChannels * kRates[j] / 100), out_length);
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000153 } else {
154 EXPECT_EQ(-1, rs_.Reset(kRates[i], kRates[j],
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700155 kChannels));
tina.legrand@webrtc.org5c43b1b2011-12-22 08:28:05 +0000156 }
157 }
158 }
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000159}
Andrew MacDonald2c9c83d2015-03-30 10:08:22 -0700160
Sam Zackrisson9da7c742017-10-30 10:05:10 +0100161// Try multiple resets between a few supported and unsupported rates.
162TEST_F(ResamplerTest, MultipleResets) {
163 constexpr size_t kNumChanges = 5;
164 constexpr std::array<int, kNumChanges> kInRates = {
165 {8000, 44000, 44000, 32000, 32000}};
166 constexpr std::array<int, kNumChanges> kOutRates = {
167 {16000, 48000, 48000, 16000, 16000}};
168 constexpr std::array<int, kNumChanges> kNumChannels = {{2, 2, 2, 2, 1}};
169 for (size_t i = 0; i < kNumChanges; ++i) {
170 ResetIfNeededAndPush(kInRates[i], kOutRates[i], kNumChannels[i]);
171 }
172}
173
andrew@webrtc.org19eefdc2011-09-14 17:02:44 +0000174} // namespace
175} // namespace webrtc