Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(367)

Side by Side Diff: media/audio/win/audio_low_latency_output_win_unittest.cc

Issue 2101303004: Pass delay and timestamp to AudioSourceCallback::OnMoreData. (Closed) Base URL: https://chromium.googlesource.com/chromium/src@master
Patch Set: Fix Mac CQ errors. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/audio/win/audio_low_latency_output_win.h" 5 #include "media/audio/win/audio_low_latency_output_win.h"
6 6
7 #include <windows.h> 7 #include <windows.h>
8 #include <mmsystem.h> 8 #include <mmsystem.h>
9 #include <stddef.h> 9 #include <stddef.h>
10 #include <stdint.h> 10 #include <stdint.h>
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 size_t elements_written = 0; 101 size_t elements_written = 0;
102 while (elements_written < elements_to_write_) { 102 while (elements_written < elements_to_write_) {
103 fprintf(text_file_, "%d\n", delta_times_[elements_written]); 103 fprintf(text_file_, "%d\n", delta_times_[elements_written]);
104 ++elements_written; 104 ++elements_written;
105 } 105 }
106 106
107 base::CloseFile(text_file_); 107 base::CloseFile(text_file_);
108 } 108 }
109 109
110 // AudioOutputStream::AudioSourceCallback implementation. 110 // AudioOutputStream::AudioSourceCallback implementation.
111 int OnMoreData(AudioBus* audio_bus, 111 int OnMoreData(base::TimeDelta /* delay */,
112 uint32_t total_bytes_delay, 112 base::TimeTicks /* delay_timestamp */,
113 uint32_t frames_skipped) override { 113 int /* prior_frames_skipped */,
114 AudioBus* dest) override {
114 // Store time difference between two successive callbacks in an array. 115 // Store time difference between two successive callbacks in an array.
115 // These values will be written to a file in the destructor. 116 // These values will be written to a file in the destructor.
116 const base::TimeTicks now_time = base::TimeTicks::Now(); 117 const base::TimeTicks now_time = base::TimeTicks::Now();
117 const int diff = (now_time - previous_call_time_).InMilliseconds(); 118 const int diff = (now_time - previous_call_time_).InMilliseconds();
118 previous_call_time_ = now_time; 119 previous_call_time_ = now_time;
119 if (elements_to_write_ < kMaxDeltaSamples) { 120 if (elements_to_write_ < kMaxDeltaSamples) {
120 delta_times_[elements_to_write_] = diff; 121 delta_times_[elements_to_write_] = diff;
121 ++elements_to_write_; 122 ++elements_to_write_;
122 } 123 }
123 124
124 int max_size = 125 int max_size = dest->frames() * dest->channels() * kBitsPerSample / 8;
125 audio_bus->frames() * audio_bus->channels() * kBitsPerSample / 8;
126 126
127 // Use samples read from a data file and fill up the audio buffer 127 // Use samples read from a data file and fill up the audio buffer
128 // provided to us in the callback. 128 // provided to us in the callback.
129 if (pos_ + static_cast<int>(max_size) > file_size()) 129 if (pos_ + static_cast<int>(max_size) > file_size())
130 max_size = file_size() - pos_; 130 max_size = file_size() - pos_;
131 int frames = max_size / (audio_bus->channels() * kBitsPerSample / 8); 131 int frames = max_size / (dest->channels() * kBitsPerSample / 8);
132 if (max_size) { 132 if (max_size) {
133 audio_bus->FromInterleaved( 133 dest->FromInterleaved(file_->data() + pos_, frames, kBitsPerSample / 8);
134 file_->data() + pos_, frames, kBitsPerSample / 8);
135 pos_ += max_size; 134 pos_ += max_size;
136 } 135 }
137 return frames; 136 return frames;
138 } 137 }
139 138
140 void OnError(AudioOutputStream* stream) override {} 139 void OnError(AudioOutputStream* stream) override {}
141 140
142 int file_size() { return file_->data_size(); } 141 int file_size() { return file_->data_size(); }
143 142
144 private: 143 private:
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
383 TEST_F(WASAPIAudioOutputStreamTest, ValidPacketSize) { 382 TEST_F(WASAPIAudioOutputStreamTest, ValidPacketSize) {
384 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get())); 383 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndOutputDevices(audio_manager_.get()));
385 384
386 MockAudioSourceCallback source; 385 MockAudioSourceCallback source;
387 // Create default WASAPI output stream which plays out in stereo using 386 // Create default WASAPI output stream which plays out in stereo using
388 // the shared mixing rate. The default buffer size is 10ms. 387 // the shared mixing rate. The default buffer size is 10ms.
389 AudioOutputStreamWrapper aosw(audio_manager_.get()); 388 AudioOutputStreamWrapper aosw(audio_manager_.get());
390 AudioOutputStream* aos = aosw.Create(); 389 AudioOutputStream* aos = aosw.Create();
391 EXPECT_TRUE(aos->Open()); 390 EXPECT_TRUE(aos->Open());
392 391
393 // Derive the expected size in bytes of each packet. 392 // Derive the expected duration of each packet.
394 uint32_t bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 393 base::TimeDelta packet_duration = base::TimeDelta::FromSecondsD(
395 (aosw.bits_per_sample() / 8); 394 static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());
396 395
397 // Wait for the first callback and verify its parameters. Ignore any 396 // Wait for the first callback and verify its parameters. Ignore any
398 // subsequent callbacks that might arrive. 397 // subsequent callbacks that might arrive.
399 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0)) 398 EXPECT_CALL(source,
399 OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
400 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()), 400 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
401 Return(aosw.samples_per_packet()))) 401 Return(aosw.samples_per_packet())))
402 .WillRepeatedly(Return(0)); 402 .WillRepeatedly(Return(0));
403 403
404 aos->Start(&source); 404 aos->Start(&source);
405 message_loop_.task_runner()->PostDelayedTask( 405 message_loop_.task_runner()->PostDelayedTask(
406 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), 406 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
407 TestTimeouts::action_timeout()); 407 TestTimeouts::action_timeout());
408 base::RunLoop().Run(); 408 base::RunLoop().Run();
409 aos->Stop(); 409 aos->Stop();
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 ExclusiveModeIsEnabled()); 575 ExclusiveModeIsEnabled());
576 576
577 MockAudioSourceCallback source; 577 MockAudioSourceCallback source;
578 // Create exclusive-mode WASAPI output stream which plays out in stereo 578 // Create exclusive-mode WASAPI output stream which plays out in stereo
579 // using the minimum buffer size at 48kHz sample rate. 579 // using the minimum buffer size at 48kHz sample rate.
580 AudioOutputStreamWrapper aosw(audio_manager_.get()); 580 AudioOutputStreamWrapper aosw(audio_manager_.get());
581 AudioOutputStream* aos = aosw.Create(48000, 160); 581 AudioOutputStream* aos = aosw.Create(48000, 160);
582 EXPECT_TRUE(aos->Open()); 582 EXPECT_TRUE(aos->Open());
583 583
584 // Derive the expected size in bytes of each packet. 584 // Derive the expected size in bytes of each packet.
585 uint32_t bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 585 base::TimeDelta packet_duration = base::TimeDelta::FromSecondsD(
586 (aosw.bits_per_sample() / 8); 586 static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());
587 587
588 // Wait for the first callback and verify its parameters. 588 // Wait for the first callback and verify its parameters.
589 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0)) 589 EXPECT_CALL(source,
590 OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
590 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()), 591 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
591 Return(aosw.samples_per_packet()))) 592 Return(aosw.samples_per_packet())))
592 .WillRepeatedly(Return(aosw.samples_per_packet())); 593 .WillRepeatedly(Return(aosw.samples_per_packet()));
593 594
594 aos->Start(&source); 595 aos->Start(&source);
595 message_loop_.task_runner()->PostDelayedTask( 596 message_loop_.task_runner()->PostDelayedTask(
596 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), 597 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
597 TestTimeouts::action_timeout()); 598 TestTimeouts::action_timeout());
598 base::RunLoop().Run(); 599 base::RunLoop().Run();
599 aos->Stop(); 600 aos->Stop();
600 aos->Close(); 601 aos->Close();
601 } 602 }
602 603
603 // Verify that we can open and start the output stream in exclusive mode at 604 // Verify that we can open and start the output stream in exclusive mode at
604 // the lowest possible delay at 44.1kHz. 605 // the lowest possible delay at 44.1kHz.
605 // It's disabled by default because a flag is required to enable exclusive mode. 606 // It's disabled by default because a flag is required to enable exclusive mode.
606 TEST_F(WASAPIAudioOutputStreamTest, 607 TEST_F(WASAPIAudioOutputStreamTest,
607 DISABLED_ExclusiveModeMinBufferSizeAt44kHz) { 608 DISABLED_ExclusiveModeMinBufferSizeAt44kHz) {
608 ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled()); 609 ABORT_AUDIO_TEST_IF_NOT(ExclusiveModeIsEnabled());
609 610
610 MockAudioSourceCallback source; 611 MockAudioSourceCallback source;
611 // Create exclusive-mode WASAPI output stream which plays out in stereo 612 // Create exclusive-mode WASAPI output stream which plays out in stereo
612 // using the minimum buffer size at 44.1kHz sample rate. 613 // using the minimum buffer size at 44.1kHz sample rate.
613 AudioOutputStreamWrapper aosw(audio_manager_.get()); 614 AudioOutputStreamWrapper aosw(audio_manager_.get());
614 AudioOutputStream* aos = aosw.Create(44100, 160); 615 AudioOutputStream* aos = aosw.Create(44100, 160);
615 EXPECT_TRUE(aos->Open()); 616 EXPECT_TRUE(aos->Open());
616 617
617 // Derive the expected size in bytes of each packet. 618 // Derive the expected size in bytes of each packet.
618 uint32_t bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 619 base::TimeDelta packet_duration = base::TimeDelta::FromSecondsD(
619 (aosw.bits_per_sample() / 8); 620 static_cast<double>(aosw.samples_per_packet()) / aosw.sample_rate());
620 621
621 // Wait for the first callback and verify its parameters. 622 // Wait for the first callback and verify its parameters.
622 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(bytes_per_packet), 0)) 623 EXPECT_CALL(source,
624 OnMoreData(HasValidDelay(packet_duration), _, 0, NotNull()))
623 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()), 625 .WillOnce(DoAll(QuitLoop(message_loop_.task_runner()),
624 Return(aosw.samples_per_packet()))) 626 Return(aosw.samples_per_packet())))
625 .WillRepeatedly(Return(aosw.samples_per_packet())); 627 .WillRepeatedly(Return(aosw.samples_per_packet()));
626 628
627 aos->Start(&source); 629 aos->Start(&source);
628 message_loop_.task_runner()->PostDelayedTask( 630 message_loop_.task_runner()->PostDelayedTask(
629 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(), 631 FROM_HERE, base::MessageLoop::QuitWhenIdleClosure(),
630 TestTimeouts::action_timeout()); 632 TestTimeouts::action_timeout());
631 base::RunLoop().Run(); 633 base::RunLoop().Run();
632 aos->Stop(); 634 aos->Stop();
633 aos->Close(); 635 aos->Close();
634 } 636 }
635 637
636 } // namespace media 638 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698