| 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" | |
| 9 #include "base/base_paths.h" | 8 #include "base/base_paths.h" |
| 10 #include "base/memory/aligned_memory.h" | 9 #include "base/memory/aligned_memory.h" |
| 11 #include "base/sync_socket.h" | 10 #include "base/sync_socket.h" |
| 12 #include "base/win/scoped_com_initializer.h" | 11 #include "base/win/scoped_com_initializer.h" |
| 13 #include "base/win/windows_version.h" | 12 #include "base/win/windows_version.h" |
| 14 #include "media/base/limits.h" | 13 #include "media/base/limits.h" |
| 15 #include "media/audio/audio_io.h" | 14 #include "media/audio/audio_io.h" |
| 16 #include "media/audio/audio_manager.h" | 15 #include "media/audio/audio_manager.h" |
| 17 #include "media/audio/audio_unittest_util.h" | 16 #include "media/audio/audio_unittest_util.h" |
| 18 #include "media/audio/mock_audio_source_callback.h" | 17 #include "media/audio/mock_audio_source_callback.h" |
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 125 if (start_) { | 124 if (start_) { |
| 126 ::UnmapViewOfFile(start_); | 125 ::UnmapViewOfFile(start_); |
| 127 ::CloseHandle(fmap_); | 126 ::CloseHandle(fmap_); |
| 128 } | 127 } |
| 129 } | 128 } |
| 130 // Returns true if the file was successfully mapped. | 129 // Returns true if the file was successfully mapped. |
| 131 bool is_valid() const { | 130 bool is_valid() const { |
| 132 return ((start_ > 0) && (size_ > 0)); | 131 return ((start_ > 0) && (size_ > 0)); |
| 133 } | 132 } |
| 134 // Returns the size in bytes of the mapped memory. | 133 // Returns the size in bytes of the mapped memory. |
| 135 uint32 size() const { | 134 uint32_t size() const { return size_; } |
| 136 return size_; | |
| 137 } | |
| 138 // Returns the memory backing the file. | 135 // Returns the memory backing the file. |
| 139 const void* GetChunkAt(uint32 offset) { | 136 const void* GetChunkAt(uint32_t offset) { return &start_[offset]; } |
| 140 return &start_[offset]; | |
| 141 } | |
| 142 | 137 |
| 143 private: | 138 private: |
| 144 HANDLE fmap_; | 139 HANDLE fmap_; |
| 145 char* start_; | 140 char* start_; |
| 146 uint32 size_; | 141 uint32_t size_; |
| 147 }; | 142 }; |
| 148 | 143 |
| 149 // =========================================================================== | 144 // =========================================================================== |
| 150 // Validation of AudioManager::AUDIO_PCM_LINEAR | 145 // Validation of AudioManager::AUDIO_PCM_LINEAR |
| 151 // | 146 // |
| 152 // NOTE: | 147 // NOTE: |
| 153 // The tests can fail on the build bots when somebody connects to them via | 148 // The tests can fail on the build bots when somebody connects to them via |
| 154 // remote-desktop and the rdp client installs an audio device that fails to open | 149 // remote-desktop and the rdp client installs an audio device that fails to open |
| 155 // at some point, possibly when the connection goes idle. | 150 // at some point, possibly when the connection goes idle. |
| 156 | 151 |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 253 oas->Close(); | 248 oas->Close(); |
| 254 } | 249 } |
| 255 | 250 |
| 256 // Test another potential deadlock situation if the thread that calls Start() | 251 // Test another potential deadlock situation if the thread that calls Start() |
| 257 // gets paused. This test is best when run over RDP with audio enabled. See | 252 // gets paused. This test is best when run over RDP with audio enabled. See |
| 258 // bug 19276 for more details. | 253 // bug 19276 for more details. |
| 259 TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) { | 254 TEST(WinAudioTest, PCMWaveStreamPlaySlowLoop) { |
| 260 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 255 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 261 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 256 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 262 | 257 |
| 263 uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; | 258 uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; |
| 264 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 259 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 265 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 260 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 266 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), | 261 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), |
| 267 std::string()); | 262 std::string()); |
| 268 ASSERT_TRUE(NULL != oas); | 263 ASSERT_TRUE(NULL != oas); |
| 269 | 264 |
| 270 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); | 265 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); |
| 271 | 266 |
| 272 EXPECT_TRUE(oas->Open()); | 267 EXPECT_TRUE(oas->Open()); |
| 273 oas->SetVolume(1.0); | 268 oas->SetVolume(1.0); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 284 // This test produces actual audio for .5 seconds on the default wave | 279 // This test produces actual audio for .5 seconds on the default wave |
| 285 // device at 44.1K s/sec. Parameters have been chosen carefully so you should | 280 // device at 44.1K s/sec. Parameters have been chosen carefully so you should |
| 286 // not hear pops or noises while the sound is playing. | 281 // not hear pops or noises while the sound is playing. |
| 287 TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) { | 282 TEST(WinAudioTest, PCMWaveStreamPlay200HzTone44Kss) { |
| 288 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 283 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 289 if (!audio_man->HasAudioOutputDevices()) { | 284 if (!audio_man->HasAudioOutputDevices()) { |
| 290 LOG(WARNING) << "No output device detected."; | 285 LOG(WARNING) << "No output device detected."; |
| 291 return; | 286 return; |
| 292 } | 287 } |
| 293 | 288 |
| 294 uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; | 289 uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; |
| 295 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 290 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 296 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 291 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 297 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), | 292 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), |
| 298 std::string()); | 293 std::string()); |
| 299 ASSERT_TRUE(NULL != oas); | 294 ASSERT_TRUE(NULL != oas); |
| 300 | 295 |
| 301 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); | 296 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); |
| 302 | 297 |
| 303 EXPECT_TRUE(oas->Open()); | 298 EXPECT_TRUE(oas->Open()); |
| 304 oas->SetVolume(1.0); | 299 oas->SetVolume(1.0); |
| 305 oas->Start(&source); | 300 oas->Start(&source); |
| 306 ::Sleep(500); | 301 ::Sleep(500); |
| 307 oas->Stop(); | 302 oas->Stop(); |
| 308 oas->Close(); | 303 oas->Close(); |
| 309 } | 304 } |
| 310 | 305 |
| 311 // This test produces actual audio for for .5 seconds on the default wave | 306 // This test produces actual audio for for .5 seconds on the default wave |
| 312 // device at 22K s/sec. Parameters have been chosen carefully so you should | 307 // device at 22K s/sec. Parameters have been chosen carefully so you should |
| 313 // not hear pops or noises while the sound is playing. The audio also should | 308 // not hear pops or noises while the sound is playing. The audio also should |
| 314 // sound with a lower volume than PCMWaveStreamPlay200HzTone44Kss. | 309 // sound with a lower volume than PCMWaveStreamPlay200HzTone44Kss. |
| 315 TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) { | 310 TEST(WinAudioTest, PCMWaveStreamPlay200HzTone22Kss) { |
| 316 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 311 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 317 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 312 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 318 | 313 |
| 319 uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 20; | 314 uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 20; |
| 320 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 315 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 321 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 316 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 322 AudioParameters::kAudioCDSampleRate / 2, 16, | 317 AudioParameters::kAudioCDSampleRate / 2, 16, |
| 323 samples_100_ms), | 318 samples_100_ms), |
| 324 std::string()); | 319 std::string()); |
| 325 ASSERT_TRUE(NULL != oas); | 320 ASSERT_TRUE(NULL != oas); |
| 326 | 321 |
| 327 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate/2); | 322 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate/2); |
| 328 | 323 |
| 329 EXPECT_TRUE(oas->Open()); | 324 EXPECT_TRUE(oas->Open()); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 344 // Uses a restricted source to play ~2 seconds of audio for about 5 seconds. We | 339 // Uses a restricted source to play ~2 seconds of audio for about 5 seconds. We |
| 345 // try hard to generate situation where the two threads are accessing the | 340 // try hard to generate situation where the two threads are accessing the |
| 346 // object roughly at the same time. | 341 // object roughly at the same time. |
| 347 TEST(WinAudioTest, PushSourceFile16KHz) { | 342 TEST(WinAudioTest, PushSourceFile16KHz) { |
| 348 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 343 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 349 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 344 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 350 | 345 |
| 351 static const int kSampleRate = 16000; | 346 static const int kSampleRate = 16000; |
| 352 SineWaveAudioSource source(1, 200.0, kSampleRate); | 347 SineWaveAudioSource source(1, 200.0, kSampleRate); |
| 353 // Compute buffer size for 100ms of audio. | 348 // Compute buffer size for 100ms of audio. |
| 354 const uint32 kSamples100ms = (kSampleRate / 1000) * 100; | 349 const uint32_t kSamples100ms = (kSampleRate / 1000) * 100; |
| 355 // Restrict SineWaveAudioSource to 100ms of samples. | 350 // Restrict SineWaveAudioSource to 100ms of samples. |
| 356 source.CapSamples(kSamples100ms); | 351 source.CapSamples(kSamples100ms); |
| 357 | 352 |
| 358 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 353 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 359 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 354 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 360 kSampleRate, 16, kSamples100ms), | 355 kSampleRate, 16, kSamples100ms), |
| 361 std::string()); | 356 std::string()); |
| 362 ASSERT_TRUE(NULL != oas); | 357 ASSERT_TRUE(NULL != oas); |
| 363 | 358 |
| 364 EXPECT_TRUE(oas->Open()); | 359 EXPECT_TRUE(oas->Open()); |
| 365 | 360 |
| 366 oas->SetVolume(1.0); | 361 oas->SetVolume(1.0); |
| 367 oas->Start(&source); | 362 oas->Start(&source); |
| 368 | 363 |
| 369 // We buffer and play at the same time, buffering happens every ~10ms and the | 364 // We buffer and play at the same time, buffering happens every ~10ms and the |
| 370 // consuming of the buffer happens every ~100ms. We do 100 buffers which | 365 // consuming of the buffer happens every ~100ms. We do 100 buffers which |
| 371 // effectively wrap around the file more than once. | 366 // effectively wrap around the file more than once. |
| 372 for (uint32 ix = 0; ix != 100; ++ix) { | 367 for (uint32_t ix = 0; ix != 100; ++ix) { |
| 373 ::Sleep(10); | 368 ::Sleep(10); |
| 374 source.Reset(); | 369 source.Reset(); |
| 375 } | 370 } |
| 376 | 371 |
| 377 // Play a little bit more of the file. | 372 // Play a little bit more of the file. |
| 378 ::Sleep(500); | 373 ::Sleep(500); |
| 379 | 374 |
| 380 oas->Stop(); | 375 oas->Stop(); |
| 381 oas->Close(); | 376 oas->Close(); |
| 382 } | 377 } |
| 383 | 378 |
| 384 // This test is to make sure an AudioOutputStream can be started after it was | 379 // This test is to make sure an AudioOutputStream can be started after it was |
| 385 // stopped. You will here two .5 seconds wave signal separated by 0.5 seconds | 380 // stopped. You will here two .5 seconds wave signal separated by 0.5 seconds |
| 386 // of silence. | 381 // of silence. |
| 387 TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) { | 382 TEST(WinAudioTest, PCMWaveStreamPlayTwice200HzTone44Kss) { |
| 388 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 383 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 389 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 384 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 390 | 385 |
| 391 uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; | 386 uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; |
| 392 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 387 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 393 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 388 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 394 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), | 389 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), |
| 395 std::string()); | 390 std::string()); |
| 396 ASSERT_TRUE(NULL != oas); | 391 ASSERT_TRUE(NULL != oas); |
| 397 | 392 |
| 398 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); | 393 SineWaveAudioSource source(1, 200.0, AudioParameters::kAudioCDSampleRate); |
| 399 EXPECT_TRUE(oas->Open()); | 394 EXPECT_TRUE(oas->Open()); |
| 400 oas->SetVolume(1.0); | 395 oas->SetVolume(1.0); |
| 401 | 396 |
| (...skipping 17 matching lines...) Expand all Loading... |
| 419 // higher and Wave is used for XP and lower. It is possible to utilize a | 414 // higher and Wave is used for XP and lower. It is possible to utilize a |
| 420 // smaller buffer size for WASAPI than for Wave. | 415 // smaller buffer size for WASAPI than for Wave. |
| 421 TEST(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) { | 416 TEST(WinAudioTest, PCMWaveStreamPlay200HzToneLowLatency) { |
| 422 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 417 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 423 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 418 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 424 | 419 |
| 425 // Use 10 ms buffer size for WASAPI and 50 ms buffer size for Wave. | 420 // Use 10 ms buffer size for WASAPI and 50 ms buffer size for Wave. |
| 426 // Take the existing native sample rate into account. | 421 // Take the existing native sample rate into account. |
| 427 const AudioParameters params = audio_man->GetDefaultOutputStreamParameters(); | 422 const AudioParameters params = audio_man->GetDefaultOutputStreamParameters(); |
| 428 int sample_rate = params.sample_rate(); | 423 int sample_rate = params.sample_rate(); |
| 429 uint32 samples_10_ms = sample_rate / 100; | 424 uint32_t samples_10_ms = sample_rate / 100; |
| 430 int n = 1; | 425 int n = 1; |
| 431 (base::win::GetVersion() <= base::win::VERSION_XP) ? n = 5 : n = 1; | 426 (base::win::GetVersion() <= base::win::VERSION_XP) ? n = 5 : n = 1; |
| 432 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 427 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 433 AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, | 428 AudioParameters(AudioParameters::AUDIO_PCM_LOW_LATENCY, |
| 434 CHANNEL_LAYOUT_MONO, sample_rate, | 429 CHANNEL_LAYOUT_MONO, sample_rate, |
| 435 16, n * samples_10_ms), | 430 16, n * samples_10_ms), |
| 436 std::string()); | 431 std::string()); |
| 437 ASSERT_TRUE(NULL != oas); | 432 ASSERT_TRUE(NULL != oas); |
| 438 | 433 |
| 439 SineWaveAudioSource source(1, 200, sample_rate); | 434 SineWaveAudioSource source(1, 200, sample_rate); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 453 ::Sleep(800); | 448 ::Sleep(800); |
| 454 oas->Stop(); | 449 oas->Stop(); |
| 455 oas->Close(); | 450 oas->Close(); |
| 456 } | 451 } |
| 457 | 452 |
| 458 // Check that the pending bytes value is correct what the stream starts. | 453 // Check that the pending bytes value is correct what the stream starts. |
| 459 TEST(WinAudioTest, PCMWaveStreamPendingBytes) { | 454 TEST(WinAudioTest, PCMWaveStreamPendingBytes) { |
| 460 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 455 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 461 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 456 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 462 | 457 |
| 463 uint32 samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; | 458 uint32_t samples_100_ms = AudioParameters::kAudioCDSampleRate / 10; |
| 464 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( | 459 AudioOutputStream* oas = audio_man->MakeAudioOutputStream( |
| 465 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, | 460 AudioParameters(AudioParameters::AUDIO_PCM_LINEAR, CHANNEL_LAYOUT_MONO, |
| 466 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), | 461 AudioParameters::kAudioCDSampleRate, 16, samples_100_ms), |
| 467 std::string()); | 462 std::string()); |
| 468 ASSERT_TRUE(NULL != oas); | 463 ASSERT_TRUE(NULL != oas); |
| 469 | 464 |
| 470 NiceMock<MockAudioSourceCallback> source; | 465 NiceMock<MockAudioSourceCallback> source; |
| 471 EXPECT_TRUE(oas->Open()); | 466 EXPECT_TRUE(oas->Open()); |
| 472 | 467 |
| 473 uint32 bytes_100_ms = samples_100_ms * 2; | 468 uint32_t bytes_100_ms = samples_100_ms * 2; |
| 474 | 469 |
| 475 // Audio output stream has either a double or triple buffer scheme. | 470 // Audio output stream has either a double or triple buffer scheme. |
| 476 // We expect the amount of pending bytes will reaching up to 2 times of | 471 // We expect the amount of pending bytes will reaching up to 2 times of |
| 477 // |bytes_100_ms| depending on number of buffers used. | 472 // |bytes_100_ms| depending on number of buffers used. |
| 478 // From that it would decrease as we are playing the data but not providing | 473 // From that it would decrease as we are playing the data but not providing |
| 479 // new one. And then we will try to provide zero data so the amount of | 474 // new one. And then we will try to provide zero data so the amount of |
| 480 // pending bytes will go down and eventually read zero. | 475 // pending bytes will go down and eventually read zero. |
| 481 InSequence s; | 476 InSequence s; |
| 482 | 477 |
| 483 EXPECT_CALL(source, OnMoreData(NotNull(), 0, 0)).WillOnce(Invoke(ClearData)); | 478 EXPECT_CALL(source, OnMoreData(NotNull(), 0, 0)).WillOnce(Invoke(ClearData)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 516 base::AlignedAlloc(data_size_, AudioBus::kChannelAlignment))); | 511 base::AlignedAlloc(data_size_, AudioBus::kChannelAlignment))); |
| 517 audio_bus_ = AudioBus::WrapMemory(params, data_.get()); | 512 audio_bus_ = AudioBus::WrapMemory(params, data_.get()); |
| 518 } | 513 } |
| 519 ~SyncSocketSource() override {} | 514 ~SyncSocketSource() override {} |
| 520 | 515 |
| 521 // AudioSourceCallback::OnMoreData implementation: | 516 // AudioSourceCallback::OnMoreData implementation: |
| 522 int OnMoreData(AudioBus* audio_bus, | 517 int OnMoreData(AudioBus* audio_bus, |
| 523 uint32_t total_bytes_delay, | 518 uint32_t total_bytes_delay, |
| 524 uint32_t frames_skipped) override { | 519 uint32_t frames_skipped) override { |
| 525 socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); | 520 socket_->Send(&total_bytes_delay, sizeof(total_bytes_delay)); |
| 526 uint32 size = socket_->Receive(data_.get(), data_size_); | 521 uint32_t size = socket_->Receive(data_.get(), data_size_); |
| 527 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); | 522 DCHECK_EQ(static_cast<size_t>(size) % sizeof(*audio_bus_->channel(0)), 0U); |
| 528 audio_bus_->CopyTo(audio_bus); | 523 audio_bus_->CopyTo(audio_bus); |
| 529 return audio_bus_->frames(); | 524 return audio_bus_->frames(); |
| 530 } | 525 } |
| 531 | 526 |
| 532 // AudioSourceCallback::OnError implementation: | 527 // AudioSourceCallback::OnError implementation: |
| 533 void OnError(AudioOutputStream* stream) override {} | 528 void OnError(AudioOutputStream* stream) override {} |
| 534 | 529 |
| 535 private: | 530 private: |
| 536 base::SyncSocket* socket_; | 531 base::SyncSocket* socket_; |
| 537 int data_size_; | 532 int data_size_; |
| 538 scoped_ptr<float, base::AlignedFreeDeleter> data_; | 533 scoped_ptr<float, base::AlignedFreeDeleter> data_; |
| 539 scoped_ptr<AudioBus> audio_bus_; | 534 scoped_ptr<AudioBus> audio_bus_; |
| 540 }; | 535 }; |
| 541 | 536 |
| 542 struct SyncThreadContext { | 537 struct SyncThreadContext { |
| 543 base::SyncSocket* socket; | 538 base::SyncSocket* socket; |
| 544 int sample_rate; | 539 int sample_rate; |
| 545 int channels; | 540 int channels; |
| 546 int frames; | 541 int frames; |
| 547 double sine_freq; | 542 double sine_freq; |
| 548 uint32 packet_size_bytes; | 543 uint32_t packet_size_bytes; |
| 549 }; | 544 }; |
| 550 | 545 |
| 551 // This thread provides the data that the SyncSocketSource above needs | 546 // This thread provides the data that the SyncSocketSource above needs |
| 552 // using the other end of a SyncSocket. The protocol is as follows: | 547 // using the other end of a SyncSocket. The protocol is as follows: |
| 553 // | 548 // |
| 554 // SyncSocketSource ---send 4 bytes ------------> SyncSocketThread | 549 // SyncSocketSource ---send 4 bytes ------------> SyncSocketThread |
| 555 // <--- audio packet ---------- | 550 // <--- audio packet ---------- |
| 556 // | 551 // |
| 557 DWORD __stdcall SyncSocketThread(void* context) { | 552 DWORD __stdcall SyncSocketThread(void* context) { |
| 558 SyncThreadContext& ctx = *(reinterpret_cast<SyncThreadContext*>(context)); | 553 SyncThreadContext& ctx = *(reinterpret_cast<SyncThreadContext*>(context)); |
| 559 | 554 |
| 560 // Setup AudioBus wrapping data we'll pass over the sync socket. | 555 // Setup AudioBus wrapping data we'll pass over the sync socket. |
| 561 scoped_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( | 556 scoped_ptr<float, base::AlignedFreeDeleter> data(static_cast<float*>( |
| 562 base::AlignedAlloc(ctx.packet_size_bytes, AudioBus::kChannelAlignment))); | 557 base::AlignedAlloc(ctx.packet_size_bytes, AudioBus::kChannelAlignment))); |
| 563 scoped_ptr<AudioBus> audio_bus = AudioBus::WrapMemory( | 558 scoped_ptr<AudioBus> audio_bus = AudioBus::WrapMemory( |
| 564 ctx.channels, ctx.frames, data.get()); | 559 ctx.channels, ctx.frames, data.get()); |
| 565 | 560 |
| 566 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); | 561 SineWaveAudioSource sine(1, ctx.sine_freq, ctx.sample_rate); |
| 567 const int kTwoSecFrames = ctx.sample_rate * 2; | 562 const int kTwoSecFrames = ctx.sample_rate * 2; |
| 568 | 563 |
| 569 uint32 total_bytes_delay = 0; | 564 uint32_t total_bytes_delay = 0; |
| 570 int times = 0; | 565 int times = 0; |
| 571 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { | 566 for (int ix = 0; ix < kTwoSecFrames; ix += ctx.frames) { |
| 572 if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) | 567 if (ctx.socket->Receive(&total_bytes_delay, sizeof(total_bytes_delay)) == 0) |
| 573 break; | 568 break; |
| 574 if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); | 569 if ((times > 0) && (total_bytes_delay < 1000)) __debugbreak(); |
| 575 sine.OnMoreData(audio_bus.get(), total_bytes_delay, 0); | 570 sine.OnMoreData(audio_bus.get(), total_bytes_delay, 0); |
| 576 ctx.socket->Send(data.get(), ctx.packet_size_bytes); | 571 ctx.socket->Send(data.get(), ctx.packet_size_bytes); |
| 577 ++times; | 572 ++times; |
| 578 } | 573 } |
| 579 | 574 |
| 580 return 0; | 575 return 0; |
| 581 } | 576 } |
| 582 | 577 |
| 583 // Test the basic operation of AudioOutputStream used with a SyncSocket. | 578 // Test the basic operation of AudioOutputStream used with a SyncSocket. |
| 584 // The emphasis is to verify that it is possible to feed data to the audio | 579 // The emphasis is to verify that it is possible to feed data to the audio |
| 585 // layer using a source based on SyncSocket. In a real situation we would | 580 // layer using a source based on SyncSocket. In a real situation we would |
| 586 // go for the low-latency version in combination with SyncSocket, but to keep | 581 // go for the low-latency version in combination with SyncSocket, but to keep |
| 587 // the test more simple, AUDIO_PCM_LINEAR is utilized instead. The main | 582 // the test more simple, AUDIO_PCM_LINEAR is utilized instead. The main |
| 588 // principle of the test still remains and we avoid the additional complexity | 583 // principle of the test still remains and we avoid the additional complexity |
| 589 // related to the two different audio-layers for AUDIO_PCM_LOW_LATENCY. | 584 // related to the two different audio-layers for AUDIO_PCM_LOW_LATENCY. |
| 590 // In this test you should hear a continuous 200Hz tone for 2 seconds. | 585 // In this test you should hear a continuous 200Hz tone for 2 seconds. |
| 591 TEST(WinAudioTest, SyncSocketBasic) { | 586 TEST(WinAudioTest, SyncSocketBasic) { |
| 592 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); | 587 scoped_ptr<AudioManager> audio_man(AudioManager::CreateForTesting()); |
| 593 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); | 588 ABORT_AUDIO_TEST_IF_NOT(audio_man->HasAudioOutputDevices()); |
| 594 | 589 |
| 595 static const int sample_rate = AudioParameters::kAudioCDSampleRate; | 590 static const int sample_rate = AudioParameters::kAudioCDSampleRate; |
| 596 static const uint32 kSamples20ms = sample_rate / 50; | 591 static const uint32_t kSamples20ms = sample_rate / 50; |
| 597 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, | 592 AudioParameters params(AudioParameters::AUDIO_PCM_LINEAR, |
| 598 CHANNEL_LAYOUT_MONO, sample_rate, 16, kSamples20ms); | 593 CHANNEL_LAYOUT_MONO, sample_rate, 16, kSamples20ms); |
| 599 | 594 |
| 600 | 595 |
| 601 AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params, | 596 AudioOutputStream* oas = audio_man->MakeAudioOutputStream(params, |
| 602 std::string()); | 597 std::string()); |
| 603 ASSERT_TRUE(NULL != oas); | 598 ASSERT_TRUE(NULL != oas); |
| 604 | 599 |
| 605 ASSERT_TRUE(oas->Open()); | 600 ASSERT_TRUE(oas->Open()); |
| 606 | 601 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 623 oas->Start(&source); | 618 oas->Start(&source); |
| 624 | 619 |
| 625 ::WaitForSingleObject(thread, INFINITE); | 620 ::WaitForSingleObject(thread, INFINITE); |
| 626 ::CloseHandle(thread); | 621 ::CloseHandle(thread); |
| 627 | 622 |
| 628 oas->Stop(); | 623 oas->Stop(); |
| 629 oas->Close(); | 624 oas->Close(); |
| 630 } | 625 } |
| 631 | 626 |
| 632 } // namespace media | 627 } // namespace media |
| OLD | NEW |