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 3 // found in the LICENSE file. 4 5 #include "content/renderer/media/webaudio_capturer_source.h" 6 7 #include "base/logging.h" 8 #include "content/renderer/media/webrtc_audio_capturer.h" 9 10 using media::AudioBus; 11 using media::AudioFifo; 12 using media::AudioParameters; 13 using media::ChannelLayout; 14 using media::CHANNEL_LAYOUT_MONO; 15 using media::CHANNEL_LAYOUT_STEREO; 16 17 static const int kFifoSize = 2048; 18 19 namespace content { 20 21 WebAudioCapturerSource::WebAudioCapturerSource(WebRtcAudioCapturer* capturer) 22 : capturer_(capturer), 23 set_format_channels_(0), 24 callback_(0), 25 started_(false) { 26 } 27 28 WebAudioCapturerSource::~WebAudioCapturerSource() { 29 } 30 31 void WebAudioCapturerSource::setFormat( 32 size_t number_of_channels, float sample_rate) { 33 DVLOG(1) << "WebAudioCapturerSource::setFormat(sample_rate=" 34 << sample_rate << ")"; 35 if (number_of_channels <= 2) { 36 set_format_channels_ = number_of_channels; 37 ChannelLayout channel_layout = 38 number_of_channels == 1 ? CHANNEL_LAYOUT_MONO : CHANNEL_LAYOUT_STEREO; 39 capturer_->SetCapturerSource(this, channel_layout, sample_rate); 40 } else { 41 // TODO(crogers): Handle more than just the mono and stereo cases. 42 LOG(WARNING) << "WebAudioCapturerSource::setFormat() : unhandled format."; 43 } 44 } 45 46 void WebAudioCapturerSource::Initialize( 47 const media::AudioParameters& params, 48 media::AudioCapturerSource::CaptureCallback* callback, 49 int session_id) { 50 // The downstream client should be configured the same as what WebKit 51 // is feeding it. 52 DCHECK_EQ(set_format_channels_, params.channels()); 53 54 base::AutoLock auto_lock(lock_); 55 params_ = params; 56 callback_ = callback; 57 wrapper_bus_ = AudioBus::CreateWrapper(params.channels()); 58 capture_bus_ = AudioBus::Create(params); 59 fifo_.reset(new AudioFifo(params.channels(), kFifoSize)); 60 } 61 62 void WebAudioCapturerSource::Start() { 63 started_ = true; 64 } 65 66 void WebAudioCapturerSource::Stop() { 67 started_ = false; 68 } 69 70 void WebAudioCapturerSource::consumeAudio( 71 const WebKit::WebVector<const float*>& audio_data, 72 size_t number_of_frames) { 73 base::AutoLock auto_lock(lock_); 74 75 if (!callback_) 76 return; 77 78 wrapper_bus_->set_frames(number_of_frames); 79 80 // Make sure WebKit is honoring what it told us up front 81 // about the channels. 82 DCHECK_EQ(set_format_channels_, static_cast<int>(audio_data.size())); 83 DCHECK_EQ(set_format_channels_, wrapper_bus_->channels()); 84 85 for (size_t i = 0; i < audio_data.size(); ++i) 86 wrapper_bus_->SetChannelData(i, const_cast<float*>(audio_data[i])); 87 88 // Handle mismatch between WebAudio buffer-size and WebRTC. 89 int available = fifo_->max_frames() - fifo_->frames(); 90 if (available < static_cast<int>(number_of_frames)) { 91 LOG(ERROR) << "WebAudioCapturerSource::Consume() : FIFO overrun."; 92 return; 93 } 94 95 fifo_->Push(wrapper_bus_.get()); 96 int capture_frames = params_.frames_per_buffer(); 97 while (fifo_->frames() >= capture_frames) { 98 fifo_->Consume(capture_bus_.get(), 0, capture_frames); 99 callback_->Capture(capture_bus_.get(), 0, 1.0); 100 } 101 } 102 103 } // namespace content 104