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

Side by Side Diff: content/renderer/media/webrtc_audio_device_impl.cc

Issue 9702019: Adds Analog Gain Control (AGC) to the WebRTC client. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased 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 "content/renderer/media/webrtc_audio_device_impl.h" 5 #include "content/renderer/media/webrtc_audio_device_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/win/windows_version.h" 9 #include "base/win/windows_version.h"
10 #include "content/renderer/media/audio_hardware.h" 10 #include "content/renderer/media/audio_hardware.h"
11 #include "content/renderer/render_thread_impl.h" 11 #include "content/renderer/render_thread_impl.h"
12 #include "media/audio/audio_util.h" 12 #include "media/audio/audio_util.h"
13 13
14 static const int64 kMillisecondsBetweenProcessCalls = 5000; 14 static const int64 kMillisecondsBetweenProcessCalls = 5000;
15 static const double kMaxVolumeLevel = 255.0;
15 16
16 // Supported hardware sample rates for input and output sides. 17 // Supported hardware sample rates for input and output sides.
17 #if defined(OS_WIN) || defined(OS_MACOSX) 18 #if defined(OS_WIN) || defined(OS_MACOSX)
18 // media::GetAudioInput[Output]HardwareSampleRate() asks the audio layer 19 // media::GetAudioInput[Output]HardwareSampleRate() asks the audio layer
19 // for its current sample rate (set by the user) on Windows and Mac OS X. 20 // for its current sample rate (set by the user) on Windows and Mac OS X.
20 // The listed rates below adds restrictions and WebRtcAudioDeviceImpl::Init() 21 // The listed rates below adds restrictions and WebRtcAudioDeviceImpl::Init()
21 // will fail if the user selects any rate outside these ranges. 22 // will fail if the user selects any rate outside these ranges.
22 static int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000}; 23 static int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000};
23 static int kValidOutputRates[] = {96000, 48000, 44100}; 24 static int kValidOutputRates[] = {96000, 48000, 44100};
24 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 25 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
25 // media::GetAudioInput[Output]HardwareSampleRate() is hardcoded to return 26 // media::GetAudioInput[Output]HardwareSampleRate() is hardcoded to return
26 // 48000 in both directions on Linux. 27 // 48000 in both directions on Linux.
27 static int kValidInputRates[] = {48000}; 28 static int kValidInputRates[] = {48000};
28 static int kValidOutputRates[] = {48000}; 29 static int kValidOutputRates[] = {48000};
29 #endif 30 #endif
30 31
31 WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl() 32 WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()
32 : ref_count_(0), 33 : ref_count_(0),
33 render_loop_(base::MessageLoopProxy::current()), 34 render_loop_(base::MessageLoopProxy::current()),
34 audio_transport_callback_(NULL), 35 audio_transport_callback_(NULL),
35 input_delay_ms_(0), 36 input_delay_ms_(0),
36 output_delay_ms_(0), 37 output_delay_ms_(0),
37 last_error_(AudioDeviceModule::kAdmErrNone), 38 last_error_(AudioDeviceModule::kAdmErrNone),
38 last_process_time_(base::TimeTicks::Now()), 39 last_process_time_(base::TimeTicks::Now()),
39 session_id_(0), 40 session_id_(0),
40 bytes_per_sample_(0), 41 bytes_per_sample_(0),
41 initialized_(false), 42 initialized_(false),
42 playing_(false), 43 playing_(false),
43 recording_(false) { 44 recording_(false),
45 agc_is_enabled_(false) {
44 DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()"; 46 DVLOG(1) << "WebRtcAudioDeviceImpl::WebRtcAudioDeviceImpl()";
45 DCHECK(RenderThreadImpl::current()) << 47 DCHECK(RenderThreadImpl::current()) <<
46 "WebRtcAudioDeviceImpl must be constructed on the render thread"; 48 "WebRtcAudioDeviceImpl must be constructed on the render thread";
47 } 49 }
48 50
49 WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() { 51 WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl() {
50 DVLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()"; 52 DVLOG(1) << "WebRtcAudioDeviceImpl::~WebRtcAudioDeviceImpl()";
51 if (playing_) 53 if (playing_)
52 StopPlayout(); 54 StopPlayout();
53 if (recording_) 55 if (recording_)
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 } 127 }
126 return number_of_frames; 128 return number_of_frames;
127 } 129 }
128 130
129 void WebRtcAudioDeviceImpl::OnRenderError() { 131 void WebRtcAudioDeviceImpl::OnRenderError() {
130 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); 132 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop());
131 // TODO(henrika): Implement error handling. 133 // TODO(henrika): Implement error handling.
132 LOG(ERROR) << "OnRenderError()"; 134 LOG(ERROR) << "OnRenderError()";
133 } 135 }
134 136
135 void WebRtcAudioDeviceImpl::Capture( 137 void WebRtcAudioDeviceImpl::Capture(const std::vector<float*>& audio_data,
136 const std::vector<float*>& audio_data, 138 size_t number_of_frames,
137 size_t number_of_frames, 139 size_t audio_delay_milliseconds,
138 size_t audio_delay_milliseconds) { 140 double volume) {
139 DCHECK_LE(number_of_frames, input_buffer_size()); 141 DCHECK_LE(number_of_frames, input_buffer_size());
142 #if defined(OS_WIN) || defined(OS_MACOSX)
143 DCHECK_LE(volume, 1.0);
144 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
145 // We have a special situation on Linux where the microphone volume can be
146 // "higher than maximum". The input volume slider in the sound preference
147 // allows the user to set a scaling that is higher than 100%. It means that
148 // even if the reported maximum levels is N, the actual microphone level can
149 // go up to 1.5*N and that corresponds to a normalized |volume| of 1.5.
150 DCHECK_LE(volume, 1.5);
151 #endif
140 152
141 int output_delay_ms = 0; 153 int output_delay_ms = 0;
142 { 154 {
143 base::AutoLock auto_lock(lock_); 155 base::AutoLock auto_lock(lock_);
144 // Store the reported audio delay locally. 156 // Store the reported audio delay locally.
145 input_delay_ms_ = audio_delay_milliseconds; 157 input_delay_ms_ = audio_delay_milliseconds;
146 output_delay_ms = output_delay_ms_; 158 output_delay_ms = output_delay_ms_;
147 } 159 }
148 160
149 const int channels = audio_data.size(); 161 const int channels = audio_data.size();
150 DCHECK_LE(channels, input_channels()); 162 DCHECK_LE(channels, input_channels());
151 uint32_t new_mic_level = 0; 163 uint32_t new_mic_level = 0;
152 164
153 // Interleave, scale, and clip input to int16 and store result in 165 // Interleave, scale, and clip input to int16 and store result in
154 // a local byte buffer. 166 // a local byte buffer.
155 media::InterleaveFloatToInt16(audio_data, 167 media::InterleaveFloatToInt16(audio_data,
156 input_buffer_.get(), 168 input_buffer_.get(),
157 number_of_frames); 169 number_of_frames);
158 170
159 int samples_per_sec = input_sample_rate(); 171 int samples_per_sec = input_sample_rate();
160 if (samples_per_sec == 44100) { 172 if (samples_per_sec == 44100) {
161 // Even if the hardware runs at 44.1kHz, we use 44.0 internally. 173 // Even if the hardware runs at 44.1kHz, we use 44.0 internally.
162 samples_per_sec = 44000; 174 samples_per_sec = 44000;
163 } 175 }
164 const int samples_per_10_msec = (samples_per_sec / 100); 176 const int samples_per_10_msec = (samples_per_sec / 100);
165 const int bytes_per_10_msec = 177 const int bytes_per_10_msec =
166 channels * samples_per_10_msec * bytes_per_sample_; 178 channels * samples_per_10_msec * bytes_per_sample_;
167 size_t accumulated_audio_samples = 0; 179 size_t accumulated_audio_samples = 0;
180 char* audio_byte_buffer = reinterpret_cast<char*>(input_buffer_.get());
168 181
169 char* audio_byte_buffer = reinterpret_cast<char*>(input_buffer_.get()); 182 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the
183 // webrtc::VoiceEngine.
184 uint32_t current_mic_level = static_cast<uint32_t>(volume * kMaxVolumeLevel);
170 185
171 // Write audio samples in blocks of 10 milliseconds to the registered 186 // Write audio samples in blocks of 10 milliseconds to the registered
172 // webrtc::AudioTransport sink. Keep writing until our internal byte 187 // webrtc::AudioTransport sink. Keep writing until our internal byte
173 // buffer is empty. 188 // buffer is empty.
174 while (accumulated_audio_samples < number_of_frames) { 189 while (accumulated_audio_samples < number_of_frames) {
175 // Deliver 10ms of recorded PCM audio. 190 // Deliver 10ms of recorded 16-bit linear PCM audio.
176 // TODO(henrika): add support for analog AGC?
177 audio_transport_callback_->RecordedDataIsAvailable( 191 audio_transport_callback_->RecordedDataIsAvailable(
178 audio_byte_buffer, 192 audio_byte_buffer,
179 samples_per_10_msec, 193 samples_per_10_msec,
180 bytes_per_sample_, 194 bytes_per_sample_,
181 channels, 195 channels,
182 samples_per_sec, 196 samples_per_sec,
183 input_delay_ms_ + output_delay_ms, 197 input_delay_ms_ + output_delay_ms,
184 0, // clock_drift 198 0, // TODO(henrika): |clock_drift| parameter is not utilized today.
185 0, // current_mic_level 199 current_mic_level,
186 new_mic_level); // not used 200 new_mic_level);
201
187 accumulated_audio_samples += samples_per_10_msec; 202 accumulated_audio_samples += samples_per_10_msec;
188 audio_byte_buffer += bytes_per_10_msec; 203 audio_byte_buffer += bytes_per_10_msec;
189 } 204 }
205
206 // The AGC returns a non-zero microphone level if it has been decided
207 // that a new level should be set.
208 if (new_mic_level != 0) {
209 // Use IPC and set the new level. Note that, it will take some time
210 // before the new level is effective due to the IPC scheme.
211 // During this time, |current_mic_level| will contain "non-valid" values
212 // and it might reduce the AGC performance. Measurements on Windows 7 have
213 // shown that we might receive old volume levels for one or two callbacks.
214 SetMicrophoneVolume(new_mic_level);
215 }
190 } 216 }
191 217
192 void WebRtcAudioDeviceImpl::OnCaptureError() { 218 void WebRtcAudioDeviceImpl::OnCaptureError() {
193 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); 219 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop());
194 // TODO(henrika): Implement error handling. 220 // TODO(henrika): Implement error handling.
195 LOG(ERROR) << "OnCaptureError()"; 221 LOG(ERROR) << "OnCaptureError()";
196 } 222 }
197 223
198 void WebRtcAudioDeviceImpl::OnDeviceStarted(const std::string& device_id) { 224 void WebRtcAudioDeviceImpl::OnDeviceStarted(const std::string& device_id) {
199 DVLOG(1) << "OnDeviceStarted (device_id=" << device_id << ")"; 225 DVLOG(1) << "OnDeviceStarted (device_id=" << device_id << ")";
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
324 } 350 }
325 351
326 // Ask the browser for the default number of audio input channels. 352 // Ask the browser for the default number of audio input channels.
327 // This request is based on a synchronous IPC message. 353 // This request is based on a synchronous IPC message.
328 ChannelLayout input_channel_layout = 354 ChannelLayout input_channel_layout =
329 audio_hardware::GetInputChannelLayout(); 355 audio_hardware::GetInputChannelLayout();
330 DVLOG(1) << "Audio input hardware channels: " << input_channel_layout; 356 DVLOG(1) << "Audio input hardware channels: " << input_channel_layout;
331 357
332 ChannelLayout out_channel_layout = CHANNEL_LAYOUT_MONO; 358 ChannelLayout out_channel_layout = CHANNEL_LAYOUT_MONO;
333 AudioParameters::Format in_format = AudioParameters::AUDIO_PCM_LINEAR; 359 AudioParameters::Format in_format = AudioParameters::AUDIO_PCM_LINEAR;
334 size_t in_buffer_size = 0; 360 int in_buffer_size = 0;
335 size_t out_buffer_size = 0; 361 int out_buffer_size = 0;
336 362
337 // TODO(henrika): factor out all platform specific parts in separate 363 // TODO(henrika): factor out all platform specific parts in separate
338 // functions. Code is a bit messy right now. 364 // functions. Code is a bit messy right now.
339 365
340 // Windows 366 // Windows
341 #if defined(OS_WIN) 367 #if defined(OS_WIN)
342 // Always use stereo rendering on Windows. 368 // Always use stereo rendering on Windows.
343 out_channel_layout = CHANNEL_LAYOUT_STEREO; 369 out_channel_layout = CHANNEL_LAYOUT_STEREO;
344 370
345 DVLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Windows."; 371 DVLOG(1) << "Using AUDIO_PCM_LOW_LATENCY as input mode on Windows.";
346 in_format = AudioParameters::AUDIO_PCM_LOW_LATENCY; 372 in_format = AudioParameters::AUDIO_PCM_LOW_LATENCY;
347 373
348 // Capture side: AUDIO_PCM_LOW_LATENCY is based on the Core Audio (WASAPI) 374 // Capture side: AUDIO_PCM_LOW_LATENCY is based on the Core Audio (WASAPI)
349 // API which was introduced in Windows Vista. For lower Windows versions, 375 // API which was introduced in Windows Vista. For lower Windows versions,
350 // a callback-driven Wave implementation is used instead. An input buffer 376 // a callback-driven Wave implementation is used instead. An input buffer
351 // size of 10ms works well for both these implementations. 377 // size of 10ms works well for both these implementations.
352 378
353 // Use different buffer sizes depending on the current hardware sample rate. 379 // Use different buffer sizes depending on the current hardware sample rate.
354 if (in_sample_rate == 44100) { 380 if (in_sample_rate == 44100) {
355 // We do run at 44.1kHz at the actual audio layer, but ask for frames 381 // We do run at 44.1kHz at the actual audio layer, but ask for frames
356 // at 44.0kHz to ensure that we can feed them to the webrtc::VoiceEngine. 382 // at 44.0kHz to ensure that we can feed them to the webrtc::VoiceEngine.
357 in_buffer_size = 440; 383 in_buffer_size = 440;
358 } else { 384 } else {
359 in_buffer_size = (in_sample_rate / 100); 385 in_buffer_size = (in_sample_rate / 100);
386 DCHECK_EQ(in_buffer_size * 100, in_sample_rate) <<
387 "Sample rate not supported. Should have been caught in Init().";
360 } 388 }
361 389
362 // Render side: AUDIO_PCM_LOW_LATENCY is based on the Core Audio (WASAPI) 390 // Render side: AUDIO_PCM_LOW_LATENCY is based on the Core Audio (WASAPI)
363 // API which was introduced in Windows Vista. For lower Windows versions, 391 // API which was introduced in Windows Vista. For lower Windows versions,
364 // a callback-driven Wave implementation is used instead. An output buffer 392 // a callback-driven Wave implementation is used instead. An output buffer
365 // size of 10ms works well for WASAPI but 30ms is needed for Wave. 393 // size of 10ms works well for WASAPI but 30ms is needed for Wave.
366 394
367 // Use different buffer sizes depending on the current hardware sample rate. 395 // Use different buffer sizes depending on the current hardware sample rate.
368 if (out_sample_rate == 96000 || out_sample_rate == 48000) { 396 if (out_sample_rate == 96000 || out_sample_rate == 48000) {
369 out_buffer_size = (out_sample_rate / 100); 397 out_buffer_size = (out_sample_rate / 100);
(...skipping 24 matching lines...) Expand all
394 // driven Core Audio implementation. Tests have shown that 10ms is a suitable 422 // driven Core Audio implementation. Tests have shown that 10ms is a suitable
395 // frame size to use, both for 48kHz and 44.1kHz. 423 // frame size to use, both for 48kHz and 44.1kHz.
396 424
397 // Use different buffer sizes depending on the current hardware sample rate. 425 // Use different buffer sizes depending on the current hardware sample rate.
398 if (in_sample_rate == 44100) { 426 if (in_sample_rate == 44100) {
399 // We do run at 44.1kHz at the actual audio layer, but ask for frames 427 // We do run at 44.1kHz at the actual audio layer, but ask for frames
400 // at 44.0kHz to ensure that we can feed them to the webrtc::VoiceEngine. 428 // at 44.0kHz to ensure that we can feed them to the webrtc::VoiceEngine.
401 in_buffer_size = 440; 429 in_buffer_size = 440;
402 } else { 430 } else {
403 in_buffer_size = (in_sample_rate / 100); 431 in_buffer_size = (in_sample_rate / 100);
432 DCHECK_EQ(in_buffer_size * 100, in_sample_rate) <<
433 "Sample rate not supported. Should have been caught in Init().";
404 } 434 }
405 435
406 // Render side: AUDIO_PCM_LOW_LATENCY on Mac OS X is based on a callback- 436 // Render side: AUDIO_PCM_LOW_LATENCY on Mac OS X is based on a callback-
407 // driven Core Audio implementation. Tests have shown that 10ms is a suitable 437 // driven Core Audio implementation. Tests have shown that 10ms is a suitable
408 // frame size to use, both for 48kHz and 44.1kHz. 438 // frame size to use, both for 48kHz and 44.1kHz.
409 439
410 // Use different buffer sizes depending on the current hardware sample rate. 440 // Use different buffer sizes depending on the current hardware sample rate.
411 if (out_sample_rate == 48000) { 441 if (out_sample_rate == 48000) {
412 out_buffer_size = 480; 442 out_buffer_size = 480;
413 } else { 443 } else {
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
587 return 0; 617 return 0;
588 } 618 }
589 619
590 bool WebRtcAudioDeviceImpl::RecordingIsInitialized() const { 620 bool WebRtcAudioDeviceImpl::RecordingIsInitialized() const {
591 DVLOG(1) << "RecordingIsInitialized()"; 621 DVLOG(1) << "RecordingIsInitialized()";
592 return (audio_input_device_ != NULL); 622 return (audio_input_device_ != NULL);
593 } 623 }
594 624
595 int32_t WebRtcAudioDeviceImpl::StartPlayout() { 625 int32_t WebRtcAudioDeviceImpl::StartPlayout() {
596 DVLOG(1) << "StartPlayout()"; 626 DVLOG(1) << "StartPlayout()";
627 LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing";
597 if (!audio_transport_callback_) { 628 if (!audio_transport_callback_) {
598 LOG(ERROR) << "Audio transport is missing";
599 return -1; 629 return -1;
600 } 630 }
601 if (playing_) { 631 if (playing_) {
602 // webrtc::VoiceEngine assumes that it is OK to call Start() twice and 632 // webrtc::VoiceEngine assumes that it is OK to call Start() twice and
603 // that the call is ignored the second time. 633 // that the call is ignored the second time.
604 return 0; 634 return 0;
605 } 635 }
606 audio_output_device_->Start(); 636 audio_output_device_->Start();
607 playing_ = true; 637 playing_ = true;
608 return 0; 638 return 0;
(...skipping 11 matching lines...) Expand all
620 } 650 }
621 651
622 bool WebRtcAudioDeviceImpl::Playing() const { 652 bool WebRtcAudioDeviceImpl::Playing() const {
623 return playing_; 653 return playing_;
624 } 654 }
625 655
626 int32_t WebRtcAudioDeviceImpl::StartRecording() { 656 int32_t WebRtcAudioDeviceImpl::StartRecording() {
627 DVLOG(1) << "StartRecording()"; 657 DVLOG(1) << "StartRecording()";
628 LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing"; 658 LOG_IF(ERROR, !audio_transport_callback_) << "Audio transport is missing";
629 if (!audio_transport_callback_) { 659 if (!audio_transport_callback_) {
630 LOG(ERROR) << "Audio transport is missing";
631 return -1; 660 return -1;
632 } 661 }
633 662
634 if (session_id_ <= 0) { 663 if (session_id_ <= 0) {
635 LOG(WARNING) << session_id_ << " is an invalid session id."; 664 LOG(WARNING) << session_id_ << " is an invalid session id.";
636 // TODO(xians): enable the return -1 when MediaStreamManager can handle 665 // TODO(xians): enable the return -1 when MediaStreamManager can handle
637 // AudioInputDeviceManager. 666 // AudioInputDeviceManager.
638 // return -1; 667 // return -1;
639 } 668 }
640 669
(...skipping 27 matching lines...) Expand all
668 base::AutoLock auto_lock(lock_); 697 base::AutoLock auto_lock(lock_);
669 recording_ = false; 698 recording_ = false;
670 return 0; 699 return 0;
671 } 700 }
672 701
673 bool WebRtcAudioDeviceImpl::Recording() const { 702 bool WebRtcAudioDeviceImpl::Recording() const {
674 return recording_; 703 return recording_;
675 } 704 }
676 705
677 int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) { 706 int32_t WebRtcAudioDeviceImpl::SetAGC(bool enable) {
678 DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::SetAGC() " << "NOT IMPLEMENTED"; 707 DVLOG(1) << "SetAGC(enable=" << enable << ")";
679 return -1; 708 // The current implementation does not support changing the AGC state while
709 // recording. Using this approach simplifies the design and it is also
710 // inline with the latest WebRTC standard.
711 DCHECK(initialized_);
712 DCHECK(!recording_) << "Unable to set AGC state while recording is active.";
713 if (recording_) {
714 return -1;
715 }
716
717 audio_input_device_->SetAutomaticGainControl(enable);
718 agc_is_enabled_ = enable;
719 return 0;
680 } 720 }
681 721
682 bool WebRtcAudioDeviceImpl::AGC() const { 722 bool WebRtcAudioDeviceImpl::AGC() const {
683 DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::AGC() " << "NOT IMPLEMENTED"; 723 // To reduce the usage of IPC messages, an internal AGC state is used.
684 return false; 724 // TODO(henrika): investigate if there is a need for a "deeper" getter.
725 return agc_is_enabled_;
685 } 726 }
686 727
687 int32_t WebRtcAudioDeviceImpl::SetWaveOutVolume(uint16_t volume_left, 728 int32_t WebRtcAudioDeviceImpl::SetWaveOutVolume(uint16_t volume_left,
688 uint16_t volume_right) { 729 uint16_t volume_right) {
689 NOTIMPLEMENTED(); 730 NOTIMPLEMENTED();
690 return -1; 731 return -1;
691 } 732 }
692 int32_t WebRtcAudioDeviceImpl::WaveOutVolume( 733 int32_t WebRtcAudioDeviceImpl::WaveOutVolume(
693 uint16_t* volume_left, 734 uint16_t* volume_left,
694 uint16_t* volume_right) const { 735 uint16_t* volume_right) const {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 int32_t WebRtcAudioDeviceImpl::SpeakerVolume(uint32_t* volume) const { 788 int32_t WebRtcAudioDeviceImpl::SpeakerVolume(uint32_t* volume) const {
748 NOTIMPLEMENTED(); 789 NOTIMPLEMENTED();
749 return -1; 790 return -1;
750 } 791 }
751 792
752 int32_t WebRtcAudioDeviceImpl::MaxSpeakerVolume(uint32_t* max_volume) const { 793 int32_t WebRtcAudioDeviceImpl::MaxSpeakerVolume(uint32_t* max_volume) const {
753 NOTIMPLEMENTED(); 794 NOTIMPLEMENTED();
754 return -1; 795 return -1;
755 } 796 }
756 797
757 int32_t WebRtcAudioDeviceImpl::MinSpeakerVolume( 798 int32_t WebRtcAudioDeviceImpl::MinSpeakerVolume(uint32_t* min_volume) const {
758 uint32_t* min_volume) const {
759 NOTIMPLEMENTED(); 799 NOTIMPLEMENTED();
760 return -1; 800 return -1;
761 } 801 }
762 802
763 int32_t WebRtcAudioDeviceImpl::SpeakerVolumeStepSize( 803 int32_t WebRtcAudioDeviceImpl::SpeakerVolumeStepSize(
764 uint16_t* step_size) const { 804 uint16_t* step_size) const {
765 NOTIMPLEMENTED(); 805 NOTIMPLEMENTED();
766 return -1; 806 return -1;
767 } 807 }
768 808
769 int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeIsAvailable(bool* available) { 809 int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeIsAvailable(bool* available) {
770 NOTIMPLEMENTED(); 810 NOTIMPLEMENTED();
771 return -1; 811 return -1;
772 } 812 }
773 813
774 int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) { 814 int32_t WebRtcAudioDeviceImpl::SetMicrophoneVolume(uint32_t volume) {
775 NOTIMPLEMENTED(); 815 DVLOG(1) << "SetMicrophoneVolume(" << volume << ")";
816 if (volume > kMaxVolumeLevel)
817 return -1;
818
819 // WebRTC uses a range of [0, 255] to represent the level of the microphone
820 // volume. The IPC channel between the renderer and browser process works
821 // with doubles in the [0.0, 1.0] range and we have to compensate for that.
822 double normalized_volume = static_cast<double>(volume / kMaxVolumeLevel);
823 audio_input_device_->SetVolume(normalized_volume);
824 return 0;
825 }
826
827 int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const {
828 // The microphone level is fed to this class using the Capture() callback
829 // and this external API should not be used. Additional IPC messages are
830 // required if support for this API is ever needed.
831 NOTREACHED();
776 return -1; 832 return -1;
777 } 833 }
778 834
779 int32_t WebRtcAudioDeviceImpl::MicrophoneVolume(uint32_t* volume) const { 835 int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume(uint32_t* max_volume) const {
780 NOTIMPLEMENTED(); 836 *max_volume = kMaxVolumeLevel;
781 return -1; 837 return 0;
782 } 838 }
783 839
784 int32_t WebRtcAudioDeviceImpl::MaxMicrophoneVolume( 840 int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(uint32_t* min_volume) const {
785 uint32_t* max_volume) const { 841 *min_volume = 0;
786 DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::MaxMicrophoneVolume() " 842 return 0;
787 << "NOT IMPLEMENTED";
788 return -1;
789 }
790
791 int32_t WebRtcAudioDeviceImpl::MinMicrophoneVolume(
792 uint32_t* min_volume) const {
793 DVLOG(2) << "WARNING: WebRtcAudioDeviceImpl::MinMicrophoneVolume() "
794 << "NOT IMPLEMENTED";
795 return -1;
796 } 843 }
797 844
798 int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeStepSize( 845 int32_t WebRtcAudioDeviceImpl::MicrophoneVolumeStepSize(
799 uint16_t* step_size) const { 846 uint16_t* step_size) const {
800 NOTIMPLEMENTED(); 847 NOTREACHED();
801 return -1; 848 return -1;
802 } 849 }
803 850
804 int32_t WebRtcAudioDeviceImpl::SpeakerMuteIsAvailable(bool* available) { 851 int32_t WebRtcAudioDeviceImpl::SpeakerMuteIsAvailable(bool* available) {
805 NOTIMPLEMENTED(); 852 NOTIMPLEMENTED();
806 return -1; 853 return -1;
807 } 854 }
808 855
809 int32_t WebRtcAudioDeviceImpl::SetSpeakerMute(bool enable) { 856 int32_t WebRtcAudioDeviceImpl::SetSpeakerMute(bool enable) {
810 NOTIMPLEMENTED(); 857 NOTIMPLEMENTED();
(...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after
988 } 1035 }
989 1036
990 int32_t WebRtcAudioDeviceImpl::GetLoudspeakerStatus(bool* enabled) const { 1037 int32_t WebRtcAudioDeviceImpl::GetLoudspeakerStatus(bool* enabled) const {
991 NOTIMPLEMENTED(); 1038 NOTIMPLEMENTED();
992 return -1; 1039 return -1;
993 } 1040 }
994 1041
995 void WebRtcAudioDeviceImpl::SetSessionId(int session_id) { 1042 void WebRtcAudioDeviceImpl::SetSessionId(int session_id) {
996 session_id_ = session_id; 1043 session_id_ = session_id;
997 } 1044 }
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_device_impl.h ('k') | content/renderer/media/webrtc_audio_device_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698