123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218 |
- // 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 <stdint.h>
- #include <memory>
- #include <string>
- #include "base/run_loop.h"
- #include "base/synchronization/waitable_event.h"
- #include "base/test/test_message_loop.h"
- #include "base/test/test_timeouts.h"
- #include "base/threading/thread_task_runner_handle.h"
- #include "base/time/time.h"
- #include "chromeos/ash/components/audio/cras_audio_handler.h"
- #include "chromeos/ash/components/dbus/audio/fake_cras_audio_client.h"
- #include "media/audio/audio_device_description.h"
- #include "media/audio/cras/audio_manager_chromeos.h"
- #include "media/audio/fake_audio_log_factory.h"
- #include "media/audio/test_audio_thread.h"
- #include "testing/gmock/include/gmock/gmock.h"
- #include "testing/gtest/include/gtest/gtest.h"
- // cras_util.h defines custom min/max macros which break compilation, so ensure
- // it's not included until last. #if avoids presubmit errors.
- #if defined(USE_CRAS)
- #include "media/audio/cras/cras_input.h"
- #endif
- using testing::_;
- using testing::AtLeast;
- using testing::Ge;
- using testing::InvokeWithoutArgs;
- using testing::StrictMock;
- namespace media {
- class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
- public:
- MOCK_METHOD3(OnData, void(const AudioBus*, base::TimeTicks, double));
- MOCK_METHOD0(OnError, void());
- };
- class MockAudioManagerCrasInput : public AudioManagerChromeOS {
- public:
- MockAudioManagerCrasInput()
- : AudioManagerChromeOS(std::make_unique<TestAudioThread>(),
- &fake_audio_log_factory_) {}
- // 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.
- void ReleaseInputStream(AudioInputStream* stream) override {
- DCHECK(stream);
- delete stream;
- }
- private:
- FakeAudioLogFactory fake_audio_log_factory_;
- };
- class CrasInputStreamTest : public testing::Test {
- protected:
- CrasInputStreamTest() {
- ash::CrasAudioClient::InitializeFake();
- ash::CrasAudioHandler::InitializeForTesting();
- mock_manager_.reset(new StrictMock<MockAudioManagerCrasInput>());
- base::RunLoop().RunUntilIdle();
- }
- CrasInputStreamTest(const CrasInputStreamTest&) = delete;
- CrasInputStreamTest& operator=(const CrasInputStreamTest&) = delete;
- ~CrasInputStreamTest() override {
- mock_manager_->Shutdown();
- ash::CrasAudioHandler::Shutdown();
- ash::CrasAudioClient::Shutdown();
- }
- CrasInputStream* CreateStream(ChannelLayout layout) {
- return CreateStream(layout, kTestFramesPerPacket);
- }
- CrasInputStream* CreateStream(ChannelLayout layout,
- int32_t samples_per_packet) {
- return CreateStream(layout, samples_per_packet,
- AudioDeviceDescription::kDefaultDeviceId);
- }
- CrasInputStream* CreateStream(ChannelLayout layout,
- int32_t samples_per_packet,
- const std::string& device_id) {
- AudioParameters params(kTestFormat,
- layout,
- kTestSampleRate,
- samples_per_packet);
- return new CrasInputStream(params, mock_manager_.get(), device_id);
- }
- void CaptureSomeFrames(const AudioParameters ¶ms,
- unsigned int duration_ms) {
- CrasInputStream* test_stream = new CrasInputStream(
- params, mock_manager_.get(), AudioDeviceDescription::kDefaultDeviceId);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
- // 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;
- base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
- base::WaitableEvent::InitialState::NOT_SIGNALED);
- EXPECT_CALL(mock_callback, OnData(_, _, _))
- .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();
- test_stream->Close();
- }
- static const unsigned int kTestCaptureDurationMs;
- static const ChannelLayout kTestChannelLayout;
- static const AudioParameters::Format kTestFormat;
- static const uint32_t kTestFramesPerPacket;
- static const int kTestSampleRate;
- base::TestMessageLoop message_loop_;
- std::unique_ptr<StrictMock<MockAudioManagerCrasInput>> mock_manager_;
- };
- const unsigned int CrasInputStreamTest::kTestCaptureDurationMs = 250;
- const ChannelLayout CrasInputStreamTest::kTestChannelLayout =
- CHANNEL_LAYOUT_STEREO;
- const AudioParameters::Format CrasInputStreamTest::kTestFormat =
- AudioParameters::AUDIO_PCM_LINEAR;
- const uint32_t CrasInputStreamTest::kTestFramesPerPacket = 1000;
- const int CrasInputStreamTest::kTestSampleRate = 44100;
- TEST_F(CrasInputStreamTest, OpenMono) {
- CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
- test_stream->Close();
- }
- TEST_F(CrasInputStreamTest, OpenStereo) {
- CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
- test_stream->Close();
- }
- TEST_F(CrasInputStreamTest, BadSampleRate) {
- AudioParameters bad_rate_params(kTestFormat,
- kTestChannelLayout,
- 0,
- kTestFramesPerPacket);
- CrasInputStream* test_stream =
- new CrasInputStream(bad_rate_params, mock_manager_.get(),
- AudioDeviceDescription::kDefaultDeviceId);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kFailed);
- test_stream->Close();
- }
- TEST_F(CrasInputStreamTest, SetGetVolume) {
- CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
- 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],
- 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],
- kTestFramesPerPacket);
- CaptureSomeFrames(params_stereo, kTestCaptureDurationMs);
- }
- }
- TEST_F(CrasInputStreamTest, CaptureLoopback) {
- CrasInputStream* test_stream =
- CreateStream(CHANNEL_LAYOUT_STEREO, kTestFramesPerPacket,
- AudioDeviceDescription::kLoopbackInputDeviceId);
- EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
- test_stream->Close();
- }
- } // namespace media
|