audio_renderer_mixer_unittest.cc revision 46d4c2bc3267f3f028f39e7e311b0f89aba2e4fd
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// MSVC++ requires this to be set before any other includes to get M_PI. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define _USE_MATH_DEFINES 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind_helpers.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_vector.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/platform_thread.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer_mixer.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/audio_renderer_mixer_input.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/fake_audio_render_callback.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/base/mock_audio_renderer_sink.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gmock/include/gmock/gmock.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameters which control the many input case tests. 2568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMixerInputs = 8; 2668043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kMixerCycles = 3; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameters used for testing. 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kBitsPerChannel = 32; 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kHighLatencyBufferSize = 8192; 3268043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kLowLatencyBufferSize = 256; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of full sine wave cycles for each Render() call. 3568043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kSineCycles = 4; 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tuple of <input sampling rate, output sampling rate, epsilon>. 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::tr1::tuple<int, int, double> AudioRendererMixerTestData; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioRendererMixerTest 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public testing::TestWithParam<AudioRendererMixerTestData> { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixerTest() 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : epsilon_(std::tr1::get<2>(GetParam())), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) half_fill_(false) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create input and output parameters based on test parameters. 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_parameters_ = AudioParameters( 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize); 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_parameters_ = AudioParameters( 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout, 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sink_ = new MockAudioRendererSink(); 5446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_CALL(*sink_, Start()); 5546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_CALL(*sink_, Stop()); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_.reset(new AudioRendererMixer( 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_parameters_, output_parameters_, sink_)); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_callback_ = sink_->callback(); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_bus_ = AudioBus::Create(output_parameters_); 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_ = AudioBus::Create(output_parameters_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate one callback for generating expected results. 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double step = kSineCycles / static_cast<double>( 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_parameters_.frames_per_buffer()); 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_.reset(new FakeAudioRenderCallback(step)); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixer* GetMixer(const AudioParameters& params) { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mixer_.get(); 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(RemoveMixer, void(const AudioParameters&)); 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitializeInputs(int count) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.reserve(count); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_.reserve(count); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup FakeAudioRenderCallback step to compensate for resampling. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double scale_factor = input_parameters_.sample_rate() / 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<double>(output_parameters_.sample_rate()); 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double step = kSineCycles / (scale_factor * 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<double>(output_parameters_.frames_per_buffer())); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < count; ++i) { 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_.push_back(new FakeAudioRenderCallback(step)); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.push_back(new AudioRendererMixerInput( 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::GetMixer, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::RemoveMixer, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)))); 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->SetVolume(1.0f); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(count); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ValidateAudioData(int index, int frames, float scale, double epsilon) { 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < audio_bus_->channels(); ++i) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = index; j < frames; j++) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double error = fabs(audio_bus_->channel(i)[j] - 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_->channel(i)[j] * scale); 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error > epsilon) { 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NEAR(expected_audio_bus_->channel(i)[j] * scale, 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_bus_->channel(i)[j], epsilon) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " i=" << i << ", j=" << j; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ValidateAudioData(int index, int frames, float scale) { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValidateAudioData(index, frames, scale, epsilon_); 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool RenderAndValidateAudioData(float scale) { 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (half_fill_) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < fake_callbacks_.size(); ++i) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_[i]->set_half_fill(true); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_->set_half_fill(true); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialize the AudioBus completely or we'll run into Valgrind problems 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // during the verification step below. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_->Zero(); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Render actual audio data. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames = mixer_callback_->Render(audio_bus_.get(), 0); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frames != audio_bus_->frames()) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Render expected audio data (without scaling). 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_->Render(expected_audio_bus_.get(), 0); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (half_fill_) { 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this case, just verify that every frame was initialized, this will 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only fail under tooling such as valgrind. 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValidateAudioData( 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, frames, 0, std::numeric_limits<double>::max()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ValidateAudioData(0, frames, scale); 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill |audio_bus_| fully with |value|. 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FillAudioData(float value) { 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < audio_bus_->channels(); ++i) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::fill(audio_bus_->channel(i), 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_bus_->channel(i) + audio_bus_->frames(), value); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify silence when mixer inputs are in pre-Start() and post-Start(). 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartTest(int inputs) { 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify silence before any inputs have been started. Fill the buffer 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before hand with non-zero data to ensure we get zeros back. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all even numbered mixer inputs and ensure we still get silence. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); i += 2) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all mixer inputs and ensure we still get silence. 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in post-Play() state. 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayTest(int inputs) { 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Play() all mixer inputs and ensure we get the right values. 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size())); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify volume adjusted output when mixer inputs are in post-Play() state. 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayVolumeAdjustedTest(int inputs) { 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a different volume for each mixer input and verify the results. 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float total_scale = 0; 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float volume = static_cast<float>(i) / mixer_inputs_.size(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_scale += volume; 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(mixer_inputs_[i]->SetVolume(volume)); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(total_scale)); 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs can only partially fulfill a Render(). 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayPartialRenderTest(int inputs) { 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify a properly filled buffer when half filled (remainder zeroed). 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) half_fill_ = true; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size())); 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in Pause() state. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PauseTest(int inputs) { 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pause() all even numbered mixer inputs and ensure we get the right value. 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); i += 2) 248c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mixer_inputs_[i]->Pause(); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size() / 2)); 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in post-Stop() state. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopTest(int inputs) { 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() and Stop() all inputs. 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify we get silence back; fill |audio_bus_| before hand to be sure. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AudioRendererMixerTest() {} 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockAudioRendererSink> sink_; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioRendererMixer> mixer_; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererSink::RenderCallback* mixer_callback_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters input_parameters_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters output_parameters_; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> audio_bus_; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> expected_audio_bus_; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<FakeAudioRenderCallback> fake_callbacks_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FakeAudioRenderCallback> expected_callback_; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double epsilon_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool half_fill_; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioRendererMixerBehavioralTest : public AudioRendererMixerTest {}; 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P(SignalEvent, event) { 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->Signal(); 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify a mixer with no inputs returns silence for all requested frames. 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, NoInputs) { 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the pre-Start() and post-Start() state. 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputStart) { 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTest(1); 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the pre-Start() and post-Start() state. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputStart) { 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTest(kMixerInputs); 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Play() state. 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlay) { 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayTest(1); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Play() state. 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlay) { 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayTest(kMixerInputs); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test volume adjusted mixer output with one input in the post-Play() state. 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlayVolumeAdjusted) { 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayVolumeAdjustedTest(1); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test volume adjusted mixer output with many inputs in the post-Play() state. 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlayVolumeAdjusted) { 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayVolumeAdjustedTest(kMixerInputs); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input and partial Render() in post-Play() state. 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlayPartialRender) { 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayPartialRenderTest(1); 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs and partial Render() in post-Play() state. 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlayPartialRender) { 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayPartialRenderTest(kMixerInputs); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Pause() state. 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPause) { 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseTest(1); 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Pause() state. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPause) { 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseTest(kMixerInputs); 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Stop() state. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputStop) { 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTest(1); 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Stop() state. 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputStop) { 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTest(kMixerInputs); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer with many inputs in mixed post-Stop() and post-Play() states. 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputMixedStopPlay) { 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(kMixerInputs); 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all inputs. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop() all even numbered mixer inputs and Play() all odd numbered inputs 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and ensure we get the right value. 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) { 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i - 1]->Stop(); 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(std::max( 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.size() / 2, static_cast<size_t>(1)))); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, OnRenderError) { 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(kMixerInputs); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[i]->Play(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*fake_callbacks_[i], OnRenderError()).Times(1); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_callback_->OnRenderError(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 39646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, OnRenderErrorPausedInput) { 39746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) InitializeInputs(kMixerInputs); 39846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 39946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 40046d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) EXPECT_CALL(*fake_callbacks_[i], OnRenderError()).Times(1); 40146d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40246d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // Fire the error before attaching any inputs. Ensure an error is recieved 40346d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) // even if the input is not connected. 40446d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) mixer_callback_->OnRenderError(); 40546d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 40646d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 40746d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) mixer_inputs_[i]->Stop(); 40846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)} 40946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles) 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure constructing an AudioRendererMixerInput, but not initializing it does 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not call RemoveMixer(). 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, NoInitialize) { 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(0); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AudioRendererMixerInput> audio_renderer_mixer = 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AudioRendererMixerInput( 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::GetMixer, 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::RemoveMixer, 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure the physical stream is paused after a certain amount of time with no 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// inputs playing. The test will hang if the behavior is incorrect. 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, MixerPausesStream) { 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kPauseTime = base::TimeDelta::FromMilliseconds(500); 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This value can't be too low or valgrind, tsan will timeout on the bots. 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kTestTimeout = 10 * kPauseTime; 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_->set_pause_delay_for_testing(kPauseTime); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WaitableEvent pause_event(true, false); 431868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*sink_.get(), Pause()).Times(2) 432868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) .WillRepeatedly(SignalEvent(&pause_event)); 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitializeInputs(1); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure never playing the input results in a sink pause. 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kSleepTime = base::TimeDelta::FromMilliseconds(100); 4377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::TimeTicks start_time = base::TimeTicks::Now(); 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!pause_event.IsSignaled()) { 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_callback_->Render(audio_bus_.get(), 0); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThread::Sleep(kSleepTime); 4417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(base::TimeTicks::Now() - start_time < kTestTimeout); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pause_event.Reset(); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Playing the input for the first time should cause a sink play. 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Start(); 447868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) EXPECT_CALL(*sink_.get(), Play()); 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Play(); 449c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mixer_inputs_[0]->Pause(); 4502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure once the input is paused the sink eventually pauses. 4527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) start_time = base::TimeTicks::Now(); 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!pause_event.IsSignaled()) { 4542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_callback_->Render(audio_bus_.get(), 0); 4552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThread::Sleep(kSleepTime); 4567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) ASSERT_TRUE(base::TimeTicks::Now() - start_time < kTestTimeout); 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Stop(); 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixerTest, AudioRendererMixerTest, testing::Values( 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No resampling. 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(44100, 44100, 0.00000048), 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upsampling. 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(44100, 48000, 0.033), 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Downsampling. 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(48000, 41000, 0.042))); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test cases for behavior which is independent of parameters. Values() doesn't 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// support single item lists and we don't want these test cases to run for every 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parameter set. 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)INSTANTIATE_TEST_CASE_P( 4772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioRendererMixerBehavioralTest, AudioRendererMixerBehavioralTest, 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) testing::ValuesIn(std::vector<AudioRendererMixerTestData>( 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, std::tr1::make_tuple(44100, 44100, 0)))); 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 482