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" |
11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
12 #include "base/message_loop.h" | 12 #include "base/message_loop.h" |
13 #include "base/path_service.h" | 13 #include "base/path_service.h" |
14 #include "base/test/test_timeouts.h" | 14 #include "base/test/test_timeouts.h" |
15 #include "base/win/scoped_com_initializer.h" | 15 #include "base/win/scoped_com_initializer.h" |
16 #include "media/audio/audio_io.h" | 16 #include "media/audio/audio_io.h" |
17 #include "media/audio/audio_manager_base.h" | 17 #include "media/audio/audio_manager_base.h" |
18 #include "media/audio/win/audio_low_latency_input_win.h" | 18 #include "media/audio/win/audio_low_latency_input_win.h" |
19 #include "media/base/seekable_buffer.h" | 19 #include "media/base/seekable_buffer.h" |
20 #include "testing/gmock/include/gmock/gmock.h" | 20 #include "testing/gmock/include/gmock/gmock.h" |
21 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
22 | 22 |
23 using base::win::ScopedCOMInitializer; | 23 using base::win::ScopedCOMInitializer; |
| 24 using ::testing::_; |
24 using ::testing::AnyNumber; | 25 using ::testing::AnyNumber; |
25 using ::testing::AtLeast; | 26 using ::testing::AtLeast; |
26 using ::testing::Gt; | 27 using ::testing::Gt; |
27 using ::testing::NotNull; | 28 using ::testing::NotNull; |
28 | 29 |
29 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) { | 30 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) { |
30 if (++*count >= limit) { | 31 if (++*count >= limit) { |
31 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); | 32 loop->PostTask(FROM_HERE, MessageLoop::QuitClosure()); |
32 } | 33 } |
33 } | 34 } |
34 | 35 |
35 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { | 36 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { |
36 public: | 37 public: |
37 MOCK_METHOD4(OnData, void(AudioInputStream* stream, | 38 MOCK_METHOD5(OnData, void(AudioInputStream* stream, |
38 const uint8* src, uint32 size, | 39 const uint8* src, uint32 size, |
39 uint32 hardware_delay_bytes)); | 40 uint32 hardware_delay_bytes, double volume)); |
40 MOCK_METHOD1(OnClose, void(AudioInputStream* stream)); | 41 MOCK_METHOD1(OnClose, void(AudioInputStream* stream)); |
41 MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code)); | 42 MOCK_METHOD2(OnError, void(AudioInputStream* stream, int code)); |
42 }; | 43 }; |
43 | 44 |
44 // This audio sink implementation should be used for manual tests only since | 45 // This audio sink implementation should be used for manual tests only since |
45 // the recorded data is stored on a raw binary data file. | 46 // the recorded data is stored on a raw binary data file. |
46 class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { | 47 class WriteToFileAudioSink : public AudioInputStream::AudioInputCallback { |
47 public: | 48 public: |
48 // Allocate space for ~10 seconds of data @ 48kHz in stereo: | 49 // Allocate space for ~10 seconds of data @ 48kHz in stereo: |
49 // 2 bytes per sample, 2 channels, 10ms @ 48kHz, 10 seconds <=> 1920000 bytes. | 50 // 2 bytes per sample, 2 channels, 10ms @ 48kHz, 10 seconds <=> 1920000 bytes. |
(...skipping 26 matching lines...) Expand all Loading... |
76 buffer_.Seek(chunk_size); | 77 buffer_.Seek(chunk_size); |
77 bytes_written += chunk_size; | 78 bytes_written += chunk_size; |
78 } | 79 } |
79 file_util::CloseFile(binary_file_); | 80 file_util::CloseFile(binary_file_); |
80 } | 81 } |
81 | 82 |
82 // AudioInputStream::AudioInputCallback implementation. | 83 // AudioInputStream::AudioInputCallback implementation. |
83 virtual void OnData(AudioInputStream* stream, | 84 virtual void OnData(AudioInputStream* stream, |
84 const uint8* src, | 85 const uint8* src, |
85 uint32 size, | 86 uint32 size, |
86 uint32 hardware_delay_bytes) { | 87 uint32 hardware_delay_bytes, |
| 88 double volume) { |
87 // Store data data in a temporary buffer to avoid making blocking | 89 // Store data data in a temporary buffer to avoid making blocking |
88 // fwrite() calls in the audio callback. The complete buffer will be | 90 // fwrite() calls in the audio callback. The complete buffer will be |
89 // written to file in the destructor. | 91 // written to file in the destructor. |
90 if (buffer_.Append(src, size)) { | 92 if (buffer_.Append(src, size)) { |
91 bytes_to_write_ += size; | 93 bytes_to_write_ += size; |
92 } | 94 } |
93 } | 95 } |
94 | 96 |
95 virtual void OnClose(AudioInputStream* stream) {} | 97 virtual void OnClose(AudioInputStream* stream) {} |
96 virtual void OnError(AudioInputStream* stream, int code) {} | 98 virtual void OnError(AudioInputStream* stream, int code) {} |
(...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
299 MockAudioInputCallback sink; | 301 MockAudioInputCallback sink; |
300 | 302 |
301 // Derive the expected size in bytes of each recorded packet. | 303 // Derive the expected size in bytes of each recorded packet. |
302 uint32 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * | 304 uint32 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * |
303 (aisw.bits_per_sample() / 8); | 305 (aisw.bits_per_sample() / 8); |
304 | 306 |
305 // We use 10ms packets and will run the test until ten packets are received. | 307 // We use 10ms packets and will run the test until ten packets are received. |
306 // All should contain valid packets of the same size and a valid delay | 308 // All should contain valid packets of the same size and a valid delay |
307 // estimate. | 309 // estimate. |
308 EXPECT_CALL(sink, OnData( | 310 EXPECT_CALL(sink, OnData( |
309 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) | 311 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) |
310 .Times(AtLeast(10)) | 312 .Times(AtLeast(10)) |
311 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 313 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); |
312 ais->Start(&sink); | 314 ais->Start(&sink); |
313 loop.Run(); | 315 loop.Run(); |
314 ais->Stop(); | 316 ais->Stop(); |
315 | 317 |
316 // Store current packet size (to be used in the subsequent tests). | 318 // Store current packet size (to be used in the subsequent tests). |
317 int samples_per_packet_10ms = aisw.samples_per_packet(); | 319 int samples_per_packet_10ms = aisw.samples_per_packet(); |
318 | 320 |
319 EXPECT_CALL(sink, OnClose(ais)) | 321 EXPECT_CALL(sink, OnClose(ais)) |
320 .Times(1); | 322 .Times(1); |
321 ais->Close(); | 323 ais->Close(); |
322 | 324 |
323 // 20 ms packet size. | 325 // 20 ms packet size. |
324 | 326 |
325 count = 0; | 327 count = 0; |
326 ais = aisw.Create(2 * samples_per_packet_10ms); | 328 ais = aisw.Create(2 * samples_per_packet_10ms); |
327 EXPECT_TRUE(ais->Open()); | 329 EXPECT_TRUE(ais->Open()); |
328 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * | 330 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * |
329 (aisw.bits_per_sample() / 8); | 331 (aisw.bits_per_sample() / 8); |
330 | 332 |
331 EXPECT_CALL(sink, OnData( | 333 EXPECT_CALL(sink, OnData( |
332 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) | 334 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) |
333 .Times(AtLeast(10)) | 335 .Times(AtLeast(10)) |
334 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 336 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); |
335 ais->Start(&sink); | 337 ais->Start(&sink); |
336 loop.Run(); | 338 loop.Run(); |
337 ais->Stop(); | 339 ais->Stop(); |
338 | 340 |
339 EXPECT_CALL(sink, OnClose(ais)) | 341 EXPECT_CALL(sink, OnClose(ais)) |
340 .Times(1); | 342 .Times(1); |
341 ais->Close(); | 343 ais->Close(); |
342 | 344 |
343 // 5 ms packet size. | 345 // 5 ms packet size. |
344 | 346 |
345 count = 0; | 347 count = 0; |
346 ais = aisw.Create(samples_per_packet_10ms / 2); | 348 ais = aisw.Create(samples_per_packet_10ms / 2); |
347 EXPECT_TRUE(ais->Open()); | 349 EXPECT_TRUE(ais->Open()); |
348 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * | 350 bytes_per_packet = aisw.channels() * aisw.samples_per_packet() * |
349 (aisw.bits_per_sample() / 8); | 351 (aisw.bits_per_sample() / 8); |
350 | 352 |
351 EXPECT_CALL(sink, OnData( | 353 EXPECT_CALL(sink, OnData( |
352 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet))) | 354 ais, NotNull(), bytes_per_packet, Gt(bytes_per_packet), _)) |
353 .Times(AtLeast(10)) | 355 .Times(AtLeast(10)) |
354 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 356 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); |
355 ais->Start(&sink); | 357 ais->Start(&sink); |
356 loop.Run(); | 358 loop.Run(); |
357 ais->Stop(); | 359 ais->Stop(); |
358 | 360 |
359 EXPECT_CALL(sink, OnClose(ais)) | 361 EXPECT_CALL(sink, OnClose(ais)) |
360 .Times(1); | 362 .Times(1); |
361 ais->Close(); | 363 ais->Close(); |
362 } | 364 } |
(...skipping 20 matching lines...) Expand all Loading... |
383 | 385 |
384 LOG(INFO) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; | 386 LOG(INFO) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; |
385 WriteToFileAudioSink file_sink(file_name); | 387 WriteToFileAudioSink file_sink(file_name); |
386 LOG(INFO) << ">> Speak into the default microphone while recording."; | 388 LOG(INFO) << ">> Speak into the default microphone while recording."; |
387 ais->Start(&file_sink); | 389 ais->Start(&file_sink); |
388 base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); | 390 base::PlatformThread::Sleep(TestTimeouts::action_timeout_ms()); |
389 ais->Stop(); | 391 ais->Stop(); |
390 LOG(INFO) << ">> Recording has stopped."; | 392 LOG(INFO) << ">> Recording has stopped."; |
391 ais->Close(); | 393 ais->Close(); |
392 } | 394 } |
OLD | NEW |