cras_input_unittest.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218
  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. #include <stdint.h>
  5. #include <memory>
  6. #include <string>
  7. #include "base/run_loop.h"
  8. #include "base/synchronization/waitable_event.h"
  9. #include "base/test/test_message_loop.h"
  10. #include "base/test/test_timeouts.h"
  11. #include "base/threading/thread_task_runner_handle.h"
  12. #include "base/time/time.h"
  13. #include "chromeos/ash/components/audio/cras_audio_handler.h"
  14. #include "chromeos/ash/components/dbus/audio/fake_cras_audio_client.h"
  15. #include "media/audio/audio_device_description.h"
  16. #include "media/audio/cras/audio_manager_chromeos.h"
  17. #include "media/audio/fake_audio_log_factory.h"
  18. #include "media/audio/test_audio_thread.h"
  19. #include "testing/gmock/include/gmock/gmock.h"
  20. #include "testing/gtest/include/gtest/gtest.h"
  21. // cras_util.h defines custom min/max macros which break compilation, so ensure
  22. // it's not included until last. #if avoids presubmit errors.
  23. #if defined(USE_CRAS)
  24. #include "media/audio/cras/cras_input.h"
  25. #endif
  26. using testing::_;
  27. using testing::AtLeast;
  28. using testing::Ge;
  29. using testing::InvokeWithoutArgs;
  30. using testing::StrictMock;
  31. namespace media {
  32. class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
  33. public:
  34. MOCK_METHOD3(OnData, void(const AudioBus*, base::TimeTicks, double));
  35. MOCK_METHOD0(OnError, void());
  36. };
  37. class MockAudioManagerCrasInput : public AudioManagerChromeOS {
  38. public:
  39. MockAudioManagerCrasInput()
  40. : AudioManagerChromeOS(std::make_unique<TestAudioThread>(),
  41. &fake_audio_log_factory_) {}
  42. // We need to override this function in order to skip checking the number
  43. // of active output streams. It is because the number of active streams
  44. // is managed inside MakeAudioInputStream, and we don't use
  45. // MakeAudioInputStream to create the stream in the tests.
  46. void ReleaseInputStream(AudioInputStream* stream) override {
  47. DCHECK(stream);
  48. delete stream;
  49. }
  50. private:
  51. FakeAudioLogFactory fake_audio_log_factory_;
  52. };
  53. class CrasInputStreamTest : public testing::Test {
  54. protected:
  55. CrasInputStreamTest() {
  56. ash::CrasAudioClient::InitializeFake();
  57. ash::CrasAudioHandler::InitializeForTesting();
  58. mock_manager_.reset(new StrictMock<MockAudioManagerCrasInput>());
  59. base::RunLoop().RunUntilIdle();
  60. }
  61. CrasInputStreamTest(const CrasInputStreamTest&) = delete;
  62. CrasInputStreamTest& operator=(const CrasInputStreamTest&) = delete;
  63. ~CrasInputStreamTest() override {
  64. mock_manager_->Shutdown();
  65. ash::CrasAudioHandler::Shutdown();
  66. ash::CrasAudioClient::Shutdown();
  67. }
  68. CrasInputStream* CreateStream(ChannelLayout layout) {
  69. return CreateStream(layout, kTestFramesPerPacket);
  70. }
  71. CrasInputStream* CreateStream(ChannelLayout layout,
  72. int32_t samples_per_packet) {
  73. return CreateStream(layout, samples_per_packet,
  74. AudioDeviceDescription::kDefaultDeviceId);
  75. }
  76. CrasInputStream* CreateStream(ChannelLayout layout,
  77. int32_t samples_per_packet,
  78. const std::string& device_id) {
  79. AudioParameters params(kTestFormat,
  80. layout,
  81. kTestSampleRate,
  82. samples_per_packet);
  83. return new CrasInputStream(params, mock_manager_.get(), device_id);
  84. }
  85. void CaptureSomeFrames(const AudioParameters &params,
  86. unsigned int duration_ms) {
  87. CrasInputStream* test_stream = new CrasInputStream(
  88. params, mock_manager_.get(), AudioDeviceDescription::kDefaultDeviceId);
  89. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
  90. // Allow 8 frames variance for SRC in the callback. Different numbers of
  91. // samples can be provided when doing non-integer SRC. For example
  92. // converting from 192k to 44.1k is a ratio of 4.35 to 1.
  93. MockAudioInputCallback mock_callback;
  94. base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  95. base::WaitableEvent::InitialState::NOT_SIGNALED);
  96. EXPECT_CALL(mock_callback, OnData(_, _, _))
  97. .WillOnce(InvokeWithoutArgs(&event, &base::WaitableEvent::Signal));
  98. test_stream->Start(&mock_callback);
  99. // Wait for samples to be captured.
  100. EXPECT_TRUE(event.TimedWait(TestTimeouts::action_timeout()));
  101. test_stream->Stop();
  102. test_stream->Close();
  103. }
  104. static const unsigned int kTestCaptureDurationMs;
  105. static const ChannelLayout kTestChannelLayout;
  106. static const AudioParameters::Format kTestFormat;
  107. static const uint32_t kTestFramesPerPacket;
  108. static const int kTestSampleRate;
  109. base::TestMessageLoop message_loop_;
  110. std::unique_ptr<StrictMock<MockAudioManagerCrasInput>> mock_manager_;
  111. };
  112. const unsigned int CrasInputStreamTest::kTestCaptureDurationMs = 250;
  113. const ChannelLayout CrasInputStreamTest::kTestChannelLayout =
  114. CHANNEL_LAYOUT_STEREO;
  115. const AudioParameters::Format CrasInputStreamTest::kTestFormat =
  116. AudioParameters::AUDIO_PCM_LINEAR;
  117. const uint32_t CrasInputStreamTest::kTestFramesPerPacket = 1000;
  118. const int CrasInputStreamTest::kTestSampleRate = 44100;
  119. TEST_F(CrasInputStreamTest, OpenMono) {
  120. CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
  121. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
  122. test_stream->Close();
  123. }
  124. TEST_F(CrasInputStreamTest, OpenStereo) {
  125. CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_STEREO);
  126. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
  127. test_stream->Close();
  128. }
  129. TEST_F(CrasInputStreamTest, BadSampleRate) {
  130. AudioParameters bad_rate_params(kTestFormat,
  131. kTestChannelLayout,
  132. 0,
  133. kTestFramesPerPacket);
  134. CrasInputStream* test_stream =
  135. new CrasInputStream(bad_rate_params, mock_manager_.get(),
  136. AudioDeviceDescription::kDefaultDeviceId);
  137. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kFailed);
  138. test_stream->Close();
  139. }
  140. TEST_F(CrasInputStreamTest, SetGetVolume) {
  141. CrasInputStream* test_stream = CreateStream(CHANNEL_LAYOUT_MONO);
  142. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
  143. double max_volume = test_stream->GetMaxVolume();
  144. EXPECT_GE(max_volume, 1.0);
  145. test_stream->SetVolume(max_volume / 2);
  146. double new_volume = test_stream->GetVolume();
  147. EXPECT_GE(new_volume, 0.0);
  148. EXPECT_LE(new_volume, max_volume);
  149. test_stream->Close();
  150. }
  151. TEST_F(CrasInputStreamTest, CaptureFrames) {
  152. const unsigned int rates[] =
  153. {8000, 16000, 22050, 32000, 44100, 48000, 96000, 192000};
  154. for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
  155. SCOPED_TRACE(testing::Message() << "Mono " << rates[i] << "Hz");
  156. AudioParameters params_mono(kTestFormat,
  157. CHANNEL_LAYOUT_MONO,
  158. rates[i],
  159. kTestFramesPerPacket);
  160. CaptureSomeFrames(params_mono, kTestCaptureDurationMs);
  161. }
  162. for (unsigned int i = 0; i < ARRAY_SIZE(rates); i++) {
  163. SCOPED_TRACE(testing::Message() << "Stereo " << rates[i] << "Hz");
  164. AudioParameters params_stereo(kTestFormat,
  165. CHANNEL_LAYOUT_STEREO,
  166. rates[i],
  167. kTestFramesPerPacket);
  168. CaptureSomeFrames(params_stereo, kTestCaptureDurationMs);
  169. }
  170. }
  171. TEST_F(CrasInputStreamTest, CaptureLoopback) {
  172. CrasInputStream* test_stream =
  173. CreateStream(CHANNEL_LAYOUT_STEREO, kTestFramesPerPacket,
  174. AudioDeviceDescription::kLoopbackInputDeviceId);
  175. EXPECT_EQ(test_stream->Open(), AudioInputStream::OpenOutcome::kSuccess);
  176. test_stream->Close();
  177. }
  178. } // namespace media