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.
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"
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;
21 static scoped_refptr
<AudioBuffer
> MakeTestBuffer(int sample_rate
,
22 ChannelLayout channel_layout
,
25 return MakeAudioBuffer
<uint8
>(kSampleFormatU8
,
32 base::TimeDelta::FromSeconds(0));
35 class AudioBufferConverterTest
: public ::testing::Test
{
37 AudioBufferConverterTest()
39 expected_output_frames_(0.0),
41 output_params_(AudioParameters::AUDIO_PCM_LOW_LATENCY
,
46 audio_buffer_converter_
.reset(new AudioBufferConverter(output_params_
));
50 audio_buffer_converter_
->Reset();
51 output_frames_
= expected_output_frames_
= input_frames_
= 0;
54 void AddInput(const scoped_refptr
<AudioBuffer
>& in
) {
55 if (!in
->end_of_stream()) {
56 input_frames_
+= in
->frame_count();
57 expected_output_frames_
+=
59 (static_cast<double>(output_params_
.sample_rate()) /
62 audio_buffer_converter_
->AddInput(in
);
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());
74 EXPECT_FALSE(audio_buffer_converter_
->HasNextBuffer());
78 void ConsumeAllOutput() {
79 AddInput(AudioBuffer::CreateEOSBuffer());
80 while (audio_buffer_converter_
->HasNextBuffer())
82 EXPECT_EQ(output_frames_
, ceil(expected_output_frames_
));
86 scoped_ptr
<AudioBufferConverter
> audio_buffer_converter_
;
89 double expected_output_frames_
;
92 AudioParameters output_params_
;
95 TEST_F(AudioBufferConverterTest
, PassThrough
) {
96 scoped_refptr
<AudioBuffer
> in
=
97 MakeTestBuffer(kOutSampleRate
, kOutChannelLayout
, kOutChannelCount
, 512);
102 TEST_F(AudioBufferConverterTest
, Downsample
) {
103 scoped_refptr
<AudioBuffer
> in
=
104 MakeTestBuffer(48000, kOutChannelLayout
, kOutChannelCount
, 512);
109 TEST_F(AudioBufferConverterTest
, Upsample
) {
110 scoped_refptr
<AudioBuffer
> in
=
111 MakeTestBuffer(8000, kOutChannelLayout
, kOutChannelCount
, 512);
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));
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));
138 TEST_F(AudioBufferConverterTest
, ChannelDownmix
) {
139 scoped_refptr
<AudioBuffer
> in
=
140 MakeTestBuffer(kOutSampleRate
, CHANNEL_LAYOUT_MONO
, 1, 512);
145 TEST_F(AudioBufferConverterTest
, ChannelUpmix
) {
146 scoped_refptr
<AudioBuffer
> in
=
147 MakeTestBuffer(kOutSampleRate
, CHANNEL_LAYOUT_5_1
, 6, 512);
152 TEST_F(AudioBufferConverterTest
, ResampleAndRemix
) {
153 scoped_refptr
<AudioBuffer
> in
=
154 MakeTestBuffer(48000, CHANNEL_LAYOUT_5_1
, 6, 512);
159 TEST_F(AudioBufferConverterTest
, ConfigChange_SampleRate
) {
160 AddInput(MakeTestBuffer(48000, kOutChannelLayout
, kOutChannelCount
, 512));
161 AddInput(MakeTestBuffer(44100, kOutChannelLayout
, kOutChannelCount
, 512));
165 TEST_F(AudioBufferConverterTest
, ConfigChange_ChannelLayout
) {
166 AddInput(MakeTestBuffer(kOutSampleRate
, CHANNEL_LAYOUT_STEREO
, 2, 512));
167 AddInput(MakeTestBuffer(kOutSampleRate
, CHANNEL_LAYOUT_MONO
, 1, 512));
171 TEST_F(AudioBufferConverterTest
, ConfigChange_SampleRateAndChannelLayout
) {
172 AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO
, 2, 512));
173 AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_MONO
, 1, 512));
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));
185 TEST_F(AudioBufferConverterTest
, Reset
) {
186 AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO
, 2, 512));
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));
199 TEST_F(AudioBufferConverterTest
, ResetThenConvert
) {
201 MakeTestBuffer(kOutSampleRate
, kOutChannelLayout
, kOutChannelCount
, 512));
203 // Make sure we can keep using the AudioBufferConverter after we've Reset().
205 MakeTestBuffer(kOutSampleRate
, kOutChannelLayout
, kOutChannelCount
, 512));
209 TEST_F(AudioBufferConverterTest
, DiscreteChannelLayout
) {
210 output_params_
= AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY
,
211 CHANNEL_LAYOUT_DISCRETE
,
217 audio_buffer_converter_
.reset(new AudioBufferConverter(output_params_
));
218 AddInput(MakeTestBuffer(kOutSampleRate
, CHANNEL_LAYOUT_STEREO
, 2, 512));
222 TEST_F(AudioBufferConverterTest
, LargeBuffersResampling
) {
223 output_params_
= AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY
,
229 audio_buffer_converter_
.reset(new AudioBufferConverter(output_params_
));
230 const int kInputSampleRate
= 48000;
231 const int kInputFrameSize
= 8192;
232 ASSERT_NE(kInputSampleRate
, kOutSampleRate
);
234 const int kInputBuffers
= 3;
235 for (int i
= 0; i
< kInputBuffers
; ++i
) {
236 AddInput(MakeTestBuffer(kInputSampleRate
,
242 // Do not add an EOS packet here, as it will invoke flushing.
243 while (audio_buffer_converter_
->HasNextBuffer())
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(),
251 EXPECT_EQ(0, audio_buffer_converter_
->input_frames_left_for_testing());