OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |