| 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
|
|
|