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)// The format of these tests are to enqueue a known amount of data and then 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// request the exact amount we expect in order to dequeue the known amount of 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// data. This ensures that for any rate we are consuming input data at the 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// correct rate. We always pass in a very large destination buffer with the 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expectation that FillBuffer() will fill as much as it can but no more. 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <algorithm> // For std::min(). 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <cmath> 13424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include <vector> 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 17424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/audio_buffer.h" 197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/audio_bus.h" 207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/buffers.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "media/base/channel_layout.h" 227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "media/base/test_helpers.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "media/filters/audio_renderer_algorithm.h" 24424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)#include "media/filters/wsola_internals.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace media { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2968043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kFrameSize = 250; 3068043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kSamplesPerSecond = 3000; 3168043e1e95eeb07d5cae7aca370b26518b0867d6Torne (Richard Coles)const int kOutputDurationInSec = 10; 32424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 33424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static void FillWithSquarePulseTrain( 34424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int half_pulse_width, int offset, int num_samples, float* data) { 35424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_GE(offset, 0); 36424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_LE(offset, num_samples); 37424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 38424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill backward from |offset| - 1 toward zero, starting with -1, alternating 39424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // between -1 and 1 every |pulse_width| samples. 40424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float pulse = -1.0f; 41424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = offset - 1, k = 0; n >= 0; --n, ++k) { 42424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (k >= half_pulse_width) { 43424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse = -pulse; 44424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) k = 0; 45424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 46424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data[n] = pulse; 47424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 48424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 49424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill forward from |offset| towards the end, starting with 1, alternating 50424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // between 1 and -1 every |pulse_width| samples. 51424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse = 1.0f; 52424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = offset, k = 0; n < num_samples; ++n, ++k) { 53424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (k >= half_pulse_width) { 54424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse = -pulse; 55424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) k = 0; 56424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 57424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) data[n] = pulse; 58424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 59424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 60424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 61424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)static void FillWithSquarePulseTrain( 62424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int half_pulse_width, int offset, int channel, AudioBus* audio_bus) { 63424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(half_pulse_width, offset, audio_bus->frames(), 64424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) audio_bus->channel(channel)); 65424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioRendererAlgorithmTest : public testing::Test { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererAlgorithmTest() 707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch : frames_enqueued_(0), 717dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channels_(0), 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_(CHANNEL_LAYOUT_NONE), 737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sample_format_(kUnknownSampleFormat), 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) samples_per_second_(0), 757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bytes_per_sample_(0) { 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~AudioRendererAlgorithmTest() {} 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Initialize() { 817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 3000); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void Initialize(ChannelLayout channel_layout, 857dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SampleFormat sample_format, 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int samples_per_second) { 877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channels_ = ChannelLayoutToChannelCount(channel_layout); 8823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) samples_per_second_ = samples_per_second; 8923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_ = channel_layout; 907dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch sample_format_ = sample_format; 917dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bytes_per_sample_ = SampleFormatToBytesPerChannel(sample_format); 927dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AudioParameters params(media::AudioParameters::AUDIO_PCM_LINEAR, 937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch channel_layout, 947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch samples_per_second, 957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bytes_per_sample_ * 8, 967dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch samples_per_second / 100); 975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) algorithm_.Initialize(params); 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillAlgorithmQueue(); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void FillAlgorithmQueue() { 1027dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // The value of the data is meaningless; we just want non-zero data to 1037dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // differentiate it from muted data. 1047dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_refptr<AudioBuffer> buffer; 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) while (!algorithm_.IsQueueFull()) { 1067dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch switch (sample_format_) { 1077dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kSampleFormatU8: 108effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch buffer = MakeAudioBuffer<uint8>( 109effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sample_format_, 110effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_layout_, 111effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ChannelLayoutToChannelCount(channel_layout_), 112effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch samples_per_second_, 113effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 114effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 115effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kFrameSize, 116effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kNoTimestamp()); 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kSampleFormatS16: 119effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch buffer = MakeAudioBuffer<int16>( 120effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sample_format_, 121effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_layout_, 122effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ChannelLayoutToChannelCount(channel_layout_), 123effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch samples_per_second_, 124effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 125effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 126effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kFrameSize, 127effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kNoTimestamp()); 1287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kSampleFormatS32: 130effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch buffer = MakeAudioBuffer<int32>( 131effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch sample_format_, 132effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channel_layout_, 133effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch ChannelLayoutToChannelCount(channel_layout_), 134effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch samples_per_second_, 135effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 136effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch 1, 137effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kFrameSize, 138effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch kNoTimestamp()); 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch default: 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED() << "Unrecognized format " << sample_format_; 1427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1437dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch algorithm_.EnqueueBuffer(buffer); 1447dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch frames_enqueued_ += kFrameSize; 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool AudioDataIsMuted(AudioBus* audio_data, int frames_written) { 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int ch = 0; ch < channels_; ++ch) { 1505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) for (int i = 0; i < frames_written; ++i) { 1515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (audio_data->channel(ch)[i] != 0.0f) 1525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return false; 1535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } 1547dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) return true; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int ComputeConsumedFrames(int initial_frames_enqueued, 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_buffered) { 1607dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frame_delta = frames_enqueued_ - initial_frames_enqueued; 1617dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; 1627dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int consumed = frame_delta - buffered_delta; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(consumed, 0); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return consumed; 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestPlaybackRate(double playback_rate) { 168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kDefaultFramesRequested = kOutputDurationInSec * 170424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) algorithm_.samples_per_second(); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1727dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TestPlaybackRate( 1737dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch playback_rate, kDefaultBufferSize, kDefaultFramesRequested); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestPlaybackRate(double playback_rate, 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size_in_frames, 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_frames_requested) { 1797dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_enqueued = frames_enqueued_; 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_buffered = algorithm_.frames_buffered(); 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1827dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<AudioBus> bus = 1837dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AudioBus::Create(channels_, buffer_size_in_frames); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate == 0.0) { 1855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int frames_written = algorithm_.FillBuffer( 1865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bus.get(), buffer_size_in_frames, playback_rate); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, frames_written); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1915f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) bool expect_muted = (playback_rate < 0.5 || playback_rate > 4); 1925f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_remaining = total_frames_requested; 194424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool first_fill_buffer = true; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (frames_remaining > 0) { 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_requested = std::min(buffer_size_in_frames, frames_remaining); 1975f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int frames_written = 1985f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) algorithm_.FillBuffer(bus.get(), frames_requested, playback_rate); 1997dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested 2007dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << ", playing at " << playback_rate; 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Do not check data if it is first pull out and only one frame written. 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The very first frame out of WSOLA is always zero because of 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // overlap-and-add window, which is zero for the first sample. Therefore, 205424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // if at very first buffer-fill only one frame is written, that is zero 206424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // which might cause exception in CheckFakeData(). 207424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!first_fill_buffer || frames_written > 1) 2085f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) ASSERT_EQ(expect_muted, AudioDataIsMuted(bus.get(), frames_written)); 209424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) first_fill_buffer = false; 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frames_remaining -= frames_written; 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillAlgorithmQueue(); 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2157dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frames_consumed = 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If playing back at normal speed, we should always get back the same 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of bytes requested. 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate == 1.0) { 2217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(total_frames_requested, frames_consumed); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, allow |kMaxAcceptableDelta| difference between the target and 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actual playback rate. 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When |kSamplesPerSecond| and |total_frames_requested| are reasonably 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // large, one can expect less than a 1% difference in most cases. In our 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current implementation, sped up playback is less accurate than slowed 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // down playback, and for playback_rate > 1, playback rate generally gets 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // less and less accurate the farther it drifts from 1 (though this is 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nonlinear). 2337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch double actual_playback_rate = 2347dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1.0 * frames_consumed / total_frames_requested; 2357dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0); 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void WsolaTest(float playback_rate) { 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kSampleRateHz = 48000; 240effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch const ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kBytesPerSample = 2; 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumFrames = kSampleRateHz / 100; // 10 milliseconds. 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channels_ = ChannelLayoutToChannelCount(kChannelLayout); 245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kSampleRateHz, kBytesPerSample * 8, kNumFrames); 2475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) algorithm_.Initialize(params); 248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // A pulse is 6 milliseconds (even number of samples). 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kPulseWidthSamples = 6 * kSampleRateHz / 1000; 251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kHalfPulseWidthSamples = kPulseWidthSamples / 2; 252424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 253424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // For the ease of implementation get 1 frame every call to FillBuffer(). 254424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> output = AudioBus::Create(channels_, 1); 255424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 256424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Input buffer to inject pulses. 25723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<AudioBuffer> input = 25823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AudioBuffer::CreateBuffer(kSampleFormatPlanarF32, 25923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kChannelLayout, 260effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch channels_, 26123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kSampleRateHz, 26223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kPulseWidthSamples); 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<uint8*>& channel_data = input->channel_data(); 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill |input| channels. 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidthSamples, 0, kPulseWidthSamples, 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reinterpret_cast<float*>(channel_data[0])); 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidthSamples, kHalfPulseWidthSamples, 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kPulseWidthSamples, 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reinterpret_cast<float*>(channel_data[1])); 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // A buffer for the output until a complete pulse is created. Then 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // reference pulse is compared with this buffer. 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> pulse_buffer = AudioBus::Create( 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channels_, kPulseWidthSamples); 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kTolerance = 0.000001f; 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Equivalent of 4 seconds. 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples; 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kNumRequestedPulses; ++n) { 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int num_buffered_frames = 0; 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) while (num_buffered_frames < kPulseWidthSamples) { 2845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) int num_samples = algorithm_.FillBuffer(output.get(), 1, playback_rate); 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_LE(num_samples, 1); 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (num_samples > 0) { 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) output->CopyPartialFramesTo(0, num_samples, num_buffered_frames, 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_buffer.get()); 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) num_buffered_frames++; 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) algorithm_.EnqueueBuffer(input); 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Pulses in the first half of WSOLA AOL frame are not constructed 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // perfectly. Do not check them. 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (n > 3) { 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int m = 0; m < channels_; ++m) { 299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float* pulse_ch = pulse_buffer->channel(m); 300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Because of overlap-and-add we might have round off error. 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kPulseWidthSamples; ++k) { 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_NEAR(reinterpret_cast<float*>(channel_data[m])[k], 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_ch[k], kTolerance) << " loop " << n 305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << " channel/sample " << m << "/" << k; 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 309424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 310424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Zero out the buffer to be sure the next comparison is relevant. 311424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_buffer->Zero(); 312424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 313424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 314424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererAlgorithm algorithm_; 3177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frames_enqueued_; 3187dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int channels_; 31923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout_; 3207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SampleFormat sample_format_; 32123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int samples_per_second_; 3227dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int bytes_per_sample_; 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) { 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalFasterRate) { 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.0001); 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalSlowerRate) { 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(0.9999); 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAQuarterRate) { 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.25); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAHalfRate) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_DoubleRate) { 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_EightTimesRate) { 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(8.0); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_ThreeQuartersRate) { 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.75); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_HalfRate) { 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_QuarterRate) { 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_Pause) { 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.0); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SlowDown) { 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(4.5); 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(3.0); 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SpeedUp) { 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(3.0); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(4.5); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_JumpAroundSpeeds) { 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.1); 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.9); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.6); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.4); 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.3); 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) { 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBufferSizeInFrames = 1; 412424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static const int kFramesRequested = kOutputDurationInSec * kSamplesPerSecond; 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested); 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) { 4197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100); 4202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.0); 4212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(0.5); 4222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.5); 4232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) { 4267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) { 4337dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, DotProduct) { 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 3; 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFrames = 20; 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kHalfPulseWidth = 2; 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> b = AudioBus::Create(kChannels, kFrames); 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> dot_prod(new float[kChannels]); 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, a.get()); 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 1, 1, a.get()); 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 2, 2, a.get()); 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, b.get()); 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 1, b.get()); 455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 2, b.get()); 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(a.get(), 0, b.get(), 0, kFrames, 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dot_prod.get()); 459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(kFrames, dot_prod[0]); 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(0, dot_prod[1]); 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(-kFrames, dot_prod[2]); 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(a.get(), 4, b.get(), 8, kFrames / 2, 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dot_prod.get()); 466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(kFrames / 2, dot_prod[0]); 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(0, dot_prod[1]); 469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(-kFrames / 2, dot_prod[2]); 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, MovingBlockEnergy) { 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 2; 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFrames = 20; 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramesPerBlock = 3; 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumBlocks = kFrames - (kFramesPerBlock - 1); 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energies(new float[kChannels * kNumBlocks]); 479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch_left = a->channel(0); 480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch_right = a->channel(1); 481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill up both channels. 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kFrames; ++n) { 484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch_left[n] = n; 485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch_right[n] = kFrames - 1 - n; 486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelMovingBlockEnergies(a.get(), kFramesPerBlock, 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) energies.get()); 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check if the energy of candidate blocks of each channel computed correctly. 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kNumBlocks; ++n) { 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float expected_energy = 0; 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kFramesPerBlock; ++k) 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy += ch_left[n + k] * ch_left[n + k]; 496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Left (first) channel. 498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(expected_energy, energies[2 * n]); 499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy = 0; 501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kFramesPerBlock; ++k) 502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy += ch_right[n + k] * ch_right[n + k]; 503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 504424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Second (right) channel. 505424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(expected_energy, energies[2 * n + 1]); 506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 507424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 508424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 509424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FullAndDecimatedSearch) { 510424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramesInSearchRegion = 12; 511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 2; 512424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float ch_0[] = { 513424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f }; 514424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float ch_1[] = { 515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.1f, 1.0f, 0.1f, 0.0f, 0.0f }; 516424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(sizeof(ch_0), sizeof(ch_1)); 517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(kFramesInSearchRegion), 518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) sizeof(ch_0) / sizeof(*ch_0)); 519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> search_region = AudioBus::Create(kChannels, 520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramesInSearchRegion); 521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch = search_region->channel(0); 522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, ch_0, sizeof(float) * kFramesInSearchRegion); 523424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = search_region->channel(1); 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, ch_1, sizeof(float) * kFramesInSearchRegion); 525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 526424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramePerBlock = 4; 527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float target_0[] = { 1.0f, 1.0f, 1.0f, 0.0f }; 528424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float target_1[] = { 0.0f, 1.0f, 0.1f, 1.0f }; 529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(sizeof(target_0), sizeof(target_1)); 530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(kFramePerBlock), 531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) sizeof(target_0) / sizeof(*target_0)); 532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> target = AudioBus::Create(kChannels, 534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramePerBlock); 535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = target->channel(0); 536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, target_0, sizeof(float) * kFramePerBlock); 537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = target->channel(1); 538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, target_1, sizeof(float) * kFramePerBlock); 539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energy_target(new float[kChannels]); 541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(target.get(), 0, target.get(), 0, 543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramePerBlock, energy_target.get()); 544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(3.f, energy_target[0]); 546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(2.01f, energy_target[1]); 547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumCandidBlocks = kFramesInSearchRegion - (kFramePerBlock - 1); 549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energy_candid_blocks(new float[kNumCandidBlocks * 550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kChannels]); 551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelMovingBlockEnergies( 553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) search_region.get(), kFramePerBlock, energy_candid_blocks.get()); 554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check the energy of the candidate blocks of the first channel. 556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[0]); 557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[2]); 558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1, energy_candid_blocks[4]); 559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(2, energy_candid_blocks[6]); 560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(3, energy_candid_blocks[8]); 561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(3, energy_candid_blocks[10]); 562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(2, energy_candid_blocks[12]); 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1, energy_candid_blocks[14]); 564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[16]); 565424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check the energy of the candidate blocks of the second channel. 567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[1]); 568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[3]); 569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[5]); 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[7]); 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0.01f, energy_candid_blocks[9]); 572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[11]); 573424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[13]); 574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[15]); 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[17]); 576424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 577424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // An interval which is of no effect. 578424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::Interval exclude_interval = std::make_pair(-100, -10); 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(5, internal::FullSearch( 580424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 0, kNumCandidBlocks - 1, exclude_interval, target.get(), 581424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) search_region.get(), energy_target.get(), energy_candid_blocks.get())); 582424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 583424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Exclude the the best match. 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval = std::make_pair(2, 5); 585424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(7, internal::FullSearch( 586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 0, kNumCandidBlocks - 1, exclude_interval, target.get(), 587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) search_region.get(), energy_target.get(), energy_candid_blocks.get())); 588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // An interval which is of no effect. 590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval = std::make_pair(-100, -10); 591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(4, internal::DecimatedSearch( 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4, exclude_interval, target.get(), search_region.get(), 593424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) energy_target.get(), energy_candid_blocks.get())); 594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(5, internal::OptimalIndex(search_region.get(), target.get(), 596424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval)); 597424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 599e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(AudioRendererAlgorithmTest, QuadraticInterpolation) { 600424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Arbitrary coefficients. 601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kA = 0.7f; 602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kB = 1.2f; 603424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kC = 0.8f; 604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 605424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float y_values[3]; 606424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[0] = kA - kB + kC; 607424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[1] = kC; 608424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[2] = kA + kB + kC; 609424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 610424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float extremum; 611424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float extremum_value; 612424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 613e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch internal::QuadraticInterpolation(y_values, &extremum, &extremum_value); 614424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 615424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float x_star = -kB / (2.f * kA); 616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float y_star = kA * x_star * x_star + kB * x_star + kC; 617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 618424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(x_star, extremum); 619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(y_star, extremum_value); 620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 622e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen MurdochTEST_F(AudioRendererAlgorithmTest, QuadraticInterpolation_Colinear) { 623e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch float y_values[3]; 624e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch y_values[0] = 1.0; 625e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch y_values[1] = 1.0; 626e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch y_values[2] = 1.0; 627e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 628e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch float extremum; 629e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch float extremum_value; 630e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 631e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch internal::QuadraticInterpolation(y_values, &extremum, &extremum_value); 632e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 633e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_FLOAT_EQ(extremum, 0.0); 634e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch EXPECT_FLOAT_EQ(extremum_value, 1.0); 635e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch} 636e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch 637424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) { 638424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WsolaTest(0.6f); 639424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 640424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 641424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) { 642424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WsolaTest(1.6f); 643424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 644424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 646