audio_buffer_converter_unittest.cc revision effb81e5f8246d0db0270817048dc992db66e9fb
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
13namespace media {
14
15// Important: Use an odd buffer size here so SIMD issues are caught.
16const int kOutFrameSize = 441;
17const int kOutSampleRate = 44100;
18const ChannelLayout kOutChannelLayout = CHANNEL_LAYOUT_STEREO;
19const int kOutChannelCount = 2;
20
21static 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                                base::TimeDelta::FromSeconds(0));
34}
35
36class AudioBufferConverterTest : public ::testing::Test {
37 public:
38  AudioBufferConverterTest()
39      : input_frames_(0), expected_output_frames_(0.0), output_frames_(0) {
40    AudioParameters output_params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
41                                  kOutChannelLayout,
42                                  kOutSampleRate,
43                                  16,
44                                  kOutFrameSize);
45    ResetConverter(output_params);
46  }
47
48  void Reset() {
49    audio_buffer_converter_->Reset();
50    output_frames_ = expected_output_frames_ = input_frames_ = 0;
51  }
52
53  void AddInput(const scoped_refptr<AudioBuffer>& in) {
54    if (!in->end_of_stream()) {
55      input_frames_ += in->frame_count();
56      expected_output_frames_ +=
57          in->frame_count() *
58          (static_cast<double>(kOutSampleRate) / in->sample_rate());
59    }
60    audio_buffer_converter_->AddInput(in);
61  }
62
63  void ConsumeAllOutput() {
64    AddInput(AudioBuffer::CreateEOSBuffer());
65    while (audio_buffer_converter_->HasNextBuffer()) {
66      scoped_refptr<AudioBuffer> out = audio_buffer_converter_->GetNextBuffer();
67      if (!out->end_of_stream()) {
68        output_frames_ += out->frame_count();
69        EXPECT_EQ(out->sample_rate(), out_sample_rate_);
70        EXPECT_EQ(out->channel_layout(), out_channel_layout_);
71        EXPECT_EQ(out->channel_count(), out_channel_count_);
72      } else {
73        EXPECT_FALSE(audio_buffer_converter_->HasNextBuffer());
74      }
75    }
76    EXPECT_EQ(output_frames_, ceil(expected_output_frames_));
77  }
78
79  void ResetConverter(AudioParameters out_params) {
80    audio_buffer_converter_.reset(new AudioBufferConverter(out_params));
81    out_channel_layout_ = out_params.channel_layout();
82    out_channel_count_ = out_params.channels();
83    out_sample_rate_ = out_params.sample_rate();
84  }
85
86 private:
87  scoped_ptr<AudioBufferConverter> audio_buffer_converter_;
88
89  int input_frames_;
90  double expected_output_frames_;
91  int output_frames_;
92
93  int out_sample_rate_;
94  ChannelLayout out_channel_layout_;
95  int out_channel_count_;
96};
97
98TEST_F(AudioBufferConverterTest, PassThrough) {
99  scoped_refptr<AudioBuffer> in =
100      MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512);
101  AddInput(in);
102  ConsumeAllOutput();
103}
104
105TEST_F(AudioBufferConverterTest, Downsample) {
106  scoped_refptr<AudioBuffer> in =
107      MakeTestBuffer(48000, kOutChannelLayout, kOutChannelCount, 512);
108  AddInput(in);
109  ConsumeAllOutput();
110}
111
112TEST_F(AudioBufferConverterTest, Upsample) {
113  scoped_refptr<AudioBuffer> in =
114      MakeTestBuffer(8000, kOutChannelLayout, kOutChannelCount, 512);
115  AddInput(in);
116  ConsumeAllOutput();
117}
118
119// Test resampling a buffer smaller than the SincResampler's kernel size.
120TEST_F(AudioBufferConverterTest, Resample_TinyBuffer) {
121  AddInput(MakeTestBuffer(
122      48000, CHANNEL_LAYOUT_STEREO, 2, SincResampler::kKernelSize - 1));
123  ConsumeAllOutput();
124}
125
126TEST_F(AudioBufferConverterTest, Resample_DifferingBufferSizes) {
127  const int input_sample_rate = 48000;
128  AddInput(MakeTestBuffer(
129      input_sample_rate, kOutChannelLayout, kOutChannelCount, 100));
130  AddInput(MakeTestBuffer(
131      input_sample_rate, kOutChannelLayout, kOutChannelCount, 200));
132  AddInput(MakeTestBuffer(
133      input_sample_rate, kOutChannelLayout, kOutChannelCount, 300));
134  AddInput(MakeTestBuffer(
135      input_sample_rate, kOutChannelLayout, kOutChannelCount, 400));
136  AddInput(MakeTestBuffer(
137      input_sample_rate, kOutChannelLayout, kOutChannelCount, 500));
138  ConsumeAllOutput();
139}
140
141TEST_F(AudioBufferConverterTest, ChannelDownmix) {
142  scoped_refptr<AudioBuffer> in =
143      MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_MONO, 1, 512);
144  AddInput(in);
145  ConsumeAllOutput();
146}
147
148TEST_F(AudioBufferConverterTest, ChannelUpmix) {
149  scoped_refptr<AudioBuffer> in =
150      MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_5_1, 6, 512);
151  AddInput(in);
152  ConsumeAllOutput();
153}
154
155TEST_F(AudioBufferConverterTest, ResampleAndRemix) {
156  scoped_refptr<AudioBuffer> in =
157      MakeTestBuffer(48000, CHANNEL_LAYOUT_5_1, 6, 512);
158  AddInput(in);
159  ConsumeAllOutput();
160}
161
162TEST_F(AudioBufferConverterTest, ConfigChange_SampleRate) {
163  AddInput(MakeTestBuffer(48000, kOutChannelLayout, kOutChannelCount, 512));
164  AddInput(MakeTestBuffer(44100, kOutChannelLayout, kOutChannelCount, 512));
165  ConsumeAllOutput();
166}
167
168TEST_F(AudioBufferConverterTest, ConfigChange_ChannelLayout) {
169  AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_STEREO, 2, 512));
170  AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_MONO, 1, 512));
171  ConsumeAllOutput();
172}
173
174TEST_F(AudioBufferConverterTest, ConfigChange_SampleRateAndChannelLayout) {
175  AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
176  AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_MONO, 1, 512));
177  ConsumeAllOutput();
178}
179
180TEST_F(AudioBufferConverterTest, ConfigChange_Multiple) {
181  AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
182  AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_MONO, 1, 512));
183  AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_5_1, 6, 512));
184  AddInput(MakeTestBuffer(22050, CHANNEL_LAYOUT_STEREO, 2, 512));
185  ConsumeAllOutput();
186}
187
188TEST_F(AudioBufferConverterTest, Reset) {
189  AddInput(MakeTestBuffer(44100, CHANNEL_LAYOUT_STEREO, 2, 512));
190  Reset();
191  ConsumeAllOutput();
192}
193
194TEST_F(AudioBufferConverterTest, ResampleThenReset) {
195  // Resampling is likely to leave some data buffered in AudioConverter's
196  // fifo or resampler, so make sure Reset() cleans that all up.
197  AddInput(MakeTestBuffer(48000, CHANNEL_LAYOUT_STEREO, 2, 512));
198  Reset();
199  ConsumeAllOutput();
200}
201
202TEST_F(AudioBufferConverterTest, ResetThenConvert) {
203  AddInput(
204      MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512));
205  Reset();
206  // Make sure we can keep using the AudioBufferConverter after we've Reset().
207  AddInput(
208      MakeTestBuffer(kOutSampleRate, kOutChannelLayout, kOutChannelCount, 512));
209  ConsumeAllOutput();
210}
211
212TEST_F(AudioBufferConverterTest, DiscreteChannelLayout) {
213  AudioParameters output_params(AudioParameters::AUDIO_PCM_LOW_LATENCY,
214                                CHANNEL_LAYOUT_DISCRETE,
215                                2,
216                                0,
217                                kOutSampleRate,
218                                16,
219                                512,
220                                0);
221  ResetConverter(output_params);
222  AddInput(MakeTestBuffer(kOutSampleRate, CHANNEL_LAYOUT_STEREO, 2, 512));
223  ConsumeAllOutput();
224}
225
226}  // namespace media
227