| OLD | NEW |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "base/basictypes.h" | 5 #include "base/basictypes.h" |
| 6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 7 #include "base/memory/scoped_ptr.h" | 7 #include "base/memory/scoped_ptr.h" |
| 8 #include "base/message_loop/message_loop.h" | 8 #include "base/message_loop/message_loop.h" |
| 9 #include "base/path_service.h" | 9 #include "base/path_service.h" |
| 10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 135 class FileAudioSource : public AudioOutputStream::AudioSourceCallback { | 135 class FileAudioSource : public AudioOutputStream::AudioSourceCallback { |
| 136 public: | 136 public: |
| 137 explicit FileAudioSource(base::WaitableEvent* event, const std::string& name) | 137 explicit FileAudioSource(base::WaitableEvent* event, const std::string& name) |
| 138 : event_(event), pos_(0) { | 138 : event_(event), pos_(0) { |
| 139 // Reads a test file from media/test/data directory and stores it in | 139 // Reads a test file from media/test/data directory and stores it in |
| 140 // a DecoderBuffer. | 140 // a DecoderBuffer. |
| 141 file_ = ReadTestDataFile(name); | 141 file_ = ReadTestDataFile(name); |
| 142 | 142 |
| 143 // Log the name of the file which is used as input for this test. | 143 // Log the name of the file which is used as input for this test. |
| 144 base::FilePath file_path = GetTestDataFilePath(name); | 144 base::FilePath file_path = GetTestDataFilePath(name); |
| 145 LOG(INFO) << "Reading from file: " << file_path.value().c_str(); | 145 VLOG(0) << "Reading from file: " << file_path.value().c_str(); |
| 146 } | 146 } |
| 147 | 147 |
| 148 virtual ~FileAudioSource() {} | 148 virtual ~FileAudioSource() {} |
| 149 | 149 |
| 150 // AudioOutputStream::AudioSourceCallback implementation. | 150 // AudioOutputStream::AudioSourceCallback implementation. |
| 151 | 151 |
| 152 // Use samples read from a data file and fill up the audio buffer | 152 // Use samples read from a data file and fill up the audio buffer |
| 153 // provided to us in the callback. | 153 // provided to us in the callback. |
| 154 virtual int OnMoreData(AudioBus* audio_bus, | 154 virtual int OnMoreData(AudioBus* audio_bus, |
| 155 AudioBuffersState buffers_state) OVERRIDE { | 155 AudioBuffersState buffers_state) OVERRIDE { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 // Allocate space for ~10 seconds of data. | 213 // Allocate space for ~10 seconds of data. |
| 214 const int kMaxBufferSize = 10 * params.GetBytesPerSecond(); | 214 const int kMaxBufferSize = 10 * params.GetBytesPerSecond(); |
| 215 buffer_.reset(new media::SeekableBuffer(0, kMaxBufferSize)); | 215 buffer_.reset(new media::SeekableBuffer(0, kMaxBufferSize)); |
| 216 | 216 |
| 217 // Open up the binary file which will be written to in the destructor. | 217 // Open up the binary file which will be written to in the destructor. |
| 218 base::FilePath file_path; | 218 base::FilePath file_path; |
| 219 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); | 219 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path)); |
| 220 file_path = file_path.AppendASCII(file_name.c_str()); | 220 file_path = file_path.AppendASCII(file_name.c_str()); |
| 221 binary_file_ = file_util::OpenFile(file_path, "wb"); | 221 binary_file_ = file_util::OpenFile(file_path, "wb"); |
| 222 DLOG_IF(ERROR, !binary_file_) << "Failed to open binary PCM data file."; | 222 DLOG_IF(ERROR, !binary_file_) << "Failed to open binary PCM data file."; |
| 223 LOG(INFO) << "Writing to file: " << file_path.value().c_str(); | 223 VLOG(0) << "Writing to file: " << file_path.value().c_str(); |
| 224 } | 224 } |
| 225 | 225 |
| 226 virtual ~FileAudioSink() { | 226 virtual ~FileAudioSink() { |
| 227 int bytes_written = 0; | 227 int bytes_written = 0; |
| 228 while (bytes_written < buffer_->forward_capacity()) { | 228 while (bytes_written < buffer_->forward_capacity()) { |
| 229 const uint8* chunk; | 229 const uint8* chunk; |
| 230 int chunk_size; | 230 int chunk_size; |
| 231 | 231 |
| 232 // Stop writing if no more data is available. | 232 // Stop writing if no more data is available. |
| 233 if (!buffer_->GetCurrentChunk(&chunk, &chunk_size)) | 233 if (!buffer_->GetCurrentChunk(&chunk, &chunk_size)) |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 436 EXPECT_TRUE(stream->Open()); | 436 EXPECT_TRUE(stream->Open()); |
| 437 stream->Start(&sink); | 437 stream->Start(&sink); |
| 438 start_time_ = base::TimeTicks::Now(); | 438 start_time_ = base::TimeTicks::Now(); |
| 439 loop()->Run(); | 439 loop()->Run(); |
| 440 end_time_ = base::TimeTicks::Now(); | 440 end_time_ = base::TimeTicks::Now(); |
| 441 stream->Stop(); | 441 stream->Stop(); |
| 442 stream->Close(); | 442 stream->Close(); |
| 443 | 443 |
| 444 double average_time_between_callbacks_ms = | 444 double average_time_between_callbacks_ms = |
| 445 AverageTimeBetweenCallbacks(num_callbacks); | 445 AverageTimeBetweenCallbacks(num_callbacks); |
| 446 LOG(INFO) << "expected time between callbacks: " | 446 VLOG(0) << "expected time between callbacks: " |
| 447 << expected_time_between_callbacks_ms << " ms"; | 447 << expected_time_between_callbacks_ms << " ms"; |
| 448 LOG(INFO) << "average time between callbacks: " | 448 VLOG(0) << "average time between callbacks: " |
| 449 << average_time_between_callbacks_ms << " ms"; | 449 << average_time_between_callbacks_ms << " ms"; |
| 450 EXPECT_GE(average_time_between_callbacks_ms, | 450 EXPECT_GE(average_time_between_callbacks_ms, |
| 451 0.70 * expected_time_between_callbacks_ms); | 451 0.70 * expected_time_between_callbacks_ms); |
| 452 EXPECT_LE(average_time_between_callbacks_ms, | 452 EXPECT_LE(average_time_between_callbacks_ms, |
| 453 1.30 * expected_time_between_callbacks_ms); | 453 1.30 * expected_time_between_callbacks_ms); |
| 454 } | 454 } |
| 455 | 455 |
| 456 void StartOutputStreamCallbacks(const AudioParameters& params) { | 456 void StartOutputStreamCallbacks(const AudioParameters& params) { |
| 457 double expected_time_between_callbacks_ms = | 457 double expected_time_between_callbacks_ms = |
| 458 ExpectedTimeBetweenCallbacks(params); | 458 ExpectedTimeBetweenCallbacks(params); |
| 459 const int num_callbacks = | 459 const int num_callbacks = |
| (...skipping 16 matching lines...) Expand all Loading... |
| 476 EXPECT_TRUE(stream->Open()); | 476 EXPECT_TRUE(stream->Open()); |
| 477 stream->Start(&source); | 477 stream->Start(&source); |
| 478 start_time_ = base::TimeTicks::Now(); | 478 start_time_ = base::TimeTicks::Now(); |
| 479 loop()->Run(); | 479 loop()->Run(); |
| 480 end_time_ = base::TimeTicks::Now(); | 480 end_time_ = base::TimeTicks::Now(); |
| 481 stream->Stop(); | 481 stream->Stop(); |
| 482 stream->Close(); | 482 stream->Close(); |
| 483 | 483 |
| 484 double average_time_between_callbacks_ms = | 484 double average_time_between_callbacks_ms = |
| 485 AverageTimeBetweenCallbacks(num_callbacks); | 485 AverageTimeBetweenCallbacks(num_callbacks); |
| 486 LOG(INFO) << "expected time between callbacks: " | 486 VLOG(0) << "expected time between callbacks: " |
| 487 << expected_time_between_callbacks_ms << " ms"; | 487 << expected_time_between_callbacks_ms << " ms"; |
| 488 LOG(INFO) << "average time between callbacks: " | 488 VLOG(0) << "average time between callbacks: " |
| 489 << average_time_between_callbacks_ms << " ms"; | 489 << average_time_between_callbacks_ms << " ms"; |
| 490 EXPECT_GE(average_time_between_callbacks_ms, | 490 EXPECT_GE(average_time_between_callbacks_ms, |
| 491 0.70 * expected_time_between_callbacks_ms); | 491 0.70 * expected_time_between_callbacks_ms); |
| 492 EXPECT_LE(average_time_between_callbacks_ms, | 492 EXPECT_LE(average_time_between_callbacks_ms, |
| 493 1.30 * expected_time_between_callbacks_ms); | 493 1.30 * expected_time_between_callbacks_ms); |
| 494 } | 494 } |
| 495 | 495 |
| 496 scoped_ptr<base::MessageLoopForUI> loop_; | 496 scoped_ptr<base::MessageLoopForUI> loop_; |
| 497 scoped_ptr<AudioManager> audio_manager_; | 497 scoped_ptr<AudioManager> audio_manager_; |
| 498 base::TimeTicks start_time_; | 498 base::TimeTicks start_time_; |
| 499 base::TimeTicks end_time_; | 499 base::TimeTicks end_time_; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 513 AudioParameters params = GetDefaultOutputStreamParameters(); | 513 AudioParameters params = GetDefaultOutputStreamParameters(); |
| 514 EXPECT_TRUE(params.IsValid()); | 514 EXPECT_TRUE(params.IsValid()); |
| 515 VLOG(1) << params; | 515 VLOG(1) << params; |
| 516 } | 516 } |
| 517 | 517 |
| 518 // Check if low-latency output is supported and log the result as output. | 518 // Check if low-latency output is supported and log the result as output. |
| 519 TEST_F(AudioAndroidTest, IsAudioLowLatencySupported) { | 519 TEST_F(AudioAndroidTest, IsAudioLowLatencySupported) { |
| 520 AudioManagerAndroid* manager = | 520 AudioManagerAndroid* manager = |
| 521 static_cast<AudioManagerAndroid*>(audio_manager()); | 521 static_cast<AudioManagerAndroid*>(audio_manager()); |
| 522 bool low_latency = manager->IsAudioLowLatencySupported(); | 522 bool low_latency = manager->IsAudioLowLatencySupported(); |
| 523 low_latency ? LOG(INFO) << "Low latency output is supported" | 523 low_latency ? VLOG(0) << "Low latency output is supported" |
| 524 : LOG(INFO) << "Low latency output is *not* supported"; | 524 : VLOG(0) << "Low latency output is *not* supported"; |
| 525 } | 525 } |
| 526 | 526 |
| 527 // Ensure that a default input stream can be created and closed. | 527 // Ensure that a default input stream can be created and closed. |
| 528 TEST_F(AudioAndroidTest, CreateAndCloseInputStream) { | 528 TEST_F(AudioAndroidTest, CreateAndCloseInputStream) { |
| 529 AudioParameters params = GetDefaultInputStreamParameters(); | 529 AudioParameters params = GetDefaultInputStreamParameters(); |
| 530 AudioInputStream* ais = audio_manager()->MakeAudioInputStream( | 530 AudioInputStream* ais = audio_manager()->MakeAudioInputStream( |
| 531 params, AudioManagerBase::kDefaultDeviceId); | 531 params, AudioManagerBase::kDefaultDeviceId); |
| 532 EXPECT_TRUE(ais); | 532 EXPECT_TRUE(ais); |
| 533 ais->Close(); | 533 ais->Close(); |
| 534 } | 534 } |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 632 FAIL() << "This test supports 44.1kHz and 48kHz mono/stereo only."; | 632 FAIL() << "This test supports 44.1kHz and 48kHz mono/stereo only."; |
| 633 return; | 633 return; |
| 634 } | 634 } |
| 635 | 635 |
| 636 base::WaitableEvent event(false, false); | 636 base::WaitableEvent event(false, false); |
| 637 FileAudioSource source(&event, file_name); | 637 FileAudioSource source(&event, file_name); |
| 638 | 638 |
| 639 EXPECT_TRUE(aos->Open()); | 639 EXPECT_TRUE(aos->Open()); |
| 640 aos->SetVolume(1.0); | 640 aos->SetVolume(1.0); |
| 641 aos->Start(&source); | 641 aos->Start(&source); |
| 642 LOG(INFO) << ">> Verify that the file is played out correctly..."; | 642 VLOG(0) << ">> Verify that the file is played out correctly..."; |
| 643 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); | 643 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); |
| 644 aos->Stop(); | 644 aos->Stop(); |
| 645 aos->Close(); | 645 aos->Close(); |
| 646 } | 646 } |
| 647 | 647 |
| 648 // Start input streaming and run it for ten seconds while recording to a | 648 // Start input streaming and run it for ten seconds while recording to a |
| 649 // local audio file. | 649 // local audio file. |
| 650 // NOTE: this test requires user interaction and is not designed to run as an | 650 // NOTE: this test requires user interaction and is not designed to run as an |
| 651 // automatized test on bots. | 651 // automatized test on bots. |
| 652 TEST_F(AudioAndroidTest, DISABLED_RunSimplexInputStreamWithFileAsSink) { | 652 TEST_F(AudioAndroidTest, DISABLED_RunSimplexInputStreamWithFileAsSink) { |
| 653 AudioParameters params = GetDefaultInputStreamParameters(); | 653 AudioParameters params = GetDefaultInputStreamParameters(); |
| 654 VLOG(1) << params; | 654 VLOG(1) << params; |
| 655 AudioInputStream* ais = audio_manager()->MakeAudioInputStream( | 655 AudioInputStream* ais = audio_manager()->MakeAudioInputStream( |
| 656 params, AudioManagerBase::kDefaultDeviceId); | 656 params, AudioManagerBase::kDefaultDeviceId); |
| 657 EXPECT_TRUE(ais); | 657 EXPECT_TRUE(ais); |
| 658 | 658 |
| 659 std::string file_name = base::StringPrintf("out_simplex_%d_%d_%d.pcm", | 659 std::string file_name = base::StringPrintf("out_simplex_%d_%d_%d.pcm", |
| 660 params.sample_rate(), | 660 params.sample_rate(), |
| 661 params.frames_per_buffer(), | 661 params.frames_per_buffer(), |
| 662 params.channels()); | 662 params.channels()); |
| 663 | 663 |
| 664 base::WaitableEvent event(false, false); | 664 base::WaitableEvent event(false, false); |
| 665 FileAudioSink sink(&event, params, file_name); | 665 FileAudioSink sink(&event, params, file_name); |
| 666 | 666 |
| 667 EXPECT_TRUE(ais->Open()); | 667 EXPECT_TRUE(ais->Open()); |
| 668 ais->Start(&sink); | 668 ais->Start(&sink); |
| 669 LOG(INFO) << ">> Speak into the microphone to record audio..."; | 669 VLOG(0) << ">> Speak into the microphone to record audio..."; |
| 670 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); | 670 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); |
| 671 ais->Stop(); | 671 ais->Stop(); |
| 672 ais->Close(); | 672 ais->Close(); |
| 673 } | 673 } |
| 674 | 674 |
| 675 // Same test as RunSimplexInputStreamWithFileAsSink but this time output | 675 // Same test as RunSimplexInputStreamWithFileAsSink but this time output |
| 676 // streaming is active as well (reads zeros only). | 676 // streaming is active as well (reads zeros only). |
| 677 // NOTE: this test requires user interaction and is not designed to run as an | 677 // NOTE: this test requires user interaction and is not designed to run as an |
| 678 // automatized test on bots. | 678 // automatized test on bots. |
| 679 TEST_F(AudioAndroidTest, DISABLED_RunDuplexInputStreamWithFileAsSink) { | 679 TEST_F(AudioAndroidTest, DISABLED_RunDuplexInputStreamWithFileAsSink) { |
| (...skipping 19 matching lines...) Expand all Loading... |
| 699 | 699 |
| 700 EXPECT_CALL(source, OnMoreData(NotNull(), _)).WillRepeatedly( | 700 EXPECT_CALL(source, OnMoreData(NotNull(), _)).WillRepeatedly( |
| 701 Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)); | 701 Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)); |
| 702 EXPECT_CALL(source, OnError(aos)).Times(0); | 702 EXPECT_CALL(source, OnError(aos)).Times(0); |
| 703 EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0); | 703 EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0); |
| 704 | 704 |
| 705 EXPECT_TRUE(ais->Open()); | 705 EXPECT_TRUE(ais->Open()); |
| 706 EXPECT_TRUE(aos->Open()); | 706 EXPECT_TRUE(aos->Open()); |
| 707 ais->Start(&sink); | 707 ais->Start(&sink); |
| 708 aos->Start(&source); | 708 aos->Start(&source); |
| 709 LOG(INFO) << ">> Speak into the microphone to record audio"; | 709 VLOG(0) << ">> Speak into the microphone to record audio"; |
| 710 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); | 710 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout())); |
| 711 aos->Stop(); | 711 aos->Stop(); |
| 712 ais->Stop(); | 712 ais->Stop(); |
| 713 aos->Close(); | 713 aos->Close(); |
| 714 ais->Close(); | 714 ais->Close(); |
| 715 } | 715 } |
| 716 | 716 |
| 717 // Start audio in both directions while feeding captured data into a FIFO so | 717 // Start audio in both directions while feeding captured data into a FIFO so |
| 718 // it can be read directly (in loopback) by the render side. A small extra | 718 // it can be read directly (in loopback) by the render side. A small extra |
| 719 // delay will be added by the FIFO and an estimate of this delay will be | 719 // delay will be added by the FIFO and an estimate of this delay will be |
| (...skipping 29 matching lines...) Expand all Loading... |
| 749 // Start a full duplex audio session and print out estimates of the extra | 749 // Start a full duplex audio session and print out estimates of the extra |
| 750 // delay we should expect from the FIFO. If real-time delay measurements are | 750 // delay we should expect from the FIFO. If real-time delay measurements are |
| 751 // performed, the result should be reduced by this extra delay since it is | 751 // performed, the result should be reduced by this extra delay since it is |
| 752 // something that has been added by the test. | 752 // something that has been added by the test. |
| 753 EXPECT_TRUE(ais->Open()); | 753 EXPECT_TRUE(ais->Open()); |
| 754 EXPECT_TRUE(aos->Open()); | 754 EXPECT_TRUE(aos->Open()); |
| 755 ais->Start(&full_duplex); | 755 ais->Start(&full_duplex); |
| 756 aos->Start(&full_duplex); | 756 aos->Start(&full_duplex); |
| 757 VLOG(1) << "HINT: an estimate of the extra FIFO delay will be updated " | 757 VLOG(1) << "HINT: an estimate of the extra FIFO delay will be updated " |
| 758 << "once per second during this test."; | 758 << "once per second during this test."; |
| 759 LOG(INFO) << ">> Speak into the mic and listen to the audio in loopback..."; | 759 VLOG(0) << ">> Speak into the mic and listen to the audio in loopback..."; |
| 760 fflush(stdout); | 760 fflush(stdout); |
| 761 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); | 761 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); |
| 762 printf("\n"); | 762 printf("\n"); |
| 763 aos->Stop(); | 763 aos->Stop(); |
| 764 ais->Stop(); | 764 ais->Stop(); |
| 765 aos->Close(); | 765 aos->Close(); |
| 766 ais->Close(); | 766 ais->Close(); |
| 767 } | 767 } |
| 768 | 768 |
| 769 } // namespace media | 769 } // namespace media |
| OLD | NEW |