Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(639)

Side by Side Diff: media/audio/android/audio_android_unittest.cc

Issue 23296008: Adding audio unit tests for Android (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: Now uses gmock Created 7 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | media/audio/android/audio_manager_android.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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.
4
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"
24
25 using ::testing::_;
26 using ::testing::AtLeast;
27 using ::testing::DoAll;
28 using ::testing::Invoke;
29 using ::testing::NotNull;
30 using ::testing::Return;
31
32 namespace media {
33
34 ACTION_P3(CheckCountAndPostQuitTask, count, limit, loop) {
35 if (++*count >= limit) {
36 loop->PostTask(FROM_HERE, base::MessageLoop::QuitClosure());
37 }
38 }
39
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";
44
45 static const float kCallbackTestTimeMs = 2000.0;
46 static const int kBitsPerSample = 16;
47 static const int kBytesPerSample = kBitsPerSample / 8;
48
49 // Converts AudioParameters::Format enumerator to readable string.
50 static std::string FormatToString(AudioParameters::Format format) {
51 switch (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");
60 default:
61 return std::string();
62 }
63 }
64
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_UNSUPPORTED:
Jói 2013/09/11 15:42:58 Could move this to just before default and fall th
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
72 return std::string("CHANNEL_LAYOUT_UNSUPPORTED");
73 case CHANNEL_LAYOUT_MONO:
74 return std::string("CHANNEL_LAYOUT_MONO");
75 case CHANNEL_LAYOUT_STEREO:
76 return std::string("CHANNEL_LAYOUT_STEREO");
77 default:
78 return std::string("CHANNEL_LAYOUT_UNSUPPORTED");
79 }
80 }
81
82 static double ExpectedTimeBetweenCallbacks(AudioParameters params) {
83 return (base::TimeDelta::FromMicroseconds(
84 params.frames_per_buffer() * base::Time::kMicrosecondsPerSecond /
85 static_cast<float>(params.sample_rate()))).InMillisecondsF();
Jói 2013/09/11 15:42:58 The function returns double, not float, is that in
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Good point. Fixed.
86 }
87
88 std::ostream& operator<<(std::ostream& os, const AudioParameters& params) {
89 os << std::endl << "format: " << FormatToString(params.format()) << std::endl
Jói 2013/09/11 15:42:58 I guess this is an artifact of git cl format, but
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Added local using namespace std.
90 << "channel layout: " << LayoutToString(params.channel_layout())
91 << std::endl << "sample rate: " << params.sample_rate() << std::endl
92 << "bits per sample: " << params.bits_per_sample() << std::endl
93 << "frames per buffer: " << params.frames_per_buffer() << std::endl
94 << "channels: " << params.channels() << std::endl
95 << "bytes per buffer: " << params.GetBytesPerBuffer() << std::endl
96 << "bytes per second: " << params.GetBytesPerSecond() << std::endl
97 << "bytes per frame: " << params.GetBytesPerFrame() << std::endl
98 << "frame size in ms: " << ExpectedTimeBetweenCallbacks(params);
99 return os;
100 }
101
102 // Gmock implementation of AudioInputStream::AudioInputCallback.
103 class MockAudioInputCallback : public AudioInputStream::AudioInputCallback {
104 public:
105 MOCK_METHOD5(OnData,
106 void(AudioInputStream* stream,
107 const uint8* src,
108 uint32 size,
109 uint32 hardware_delay_bytes,
110 double volume));
111 MOCK_METHOD1(OnClose, void(AudioInputStream* stream));
112 MOCK_METHOD1(OnError, void(AudioInputStream* stream));
113 };
114
115 // Gmock implementation of AudioOutputStream::AudioSourceCallback.
116 class MockAudioOutputCallback : public AudioOutputStream::AudioSourceCallback {
117 public:
118 MOCK_METHOD2(OnMoreData,
119 int(AudioBus* dest, AudioBuffersState buffers_state));
120 MOCK_METHOD3(OnMoreIOData,
121 int(AudioBus* source,
122 AudioBus* dest,
123 AudioBuffersState buffers_state));
124 MOCK_METHOD1(OnError, void(AudioOutputStream* stream));
125
126 // We clear the data bus to ensure that the test does not cause noise.
127 int RealOnMoreData(AudioBus* dest, AudioBuffersState buffers_state) {
128 dest->Zero();
129 return dest->frames();
130 }
131 };
132
133 // Implements AudioOutputStream::AudioSourceCallback and provides audio data
134 // by reading from a data file.
135 class FileAudioSource : public AudioOutputStream::AudioSourceCallback {
136 public:
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
140 // a DecoderBuffer.
141 file_ = ReadTestDataFile(name);
142
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();
146 }
147
148 virtual ~FileAudioSource() {}
149
150 // AudioOutputStream::AudioSourceCallback implementation.
151
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;
157 int max_size =
158 audio_bus->frames() * audio_bus->channels() * kBytesPerSample;
159
160 // Adjust data size and prepare for end signal if file has ended.
161 if (pos_ + max_size > file_size()) {
162 stop_playing = true;
163 max_size = file_size() - pos_;
164 }
165
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);
171 if (max_size) {
172 audio_bus->FromInterleaved(file_->data() + pos_, frames, kBytesPerSample);
173 pos_ += max_size;
174 }
175
176 // Set event to ensure that the test can stop when the file has ended.
177 if (stop_playing)
178 event_->Signal();
179
180 return frames;
181 }
182
183 virtual int OnMoreIOData(AudioBus* source,
184 AudioBus* dest,
185 AudioBuffersState buffers_state) OVERRIDE {
186 NOTREACHED();
187 return 0;
188 }
189
190 virtual void OnError(AudioOutputStream* stream) OVERRIDE {}
191
192 int file_size() { return file_->data_size(); }
193
194 private:
195 base::WaitableEvent* event_;
196 int pos_;
197 scoped_refptr<DecoderBuffer> file_;
198
199 DISALLOW_COPY_AND_ASSIGN(FileAudioSource);
200 };
201
202 // Implements AudioInputStream::AudioInputCallback and writes the recorded
203 // audio data to a local output file.
Jói 2013/09/11 15:42:58 Would put a note here saying this is only used for
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
204 class FileAudioSink : public AudioInputStream::AudioInputCallback {
205 public:
206 explicit FileAudioSink(base::WaitableEvent* event,
207 const AudioParameters& params,
208 const std::string& file_name)
209 : event_(event), params_(params) {
210 // Allocate space for ~10 seconds of data.
211 const int kMaxBufferSize = 10 * params.GetBytesPerSecond();
212 buffer_.reset(new media::SeekableBuffer(0, kMaxBufferSize));
213
214 // Open up the binary file which will be written to in the destructor.
215 base::FilePath file_path;
216 EXPECT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &file_path));
217 file_path = file_path.AppendASCII(file_name.c_str());
218 binary_file_ = file_util::OpenFile(file_path, "wb");
219 DLOG_IF(ERROR, !binary_file_) << "Failed to open binary PCM data file.";
220 LOG(INFO) << "Writing to file: " << file_path.value().c_str();
221 }
222
223 virtual ~FileAudioSink() {
224 int bytes_written = 0;
225 while (bytes_written < buffer_->forward_capacity()) {
226 const uint8* chunk;
227 int chunk_size;
228
229 // Stop writing if no more data is available.
230 if (!buffer_->GetCurrentChunk(&chunk, &chunk_size))
231 break;
232
233 // Write recorded data chunk to the file and prepare for next chunk.
234 // TODO(henrika): use file_util:: instead.
235 fwrite(chunk, 1, chunk_size, binary_file_);
236 buffer_->Seek(chunk_size);
237 bytes_written += chunk_size;
238 }
239 file_util::CloseFile(binary_file_);
240 }
241
242 // AudioInputStream::AudioInputCallback implementation.
243 virtual void OnData(AudioInputStream* stream,
244 const uint8* src,
245 uint32 size,
246 uint32 hardware_delay_bytes,
247 double volume) OVERRIDE {
248 // Store data data in a temporary buffer to avoid making blocking
249 // fwrite() calls in the audio callback. The complete buffer will be
250 // written to file in the destructor.
251 if (!buffer_->Append(src, size))
252 event_->Signal();
253 }
254
255 virtual void OnClose(AudioInputStream* stream) OVERRIDE {}
256 virtual void OnError(AudioInputStream* stream) OVERRIDE {}
257
258 private:
259 base::WaitableEvent* event_;
260 AudioParameters params_;
261 scoped_ptr<media::SeekableBuffer> buffer_;
262 FILE* binary_file_;
263
264 DISALLOW_COPY_AND_ASSIGN(FileAudioSink);
265 };
266
267 // Implements AudioInputCallback and AudioSourceCallback to support full
268 // duplex audio where captured samples are played out in loopback after
269 // reading from a temporary FIFO storage.
270 class FullDuplexAudioSinkSource
271 : public AudioInputStream::AudioInputCallback,
272 public AudioOutputStream::AudioSourceCallback {
273 public:
274 explicit FullDuplexAudioSinkSource(const AudioParameters& params)
275 : params_(params),
276 previous_time_(base::TimeTicks::Now()),
277 started_(false) {
278 // Start with a reasonably small FIFO size. It will be increased
279 // dynamically during the test if required.
280 fifo_.reset(new media::SeekableBuffer(0, 2 * params.GetBytesPerBuffer()));
281 buffer_.reset(new uint8[params_.GetBytesPerBuffer()]);
282 }
283
284 virtual ~FullDuplexAudioSinkSource() {}
285
286 // AudioInputStream::AudioInputCallback implementation
287 virtual void OnData(AudioInputStream* stream,
288 const uint8* src,
289 uint32 size,
290 uint32 hardware_delay_bytes,
291 double volume) OVERRIDE {
292 const base::TimeTicks now_time = base::TimeTicks::Now();
293 const int diff = (now_time - previous_time_).InMilliseconds();
294
295 base::AutoLock lock(lock_);
296 if (diff > 1000) {
297 started_ = true;
298 previous_time_ = now_time;
299
300 // Log out the extra delay added by the FIFO. This is a best effort
301 // estimate. We might be +- 10ms off here.
302 int extra_fio_delay =
303 static_cast<int>(BytesToMilliseconds(fifo_->forward_bytes() + size));
304 DVLOG(1) << extra_fio_delay;
Jói 2013/09/11 15:42:58 extra_fio_delay -> extra_fifo_delay
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
305 }
306
307 // We add an initial delay of ~1 second before loopback starts to ensure
308 // a stable callback sequence and to avoid initial bursts which might add
309 // to the extra FIFO delay.
310 if (!started_)
311 return;
312
313 // Append new data to the FIFO and extend the size if the mac capacity
Jói 2013/09/11 15:42:58 mac -> max
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
314 // was exceeded. Flush the FIFO if is extended just in case.
315 if (!fifo_->Append(src, size)) {
316 fifo_->set_forward_capacity(2 * fifo_->forward_capacity());
317 fifo_->Clear();
318 }
319 }
320
321 virtual void OnClose(AudioInputStream* stream) OVERRIDE {}
322 virtual void OnError(AudioInputStream* stream) OVERRIDE {}
323
324 // AudioOutputStream::AudioSourceCallback implementation
325 virtual int OnMoreData(AudioBus* dest,
326 AudioBuffersState buffers_state) OVERRIDE {
327 const int size_in_bytes =
328 (params_.bits_per_sample() / 8) * dest->frames() * dest->channels();
329 EXPECT_EQ(size_in_bytes, params_.GetBytesPerBuffer());
330
331 base::AutoLock lock(lock_);
332
333 // We add an initial delay of ~1 second before loopback starts to ensure
334 // a stable callback sequences and to avoid initial bursts which might add
335 // to the extra FIFO delay.
336 if (!started_) {
337 dest->Zero();
338 return dest->frames();
339 }
340
341 // Fill up destination with zeros if the FIFO does not contain enough
342 // data to fulfill the request.
343 if (fifo_->forward_bytes() < size_in_bytes) {
344 dest->Zero();
345 } else {
346 fifo_->Read(buffer_.get(), size_in_bytes);
347 dest->FromInterleaved(
348 buffer_.get(), dest->frames(), params_.bits_per_sample() / 8);
349 }
350
351 return dest->frames();
352 }
353
354 virtual int OnMoreIOData(AudioBus* source,
355 AudioBus* dest,
356 AudioBuffersState buffers_state) OVERRIDE {
357 NOTREACHED();
358 return 0;
359 }
360
361 virtual void OnError(AudioOutputStream* stream) OVERRIDE {}
362
363 private:
364 // Converts from bytes to milliseconds given number of bytes and existing
365 // audio parameters.
366 double BytesToMilliseconds(int bytes) const {
367 const int frames = bytes / params_.GetBytesPerFrame();
368 return (base::TimeDelta::FromMicroseconds(
369 frames * base::Time::kMicrosecondsPerSecond /
370 static_cast<float>(params_.sample_rate()))).InMillisecondsF();
Jói 2013/09/11 15:42:58 Again float vs. double, is it intentional?
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
371 }
372
373 AudioParameters params_;
374 base::TimeTicks previous_time_;
375 base::Lock lock_;
376 scoped_ptr<media::SeekableBuffer> fifo_;
377 scoped_ptr<uint8[]> buffer_;
378 bool started_;
379
380 DISALLOW_COPY_AND_ASSIGN(FullDuplexAudioSinkSource);
381 };
382
383 // Test fixture class.
384 class AudioAndroidTest : public testing::Test {
385 public:
386 AudioAndroidTest() {}
387
388 protected:
389 virtual void SetUp() {
390 audio_manager_.reset(AudioManager::Create());
391 loop_.reset(new base::MessageLoopForUI());
392 }
393
394 virtual void TearDown() {}
395
396 AudioManager* audio_manager() { return audio_manager_.get(); }
397 base::MessageLoopForUI* loop() { return loop_.get(); }
398
399 AudioParameters GetDefaultInputStreamParameters() {
400 return audio_manager()->GetInputStreamParameters(
401 AudioManagerBase::kDefaultDeviceId);
402 }
403
404 AudioParameters GetDefaultOutputStreamParameters() {
405 return audio_manager()->GetDefaultOutputStreamParameters();
406 }
407
408 double AverageTimeBetweenCallbacks(int num_callbacks) const {
409 return ((end_time_ - start_time_) / (num_callbacks - 1)).InMillisecondsF();
Jói 2013/09/11 15:42:58 Looks like the calculation occurs in integer land,
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Thanks. Please note that InMillisecondsF() does re
410 }
411
412 void StartInputStreamCallbacks(const AudioParameters& params) {
413 double expected_time_between_callbacks_ms =
414 ExpectedTimeBetweenCallbacks(params);
415 const int num_callbacks =
416 (kCallbackTestTimeMs / expected_time_between_callbacks_ms);
417 AudioInputStream* stream = audio_manager()->MakeAudioInputStream(
418 params, AudioManagerBase::kDefaultDeviceId);
419 EXPECT_TRUE(stream);
420
421 int count = 0;
422 MockAudioInputCallback sink;
423
424 EXPECT_CALL(sink,
425 OnData(stream, NotNull(), params.GetBytesPerBuffer(), _, _))
426 .Times(AtLeast(num_callbacks))
427 .WillRepeatedly(
428 CheckCountAndPostQuitTask(&count, num_callbacks, loop()));
429 EXPECT_CALL(sink, OnError(stream)).Times(0);
430 EXPECT_CALL(sink, OnClose(stream)).Times(1);
431
432 EXPECT_TRUE(stream->Open());
433 stream->Start(&sink);
434 start_time_ = base::TimeTicks::Now();
435 loop()->Run();
436 end_time_ = base::TimeTicks::Now();
437 stream->Stop();
438 stream->Close();
439
440 double average_time_between_callbacks_ms =
441 AverageTimeBetweenCallbacks(num_callbacks);
442 LOG(INFO) << "expected time between callbacks: "
443 << expected_time_between_callbacks_ms << " ms";
444 LOG(INFO) << "average time between callbacks: "
445 << average_time_between_callbacks_ms << " ms";
446 EXPECT_GE(average_time_between_callbacks_ms,
447 0.70 * expected_time_between_callbacks_ms);
448 EXPECT_LE(average_time_between_callbacks_ms,
449 1.30 * expected_time_between_callbacks_ms);
450 }
451
452 void StartOutputStreamCallbacks(const AudioParameters& params) {
453 double expected_time_between_callbacks_ms =
454 ExpectedTimeBetweenCallbacks(params);
455 const int num_callbacks =
456 (kCallbackTestTimeMs / expected_time_between_callbacks_ms);
457 AudioOutputStream* stream = audio_manager()->MakeAudioOutputStream(
458 params, std::string(), std::string());
459 EXPECT_TRUE(stream);
460
461 int count = 0;
462 MockAudioOutputCallback source;
463
464 EXPECT_CALL(source, OnMoreData(NotNull(), _))
465 .Times(AtLeast(num_callbacks))
466 .WillRepeatedly(
467 DoAll(CheckCountAndPostQuitTask(&count, num_callbacks, loop()),
468 Invoke(&source, &MockAudioOutputCallback::RealOnMoreData)));
469 EXPECT_CALL(source, OnError(stream)).Times(0);
470 EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
471
472 EXPECT_TRUE(stream->Open());
473 stream->Start(&source);
474 start_time_ = base::TimeTicks::Now();
475 loop()->Run();
476 end_time_ = base::TimeTicks::Now();
477 stream->Stop();
478 stream->Close();
479
480 double average_time_between_callbacks_ms =
481 AverageTimeBetweenCallbacks(num_callbacks);
482 LOG(INFO) << "expected time between callbacks: "
483 << expected_time_between_callbacks_ms << " ms";
484 LOG(INFO) << "average time between callbacks: "
485 << average_time_between_callbacks_ms << " ms";
486 EXPECT_GE(average_time_between_callbacks_ms,
487 0.70 * expected_time_between_callbacks_ms);
488 EXPECT_LE(average_time_between_callbacks_ms,
489 1.30 * expected_time_between_callbacks_ms);
490 }
491
492 scoped_ptr<base::MessageLoopForUI> loop_;
493 scoped_ptr<AudioManager> audio_manager_;
494 base::TimeTicks start_time_;
495 base::TimeTicks end_time_;
496
497 DISALLOW_COPY_AND_ASSIGN(AudioAndroidTest);
498 };
499
500 // Get the default audio input parameters and log the result.
501 TEST_F(AudioAndroidTest, GetInputStreamParameters) {
502 AudioParameters params = GetDefaultInputStreamParameters();
503 EXPECT_TRUE(params.IsValid());
504 LOG(INFO) << params;
Jói 2013/09/11 15:42:58 For all of the tests that are enabled to run witho
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
505 }
506
507 // Get the default audio output parameters and log the result.
508 TEST_F(AudioAndroidTest, GetDefaultOutputStreamParameters) {
509 AudioParameters params = GetDefaultOutputStreamParameters();
510 EXPECT_TRUE(params.IsValid());
511 LOG(INFO) << params;
512 }
513
514 // Check if low-latency output is supported and log the result as output.
515 TEST_F(AudioAndroidTest, IsAudioLowLatencySupported) {
516 AudioManagerAndroid* manager =
517 static_cast<AudioManagerAndroid*>(audio_manager());
518 bool low_latency = manager->IsAudioLowLatencySupported();
519 low_latency ? LOG(INFO) << "Low latency output is supported"
520 : LOG(INFO) << "Low latency output is *not* supported";
521 }
522
523 // Ensure that a default input stream can be created and closed.
524 TEST_F(AudioAndroidTest, CreateAndCloseInputStream) {
525 AudioParameters params = GetDefaultInputStreamParameters();
526 AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
527 params, AudioManagerBase::kDefaultDeviceId);
528 EXPECT_TRUE(ais);
529 ais->Close();
530 }
531
532 // Ensure that a default output stream can be created and closed.
533 // TODO(henrika): should we also verify that this API changes the audio mode
534 // to communication mode, and calls RegisterHeadsetReceiver, the first time
535 // it is called?
536 TEST_F(AudioAndroidTest, CreateAndCloseOutputStream) {
537 AudioParameters params = GetDefaultOutputStreamParameters();
538 AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
539 params, std::string(), std::string());
540 EXPECT_TRUE(aos);
541 aos->Close();
542 }
543
544 // Ensure that a default input stream can be opened and closed.
545 TEST_F(AudioAndroidTest, OpenAndCloseInputStream) {
546 AudioParameters params = GetDefaultInputStreamParameters();
547 AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
548 params, AudioManagerBase::kDefaultDeviceId);
549 EXPECT_TRUE(ais);
550 EXPECT_TRUE(ais->Open());
551 ais->Close();
552 }
553
554 // Ensure that a default output stream can be opened and closed.
555 TEST_F(AudioAndroidTest, OpenAndCloseOutputStream) {
556 AudioParameters params = GetDefaultOutputStreamParameters();
557 AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
558 params, std::string(), std::string());
559 EXPECT_TRUE(aos);
560 EXPECT_TRUE(aos->Open());
561 aos->Close();
562 }
563
564 // Start input streaming using default input parameters and ensure that the
565 // callback sequence is sane.
566 TEST_F(AudioAndroidTest, StartInputStreamCallbacks) {
567 AudioParameters params = GetDefaultInputStreamParameters();
568 StartInputStreamCallbacks(params);
569 }
570
571 // Start input streaming using non default input parameters and ensure that the
572 // callback sequence is sane. The only change we make in this test is to select
573 // a 10ms buffer size instead of the default size.
574 // TODO(henrika): possibly add support for more variations.
575 TEST_F(AudioAndroidTest, StartInputStreamCallbacksNonDefaultParameters) {
576 AudioParameters native_params = GetDefaultInputStreamParameters();
577 AudioParameters params(native_params.format(),
578 native_params.channel_layout(),
579 native_params.sample_rate(),
580 native_params.bits_per_sample(),
581 native_params.sample_rate() / 100);
582 StartInputStreamCallbacks(params);
583 }
584
585 // Start output streaming using default output parameters and ensure that the
586 // callback sequence is sane.
587 TEST_F(AudioAndroidTest, StartOutputStreamCallbacks) {
588 AudioParameters params = GetDefaultOutputStreamParameters();
589 StartOutputStreamCallbacks(params);
590 }
591
592 // Start output streaming using non default output parameters and ensure that
593 // the callback sequence is sane. The only changed we make in this test is to
Jói 2013/09/11 15:42:58 changed -> change
henrika (OOO until Aug 14) 2013/09/12 09:47:05 Done.
594 // select a 10ms buffer size instead of the default size and to open up the
595 // device in mono.
596 // TODO(henrika): possibly add support for more variations.
597 TEST_F(AudioAndroidTest, StartOutputStreamCallbacksNonDefaultParameters) {
598 AudioParameters native_params = GetDefaultOutputStreamParameters();
599 AudioParameters params(native_params.format(),
600 CHANNEL_LAYOUT_MONO,
601 native_params.sample_rate(),
602 native_params.bits_per_sample(),
603 native_params.sample_rate() / 100);
604 StartOutputStreamCallbacks(params);
605 }
606
607 // Play out a PCM file segment in real time and allow the user to verify that
608 // the rendered audio sounds OK.
609 // NOTE: this test requires user interaction and is not designed to run as an
610 // automatized test on bots.
611 TEST_F(AudioAndroidTest, DISABLED_RunOutputStreamWithFileAsSource) {
612 AudioParameters params = GetDefaultOutputStreamParameters();
613 LOG(INFO) << params;
614 AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
615 params, std::string(), std::string());
616 EXPECT_TRUE(aos);
617
618 std::string file_name;
619 if (params.sample_rate() == 48000 && params.channels() == 2) {
620 file_name = kSpeechFile_16b_s_48k;
621 } else if (params.sample_rate() == 48000 && params.channels() == 1) {
622 file_name = kSpeechFile_16b_m_48k;
623 } else if (params.sample_rate() == 44100 && params.channels() == 2) {
624 file_name = kSpeechFile_16b_s_44k;
625 } else if (params.sample_rate() == 44100 && params.channels() == 1) {
626 file_name = kSpeechFile_16b_m_44k;
627 } else {
628 FAIL() << "This test supports 44.1kHz and 48kHz mono/stereo only.";
629 return;
630 }
631
632 base::WaitableEvent event(false, false);
633 FileAudioSource source(&event, file_name);
634
635 EXPECT_TRUE(aos->Open());
636 aos->SetVolume(1.0);
637 aos->Start(&source);
638 LOG(INFO) << ">> Verify that the file is played out correctly...";
639 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
640 aos->Stop();
641 aos->Close();
642 }
643
644 // Start input streaming and run it for ten seconds while recording to a
645 // local audio file.
646 // NOTE: this test requires user interaction and is not designed to run as an
647 // automatized test on bots.
648 TEST_F(AudioAndroidTest, DISABLED_RunSimplexInputStreamWithFileAsSink) {
649 AudioParameters params = GetDefaultInputStreamParameters();
650 LOG(INFO) << params;
651 AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
652 params, AudioManagerBase::kDefaultDeviceId);
653 EXPECT_TRUE(ais);
654
655 std::string file_name = base::StringPrintf("out_simplex_%d_%d_%d.pcm",
656 params.sample_rate(),
657 params.frames_per_buffer(),
658 params.channels());
659
660 base::WaitableEvent event(false, false);
661 FileAudioSink sink(&event, params, file_name);
662
663 EXPECT_TRUE(ais->Open());
664 ais->Start(&sink);
665 DLOG(INFO) << ">> Speak into the microphone to record audio...";
666 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
667 ais->Stop();
668 ais->Close();
669 }
670
671 // Same test as RunSimplexInputStreamWithFileAsSink but this time output
672 // streaming is active as well (reads zeros only).
673 // NOTE: this test requires user interaction and is not designed to run as an
674 // automatized test on bots.
675 TEST_F(AudioAndroidTest, DISABLED_RunDuplexInputStreamWithFileAsSink) {
676 AudioParameters in_params = GetDefaultInputStreamParameters();
677 AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
678 in_params, AudioManagerBase::kDefaultDeviceId);
679 EXPECT_TRUE(ais);
680
681 AudioParameters out_params =
682 audio_manager()->GetDefaultOutputStreamParameters();
683 AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
684 out_params, std::string(), std::string());
685 EXPECT_TRUE(aos);
686
687 std::string file_name = base::StringPrintf("out_duplex_%d_%d_%d.pcm",
688 in_params.sample_rate(),
689 in_params.frames_per_buffer(),
690 in_params.channels());
691
692 base::WaitableEvent event(false, false);
693 FileAudioSink sink(&event, in_params, file_name);
694 MockAudioOutputCallback source;
695
696 EXPECT_CALL(source, OnMoreData(NotNull(), _)).WillRepeatedly(
697 Invoke(&source, &MockAudioOutputCallback::RealOnMoreData));
698 EXPECT_CALL(source, OnError(aos)).Times(0);
699 EXPECT_CALL(source, OnMoreIOData(_, _, _)).Times(0);
700
701 EXPECT_TRUE(ais->Open());
702 EXPECT_TRUE(aos->Open());
703 ais->Start(&sink);
704 aos->Start(&source);
705 LOG(INFO) << ">> Speak into the microphone to record audio";
706 EXPECT_TRUE(event.TimedWait(TestTimeouts::action_max_timeout()));
707 aos->Stop();
708 ais->Stop();
709 aos->Close();
710 ais->Close();
711 }
712
713 // Start audio in both directions while feeding captured data into a FIFO so
714 // it can be read directly (in loopback) by the render side. A small extra
715 // delay will be added by the FIFO and an estimate of this delay will be
716 // printed out during the test.
717 // NOTE: this test requires user interaction and is not designed to run as an
718 // automatized test on bots.
719 TEST_F(AudioAndroidTest,
720 DISABLED_RunSymmetricInputAndOutputStreamsInFullDuplex) {
721 // Get native audio parameters for the input side.
722 AudioParameters default_input_params = GetDefaultInputStreamParameters();
723
724 // Modify the parameters so that both input and output can use the same
725 // parameters by selecting 10ms as buffer size. This will also ensure that
726 // the output stream will be a mono stream since mono is default for input
727 // audio on Android.
728 AudioParameters io_params(default_input_params.format(),
729 default_input_params.channel_layout(),
730 default_input_params.sample_rate(),
731 default_input_params.bits_per_sample(),
732 default_input_params.sample_rate() / 100);
733 LOG(INFO) << io_params;
734
735 // Create input and output streams using the common audio parameters.
736 AudioInputStream* ais = audio_manager()->MakeAudioInputStream(
737 io_params, AudioManagerBase::kDefaultDeviceId);
738 EXPECT_TRUE(ais);
739 AudioOutputStream* aos = audio_manager()->MakeAudioOutputStream(
740 io_params, std::string(), std::string());
741 EXPECT_TRUE(aos);
742
743 FullDuplexAudioSinkSource full_duplex(io_params);
744
745 // Start a full duplex audio session and print out estimates of the extra
746 // delay we should expect from the FIFO. If real-time delay measurements are
747 // performed, the result should be reduced by this extra delay since it is
748 // something that has been added by the test.
749 EXPECT_TRUE(ais->Open());
750 EXPECT_TRUE(aos->Open());
751 ais->Start(&full_duplex);
752 aos->Start(&full_duplex);
753 DVLOG(1) << "HINT: an estimate of the extra FIFO delay will be updated "
754 << "once per second during this test.";
755 LOG(INFO) << ">> Speak into the mic and listen to the audio in loopback...";
756 fflush(stdout);
757 base::PlatformThread::Sleep(base::TimeDelta::FromSeconds(20));
758 printf("\n");
759 aos->Stop();
760 ais->Stop();
761 aos->Close();
762 ais->Close();
763 }
764
765 } // namespace media
OLDNEW
« no previous file with comments | « no previous file | media/audio/android/audio_manager_android.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698