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 "base/basictypes.h" 6 #include "base/environment.h" 7 #include "base/memory/scoped_ptr.h" 8 #include "base/message_loop/message_loop.h" 9 #include "base/threading/platform_thread.h" 10 #include "media/audio/audio_io.h" 11 #include "media/audio/audio_manager_base.h" 12 #include "testing/gtest/include/gtest/gtest.h" 13 14 namespace media { 15 16 static const int kSamplingRate = 8000; 17 static const int kSamplesPerPacket = kSamplingRate / 20; 18 19 // This class allows to find out if the callbacks are occurring as 20 // expected and if any error has been reported. 21 class TestInputCallback : public AudioInputStream::AudioInputCallback { 22 public: 23 explicit TestInputCallback(int max_data_bytes) 24 : callback_count_(0), 25 had_error_(0), 26 max_data_bytes_(max_data_bytes) { 27 } 28 virtual void OnData(AudioInputStream* stream, 29 const uint8* data, 30 uint32 size, 31 uint32 hardware_delay_bytes, 32 double volume) OVERRIDE { 33 ++callback_count_; 34 // Read the first byte to make sure memory is good. 35 if (size) { 36 ASSERT_LE(static_cast<int>(size), max_data_bytes_); 37 int value = data[0]; 38 EXPECT_GE(value, 0); 39 } 40 } 41 virtual void OnClose(AudioInputStream* stream) OVERRIDE {} 42 virtual void OnError(AudioInputStream* stream) OVERRIDE { 43 ++had_error_; 44 } 45 // Returns how many times OnData() has been called. 46 int callback_count() const { 47 return callback_count_; 48 } 49 // Returns how many times the OnError callback was called. 50 int had_error() const { 51 return had_error_; 52 } 53 54 private: 55 int callback_count_; 56 int had_error_; 57 int max_data_bytes_; 58 }; 59 60 static bool CanRunAudioTests(AudioManager* audio_man) { 61 bool has_input = audio_man->HasAudioInputDevices(); 62 63 if (!has_input) 64 LOG(WARNING) << "No input devices detected"; 65 66 return has_input; 67 } 68 69 static AudioInputStream* CreateTestAudioInputStream(AudioManager* audio_man) { 70 AudioInputStream* ais = audio_man->MakeAudioInputStream( 71 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_STEREO, 72 kSamplingRate, 16, kSamplesPerPacket), 73 AudioManagerBase::kDefaultDeviceId); 74 EXPECT_TRUE(NULL != ais); 75 return ais; 76 } 77 78 // Test that AudioInputStream rejects out of range parameters. 79 TEST(AudioInputTest, SanityOnMakeParams) { 80 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 81 if (!CanRunAudioTests(audio_man.get())) 82 return; 83 84 AudioParameters::Format fmt = AudioParameters::AUDIO_PCM_LINEAR; 85 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 86 AudioParameters(fmt, CHANNEL_LAYOUT_7_1, 8000, 16, 87 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 88 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 89 AudioParameters(fmt, CHANNEL_LAYOUT_MONO, 1024 * 1024, 16, 90 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 91 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 92 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 93 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 94 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 95 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 80, 96 1000 * kSamplesPerPacket), 97 AudioManagerBase::kDefaultDeviceId)); 98 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 99 AudioParameters(fmt, CHANNEL_LAYOUT_UNSUPPORTED, 8000, 16, 100 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 101 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 102 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, -8000, 16, 103 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 104 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 105 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, -16, 106 kSamplesPerPacket), AudioManagerBase::kDefaultDeviceId)); 107 EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream( 108 AudioParameters(fmt, CHANNEL_LAYOUT_STEREO, 8000, 16, -1024), 109 AudioManagerBase::kDefaultDeviceId)); 110 } 111 112 // Test create and close of an AudioInputStream without recording audio. 113 TEST(AudioInputTest, CreateAndClose) { 114 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 115 if (!CanRunAudioTests(audio_man.get())) 116 return; 117 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 118 ais->Close(); 119 } 120 121 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 122 // This test is failing on ARM linux: http://crbug.com/238490 123 #define MAYBE_OpenAndClose DISABLED_OpenAndClose 124 #else 125 #define MAYBE_OpenAndClose OpenAndClose 126 #endif 127 // Test create, open and close of an AudioInputStream without recording audio. 128 TEST(AudioInputTest, MAYBE_OpenAndClose) { 129 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 130 if (!CanRunAudioTests(audio_man.get())) 131 return; 132 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 133 EXPECT_TRUE(ais->Open()); 134 ais->Close(); 135 } 136 137 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 138 // This test is failing on ARM linux: http://crbug.com/238490 139 #define MAYBE_OpenStopAndClose DISABLED_OpenStopAndClose 140 #else 141 #define MAYBE_OpenStopAndClose OpenStopAndClose 142 #endif 143 // Test create, open, stop and close of an AudioInputStream without recording. 144 TEST(AudioInputTest, MAYBE_OpenStopAndClose) { 145 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 146 if (!CanRunAudioTests(audio_man.get())) 147 return; 148 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 149 EXPECT_TRUE(ais->Open()); 150 ais->Stop(); 151 ais->Close(); 152 } 153 154 #if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(ARCH_CPU_ARM_FAMILY) 155 // This test is failing on ARM linux: http://crbug.com/238490 156 #define MAYBE_Record DISABLED_Record 157 #else 158 #define MAYBE_Record Record 159 #endif 160 // Test a normal recording sequence using an AudioInputStream. 161 TEST(AudioInputTest, MAYBE_Record) { 162 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); 163 if (!CanRunAudioTests(audio_man.get())) 164 return; 165 base::MessageLoop message_loop(base::MessageLoop::TYPE_DEFAULT); 166 AudioInputStream* ais = CreateTestAudioInputStream(audio_man.get()); 167 EXPECT_TRUE(ais->Open()); 168 169 TestInputCallback test_callback(kSamplesPerPacket * 4); 170 ais->Start(&test_callback); 171 // Verify at least 500ms worth of audio was recorded, after giving sufficient 172 // extra time. 173 message_loop.PostDelayedTask( 174 FROM_HERE, 175 base::MessageLoop::QuitClosure(), 176 base::TimeDelta::FromMilliseconds(690)); 177 message_loop.Run(); 178 EXPECT_GE(test_callback.callback_count(), 1); 179 EXPECT_FALSE(test_callback.had_error()); 180 181 ais->Stop(); 182 ais->Close(); 183 } 184 185 } // namespace media 186