| 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/android/build_info.h" | 5 #include "base/android/build_info.h" |
| 6 #include "base/basictypes.h" | 6 #include "base/basictypes.h" |
| 7 #include "base/file_util.h" | 7 #include "base/file_util.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop/message_loop.h" | 9 #include "base/message_loop/message_loop.h" |
| 10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 << "bytes per frame: " << params.GetBytesPerFrame() << endl | 141 << "bytes per frame: " << params.GetBytesPerFrame() << endl |
| 142 << "chunk size in ms: " << ExpectedTimeBetweenCallbacks(params) << endl | 142 << "chunk size in ms: " << ExpectedTimeBetweenCallbacks(params) << endl |
| 143 << "echo_canceller: " | 143 << "echo_canceller: " |
| 144 << (params.effects() & AudioParameters::ECHO_CANCELLER); | 144 << (params.effects() & AudioParameters::ECHO_CANCELLER); |
| 145 return os; | 145 return os; |
| 146 } | 146 } |
| 147 | 147 |
| 148 // Gmock implementation of AudioInputStream::AudioInputCallback. | 148 // Gmock implementation of AudioInputStream::AudioInputCallback. |
| 149 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { | 149 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback { |
| 150 public: | 150 public: |
| 151 MOCK_METHOD5(OnData, | 151 MOCK_METHOD4(OnData, |
| 152 void(AudioInputStream* stream, | 152 void(AudioInputStream* stream, |
| 153 const uint8* src, | 153 const AudioBus* src, |
| 154 uint32 size, | |
| 155 uint32 hardware_delay_bytes, | 154 uint32 hardware_delay_bytes, |
| 156 double volume)); | 155 double volume)); |
| 157 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); | 156 MOCK_METHOD1(OnError, void(AudioInputStream* stream)); |
| 158 }; | 157 }; |
| 159 | 158 |
| 160 // Implements AudioOutputStream::AudioSourceCallback and provides audio data | 159 // Implements AudioOutputStream::AudioSourceCallback and provides audio data |
| 161 // by reading from a data file. | 160 // by reading from a data file. |
| 162 class FileAudioSource : public AudioOutputStream::AudioSourceCallback { | 161 class FileAudioSource : public AudioOutputStream::AudioSourceCallback { |
| 163 public: | 162 public: |
| 164 explicit FileAudioSource(base::WaitableEvent* event, const std::string& name) | 163 explicit FileAudioSource(base::WaitableEvent* event, const std::string& name) |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 257 // TODO(henrika): use file_util:: instead. | 256 // TODO(henrika): use file_util:: instead. |
| 258 fwrite(chunk, 1, chunk_size, binary_file_); | 257 fwrite(chunk, 1, chunk_size, binary_file_); |
| 259 buffer_->Seek(chunk_size); | 258 buffer_->Seek(chunk_size); |
| 260 bytes_written += chunk_size; | 259 bytes_written += chunk_size; |
| 261 } | 260 } |
| 262 base::CloseFile(binary_file_); | 261 base::CloseFile(binary_file_); |
| 263 } | 262 } |
| 264 | 263 |
| 265 // AudioInputStream::AudioInputCallback implementation. | 264 // AudioInputStream::AudioInputCallback implementation. |
| 266 virtual void OnData(AudioInputStream* stream, | 265 virtual void OnData(AudioInputStream* stream, |
| 267 const uint8* src, | 266 const AudioBus* src, |
| 268 uint32 size, | |
| 269 uint32 hardware_delay_bytes, | 267 uint32 hardware_delay_bytes, |
| 270 double volume) OVERRIDE { | 268 double volume) OVERRIDE { |
| 269 const int num_samples = src->frames() * src->channels(); |
| 270 scoped_ptr<int16> interleaved(new int16[num_samples]); |
| 271 const int bytes_per_sample = sizeof(*interleaved); |
| 272 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); |
| 273 |
| 271 // Store data data in a temporary buffer to avoid making blocking | 274 // Store data data in a temporary buffer to avoid making blocking |
| 272 // fwrite() calls in the audio callback. The complete buffer will be | 275 // fwrite() calls in the audio callback. The complete buffer will be |
| 273 // written to file in the destructor. | 276 // written to file in the destructor. |
| 274 if (!buffer_->Append(src, size)) | 277 const int size = bytes_per_sample * num_samples; |
| 278 if (!buffer_->Append((const uint8*)interleaved.get(), size)) |
| 275 event_->Signal(); | 279 event_->Signal(); |
| 276 } | 280 } |
| 277 | 281 |
| 278 virtual void OnError(AudioInputStream* stream) OVERRIDE {} | 282 virtual void OnError(AudioInputStream* stream) OVERRIDE {} |
| 279 | 283 |
| 280 private: | 284 private: |
| 281 base::WaitableEvent* event_; | 285 base::WaitableEvent* event_; |
| 282 AudioParameters params_; | 286 AudioParameters params_; |
| 283 scoped_ptr<media::SeekableBuffer> buffer_; | 287 scoped_ptr<media::SeekableBuffer> buffer_; |
| 284 FILE* binary_file_; | 288 FILE* binary_file_; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 300 // Start with a reasonably small FIFO size. It will be increased | 304 // Start with a reasonably small FIFO size. It will be increased |
| 301 // dynamically during the test if required. | 305 // dynamically during the test if required. |
| 302 fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer())); | 306 fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer())); |
| 303 buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); | 307 buffer_.reset(new uint8[params_.GetBytesPerBuffer()]); |
| 304 } | 308 } |
| 305 | 309 |
| 306 virtual ~FullDuplexAudioSinkSource() {} | 310 virtual ~FullDuplexAudioSinkSource() {} |
| 307 | 311 |
| 308 // AudioInputStream::AudioInputCallback implementation | 312 // AudioInputStream::AudioInputCallback implementation |
| 309 virtual void OnData(AudioInputStream* stream, | 313 virtual void OnData(AudioInputStream* stream, |
| 310 const uint8* src, | 314 const AudioBus* src, |
| 311 uint32 size, | |
| 312 uint32 hardware_delay_bytes, | 315 uint32 hardware_delay_bytes, |
| 313 double volume) OVERRIDE { | 316 double volume) OVERRIDE { |
| 314 const base::TimeTicks now_time = base::TimeTicks::Now(); | 317 const base::TimeTicks now_time = base::TimeTicks::Now(); |
| 315 const int diff = (now_time - previous_time_).InMilliseconds(); | 318 const int diff = (now_time - previous_time_).InMilliseconds(); |
| 316 | 319 |
| 320 EXPECT_EQ(params_.bits_per_sample(), 16); |
| 321 const int num_samples = src->frames() * src->channels(); |
| 322 scoped_ptr<int16> interleaved(new int16[num_samples]); |
| 323 const int bytes_per_sample = sizeof(*interleaved); |
| 324 src->ToInterleaved(src->frames(), bytes_per_sample, interleaved.get()); |
| 325 const int size = bytes_per_sample * num_samples; |
| 326 |
| 317 base::AutoLock lock(lock_); | 327 base::AutoLock lock(lock_); |
| 318 if (diff > 1000) { | 328 if (diff > 1000) { |
| 319 started_ = true; | 329 started_ = true; |
| 320 previous_time_ = now_time; | 330 previous_time_ = now_time; |
| 321 | 331 |
| 322 // Log out the extra delay added by the FIFO. This is a best effort | 332 // Log out the extra delay added by the FIFO. This is a best effort |
| 323 // estimate. We might be +- 10ms off here. | 333 // estimate. We might be +- 10ms off here. |
| 324 int extra_fifo_delay = | 334 int extra_fifo_delay = |
| 325 static_cast<int>(BytesToMilliseconds(fifo_->forward_bytes() + size)); | 335 static_cast<int>(BytesToMilliseconds(fifo_->forward_bytes() + size)); |
| 326 DVLOG(1) << extra_fifo_delay; | 336 DVLOG(1) << extra_fifo_delay; |
| 327 } | 337 } |
| 328 | 338 |
| 329 // We add an initial delay of ~1 second before loopback starts to ensure | 339 // We add an initial delay of ~1 second before loopback starts to ensure |
| 330 // a stable callback sequence and to avoid initial bursts which might add | 340 // a stable callback sequence and to avoid initial bursts which might add |
| 331 // to the extra FIFO delay. | 341 // to the extra FIFO delay. |
| 332 if (!started_) | 342 if (!started_) |
| 333 return; | 343 return; |
| 334 | 344 |
| 335 // Append new data to the FIFO and extend the size if the max capacity | 345 // Append new data to the FIFO and extend the size if the max capacity |
| 336 // was exceeded. Flush the FIFO when extended just in case. | 346 // was exceeded. Flush the FIFO when extended just in case. |
| 337 if (!fifo_->Append(src, size)) { | 347 if (!fifo_->Append((const uint8*)interleaved.get(), size)) { |
| 338 fifo_->set_forward_capacity(2 * fifo_->forward_capacity()); | 348 fifo_->set_forward_capacity(2 * fifo_->forward_capacity()); |
| 339 fifo_->Clear(); | 349 fifo_->Clear(); |
| 340 } | 350 } |
| 341 } | 351 } |
| 342 | 352 |
| 343 virtual void OnError(AudioInputStream* stream) OVERRIDE {} | 353 virtual void OnError(AudioInputStream* stream) OVERRIDE {} |
| 344 | 354 |
| 345 // AudioOutputStream::AudioSourceCallback implementation | 355 // AudioOutputStream::AudioSourceCallback implementation |
| 346 virtual int OnMoreData(AudioBus* dest, | 356 virtual int OnMoreData(AudioBus* dest, |
| 347 AudioBuffersState buffers_state) OVERRIDE { | 357 AudioBuffersState buffers_state) OVERRIDE { |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 633 double expected_time_between_callbacks_ms = | 643 double expected_time_between_callbacks_ms = |
| 634 ExpectedTimeBetweenCallbacks(params); | 644 ExpectedTimeBetweenCallbacks(params); |
| 635 const int num_callbacks = | 645 const int num_callbacks = |
| 636 (kCallbackTestTimeMs / expected_time_between_callbacks_ms); | 646 (kCallbackTestTimeMs / expected_time_between_callbacks_ms); |
| 637 | 647 |
| 638 MakeAudioInputStreamOnAudioThread(params); | 648 MakeAudioInputStreamOnAudioThread(params); |
| 639 | 649 |
| 640 int count = 0; | 650 int count = 0; |
| 641 MockAudioInputCallback sink; | 651 MockAudioInputCallback sink; |
| 642 | 652 |
| 643 EXPECT_CALL(sink, | 653 EXPECT_CALL(sink, OnData(audio_input_stream_, NotNull(), _, _)) |
| 644 OnData(audio_input_stream_, | |
| 645 NotNull(), | |
| 646 params. | |
| 647 GetBytesPerBuffer(), _, _)) | |
| 648 .Times(AtLeast(num_callbacks)) | 654 .Times(AtLeast(num_callbacks)) |
| 649 .WillRepeatedly( | 655 .WillRepeatedly( |
| 650 CheckCountAndPostQuitTask(&count, num_callbacks, loop())); | 656 CheckCountAndPostQuitTask(&count, num_callbacks, loop())); |
| 651 EXPECT_CALL(sink, OnError(audio_input_stream_)).Times(0); | 657 EXPECT_CALL(sink, OnError(audio_input_stream_)).Times(0); |
| 652 | 658 |
| 653 OpenAndStartAudioInputStreamOnAudioThread(&sink); | 659 OpenAndStartAudioInputStreamOnAudioThread(&sink); |
| 654 | 660 |
| 655 start_time_ = base::TimeTicks::Now(); | 661 start_time_ = base::TimeTicks::Now(); |
| 656 loop()->Run(); | 662 loop()->Run(); |
| 657 end_time_ = base::TimeTicks::Now(); | 663 end_time_ = base::TimeTicks::Now(); |
| 658 | 664 |
| 659 StopAndCloseAudioInputStreamOnAudioThread(); | 665 StopAndCloseAudioInputStreamOnAudioThread(); |
| 660 | 666 |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 963 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); | 969 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20)); |
| 964 printf("\n"); | 970 printf("\n"); |
| 965 StopAndCloseAudioOutputStreamOnAudioThread(); | 971 StopAndCloseAudioOutputStreamOnAudioThread(); |
| 966 StopAndCloseAudioInputStreamOnAudioThread(); | 972 StopAndCloseAudioInputStreamOnAudioThread(); |
| 967 } | 973 } |
| 968 | 974 |
| 969 INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest, | 975 INSTANTIATE_TEST_CASE_P(AudioAndroidInputTest, AudioAndroidInputTest, |
| 970 testing::ValuesIn(RunAudioRecordInputPathTests())); | 976 testing::ValuesIn(RunAudioRecordInputPathTests())); |
| 971 | 977 |
| 972 } // namespace media | 978 } // namespace media |
| OLD | NEW |