Index: media/audio/win/audio_input_win_unittest.cc |
diff --git a/media/audio/win/audio_input_win_unittest.cc b/media/audio/win/audio_input_win_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..311f38f7decb76b22d4d7926b9b5b7bcfbe02f92 |
--- /dev/null |
+++ b/media/audio/win/audio_input_win_unittest.cc |
@@ -0,0 +1,184 @@ |
+// 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. |
+ |
+#include <windows.h> |
+ |
+#include "base/basictypes.h" |
+#include "media/audio/audio_io.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace { |
+ |
+// 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 { |
+ public: |
+ explicit TestInputCallback(int max_data_bytes) |
+ : callback_count_(0), |
+ had_error_(0), |
+ was_closed_(0), |
+ max_data_bytes_(max_data_bytes) { |
+ } |
+ virtual void OnData(AudioInputStream* stream, const uint8* data, |
+ uint32 size) { |
+ ++callback_count_; |
+ // 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); |
+ } |
+ } |
+ virtual void OnClose(AudioInputStream* stream) { |
+ ++was_closed_; |
+ } |
+ virtual void OnError(AudioInputStream* stream, int code) { |
+ ++had_error_; |
+ } |
+ // Returns how many times OnData() has been called. |
+ int callback_count() const { |
+ return callback_count_; |
+ } |
+ // Returns how many times the OnError callback was called. |
+ int had_error() const { |
+ return had_error_; |
+ } |
+ |
+ void set_error(bool error) { |
+ had_error_ += error ? 1 : 0; |
+ } |
+ // Returns how many times the OnClose callback was called. |
+ int was_closed() const { |
+ return was_closed_; |
+ } |
+ |
+ private: |
+ int callback_count_; |
+ int had_error_; |
+ int was_closed_; |
+ int max_data_bytes_; |
+}; |
+ |
+// Specializes TestInputCallback to simulate a sink that blocks for some time |
+// in the OnData callback. |
+class TestInputCallbackBlocking : public TestInputCallback { |
+ public: |
+ TestInputCallbackBlocking(int max_data_bytes, int block_after_callback, |
+ int block_for_ms) |
+ : TestInputCallback(max_data_bytes), |
+ block_after_callback_(block_after_callback), |
+ block_for_ms_(block_for_ms) { |
+ } |
+ virtual void OnData(AudioInputStream* stream, const uint8* data, |
+ uint32 size) { |
+ // Call the base, which increments the callback_count_. |
+ TestInputCallback::OnData(stream, data, size); |
+ if (callback_count() > block_after_callback_) |
+ ::Sleep(block_for_ms_); |
+ } |
+ |
+ private: |
+ int block_after_callback_; |
+ int block_for_ms_; |
+}; |
+ |
+bool CanRunAudioTests() { |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ if (NULL == audio_man) |
+ return false; |
+ return (audio_man->HasAudioInputDevices() && |
+ ::GetEnvironmentVariableW(L"CHROME_HEADLESS", NULL, 0) == 0); |
+} |
+ |
+} // namespace. |
+ |
+// Test that AudioInputStream rejects out of range parameters. |
+TEST(WinAudioInputTest, SanityOnMakeParams) { |
+ if (!CanRunAudioTests()) |
+ return; |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ AudioManager::Format fmt = AudioManager::AUDIO_PCM_LINEAR; |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 8, 8000, 16, 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 1, 1024 * 1024, 16, |
+ 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 80, 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 80, |
+ 1024 * 4096)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, -2, 8000, 16, 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, -8000, 16, 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, -16, 0)); |
+ EXPECT_TRUE(NULL == audio_man->MakeAudioInputStream(fmt, 2, 8000, 16, -1024)); |
+} |
+ |
+// Test create and close of an AudioInputStream without recording audio. |
+TEST(WinAudioInputTest, CreateAndClose) { |
+ if (!CanRunAudioTests()) |
+ return; |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ AudioInputStream* ais = audio_man->MakeAudioInputStream( |
+ AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16, 0); |
+ ASSERT_TRUE(NULL != ais); |
+ ais->Close(); |
+} |
+ |
+// Test create, open and close of an AudioInputStream without recording audio. |
+TEST(WinAudioInputTest, OpenAndClose) { |
+ if (!CanRunAudioTests()) |
+ return; |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ AudioInputStream* ais = audio_man->MakeAudioInputStream( |
+ AudioManager::AUDIO_PCM_LINEAR, 2, 8000, 16, 0); |
+ ASSERT_TRUE(NULL != ais); |
+ EXPECT_TRUE(ais->Open()); |
+ ais->Close(); |
+} |
+ |
+// Test a normal recording sequence using an AudioInputStream. |
+TEST(WinAudioInputTest, Record) { |
+ if (!CanRunAudioTests()) |
+ return; |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ const int kSamplingRate = 8000; |
+ const int kSamplesPerPacket = kSamplingRate / 20; |
+ AudioInputStream* ais = audio_man->MakeAudioInputStream( |
+ AudioManager::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16, kSamplesPerPacket); |
+ ASSERT_TRUE(NULL != ais); |
+ 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); |
+ EXPECT_GE(test_callback.callback_count(), 10); |
+ EXPECT_FALSE(test_callback.had_error()); |
+ |
+ ais->Stop(); |
+ ais->Close(); |
+} |
+ |
+// Test a recording sequence with delays in the audio callback. |
+TEST(WinAudioInputTest, RecordWithSlowSink) { |
+ if (!CanRunAudioTests()) |
+ return; |
+ AudioManager* audio_man = AudioManager::GetAudioManager(); |
+ const int kSamplingRate = 8000; |
+ const int kSamplesPerPacket = kSamplingRate / 20; |
+ AudioInputStream* ais = audio_man->MakeAudioInputStream( |
+ AudioManager::AUDIO_PCM_LINEAR, 2, kSamplingRate, 16, kSamplesPerPacket); |
+ ASSERT_TRUE(NULL != ais); |
+ EXPECT_TRUE(ais->Open()); |
+ |
+ // We should normally get a callback every 50ms, and a 20ms delay inside each |
+ // callback should not change this sequence. |
+ TestInputCallbackBlocking test_callback(kSamplesPerPacket * 4, 0, 20); |
+ ais->Start(&test_callback); |
+ // Verify at least 500ms worth of audio was recorded, after giving sufficient |
+ // extra time. |
+ Sleep(590); |
+ EXPECT_GE(test_callback.callback_count(), 10); |
+ EXPECT_FALSE(test_callback.had_error()); |
+ |
+ ais->Stop(); |
+ ais->Close(); |
+} |