Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2013 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/webrtc_local_audio_source_provider.h" | |
| 6 | |
| 7 #include "base/logging.h" | |
| 8 #include "content/renderer/render_thread_impl.h" | |
| 9 #include "media/audio/audio_parameters.h" | |
| 10 #include "media/base/audio_fifo.h" | |
| 11 #include "media/base/audio_hardware_config.h" | |
| 12 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h" | |
| 13 | |
| 14 using WebKit::WebVector; | |
| 15 | |
| 16 namespace content { | |
| 17 | |
| 18 static const size_t kMaxNumberOfBuffer = 10; | |
| 19 static const size_t kWebAudioRenderBufferSize = 128; | |
| 20 | |
| 21 WebRtcLocalAudioSourceProvider::WebRtcLocalAudioSourceProvider() | |
| 22 : audio_delay_ms_(0), | |
| 23 volume_(1), | |
| 24 key_pressed_(false), | |
| 25 is_enabled_(false), | |
| 26 use_sink_params_for_testing_(false) { | |
|
tommi (sloooow) - chröme
2013/09/10 16:00:38
I don't like mixing test code and production code
no longer working on chromium
2013/09/11 10:22:07
How about now?
| |
| 27 } | |
| 28 | |
| 29 WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() { | |
| 30 if (audio_converter_.get()) | |
| 31 audio_converter_->RemoveInput(this); | |
| 32 } | |
| 33 | |
| 34 void WebRtcLocalAudioSourceProvider::Initialize( | |
| 35 const media::AudioParameters& source_params) { | |
| 36 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 37 if (!use_sink_params_for_testing_) { | |
| 38 // Use the native audio output hardware sample-rate for the sink. | |
| 39 media::AudioHardwareConfig* hardware_config = | |
| 40 RenderThreadImpl::current()->GetAudioHardwareConfig(); | |
| 41 int sample_rate = hardware_config->GetOutputSampleRate(); | |
| 42 sink_params_.Reset( | |
| 43 source_params.format(), media::CHANNEL_LAYOUT_STEREO, 2, 0, | |
| 44 sample_rate, source_params.bits_per_sample(), | |
| 45 kWebAudioRenderBufferSize); | |
| 46 } | |
| 47 | |
| 48 base::AutoLock auto_lock(lock_); | |
| 49 source_params_ = source_params; | |
| 50 // Create the audio converter with |disable_fifo| as false so that the | |
| 51 // converter will request source_params.frames_per_buffer() each time. | |
| 52 // This will not increase the complexity as there is only one client to | |
| 53 // the converter. | |
| 54 audio_converter_.reset( | |
| 55 new media::AudioConverter(source_params, sink_params_, false)); | |
| 56 audio_converter_->AddInput(this); | |
| 57 fifo_.reset(new media::AudioFifo( | |
| 58 source_params.channels(), | |
| 59 kMaxNumberOfBuffer * source_params.frames_per_buffer())); | |
| 60 } | |
| 61 | |
| 62 void WebRtcLocalAudioSourceProvider::DeliverData( | |
| 63 media::AudioBus* audio_source, | |
| 64 int audio_delay_milliseconds, | |
| 65 int volume, | |
| 66 bool key_pressed) { | |
| 67 base::AutoLock auto_lock(lock_); | |
| 68 if (!is_enabled_) | |
| 69 return; | |
| 70 | |
| 71 DCHECK(fifo_.get()); | |
| 72 | |
| 73 if (fifo_->frames() + audio_source->frames() <= fifo_->max_frames()) { | |
| 74 fifo_->Push(audio_source); | |
| 75 } else { | |
| 76 // This can happen if the data in FIFO is too slowed to be consumed or | |
| 77 // WebAudio stops consuming data. | |
| 78 DLOG(WARNING) << "Local source provicer FIFO is full" << fifo_->frames(); | |
| 79 } | |
| 80 | |
| 81 // Cache the values for GetAudioProcessingParams(). | |
| 82 last_fill_ = base::TimeTicks::Now(); | |
| 83 audio_delay_ms_ = audio_delay_milliseconds; | |
| 84 volume_ = volume; | |
| 85 key_pressed_ = key_pressed; | |
| 86 } | |
| 87 | |
| 88 void WebRtcLocalAudioSourceProvider::GetAudioProcessingParams( | |
| 89 int* delay_ms, int* volume, bool* key_pressed) { | |
| 90 int elapsed_ms = 0; | |
| 91 if (!last_fill_.is_null()) { | |
| 92 elapsed_ms = static_cast<int>( | |
| 93 (base::TimeTicks::Now() - last_fill_).InMilliseconds()); | |
| 94 } | |
| 95 *delay_ms = audio_delay_ms_ + elapsed_ms + static_cast<int>( | |
| 96 1000 * fifo_->frames() / source_params_.sample_rate() + 0.5); | |
| 97 *volume = volume_; | |
| 98 *key_pressed = key_pressed_; | |
| 99 } | |
| 100 | |
| 101 void WebRtcLocalAudioSourceProvider::setClient( | |
| 102 WebKit::WebAudioSourceProviderClient* client) { | |
| 103 NOTIMPLEMENTED(); | |
| 104 } | |
| 105 | |
| 106 void WebRtcLocalAudioSourceProvider::provideInput( | |
| 107 const WebVector<float*>& audio_data, size_t number_of_frames) { | |
| 108 DCHECK_EQ(number_of_frames, kWebAudioRenderBufferSize); | |
| 109 if (!bus_wrapper_ || | |
| 110 static_cast<size_t>(bus_wrapper_->channels()) != audio_data.size()) { | |
| 111 bus_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size()); | |
| 112 } | |
| 113 | |
| 114 bus_wrapper_->set_frames(number_of_frames); | |
| 115 for (size_t i = 0; i < audio_data.size(); ++i) | |
| 116 bus_wrapper_->SetChannelData(i, audio_data[i]); | |
| 117 | |
| 118 base::AutoLock auto_lock(lock_); | |
| 119 DCHECK(audio_converter_.get()); | |
| 120 DCHECK(fifo_.get()); | |
| 121 is_enabled_ = true; | |
| 122 audio_converter_->Convert(bus_wrapper_.get()); | |
| 123 } | |
| 124 | |
| 125 double WebRtcLocalAudioSourceProvider::ProvideInput( | |
| 126 media::AudioBus* audio_bus, base::TimeDelta buffer_delay) { | |
| 127 if (fifo_->frames() >= audio_bus->frames()) { | |
| 128 fifo_->Consume(audio_bus, 0, audio_bus->frames()); | |
| 129 } else { | |
| 130 audio_bus->Zero(); | |
| 131 if (!last_fill_.is_null()) { | |
| 132 DLOG(WARNING) << "Underrun, FIFO has data " << fifo_->frames() | |
| 133 << " samples but " << audio_bus->frames() | |
| 134 << " samples are needed"; | |
| 135 } | |
| 136 } | |
| 137 | |
| 138 return 1.0; | |
| 139 } | |
| 140 | |
| 141 void WebRtcLocalAudioSourceProvider::SetSinkParamsForTesting( | |
| 142 const media::AudioParameters& sink_params) { | |
| 143 DCHECK(thread_checker_.CalledOnValidThread()); | |
| 144 sink_params_ = sink_params; | |
| 145 use_sink_params_for_testing_ = true; | |
| 146 } | |
| 147 | |
| 148 } // namespace content | |
| OLD | NEW |