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/base_paths.h" | 9 #include "base/base_paths.h" |
10 #include "base/memory/aligned_memory.h" | 10 #include "base/memory/aligned_memory.h" |
(...skipping 14 matching lines...) Expand all Loading... |
25 using ::testing::DoAll; | 25 using ::testing::DoAll; |
26 using ::testing::Field; | 26 using ::testing::Field; |
27 using ::testing::Invoke; | 27 using ::testing::Invoke; |
28 using ::testing::InSequence; | 28 using ::testing::InSequence; |
29 using ::testing::NiceMock; | 29 using ::testing::NiceMock; |
30 using ::testing::NotNull; | 30 using ::testing::NotNull; |
31 using ::testing::Return; | 31 using ::testing::Return; |
32 | 32 |
33 namespace media { | 33 namespace media { |
34 | 34 |
35 static int ClearData(AudioBus* audio_bus, | 35 static int ClearData(AudioBus* audio_bus, uint32 total_bytes_delay) { |
36 uint32_t total_bytes_delay, | |
37 uint32_t frames_skipped) { | |
38 audio_bus->Zero(); | 36 audio_bus->Zero(); |
39 return audio_bus->frames(); | 37 return audio_bus->frames(); |
40 } | 38 } |
41 | 39 |
42 // This class allows to find out if the callbacks are occurring as | 40 // This class allows to find out if the callbacks are occurring as |
43 // expected and if any error has been reported. | 41 // expected and if any error has been reported. |
44 class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { | 42 class TestSourceBasic : public AudioOutputStream::AudioSourceCallback { |
45 public: | 43 public: |
46 TestSourceBasic() | 44 TestSourceBasic() |
47 : callback_count_(0), | 45 : callback_count_(0), |
48 had_error_(0) { | 46 had_error_(0) { |
49 } | 47 } |
50 // AudioSourceCallback::OnMoreData implementation: | 48 // AudioSourceCallback::OnMoreData implementation: |
51 int OnMoreData(AudioBus* audio_bus, | 49 int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override { |
52 uint32_t total_bytes_delay, | |
53 uint32_t frames_skipped) override { | |
54 ++callback_count_; | 50 ++callback_count_; |
55 // Touch the channel memory value to make sure memory is good. | 51 // Touch the channel memory value to make sure memory is good. |
56 audio_bus->Zero(); | 52 audio_bus->Zero(); |
57 return audio_bus->frames(); | 53 return audio_bus->frames(); |
58 } | 54 } |
59 // AudioSourceCallback::OnError implementation: | 55 // AudioSourceCallback::OnError implementation: |
60 void OnError(AudioOutputStream* stream) override { ++had_error_; } | 56 void OnError(AudioOutputStream* stream) override { ++had_error_; } |
61 // Returns how many times OnMoreData() has been called. | 57 // Returns how many times OnMoreData() has been called. |
62 int callback_count() const { | 58 int callback_count() const { |
63 return callback_count_; | 59 return callback_count_; |
(...skipping 13 matching lines...) Expand all Loading... |
77 }; | 73 }; |
78 | 74 |
79 const int kMaxNumBuffers = 3; | 75 const int kMaxNumBuffers = 3; |
80 // Specializes TestSourceBasic to simulate a source that blocks for some time | 76 // Specializes TestSourceBasic to simulate a source that blocks for some time |
81 // in the OnMoreData callback. | 77 // in the OnMoreData callback. |
82 class TestSourceLaggy : public TestSourceBasic { | 78 class TestSourceLaggy : public TestSourceBasic { |
83 public: | 79 public: |
84 explicit TestSourceLaggy(int lag_in_ms) | 80 explicit TestSourceLaggy(int lag_in_ms) |
85 : lag_in_ms_(lag_in_ms) { | 81 : lag_in_ms_(lag_in_ms) { |
86 } | 82 } |
87 int OnMoreData(AudioBus* audio_bus, | 83 int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override { |
88 uint32_t total_bytes_delay, | |
89 uint32_t frames_skipped) override { | |
90 // Call the base, which increments the callback_count_. | 84 // Call the base, which increments the callback_count_. |
91 TestSourceBasic::OnMoreData(audio_bus, total_bytes_delay, frames_skipped); | 85 TestSourceBasic::OnMoreData(audio_bus, total_bytes_delay); |
92 if (callback_count() > kMaxNumBuffers) { | 86 if (callback_count() > kMaxNumBuffers) { |
93 ::Sleep(lag_in_ms_); | 87 ::Sleep(lag_in_ms_); |
94 } | 88 } |
95 return audio_bus->frames(); | 89 return audio_bus->frames(); |
96 } | 90 } |
97 private: | 91 private: |
98 int lag_in_ms_; | 92 int lag_in_ms_; |
99 }; | 93 }; |
100 | 94 |
101 // Helper class to memory map an entire file. The mapping is read-only. Don't | 95 // Helper class to memory map an entire file. The mapping is read-only. Don't |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 uint32 bytes_100_ms = samples_100_ms * 2; | 467 uint32 bytes_100_ms = samples_100_ms * 2; |
474 | 468 |
475 // Audio output stream has either a double or triple buffer scheme. | 469 // Audio output stream has either a double or triple buffer scheme. |
476 // We expect the amount of pending bytes will reaching up to 2 times of | 470 // We expect the amount of pending bytes will reaching up to 2 times of |
477 // |bytes_100_ms| depending on number of buffers used. | 471 // |bytes_100_ms| depending on number of buffers used. |
478 // From that it would decrease as we are playing the data but not providing | 472 // From that it would decrease as we are playing the data but not providing |
479 // new one. And then we will try to provide zero data so the amount of | 473 // new one. And then we will try to provide zero data so the amount of |
480 // pending bytes will go down and eventually read zero. | 474 // pending bytes will go down and eventually read zero. |
481 InSequence s; | 475 InSequence s; |
482 | 476 |
483 EXPECT_CALL(source, OnMoreData(NotNull(), 0, 0)).WillOnce(Invoke(ClearData)); | 477 EXPECT_CALL(source, OnMoreData(NotNull(), 0)) |
| 478 .WillOnce(Invoke(ClearData)); |
484 | 479 |
485 // Note: If AudioManagerWin::NumberOfWaveOutBuffers() ever changes, or if this | 480 // Note: If AudioManagerWin::NumberOfWaveOutBuffers() ever changes, or if this |
486 // test is run on Vista, these expectations will fail. | 481 // test is run on Vista, these expectations will fail. |
487 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 0)) | 482 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms)) |
488 .WillOnce(Invoke(ClearData)); | 483 .WillOnce(Invoke(ClearData)); |
489 EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms, 0)) | 484 EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms)) |
490 .WillOnce(Invoke(ClearData)); | 485 .WillOnce(Invoke(ClearData)); |
491 EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms, 0)) | 486 EXPECT_CALL(source, OnMoreData(NotNull(), 2 * bytes_100_ms)) |
492 .Times(AnyNumber()) | 487 .Times(AnyNumber()) |
493 .WillRepeatedly(Return(0)); | 488 .WillRepeatedly(Return(0)); |
494 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms, 0)) | 489 EXPECT_CALL(source, OnMoreData(NotNull(), bytes_100_ms)) |
495 .Times(AnyNumber()) | 490 .Times(AnyNumber()) |
496 .WillRepeatedly(Return(0)); | 491 .WillRepeatedly(Return(0)); |
497 EXPECT_CALL(source, OnMoreData(NotNull(), 0, 0)) | 492 EXPECT_CALL(source, OnMoreData(NotNull(), 0)) |
498 .Times(AnyNumber()) | 493 .Times(AnyNumber()) |
499 .WillRepeatedly(Return(0)); | 494 .WillRepeatedly(Return(0)); |
500 | 495 |
501 oas->Start(&source); | 496 oas->Start(&source); |
502 ::Sleep(500); | 497 ::Sleep(500); |
503 oas->Stop(); | 498 oas->Stop(); |
504 oas->Close(); | 499 oas->Close(); |
505 } | 500 } |
506 | 501 |
507 // Simple source that uses a SyncSocket to retrieve the audio data | 502 // Simple source that uses a SyncSocket to retrieve the audio data |
508 // from a potentially remote thread. | 503 // from a potentially remote thread. |
509 class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { | 504 class SyncSocketSource : public AudioOutputStream::AudioSourceCallback { |
510 public: | 505 public: |
511 SyncSocketSource(base::SyncSocket* socket, const AudioParameters& params) | 506 SyncSocketSource(base::SyncSocket* socket, const AudioParameters& params) |
512 : socket_(socket) { | 507 : socket_(socket) { |
513 // Setup AudioBus wrapping data we'll receive over the sync socket. | 508 // Setup AudioBus wrapping data we'll receive over the sync socket. |
514 data_size_ = AudioBus::CalculateMemorySize(params); | 509 data_size_ = AudioBus::CalculateMemorySize(params); |
515 data_.reset(static_cast<float*>( | 510 data_.reset(static_cast<float*>( |
516 base::AlignedAlloc(data_size_, AudioBus::kChannelAlignment))); | 511 base::AlignedAlloc(data_size_, AudioBus::kChannelAlignment))); |
517 audio_bus_ = AudioBus::WrapMemory(params, data_.get()); | 512 audio_bus_ = AudioBus::WrapMemory(params, data_.get()); |
518 } | 513 } |
519 ~SyncSocketSource() override {} | 514 ~SyncSocketSource() override {} |
520 | 515 |
521 // AudioSourceCallback::OnMoreData implementation: | 516 // AudioSourceCallback::OnMoreData implementation: |
522 int OnMoreData(AudioBus* audio_bus, | 517 int OnMoreData(AudioBus* audio_bus, uint32 total_bytes_delay) override { |
523 uint32_t total_bytes_delay, | |
524 uint32_t frames_skipped) override { | |
525 socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); | 518 socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); |
526 uint32 size = socket_->Receive(data_.get(), data_size_); | 519 uint32 size = socket_->Receive(data_.get(), data_size_); |
527 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); | 520 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); |
528 audio_bus_->CopyTo(audio_bus); | 521 audio_bus_->CopyTo(audio_bus); |
529 return audio_bus_->frames(); | 522 return audio_bus_->frames(); |
530 } | 523 } |
531 | 524 |
532 // AudioSourceCallback::OnError implementation: | 525 // AudioSourceCallback::OnError implementation: |
533 void OnError(AudioOutputStream* stream) override {} | 526 void OnError(AudioOutputStream* stream) override {} |
534 | 527 |
(...skipping 30 matching lines...) Expand all Loading... |
565 | 558 |
566 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); | 559 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); |
567 const int kTwoSecFrames = ctx.sample_rate * 2; | 560 const int kTwoSecFrames = ctx.sample_rate * 2; |
568 | 561 |
569 uint32 total_bytes_delay = 0; | 562 uint32 total_bytes_delay = 0; |
570 int times = 0; | 563 int times = 0; |
571 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { | 564 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { |
572 if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) | 565 if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) |
573 break; | 566 break; |
574 if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); | 567 if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); |
575 sine.OnMoreData(audio_bus.get(), total_bytes_delay, 0); | 568 sine.OnMoreData(audio_bus.get(), total_bytes_delay); |
576 ctx.socket->Send(data.get(), ctx.packet_size_bytes); | 569 ctx.socket->Send(data.get(), ctx.packet_size_bytes); |
577 ++times; | 570 ++times; |
578 } | 571 } |
579 | 572 |
580 return 0; | 573 return 0; |
581 } | 574 } |
582 | 575 |
583 // Test the basic operation of AudioOutputStream used with a SyncSocket. | 576 // Test the basic operation of AudioOutputStream used with a SyncSocket. |
584 // The emphasis is to verify that it is possible to feed data to the audio | 577 // The emphasis is to verify that it is possible to feed data to the audio |
585 // layer using a source based on SyncSocket. In a real situation we would | 578 // layer using a source based on SyncSocket. In a real situation we would |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
623 oas->Start(&source); | 616 oas->Start(&source); |
624 | 617 |
625 ::WaitForSingleObject(thread, INFINITE); | 618 ::WaitForSingleObject(thread, INFINITE); |
626 ::CloseHandle(thread); | 619 ::CloseHandle(thread); |
627 | 620 |
628 oas->Stop(); | 621 oas->Stop(); |
629 oas->Close(); | 622 oas->Close(); |
630 } | 623 } |
631 | 624 |
632 } // namespace media | 625 } // namespace media |
OLD | NEW |