OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 <windows.h> | 5 #include <windows.h> |
6 #include <mmsystem.h> | 6 #include <mmsystem.h> |
7 | 7 |
8 #include "base/basictypes.h" | 8 #include "base/basictypes.h" |
9 #include "base/environment.h" | 9 #include "base/environment.h" |
10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
(...skipping 145 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
156 // TODO(henrika): note that we use Wave today to query the number of | 156 // TODO(henrika): note that we use Wave today to query the number of |
157 // existing input devices. | 157 // existing input devices. |
158 return CoreAudioUtil::IsSupported() && audio_man->HasAudioInputDevices(); | 158 return CoreAudioUtil::IsSupported() && audio_man->HasAudioInputDevices(); |
159 } | 159 } |
160 | 160 |
161 // Convenience method which creates a default AudioInputStream object but | 161 // Convenience method which creates a default AudioInputStream object but |
162 // also allows the user to modify the default settings. | 162 // also allows the user to modify the default settings. |
163 class AudioInputStreamWrapper { | 163 class AudioInputStreamWrapper { |
164 public: | 164 public: |
165 explicit AudioInputStreamWrapper(AudioManager* audio_manager) | 165 explicit AudioInputStreamWrapper(AudioManager* audio_manager) |
166 : audio_man_(audio_manager), | 166 : com_init_(ScopedCOMInitializer::kMTA), |
167 default_params_(audio_man_->GetInputStreamParameters( | 167 audio_man_(audio_manager), |
168 AudioManagerBase::kDefaultDeviceId)) { | 168 default_params_( |
| 169 audio_manager->GetInputStreamParameters( |
| 170 AudioManagerBase::kDefaultDeviceId)) { |
169 EXPECT_EQ(format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); | 171 EXPECT_EQ(format(), AudioParameters::AUDIO_PCM_LOW_LATENCY); |
170 frames_per_buffer_ = default_params_.frames_per_buffer(); | 172 frames_per_buffer_ = default_params_.frames_per_buffer(); |
171 // We expect the default buffer size to be a 10ms buffer. | 173 // We expect the default buffer size to be a 10ms buffer. |
172 EXPECT_EQ(frames_per_buffer_, sample_rate() / 100); | 174 EXPECT_EQ(frames_per_buffer_, sample_rate() / 100); |
173 } | 175 } |
174 | 176 |
175 ~AudioInputStreamWrapper() {} | 177 ~AudioInputStreamWrapper() {} |
176 | 178 |
177 // Creates AudioInputStream object using default parameters. | 179 // Creates AudioInputStream object using default parameters. |
178 AudioInputStream* Create() { | 180 AudioInputStream* Create() { |
(...skipping 19 matching lines...) Expand all Loading... |
198 AudioInputStream* CreateInputStream() { | 200 AudioInputStream* CreateInputStream() { |
199 AudioInputStream* ais = audio_man_->MakeAudioInputStream( | 201 AudioInputStream* ais = audio_man_->MakeAudioInputStream( |
200 AudioParameters(format(), default_params_.channel_layout(), | 202 AudioParameters(format(), default_params_.channel_layout(), |
201 sample_rate(), bits_per_sample(), frames_per_buffer_, | 203 sample_rate(), bits_per_sample(), frames_per_buffer_, |
202 default_params_.effects()), | 204 default_params_.effects()), |
203 AudioManagerBase::kDefaultDeviceId); | 205 AudioManagerBase::kDefaultDeviceId); |
204 EXPECT_TRUE(ais); | 206 EXPECT_TRUE(ais); |
205 return ais; | 207 return ais; |
206 } | 208 } |
207 | 209 |
| 210 ScopedCOMInitializer com_init_; |
208 AudioManager* audio_man_; | 211 AudioManager* audio_man_; |
209 const AudioParameters default_params_; | 212 const AudioParameters default_params_; |
210 int frames_per_buffer_; | 213 int frames_per_buffer_; |
211 }; | 214 }; |
212 | 215 |
213 // Convenience method which creates a default AudioInputStream object. | 216 // Convenience method which creates a default AudioInputStream object. |
214 static AudioInputStream* CreateDefaultAudioInputStream( | 217 static AudioInputStream* CreateDefaultAudioInputStream( |
215 AudioManager* audio_manager) { | 218 AudioManager* audio_manager) { |
216 AudioInputStreamWrapper aisw(audio_manager); | 219 AudioInputStreamWrapper aisw(audio_manager); |
217 AudioInputStream* ais = aisw.Create(); | 220 AudioInputStream* ais = aisw.Create(); |
(...skipping 26 matching lines...) Expand all Loading... |
244 Close(); | 247 Close(); |
245 stream_ = new_stream; | 248 stream_ = new_stream; |
246 } | 249 } |
247 | 250 |
248 private: | 251 private: |
249 AudioInputStream* stream_; | 252 AudioInputStream* stream_; |
250 | 253 |
251 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); | 254 DISALLOW_COPY_AND_ASSIGN(ScopedAudioInputStream); |
252 }; | 255 }; |
253 | 256 |
254 class WinAudioInputTest : public testing::Test { | |
255 public: | |
256 WinAudioInputTest() : audio_manager_(AudioManager::CreateForTesting()) {} | |
257 ~WinAudioInputTest() override {} | |
258 | |
259 protected: | |
260 ScopedCOMInitializer com_init_; | |
261 scoped_ptr<AudioManager> audio_manager_; | |
262 }; | |
263 | |
264 // Verify that we can retrieve the current hardware/mixing sample rate | 257 // Verify that we can retrieve the current hardware/mixing sample rate |
265 // for all available input devices. | 258 // for all available input devices. |
266 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { | 259 TEST(WinAudioInputTest, WASAPIAudioInputStreamHardwareSampleRate) { |
267 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 260 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 261 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
| 262 |
| 263 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); |
268 | 264 |
269 // Retrieve a list of all available input devices. | 265 // Retrieve a list of all available input devices. |
270 media::AudioDeviceNames device_names; | 266 media::AudioDeviceNames device_names; |
271 audio_manager_->GetAudioInputDeviceNames(&device_names); | 267 audio_manager->GetAudioInputDeviceNames(&device_names); |
272 | 268 |
273 // Scan all available input devices and repeat the same test for all of them. | 269 // Scan all available input devices and repeat the same test for all of them. |
274 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); | 270 for (media::AudioDeviceNames::const_iterator it = device_names.begin(); |
275 it != device_names.end(); ++it) { | 271 it != device_names.end(); ++it) { |
276 // Retrieve the hardware sample rate given a specified audio input device. | 272 // Retrieve the hardware sample rate given a specified audio input device. |
277 AudioParameters params = WASAPIAudioInputStream::GetInputStreamParameters( | 273 AudioParameters params = WASAPIAudioInputStream::GetInputStreamParameters( |
278 it->unique_id); | 274 it->unique_id); |
279 EXPECT_GE(params.sample_rate(), 0); | 275 EXPECT_GE(params.sample_rate(), 0); |
280 } | 276 } |
281 } | 277 } |
282 | 278 |
283 // Test Create(), Close() calling sequence. | 279 // Test Create(), Close() calling sequence. |
284 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { | 280 TEST(WinAudioInputTest, WASAPIAudioInputStreamCreateAndClose) { |
285 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 281 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 282 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
286 ScopedAudioInputStream ais( | 283 ScopedAudioInputStream ais( |
287 CreateDefaultAudioInputStream(audio_manager_.get())); | 284 CreateDefaultAudioInputStream(audio_manager.get())); |
288 ais.Close(); | 285 ais.Close(); |
289 } | 286 } |
290 | 287 |
291 // Test Open(), Close() calling sequence. | 288 // Test Open(), Close() calling sequence. |
292 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { | 289 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenAndClose) { |
293 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 290 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 291 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
294 ScopedAudioInputStream ais( | 292 ScopedAudioInputStream ais( |
295 CreateDefaultAudioInputStream(audio_manager_.get())); | 293 CreateDefaultAudioInputStream(audio_manager.get())); |
296 EXPECT_TRUE(ais->Open()); | 294 EXPECT_TRUE(ais->Open()); |
297 ais.Close(); | 295 ais.Close(); |
298 } | 296 } |
299 | 297 |
300 // Test Open(), Start(), Close() calling sequence. | 298 // Test Open(), Start(), Close() calling sequence. |
301 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { | 299 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartAndClose) { |
302 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 300 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 301 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
303 ScopedAudioInputStream ais( | 302 ScopedAudioInputStream ais( |
304 CreateDefaultAudioInputStream(audio_manager_.get())); | 303 CreateDefaultAudioInputStream(audio_manager.get())); |
305 EXPECT_TRUE(ais->Open()); | 304 EXPECT_TRUE(ais->Open()); |
306 MockAudioInputCallback sink; | 305 MockAudioInputCallback sink; |
307 ais->Start(&sink); | 306 ais->Start(&sink); |
308 ais.Close(); | 307 ais.Close(); |
309 } | 308 } |
310 | 309 |
311 // Test Open(), Start(), Stop(), Close() calling sequence. | 310 // Test Open(), Start(), Stop(), Close() calling sequence. |
312 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { | 311 TEST(WinAudioInputTest, WASAPIAudioInputStreamOpenStartStopAndClose) { |
313 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 312 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 313 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
314 ScopedAudioInputStream ais( | 314 ScopedAudioInputStream ais( |
315 CreateDefaultAudioInputStream(audio_manager_.get())); | 315 CreateDefaultAudioInputStream(audio_manager.get())); |
316 EXPECT_TRUE(ais->Open()); | 316 EXPECT_TRUE(ais->Open()); |
317 MockAudioInputCallback sink; | 317 MockAudioInputCallback sink; |
318 ais->Start(&sink); | 318 ais->Start(&sink); |
319 ais->Stop(); | 319 ais->Stop(); |
320 ais.Close(); | 320 ais.Close(); |
321 } | 321 } |
322 | 322 |
323 // Test some additional calling sequences. | 323 // Test some additional calling sequences. |
324 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { | 324 TEST(WinAudioInputTest, WASAPIAudioInputStreamMiscCallingSequences) { |
325 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 325 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 326 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
326 ScopedAudioInputStream ais( | 327 ScopedAudioInputStream ais( |
327 CreateDefaultAudioInputStream(audio_manager_.get())); | 328 CreateDefaultAudioInputStream(audio_manager.get())); |
328 WASAPIAudioInputStream* wais = | 329 WASAPIAudioInputStream* wais = |
329 static_cast<WASAPIAudioInputStream*>(ais.get()); | 330 static_cast<WASAPIAudioInputStream*>(ais.get()); |
330 | 331 |
331 // Open(), Open() should fail the second time. | 332 // Open(), Open() should fail the second time. |
332 EXPECT_TRUE(ais->Open()); | 333 EXPECT_TRUE(ais->Open()); |
333 EXPECT_FALSE(ais->Open()); | 334 EXPECT_FALSE(ais->Open()); |
334 | 335 |
335 MockAudioInputCallback sink; | 336 MockAudioInputCallback sink; |
336 | 337 |
337 // Start(), Start() is a valid calling sequence (second call does nothing). | 338 // Start(), Start() is a valid calling sequence (second call does nothing). |
338 ais->Start(&sink); | 339 ais->Start(&sink); |
339 EXPECT_TRUE(wais->started()); | 340 EXPECT_TRUE(wais->started()); |
340 ais->Start(&sink); | 341 ais->Start(&sink); |
341 EXPECT_TRUE(wais->started()); | 342 EXPECT_TRUE(wais->started()); |
342 | 343 |
343 // Stop(), Stop() is a valid calling sequence (second call does nothing). | 344 // Stop(), Stop() is a valid calling sequence (second call does nothing). |
344 ais->Stop(); | 345 ais->Stop(); |
345 EXPECT_FALSE(wais->started()); | 346 EXPECT_FALSE(wais->started()); |
346 ais->Stop(); | 347 ais->Stop(); |
347 EXPECT_FALSE(wais->started()); | 348 EXPECT_FALSE(wais->started()); |
348 ais.Close(); | 349 ais.Close(); |
349 } | 350 } |
350 | 351 |
351 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { | 352 TEST(WinAudioInputTest, WASAPIAudioInputStreamTestPacketSizes) { |
352 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 353 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 354 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
353 | 355 |
354 int count = 0; | 356 int count = 0; |
355 base::MessageLoopForUI loop; | 357 base::MessageLoopForUI loop; |
356 | 358 |
357 // 10 ms packet size. | 359 // 10 ms packet size. |
358 | 360 |
359 // Create default WASAPI input stream which records in stereo using | 361 // Create default WASAPI input stream which records in stereo using |
360 // the shared mixing rate. The default buffer size is 10ms. | 362 // the shared mixing rate. The default buffer size is 10ms. |
361 AudioInputStreamWrapper aisw(audio_manager_.get()); | 363 AudioInputStreamWrapper aisw(audio_manager.get()); |
362 ScopedAudioInputStream ais(aisw.Create()); | 364 ScopedAudioInputStream ais(aisw.Create()); |
363 EXPECT_TRUE(ais->Open()); | 365 EXPECT_TRUE(ais->Open()); |
364 | 366 |
365 MockAudioInputCallback sink; | 367 MockAudioInputCallback sink; |
366 | 368 |
367 // Derive the expected size in bytes of each recorded packet. | 369 // Derive the expected size in bytes of each recorded packet. |
368 uint32 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * | 370 uint32 bytes_per_packet = aisw.channels() * aisw.frames_per_buffer() * |
369 (aisw.bits_per_sample() / 8); | 371 (aisw.bits_per_sample() / 8); |
370 | 372 |
371 // We use 10ms packets and will run the test until ten packets are received. | 373 // We use 10ms packets and will run the test until ten packets are received. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
410 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), Gt(bytes_per_packet), _)) | 412 EXPECT_CALL(sink, OnData(ais.get(), NotNull(), Gt(bytes_per_packet), _)) |
411 .Times(AtLeast(10)) | 413 .Times(AtLeast(10)) |
412 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); | 414 .WillRepeatedly(CheckCountAndPostQuitTask(&count, 10, &loop)); |
413 ais->Start(&sink); | 415 ais->Start(&sink); |
414 loop.Run(); | 416 loop.Run(); |
415 ais->Stop(); | 417 ais->Stop(); |
416 ais.Close(); | 418 ais.Close(); |
417 } | 419 } |
418 | 420 |
419 // Test that we can capture a stream in loopback. | 421 // Test that we can capture a stream in loopback. |
420 TEST_F(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { | 422 TEST(WinAudioInputTest, WASAPIAudioInputStreamLoopback) { |
421 ABORT_AUDIO_TEST_IF_NOT(audio_manager_->HasAudioOutputDevices() && | 423 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 424 ABORT_AUDIO_TEST_IF_NOT(audio_manager->HasAudioOutputDevices() && |
422 CoreAudioUtil::IsSupported()); | 425 CoreAudioUtil::IsSupported()); |
423 | 426 |
424 AudioParameters params = audio_manager_->GetInputStreamParameters( | 427 AudioParameters params = audio_manager->GetInputStreamParameters( |
425 AudioManagerBase::kLoopbackInputDeviceId); | 428 AudioManagerBase::kLoopbackInputDeviceId); |
426 EXPECT_EQ(params.effects(), 0); | 429 EXPECT_EQ(params.effects(), 0); |
427 | 430 |
428 AudioParameters output_params = | 431 AudioParameters output_params = |
429 audio_manager_->GetOutputStreamParameters(std::string()); | 432 audio_manager->GetOutputStreamParameters(std::string()); |
430 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); | 433 EXPECT_EQ(params.sample_rate(), output_params.sample_rate()); |
431 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); | 434 EXPECT_EQ(params.channel_layout(), output_params.channel_layout()); |
432 | 435 |
433 ScopedAudioInputStream stream(audio_manager_->MakeAudioInputStream( | 436 ScopedAudioInputStream stream(audio_manager->MakeAudioInputStream( |
434 params, AudioManagerBase::kLoopbackInputDeviceId)); | 437 params, AudioManagerBase::kLoopbackInputDeviceId)); |
435 ASSERT_TRUE(stream->Open()); | 438 ASSERT_TRUE(stream->Open()); |
436 FakeAudioInputCallback sink; | 439 FakeAudioInputCallback sink; |
437 stream->Start(&sink); | 440 stream->Start(&sink); |
438 ASSERT_FALSE(sink.error()); | 441 ASSERT_FALSE(sink.error()); |
439 | 442 |
440 sink.WaitForData(); | 443 sink.WaitForData(); |
441 stream.Close(); | 444 stream.Close(); |
442 | 445 |
443 EXPECT_GT(sink.num_received_audio_frames(), 0); | 446 EXPECT_GT(sink.num_received_audio_frames(), 0); |
444 EXPECT_FALSE(sink.error()); | 447 EXPECT_FALSE(sink.error()); |
445 } | 448 } |
446 | 449 |
447 // This test is intended for manual tests and should only be enabled | 450 // This test is intended for manual tests and should only be enabled |
448 // when it is required to store the captured data on a local file. | 451 // when it is required to store the captured data on a local file. |
449 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. | 452 // By default, GTest will print out YOU HAVE 1 DISABLED TEST. |
450 // To include disabled tests in test execution, just invoke the test program | 453 // To include disabled tests in test execution, just invoke the test program |
451 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS | 454 // with --gtest_also_run_disabled_tests or set the GTEST_ALSO_RUN_DISABLED_TESTS |
452 // environment variable to a value greater than 0. | 455 // environment variable to a value greater than 0. |
453 TEST_F(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { | 456 TEST(WinAudioInputTest, DISABLED_WASAPIAudioInputStreamRecordToFile) { |
454 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager_.get())); | 457 scoped_ptr<AudioManager> audio_manager(AudioManager::CreateForTesting()); |
| 458 ABORT_AUDIO_TEST_IF_NOT(HasCoreAudioAndInputDevices(audio_manager.get())); |
455 | 459 |
456 // Name of the output PCM file containing captured data. The output file | 460 // Name of the output PCM file containing captured data. The output file |
457 // will be stored in the directory containing 'media_unittests.exe'. | 461 // will be stored in the directory containing 'media_unittests.exe'. |
458 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. | 462 // Example of full name: \src\build\Debug\out_stereo_10sec.pcm. |
459 const char* file_name = "out_stereo_10sec.pcm"; | 463 const char* file_name = "out_stereo_10sec.pcm"; |
460 | 464 |
461 AudioInputStreamWrapper aisw(audio_manager_.get()); | 465 AudioInputStreamWrapper aisw(audio_manager.get()); |
462 ScopedAudioInputStream ais(aisw.Create()); | 466 ScopedAudioInputStream ais(aisw.Create()); |
463 EXPECT_TRUE(ais->Open()); | 467 EXPECT_TRUE(ais->Open()); |
464 | 468 |
465 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; | 469 VLOG(0) << ">> Sample rate: " << aisw.sample_rate() << " [Hz]"; |
466 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); | 470 WriteToFileAudioSink file_sink(file_name, aisw.bits_per_sample()); |
467 VLOG(0) << ">> Speak into the default microphone while recording."; | 471 VLOG(0) << ">> Speak into the default microphone while recording."; |
468 ais->Start(&file_sink); | 472 ais->Start(&file_sink); |
469 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); | 473 base::PlatformThread::Sleep(TestTimeouts::action_timeout()); |
470 ais->Stop(); | 474 ais->Stop(); |
471 VLOG(0) << ">> Recording has stopped."; | 475 VLOG(0) << ">> Recording has stopped."; |
472 ais.Close(); | 476 ais.Close(); |
473 } | 477 } |
474 | 478 |
475 } // namespace media | 479 } // namespace media |
OLD | NEW |