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
3 // found in the LICENSE file.
5 #include "base/basictypes.h"
6 #include "base/file_util.h"
7 #include "base/memory/scoped_ptr.h"
8 #include "base/message_loop/message_loop.h"
9 #include "base/path_service.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/synchronization/lock.h"
12 #include "base/synchronization/waitable_event.h"
13 #include "base/test/test_timeouts.h"
14 #include "base/time/time.h"
15 #include "build/build_config.h"
16 #include "media/audio/android/audio_manager_android.h"
17 #include "media/audio/audio_io.h"
18 #include "media/audio/audio_manager_base.h"
19 #include "media/base/decoder_buffer.h"
20 #include "media/base/seekable_buffer.h"
21 #include "media/base/test_data_util.h"
22 #include "testing/gmock/include/gmock/gmock.h"
23 #include "testing/gtest/include/gtest/gtest.h"
26 using ::testing::AtLeast
;
27 using ::testing::DoAll
;
28 using ::testing::Invoke
;
29 using ::testing::NotNull
;
30 using ::testing::Return
;
34 ACTION_P3(CheckCountAndPostQuitTask
, count
, limit
, loop
) {
35 if (++*count
>= limit
) {
36 loop
->PostTask(FROM_HERE
, base::MessageLoop::QuitClosure());
40 static const char kSpeechFile_16b_s_48k
[] = "speech_16b_stereo_48kHz.raw";
41 static const char kSpeechFile_16b_m_48k
[] = "speech_16b_mono_48kHz.raw";
42 static const char kSpeechFile_16b_s_44k
[] = "speech_16b_stereo_44kHz.raw";
43 static const char kSpeechFile_16b_m_44k
[] = "speech_16b_mono_44kHz.raw";
45 static const float kCallbackTestTimeMs
= 2000.0;
46 static const int kBitsPerSample
= 16;
47 static const int kBytesPerSample
= kBitsPerSample
/ 8;
49 // Converts AudioParameters::Format enumerator to readable string.
50 static std::string
FormatToString(AudioParameters::Format format
) {
52 case AudioParameters::AUDIO_PCM_LINEAR
:
53 return std::string("AUDIO_PCM_LINEAR");
54 case AudioParameters::AUDIO_PCM_LOW_LATENCY
:
55 return std::string("AUDIO_PCM_LOW_LATENCY");
56 case AudioParameters::AUDIO_FAKE
:
57 return std::string("AUDIO_FAKE");
58 case AudioParameters::AUDIO_LAST_FORMAT
:
59 return std::string("AUDIO_LAST_FORMAT");
65 // Converts ChannelLayout enumerator to readable string. Does not include
66 // multi-channel cases since these layouts are not supported on Android.
67 static std::string
LayoutToString(ChannelLayout channel_layout
) {
68 switch (channel_layout
) {
69 case CHANNEL_LAYOUT_NONE
:
70 return std::string("CHANNEL_LAYOUT_NONE");
71 case CHANNEL_LAYOUT_MONO
:
72 return std::string("CHANNEL_LAYOUT_MONO");
73 case CHANNEL_LAYOUT_STEREO
:
74 return std::string("CHANNEL_LAYOUT_STEREO");
75 case CHANNEL_LAYOUT_UNSUPPORTED
:
77 return std::string("CHANNEL_LAYOUT_UNSUPPORTED");
81 static double ExpectedTimeBetweenCallbacks(AudioParameters params
) {
82 return (base::TimeDelta::FromMicroseconds(
83 params
.frames_per_buffer() * base::Time::kMicrosecondsPerSecond
/
84 static_cast<double>(params
.sample_rate()))).InMillisecondsF();
87 std::ostream
& operator<<(std::ostream
& os
, const AudioParameters
& params
) {
89 os
<< endl
<< "format: " << FormatToString(params
.format()) << endl
90 << "channel layout: " << LayoutToString(params
.channel_layout()) << endl
91 << "sample rate: " << params
.sample_rate() << endl
92 << "bits per sample: " << params
.bits_per_sample() << endl
93 << "frames per buffer: " << params
.frames_per_buffer() << endl
94 << "channels: " << params
.channels() << endl
95 << "bytes per buffer: " << params
.GetBytesPerBuffer() << endl
96 << "bytes per second: " << params
.GetBytesPerSecond() << endl
97 << "bytes per frame: " << params
.GetBytesPerFrame() << endl
98 << "frame size in ms: " << ExpectedTimeBetweenCallbacks(params
);
102 // Gmock implementation of AudioInputStream::AudioInputCallback.
103 class MockAudioInputCallback
: public AudioInputStream::AudioInputCallback
{
106 void(AudioInputStream
* stream
,
109 uint32 hardware_delay_bytes
,
111 MOCK_METHOD1(OnClose
, void(AudioInputStream
* stream
));
112 MOCK_METHOD1(OnError
, void(AudioInputStream
* stream
));
115 // Gmock implementation of AudioOutputStream::AudioSourceCallback.
116 class MockAudioOutputCallback
: public AudioOutputStream::AudioSourceCallback
{
118 MOCK_METHOD2(OnMoreData
,
119 int(AudioBus
* dest
, AudioBuffersState buffers_state
));
120 MOCK_METHOD3(OnMoreIOData
,
121 int(AudioBus
* source
,
123 AudioBuffersState buffers_state
));
124 MOCK_METHOD1(OnError
, void(AudioOutputStream
* stream
));
126 // We clear the data bus to ensure that the test does not cause noise.
127 int RealOnMoreData(AudioBus
* dest
, AudioBuffersState buffers_state
) {
129 return dest
->frames();
133 // Implements AudioOutputStream::AudioSourceCallback and provides audio data
134 // by reading from a data file.
135 class FileAudioSource
: public AudioOutputStream::AudioSourceCallback
{
137 explicit FileAudioSource(base::WaitableEvent
* event
, const std::string
& name
)
138 : event_(event
), pos_(0) {
139 // Reads a test file from media/test/data directory and stores it in
141 file_
= ReadTestDataFile(name
);
143 // Log the name of the file which is used as input for this test.
144 base::FilePath file_path
= GetTestDataFilePath(name
);
145 LOG(INFO
) << "Reading from file: " << file_path
.value().c_str();
148 virtual ~FileAudioSource() {}
150 // AudioOutputStream::AudioSourceCallback implementation.
152 // Use samples read from a data file and fill up the audio buffer
153 // provided to us in the callback.
154 virtual int OnMoreData(AudioBus
* audio_bus
,
155 AudioBuffersState buffers_state
) OVERRIDE
{
156 bool stop_playing
= false;
158 audio_bus
->frames() * audio_bus
->channels() * kBytesPerSample
;
160 // Adjust data size and prepare for end signal if file has ended.
161 if (pos_
+ max_size
> file_size()) {
163 max_size
= file_size() - pos_
;
166 // File data is stored as interleaved 16-bit values. Copy data samples from
167 // the file and deinterleave to match the audio bus format.
168 // FromInterleaved() will zero out any unfilled frames when there is not
169 // sufficient data remaining in the file to fill up the complete frame.
170 int frames
= max_size
/ (audio_bus
->channels() * kBytesPerSample
);
172 audio_bus
->FromInterleaved(file_
->data() + pos_
, frames
, kBytesPerSample
);
176 // Set event to ensure that the test can stop when the file has ended.
183 virtual int OnMoreIOData(AudioBus
* source
,
185 AudioBuffersState buffers_state
) OVERRIDE
{
190 virtual void OnError(AudioOutputStream
* stream
) OVERRIDE
{}
192 int file_size() { return file_
->data_size(); }
195 base::WaitableEvent
* event_
;
197 scoped_refptr
<DecoderBuffer
> file_
;
199 DISALLOW_COPY_AND_ASSIGN(FileAudioSource
);
202 // Implements AudioInputStream::AudioInputCallback and writes the recorded
203 // audio data to a local output file. Note that this implementation should
204 // only be used for manually invoked and evaluated tests, hence the created
205 // file will not be destroyed after the test is done since the intention is
206 // that it shall be available for off-line analysis.
207 class FileAudioSink
: public AudioInputStream::AudioInputCallback
{
209 explicit FileAudioSink(base::WaitableEvent
* event
,
210 const AudioParameters
& params
,
211 const std::string
& file_name
)
212 : event_(event
), params_(params
) {
213 // Allocate space for ~10 seconds of data.
214 const int kMaxBufferSize
= 10 * params
.GetBytesPerSecond();
215 buffer_
.reset(new media::SeekableBuffer(0, kMaxBufferSize
));
217 // Open up the binary file which will be written to in the destructor.
218 base::FilePath file_path
;
219 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT
, &file_path
));
220 file_path
= file_path
.AppendASCII(file_name
.c_str());
221 binary_file_
= file_util::OpenFile(file_path
, "wb");
222 DLOG_IF(ERROR
, !binary_file_
) << "Failed to open binary PCM data file.";
223 LOG(INFO
) << "Writing to file: " << file_path
.value().c_str();
226 virtual ~FileAudioSink() {
227 int bytes_written
= 0;
228 while (bytes_written
< buffer_
->forward_capacity()) {
232 // Stop writing if no more data is available.
233 if (!buffer_
->GetCurrentChunk(&chunk
, &chunk_size
))
236 // Write recorded data chunk to the file and prepare for next chunk.
237 // TODO(henrika): use file_util:: instead.
238 fwrite(chunk
, 1, chunk_size
, binary_file_
);
239 buffer_
->Seek(chunk_size
);
240 bytes_written
+= chunk_size
;
242 file_util::CloseFile(binary_file_
);
245 // AudioInputStream::AudioInputCallback implementation.
246 virtual void OnData(AudioInputStream
* stream
,
249 uint32 hardware_delay_bytes
,
250 double volume
) OVERRIDE
{
251 // Store data data in a temporary buffer to avoid making blocking
252 // fwrite() calls in the audio callback. The complete buffer will be
253 // written to file in the destructor.
254 if (!buffer_
->Append(src
, size
))
258 virtual void OnClose(AudioInputStream
* stream
) OVERRIDE
{}
259 virtual void OnError(AudioInputStream
* stream
) OVERRIDE
{}
262 base::WaitableEvent
* event_
;
263 AudioParameters params_
;
264 scoped_ptr
<media::SeekableBuffer
> buffer_
;
267 DISALLOW_COPY_AND_ASSIGN(FileAudioSink
);
270 // Implements AudioInputCallback and AudioSourceCallback to support full
271 // duplex audio where captured samples are played out in loopback after
272 // reading from a temporary FIFO storage.
273 class FullDuplexAudioSinkSource
274 : public AudioInputStream::AudioInputCallback
,
275 public AudioOutputStream::AudioSourceCallback
{
277 explicit FullDuplexAudioSinkSource(const AudioParameters
& params
)
279 previous_time_(base::TimeTicks::Now()),
281 // Start with a reasonably small FIFO size. It will be increased
282 // dynamically during the test if required.
283 fifo_
.reset(new media::SeekableBuffer(0, 2 * params
.GetBytesPerBuffer()));
284 buffer_
.reset(new uint8
[params_
.GetBytesPerBuffer()]);
287 virtual ~FullDuplexAudioSinkSource() {}
289 // AudioInputStream::AudioInputCallback implementation
290 virtual void OnData(AudioInputStream
* stream
,
293 uint32 hardware_delay_bytes
,
294 double volume
) OVERRIDE
{
295 const base::TimeTicks now_time
= base::TimeTicks::Now();
296 const int diff
= (now_time
- previous_time_
).InMilliseconds();
298 base::AutoLock
lock(lock_
);
301 previous_time_
= now_time
;
303 // Log out the extra delay added by the FIFO. This is a best effort
304 // estimate. We might be +- 10ms off here.
305 int extra_fifo_delay
=
306 static_cast<int>(BytesToMilliseconds(fifo_
->forward_bytes() + size
));
307 DVLOG(1) << extra_fifo_delay
;
310 // We add an initial delay of ~1 second before loopback starts to ensure
311 // a stable callback sequence and to avoid initial bursts which might add
312 // to the extra FIFO delay.
316 // Append new data to the FIFO and extend the size if the max capacity
317 // was exceeded. Flush the FIFO when extended just in case.
318 if (!fifo_
->Append(src
, size
)) {
319 fifo_
->set_forward_capacity(2 * fifo_
->forward_capacity());
324 virtual void OnClose(AudioInputStream
* stream
) OVERRIDE
{}
325 virtual void OnError(AudioInputStream
* stream
) OVERRIDE
{}
327 // AudioOutputStream::AudioSourceCallback implementation
328 virtual int OnMoreData(AudioBus
* dest
,
329 AudioBuffersState buffers_state
) OVERRIDE
{
330 const int size_in_bytes
=
331 (params_
.bits_per_sample() / 8) * dest
->frames() * dest
->channels();
332 EXPECT_EQ(size_in_bytes
, params_
.GetBytesPerBuffer());
334 base::AutoLock
lock(lock_
);
336 // We add an initial delay of ~1 second before loopback starts to ensure
337 // a stable callback sequences and to avoid initial bursts which might add
338 // to the extra FIFO delay.
341 return dest
->frames();
344 // Fill up destination with zeros if the FIFO does not contain enough
345 // data to fulfill the request.
346 if (fifo_
->forward_bytes() < size_in_bytes
) {
349 fifo_
->Read(buffer_
.get(), size_in_bytes
);
350 dest
->FromInterleaved(
351 buffer_
.get(), dest
->frames(), params_
.bits_per_sample() / 8);
354 return dest
->frames();
357 virtual int OnMoreIOData(AudioBus
* source
,
359 AudioBuffersState buffers_state
) OVERRIDE
{
364 virtual void OnError(AudioOutputStream
* stream
) OVERRIDE
{}
367 // Converts from bytes to milliseconds given number of bytes and existing
369 double BytesToMilliseconds(int bytes
) const {
370 const int frames
= bytes
/ params_
.GetBytesPerFrame();
371 return (base::TimeDelta::FromMicroseconds(
372 frames
* base::Time::kMicrosecondsPerSecond
/
373 static_cast<double>(params_
.sample_rate()))).InMillisecondsF();
376 AudioParameters params_
;
377 base::TimeTicks previous_time_
;
379 scoped_ptr
<media::SeekableBuffer
> fifo_
;
380 scoped_ptr
<uint8
[]> buffer_
;
383 DISALLOW_COPY_AND_ASSIGN(FullDuplexAudioSinkSource
);
386 // Test fixture class.
387 class AudioAndroidTest
: public testing::Test
{
389 AudioAndroidTest() {}
392 virtual void SetUp() {
393 audio_manager_
.reset(AudioManager::Create());
394 loop_
.reset(new base::MessageLoopForUI());
397 virtual void TearDown() {}
399 AudioManager
* audio_manager() { return audio_manager_
.get(); }
400 base::MessageLoopForUI
* loop() { return loop_
.get(); }
402 AudioParameters
GetDefaultInputStreamParameters() {
403 return audio_manager()->GetInputStreamParameters(
404 AudioManagerBase::kDefaultDeviceId
);
407 AudioParameters
GetDefaultOutputStreamParameters() {
408 return audio_manager()->GetDefaultOutputStreamParameters();
411 double AverageTimeBetweenCallbacks(int num_callbacks
) const {
412 return ((end_time_
- start_time_
) / static_cast<double>(num_callbacks
- 1))
416 void StartInputStreamCallbacks(const AudioParameters
& params
) {
417 double expected_time_between_callbacks_ms
=
418 ExpectedTimeBetweenCallbacks(params
);
419 const int num_callbacks
=
420 (kCallbackTestTimeMs
/ expected_time_between_callbacks_ms
);
421 AudioInputStream
* stream
= audio_manager()->MakeAudioInputStream(
422 params
, AudioManagerBase::kDefaultDeviceId
);
426 MockAudioInputCallback sink
;
429 OnData(stream
, NotNull(), params
.GetBytesPerBuffer(), _
, _
))
430 .Times(AtLeast(num_callbacks
))
432 CheckCountAndPostQuitTask(&count
, num_callbacks
, loop()));
433 EXPECT_CALL(sink
, OnError(stream
)).Times(0);
434 EXPECT_CALL(sink
, OnClose(stream
)).Times(1);
436 EXPECT_TRUE(stream
->Open());
437 stream
->Start(&sink
);
438 start_time_
= base::TimeTicks::Now();
440 end_time_
= base::TimeTicks::Now();
444 double average_time_between_callbacks_ms
=
445 AverageTimeBetweenCallbacks(num_callbacks
);
446 LOG(INFO
) << "expected time between callbacks: "
447 << expected_time_between_callbacks_ms
<< " ms";
448 LOG(INFO
) << "average time between callbacks: "
449 << average_time_between_callbacks_ms
<< " ms";
450 EXPECT_GE(average_time_between_callbacks_ms
,
451 0.70 * expected_time_between_callbacks_ms
);
452 EXPECT_LE(average_time_between_callbacks_ms
,
453 1.30 * expected_time_between_callbacks_ms
);
456 void StartOutputStreamCallbacks(const AudioParameters
& params
) {
457 double expected_time_between_callbacks_ms
=
458 ExpectedTimeBetweenCallbacks(params
);
459 const int num_callbacks
=
460 (kCallbackTestTimeMs
/ expected_time_between_callbacks_ms
);
461 AudioOutputStream
* stream
= audio_manager()->MakeAudioOutputStream(
462 params
, std::string(), std::string());
466 MockAudioOutputCallback source
;
468 EXPECT_CALL(source
, OnMoreData(NotNull(), _
))
469 .Times(AtLeast(num_callbacks
))
471 DoAll(CheckCountAndPostQuitTask(&count
, num_callbacks
, loop()),
472 Invoke(&source
, &MockAudioOutputCallback::RealOnMoreData
)));
473 EXPECT_CALL(source
, OnError(stream
)).Times(0);
474 EXPECT_CALL(source
, OnMoreIOData(_
, _
, _
)).Times(0);
476 EXPECT_TRUE(stream
->Open());
477 stream
->Start(&source
);
478 start_time_
= base::TimeTicks::Now();
480 end_time_
= base::TimeTicks::Now();
484 double average_time_between_callbacks_ms
=
485 AverageTimeBetweenCallbacks(num_callbacks
);
486 LOG(INFO
) << "expected time between callbacks: "
487 << expected_time_between_callbacks_ms
<< " ms";
488 LOG(INFO
) << "average time between callbacks: "
489 << average_time_between_callbacks_ms
<< " ms";
490 EXPECT_GE(average_time_between_callbacks_ms
,
491 0.70 * expected_time_between_callbacks_ms
);
492 EXPECT_LE(average_time_between_callbacks_ms
,
493 1.30 * expected_time_between_callbacks_ms
);
496 scoped_ptr
<base::MessageLoopForUI
> loop_
;
497 scoped_ptr
<AudioManager
> audio_manager_
;
498 base::TimeTicks start_time_
;
499 base::TimeTicks end_time_
;
501 DISALLOW_COPY_AND_ASSIGN(AudioAndroidTest
);
504 // Get the default audio input parameters and log the result.
505 TEST_F(AudioAndroidTest
, GetInputStreamParameters
) {
506 AudioParameters params
= GetDefaultInputStreamParameters();
507 EXPECT_TRUE(params
.IsValid());
511 // Get the default audio output parameters and log the result.
512 TEST_F(AudioAndroidTest
, GetDefaultOutputStreamParameters
) {
513 AudioParameters params
= GetDefaultOutputStreamParameters();
514 EXPECT_TRUE(params
.IsValid());
518 // Check if low-latency output is supported and log the result as output.
519 TEST_F(AudioAndroidTest
, IsAudioLowLatencySupported
) {
520 AudioManagerAndroid
* manager
=
521 static_cast<AudioManagerAndroid
*>(audio_manager());
522 bool low_latency
= manager
->IsAudioLowLatencySupported();
523 low_latency
? LOG(INFO
) << "Low latency output is supported"
524 : LOG(INFO
) << "Low latency output is *not* supported";
527 // Ensure that a default input stream can be created and closed.
528 TEST_F(AudioAndroidTest
, CreateAndCloseInputStream
) {
529 AudioParameters params
= GetDefaultInputStreamParameters();
530 AudioInputStream
* ais
= audio_manager()->MakeAudioInputStream(
531 params
, AudioManagerBase::kDefaultDeviceId
);
536 // Ensure that a default output stream can be created and closed.
537 // TODO(henrika): should we also verify that this API changes the audio mode
538 // to communication mode, and calls RegisterHeadsetReceiver, the first time
540 TEST_F(AudioAndroidTest
, CreateAndCloseOutputStream
) {
541 AudioParameters params
= GetDefaultOutputStreamParameters();
542 AudioOutputStream
* aos
= audio_manager()->MakeAudioOutputStream(
543 params
, std::string(), std::string());
548 // Ensure that a default input stream can be opened and closed.
549 TEST_F(AudioAndroidTest
, OpenAndCloseInputStream
) {
550 AudioParameters params
= GetDefaultInputStreamParameters();
551 AudioInputStream
* ais
= audio_manager()->MakeAudioInputStream(
552 params
, AudioManagerBase::kDefaultDeviceId
);
554 EXPECT_TRUE(ais
->Open());
558 // Ensure that a default output stream can be opened and closed.
559 TEST_F(AudioAndroidTest
, OpenAndCloseOutputStream
) {
560 AudioParameters params
= GetDefaultOutputStreamParameters();
561 AudioOutputStream
* aos
= audio_manager()->MakeAudioOutputStream(
562 params
, std::string(), std::string());
564 EXPECT_TRUE(aos
->Open());
568 // Start input streaming using default input parameters and ensure that the
569 // callback sequence is sane.
570 TEST_F(AudioAndroidTest
, StartInputStreamCallbacks
) {
571 AudioParameters params
= GetDefaultInputStreamParameters();
572 StartInputStreamCallbacks(params
);
575 // Start input streaming using non default input parameters and ensure that the
576 // callback sequence is sane. The only change we make in this test is to select
577 // a 10ms buffer size instead of the default size.
578 // TODO(henrika): possibly add support for more variations.
579 TEST_F(AudioAndroidTest
, StartInputStreamCallbacksNonDefaultParameters
) {
580 AudioParameters native_params
= GetDefaultInputStreamParameters();
581 AudioParameters
params(native_params
.format(),
582 native_params
.channel_layout(),
583 native_params
.sample_rate(),
584 native_params
.bits_per_sample(),
585 native_params
.sample_rate() / 100);
586 StartInputStreamCallbacks(params
);
589 // Start output streaming using default output parameters and ensure that the
590 // callback sequence is sane.
591 TEST_F(AudioAndroidTest
, StartOutputStreamCallbacks
) {
592 AudioParameters params
= GetDefaultOutputStreamParameters();
593 StartOutputStreamCallbacks(params
);
596 // Start output streaming using non default output parameters and ensure that
597 // the callback sequence is sane. The only change we make in this test is to
598 // select a 10ms buffer size instead of the default size and to open up the
600 // TODO(henrika): possibly add support for more variations.
601 TEST_F(AudioAndroidTest
, StartOutputStreamCallbacksNonDefaultParameters
) {
602 AudioParameters native_params
= GetDefaultOutputStreamParameters();
603 AudioParameters
params(native_params
.format(),
605 native_params
.sample_rate(),
606 native_params
.bits_per_sample(),
607 native_params
.sample_rate() / 100);
608 StartOutputStreamCallbacks(params
);
611 // Play out a PCM file segment in real time and allow the user to verify that
612 // the rendered audio sounds OK.
613 // NOTE: this test requires user interaction and is not designed to run as an
614 // automatized test on bots.
615 TEST_F(AudioAndroidTest
, DISABLED_RunOutputStreamWithFileAsSource
) {
616 AudioParameters params
= GetDefaultOutputStreamParameters();
618 AudioOutputStream
* aos
= audio_manager()->MakeAudioOutputStream(
619 params
, std::string(), std::string());
622 std::string file_name
;
623 if (params
.sample_rate() == 48000 && params
.channels() == 2) {
624 file_name
= kSpeechFile_16b_s_48k
;
625 } else if (params
.sample_rate() == 48000 && params
.channels() == 1) {
626 file_name
= kSpeechFile_16b_m_48k
;
627 } else if (params
.sample_rate() == 44100 && params
.channels() == 2) {
628 file_name
= kSpeechFile_16b_s_44k
;
629 } else if (params
.sample_rate() == 44100 && params
.channels() == 1) {
630 file_name
= kSpeechFile_16b_m_44k
;
632 FAIL() << "This test supports 44.1kHz and 48kHz mono/stereo only.";
636 base::WaitableEvent
event(false, false);
637 FileAudioSource
source(&event
, file_name
);
639 EXPECT_TRUE(aos
->Open());
642 LOG(INFO
) << ">> Verify that the file is played out correctly...";
643 EXPECT_TRUE(event
.TimedWait(TestTimeouts::action_max_timeout()));
648 // Start input streaming and run it for ten seconds while recording to a
650 // NOTE: this test requires user interaction and is not designed to run as an
651 // automatized test on bots.
652 TEST_F(AudioAndroidTest
, DISABLED_RunSimplexInputStreamWithFileAsSink
) {
653 AudioParameters params
= GetDefaultInputStreamParameters();
655 AudioInputStream
* ais
= audio_manager()->MakeAudioInputStream(
656 params
, AudioManagerBase::kDefaultDeviceId
);
659 std::string file_name
= base::StringPrintf("out_simplex_%d_%d_%d.pcm",
660 params
.sample_rate(),
661 params
.frames_per_buffer(),
664 base::WaitableEvent
event(false, false);
665 FileAudioSink
sink(&event
, params
, file_name
);
667 EXPECT_TRUE(ais
->Open());
669 LOG(INFO
) << ">> Speak into the microphone to record audio...";
670 EXPECT_TRUE(event
.TimedWait(TestTimeouts::action_max_timeout()));
675 // Same test as RunSimplexInputStreamWithFileAsSink but this time output
676 // streaming is active as well (reads zeros only).
677 // NOTE: this test requires user interaction and is not designed to run as an
678 // automatized test on bots.
679 TEST_F(AudioAndroidTest
, DISABLED_RunDuplexInputStreamWithFileAsSink
) {
680 AudioParameters in_params
= GetDefaultInputStreamParameters();
681 AudioInputStream
* ais
= audio_manager()->MakeAudioInputStream(
682 in_params
, AudioManagerBase::kDefaultDeviceId
);
685 AudioParameters out_params
=
686 audio_manager()->GetDefaultOutputStreamParameters();
687 AudioOutputStream
* aos
= audio_manager()->MakeAudioOutputStream(
688 out_params
, std::string(), std::string());
691 std::string file_name
= base::StringPrintf("out_duplex_%d_%d_%d.pcm",
692 in_params
.sample_rate(),
693 in_params
.frames_per_buffer(),
694 in_params
.channels());
696 base::WaitableEvent
event(false, false);
697 FileAudioSink
sink(&event
, in_params
, file_name
);
698 MockAudioOutputCallback source
;
700 EXPECT_CALL(source
, OnMoreData(NotNull(), _
)).WillRepeatedly(
701 Invoke(&source
, &MockAudioOutputCallback::RealOnMoreData
));
702 EXPECT_CALL(source
, OnError(aos
)).Times(0);
703 EXPECT_CALL(source
, OnMoreIOData(_
, _
, _
)).Times(0);
705 EXPECT_TRUE(ais
->Open());
706 EXPECT_TRUE(aos
->Open());
709 LOG(INFO
) << ">> Speak into the microphone to record audio";
710 EXPECT_TRUE(event
.TimedWait(TestTimeouts::action_max_timeout()));
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
719 // delay will be added by the FIFO and an estimate of this delay will be
720 // printed out during the test.
721 // NOTE: this test requires user interaction and is not designed to run as an
722 // automatized test on bots.
723 TEST_F(AudioAndroidTest
,
724 DISABLED_RunSymmetricInputAndOutputStreamsInFullDuplex
) {
725 // Get native audio parameters for the input side.
726 AudioParameters default_input_params
= GetDefaultInputStreamParameters();
728 // Modify the parameters so that both input and output can use the same
729 // parameters by selecting 10ms as buffer size. This will also ensure that
730 // the output stream will be a mono stream since mono is default for input
732 AudioParameters
io_params(default_input_params
.format(),
733 default_input_params
.channel_layout(),
734 default_input_params
.sample_rate(),
735 default_input_params
.bits_per_sample(),
736 default_input_params
.sample_rate() / 100);
737 VLOG(1) << io_params
;
739 // Create input and output streams using the common audio parameters.
740 AudioInputStream
* ais
= audio_manager()->MakeAudioInputStream(
741 io_params
, AudioManagerBase::kDefaultDeviceId
);
743 AudioOutputStream
* aos
= audio_manager()->MakeAudioOutputStream(
744 io_params
, std::string(), std::string());
747 FullDuplexAudioSinkSource
full_duplex(io_params
);
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
751 // performed, the result should be reduced by this extra delay since it is
752 // something that has been added by the test.
753 EXPECT_TRUE(ais
->Open());
754 EXPECT_TRUE(aos
->Open());
755 ais
->Start(&full_duplex
);
756 aos
->Start(&full_duplex
);
757 VLOG(1) << "HINT: an estimate of the extra FIFO delay will be updated "
758 << "once per second during this test.";
759 LOG(INFO
) << ">> Speak into the mic and listen to the audio in loopback...";
761 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));