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

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

Issue 10832285: Switch OnMoreData() to use AudioBus. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Review ready. Created 8 years, 4 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 | Annotate | Revision Log
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 <windows.h> 5 #include <windows.h>
6 #include <mmsystem.h> 6 #include <mmsystem.h>
7 7
8 #include "base/basictypes.h" 8 #include "base/basictypes.h"
9 #include "base/environment.h" 9 #include "base/environment.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 29 matching lines...) Expand all
40 40
41 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw"; 41 static const char kSpeechFile_16b_s_48k[] = "speech_16b_stereo_48kHz.raw";
42 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw"; 42 static const char kSpeechFile_16b_s_44k[] = "speech_16b_stereo_44kHz.raw";
43 static const char kSpeechFile_16b_m_48k[] = "speech_16b_mono_48kHz.raw"; 43 static const char kSpeechFile_16b_m_48k[] = "speech_16b_mono_48kHz.raw";
44 static const char kSpeechFile_16b_m_44k[] = "speech_16b_mono_44kHz.raw"; 44 static const char kSpeechFile_16b_m_44k[] = "speech_16b_mono_44kHz.raw";
45 static const size_t kFileDurationMs = 20000; 45 static const size_t kFileDurationMs = 20000;
46 static const size_t kNumFileSegments = 2; 46 static const size_t kNumFileSegments = 2;
47 47
48 static const size_t kMaxDeltaSamples = 1000; 48 static const size_t kMaxDeltaSamples = 1000;
49 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt"; 49 static const char* kDeltaTimeMsFileName = "delta_times_ms.txt";
50 50
henrika (OOO until Aug 14) 2012/08/23 14:42:53 nit, why empty line here?
DaleCurtis 2012/08/24 23:53:12 Didn't seem to fit with the lines directly above.
51 static const int kBitsPerSample = 16;
52
51 MATCHER_P(HasValidDelay, value, "") { 53 MATCHER_P(HasValidDelay, value, "") {
52 // It is difficult to come up with a perfect test condition for the delay 54 // It is difficult to come up with a perfect test condition for the delay
53 // estimation. For now, verify that the produced output delay is always 55 // estimation. For now, verify that the produced output delay is always
54 // larger than the selected buffer size. 56 // larger than the selected buffer size.
55 return arg.hardware_delay_bytes > value.hardware_delay_bytes; 57 return arg.hardware_delay_bytes > value.hardware_delay_bytes;
56 } 58 }
57 59
58 // Used to terminate a loop from a different thread than the loop belongs to. 60 // Used to terminate a loop from a different thread than the loop belongs to.
59 // |loop| should be a MessageLoopProxy. 61 // |loop| should be a MessageLoopProxy.
60 ACTION_P(QuitLoop, loop) { 62 ACTION_P(QuitLoop, loop) {
61 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); 63 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure());
62 } 64 }
63 65
64 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback { 66 class MockAudioSourceCallback : public AudioOutputStream::AudioSourceCallback {
65 public: 67 public:
66 MOCK_METHOD3(OnMoreData, uint32(uint8* dest, 68 MOCK_METHOD2(OnMoreData, int(AudioBus* audio_bus,
67 uint32 max_size, 69 AudioBuffersState buffers_state));
68 AudioBuffersState buffers_state));
69 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code)); 70 MOCK_METHOD2(OnError, void(AudioOutputStream* stream, int code));
70 }; 71 };
71 72
72 // This audio source implementation should be used for manual tests only since 73 // This audio source implementation should be used for manual tests only since
73 // it takes about 20 seconds to play out a file. 74 // it takes about 20 seconds to play out a file.
74 class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback { 75 class ReadFromFileAudioSource : public AudioOutputStream::AudioSourceCallback {
75 public: 76 public:
76 explicit ReadFromFileAudioSource(const std::string& name) 77 explicit ReadFromFileAudioSource(const std::string& name)
77 : pos_(0), 78 : pos_(0),
78 previous_call_time_(base::Time::Now()), 79 previous_call_time_(base::Time::Now()),
(...skipping 24 matching lines...) Expand all
103 size_t elements_written = 0; 104 size_t elements_written = 0;
104 while (elements_written < elements_to_write_) { 105 while (elements_written < elements_to_write_) {
105 fprintf(text_file_, "%d\n", delta_times_[elements_written]); 106 fprintf(text_file_, "%d\n", delta_times_[elements_written]);
106 ++elements_written; 107 ++elements_written;
107 } 108 }
108 109
109 file_util::CloseFile(text_file_); 110 file_util::CloseFile(text_file_);
110 } 111 }
111 112
112 // AudioOutputStream::AudioSourceCallback implementation. 113 // AudioOutputStream::AudioSourceCallback implementation.
113 virtual uint32 OnMoreData(uint8* dest, 114 virtual int OnMoreData(AudioBus* audio_bus,
114 uint32 max_size, 115 AudioBuffersState buffers_state) {
115 AudioBuffersState buffers_state) {
116 // Store time difference between two successive callbacks in an array. 116 // Store time difference between two successive callbacks in an array.
117 // These values will be written to a file in the destructor. 117 // These values will be written to a file in the destructor.
118 int diff = (base::Time::Now() - previous_call_time_).InMilliseconds(); 118 int diff = (base::Time::Now() - previous_call_time_).InMilliseconds();
119 previous_call_time_ = base::Time::Now(); 119 previous_call_time_ = base::Time::Now();
120 if (elements_to_write_ < kMaxDeltaSamples) { 120 if (elements_to_write_ < kMaxDeltaSamples) {
121 delta_times_[elements_to_write_] = diff; 121 delta_times_[elements_to_write_] = diff;
122 ++elements_to_write_; 122 ++elements_to_write_;
123 } 123 }
124 124
125 int max_size =
126 audio_bus->frames() * audio_bus->channels() * kBitsPerSample / 8;
127
125 // Use samples read from a data file and fill up the audio buffer 128 // Use samples read from a data file and fill up the audio buffer
126 // provided to us in the callback. 129 // provided to us in the callback.
127 if (pos_ + static_cast<int>(max_size) > file_size()) 130 if (pos_ + static_cast<int>(max_size) > file_size())
128 max_size = file_size() - pos_; 131 max_size = file_size() - pos_;
132 int frames = max_size / (audio_bus->channels() * kBitsPerSample / 8);
129 if (max_size) { 133 if (max_size) {
130 memcpy(dest, file_->GetData() + pos_, max_size); 134 audio_bus->FromInterleaved(
henrika (OOO until Aug 14) 2012/08/23 14:42:53 Thx ;-)
135 file_->GetData() + pos_, frames, kBitsPerSample / 8);
131 pos_ += max_size; 136 pos_ += max_size;
132 } 137 }
133 return max_size; 138 return frames;
134 } 139 }
135 140
136 virtual void OnError(AudioOutputStream* stream, int code) {} 141 virtual void OnError(AudioOutputStream* stream, int code) {}
137 142
138 int file_size() { return file_->GetDataSize(); } 143 int file_size() { return file_->GetDataSize(); }
139 144
140 private: 145 private:
141 scoped_refptr<DecoderBuffer> file_; 146 scoped_refptr<DecoderBuffer> file_;
142 scoped_array<int> delta_times_; 147 scoped_array<int> delta_times_;
143 int pos_; 148 int pos_;
(...skipping 25 matching lines...) Expand all
169 174
170 // Convenience method which creates a default AudioOutputStream object but 175 // Convenience method which creates a default AudioOutputStream object but
171 // also allows the user to modify the default settings. 176 // also allows the user to modify the default settings.
172 class AudioOutputStreamWrapper { 177 class AudioOutputStreamWrapper {
173 public: 178 public:
174 explicit AudioOutputStreamWrapper(AudioManager* audio_manager) 179 explicit AudioOutputStreamWrapper(AudioManager* audio_manager)
175 : com_init_(ScopedCOMInitializer::kMTA), 180 : com_init_(ScopedCOMInitializer::kMTA),
176 audio_man_(audio_manager), 181 audio_man_(audio_manager),
177 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY), 182 format_(AudioParameters::AUDIO_PCM_LOW_LATENCY),
178 channel_layout_(CHANNEL_LAYOUT_STEREO), 183 channel_layout_(CHANNEL_LAYOUT_STEREO),
179 bits_per_sample_(16) { 184 bits_per_sample_(kBitsPerSample) {
180 // Use native/mixing sample rate and 10ms frame size as default. 185 // Use native/mixing sample rate and 10ms frame size as default.
181 sample_rate_ = static_cast<int>( 186 sample_rate_ = static_cast<int>(
182 WASAPIAudioOutputStream::HardwareSampleRate(eConsole)); 187 WASAPIAudioOutputStream::HardwareSampleRate(eConsole));
183 samples_per_packet_ = sample_rate_ / 100; 188 samples_per_packet_ = sample_rate_ / 100;
184 DCHECK(sample_rate_); 189 DCHECK(sample_rate_);
185 } 190 }
186 191
187 ~AudioOutputStreamWrapper() {} 192 ~AudioOutputStreamWrapper() {}
188 193
189 // Creates AudioOutputStream object using default parameters. 194 // Creates AudioOutputStream object using default parameters.
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 EXPECT_TRUE(aos->Open()); 459 EXPECT_TRUE(aos->Open());
455 460
456 // Derive the expected size in bytes of each packet. 461 // Derive the expected size in bytes of each packet.
457 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 462 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
458 (aosw.bits_per_sample() / 8); 463 (aosw.bits_per_sample() / 8);
459 464
460 // Set up expected minimum delay estimation. 465 // Set up expected minimum delay estimation.
461 AudioBuffersState state(0, bytes_per_packet); 466 AudioBuffersState state(0, bytes_per_packet);
462 467
463 // Wait for the first callback and verify its parameters. 468 // Wait for the first callback and verify its parameters.
464 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 469 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
465 HasValidDelay(state)))
466 .WillOnce(DoAll( 470 .WillOnce(DoAll(
467 QuitLoop(loop.message_loop_proxy()), 471 QuitLoop(loop.message_loop_proxy()),
468 Return(bytes_per_packet))); 472 Return(aosw.samples_per_packet())));
469 473
470 aos->Start(&source); 474 aos->Start(&source);
471 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 475 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
472 TestTimeouts::action_timeout()); 476 TestTimeouts::action_timeout());
473 loop.Run(); 477 loop.Run();
474 aos->Stop(); 478 aos->Stop();
475 aos->Close(); 479 aos->Close();
476 } 480 }
477 481
478 // Use a fixed packets size (independent of sample rate) and verify 482 // Use a fixed packets size (independent of sample rate) and verify
(...skipping 14 matching lines...) Expand all
493 EXPECT_TRUE(aos->Open()); 497 EXPECT_TRUE(aos->Open());
494 498
495 // Derive the expected size in bytes of each packet. 499 // Derive the expected size in bytes of each packet.
496 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 500 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
497 (aosw.bits_per_sample() / 8); 501 (aosw.bits_per_sample() / 8);
498 502
499 // Set up expected minimum delay estimation. 503 // Set up expected minimum delay estimation.
500 AudioBuffersState state(0, bytes_per_packet); 504 AudioBuffersState state(0, bytes_per_packet);
501 505
502 // Ensure that callbacks start correctly. 506 // Ensure that callbacks start correctly.
503 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 507 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
504 HasValidDelay(state)))
505 .WillOnce(DoAll( 508 .WillOnce(DoAll(
506 QuitLoop(loop.message_loop_proxy()), 509 QuitLoop(loop.message_loop_proxy()),
507 Return(bytes_per_packet))) 510 Return(aosw.samples_per_packet())))
508 .WillRepeatedly(Return(bytes_per_packet)); 511 .WillRepeatedly(Return(aosw.samples_per_packet()));
509 512
510 aos->Start(&source); 513 aos->Start(&source);
511 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 514 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
512 TestTimeouts::action_timeout()); 515 TestTimeouts::action_timeout());
513 loop.Run(); 516 loop.Run();
514 aos->Stop(); 517 aos->Stop();
515 aos->Close(); 518 aos->Close();
516 } 519 }
517 520
518 TEST(WASAPIAudioOutputStreamTest, Mono) { 521 TEST(WASAPIAudioOutputStreamTest, Mono) {
(...skipping 10 matching lines...) Expand all
529 AudioOutputStream* aos = aosw.Create(CHANNEL_LAYOUT_MONO); 532 AudioOutputStream* aos = aosw.Create(CHANNEL_LAYOUT_MONO);
530 EXPECT_TRUE(aos->Open()); 533 EXPECT_TRUE(aos->Open());
531 534
532 // Derive the expected size in bytes of each packet. 535 // Derive the expected size in bytes of each packet.
533 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 536 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
534 (aosw.bits_per_sample() / 8); 537 (aosw.bits_per_sample() / 8);
535 538
536 // Set up expected minimum delay estimation. 539 // Set up expected minimum delay estimation.
537 AudioBuffersState state(0, bytes_per_packet); 540 AudioBuffersState state(0, bytes_per_packet);
538 541
539 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 542 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
540 HasValidDelay(state)))
541 .WillOnce(DoAll( 543 .WillOnce(DoAll(
542 QuitLoop(loop.message_loop_proxy()), 544 QuitLoop(loop.message_loop_proxy()),
543 Return(bytes_per_packet))) 545 Return(aosw.samples_per_packet())))
544 .WillRepeatedly(Return(bytes_per_packet)); 546 .WillRepeatedly(Return(aosw.samples_per_packet()));
545 547
546 aos->Start(&source); 548 aos->Start(&source);
547 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 549 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
548 TestTimeouts::action_timeout()); 550 TestTimeouts::action_timeout());
549 loop.Run(); 551 loop.Run();
550 aos->Stop(); 552 aos->Stop();
551 aos->Close(); 553 aos->Close();
552 } 554 }
553 555
554 // This test is intended for manual tests and should only be enabled 556 // This test is intended for manual tests and should only be enabled
(...skipping 227 matching lines...) Expand 10 before | Expand all | Expand 10 after
782 EXPECT_TRUE(aos->Open()); 784 EXPECT_TRUE(aos->Open());
783 785
784 // Derive the expected size in bytes of each packet. 786 // Derive the expected size in bytes of each packet.
785 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 787 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
786 (aosw.bits_per_sample() / 8); 788 (aosw.bits_per_sample() / 8);
787 789
788 // Set up expected minimum delay estimation. 790 // Set up expected minimum delay estimation.
789 AudioBuffersState state(0, bytes_per_packet); 791 AudioBuffersState state(0, bytes_per_packet);
790 792
791 // Wait for the first callback and verify its parameters. 793 // Wait for the first callback and verify its parameters.
792 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 794 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
793 HasValidDelay(state)))
794 .WillOnce(DoAll( 795 .WillOnce(DoAll(
795 QuitLoop(loop.message_loop_proxy()), 796 QuitLoop(loop.message_loop_proxy()),
796 Return(bytes_per_packet))) 797 Return(aosw.samples_per_packet())))
797 .WillRepeatedly(Return(bytes_per_packet)); 798 .WillRepeatedly(Return(aosw.samples_per_packet()));
798 799
799 aos->Start(&source); 800 aos->Start(&source);
800 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 801 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
801 TestTimeouts::action_timeout()); 802 TestTimeouts::action_timeout());
802 loop.Run(); 803 loop.Run();
803 aos->Stop(); 804 aos->Stop();
804 aos->Close(); 805 aos->Close();
805 } 806 }
806 807
807 // Verify that we can open and start the output stream in exclusive mode at 808 // Verify that we can open and start the output stream in exclusive mode at
(...skipping 16 matching lines...) Expand all
824 EXPECT_TRUE(aos->Open()); 825 EXPECT_TRUE(aos->Open());
825 826
826 // Derive the expected size in bytes of each packet. 827 // Derive the expected size in bytes of each packet.
827 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() * 828 uint32 bytes_per_packet = aosw.channels() * aosw.samples_per_packet() *
828 (aosw.bits_per_sample() / 8); 829 (aosw.bits_per_sample() / 8);
829 830
830 // Set up expected minimum delay estimation. 831 // Set up expected minimum delay estimation.
831 AudioBuffersState state(0, bytes_per_packet); 832 AudioBuffersState state(0, bytes_per_packet);
832 833
833 // Wait for the first callback and verify its parameters. 834 // Wait for the first callback and verify its parameters.
834 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_per_packet, 835 EXPECT_CALL(source, OnMoreData(NotNull(), HasValidDelay(state)))
835 HasValidDelay(state)))
836 .WillOnce(DoAll( 836 .WillOnce(DoAll(
837 QuitLoop(loop.message_loop_proxy()), 837 QuitLoop(loop.message_loop_proxy()),
838 Return(bytes_per_packet))) 838 Return(aosw.samples_per_packet())))
839 .WillRepeatedly(Return(bytes_per_packet)); 839 .WillRepeatedly(Return(aosw.samples_per_packet()));
840 840
841 aos->Start(&source); 841 aos->Start(&source);
842 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(), 842 loop.PostDelayedTask(FROM_HERE, MessageLoop::QuitClosure(),
843 TestTimeouts::action_timeout()); 843 TestTimeouts::action_timeout());
844 loop.Run(); 844 loop.Run();
845 aos->Stop(); 845 aos->Stop();
846 aos->Close(); 846 aos->Close();
847 } 847 }
848 848
849 } // namespace media 849 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698