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