Fixes chromecast build to point to ui/resources and ui/strings.
[chromium-blink-merge.git] / remoting / client / audio_player_unittest.cc
bloba6b5a5bf473c53fd2af8cb1ea460ede7c69f9f75
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "remoting/client/audio_player.h"
7 #include "base/compiler_specific.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "testing/gtest/include/gtest/gtest.h"
11 namespace {
13 const int kAudioSamplesPerFrame = 25;
14 const int kAudioSampleBytes = 4;
15 const int kAudioFrameBytes = kAudioSamplesPerFrame * kAudioSampleBytes;
16 const int kPaddingBytes = 16;
18 // TODO(garykac): Generate random audio data in the tests rather than having
19 // a single constant value.
20 const uint8 kDefaultBufferData = 0x5A;
21 const uint8 kDummyAudioData = 0x8B;
23 } // namespace
25 namespace remoting {
27 class FakeAudioPlayer : public AudioPlayer {
28 public:
29 FakeAudioPlayer() {
32 virtual bool ResetAudioPlayer(AudioPacket::SamplingRate) OVERRIDE {
33 return true;
36 virtual uint32 GetSamplesPerFrame() OVERRIDE {
37 return kAudioSamplesPerFrame;
41 class AudioPlayerTest : public ::testing::Test {
42 protected:
43 virtual void SetUp() {
44 audio_.reset(new FakeAudioPlayer());
45 buffer_.reset(new char[kAudioFrameBytes + kPaddingBytes]);
48 virtual void TearDown() {
51 void ConsumeAudioFrame() {
52 uint8* buffer = reinterpret_cast<uint8*>(buffer_.get());
53 memset(buffer, kDefaultBufferData, kAudioFrameBytes + kPaddingBytes);
54 AudioPlayer::AudioPlayerCallback(reinterpret_cast<void*>(buffer_.get()),
55 kAudioFrameBytes,
56 reinterpret_cast<void*>(audio_.get()));
57 // Verify we haven't written beyond the end of the buffer.
58 for (int i = 0; i < kPaddingBytes; i++)
59 ASSERT_EQ(kDefaultBufferData, *(buffer + kAudioFrameBytes + i));
62 // Check that the first |num_bytes| bytes are filled with audio data and
63 // the rest of the buffer is zero-filled.
64 void CheckAudioFrameBytes(int num_bytes) {
65 uint8* buffer = reinterpret_cast<uint8*>(buffer_.get());
66 int i = 0;
67 for (; i < num_bytes; i++) {
68 ASSERT_EQ(kDummyAudioData, *(buffer + i));
70 // Rest of audio frame must be filled with '0's.
71 for (; i < kAudioFrameBytes; i++) {
72 ASSERT_EQ(0, *(buffer + i));
76 int GetNumQueuedSamples() {
77 return audio_->queued_bytes_ / kAudioSampleBytes;
80 int GetNumQueuedPackets() {
81 return static_cast<int>(audio_->queued_packets_.size());
84 int GetBytesConsumed() {
85 return static_cast<int>(audio_->bytes_consumed_);
88 scoped_ptr<AudioPlayer> audio_;
89 scoped_ptr<char[]> buffer_;
92 scoped_ptr<AudioPacket> CreatePacketWithSamplingRate(
93 AudioPacket::SamplingRate rate, int samples) {
94 scoped_ptr<AudioPacket> packet(new AudioPacket());
95 packet->set_encoding(AudioPacket::ENCODING_RAW);
96 packet->set_sampling_rate(rate);
97 packet->set_bytes_per_sample(AudioPacket::BYTES_PER_SAMPLE_2);
98 packet->set_channels(AudioPacket::CHANNELS_STEREO);
100 // The data must be a multiple of 4 bytes (channels x bytes_per_sample).
101 std::string data;
102 data.resize(samples * kAudioSampleBytes, kDummyAudioData);
103 packet->add_data(data);
105 return packet.Pass();
108 scoped_ptr<AudioPacket> CreatePacket44100Hz(int samples) {
109 return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_44100,
110 samples);
113 scoped_ptr<AudioPacket> CreatePacket48000Hz(int samples) {
114 return CreatePacketWithSamplingRate(AudioPacket::SAMPLING_RATE_48000,
115 samples);
118 TEST_F(AudioPlayerTest, Init) {
119 ASSERT_EQ(0, GetNumQueuedPackets());
121 scoped_ptr<AudioPacket> packet(CreatePacket44100Hz(10));
122 audio_->ProcessAudioPacket(packet.Pass());
123 ASSERT_EQ(1, GetNumQueuedPackets());
126 TEST_F(AudioPlayerTest, MultipleSamples) {
127 scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(10));
128 audio_->ProcessAudioPacket(packet1.Pass());
129 ASSERT_EQ(10, GetNumQueuedSamples());
130 ASSERT_EQ(1, GetNumQueuedPackets());
132 scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(20));
133 audio_->ProcessAudioPacket(packet2.Pass());
134 ASSERT_EQ(30, GetNumQueuedSamples());
135 ASSERT_EQ(2, GetNumQueuedPackets());
138 TEST_F(AudioPlayerTest, ChangeSampleRate) {
139 scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(10));
140 audio_->ProcessAudioPacket(packet1.Pass());
141 ASSERT_EQ(10, GetNumQueuedSamples());
142 ASSERT_EQ(1, GetNumQueuedPackets());
144 // New packet with different sampling rate causes previous samples to
145 // be removed.
146 scoped_ptr<AudioPacket> packet2(CreatePacket48000Hz(20));
147 audio_->ProcessAudioPacket(packet2.Pass());
148 ASSERT_EQ(20, GetNumQueuedSamples());
149 ASSERT_EQ(1, GetNumQueuedPackets());
152 TEST_F(AudioPlayerTest, ExceedLatency) {
153 // Push about 4 seconds worth of samples.
154 for (int i = 0; i < 100; ++i) {
155 scoped_ptr<AudioPacket> packet1(CreatePacket48000Hz(2000));
156 audio_->ProcessAudioPacket(packet1.Pass());
159 // Verify that we don't have more than 0.5s.
160 EXPECT_LT(GetNumQueuedSamples(), 24000);
163 // Incoming packets: 100
164 // Consume: 25 (w/ 75 remaining, offset 25 into packet)
165 TEST_F(AudioPlayerTest, ConsumePartialPacket) {
166 int total_samples = 0;
167 int bytes_consumed = 0;
169 // Process 100 samples.
170 int packet1_samples = 100;
171 scoped_ptr<AudioPacket> packet(CreatePacket44100Hz(packet1_samples));
172 total_samples += packet1_samples;
173 audio_->ProcessAudioPacket(packet.Pass());
174 ASSERT_EQ(total_samples, GetNumQueuedSamples());
175 ASSERT_EQ(1, GetNumQueuedPackets());
176 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
178 // Consume one frame (=25) of samples.
179 ConsumeAudioFrame();
180 total_samples -= kAudioSamplesPerFrame;
181 bytes_consumed += kAudioFrameBytes;
182 ASSERT_EQ(total_samples, GetNumQueuedSamples());
183 ASSERT_EQ(1, GetNumQueuedPackets());
184 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
185 CheckAudioFrameBytes(kAudioFrameBytes);
187 // Remaining samples.
188 ASSERT_EQ(75, total_samples);
189 ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed);
192 // Incoming packets: 20, 70
193 // Consume: 25, 25 (w/ 40 remaining, offset 30 into packet)
194 TEST_F(AudioPlayerTest, ConsumeAcrossPackets) {
195 int total_samples = 0;
196 int bytes_consumed = 0;
198 // Packet 1.
199 int packet1_samples = 20;
200 scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples));
201 total_samples += packet1_samples;
202 audio_->ProcessAudioPacket(packet1.Pass());
203 ASSERT_EQ(total_samples, GetNumQueuedSamples());
205 // Packet 2.
206 int packet2_samples = 70;
207 scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(packet2_samples));
208 total_samples += packet2_samples;
209 audio_->ProcessAudioPacket(packet2.Pass());
210 ASSERT_EQ(total_samples, GetNumQueuedSamples());
211 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
213 // Consume 1st frame of 25 samples.
214 // This will consume the entire 1st packet.
215 ConsumeAudioFrame();
216 total_samples -= kAudioSamplesPerFrame;
217 bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes);
218 ASSERT_EQ(total_samples, GetNumQueuedSamples());
219 ASSERT_EQ(1, GetNumQueuedPackets());
220 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
221 CheckAudioFrameBytes(kAudioFrameBytes);
223 // Consume 2nd frame of 25 samples.
224 ConsumeAudioFrame();
225 total_samples -= kAudioSamplesPerFrame;
226 bytes_consumed += kAudioFrameBytes;
227 ASSERT_EQ(total_samples, GetNumQueuedSamples());
228 ASSERT_EQ(1, GetNumQueuedPackets());
229 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
230 CheckAudioFrameBytes(kAudioFrameBytes);
232 // Remaining samples.
233 ASSERT_EQ(40, total_samples);
234 ASSERT_EQ(30 * kAudioSampleBytes, bytes_consumed);
237 // Incoming packets: 50, 30
238 // Consume: 25, 25, 25 (w/ 5 remaining, offset 25 into packet)
239 TEST_F(AudioPlayerTest, ConsumeEntirePacket) {
240 int total_samples = 0;
241 int bytes_consumed = 0;
243 // Packet 1.
244 int packet1_samples = 50;
245 scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples));
246 total_samples += packet1_samples;
247 audio_->ProcessAudioPacket(packet1.Pass());
248 ASSERT_EQ(total_samples, GetNumQueuedSamples());
249 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
251 // Packet 2.
252 int packet2_samples = 30;
253 scoped_ptr<AudioPacket> packet2(CreatePacket44100Hz(packet2_samples));
254 total_samples += packet2_samples;
255 audio_->ProcessAudioPacket(packet2.Pass());
256 ASSERT_EQ(total_samples, GetNumQueuedSamples());
257 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
259 // Consume 1st frame of 25 samples.
260 ConsumeAudioFrame();
261 total_samples -= kAudioSamplesPerFrame;
262 bytes_consumed += kAudioFrameBytes;
263 ASSERT_EQ(total_samples, GetNumQueuedSamples());
264 ASSERT_EQ(2, GetNumQueuedPackets());
265 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
266 CheckAudioFrameBytes(kAudioFrameBytes);
268 // Consume 2nd frame of 25 samples.
269 // This will consume the entire first packet (exactly), but the entry for
270 // this packet will stick around (empty) until the next audio chunk is
271 // consumed.
272 ConsumeAudioFrame();
273 total_samples -= kAudioSamplesPerFrame;
274 bytes_consumed += kAudioFrameBytes;
275 ASSERT_EQ(total_samples, GetNumQueuedSamples());
276 ASSERT_EQ(2, GetNumQueuedPackets());
277 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
278 CheckAudioFrameBytes(kAudioFrameBytes);
280 // Consume 3rd frame of 25 samples.
281 ConsumeAudioFrame();
282 total_samples -= kAudioSamplesPerFrame;
283 bytes_consumed += kAudioFrameBytes - (packet1_samples * kAudioSampleBytes);
284 ASSERT_EQ(total_samples, GetNumQueuedSamples());
285 ASSERT_EQ(1, GetNumQueuedPackets());
286 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
287 CheckAudioFrameBytes(kAudioFrameBytes);
289 // Remaining samples.
290 ASSERT_EQ(5, total_samples);
291 ASSERT_EQ(25 * kAudioSampleBytes, bytes_consumed);
294 // Incoming packets: <none>
295 // Consume: 25
296 TEST_F(AudioPlayerTest, NoDataToConsume) {
297 // Attempt to consume a frame of 25 samples.
298 ConsumeAudioFrame();
299 ASSERT_EQ(0, GetNumQueuedSamples());
300 ASSERT_EQ(0, GetNumQueuedPackets());
301 ASSERT_EQ(0, GetBytesConsumed());
302 CheckAudioFrameBytes(0);
305 // Incoming packets: 10
306 // Consume: 25
307 TEST_F(AudioPlayerTest, NotEnoughDataToConsume) {
308 int total_samples = 0;
309 int bytes_consumed = 0;
311 // Packet 1.
312 int packet1_samples = 10;
313 scoped_ptr<AudioPacket> packet1(CreatePacket44100Hz(packet1_samples));
314 total_samples += packet1_samples;
315 audio_->ProcessAudioPacket(packet1.Pass());
316 ASSERT_EQ(total_samples, GetNumQueuedSamples());
317 ASSERT_EQ(bytes_consumed, GetBytesConsumed());
319 // Attempt to consume a frame of 25 samples.
320 ConsumeAudioFrame();
321 ASSERT_EQ(0, GetNumQueuedSamples());
322 ASSERT_EQ(0, GetNumQueuedPackets());
323 ASSERT_EQ(0, GetBytesConsumed());
324 CheckAudioFrameBytes(packet1_samples * kAudioSampleBytes);
327 } // namespace remoting