diff options
author | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 16:16:49 +0000 |
---|---|---|
committer | satish@chromium.org <satish@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-09-02 16:16:49 +0000 |
commit | 3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50 (patch) | |
tree | 3b19af016ec61763cbe6e4f5c925a5fbd3ac0c64 | |
parent | 4f8452d18c71301f141795eb95a9c2e0a8358aaf (diff) | |
download | chromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.zip chromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.tar.gz chromium_src-3af7229b4f97f17b4f2aee34bd3ef3af7fd16e50.tar.bz2 |
This test now works for the mac audio capture code as well, and in a future CL I'll enable audio recording in linux and this test will suit that code too.
In the process I changed a uint32 in a function prototype to int because style guide recommends int for such cases. I also added parameter validation code to the mac audio manager to get it pass this new test.
BUG=none
TEST=media_unittests should succeed as before.
Review URL: http://codereview.chromium.org/3357004
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@58365 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | media/audio/audio_input_unittest.cc (renamed from media/audio/win/audio_input_win_unittest.cc) | 85 | ||||
-rw-r--r-- | media/audio/audio_manager.cc | 2 | ||||
-rw-r--r-- | media/audio/audio_manager.h | 2 | ||||
-rw-r--r-- | media/audio/linux/audio_manager_linux.cc | 2 | ||||
-rw-r--r-- | media/audio/linux/audio_manager_linux.h | 2 | ||||
-rw-r--r-- | media/audio/mac/audio_input_mac.cc | 2 | ||||
-rw-r--r-- | media/audio/mac/audio_input_mac.h | 2 | ||||
-rw-r--r-- | media/audio/mac/audio_input_mac_unittest.cc | 105 | ||||
-rw-r--r-- | media/audio/mac/audio_manager_mac.cc | 10 | ||||
-rw-r--r-- | media/audio/mac/audio_manager_mac.h | 2 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.cc | 2 | ||||
-rw-r--r-- | media/audio/win/audio_manager_win.h | 2 | ||||
-rw-r--r-- | media/media.gyp | 3 |
13 files changed, 69 insertions, 152 deletions
diff --git a/media/audio/win/audio_input_win_unittest.cc b/media/audio/audio_input_unittest.cc index 39cc3fba..6a67f0c 100644 --- a/media/audio/win/audio_input_win_unittest.cc +++ b/media/audio/audio_input_unittest.cc @@ -2,15 +2,20 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include <windows.h> - #include "base/basictypes.h" +#include "base/environment.h" +#include "base/message_loop.h" +#include "base/platform_thread.h" +#include "base/scoped_ptr.h" #include "media/audio/audio_io.h" #include "media/audio/audio_manager.h" #include "testing/gtest/include/gtest/gtest.h" namespace { +const int kSamplingRate = 8000; +const int kSamplesPerPacket = kSamplingRate / 20; + // This class allows to find out if the callbacks are occurring as // expected and if any error has been reported. class TestInputCallback : public AudioInputStream::AudioInputCallback { @@ -27,7 +32,8 @@ class TestInputCallback : public AudioInputStream::AudioInputCallback { // Read the first byte to make sure memory is good. if (size) { ASSERT_LE(static_cast<int>(size), max_data_bytes_); - EXPECT_TRUE(data[0] >= 0); + int value = data[0]; + EXPECT_TRUE(value >= 0); } } virtual void OnClose(AudioInputStream* stream) { @@ -75,7 +81,7 @@ class TestInputCallbackBlocking : public TestInputCallback { // Call the base, which increments the callback_count_. TestInputCallback::OnData(stream, data, size); if (callback_count() > block_after_callback_) - ::Sleep(block_for_ms_); + PlatformThread::Sleep(block_for_ms_); } private: @@ -84,17 +90,30 @@ class TestInputCallbackBlocking : public TestInputCallback { }; bool CanRunAudioTests() { + scoped_ptr<base::Environment> env(base::Environment::Create()); + if (env->HasVar("CHROME_HEADLESS")) + return false; + AudioManager* audio_man = AudioManager::GetAudioManager(); if (NULL == audio_man) return false; - return (audio_man->HasAudioInputDevices() && - ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0) == 0); + + return audio_man->HasAudioInputDevices(); +} + +AudioInputStream* CreateTestAudioInputStream() { + AudioManager* audio_man = AudioManager::GetAudioManager(); + AudioInputStream* ais = audio_man->MakeAudioInputStream( + AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), + kSamplesPerPacket); + EXPECT_TRUE(NULL != ais); + return ais; } } // namespace. // Test that AudioInputStream rejects out of range parameters. -TEST(WinAudioInputTest, SanityOnMakeParams) { +TEST(AudioInputTest, SanityOnMakeParams) { if (!CanRunAudioTests()) return; AudioManager* audio_man = AudioManager::GetAudioManager(); @@ -118,46 +137,46 @@ TEST(WinAudioInputTest, SanityOnMakeParams) { } // Test create and close of an AudioInputStream without recording audio. -TEST(WinAudioInputTest, CreateAndClose) { +TEST(AudioInputTest, CreateAndClose) { if (!CanRunAudioTests()) return; - AudioManager* audio_man = AudioManager::GetAudioManager(); - AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0); - ASSERT_TRUE(NULL != ais); + AudioInputStream* ais = CreateTestAudioInputStream(); ais->Close(); } // Test create, open and close of an AudioInputStream without recording audio. -TEST(WinAudioInputTest, OpenAndClose) { +TEST(AudioInputTest, OpenAndClose) { if (!CanRunAudioTests()) return; - AudioManager* audio_man = AudioManager::GetAudioManager(); - AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, 8000, 16), 0); - ASSERT_TRUE(NULL != ais); + AudioInputStream* ais = CreateTestAudioInputStream(); EXPECT_TRUE(ais->Open()); ais->Close(); } +// Test create, open, stop and close of an AudioInputStream without recording. +TEST(AudioInputTest, OpenStopAndClose) { + if (!CanRunAudioTests()) + return; + AudioInputStream* ais = CreateTestAudioInputStream(); + EXPECT_TRUE(ais->Open()); + ais->Stop(); + ais->Close(); +} + // Test a normal recording sequence using an AudioInputStream. -TEST(WinAudioInputTest, Record) { +TEST(AudioInputTest, Record) { if (!CanRunAudioTests()) return; - AudioManager* audio_man = AudioManager::GetAudioManager(); - const int kSamplingRate = 8000; - const int kSamplesPerPacket = kSamplingRate / 20; - AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), - kSamplesPerPacket); - ASSERT_TRUE(NULL != ais); + MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); + AudioInputStream* ais = CreateTestAudioInputStream(); EXPECT_TRUE(ais->Open()); TestInputCallback test_callback(kSamplesPerPacket * 4); ais->Start(&test_callback); // Verify at least 500ms worth of audio was recorded, after giving sufficient // extra time. - Sleep(590); + message_loop.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), 590); + message_loop.Run(); EXPECT_GE(test_callback.callback_count(), 10); EXPECT_FALSE(test_callback.had_error()); @@ -166,16 +185,11 @@ TEST(WinAudioInputTest, Record) { } // Test a recording sequence with delays in the audio callback. -TEST(WinAudioInputTest, RecordWithSlowSink) { +TEST(AudioInputTest, RecordWithSlowSink) { if (!CanRunAudioTests()) return; - AudioManager* audio_man = AudioManager::GetAudioManager(); - const int kSamplingRate = 8000; - const int kSamplesPerPacket = kSamplingRate / 20; - AudioInputStream* ais = audio_man->MakeAudioInputStream( - AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16), - kSamplesPerPacket); - ASSERT_TRUE(NULL != ais); + MessageLoop message_loop(MessageLoop::TYPE_DEFAULT); + AudioInputStream* ais = CreateTestAudioInputStream(); EXPECT_TRUE(ais->Open()); // We should normally get a callback every 50ms, and a 20ms delay inside each @@ -184,7 +198,8 @@ TEST(WinAudioInputTest, RecordWithSlowSink) { ais->Start(&test_callback); // Verify at least 500ms worth of audio was recorded, after giving sufficient // extra time. - Sleep(590); + message_loop.PostDelayedTask(FROM_HERE, new MessageLoop::QuitTask(), 590); + message_loop.Run(); EXPECT_GE(test_callback.callback_count(), 10); EXPECT_FALSE(test_callback.had_error()); diff --git a/media/audio/audio_manager.cc b/media/audio/audio_manager.cc index 7bb2402..3abd010 100644 --- a/media/audio/audio_manager.cc +++ b/media/audio/audio_manager.cc @@ -25,7 +25,7 @@ class NullAudioManager : public AudioManager { return NULL; } virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - uint32 samples_per_packet) { + int samples_per_packet) { NOTIMPLEMENTED(); return NULL; } diff --git a/media/audio/audio_manager.h b/media/audio/audio_manager.h index 2c988ba..805db89 100644 --- a/media/audio/audio_manager.h +++ b/media/audio/audio_manager.h @@ -54,7 +54,7 @@ class AudioManager { // Do not free the returned AudioInputStream. It is owned by AudioManager. // When you are done with it, call |Stop()| and |Close()| to release it. virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - uint32 samples_per_packet) = 0; + int samples_per_packet) = 0; // Muting continues playback but effectively the volume is set to zero. // Un-muting returns the volume to the previous level. diff --git a/media/audio/linux/audio_manager_linux.cc b/media/audio/linux/audio_manager_linux.cc index 00f23b1a..40a8783 100644 --- a/media/audio/linux/audio_manager_linux.cc +++ b/media/audio/linux/audio_manager_linux.cc @@ -50,7 +50,7 @@ AudioOutputStream* AudioManagerLinux::MakeAudioOutputStream( } AudioInputStream* AudioManagerLinux::MakeAudioInputStream( - AudioParameters params, uint32 samples_per_packet) { + AudioParameters params, int samples_per_packet) { if (params.format == AudioParameters::AUDIO_MOCK) { return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); } diff --git a/media/audio/linux/audio_manager_linux.h b/media/audio/linux/audio_manager_linux.h index f13e1a8..afa60af 100644 --- a/media/audio/linux/audio_manager_linux.h +++ b/media/audio/linux/audio_manager_linux.h @@ -28,7 +28,7 @@ class AudioManagerLinux : public AudioManagerBase { virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); virtual AudioInputStream* MakeAudioInputStream( - AudioParameters params, uint32 samples_per_packet); + AudioParameters params, int samples_per_packet); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/mac/audio_input_mac.cc b/media/audio/mac/audio_input_mac.cc index 9705cb30..88db2db 100644 --- a/media/audio/mac/audio_input_mac.cc +++ b/media/audio/mac/audio_input_mac.cc @@ -19,7 +19,7 @@ enum { PCMQueueInAudioInputStream::PCMQueueInAudioInputStream( AudioManagerMac* manager, AudioParameters params, - uint32 samples_per_buffer) + int samples_per_buffer) : manager_(manager), callback_(NULL), audio_queue_(NULL), diff --git a/media/audio/mac/audio_input_mac.h b/media/audio/mac/audio_input_mac.h index c232d85..8b049f7 100644 --- a/media/audio/mac/audio_input_mac.h +++ b/media/audio/mac/audio_input_mac.h @@ -20,7 +20,7 @@ class PCMQueueInAudioInputStream : public AudioInputStream { // Parameters as per AudioManager::MakeAudioInputStream. PCMQueueInAudioInputStream(AudioManagerMac* manager, AudioParameters params, - uint32 samples_per_packet); + int samples_per_packet); virtual ~PCMQueueInAudioInputStream(); // Implementation of AudioInputStream. diff --git a/media/audio/mac/audio_input_mac_unittest.cc b/media/audio/mac/audio_input_mac_unittest.cc deleted file mode 100644 index da0c918..0000000 --- a/media/audio/mac/audio_input_mac_unittest.cc +++ /dev/null @@ -1,105 +0,0 @@ -// Copyright (c) 2010 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. - -// Tests the mac audio input stream implementation. -// TODO(joth): See if we can generalize this for all platforms? - -#include "base/time.h" -#include "media/audio/audio_io.h" -#include "media/audio/audio_manager.h" -#include "testing/gmock/include/gmock/gmock.h" -#include "testing/gtest/include/gtest/gtest.h" - -using ::testing::AllOf; -using ::testing::AtLeast; -using ::testing::Gt; -using ::testing::Le; -using ::testing::NotNull; -using ::testing::StrictMock; - -class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { - public: - MOCK_METHOD3(OnData, void(AudioInputStream* stream, const uint8* src, - uint32 size)); - MOCK_METHOD1(OnClose, void(AudioInputStream* stream)); - MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code)); -}; - -// Test fixture. -class AudioInputStreamMacTest : public testing::Test { - protected: - // From testing::Test. - virtual void SetUp() { - ias_ = NULL; - AudioManager* audio_man = AudioManager::GetAudioManager(); - ASSERT_TRUE(NULL != audio_man); - if (audio_man->HasAudioInputDevices()) { - AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, 2, - kSampleRate, 16); - ias_ = audio_man->MakeAudioInputStream(params, kSamplesPerCall); - } - } - virtual void TearDown() { - ias_->Close(); - } - - bool TestEnabled() const { - return NULL != ias_; - } - - static const int kSampleRate = 8000; - static const int kSamplesPerCall = 3000; - // This is the default callback implementation; it will assert the expected - // calls were received when it is destroyed. - StrictMock<MockAudioInputCallback> client_; - // The audio input stream under test. - AudioInputStream* ias_; -}; - -// Test that can it be created and closed. -TEST_F(AudioInputStreamMacTest, PCMInputStreamCreateAndClose) { - if (!TestEnabled()) - return; -} - -// Test that it can be opened and closed. -TEST_F(AudioInputStreamMacTest, PCMInputStreamOpenAndClose) { - if (!TestEnabled()) - return; - EXPECT_TRUE(ias_->Open()); -} - -// Test we handle a open then stop OK. -TEST_F(AudioInputStreamMacTest, PCMInputStreamOpenTheStop) { - if (!TestEnabled()) - return; - EXPECT_TRUE(ias_->Open()); - ias_->Stop(); -} - -// Record for a short time then stop. Make sure we get the callbacks. -TEST_F(AudioInputStreamMacTest, PCMInputStreamRecordCoupleSeconds) { - if (!TestEnabled()) - return; - ASSERT_TRUE(ias_->Open()); - // For a given sample rate, number of samples per callback, and recording time - // we can estimate the number of callbacks we should get. We underestimate - // this slightly, as the callback thread could be slow. - static const double kRecordPeriodSecs = 1.5; - static const int kMinExpectedCalls = - (kRecordPeriodSecs * kSampleRate / kSamplesPerCall) - 1; - // Check this is in reasonable bounds. - EXPECT_GT(kMinExpectedCalls, 1); - EXPECT_LT(kMinExpectedCalls, 10); - - static const uint kMaxBytesPerCall = 2 * 2 * kSamplesPerCall; - EXPECT_CALL(client_, OnData(ias_, NotNull(), - AllOf(Gt(0u), Le(kMaxBytesPerCall)))) - .Times(AtLeast(kMinExpectedCalls)); - EXPECT_CALL(client_, OnClose(ias_)); - - ias_->Start(&client_); - usleep(kRecordPeriodSecs * base::Time::kMicrosecondsPerSecond); - ias_->Stop(); -} diff --git a/media/audio/mac/audio_manager_mac.cc b/media/audio/mac/audio_manager_mac.cc index dde2917..1eb9398 100644 --- a/media/audio/mac/audio_manager_mac.cc +++ b/media/audio/mac/audio_manager_mac.cc @@ -9,8 +9,12 @@ #include "media/audio/mac/audio_input_mac.h" #include "media/audio/mac/audio_manager_mac.h" #include "media/audio/mac/audio_output_mac.h" +#include "media/base/limits.h" namespace { +const int kMaxInputChannels = 2; +const int kMaxSamplesPerPacket = media::Limits::kMaxSampleRate; + bool HasAudioHardware(AudioObjectPropertySelector selector) { AudioDeviceID output_device_id = kAudioObjectUnknown; const AudioObjectPropertyAddress property_address = { @@ -48,7 +52,11 @@ AudioOutputStream* AudioManagerMac::MakeAudioOutputStream( } AudioInputStream* AudioManagerMac::MakeAudioInputStream( - AudioParameters params, uint32 samples_per_packet) { + AudioParameters params, int samples_per_packet) { + if (!params.IsValid() || (params.channels > kMaxInputChannels) || + (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) + return NULL; + if (params.format == AudioParameters::AUDIO_MOCK) { return FakeAudioInputStream::MakeFakeStream(params, samples_per_packet); } else if (params.format == AudioParameters::AUDIO_PCM_LINEAR) { diff --git a/media/audio/mac/audio_manager_mac.h b/media/audio/mac/audio_manager_mac.h index 53df700..3abfab1 100644 --- a/media/audio/mac/audio_manager_mac.h +++ b/media/audio/mac/audio_manager_mac.h @@ -23,7 +23,7 @@ class AudioManagerMac : public AudioManagerBase { virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - uint32 samples_per_packet); + int samples_per_packet); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/audio/win/audio_manager_win.cc b/media/audio/win/audio_manager_win.cc index f1c88e3..2e65879 100644 --- a/media/audio/win/audio_manager_win.cc +++ b/media/audio/win/audio_manager_win.cc @@ -65,7 +65,7 @@ AudioOutputStream* AudioManagerWin::MakeAudioOutputStream( // Factory for the implementations of AudioInputStream. AudioInputStream* AudioManagerWin::MakeAudioInputStream( - AudioParameters params, uint32 samples_per_packet) { + AudioParameters params, int samples_per_packet) { if (!params.IsValid() || (params.channels > kWinMaxInputChannels) || (samples_per_packet > kMaxSamplesPerPacket) || (samples_per_packet < 0)) return NULL; diff --git a/media/audio/win/audio_manager_win.h b/media/audio/win/audio_manager_win.h index 61c7b33..09f0019 100644 --- a/media/audio/win/audio_manager_win.h +++ b/media/audio/win/audio_manager_win.h @@ -24,7 +24,7 @@ class AudioManagerWin : public AudioManagerBase { virtual bool HasAudioInputDevices(); virtual AudioOutputStream* MakeAudioOutputStream(AudioParameters params); virtual AudioInputStream* MakeAudioInputStream(AudioParameters params, - uint32 samples_per_packet); + int samples_per_packet); virtual void MuteAll(); virtual void UnMuteAll(); diff --git a/media/media.gyp b/media/media.gyp index 6b56922..70e7c26 100644 --- a/media/media.gyp +++ b/media/media.gyp @@ -238,14 +238,13 @@ ], 'sources': [ 'audio/audio_input_controller_unittest.cc', + 'audio/audio_input_unittest.cc', 'audio/audio_output_controller_unittest.cc', 'audio/audio_util_unittest.cc', 'audio/fake_audio_input_stream_unittest.cc', 'audio/linux/alsa_output_unittest.cc', - 'audio/mac/audio_input_mac_unittest.cc', 'audio/mac/audio_output_mac_unittest.cc', 'audio/simple_sources_unittest.cc', - 'audio/win/audio_input_win_unittest.cc', 'audio/win/audio_output_win_unittest.cc', 'base/clock_impl_unittest.cc', 'base/data_buffer_unittest.cc', |