Chromium Code Reviews| Index: components/copresence/mediums/audio/audio_player_unittest.cc |
| diff --git a/components/copresence/mediums/audio/audio_player_unittest.cc b/components/copresence/mediums/audio/audio_player_unittest.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..1a0e6f73f70e789ac97a4b018417ea7fbfab1c08 |
| --- /dev/null |
| +++ b/components/copresence/mediums/audio/audio_player_unittest.cc |
| @@ -0,0 +1,193 @@ |
| +// Copyright 2014 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 "components/copresence/mediums/audio/audio_player.h" |
| + |
| +#include <cstdlib> |
| + |
| +#include "base/bind.h" |
| +#include "base/memory/weak_ptr.h" |
| +#include "components/copresence/common/copresence_constants.h" |
| +#include "media/audio/audio_manager.h" |
| +#include "media/audio/audio_manager_base.h" |
| +#include "media/base/audio_bus.h" |
| +#include "testing/gtest/include/gtest/gtest.h" |
| + |
| +namespace { |
| + |
| +class TestAudioOutputStream : public media::AudioOutputStream { |
| + public: |
| + typedef base::Callback<void(scoped_ptr<media::AudioBus>, int frames)> |
| + GatherSamplesCallback; |
| + TestAudioOutputStream(int default_frame_count, |
| + int max_frame_count, |
| + GatherSamplesCallback gather_callback) |
| + : default_frame_count_(default_frame_count), |
| + max_frame_count_(max_frame_count), |
| + gather_callback_(gather_callback), |
| + callback_(NULL) { |
| + caller_loop_ = base::MessageLoop::current(); |
| + } |
| + |
| + virtual ~TestAudioOutputStream() {} |
| + |
| + virtual bool Open() OVERRIDE { return true; } |
| + virtual void Start(AudioSourceCallback* callback) OVERRIDE { |
| + callback_ = callback; |
| + GatherPlayedSamples(); |
| + } |
| + virtual void Stop() OVERRIDE {} |
| + virtual void SetVolume(double volume) OVERRIDE {} |
| + virtual void GetVolume(double* volume) OVERRIDE {} |
| + virtual void Close() OVERRIDE {} |
| + |
| + private: |
| + void GatherPlayedSamples() { |
| + int frames = 0, total_frames = 0; |
| + do { |
| + scoped_ptr<media::AudioBus> dest = |
| + media::AudioBus::Create(1, default_frame_count_); |
| + frames = callback_->OnMoreData(dest.get(), media::AudioBuffersState()); |
| + total_frames += frames; |
|
Daniel Erat
2014/07/28 21:18:18
does this mean that total_frames can exceed max_fr
rkc
2014/07/29 00:33:35
If total_frames equals the max frame count, we bre
|
| + caller_loop_->PostTask( |
| + FROM_HERE, base::Bind(gather_callback_, base::Passed(&dest), frames)); |
| + } while (frames && total_frames < max_frame_count_); |
| + } |
| + |
| + int default_frame_count_; |
| + int max_frame_count_; |
| + GatherSamplesCallback gather_callback_; |
| + AudioSourceCallback* callback_; |
| + base::MessageLoop* caller_loop_; |
| + |
| + DISALLOW_COPY_AND_ASSIGN(TestAudioOutputStream); |
| +}; |
| + |
| +} // namespace |
| + |
| +namespace copresence { |
| + |
| +class AudioPlayerTest : public testing::Test, |
| + public base::SupportsWeakPtr<AudioPlayerTest> { |
| + public: |
| + AudioPlayerTest() : buffer_index_(0), player_(NULL) { |
| + if (!media::AudioManager::Get()) |
| + media::AudioManager::CreateForTesting(); |
| + } |
| + |
| + virtual ~AudioPlayerTest() { DeletePlayer(); } |
| + |
| + void CreatePlayer() { |
| + DeletePlayer(); |
| + player_ = new AudioPlayer(new TestAudioOutputStream( |
| + kDefaultFrameCount, |
| + kMaxFrameCount, |
| + base::Bind(&AudioPlayerTest::GatherSamples, AsWeakPtr()))); |
| + } |
| + |
| + void DeletePlayer() { |
| + if (!player_) |
| + return; |
| + player_->Finalize(); |
| + player_ = NULL; |
| + } |
| + |
| + void PlayAndVerifySamples( |
| + const scoped_refptr<media::AudioBusRefCounted>& samples) { |
| + buffer_ = media::AudioBus::Create(1, kMaxFrameCount); |
| + player_->Play(samples); |
| + player_->FlushAudioLoop(); |
| + |
| + int differences = 0; |
| + for (int i = 0; i < samples->frames(); ++i) |
| + differences += (buffer_->channel(0)[i] != samples->channel(0)[i]); |
| + ASSERT_EQ(0, differences); |
|
Daniel Erat
2014/07/28 21:18:18
is it worthwhile logging the indices of the frames
rkc
2014/07/29 00:33:35
Not really. If we have any differences at all, thi
|
| + |
| + buffer_.reset(); |
| + } |
| + |
| + void GatherSamples(scoped_ptr<media::AudioBus> bus, int frames) { |
| + if (!buffer_.get()) |
| + return; |
| + bus->CopyPartialFramesTo(0, frames, buffer_index_, buffer_.get()); |
| + buffer_index_ += frames; |
| + } |
| + |
| + protected: |
| + // Populate random samples given a random seed into the samples array. |
| + void PopulateSamples(int random_seed, size_t size, float* samples) { |
|
Daniel Erat
2014/07/28 21:18:18
this seems like it's duplicated across multiple fi
rkc
2014/07/29 00:33:35
Done.
|
| + srand(random_seed); |
| + for (size_t i = 0; i < size; ++i) |
| + samples[i] = (2.0 * rand() / RAND_MAX) - 1; |
| + } |
| + |
| + static const int kDefaultFrameCount = 1024; |
| + static const int kMaxFrameCount = 1024 * 10; |
| + |
| + scoped_ptr<media::AudioBus> buffer_; |
| + int buffer_index_; |
| + |
| + AudioPlayer* player_; |
| + |
| + base::MessageLoop message_loop_; |
| +}; |
| + |
| +TEST_F(AudioPlayerTest, BasicPlayAndStop) { |
| + CreatePlayer(); |
| + scoped_refptr<media::AudioBusRefCounted> samples = |
| + media::AudioBusRefCounted::Create(1, 7331); |
| + |
| + player_->Play(samples); |
| + EXPECT_TRUE(player_->IsPlaying()); |
| + player_->Stop(); |
| + EXPECT_FALSE(player_->IsPlaying()); |
| + player_->Play(samples); |
| + |
| + EXPECT_TRUE(player_->IsPlaying()); |
| + player_->Stop(); |
| + EXPECT_FALSE(player_->IsPlaying()); |
| + player_->Play(samples); |
| + |
| + EXPECT_TRUE(player_->IsPlaying()); |
| + player_->Stop(); |
| + EXPECT_FALSE(player_->IsPlaying()); |
| + |
| + DeletePlayer(); |
| +} |
| + |
| +TEST_F(AudioPlayerTest, OutOfOrderPlayAndStopMultiple) { |
| + CreatePlayer(); |
| + scoped_refptr<media::AudioBusRefCounted> samples = |
| + media::AudioBusRefCounted::Create(1, 1337); |
| + |
| + player_->Stop(); |
| + player_->Stop(); |
| + player_->Stop(); |
| + EXPECT_FALSE(player_->IsPlaying()); |
| + |
| + player_->Play(samples); |
| + player_->Play(samples); |
| + EXPECT_TRUE(player_->IsPlaying()); |
| + |
| + player_->Stop(); |
| + player_->Stop(); |
| + EXPECT_FALSE(player_->IsPlaying()); |
| + |
| + DeletePlayer(); |
| +} |
| + |
| +TEST_F(AudioPlayerTest, RecordingEndToEnd) { |
| + const int kNumSamples = kDefaultFrameCount * 10; |
| + CreatePlayer(); |
| + |
| + scoped_refptr<media::AudioBusRefCounted> samples = |
| + media::AudioBusRefCounted::Create(1, kNumSamples); |
| + PopulateSamples(0x1337, kNumSamples, samples->channel(0)); |
| + |
| + PlayAndVerifySamples(samples); |
| + |
| + DeletePlayer(); |
| +} |
| + |
| +} // namespace copresence |