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