audio_auhal_mac_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
1// Copyright 2013 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/basictypes.h"
6#include "base/memory/scoped_ptr.h"
7#include "media/audio/audio_io.h"
8#include "media/audio/audio_manager.h"
9#include "media/audio/simple_sources.h"
10#include "testing/gmock/include/gmock/gmock.h"
11#include "testing/gtest/include/gtest/gtest.h"
12
13using ::testing::_;
14using ::testing::AnyNumber;
15using ::testing::DoAll;
16using ::testing::Field;
17using ::testing::InSequence;
18using ::testing::Invoke;
19using ::testing::NiceMock;
20using ::testing::NotNull;
21using ::testing::Return;
22
23static const int kBitsPerSample = 16;
24
25// TODO(crogers): Most of these tests can be made platform agnostic.
26// http://crbug.com/223242
27
28namespace media {
29
30class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
31 public:
32  MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
33                               AudioBuffersState buffers_state));
34  MOCK_METHOD3(OnMoreIOData, int(AudioBus* source,
35                                 AudioBus* dest,
36                                 AudioBuffersState buffers_state));
37  MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
38};
39
40// Convenience method which creates a default AudioOutputStream object but
41// also allows the user to modify the default settings.
42class AudioOutputStreamWrapper {
43 public:
44  explicit AudioOutputStreamWrapper()
45      : audio_man_(AudioManager::Create()),
46        format_(AudioParameters::AUDIO_PCM_LOW_LATENCY),
47        bits_per_sample_(kBitsPerSample) {
48    AudioParameters preferred_params =
49        audio_man_->GetDefaultOutputStreamParameters();
50    channel_layout_ = preferred_params.channel_layout();
51    channels_ = preferred_params.channels();
52    sample_rate_ = preferred_params.sample_rate();
53    samples_per_packet_ = preferred_params.frames_per_buffer();
54  }
55
56  ~AudioOutputStreamWrapper() {}
57
58  // Creates AudioOutputStream object using default parameters.
59  AudioOutputStream* Create() {
60    return CreateOutputStream();
61  }
62
63  // Creates AudioOutputStream object using non-default parameters where the
64  // frame size is modified.
65  AudioOutputStream* Create(int samples_per_packet) {
66    samples_per_packet_ = samples_per_packet;
67    return CreateOutputStream();
68  }
69
70  // Creates AudioOutputStream object using non-default parameters where the
71  // sample rate is modified.
72  AudioOutputStream* CreateWithSampleRate(int sample_rate) {
73    sample_rate_ = sample_rate;
74    return CreateOutputStream();
75  }
76
77  // Creates AudioOutputStream object using non-default parameters where the
78  // channel layout is modified.
79  AudioOutputStream* CreateWithLayout(ChannelLayout layout) {
80    channel_layout_ = layout;
81    channels_ = ChannelLayoutToChannelCount(layout);
82    return CreateOutputStream();
83  }
84
85  AudioParameters::Format format() const { return format_; }
86  int channels() const { return ChannelLayoutToChannelCount(channel_layout_); }
87  int bits_per_sample() const { return bits_per_sample_; }
88  int sample_rate() const { return sample_rate_; }
89  int samples_per_packet() const { return samples_per_packet_; }
90
91  bool CanRunAudioTests() {
92    return audio_man_->HasAudioOutputDevices();
93  }
94
95 private:
96  AudioOutputStream* CreateOutputStream() {
97    AudioParameters params;
98    params.Reset(format_, channel_layout_,
99                 channels_, 0,
100                 sample_rate_, bits_per_sample_,
101                 samples_per_packet_);
102
103    AudioOutputStream* aos = audio_man_->MakeAudioOutputStream(params);
104    EXPECT_TRUE(aos);
105    return aos;
106  }
107
108  scoped_ptr<AudioManager> audio_man_;
109
110  AudioParameters::Format format_;
111  ChannelLayout channel_layout_;
112  int channels_;
113  int bits_per_sample_;
114  int sample_rate_;
115  int samples_per_packet_;
116};
117
118// Test that we can get the hardware sample-rate.
119TEST(AUHALStreamTest, HardwareSampleRate) {
120  AudioOutputStreamWrapper aosw;
121  if (!aosw.CanRunAudioTests())
122    return;
123
124  int sample_rate = aosw.sample_rate();
125  EXPECT_GE(sample_rate, 16000);
126  EXPECT_LE(sample_rate, 192000);
127}
128
129// Test Create(), Close() calling sequence.
130TEST(AUHALStreamTest, CreateAndClose) {
131  AudioOutputStreamWrapper aosw;
132  if (!aosw.CanRunAudioTests())
133    return;
134
135  AudioOutputStream* aos = aosw.Create();
136  aos->Close();
137}
138
139// Test Open(), Close() calling sequence.
140TEST(AUHALStreamTest, OpenAndClose) {
141  AudioOutputStreamWrapper aosw;
142  if (!aosw.CanRunAudioTests())
143    return;
144
145  AudioOutputStream* aos = aosw.Create();
146  EXPECT_TRUE(aos->Open());
147  aos->Close();
148}
149
150// Test Open(), Start(), Close() calling sequence.
151TEST(AUHALStreamTest, OpenStartAndClose) {
152  AudioOutputStreamWrapper aosw;
153  if (!aosw.CanRunAudioTests())
154    return;
155
156  AudioOutputStream* aos = aosw.Create();
157  EXPECT_TRUE(aos->Open());
158  MockAudioSourceCallback source;
159  EXPECT_CALL(source, OnError(aos))
160      .Times(0);
161  aos->Start(&source);
162  aos->Close();
163}
164
165// Test Open(), Start(), Stop(), Close() calling sequence.
166TEST(AUHALStreamTest, OpenStartStopAndClose) {
167  AudioOutputStreamWrapper aosw;
168  if (!aosw.CanRunAudioTests())
169    return;
170
171  AudioOutputStream* aos = aosw.Create();
172  EXPECT_TRUE(aos->Open());
173  MockAudioSourceCallback source;
174  EXPECT_CALL(source, OnError(aos))
175      .Times(0);
176  aos->Start(&source);
177  aos->Stop();
178  aos->Close();
179}
180
181// This test produces actual audio for 0.5 seconds on the default audio device
182// at the hardware sample-rate (usually 44.1KHz).
183// Parameters have been chosen carefully so you should not hear
184// pops or noises while the sound is playing.
185TEST(AUHALStreamTest, AUHALStreamPlay200HzTone) {
186  AudioOutputStreamWrapper aosw;
187  if (!aosw.CanRunAudioTests())
188    return;
189
190  AudioOutputStream* aos = aosw.CreateWithLayout(CHANNEL_LAYOUT_MONO);
191
192  EXPECT_TRUE(aos->Open());
193
194  SineWaveAudioSource source(1, 200.0, aosw.sample_rate());
195  aos->Start(&source);
196  usleep(500000);
197
198  aos->Stop();
199  aos->Close();
200}
201
202// Test that Open() will fail with a sample-rate which isn't the hardware
203// sample-rate.
204TEST(AUHALStreamTest, AUHALStreamInvalidSampleRate) {
205  AudioOutputStreamWrapper aosw;
206  if (!aosw.CanRunAudioTests())
207    return;
208
209  int non_default_sample_rate = aosw.sample_rate() == 44100 ?
210      48000 : 44100;
211  AudioOutputStream* aos = aosw.CreateWithSampleRate(non_default_sample_rate);
212
213  EXPECT_FALSE(aos->Open());
214
215  aos->Close();
216}
217
218}  // namespace media
219