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)#include "remoting/client/audio_player.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAudioSamplesPerFrame = 25; 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAudioSampleBytes = 4; 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kAudioFrameBytes = kAudioSamplesPerFrame * kAudioSampleBytes; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kPaddingBytes = 16; 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(garykac): Generate random audio data in the tests rather than having 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// a single constant value. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8 kDefaultBufferData = 0x5A; 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8 kDummyAudioData = 0x8B; 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace remoting { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FakeAudioPlayer : public AudioPlayer { 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FakeAudioPlayer() { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool ResetAudioPlayer(AudioPacket::SamplingRate) OVERRIDE { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual uint32 GetSamplesPerFrame() OVERRIDE { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return kAudioSamplesPerFrame; 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AudioPlayerTest : public ::testing::Test { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void SetUp() { 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_.reset(new FakeAudioPlayer()); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) buffer_.reset(new char[kAudioFrameBytes + kPaddingBytes]); 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void TearDown() { 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ConsumeAudioFrame() { 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = reinterpret_cast<uint8*>(buffer_.get()); 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) memset(buffer, kDefaultBufferData, kAudioFrameBytes + kPaddingBytes); 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioPlayer::AudioPlayerCallback(reinterpret_cast<void*>(buffer_.get()), 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kAudioFrameBytes, 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) reinterpret_cast<void*>(audio_.get())); 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Verify we haven't written beyond the end of the buffer. 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < kPaddingBytes; i++) 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kDefaultBufferData, *(buffer + kAudioFrameBytes + i)); 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Check that the first |num_bytes| bytes are filled with audio data and 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the rest of the buffer is zero-filled. 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void CheckAudioFrameBytes(int num_bytes) { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint8* buffer = reinterpret_cast<uint8*>(buffer_.get()); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int i = 0; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < num_bytes; i++) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(kDummyAudioData, *(buffer + i)); 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Rest of audio frame must be filled with '0's. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; i < kAudioFrameBytes; i++) { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, *(buffer + i)); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetNumQueuedSamples() { 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return audio_->queued_bytes_ / kAudioSampleBytes; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetNumQueuedPackets() { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(audio_->queued_packets_.size()); 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int GetBytesConsumed() { 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return static_cast<int>(audio_->bytes_consumed_); 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPlayer> audio_; 89c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<char[]> buffer_; 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<AudioPacket> CreatePacketWithSamplingRate( 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AudioPacket::SamplingRate rate, int samples) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet(new AudioPacket()); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_encoding(AudioPacket::ENCODING_RAW); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_sampling_rate(rate); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2); 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->set_channels(AudioPacket::CHANNELS_STEREO); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The data must be a multiple of 4 bytes (channels x bytes_per_sample). 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string data; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) data.resize(samples * kAudioSampleBytes, kDummyAudioData); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) packet->add_data(data); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return packet.Pass(); 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<AudioPacket> CreatePacket44100Hz(int samples) { 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_44100, 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)scoped_ptr<AudioPacket> CreatePacket48000Hz(int samples) { 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_48000, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) samples); 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, Init) { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetNumQueuedPackets()); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet(CreatePacket44100Hz(10)); 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet.Pass()); 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, MultipleSamples) { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(10)); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(10, GetNumQueuedSamples()); 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(20)); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet2.Pass()); 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(30, GetNumQueuedSamples()); 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2, GetNumQueuedPackets()); 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, ChangeSampleRate) { 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(10)); 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(10, GetNumQueuedSamples()); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // New packet with different sampling rate causes previous samples to 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // be removed. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet2(CreatePacket48000Hz(20)); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet2.Pass()); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(20, GetNumQueuedSamples()); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, ExceedLatency) { 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Push about 4 seconds worth of samples. 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 0; i < 100; ++i) { 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket48000Hz(2000)); 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Verify that we don't have more than 0.5s. 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_LT(GetNumQueuedSamples(), 24000); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incoming packets: 100 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Consume: 25 (w/ 75 remaining, offset 25 into packet) 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, ConsumePartialPacket) { 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_samples = 0; 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_consumed = 0; 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Process 100 samples. 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet1_samples = 100; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet(CreatePacket44100Hz(packet1_samples)); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet1_samples; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet.Pass()); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume one frame (=25) of samples. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes; 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remaining samples. 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(75, total_samples); 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incoming packets: 20, 70 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Consume: 25, 25 (w/ 40 remaining, offset 30 into packet) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, ConsumeAcrossPackets) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_samples = 0; 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_consumed = 0; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Packet 1. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet1_samples = 20; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples)); 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet1_samples; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Packet 2. 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet2_samples = 70; 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(packet2_samples)); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet2_samples; 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet2.Pass()); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume 1st frame of 25 samples. 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will consume the entire 1st packet. 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume 2nd frame of 25 samples. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remaining samples. 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(40, total_samples); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(30 * kAudioSampleBytes, bytes_consumed); 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incoming packets: 50, 30 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Consume: 25, 25, 25 (w/ 5 remaining, offset 25 into packet) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, ConsumeEntirePacket) { 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_samples = 0; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_consumed = 0; 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Packet 1. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet1_samples = 50; 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet1_samples; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Packet 2. 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet2_samples = 30; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(packet2_samples)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet2_samples; 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet2.Pass()); 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume 1st frame of 25 samples. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes; 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2, GetNumQueuedPackets()); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume 2nd frame of 25 samples. 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This will consume the entire first packet (exactly), but the entry for 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this packet will stick around (empty) until the next audio chunk is 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // consumed. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(2, GetNumQueuedPackets()); 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Consume 3rd frame of 25 samples. 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples -= kAudioSamplesPerFrame; 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(1, GetNumQueuedPackets()); 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(kAudioFrameBytes); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Remaining samples. 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(5, total_samples); 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed); 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incoming packets: <none> 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Consume: 25 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, NoDataToConsume) { 2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to consume a frame of 25 samples. 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetNumQueuedSamples()); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetNumQueuedPackets()); 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetBytesConsumed()); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(0); 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Incoming packets: 10 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Consume: 25 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(AudioPlayerTest, NotEnoughDataToConsume) { 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_samples = 0; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int bytes_consumed = 0; 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Packet 1. 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int packet1_samples = 10; 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples)); 3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_samples += packet1_samples; 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) audio_->ProcessAudioPacket(packet1.Pass()); 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(total_samples, GetNumQueuedSamples()); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(bytes_consumed, GetBytesConsumed()); 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Attempt to consume a frame of 25 samples. 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConsumeAudioFrame(); 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetNumQueuedSamples()); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetNumQueuedPackets()); 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_EQ(0, GetBytesConsumed()); 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CheckAudioFrameBytes(packet1_samples * kAudioSampleBytes); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace remoting 328