| Index: media/audio/linux/cras_input_unittest.cc
|
| diff --git a/media/audio/linux/cras_input_unittest.cc b/media/audio/linux/cras_input_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..5d9a1c86215b36c7e1dfd7b3fb194d99dbfca1ce
|
| --- /dev/null
|
| +++ b/media/audio/linux/cras_input_unittest.cc
|
| @@ -0,0 +1,212 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <unistd.h>
|
| +
|
| +#include <string>
|
| +
|
| +#include "base/synchronization/waitable_event.h"
|
| +#include "base/test/test_timeouts.h"
|
| +#include "base/time.h"
|
| +#include "media/audio/linux/audio_manager_linux.h"
|
| +#include "media/audio/linux/cras_input.h"
|
| +#include "testing/gmock/include/gmock/gmock.h"
|
| +#include "testing/gtest/include/gtest/gtest.h"
|
| +
|
| +using testing::_;
|
| +using testing::AtLeast;
|
| +using testing::Ge;
|
| +using testing::InvokeWithoutArgs;
|
| +using testing::StrictMock;
|
| +
|
| +namespace media {
|
| +
|
| +class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
|
| + public:
|
| + MOCK_METHOD5(OnData, void(
|
| + AudioInputStream*, const uint8*, uint32, uint32, double));
|
| + MOCK_METHOD2(OnError, void(AudioInputStream*, int));
|
| + MOCK_METHOD1(OnClose, void(AudioInputStream*));
|
| +};
|
| +
|
| +class MockAudioManagerLinuxInput : public AudioManagerLinux {
|
| + public:
|
| + // We need to override this function in order to skip checking the number
|
| + // of active output streams. It is because the number of active streams
|
| + // is managed inside MakeAudioInputStream, and we don't use
|
| + // MakeAudioInputStream to create the stream in the tests.
|
| + virtual void ReleaseInputStream(AudioInputStream* stream) OVERRIDE {
|
| + DCHECK(stream);
|
| + delete stream;
|
| + }
|
| +};
|
| +
|
| +class CrasInputStreamTest : public testing::Test {
|
| + protected:
|
| + CrasInputStreamTest() {
|
| + mock_manager_.reset(new StrictMock<MockAudioManagerLinuxInput>());
|
| + }
|
| +
|
| + virtual ~CrasInputStreamTest() {
|
| + }
|
| +
|
| + CrasInputStream* CreateStream(ChannelLayout layout) {
|
| + return CreateStream(layout, kTestFramesPerPacket);
|
| + }
|
| +
|
| + CrasInputStream* CreateStream(ChannelLayout layout,
|
| + int32 samples_per_packet) {
|
| + AudioParameters params(kTestFormat,
|
| + layout,
|
| + kTestSampleRate,
|
| + kTestBitsPerSample,
|
| + samples_per_packet);
|
| + return new CrasInputStream(params, mock_manager_.get());
|
| + }
|
| +
|
| + void CaptureSomeFrames(const AudioParameters ¶ms,
|
| + unsigned int duration_ms) {
|
| + CrasInputStream* test_stream = new CrasInputStream(params,
|
| + mock_manager_.get());
|
| +
|
| + ASSERT_TRUE(test_stream->Open());
|
| +
|
| + // Allow 8 frames variance for SRC in the callback. Different numbers of
|
| + // samples can be provided when doing non-integer SRC. For example
|
| + // converting from 192k to 44.1k is a ratio of 4.35 to 1.
|
| + MockAudioInputCallback mock_callback;
|
| + unsigned int expected_size = (kTestFramesPerPacket - 8) *
|
| + params.channels() *
|
| + params.bits_per_sample() / 8;
|
| +
|
| + base::WaitableEvent event(false, false);
|
| +
|
| + EXPECT_CALL(mock_callback,
|
| + OnData(test_stream, _, Ge(expected_size), _, _))
|
| + .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));
|
| +
|
| + test_stream->Start(&mock_callback);
|
| +
|
| + // Wait for samples to be captured.
|
| + EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout()));
|
| +
|
| + test_stream->Stop();
|
| +
|
| + EXPECT_CALL(mock_callback, OnClose(test_stream)).Times(1);
|
| + test_stream->Close();
|
| + }
|
| +
|
| + static const unsigned int kTestBitsPerSample;
|
| + static const unsigned int kTestCaptureDurationMs;
|
| + static const ChannelLayout kTestChannelLayout;
|
| + static const AudioParameters::Format kTestFormat;
|
| + static const uint32 kTestFramesPerPacket;
|
| + static const int kTestSampleRate;
|
| +
|
| + scoped_ptr<StrictMock<MockAudioManagerLinuxInput> > mock_manager_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(CrasInputStreamTest);
|
| +};
|
| +
|
| +const unsigned int CrasInputStreamTest::kTestBitsPerSample = 16;
|
| +const unsigned int CrasInputStreamTest::kTestCaptureDurationMs = 250;
|
| +const ChannelLayout CrasInputStreamTest::kTestChannelLayout =
|
| + CHANNEL_LAYOUT_STEREO;
|
| +const AudioParameters::Format CrasInputStreamTest::kTestFormat =
|
| + AudioParameters::AUDIO_PCM_LINEAR;
|
| +const uint32 CrasInputStreamTest::kTestFramesPerPacket = 1000;
|
| +const int CrasInputStreamTest::kTestSampleRate = 44100;
|
| +
|
| +TEST_F(CrasInputStreamTest, OpenMono) {
|
| + CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
|
| + EXPECT_TRUE(test_stream->Open());
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, OpenStereo) {
|
| + CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO);
|
| + EXPECT_TRUE(test_stream->Open());
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, BadBitsPerSample) {
|
| + AudioParameters bad_bps_params(kTestFormat,
|
| + kTestChannelLayout,
|
| + kTestSampleRate,
|
| + kTestBitsPerSample - 1,
|
| + kTestFramesPerPacket);
|
| + CrasInputStream* test_stream =
|
| + new CrasInputStream(bad_bps_params, mock_manager_.get());
|
| + EXPECT_FALSE(test_stream->Open());
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, BadFormat) {
|
| + AudioParameters bad_format_params(AudioParameters::AUDIO_LAST_FORMAT,
|
| + kTestChannelLayout,
|
| + kTestSampleRate,
|
| + kTestBitsPerSample,
|
| + kTestFramesPerPacket);
|
| + CrasInputStream* test_stream =
|
| + new CrasInputStream(bad_format_params, mock_manager_.get());
|
| + EXPECT_FALSE(test_stream->Open());
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, BadSampleRate) {
|
| + AudioParameters bad_rate_params(kTestFormat,
|
| + kTestChannelLayout,
|
| + 0,
|
| + kTestBitsPerSample,
|
| + kTestFramesPerPacket);
|
| + CrasInputStream* test_stream =
|
| + new CrasInputStream(bad_rate_params, mock_manager_.get());
|
| + EXPECT_FALSE(test_stream->Open());
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, SetGetVolume) {
|
| + CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
|
| + EXPECT_TRUE(test_stream->Open());
|
| +
|
| + double max_volume = test_stream->GetMaxVolume();
|
| + EXPECT_GE(max_volume, 1.0);
|
| +
|
| + test_stream->SetVolume(max_volume / 2);
|
| +
|
| + double new_volume = test_stream->GetVolume();
|
| +
|
| + EXPECT_GE(new_volume, 0.0);
|
| + EXPECT_LE(new_volume, max_volume);
|
| +
|
| + test_stream->Close();
|
| +}
|
| +
|
| +TEST_F(CrasInputStreamTest, CaptureFrames) {
|
| + const unsigned int rates[] =
|
| + {8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000};
|
| +
|
| + for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
|
| + SCOPED_TRACE(testing::Message() << "Mono " << rates[i] << "Hz");
|
| + AudioParameters params_mono(kTestFormat,
|
| + CHANNEL_LAYOUT_MONO,
|
| + rates[i],
|
| + kTestBitsPerSample,
|
| + kTestFramesPerPacket);
|
| + CaptureSomeFrames(params_mono, kTestCaptureDurationMs);
|
| + }
|
| +
|
| + for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
|
| + SCOPED_TRACE(testing::Message() << "Stereo " << rates[i] << "Hz");
|
| + AudioParameters params_stereo(kTestFormat,
|
| + CHANNEL_LAYOUT_STEREO,
|
| + rates[i],
|
| + kTestBitsPerSample,
|
| + kTestFramesPerPacket);
|
| + CaptureSomeFrames(params_stereo, kTestCaptureDurationMs);
|
| + }
|
| +}
|
| +
|
| +} // namespace media
|
|
|