audio_renderer_algorithm_unittest.cc revision 23730a6e56a168d1879203e4b3819bb36e3d8f1f
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); 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) algorithm_.Initialize(1, 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: 108a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffer = MakeAudioBuffer<uint8>(sample_format_, 10923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_, 11023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) samples_per_second_, 111a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 112a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 113a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kFrameSize, 114a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp(), 115a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp()); 1167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1177dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kSampleFormatS16: 118a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffer = MakeAudioBuffer<int16>(sample_format_, 11923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_, 12023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) samples_per_second_, 121a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 122a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 123a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kFrameSize, 124a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp(), 125a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp()); 1267dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch case kSampleFormatS32: 128a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) buffer = MakeAudioBuffer<int32>(sample_format_, 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) channel_layout_, 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) samples_per_second_, 131a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 132a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) 1, 133a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kFrameSize, 134a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp(), 135a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles) kNoTimestamp()); 1367dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch break; 1377dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch default: 1387dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch NOTREACHED() << "Unrecognized format " << sample_format_; 1397dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1407dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch algorithm_.EnqueueBuffer(buffer); 1417dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch frames_enqueued_ += kFrameSize; 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1457dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch void CheckFakeData(AudioBus* audio_data, int frames_written) { 1467dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch // Check each channel individually. 1477dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int ch = 0; ch < channels_; ++ch) { 1487dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch bool all_zero = true; 1497dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch for (int i = 0; i < frames_written && all_zero; ++i) 1507dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch all_zero = audio_data->channel(ch)[i] == 0.0f; 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ASSERT_FALSE(all_zero) << " for channel " << ch; 1527dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch } 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1557dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int ComputeConsumedFrames(int initial_frames_enqueued, 1567dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_buffered) { 1577dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frame_delta = frames_enqueued_ - initial_frames_enqueued; 1587dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int buffered_delta = algorithm_.frames_buffered() - initial_frames_buffered; 1597dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int consumed = frame_delta - buffered_delta; 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CHECK_GE(consumed, 0); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return consumed; 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestPlaybackRate(double playback_rate) { 165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const int kDefaultBufferSize = algorithm_.samples_per_second() / 100; 166424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kDefaultFramesRequested = kOutputDurationInSec * 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) algorithm_.samples_per_second(); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1697dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch TestPlaybackRate( 1707dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch playback_rate, kDefaultBufferSize, kDefaultFramesRequested); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void TestPlaybackRate(double playback_rate, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int buffer_size_in_frames, 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_frames_requested) { 1767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_enqueued = frames_enqueued_; 1777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int initial_frames_buffered = algorithm_.frames_buffered(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) algorithm_.SetPlaybackRate(static_cast<float>(playback_rate)); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1807dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch scoped_ptr<AudioBus> bus = 1817dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch AudioBus::Create(channels_, buffer_size_in_frames); 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate == 0.0) { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_written = 1847dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch algorithm_.FillBuffer(bus.get(), buffer_size_in_frames); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_EQ(0, frames_written); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_remaining = total_frames_requested; 190424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool first_fill_buffer = true; 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (frames_remaining > 0) { 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int frames_requested = std::min(buffer_size_in_frames, frames_remaining); 1937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frames_written = algorithm_.FillBuffer(bus.get(), frames_requested); 1947dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ASSERT_GT(frames_written, 0) << "Requested: " << frames_requested 1957dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch << ", playing at " << playback_rate; 196424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 197424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Do not check data if it is first pull out and only one frame written. 198424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // The very first frame out of WSOLA is always zero because of 199424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // overlap-and-add window, which is zero for the first sample. Therefore, 200424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // if at very first buffer-fill only one frame is written, that is zero 201424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // which might cause exception in CheckFakeData(). 202424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!first_fill_buffer || frames_written > 1) 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) CheckFakeData(bus.get(), frames_written); 204424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) first_fill_buffer = false; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) frames_remaining -= frames_written; 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FillAlgorithmQueue(); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2107dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frames_consumed = 2117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch ComputeConsumedFrames(initial_frames_enqueued, initial_frames_buffered); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If playing back at normal speed, we should always get back the same 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number of bytes requested. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (playback_rate == 1.0) { 2167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_EQ(total_frames_requested, frames_consumed); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Otherwise, allow |kMaxAcceptableDelta| difference between the target and 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // actual playback rate. 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // When |kSamplesPerSecond| and |total_frames_requested| are reasonably 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // large, one can expect less than a 1% difference in most cases. In our 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // current implementation, sped up playback is less accurate than slowed 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // down playback, and for playback_rate > 1, playback rate generally gets 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // less and less accurate the farther it drifts from 1 (though this is 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nonlinear). 2287dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch double actual_playback_rate = 2297dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch 1.0 * frames_consumed / total_frames_requested; 2307dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch EXPECT_NEAR(playback_rate, actual_playback_rate, playback_rate / 100.0); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 233424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) void WsolaTest(float playback_rate) { 234424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kSampleRateHz = 48000; 235424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const media::ChannelLayout kChannelLayout = CHANNEL_LAYOUT_STEREO; 236424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kBytesPerSample = 2; 237424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumFrames = kSampleRateHz / 100; // 10 milliseconds. 238424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 239424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channels_ = ChannelLayoutToChannelCount(kChannelLayout); 240424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, kChannelLayout, 241424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kSampleRateHz, kBytesPerSample * 8, kNumFrames); 242424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) algorithm_.Initialize(playback_rate, params); 243424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 244424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // A pulse is 6 milliseconds (even number of samples). 245424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kPulseWidthSamples = 6 * kSampleRateHz / 1000; 246424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kHalfPulseWidthSamples = kPulseWidthSamples / 2; 247424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 248424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // For the ease of implementation get 1 frame every call to FillBuffer(). 249424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> output = AudioBus::Create(channels_, 1); 250424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 251424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Input buffer to inject pulses. 25223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) scoped_refptr<AudioBuffer> input = 25323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) AudioBuffer::CreateBuffer(kSampleFormatPlanarF32, 25423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kChannelLayout, 25523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kSampleRateHz, 25623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) kPulseWidthSamples); 257424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 258424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const std::vector<uint8*>& channel_data = input->channel_data(); 259424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 260424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill |input| channels. 261424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidthSamples, 0, kPulseWidthSamples, 262424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reinterpret_cast<float*>(channel_data[0])); 263424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidthSamples, kHalfPulseWidthSamples, 264424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kPulseWidthSamples, 265424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) reinterpret_cast<float*>(channel_data[1])); 266424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 267424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // A buffer for the output until a complete pulse is created. Then 268424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // reference pulse is compared with this buffer. 269424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> pulse_buffer = AudioBus::Create( 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) channels_, kPulseWidthSamples); 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 272424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kTolerance = 0.000001f; 273424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Equivalent of 4 seconds. 274424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumRequestedPulses = kSampleRateHz * 4 / kPulseWidthSamples; 275424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kNumRequestedPulses; ++n) { 276424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int num_buffered_frames = 0; 277424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) while (num_buffered_frames < kPulseWidthSamples) { 278424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) int num_samples = algorithm_.FillBuffer(output.get(), 1); 279424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_LE(num_samples, 1); 280424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (num_samples > 0) { 281424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) output->CopyPartialFramesTo(0, num_samples, num_buffered_frames, 282424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_buffer.get()); 283424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) num_buffered_frames++; 284424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } else { 285424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) algorithm_.EnqueueBuffer(input); 286424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 287424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 288424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 289424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Pulses in the first half of WSOLA AOL frame are not constructed 290424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // perfectly. Do not check them. 291424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (n > 3) { 292424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int m = 0; m < channels_; ++m) { 293424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float* pulse_ch = pulse_buffer->channel(m); 294424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 295424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Because of overlap-and-add we might have round off error. 296424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kPulseWidthSamples; ++k) { 297424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_NEAR(reinterpret_cast<float*>(channel_data[m])[k], 298424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_ch[k], kTolerance) << " loop " << n 299424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) << " channel/sample " << m << "/" << k; 300424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 301424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 302424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 303424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 304424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Zero out the buffer to be sure the next comparison is relevant. 305424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) pulse_buffer->Zero(); 306424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 307424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 308424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioRendererAlgorithm algorithm_; 3117dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int frames_enqueued_; 3127dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int channels_; 31323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) ChannelLayout channel_layout_; 3147dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch SampleFormat sample_format_; 31523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) int samples_per_second_; 3167dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch int bytes_per_sample_; 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NormalRate) { 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalFasterRate) { 3252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.0001); 3272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_NearlyNormalSlowerRate) { 3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Initialize(); 3312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(0.9999); 3322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAQuarterRate) { 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.25); 3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_OneAndAHalfRate) { 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_DoubleRate) { 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_EightTimesRate) { 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(8.0); 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_ThreeQuartersRate) { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.75); 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_HalfRate) { 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_QuarterRate) { 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_Pause) { 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.0); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SlowDown) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(4.5); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(3.0); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SpeedUp) { 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.25); 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.0); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(3.0); 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(4.5); 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_JumpAroundSpeeds) { 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(2.1); 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.9); 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.6); 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.4); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.3); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_SmallBufferSize) { 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Initialize(); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kBufferSizeInFrames = 1; 406424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) static const int kFramesRequested = kOutputDurationInSec * kSamplesPerSecond; 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0, kBufferSizeInFrames, kFramesRequested); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5, kBufferSizeInFrames, kFramesRequested); 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5, kBufferSizeInFrames, kFramesRequested); 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_LargeBufferSize) { 4137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS16, 44100); 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.0); 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(0.5); 4162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestPlaybackRate(1.5); 4172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 4182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_LowerQualityAudio) { 4207dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_MONO, kSampleFormatU8, kSamplesPerSecond); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FillBuffer_HigherQualityAudio) { 4277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch Initialize(CHANNEL_LAYOUT_STEREO, kSampleFormatS32, kSamplesPerSecond); 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.0); 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(0.5); 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestPlaybackRate(1.5); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 433424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, DotProduct) { 434424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 3; 435424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFrames = 20; 436424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kHalfPulseWidth = 2; 437424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 438424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); 439424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> b = AudioBus::Create(kChannels, kFrames); 440424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 441424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> dot_prod(new float[kChannels]); 442424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 443424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, a.get()); 444424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 1, 1, a.get()); 445424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 2, 2, a.get()); 446424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 447424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 0, b.get()); 448424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 1, b.get()); 449424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) FillWithSquarePulseTrain(kHalfPulseWidth, 0, 2, b.get()); 450424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 451424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(a.get(), 0, b.get(), 0, kFrames, 452424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dot_prod.get()); 453424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 454424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(kFrames, dot_prod[0]); 455424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(0, dot_prod[1]); 456424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(-kFrames, dot_prod[2]); 457424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 458424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(a.get(), 4, b.get(), 8, kFrames / 2, 459424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) dot_prod.get()); 460424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 461424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(kFrames / 2, dot_prod[0]); 462424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(0, dot_prod[1]); 463424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(-kFrames / 2, dot_prod[2]); 464424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 465424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 466424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, MovingBlockEnergy) { 467424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 2; 468424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFrames = 20; 469424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramesPerBlock = 3; 470424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumBlocks = kFrames - (kFramesPerBlock - 1); 471424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> a = AudioBus::Create(kChannels, kFrames); 472424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energies(new float[kChannels * kNumBlocks]); 473424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch_left = a->channel(0); 474424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch_right = a->channel(1); 475424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 476424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Fill up both channels. 477424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kFrames; ++n) { 478424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch_left[n] = n; 479424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch_right[n] = kFrames - 1 - n; 480424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 481424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 482424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelMovingBlockEnergies(a.get(), kFramesPerBlock, 483424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) energies.get()); 484424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 485424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check if the energy of candidate blocks of each channel computed correctly. 486424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int n = 0; n < kNumBlocks; ++n) { 487424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float expected_energy = 0; 488424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kFramesPerBlock; ++k) 489424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy += ch_left[n + k] * ch_left[n + k]; 490424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 491424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Left (first) channel. 492424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(expected_energy, energies[2 * n]); 493424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 494424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy = 0; 495424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) for (int k = 0; k < kFramesPerBlock; ++k) 496424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) expected_energy += ch_right[n + k] * ch_right[n + k]; 497424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 498424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Second (right) channel. 499424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(expected_energy, energies[2 * n + 1]); 500424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 501424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 502424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 503424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, FullAndDecimatedSearch) { 504424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramesInSearchRegion = 12; 505424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kChannels = 2; 506424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float ch_0[] = { 507424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (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 }; 508424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float ch_1[] = { 509424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (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 }; 510424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(sizeof(ch_0), sizeof(ch_1)); 511424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(kFramesInSearchRegion), 512424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) sizeof(ch_0) / sizeof(*ch_0)); 513424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> search_region = AudioBus::Create(kChannels, 514424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramesInSearchRegion); 515424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float* ch = search_region->channel(0); 516424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, ch_0, sizeof(float) * kFramesInSearchRegion); 517424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = search_region->channel(1); 518424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, ch_1, sizeof(float) * kFramesInSearchRegion); 519424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 520424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kFramePerBlock = 4; 521424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float target_0[] = { 1.0f, 1.0f, 1.0f, 0.0f }; 522424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float target_1[] = { 0.0f, 1.0f, 0.1f, 1.0f }; 523424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(sizeof(target_0), sizeof(target_1)); 524424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(static_cast<size_t>(kFramePerBlock), 525424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) sizeof(target_0) / sizeof(*target_0)); 526424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 527424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<AudioBus> target = AudioBus::Create(kChannels, 528424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramePerBlock); 529424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = target->channel(0); 530424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, target_0, sizeof(float) * kFramePerBlock); 531424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ch = target->channel(1); 532424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) memcpy(ch, target_1, sizeof(float) * kFramePerBlock); 533424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 534424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energy_target(new float[kChannels]); 535424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 536424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelDotProduct(target.get(), 0, target.get(), 0, 537424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kFramePerBlock, energy_target.get()); 538424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 539424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(3.f, energy_target[0]); 540424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_EQ(2.01f, energy_target[1]); 541424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 542424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const int kNumCandidBlocks = kFramesInSearchRegion - (kFramePerBlock - 1); 543424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) scoped_ptr<float[]> energy_candid_blocks(new float[kNumCandidBlocks * 544424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) kChannels]); 545424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 546424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::MultiChannelMovingBlockEnergies( 547424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) search_region.get(), kFramePerBlock, energy_candid_blocks.get()); 548424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 549424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check the energy of the candidate blocks of the first channel. 550424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[0]); 551424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[2]); 552424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1, energy_candid_blocks[4]); 553424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(2, energy_candid_blocks[6]); 554424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(3, energy_candid_blocks[8]); 555424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(3, energy_candid_blocks[10]); 556424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(2, energy_candid_blocks[12]); 557424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1, energy_candid_blocks[14]); 558424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[16]); 559424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 560424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Check the energy of the candidate blocks of the second channel. 561424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[1]); 562424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[3]); 563424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[5]); 564424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0, energy_candid_blocks[7]); 565424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(0.01f, energy_candid_blocks[9]); 566424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[11]); 567424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[13]); 568424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.02f, energy_candid_blocks[15]); 569424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ASSERT_FLOAT_EQ(1.01f, energy_candid_blocks[17]); 570424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 571424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // An interval which is of no effect. 572424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::Interval exclude_interval = std::make_pair(-100, -10); 573424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(5, internal::FullSearch( 574424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 0, kNumCandidBlocks - 1, exclude_interval, target.get(), 575424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) search_region.get(), energy_target.get(), energy_candid_blocks.get())); 576424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 577424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Exclude the the best match. 578424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval = std::make_pair(2, 5); 579424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(7, 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) // An interval which is of no effect. 584424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval = std::make_pair(-100, -10); 585424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(4, internal::DecimatedSearch( 586424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 4, exclude_interval, target.get(), search_region.get(), 587424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) energy_target.get(), energy_candid_blocks.get())); 588424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 589424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_EQ(5, internal::OptimalIndex(search_region.get(), target.get(), 590424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) exclude_interval)); 591424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 592424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 593424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, CubicInterpolation) { 594424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Arbitrary coefficients. 595424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kA = 0.7f; 596424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kB = 1.2f; 597424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) const float kC = 0.8f; 598424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 599424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float y_values[3]; 600424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[0] = kA - kB + kC; 601424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[1] = kC; 602424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) y_values[2] = kA + kB + kC; 603424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 604424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float extremum; 605424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float extremum_value; 606424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 607424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) internal::CubicInterpolation(y_values, &extremum, &extremum_value); 608424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 609424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float x_star = -kB / (2.f * kA); 610424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) float y_star = kA * x_star * x_star + kB * x_star + kC; 611424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 612424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(x_star, extremum); 613424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) EXPECT_FLOAT_EQ(y_star, extremum_value); 614424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 615424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 616424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, WsolaSlowdown) { 617424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WsolaTest(0.6f); 618424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 619424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 620424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)TEST_F(AudioRendererAlgorithmTest, WsolaSpeedup) { 621424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) WsolaTest(1.6f); 622424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)} 623424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace media 625