Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / media / base / audio_buffer_converter_unittest.cc
1 // Copyright 2014 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 "base/memory/scoped_ptr.h"
6 #include "media/base/audio_buffer.h"
7 #include "media/base/audio_buffer_converter.h"
8 #include "media/base/sinc_resampler.h"
9 #include "media/base/test_helpers.h"
10 #include "testing/gmock/include/gmock/gmock.h"
11 #include "testing/gtest/include/gtest/gtest.h"
12
13 namespace media {
14
15 // Important: Use an odd buffer size here so SIMD issues are caught.
16 const int kOutFrameSize = 441;
17 const int kOutSampleRate = 44100;
18 const ChannelLayout kOutChannelLayout = CHANNEL_LAYOUT_STEREO;
19 const int kOutChannelCount = 2;
20
21 static scoped_refptr<AudioBuffer> MakeTestBuffer(int sample_rate,
22                                                  ChannelLayout channel_layout,
23                                                  int channel_count,
24                                                  int frames) {
25   return MakeAudioBuffer<uint8>(kSampleFormatU8,
26                                 channel_layout,
27                                 channel_count,
28                                 sample_rate,
29                                 0,
30                                 1,
31                                 frames,
32                                 base::TimeDelta::FromSeconds(0));
33 }
34
35 class AudioBufferConverterTest : public ::testing::Test {
36  public:
37   AudioBufferConverterTest()
38       : input_frames_(0),
39         expected_output_frames_(0.0),
40         output_frames_(0),
41         output_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY,
42                        kOutChannelLayout,
43                        kOutSampleRate,
44                        16,
45                        kOutFrameSize) {
46     audio_buffer_converter_.reset(new AudioBufferConverter(output_params_));
47   }
48
49   void Reset() {
50     audio_buffer_converter_->Reset();
51     output_frames_ = expected_output_frames_ = input_frames_ = 0;
52   }
53
54   void AddInput(const scoped_refptr<AudioBuffer>& in) {
55     if (!in->end_of_stream()) {
56       input_frames_ += in->frame_count();
57       expected_output_frames_ +=
58           in->frame_count() *
59           (static_cast<double>(output_params_.sample_rate()) /
60            in->sample_rate());
61     }
62     audio_buffer_converter_->AddInput(in);
63   }
64
65   void ConsumeOutput() {
66     ASSERT_TRUE(audio_buffer_converter_->HasNextBuffer());
67     scoped_refptr<AudioBuffer> out = audio_buffer_converter_->GetNextBuffer();
68     if (!out->end_of_stream()) {
69       output_frames_ += out->frame_count();
70       EXPECT_EQ(out->sample_rate(), output_params_.sample_rate());
71       EXPECT_EQ(out->channel_layout(), output_params_.channel_layout());
72       EXPECT_EQ(out->channel_count(), output_params_.channels());
73     } else {
74       EXPECT_FALSE(audio_buffer_converter_->HasNextBuffer());
75     }
76   }
77
78   void ConsumeAllOutput() {
79     AddInput(AudioBuffer::CreateEOSBuffer());
80     while (audio_buffer_converter_->HasNextBuffer())
81       ConsumeOutput();
82     EXPECT_EQ(output_frames_, ceil(expected_output_frames_));
83   }
84
85  protected:
86   scoped_ptr<AudioBufferConverter> audio_buffer_converter_;
87
88   int input_frames_;
89   double expected_output_frames_;
90   int output_frames_;
91   int input_buffers_;
92   AudioParameters output_params_;
93 };
94
95 TEST_F(AudioBufferConverterTest, PassThrough) {
96   scoped_refptr<AudioBuffer> in =
97       MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512);
98   AddInput(in);
99   ConsumeAllOutput();
100 }
101
102 TEST_F(AudioBufferConverterTest, Downsample) {
103   scoped_refptr<AudioBuffer> in =
104       MakeTestBuffer(48000, kOutChannelLayout, kOutChannelCount, 512);
105   AddInput(in);
106   ConsumeAllOutput();
107 }
108
109 TEST_F(AudioBufferConverterTest, Upsample) {
110   scoped_refptr<AudioBuffer> in =
111       MakeTestBuffer(8000, kOutChannelLayout, kOutChannelCount, 512);
112   AddInput(in);
113   ConsumeAllOutput();
114 }
115
116 // Test resampling a buffer smaller than the SincResampler's kernel size.
117 TEST_F(AudioBufferConverterTest, Resample_TinyBuffer) {
118   AddInput(MakeTestBuffer(
119       48000, CHANNEL_LAYOUT_STEREO, 2, SincResampler::kKernelSize - 1));
120   ConsumeAllOutput();
121 }
122
123 TEST_F(AudioBufferConverterTest, Resample_DifferingBufferSizes) {
124   const int input_sample_rate = 48000;
125   AddInput(MakeTestBuffer(
126       input_sample_rate, kOutChannelLayout, kOutChannelCount, 100));
127   AddInput(MakeTestBuffer(
128       input_sample_rate, kOutChannelLayout, kOutChannelCount, 200));
129   AddInput(MakeTestBuffer(
130       input_sample_rate, kOutChannelLayout, kOutChannelCount, 300));
131   AddInput(MakeTestBuffer(
132       input_sample_rate, kOutChannelLayout, kOutChannelCount, 400));
133   AddInput(MakeTestBuffer(
134       input_sample_rate, kOutChannelLayout, kOutChannelCount, 500));
135   ConsumeAllOutput();
136 }
137
138 TEST_F(AudioBufferConverterTest, ChannelDownmix) {
139   scoped_refptr<AudioBuffer> in =
140       MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_MONO, 1, 512);
141   AddInput(in);
142   ConsumeAllOutput();
143 }
144
145 TEST_F(AudioBufferConverterTest, ChannelUpmix) {
146   scoped_refptr<AudioBuffer> in =
147       MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_5_1, 6, 512);
148   AddInput(in);
149   ConsumeAllOutput();
150 }
151
152 TEST_F(AudioBufferConverterTest, ResampleAndRemix) {
153   scoped_refptr<AudioBuffer> in =
154       MakeTestBuffer(48000, CHANNEL_LAYOUT_5_1, 6, 512);
155   AddInput(in);
156   ConsumeAllOutput();
157 }
158
159 TEST_F(AudioBufferConverterTest, ConfigChange_SampleRate) {
160   AddInput(MakeTestBuffer(48000, kOutChannelLayout, kOutChannelCount, 512));
161   AddInput(MakeTestBuffer(44100, kOutChannelLayout, kOutChannelCount, 512));
162   ConsumeAllOutput();
163 }
164
165 TEST_F(AudioBufferConverterTest, ConfigChange_ChannelLayout) {
166   AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_STEREO, 2, 512));
167   AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_MONO, 1, 512));
168   ConsumeAllOutput();
169 }
170
171 TEST_F(AudioBufferConverterTest, ConfigChange_SampleRateAndChannelLayout) {
172   AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
173   AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_MONO, 1, 512));
174   ConsumeAllOutput();
175 }
176
177 TEST_F(AudioBufferConverterTest, ConfigChange_Multiple) {
178   AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
179   AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_MONO, 1, 512));
180   AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_5_1, 6, 512));
181   AddInput(MakeTestBuffer(22050, CHANNEL_LAYOUT_STEREO, 2, 512));
182   ConsumeAllOutput();
183 }
184
185 TEST_F(AudioBufferConverterTest, Reset) {
186   AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
187   Reset();
188   ConsumeAllOutput();
189 }
190
191 TEST_F(AudioBufferConverterTest, ResampleThenReset) {
192   // Resampling is likely to leave some data buffered in AudioConverter's
193   // fifo or resampler, so make sure Reset() cleans that all up.
194   AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_STEREO, 2, 512));
195   Reset();
196   ConsumeAllOutput();
197 }
198
199 TEST_F(AudioBufferConverterTest, ResetThenConvert) {
200   AddInput(
201       MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512));
202   Reset();
203   // Make sure we can keep using the AudioBufferConverter after we've Reset().
204   AddInput(
205       MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512));
206   ConsumeAllOutput();
207 }
208
209 TEST_F(AudioBufferConverterTest, DiscreteChannelLayout) {
210   output_params_ = AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
211                                    CHANNEL_LAYOUT_DISCRETE,
212                                    2,
213                                    kOutSampleRate,
214                                    16,
215                                    512,
216                                    0);
217   audio_buffer_converter_.reset(new AudioBufferConverter(output_params_));
218   AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_STEREO, 2, 512));
219   ConsumeAllOutput();
220 }
221
222 TEST_F(AudioBufferConverterTest, LargeBuffersResampling) {
223   output_params_ = AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY,
224                                    kOutChannelLayout,
225                                    kOutSampleRate,
226                                    16,
227                                    2048);
228
229   audio_buffer_converter_.reset(new AudioBufferConverter(output_params_));
230   const int kInputSampleRate = 48000;
231   const int kInputFrameSize = 8192;
232   ASSERT_NE(kInputSampleRate, kOutSampleRate);
233
234   const int kInputBuffers = 3;
235   for (int i = 0; i < kInputBuffers; ++i) {
236     AddInput(MakeTestBuffer(kInputSampleRate,
237                             kOutChannelLayout,
238                             kOutChannelCount,
239                             kInputFrameSize));
240   }
241
242   // Do not add an EOS packet here, as it will invoke flushing.
243   while (audio_buffer_converter_->HasNextBuffer())
244     ConsumeOutput();
245
246   // Since the input buffer size is a multiple of the input request size there
247   // should never be any frames remaining at this point.
248   ASSERT_EQ(kInputFrameSize %
249                 audio_buffer_converter_->input_buffer_size_for_testing(),
250             0);
251   EXPECT_EQ(0, audio_buffer_converter_->input_frames_left_for_testing());
252 }
253
254 }  // namespace media