OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
9 #include "base/utf_string_conversions.h" | 9 #include "base/utf_string_conversions.h" |
10 #include "media/audio/audio_util.h" | 10 #include "media/audio/audio_util.h" |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
177 sink_ = NULL; | 177 sink_ = NULL; |
178 } | 178 } |
179 | 179 |
180 // Inform the audio manager that we have been closed. This will cause our | 180 // Inform the audio manager that we have been closed. This will cause our |
181 // destruction. | 181 // destruction. |
182 manager_->ReleaseInputStream(this); | 182 manager_->ReleaseInputStream(this); |
183 } | 183 } |
184 | 184 |
185 // static | 185 // static |
186 double WASAPIAudioInputStream::HardwareSampleRate(ERole device_role) { | 186 double WASAPIAudioInputStream::HardwareSampleRate(ERole device_role) { |
| 187 base::win::ScopedCoMem<WAVEFORMATEX> audio_engine_mix_format; |
| 188 HRESULT hr = GetMixFormat(device_role, &audio_engine_mix_format); |
| 189 if (FAILED(hr)) { |
| 190 NOTREACHED() << "error code: " << hr; |
| 191 return 0.0; |
| 192 } |
| 193 |
| 194 return static_cast<double>(audio_engine_mix_format->nSamplesPerSec); |
| 195 } |
| 196 |
| 197 // static |
| 198 size_t WASAPIAudioInputStream::HardwareChannelCount(ERole device_role) { |
| 199 base::win::ScopedCoMem<WAVEFORMATEX> audio_engine_mix_format; |
| 200 HRESULT hr = GetMixFormat(device_role, &audio_engine_mix_format); |
| 201 if (FAILED(hr)) { |
| 202 NOTREACHED() << "error code: " << hr; |
| 203 return CHANNEL_LAYOUT_NONE; |
| 204 } |
| 205 |
| 206 return audio_engine_mix_format->nChannels; |
| 207 } |
| 208 |
| 209 // static |
| 210 HRESULT WASAPIAudioInputStream::GetMixFormat(ERole device_role, |
| 211 WAVEFORMATEX** device_format) { |
187 // It is assumed that this static method is called from a COM thread, i.e., | 212 // It is assumed that this static method is called from a COM thread, i.e., |
188 // CoInitializeEx() is not called here to avoid STA/MTA conflicts. | 213 // CoInitializeEx() is not called here to avoid STA/MTA conflicts. |
189 ScopedComPtr<IMMDeviceEnumerator> enumerator; | 214 ScopedComPtr<IMMDeviceEnumerator> enumerator; |
190 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), | 215 HRESULT hr = CoCreateInstance(__uuidof(MMDeviceEnumerator), |
191 NULL, | 216 NULL, |
192 CLSCTX_INPROC_SERVER, | 217 CLSCTX_INPROC_SERVER, |
193 __uuidof(IMMDeviceEnumerator), | 218 __uuidof(IMMDeviceEnumerator), |
194 enumerator.ReceiveVoid()); | 219 enumerator.ReceiveVoid()); |
195 if (FAILED(hr)) { | 220 if (FAILED(hr)) |
196 NOTREACHED() << "error code: " << hr; | 221 return hr; |
197 return 0.0; | |
198 } | |
199 | 222 |
200 ScopedComPtr<IMMDevice> endpoint_device; | 223 ScopedComPtr<IMMDevice> endpoint_device; |
201 hr = enumerator->GetDefaultAudioEndpoint(eCapture, | 224 hr = enumerator->GetDefaultAudioEndpoint(eCapture, |
202 device_role, | 225 device_role, |
203 endpoint_device.Receive()); | 226 endpoint_device.Receive()); |
204 if (FAILED(hr)) { | 227 if (FAILED(hr)) { |
205 // This will happen if there's no audio capture device found or available | 228 // This will happen if there's no audio capture device found or available |
206 // (e.g. some audio cards that have inputs will still report them as | 229 // (e.g. some audio cards that have inputs will still report them as |
207 // "not found" when no mic is plugged into the input jack). | 230 // "not found" when no mic is plugged into the input jack). |
208 LOG(WARNING) << "No audio end point: " << std::hex << hr; | 231 LOG(WARNING) << "No audio end point: " << std::hex << hr; |
209 return 0.0; | 232 return hr; |
210 } | 233 } |
211 | 234 |
212 ScopedComPtr<IAudioClient> audio_client; | 235 ScopedComPtr<IAudioClient> audio_client; |
213 hr = endpoint_device->Activate(__uuidof(IAudioClient), | 236 hr = endpoint_device->Activate(__uuidof(IAudioClient), |
214 CLSCTX_INPROC_SERVER, | 237 CLSCTX_INPROC_SERVER, |
215 NULL, | 238 NULL, |
216 audio_client.ReceiveVoid()); | 239 audio_client.ReceiveVoid()); |
217 if (FAILED(hr)) { | 240 if (SUCCEEDED(hr)) |
218 NOTREACHED() << "error code: " << hr; | 241 hr = audio_client->GetMixFormat(device_format); |
219 return 0.0; | |
220 } | |
221 | 242 |
222 base::win::ScopedCoMem<WAVEFORMATEX> audio_engine_mix_format; | 243 return hr; |
223 hr = audio_client->GetMixFormat(&audio_engine_mix_format); | |
224 if (FAILED(hr)) { | |
225 NOTREACHED() << "error code: " << hr; | |
226 return 0.0; | |
227 } | |
228 | |
229 return static_cast<double>(audio_engine_mix_format->nSamplesPerSec); | |
230 } | 244 } |
231 | 245 |
232 void WASAPIAudioInputStream::Run() { | 246 void WASAPIAudioInputStream::Run() { |
233 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); | 247 ScopedCOMInitializer com_init(ScopedCOMInitializer::kMTA); |
234 | 248 |
235 // Increase the thread priority. | 249 // Increase the thread priority. |
236 capture_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); | 250 capture_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); |
237 | 251 |
238 // Enable MMCSS to ensure that this thread receives prioritized access to | 252 // Enable MMCSS to ensure that this thread receives prioritized access to |
239 // CPU resources. | 253 // CPU resources. |
(...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
513 hr = audio_client_->SetEventHandle(audio_samples_ready_event_.Get()); | 527 hr = audio_client_->SetEventHandle(audio_samples_ready_event_.Get()); |
514 if (FAILED(hr)) | 528 if (FAILED(hr)) |
515 return hr; | 529 return hr; |
516 | 530 |
517 // Get access to the IAudioCaptureClient interface. This interface | 531 // Get access to the IAudioCaptureClient interface. This interface |
518 // enables us to read input data from the capture endpoint buffer. | 532 // enables us to read input data from the capture endpoint buffer. |
519 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), | 533 hr = audio_client_->GetService(__uuidof(IAudioCaptureClient), |
520 audio_capture_client_.ReceiveVoid()); | 534 audio_capture_client_.ReceiveVoid()); |
521 return hr; | 535 return hr; |
522 } | 536 } |
OLD | NEW |