audio_renderer_mixer_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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. 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMixerInputs = 8; 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kMixerCycles = 3; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Parameters used for testing. 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kBitsPerChannel = 32; 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHighLatencyBufferSize = 8192; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kLowLatencyBufferSize = 256; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSampleRate = 48000; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Number of full sine wave cycles for each Render() call. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kSineCycles = 4; 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tuple of <input sampling rate, output sampling rate, epsilon>. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)typedef std::tr1::tuple<int, int, double> AudioRendererMixerTestData; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioRendererMixerTest 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public testing::TestWithParam<AudioRendererMixerTestData> { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixerTest() 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : epsilon_(std::tr1::get<2>(GetParam())), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) half_fill_(false) { 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create input and output parameters based on test parameters. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_parameters_ = AudioParameters( 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::get<0>(GetParam()), kBitsPerChannel, kHighLatencyBufferSize); 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_parameters_ = AudioParameters( 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters::AUDIO_PCM_LOW_LATENCY, kChannelLayout, 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::get<1>(GetParam()), 16, kLowLatencyBufferSize); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sink_ = new MockAudioRendererSink(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*sink_, Start()); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*sink_, Stop()); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_.reset(new AudioRendererMixer( 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) input_parameters_, output_parameters_, sink_)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_callback_ = sink_->callback(); 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_bus_ = AudioBus::Create(output_parameters_); 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_ = AudioBus::Create(output_parameters_); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Allocate one callback for generating expected results. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double step = kSineCycles / static_cast<double>( 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) output_parameters_.frames_per_buffer()); 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_.reset(new FakeAudioRenderCallback(step)); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixer* GetMixer(const AudioParameters& params) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return mixer_.get(); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MOCK_METHOD1(RemoveMixer, void(const AudioParameters&)); 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InitializeInputs(int count) { 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.reserve(count); 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_.reserve(count); 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Setup FakeAudioRenderCallback step to compensate for resampling. 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) double scale_factor = input_parameters_.sample_rate() / 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) static_cast<double>(output_parameters_.sample_rate()); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double step = kSineCycles / (scale_factor * 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<double>(output_parameters_.frames_per_buffer())); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < count; ++i) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_.push_back(new FakeAudioRenderCallback(step)); 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.push_back(new AudioRendererMixerInput( 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::GetMixer, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::RemoveMixer, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)))); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Initialize(input_parameters_, fake_callbacks_[i]); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->SetVolume(1.0f); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(count); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ValidateAudioData(int index, int frames, float scale, double epsilon) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < audio_bus_->channels(); ++i) { 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = index; j < frames; j++) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double error = fabs(audio_bus_->channel(i)[j] - 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_->channel(i)[j] * scale); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (error > epsilon) { 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_NEAR(expected_audio_bus_->channel(i)[j] * scale, 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_bus_->channel(i)[j], epsilon) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << " i=" << i << ", j=" << j; 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool ValidateAudioData(int index, int frames, float scale) { 1172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValidateAudioData(index, frames, scale, epsilon_); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool RenderAndValidateAudioData(float scale) { 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (half_fill_) { 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < fake_callbacks_.size(); ++i) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) fake_callbacks_[i]->set_half_fill(true); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_->set_half_fill(true); 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Initialize the AudioBus completely or we'll run into Valgrind problems 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // during the verification step below. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_audio_bus_->Zero(); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Render actual audio data. 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames = mixer_callback_->Render(audio_bus_.get(), 0); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (frames != audio_bus_->frames()) 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Render expected audio data (without scaling). 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) expected_callback_->Render(expected_audio_bus_.get(), 0); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (half_fill_) { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // In this case, just verify that every frame was initialized, this will 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // only fail under tooling such as valgrind. 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ValidateAudioData( 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 0, frames, 0, std::numeric_limits<double>::max()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ValidateAudioData(0, frames, scale); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Fill |audio_bus_| fully with |value|. 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void FillAudioData(float value) { 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < audio_bus_->channels(); ++i) { 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::fill(audio_bus_->channel(i), 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_bus_->channel(i) + audio_bus_->frames(), value); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify silence when mixer inputs are in pre-Start() and post-Start(). 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StartTest(int inputs) { 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify silence before any inputs have been started. Fill the buffer 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before hand with non-zero data to ensure we get zeros back. 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all even numbered mixer inputs and ensure we still get silence. 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); i += 2) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all mixer inputs and ensure we still get silence. 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in post-Play() state. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayTest(int inputs) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Play() all mixer inputs and ensure we get the right values. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size())); 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify volume adjusted output when mixer inputs are in post-Play() state. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayVolumeAdjustedTest(int inputs) { 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set a different volume for each mixer input and verify the results. 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float total_scale = 0; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) float volume = static_cast<float>(i) / mixer_inputs_.size(); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_scale += volume; 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(mixer_inputs_[i]->SetVolume(volume)); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(total_scale)); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs can only partially fulfill a Render(). 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PlayPartialRenderTest(int inputs) { 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify a properly filled buffer when half filled (remainder zeroed). 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) half_fill_ = true; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size())); 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in Pause() state. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void PauseTest(int inputs) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pause() all even numbered mixer inputs and ensure we get the right value. 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); i += 2) 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mixer_inputs_[i]->Pause(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kMixerCycles; ++i) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(mixer_inputs_.size() / 2)); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify output when mixer inputs are in post-Stop() state. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void StopTest(int inputs) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(inputs); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() and Stop() all inputs. 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify we get silence back; fill |audio_bus_| before hand to be sure. 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AudioRendererMixerTest() {} 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<MockAudioRendererSink> sink_; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioRendererMixer> mixer_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererSink::RenderCallback* mixer_callback_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters input_parameters_; 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioParameters output_parameters_; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> audio_bus_; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioBus> expected_audio_bus_; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector< scoped_refptr<AudioRendererMixerInput> > mixer_inputs_; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ScopedVector<FakeAudioRenderCallback> fake_callbacks_; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<FakeAudioRenderCallback> expected_callback_; 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) double epsilon_; 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool half_fill_; 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AudioRendererMixerTest); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class AudioRendererMixerBehavioralTest : public AudioRendererMixerTest {}; 2922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ACTION_P(SignalEvent, event) { 2942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) event->Signal(); 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Verify a mixer with no inputs returns silence for all requested frames. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, NoInputs) { 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FillAudioData(1.0f); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(RenderAndValidateAudioData(0.0f)); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the pre-Start() and post-Start() state. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputStart) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTest(1); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the pre-Start() and post-Start() state. 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputStart) { 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StartTest(kMixerInputs); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Play() state. 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlay) { 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayTest(1); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Play() state. 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlay) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayTest(kMixerInputs); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test volume adjusted mixer output with one input in the post-Play() state. 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlayVolumeAdjusted) { 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayVolumeAdjustedTest(1); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test volume adjusted mixer output with many inputs in the post-Play() state. 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlayVolumeAdjusted) { 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayVolumeAdjustedTest(kMixerInputs); 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input and partial Render() in post-Play() state. 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPlayPartialRender) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayPartialRenderTest(1); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs and partial Render() in post-Play() state. 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPlayPartialRender) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlayPartialRenderTest(kMixerInputs); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Pause() state. 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputPause) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseTest(1); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Pause() state. 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputPause) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PauseTest(kMixerInputs); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with one input in the post-Stop() state. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, OneInputStop) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTest(1); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer output with many inputs in the post-Stop() state. 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputStop) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) StopTest(kMixerInputs); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test mixer with many inputs in mixed post-Stop() and post-Play() states. 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_P(AudioRendererMixerTest, ManyInputMixedStopPlay) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(kMixerInputs); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start() all inputs. 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop() all even numbered mixer inputs and Play() all odd numbered inputs 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and ensure we get the right value. 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) { 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i - 1]->Stop(); 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Play(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(RenderAndValidateAudioData(std::max( 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_.size() / 2, static_cast<size_t>(1)))); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 1; i < mixer_inputs_.size(); i += 2) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, OnRenderError) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InitializeInputs(kMixerInputs); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) { 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Start(); 3882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[i]->Play(); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*fake_callbacks_[i], OnRenderError()).Times(1); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_callback_->OnRenderError(); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t i = 0; i < mixer_inputs_.size(); ++i) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) mixer_inputs_[i]->Stop(); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Ensure constructing an AudioRendererMixerInput, but not initializing it does 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not call RemoveMixer(). 3992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, NoInitialize) { 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_CALL(*this, RemoveMixer(testing::_)).Times(0); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<AudioRendererMixerInput> audio_renderer_mixer = 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new AudioRendererMixerInput( 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::GetMixer, 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this)), 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&AudioRendererMixerTest::RemoveMixer, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Unretained(this))); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Ensure the physical stream is paused after a certain amount of time with no 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// inputs playing. The test will hang if the behavior is incorrect. 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_P(AudioRendererMixerBehavioralTest, MixerPausesStream) { 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kPauseTime = base::TimeDelta::FromMilliseconds(500); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This value can't be too low or valgrind, tsan will timeout on the bots. 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kTestTimeout = 10 * kPauseTime; 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_->set_pause_delay_for_testing(kPauseTime); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::WaitableEvent pause_event(true, false); 418c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_CALL(*sink_, Pause()) 4192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) .Times(2).WillRepeatedly(SignalEvent(&pause_event)); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) InitializeInputs(1); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure never playing the input results in a sink pause. 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::TimeDelta kSleepTime = base::TimeDelta::FromMilliseconds(100); 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Time start_time = base::Time::Now(); 4252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!pause_event.IsSignaled()) { 4262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_callback_->Render(audio_bus_.get(), 0); 4272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThread::Sleep(kSleepTime); 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(base::Time::Now() - start_time < kTestTimeout); 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) pause_event.Reset(); 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Playing the input for the first time should cause a sink play. 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Start(); 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_CALL(*sink_, Play()); 4352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Play(); 436c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) mixer_inputs_[0]->Pause(); 4372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Ensure once the input is paused the sink eventually pauses. 4392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) start_time = base::Time::Now(); 4402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!pause_event.IsSignaled()) { 4412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_callback_->Render(audio_bus_.get(), 0); 4422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::PlatformThread::Sleep(kSleepTime); 4432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(base::Time::Now() - start_time < kTestTimeout); 4442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 4452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) mixer_inputs_[0]->Stop(); 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)INSTANTIATE_TEST_CASE_P( 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererMixerTest, AudioRendererMixerTest, testing::Values( 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // No resampling. 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(44100, 44100, 0.00000048), 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Upsampling. 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(44100, 48000, 0.033), 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Downsampling. 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::tr1::make_tuple(48000, 41000, 0.042))); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Test cases for behavior which is independent of parameters. Values() doesn't 4612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// support single item lists and we don't want these test cases to run for every 4622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// parameter set. 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)INSTANTIATE_TEST_CASE_P( 4642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) AudioRendererMixerBehavioralTest, AudioRendererMixerBehavioralTest, 4652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) testing::ValuesIn(std::vector<AudioRendererMixerTestData>( 4662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1, std::tr1::make_tuple(44100, 44100, 0)))); 4672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 469