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

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

Powered by Google App Engine
This is Rietveld 408576698