cras_input_unittest.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
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 <unistd.h> 6 7#include <string> 8 9#include "base/synchronization/waitable_event.h" 10#include "base/test/test_timeouts.h" 11#include "base/time/time.h" 12#include "media/audio/cras/audio_manager_cras.h" 13#include "media/audio/cras/cras_input.h" 14#include "testing/gmock/include/gmock/gmock.h" 15#include "testing/gtest/include/gtest/gtest.h" 16 17using testing::_; 18using testing::AtLeast; 19using testing::Ge; 20using testing::InvokeWithoutArgs; 21using testing::StrictMock; 22 23namespace media { 24 25class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { 26 public: 27 MOCK_METHOD5(OnData, void( 28 AudioInputStream*, const uint8*, uint32, uint32, double)); 29 MOCK_METHOD1(OnError, void(AudioInputStream*)); 30 MOCK_METHOD1(OnClose, void(AudioInputStream*)); 31}; 32 33class MockAudioManagerCrasInput : public AudioManagerCras { 34 public: 35 // We need to override this function in order to skip checking the number 36 // of active output streams. It is because the number of active streams 37 // is managed inside MakeAudioInputStream, and we don't use 38 // MakeAudioInputStream to create the stream in the tests. 39 virtual void ReleaseInputStream(AudioInputStream* stream) OVERRIDE { 40 DCHECK(stream); 41 delete stream; 42 } 43}; 44 45class CrasInputStreamTest : public testing::Test { 46 protected: 47 CrasInputStreamTest() { 48 mock_manager_.reset(new StrictMock<MockAudioManagerCrasInput>()); 49 } 50 51 virtual ~CrasInputStreamTest() { 52 } 53 54 CrasInputStream* CreateStream(ChannelLayout layout) { 55 return CreateStream(layout, kTestFramesPerPacket); 56 } 57 58 CrasInputStream* CreateStream(ChannelLayout layout, 59 int32 samples_per_packet) { 60 AudioParameters params(kTestFormat, 61 layout, 62 kTestSampleRate, 63 kTestBitsPerSample, 64 samples_per_packet); 65 return new CrasInputStream(params, mock_manager_.get()); 66 } 67 68 void CaptureSomeFrames(const AudioParameters ¶ms, 69 unsigned int duration_ms) { 70 CrasInputStream* test_stream = new CrasInputStream(params, 71 mock_manager_.get()); 72 73 ASSERT_TRUE(test_stream->Open()); 74 75 // Allow 8 frames variance for SRC in the callback. Different numbers of 76 // samples can be provided when doing non-integer SRC. For example 77 // converting from 192k to 44.1k is a ratio of 4.35 to 1. 78 MockAudioInputCallback mock_callback; 79 unsigned int expected_size = (kTestFramesPerPacket - 8) * 80 params.channels() * 81 params.bits_per_sample() / 8; 82 83 base::WaitableEvent event(false, false); 84 85 EXPECT_CALL(mock_callback, 86 OnData(test_stream, _, Ge(expected_size), _, _)) 87 .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal)); 88 89 test_stream->Start(&mock_callback); 90 91 // Wait for samples to be captured. 92 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout())); 93 94 test_stream->Stop(); 95 96 EXPECT_CALL(mock_callback, OnClose(test_stream)).Times(1); 97 test_stream->Close(); 98 } 99 100 static const unsigned int kTestBitsPerSample; 101 static const unsigned int kTestCaptureDurationMs; 102 static const ChannelLayout kTestChannelLayout; 103 static const AudioParameters::Format kTestFormat; 104 static const uint32 kTestFramesPerPacket; 105 static const int kTestSampleRate; 106 107 scoped_ptr<StrictMock<MockAudioManagerCrasInput> > mock_manager_; 108 109 private: 110 DISALLOW_COPY_AND_ASSIGN(CrasInputStreamTest); 111}; 112 113const unsigned int CrasInputStreamTest::kTestBitsPerSample = 16; 114const unsigned int CrasInputStreamTest::kTestCaptureDurationMs = 250; 115const ChannelLayout CrasInputStreamTest::kTestChannelLayout = 116 CHANNEL_LAYOUT_STEREO; 117const AudioParameters::Format CrasInputStreamTest::kTestFormat = 118 AudioParameters::AUDIO_PCM_LINEAR; 119const uint32 CrasInputStreamTest::kTestFramesPerPacket = 1000; 120const int CrasInputStreamTest::kTestSampleRate = 44100; 121 122TEST_F(CrasInputStreamTest, OpenMono) { 123 CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO); 124 EXPECT_TRUE(test_stream->Open()); 125 test_stream->Close(); 126} 127 128TEST_F(CrasInputStreamTest, OpenStereo) { 129 CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO); 130 EXPECT_TRUE(test_stream->Open()); 131 test_stream->Close(); 132} 133 134TEST_F(CrasInputStreamTest, BadBitsPerSample) { 135 AudioParameters bad_bps_params(kTestFormat, 136 kTestChannelLayout, 137 kTestSampleRate, 138 kTestBitsPerSample - 1, 139 kTestFramesPerPacket); 140 CrasInputStream* test_stream = 141 new CrasInputStream(bad_bps_params, mock_manager_.get()); 142 EXPECT_FALSE(test_stream->Open()); 143 test_stream->Close(); 144} 145 146TEST_F(CrasInputStreamTest, BadFormat) { 147 AudioParameters bad_format_params(AudioParameters::AUDIO_LAST_FORMAT, 148 kTestChannelLayout, 149 kTestSampleRate, 150 kTestBitsPerSample, 151 kTestFramesPerPacket); 152 CrasInputStream* test_stream = 153 new CrasInputStream(bad_format_params, mock_manager_.get()); 154 EXPECT_FALSE(test_stream->Open()); 155 test_stream->Close(); 156} 157 158TEST_F(CrasInputStreamTest, BadSampleRate) { 159 AudioParameters bad_rate_params(kTestFormat, 160 kTestChannelLayout, 161 0, 162 kTestBitsPerSample, 163 kTestFramesPerPacket); 164 CrasInputStream* test_stream = 165 new CrasInputStream(bad_rate_params, mock_manager_.get()); 166 EXPECT_FALSE(test_stream->Open()); 167 test_stream->Close(); 168} 169 170TEST_F(CrasInputStreamTest, SetGetVolume) { 171 CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO); 172 EXPECT_TRUE(test_stream->Open()); 173 174 double max_volume = test_stream->GetMaxVolume(); 175 EXPECT_GE(max_volume, 1.0); 176 177 test_stream->SetVolume(max_volume / 2); 178 179 double new_volume = test_stream->GetVolume(); 180 181 EXPECT_GE(new_volume, 0.0); 182 EXPECT_LE(new_volume, max_volume); 183 184 test_stream->Close(); 185} 186 187TEST_F(CrasInputStreamTest, CaptureFrames) { 188 const unsigned int rates[] = 189 {8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000}; 190 191 for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) { 192 SCOPED_TRACE(testing::Message() << "Mono " << rates[i] << "Hz"); 193 AudioParameters params_mono(kTestFormat, 194 CHANNEL_LAYOUT_MONO, 195 rates[i], 196 kTestBitsPerSample, 197 kTestFramesPerPacket); 198 CaptureSomeFrames(params_mono, kTestCaptureDurationMs); 199 } 200 201 for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) { 202 SCOPED_TRACE(testing::Message() << "Stereo " << rates[i] << "Hz"); 203 AudioParameters params_stereo(kTestFormat, 204 CHANNEL_LAYOUT_STEREO, 205 rates[i], 206 kTestBitsPerSample, 207 kTestFramesPerPacket); 208 CaptureSomeFrames(params_stereo, kTestCaptureDurationMs); 209 } 210} 211 212} // namespace media 213