Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: media/audio/win/audio_low_latency_input_win.cc

Issue 9702019: Adds Analog Gain Control (AGC) to the WebRTC client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Improved AGC comments Created 8 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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 = static_cast<double>(GetVolume());
tommi (sloooow) - chröme 2012/03/26 15:26:40 is the cast necessary?
henrika (OOO until Aug 14) 2012/03/27 09:20:38 It should not be needed in float->double. Removed.
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698