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