Chromium Code Reviews| 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 "media/audio/win/audio_low_latency_input_win.h" | 5 #include "media/audio/win/audio_low_latency_input_win.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/metrics/histogram_macros.h" | 10 #include "base/metrics/histogram_macros.h" |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 319 // 1) The recorded buffer size is smaller, or does not match exactly with, | 319 // 1) The recorded buffer size is smaller, or does not match exactly with, |
| 320 // the selected packet size used in each callback. | 320 // the selected packet size used in each callback. |
| 321 // 2) The selected buffer size is larger than the recorded buffer size in | 321 // 2) The selected buffer size is larger than the recorded buffer size in |
| 322 // each event. | 322 // each event. |
| 323 size_t buffer_frame_index = 0; | 323 size_t buffer_frame_index = 0; |
| 324 size_t capture_buffer_size = | 324 size_t capture_buffer_size = |
| 325 std::max(2 * endpoint_buffer_size_frames_ * frame_size_, | 325 std::max(2 * endpoint_buffer_size_frames_ * frame_size_, |
| 326 2 * packet_size_frames_ * frame_size_); | 326 2 * packet_size_frames_ * frame_size_); |
| 327 std::unique_ptr<uint8_t[]> capture_buffer(new uint8_t[capture_buffer_size]); | 327 std::unique_ptr<uint8_t[]> capture_buffer(new uint8_t[capture_buffer_size]); |
| 328 | 328 |
| 329 LARGE_INTEGER now_count = {}; | |
| 330 bool recording = true; | 329 bool recording = true; |
| 331 bool error = false; | 330 bool error = false; |
| 332 double volume = GetVolume(); | 331 double volume = GetVolume(); |
| 333 HANDLE wait_array[2] = {stop_capture_event_.Get(), | 332 HANDLE wait_array[2] = {stop_capture_event_.Get(), |
| 334 audio_samples_ready_event_.Get()}; | 333 audio_samples_ready_event_.Get()}; |
| 335 | 334 |
| 336 base::win::ScopedComPtr<IAudioClock> audio_clock; | 335 base::win::ScopedComPtr<IAudioClock> audio_clock; |
| 337 audio_client_->GetService(__uuidof(IAudioClock), audio_clock.ReceiveVoid()); | 336 audio_client_->GetService(__uuidof(IAudioClock), audio_clock.ReceiveVoid()); |
| 338 | 337 |
| 339 while (recording && !error) { | 338 while (recording && !error) { |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 394 buffer_frame_index += num_frames_to_read; | 393 buffer_frame_index += num_frames_to_read; |
| 395 } | 394 } |
| 396 | 395 |
| 397 hr = audio_capture_client_->ReleaseBuffer(num_frames_to_read); | 396 hr = audio_capture_client_->ReleaseBuffer(num_frames_to_read); |
| 398 DLOG_IF(ERROR, FAILED(hr)) << "Failed to release capture buffer"; | 397 DLOG_IF(ERROR, FAILED(hr)) << "Failed to release capture buffer"; |
| 399 | 398 |
| 400 // Derive a delay estimate for the captured audio packet. | 399 // Derive a delay estimate for the captured audio packet. |
| 401 // The value contains two parts (A+B), where A is the delay of the | 400 // The value contains two parts (A+B), where A is the delay of the |
| 402 // first audio frame in the packet and B is the extra delay | 401 // first audio frame in the packet and B is the extra delay |
| 403 // contained in any stored data. Unit is in audio frames. | 402 // contained in any stored data. Unit is in audio frames. |
| 404 QueryPerformanceCounter(&now_count); | |
| 405 // first_audio_frame_timestamp will be 0 if we didn't get a timestamp. | 403 // first_audio_frame_timestamp will be 0 if we didn't get a timestamp. |
| 404 | |
| 405 base::TimeTicks delay_timestamp = | |
| 406 base::TimeTicks::FromQPCValue(first_audio_frame_timestamp); | |
| 407 | |
| 408 // TODO(dalecurtis): This is all wrong and brain is mush, fix tomorrow. | |
|
miu
2017/02/12 04:21:37
It may help to consult what was done for this same
| |
| 409 // Needs to compensate for input buffers from past cycles. | |
| 410 base::TimeDelta delay = | |
| 411 first_audio_frame_timestamp | |
| 412 ? base::TimeTicks::Now() - delay_timestamp | |
| 413 : base::TimeDelta::FromSecondsD( | |
| 414 num_frames_to_read / | |
| 415 static_cast<double>(format_.nSamplesPerSec)); | |
| 416 | |
| 417 #if 0 | |
| 406 double audio_delay_frames = | 418 double audio_delay_frames = |
| 407 first_audio_frame_timestamp == 0 | 419 first_audio_frame_timestamp == 0 |
| 408 ? num_frames_to_read | 420 ? num_frames_to_read |
| 409 : ((perf_count_to_100ns_units_ * now_count.QuadPart - | 421 : ((perf_count_to_100ns_units_ * now_count.QuadPart - |
| 410 first_audio_frame_timestamp) / | 422 first_audio_frame_timestamp) / |
| 411 10000.0) * | 423 10000.0) * |
| 412 ms_to_frame_count_ + | 424 ms_to_frame_count_ + |
| 413 buffer_frame_index - num_frames_to_read; | 425 buffer_frame_index - num_frames_to_read; |
| 414 | 426 #endif |
| 415 // Get a cached AGC volume level which is updated once every second | 427 // Get a cached AGC volume level which is updated once every second |
| 416 // on the audio manager thread. Note that, |volume| is also updated | 428 // on the audio manager thread. Note that, |volume| is also updated |
| 417 // each time SetVolume() is called through IPC by the render-side AGC. | 429 // each time SetVolume() is called through IPC by the render-side AGC. |
| 418 GetAgcVolume(&volume); | 430 GetAgcVolume(&volume); |
| 419 | 431 |
| 420 // Deliver captured data to the registered consumer using a packet | 432 // Deliver captured data to the registered consumer using a packet |
| 421 // size which was specified at construction. | 433 // size which was specified at construction. |
| 422 uint32_t delay_frames = static_cast<uint32_t>(audio_delay_frames + 0.5); | |
| 423 while (buffer_frame_index >= packet_size_frames_) { | 434 while (buffer_frame_index >= packet_size_frames_) { |
| 424 // Copy data to audio bus to match the OnData interface. | 435 // Copy data to audio bus to match the OnData interface. |
| 425 uint8_t* audio_data = | 436 uint8_t* audio_data = |
| 426 reinterpret_cast<uint8_t*>(capture_buffer.get()); | 437 reinterpret_cast<uint8_t*>(capture_buffer.get()); |
| 427 audio_bus_->FromInterleaved(audio_data, audio_bus_->frames(), | 438 audio_bus_->FromInterleaved(audio_data, audio_bus_->frames(), |
| 428 format_.wBitsPerSample / 8); | 439 format_.wBitsPerSample / 8); |
| 429 | 440 |
| 430 // Deliver data packet, delay estimation and volume level to | 441 // Deliver data packet, delay estimation and volume level to |
| 431 // the user. | 442 // the user. |
| 432 sink_->OnData(this, audio_bus_.get(), delay_frames * frame_size_, | 443 sink_->OnData(this, audio_bus_.get(), delay, delay_timestamp, volume); |
| 433 volume); | |
| 434 | 444 |
| 435 // Store parts of the recorded data which can't be delivered | 445 // Store parts of the recorded data which can't be delivered |
| 436 // using the current packet size. The stored section will be used | 446 // using the current packet size. The stored section will be used |
| 437 // either in the next while-loop iteration or in the next | 447 // either in the next while-loop iteration or in the next |
| 438 // capture event. | 448 // capture event. |
| 439 // TODO(tommi): If this data will be used in the next capture | 449 // TODO(tommi): If this data will be used in the next capture |
| 440 // event, we will report incorrect delay estimates because | 450 // event, we will report incorrect delay estimates because |
| 441 // we'll use the one for the captured data that time around | 451 // we'll use the one for the captured data that time around |
| 442 // (i.e. in the future). | 452 // (i.e. in the future). |
| 443 memmove(&capture_buffer[0], &capture_buffer[packet_size_bytes_], | 453 memmove(&capture_buffer[0], &capture_buffer[packet_size_bytes_], |
| 444 (buffer_frame_index - packet_size_frames_) * frame_size_); | 454 (buffer_frame_index - packet_size_frames_) * frame_size_); |
| 445 | 455 |
| 446 DCHECK_GE(buffer_frame_index, packet_size_frames_); | 456 DCHECK_GE(buffer_frame_index, packet_size_frames_); |
| 447 buffer_frame_index -= packet_size_frames_; | 457 buffer_frame_index -= packet_size_frames_; |
| 448 if (delay_frames > packet_size_frames_) { | |
| 449 delay_frames -= packet_size_frames_; | |
| 450 } else { | |
| 451 delay_frames = 0; | |
| 452 } | |
| 453 } | 458 } |
| 454 } break; | 459 } break; |
| 455 default: | 460 default: |
| 456 error = true; | 461 error = true; |
| 457 break; | 462 break; |
| 458 } | 463 } |
| 459 } | 464 } |
| 460 | 465 |
| 461 if (recording && error) { | 466 if (recording && error) { |
| 462 // TODO(henrika): perhaps it worth improving the cleanup here by e.g. | 467 // TODO(henrika): perhaps it worth improving the cleanup here by e.g. |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 732 return hr; | 737 return hr; |
| 733 } | 738 } |
| 734 | 739 |
| 735 void WASAPIAudioInputStream::ReportOpenResult() const { | 740 void WASAPIAudioInputStream::ReportOpenResult() const { |
| 736 DCHECK(!opened_); // This method must be called before we set this flag. | 741 DCHECK(!opened_); // This method must be called before we set this flag. |
| 737 UMA_HISTOGRAM_ENUMERATION("Media.Audio.Capture.Win.Open", open_result_, | 742 UMA_HISTOGRAM_ENUMERATION("Media.Audio.Capture.Win.Open", open_result_, |
| 738 OPEN_RESULT_MAX + 1); | 743 OPEN_RESULT_MAX + 1); |
| 739 } | 744 } |
| 740 | 745 |
| 741 } // namespace media | 746 } // namespace media |
| OLD | NEW |