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 "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 174 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
185 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; | 185 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; |
186 if (!opened_) | 186 if (!opened_) |
187 return 0.0; | 187 return 0.0; |
188 | 188 |
189 // The effective volume value is always in the range 0.0 to 1.0, hence | 189 // The effective volume value is always in the range 0.0 to 1.0, hence |
190 // we can return a fixed value (=1.0) here. | 190 // we can return a fixed value (=1.0) here. |
191 return 1.0; | 191 return 1.0; |
192 } | 192 } |
193 | 193 |
194 void WASAPIAudioInputStream::SetVolume(double volume) { | 194 void WASAPIAudioInputStream::SetVolume(double volume) { |
| 195 DVLOG(1) << "SetVolume(volume=" << volume << ")"; |
195 DCHECK(CalledOnValidThread()); | 196 DCHECK(CalledOnValidThread()); |
196 DCHECK(volume <= 1.0 && volume >= 0.0); | 197 DCHECK_GE(volume, 0.0); |
| 198 DCHECK_LE(volume, 1.0); |
197 | 199 |
198 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; | 200 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; |
199 if (!opened_) | 201 if (!opened_) |
200 return; | 202 return; |
201 | 203 |
202 // Set a new master volume level. Valid volume levels are in the range | 204 // Set a new master volume level. Valid volume levels are in the range |
203 // 0.0 to 1.0. Ignore volume-change events. | 205 // 0.0 to 1.0. Ignore volume-change events. |
204 HRESULT hr = simple_audio_volume_->SetMasterVolume(static_cast<float>(volume), | 206 HRESULT hr = simple_audio_volume_->SetMasterVolume(static_cast<float>(volume), |
205 NULL); | 207 NULL); |
206 DLOG_IF(WARNING, FAILED(hr)) << "Failed to set new input master volume."; | 208 DLOG_IF(WARNING, FAILED(hr)) << "Failed to set new input master volume."; |
| 209 |
| 210 // Update the AGC volume level based on the last setting above. Note that, |
| 211 // the volume-level resolution is not infinite and it is therefore not |
| 212 // possible to assume that the volume provided as input parameter can be |
| 213 // used directly. Instead, a new query to the audio hardware is required. |
| 214 // This method does nothing if AGC is disabled. |
| 215 UpdateAgcVolume(); |
207 } | 216 } |
208 | 217 |
209 double WASAPIAudioInputStream::GetVolume() { | 218 double WASAPIAudioInputStream::GetVolume() { |
210 DCHECK(CalledOnValidThread()); | |
211 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; | 219 DLOG_IF(ERROR, !opened_) << "Open() has not been called successfully"; |
212 if (!opened_) | 220 if (!opened_) |
213 return 0.0; | 221 return 0.0; |
214 | 222 |
215 // Retrieve the current volume level. The value is in the range 0.0 to 1.0. | 223 // Retrieve the current volume level. The value is in the range 0.0 to 1.0. |
216 float level = 0.0f; | 224 float level = 0.0f; |
217 HRESULT hr = simple_audio_volume_->GetMasterVolume(&level); | 225 HRESULT hr = simple_audio_volume_->GetMasterVolume(&level); |
218 DLOG_IF(WARNING, FAILED(hr)) << "Failed to get input master volume."; | 226 DLOG_IF(WARNING, FAILED(hr)) << "Failed to get input master volume."; |
219 | 227 |
220 return static_cast<double>(level); | 228 return static_cast<double>(level); |
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
316 // each event. | 324 // each event. |
317 size_t buffer_frame_index = 0; | 325 size_t buffer_frame_index = 0; |
318 size_t capture_buffer_size = std::max( | 326 size_t capture_buffer_size = std::max( |
319 2 * endpoint_buffer_size_frames_ * frame_size_, | 327 2 * endpoint_buffer_size_frames_ * frame_size_, |
320 2 * packet_size_frames_ * frame_size_); | 328 2 * packet_size_frames_ * frame_size_); |
321 scoped_array<uint8> capture_buffer(new uint8[capture_buffer_size]); | 329 scoped_array<uint8> capture_buffer(new uint8[capture_buffer_size]); |
322 | 330 |
323 LARGE_INTEGER now_count; | 331 LARGE_INTEGER now_count; |
324 bool recording = true; | 332 bool recording = true; |
325 bool error = false; | 333 bool error = false; |
| 334 double volume = GetVolume(); |
326 HANDLE wait_array[2] = {stop_capture_event_, audio_samples_ready_event_}; | 335 HANDLE wait_array[2] = {stop_capture_event_, audio_samples_ready_event_}; |
327 | 336 |
328 while (recording && !error) { | 337 while (recording && !error) { |
329 HRESULT hr = S_FALSE; | 338 HRESULT hr = S_FALSE; |
330 | 339 |
331 // Wait for a close-down event or a new capture event. | 340 // Wait for a close-down event or a new capture event. |
332 DWORD wait_result = WaitForMultipleObjects(2, wait_array, FALSE, INFINITE); | 341 DWORD wait_result = WaitForMultipleObjects(2, wait_array, FALSE, INFINITE); |
333 switch (wait_result) { | 342 switch (wait_result) { |
334 case WAIT_FAILED: | 343 case WAIT_FAILED: |
335 error = true; | 344 error = true; |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
382 // Derive a delay estimate for the captured audio packet. | 391 // Derive a delay estimate for the captured audio packet. |
383 // The value contains two parts (A+B), where A is the delay of the | 392 // The value contains two parts (A+B), where A is the delay of the |
384 // first audio frame in the packet and B is the extra delay | 393 // first audio frame in the packet and B is the extra delay |
385 // contained in any stored data. Unit is in audio frames. | 394 // contained in any stored data. Unit is in audio frames. |
386 QueryPerformanceCounter(&now_count); | 395 QueryPerformanceCounter(&now_count); |
387 double audio_delay_frames = | 396 double audio_delay_frames = |
388 ((perf_count_to_100ns_units_ * now_count.QuadPart - | 397 ((perf_count_to_100ns_units_ * now_count.QuadPart - |
389 first_audio_frame_timestamp) / 10000.0) * ms_to_frame_count_ + | 398 first_audio_frame_timestamp) / 10000.0) * ms_to_frame_count_ + |
390 buffer_frame_index - num_frames_to_read; | 399 buffer_frame_index - num_frames_to_read; |
391 | 400 |
| 401 // Update the AGC volume level once every second. Note that, |
| 402 // |volume| is also updated each time SetVolume() is called |
| 403 // through IPC by the render-side AGC. |
| 404 QueryAgcVolume(&volume); |
| 405 |
392 // Deliver captured data to the registered consumer using a packet | 406 // Deliver captured data to the registered consumer using a packet |
393 // size which was specified at construction. | 407 // size which was specified at construction. |
394 uint32 delay_frames = static_cast<uint32>(audio_delay_frames + 0.5); | 408 uint32 delay_frames = static_cast<uint32>(audio_delay_frames + 0.5); |
395 while (buffer_frame_index >= packet_size_frames_) { | 409 while (buffer_frame_index >= packet_size_frames_) { |
396 uint8* audio_data = | 410 uint8* audio_data = |
397 reinterpret_cast<uint8*>(capture_buffer.get()); | 411 reinterpret_cast<uint8*>(capture_buffer.get()); |
398 | 412 |
399 // Deliver data packet and delay estimation to the user. | 413 // Deliver data packet, delay estimation and volume level to |
| 414 // the user. |
400 sink_->OnData(this, | 415 sink_->OnData(this, |
401 audio_data, | 416 audio_data, |
402 packet_size_bytes_, | 417 packet_size_bytes_, |
403 delay_frames * frame_size_); | 418 delay_frames * frame_size_, |
| 419 volume); |
404 | 420 |
405 // Store parts of the recorded data which can't be delivered | 421 // Store parts of the recorded data which can't be delivered |
406 // using the current packet size. The stored section will be used | 422 // using the current packet size. The stored section will be used |
407 // either in the next while-loop iteration or in the next | 423 // either in the next while-loop iteration or in the next |
408 // capture event. | 424 // capture event. |
409 memmove(&capture_buffer[0], | 425 memmove(&capture_buffer[0], |
410 &capture_buffer[packet_size_bytes_], | 426 &capture_buffer[packet_size_bytes_], |
411 (buffer_frame_index - packet_size_frames_) * frame_size_); | 427 (buffer_frame_index - packet_size_frames_) * frame_size_); |
412 | 428 |
413 buffer_frame_index -= packet_size_frames_; | 429 buffer_frame_index -= packet_size_frames_; |
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
618 audio_capture_client_.ReceiveVoid()); | 634 audio_capture_client_.ReceiveVoid()); |
619 if (FAILED(hr)) | 635 if (FAILED(hr)) |
620 return hr; | 636 return hr; |
621 | 637 |
622 // Obtain a reference to the ISimpleAudioVolume interface which enables | 638 // Obtain a reference to the ISimpleAudioVolume interface which enables |
623 // us to control the master volume level of an audio session. | 639 // us to control the master volume level of an audio session. |
624 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), | 640 hr = audio_client_->GetService(__uuidof(ISimpleAudioVolume), |
625 simple_audio_volume_.ReceiveVoid()); | 641 simple_audio_volume_.ReceiveVoid()); |
626 return hr; | 642 return hr; |
627 } | 643 } |
OLD | NEW |