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