Index: chromecast/media/audio/cast_audio_stream_test.cc |
diff --git a/chromecast/media/audio/cast_audio_stream_test.cc b/chromecast/media/audio/cast_audio_stream_test.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..9fa2e432943c9ddfc7a25e12d028f60243d12ebf |
--- /dev/null |
+++ b/chromecast/media/audio/cast_audio_stream_test.cc |
@@ -0,0 +1,169 @@ |
+// Copyright 2015 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 "base/at_exit.h" |
+#include "base/basictypes.h" |
+#include "base/bind.h" |
+#include "base/command_line.h" |
+#include "base/location.h" |
+#include "base/single_thread_task_runner.h" |
+#include "base/synchronization/waitable_event.h" |
+#include "base/thread_task_runner_handle.h" |
+#include "base/threading/thread.h" |
+#include "chromecast/media/audio/cast_audio_manager_factory.h" |
+#include "chromecast/public/cast_media_shlib.h" |
+#include "media/audio/audio_io.h" |
+#include "media/audio/audio_manager_base.h" |
+#include "media/audio/audio_manager_factory.h" |
+#include "media/audio/simple_sources.h" |
+#include "media/base/bind_to_current_loop.h" |
+#include "media/base/data_buffer.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace chromecast { |
+namespace media { |
+ |
+namespace { |
+base::WaitableEvent g_event(false, false); |
+ |
+class SineWaveRenderer { |
+ public: |
+ SineWaveRenderer(int sampling_frequency, int sine_frequency) |
+ : sampling_frequency_(sampling_frequency) { |
+ sine_wave_source_.reset(new ::media::SineWaveAudioSource( |
+ 1, sine_frequency, sampling_frequency_)); |
+ } |
+ |
+ void Play(const base::TimeDelta& sine_duration, |
+ const base::Closure& playback_done_cb) { |
+ playback_done_cb_ = playback_done_cb; |
+ ::media::AudioParameters params( |
+ ::media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
+ ::media::CHANNEL_LAYOUT_STEREO, |
+ sampling_frequency_, |
+ 16, |
+ 1024); |
+ |
+ audio_output_stream_ = |
+ ::media::AudioManager::Get()->MakeAudioOutputStream(params, ""); |
+ DCHECK(audio_output_stream_); |
+ audio_output_stream_->Open(); |
+ |
+ base::ThreadTaskRunnerHandle::Get()->PostDelayedTask( |
+ FROM_HERE, |
+ base::Bind(&SineWaveRenderer::OnPlaybackDone, base::Unretained(this)), |
+ sine_duration); |
+ audio_output_stream_->SetVolume(0.01); |
+ audio_output_stream_->Start(sine_wave_source_.get()); |
+ } |
+ |
+ protected: |
+ void OnPlaybackDone() { |
+ audio_output_stream_->Close(); |
+ audio_output_stream_ = NULL; |
+ playback_done_cb_.Run(); |
+ } |
+ |
+ private: |
+ int sampling_frequency_; |
+ scoped_ptr< ::media::SineWaveAudioSource> sine_wave_source_; |
+ ::media::AudioOutputStream* audio_output_stream_; |
+ base::Closure playback_done_cb_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(SineWaveRenderer); |
+}; |
+ |
+} // namespace |
+ |
+class AudioOutputStreamTest : public testing::Test { |
+ public: |
+ void OnPlaybackDone(); |
+ |
+ protected: |
+ AudioOutputStreamTest(); |
+ ~AudioOutputStreamTest() override; |
+ |
+ // testing::Test implementation: |
+ void SetUp() override; |
+ void TearDown() override; |
+ |
+ int sine_count_; |
+ |
+ private: |
+ scoped_ptr< ::media::AudioManager> audio_manager_; |
+ |
+ DISALLOW_COPY_AND_ASSIGN(AudioOutputStreamTest); |
+}; |
+ |
+AudioOutputStreamTest::AudioOutputStreamTest() : sine_count_(0) { |
+} |
+ |
+AudioOutputStreamTest::~AudioOutputStreamTest() { |
+} |
+ |
+void AudioOutputStreamTest::SetUp() { |
+ ASSERT_TRUE(base::CommandLine::InitializedForCurrentProcess()); |
+ |
+ // Initialize the presentation engine. |
+ chromecast::media::CastMediaShlib::Initialize( |
+ base::CommandLine::ForCurrentProcess()->argv()); |
+ |
+ ::media::AudioManager::SetFactory(new CastAudioManagerFactory()); |
+ audio_manager_.reset(::media::AudioManager::CreateForTesting()); |
+} |
+ |
+void AudioOutputStreamTest::TearDown() { |
+ ::media::AudioManager::ResetFactoryForTesting(); |
+ |
+ // These must be called to reset underlying static instances. |
+ chromecast::media::CastMediaShlib::Finalize(); |
+} |
+ |
+void AudioOutputStreamTest::OnPlaybackDone() { |
+ sine_count_--; |
+ if (sine_count_ == 0) { |
+ g_event.Signal(); |
+ } |
+} |
+ |
+TEST_F(AudioOutputStreamTest, PlaybackSineWaves) { |
+ const base::TimeDelta duration(base::TimeDelta::FromSeconds(10)); |
+ const int sampling_frequency = 32000; |
+ |
+ scoped_ptr<base::Thread> audio_thread(new base::Thread("AudioThread")); |
+ audio_thread->Start(); |
+ |
+ base::Closure on_playback_done = base::Bind( |
+ &AudioOutputStreamTest::OnPlaybackDone, base::Unretained(this)); |
+ |
+ ++sine_count_; |
+ SineWaveRenderer renderer(sampling_frequency, 440); |
+ audio_thread->task_runner()->PostTask(FROM_HERE, |
+ base::Bind(&SineWaveRenderer::Play, |
+ base::Unretained(&renderer), |
+ duration, |
+ on_playback_done)); |
+ |
+ ++sine_count_; |
+ SineWaveRenderer renderer2(sampling_frequency, 330); |
+ audio_thread->task_runner()->PostTask(FROM_HERE, |
+ base::Bind(&SineWaveRenderer::Play, |
+ base::Unretained(&renderer2), |
+ duration, |
+ on_playback_done)); |
+ |
+ ++sine_count_; |
+ SineWaveRenderer renderer3(sampling_frequency, 220); |
+ audio_thread->task_runner()->PostTask(FROM_HERE, |
+ base::Bind(&SineWaveRenderer::Play, |
+ base::Unretained(&renderer3), |
+ duration, |
+ on_playback_done)); |
+ |
+ g_event.Wait(); |
+ audio_thread.reset(); |
+} |
+ |
+} // namespace media |
+} // namespace chromecast |