OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include <cmath> | |
6 | |
7 #include "base/logging.h" | |
8 #include "base/memory/scoped_ptr.h" | |
9 #include "media/base/multi_channel_resampler.h" | |
10 #include "testing/gtest/include/gtest/gtest.h" | |
11 | |
12 namespace media { | |
13 | |
14 // Just test a basic resampling case. The SincResampler unit test will take | |
15 // care of accuracy testing; we just need to check that multichannel works as | |
16 // expected within some tolerance. | |
17 static const float kScaleFactor = 44100.0 / 48000.0; | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
probably need 'f's to disambiguate double-vs-float
DaleCurtis
2012/07/03 03:02:57
Done.
| |
18 | |
19 // Simulate large and small sample requests used by the different audio paths. | |
20 static const int kHighLatencySize = 8192; | |
21 // Low latency buffers show a larger error than high latency ones. Which makes | |
22 // sense since each error represents a larger portion of the total request. | |
23 static const int kLowLatencySize = 128; | |
24 | |
25 // Test fill value. | |
26 static const float kFillValue = 0.1; | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
needs 'f' suffix
DaleCurtis
2012/07/03 03:02:57
Done.
| |
27 | |
28 // Chosen arbitrarily on what each resampler reported during testing. | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
s/on/based on/
DaleCurtis
2012/07/03 03:02:57
Done.
| |
29 static const double kLowLatencyMaxRMSError = 0.001; | |
30 static const double kLowLatencyMaxError = 0.0068; | |
31 static const double kHighLatencyMaxRMSError = 0.00013; | |
32 static const double kHighLatencyMaxError = 0.0068; | |
33 | |
34 | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
extra \n
DaleCurtis
2012/07/03 03:02:57
Done.
| |
35 class MultiChannelProviderTest | |
36 : public MultiChannelResampler::MultiChannelAudioSourceProvider, | |
37 public ::testing::Test { | |
38 public: | |
39 MultiChannelProviderTest() {} | |
40 virtual ~MultiChannelProviderTest() { | |
41 if (!audio_data_.empty()) { | |
42 for (size_t i = 0; i < audio_data_.size(); ++i) | |
43 delete [] audio_data_[i]; | |
44 audio_data_.clear(); | |
45 } | |
46 } | |
47 | |
48 void InitializeAudioData(int channels, int frames) { | |
49 frames_ = frames; | |
50 audio_data_.reserve(channels); | |
51 for (int i = 0; i < channels; ++i) { | |
52 audio_data_.push_back(new float[frames]); | |
53 | |
54 // Zero initialize so we can be sure every value has been provided. | |
55 memset(audio_data_[i], 0, sizeof(*audio_data_[i]) * frames); | |
56 } | |
57 } | |
58 | |
59 // MultiChannelResampler::MultiChannelAudioSourceProvider implementation, just | |
60 // fills the provided audio_data with |kFillValue|. | |
61 virtual void ProvideInput(const std::vector<float*>& audio_data, | |
62 int number_of_frames) OVERRIDE { | |
63 EXPECT_EQ(audio_data.size(), audio_data_.size()); | |
64 for (size_t i = 0; i < audio_data.size(); ++i) | |
65 for (int j = 0; j < number_of_frames; ++j) | |
66 audio_data[i][j] = kFillValue; | |
67 } | |
68 | |
69 void MultiChannelTest(int channels, int frames, double expected_max_rms_error, | |
70 double expected_max_error) { | |
71 InitializeAudioData(channels, frames); | |
72 scoped_ptr<MultiChannelResampler> resampler(new MultiChannelResampler( | |
73 this, kScaleFactor, channels)); | |
74 resampler->Resample(audio_data_, frames); | |
75 TestValues(expected_max_rms_error, expected_max_error); | |
76 } | |
77 | |
78 void HighLatencyTest(int channels) { | |
79 MultiChannelTest(channels, kHighLatencySize, kHighLatencyMaxRMSError, | |
80 kHighLatencyMaxError); | |
81 } | |
82 | |
83 void LowLatencyTest(int channels) { | |
84 MultiChannelTest(channels, kLowLatencySize, kLowLatencyMaxRMSError, | |
85 kLowLatencyMaxError); | |
86 } | |
87 | |
88 void TestValues(double expected_max_rms_error, double expected_max_error ) { | |
89 // Calculate Root-Mean-Square-Error for the resampling. | |
90 double max_error = 0.0; | |
91 double sum_of_squares = 0.0; | |
92 for (size_t i = 0; i < audio_data_.size(); ++i) { | |
93 for (int j = 0; j < frames_; ++j) { | |
94 // Ensure all values are accounted for. | |
95 ASSERT_NE(audio_data_[i][j], 0); | |
96 | |
97 double error = fabs(audio_data_[i][j] - kFillValue); | |
98 max_error = std::max(max_error, error); | |
99 sum_of_squares += error * error; | |
100 } | |
101 } | |
102 | |
103 double rms_error = sqrt( | |
104 sum_of_squares / (frames_ * audio_data_.size())); | |
105 | |
106 EXPECT_LE(rms_error, expected_max_rms_error); | |
107 EXPECT_LE(max_error, expected_max_error); | |
108 } | |
109 | |
110 protected: | |
111 int frames_; | |
112 std::vector<float*> audio_data_; | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
scoped* to avoid dtor work
DaleCurtis
2012/07/03 03:02:57
Can't due to RenderCallback interface.
| |
113 | |
114 DISALLOW_COPY_AND_ASSIGN(MultiChannelProviderTest); | |
115 }; | |
116 | |
117 TEST_F(MultiChannelProviderTest, MultiChannel_1_HighLatency) { | |
Ami GONE FROM CHROMIUM
2012/06/30 20:12:14
Any reason not to use parameterized gtest?
DaleCurtis
2012/07/03 03:02:57
Done.
| |
118 HighLatencyTest(1); | |
119 } | |
120 | |
121 TEST_F(MultiChannelProviderTest, MultiChannel_2_HighLatency) { | |
122 HighLatencyTest(2); | |
123 } | |
124 | |
125 TEST_F(MultiChannelProviderTest, MultiChannel_6_HighLatency) { | |
126 HighLatencyTest(6); | |
127 } | |
128 | |
129 TEST_F(MultiChannelProviderTest, MultiChannel_8_HighLatency) { | |
130 HighLatencyTest(8); | |
131 } | |
132 | |
133 TEST_F(MultiChannelProviderTest, MultiChannel_1_LowLatency) { | |
134 LowLatencyTest(1); | |
135 } | |
136 | |
137 TEST_F(MultiChannelProviderTest, MultiChannel_2_LowLatency) { | |
138 LowLatencyTest(2); | |
139 } | |
140 | |
141 TEST_F(MultiChannelProviderTest, MultiChannel_6_LowLatency) { | |
142 LowLatencyTest(6); | |
143 } | |
144 | |
145 TEST_F(MultiChannelProviderTest, MultiChannel_8_LowLatency) { | |
146 LowLatencyTest(8); | |
147 } | |
148 | |
149 } // namespace media | |
OLD | NEW |