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 <windows.h> | 5 #include <windows.h> |
| 6 #include <audioclient.h> | 6 #include <audioclient.h> |
| 7 #include <avrt.h> | 7 #include <avrt.h> |
| 8 #include <mmdeviceapi.h> | 8 #include <mmdeviceapi.h> |
| 9 #include <mmreg.h> | 9 #include <mmreg.h> |
| 10 #include <mmsystem.h> | 10 #include <mmsystem.h> |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 27 const int kBitsPerSample = 16; | 27 const int kBitsPerSample = 16; |
| 28 const int kBitsPerByte = 8; | 28 const int kBitsPerByte = 8; |
| 29 // Conversion factor from 100ns to 1ms. | 29 // Conversion factor from 100ns to 1ms. |
| 30 const int kHnsToMs = 10000; | 30 const int kHnsToMs = 10000; |
| 31 | 31 |
| 32 // Tolerance for catching packets of silence. If all samples have absolute | 32 // Tolerance for catching packets of silence. If all samples have absolute |
| 33 // value less than this threshold, the packet will be counted as a packet of | 33 // value less than this threshold, the packet will be counted as a packet of |
| 34 // silence. A value of 2 was chosen, because Windows can give samples of 1 and | 34 // silence. A value of 2 was chosen, because Windows can give samples of 1 and |
| 35 // -1, even when no audio is playing. | 35 // -1, even when no audio is playing. |
| 36 const int kSilenceThreshold = 2; | 36 const int kSilenceThreshold = 2; |
| 37 | |
| 38 // Number of packets that can be stored in the Windows capture buffer. | |
| 39 // Even if we capture once every |audio_device_period_| * |kWindowsBufferSize|, | |
| 40 // we will buffer enough to avoid glitches. | |
| 41 const int kWindowsBufferSize = 10; | |
|
Wez
2012/08/15 21:32:29
Why 10? Surely we want to configure things to cope
kxing
2012/08/16 17:30:57
Done.
| |
| 37 } // namespace | 42 } // namespace |
| 38 | 43 |
| 39 namespace remoting { | 44 namespace remoting { |
| 40 | 45 |
| 41 class AudioCapturerWin : public AudioCapturer { | 46 class AudioCapturerWin : public AudioCapturer { |
| 42 public: | 47 public: |
| 43 AudioCapturerWin(); | 48 AudioCapturerWin(); |
| 44 virtual ~AudioCapturerWin(); | 49 virtual ~AudioCapturerWin(); |
| 45 | 50 |
| 46 // AudioCapturer interface. | 51 // AudioCapturer interface. |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 188 break; | 193 break; |
| 189 } | 194 } |
| 190 default: | 195 default: |
| 191 LOG(ERROR) << "Failed to force 16-bit PCM"; | 196 LOG(ERROR) << "Failed to force 16-bit PCM"; |
| 192 return false; | 197 return false; |
| 193 } | 198 } |
| 194 | 199 |
| 195 // Initialize the IAudioClient. | 200 // Initialize the IAudioClient. |
| 196 hr = audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED, | 201 hr = audio_client_->Initialize(AUDCLNT_SHAREMODE_SHARED, |
| 197 AUDCLNT_STREAMFLAGS_LOOPBACK, | 202 AUDCLNT_STREAMFLAGS_LOOPBACK, |
| 198 0, | 203 device_period * kWindowsBufferSize, |
|
Sergey Ulanov
2012/08/15 21:43:22
Does this have to be multiple of device_period? Ca
kxing
2012/08/16 17:30:57
Done.
| |
| 199 0, | 204 0, |
| 200 wave_format_ex_, | 205 wave_format_ex_, |
| 201 NULL); | 206 NULL); |
| 202 if (FAILED(hr)) { | 207 if (FAILED(hr)) { |
| 203 LOG(ERROR) << "Failed to initialize IAudioClient. Error " << hr; | 208 LOG(ERROR) << "Failed to initialize IAudioClient. Error " << hr; |
| 204 return false; | 209 return false; |
| 205 } | 210 } |
| 206 | 211 |
| 207 // Get an IAudioCaptureClient. | 212 // Get an IAudioCaptureClient. |
| 208 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), | 213 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), |
| 209 audio_capture_client_.ReceiveVoid()); | 214 audio_capture_client_.ReceiveVoid()); |
| 210 if (FAILED(hr)) { | 215 if (FAILED(hr)) { |
| 211 LOG(ERROR) << "Failed to get an IAudioCaptureClient. Error " << hr; | 216 LOG(ERROR) << "Failed to get an IAudioCaptureClient. Error " << hr; |
| 212 return false; | 217 return false; |
| 213 } | 218 } |
| 214 | 219 |
| 215 // Start the IAudioClient. | 220 // Start the IAudioClient. |
| 216 hr = audio_client_->Start(); | 221 hr = audio_client_->Start(); |
| 217 if (FAILED(hr)) { | 222 if (FAILED(hr)) { |
| 218 LOG(ERROR) << "Failed to start IAudioClient. Error " << hr; | 223 LOG(ERROR) << "Failed to start IAudioClient. Error " << hr; |
| 219 return false; | 224 return false; |
| 220 } | 225 } |
| 221 | 226 |
| 222 // Start capturing. | 227 // Start capturing. |
| 223 capture_timer_->Start(FROM_HERE, | 228 capture_timer_->Start(FROM_HERE, |
| 224 audio_device_period_, | 229 audio_device_period_, |
|
Sergey Ulanov
2012/08/15 21:43:22
why do we need timer to be scheduled with device_p
Wez
2012/08/15 21:55:30
We need to cope with the case where the device per
kxing
2012/08/16 17:30:57
Done.
kxing
2012/08/16 17:30:57
Done.
| |
| 225 this, | 230 this, |
| 226 &AudioCapturerWin::DoCapture); | 231 &AudioCapturerWin::DoCapture); |
| 227 return true; | 232 return true; |
| 228 } | 233 } |
| 229 | 234 |
| 230 void AudioCapturerWin::Stop() { | 235 void AudioCapturerWin::Stop() { |
| 231 DCHECK(thread_checker_.CalledOnValidThread()); | 236 DCHECK(thread_checker_.CalledOnValidThread()); |
| 232 DCHECK(IsRunning()); | 237 DCHECK(IsRunning()); |
| 233 | 238 |
| 234 capture_timer_.reset(); | 239 capture_timer_.reset(); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 306 return false; | 311 return false; |
| 307 } | 312 } |
| 308 return true; | 313 return true; |
| 309 } | 314 } |
| 310 | 315 |
| 311 scoped_ptr<AudioCapturer> AudioCapturer::Create() { | 316 scoped_ptr<AudioCapturer> AudioCapturer::Create() { |
| 312 return scoped_ptr<AudioCapturer>(new AudioCapturerWin()); | 317 return scoped_ptr<AudioCapturer>(new AudioCapturerWin()); |
| 313 } | 318 } |
| 314 | 319 |
| 315 } // namespace remoting | 320 } // namespace remoting |
| OLD | NEW |