Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 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/media_stream_audio_processor.h" | 5 #include "content/renderer/media/media_stream_audio_processor.h" |
| 6 | 6 |
| 7 #include "base/command_line.h" | 7 #include "base/command_line.h" |
| 8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
| 9 #include "content/public/common/content_switches.h" | 9 #include "content/public/common/content_switches.h" |
| 10 #include "content/renderer/media/media_stream_audio_processor_options.h" | 10 #include "content/renderer/media/media_stream_audio_processor_options.h" |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 134 // TODO(xians): consider using SincResampler to save some memcpy. | 134 // TODO(xians): consider using SincResampler to save some memcpy. |
| 135 // Handles mixing and resampling between input and output parameters. | 135 // Handles mixing and resampling between input and output parameters. |
| 136 media::AudioConverter audio_converter_; | 136 media::AudioConverter audio_converter_; |
| 137 scoped_ptr<media::AudioBus> audio_wrapper_; | 137 scoped_ptr<media::AudioBus> audio_wrapper_; |
| 138 scoped_ptr<media::AudioFifo> fifo_; | 138 scoped_ptr<media::AudioFifo> fifo_; |
| 139 }; | 139 }; |
| 140 | 140 |
| 141 MediaStreamAudioProcessor::MediaStreamAudioProcessor( | 141 MediaStreamAudioProcessor::MediaStreamAudioProcessor( |
| 142 const media::AudioParameters& source_params, | 142 const media::AudioParameters& source_params, |
| 143 const blink::WebMediaConstraints& constraints, | 143 const blink::WebMediaConstraints& constraints, |
| 144 int effects) | 144 int effects, |
| 145 WebRtcPlayoutDataSource* playout_data_source) | |
| 145 : render_delay_ms_(0), | 146 : render_delay_ms_(0), |
| 147 playout_data_source_(playout_data_source), | |
| 146 audio_mirroring_(false) { | 148 audio_mirroring_(false) { |
| 147 capture_thread_checker_.DetachFromThread(); | 149 capture_thread_checker_.DetachFromThread(); |
| 148 render_thread_checker_.DetachFromThread(); | 150 render_thread_checker_.DetachFromThread(); |
| 149 InitializeAudioProcessingModule(constraints, effects); | 151 InitializeAudioProcessingModule(constraints, effects); |
| 150 InitializeCaptureConverter(source_params); | 152 InitializeCaptureConverter(source_params); |
| 151 } | 153 } |
| 152 | 154 |
| 153 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { | 155 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { |
| 154 DCHECK(main_thread_checker_.CalledOnValidThread()); | |
|
tommi (sloooow) - chröme
2014/02/06 16:47:01
why removing?
(it seems like a good thing to make
no longer working on chromium
2014/02/06 17:20:14
MediaStreamAudioProcessor is reference counted, an
tommi (sloooow) - chröme
2014/02/06 17:58:44
Can we move construction to the audio thread then
no longer working on chromium
2014/02/17 13:27:28
WebRtcAudioCapturer today creates/deletes its reso
| |
| 155 StopAudioProcessing(); | 156 StopAudioProcessing(); |
| 156 } | 157 } |
| 157 | 158 |
| 158 void MediaStreamAudioProcessor::PushCaptureData(media::AudioBus* audio_source) { | 159 void MediaStreamAudioProcessor::PushCaptureData(media::AudioBus* audio_source) { |
| 159 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 160 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| 160 capture_converter_->Push(audio_source); | 161 capture_converter_->Push(audio_source); |
| 161 } | 162 } |
| 162 | 163 |
| 163 void MediaStreamAudioProcessor::PushRenderData( | |
| 164 const int16* render_audio, int sample_rate, int number_of_channels, | |
| 165 int number_of_frames, base::TimeDelta render_delay) { | |
| 166 DCHECK(render_thread_checker_.CalledOnValidThread()); | |
| 167 | |
| 168 // Return immediately if the echo cancellation is off. | |
| 169 if (!audio_processing_ || | |
| 170 !audio_processing_->echo_cancellation()->is_enabled()) { | |
| 171 return; | |
| 172 } | |
| 173 | |
| 174 TRACE_EVENT0("audio", | |
| 175 "MediaStreamAudioProcessor::FeedRenderDataToAudioProcessing"); | |
| 176 int64 new_render_delay_ms = render_delay.InMilliseconds(); | |
| 177 DCHECK_LT(new_render_delay_ms, | |
| 178 std::numeric_limits<base::subtle::Atomic32>::max()); | |
| 179 base::subtle::Release_Store(&render_delay_ms_, new_render_delay_ms); | |
| 180 | |
| 181 InitializeRenderConverterIfNeeded(sample_rate, number_of_channels, | |
| 182 number_of_frames); | |
| 183 | |
| 184 // TODO(xians): Avoid this extra interleave/deinterleave. | |
| 185 render_data_bus_->FromInterleaved(render_audio, | |
| 186 render_data_bus_->frames(), | |
| 187 sizeof(render_audio[0])); | |
| 188 render_converter_->Push(render_data_bus_.get()); | |
| 189 while (render_converter_->Convert(&render_frame_)) | |
| 190 audio_processing_->AnalyzeReverseStream(&render_frame_); | |
| 191 } | |
| 192 | |
| 193 bool MediaStreamAudioProcessor::ProcessAndConsumeData( | 164 bool MediaStreamAudioProcessor::ProcessAndConsumeData( |
| 194 base::TimeDelta capture_delay, int volume, bool key_pressed, | 165 base::TimeDelta capture_delay, int volume, bool key_pressed, |
| 195 int* new_volume, int16** out) { | 166 int* new_volume, int16** out) { |
| 196 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 167 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| 197 TRACE_EVENT0("audio", | 168 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::ProcessAndConsumeData"); |
| 198 "MediaStreamAudioProcessor::ProcessAndConsumeData"); | |
| 199 | 169 |
| 200 if (!capture_converter_->Convert(&capture_frame_)) | 170 if (!capture_converter_->Convert(&capture_frame_)) |
| 201 return false; | 171 return false; |
| 202 | 172 |
| 203 *new_volume = ProcessData(&capture_frame_, capture_delay, volume, | 173 *new_volume = ProcessData(&capture_frame_, capture_delay, volume, |
| 204 key_pressed); | 174 key_pressed); |
| 205 *out = capture_frame_.data_; | 175 *out = capture_frame_.data_; |
| 206 | 176 |
| 207 return true; | 177 return true; |
| 208 } | 178 } |
| 209 | 179 |
| 210 const media::AudioParameters& MediaStreamAudioProcessor::InputFormat() const { | 180 const media::AudioParameters& MediaStreamAudioProcessor::InputFormat() const { |
| 211 return capture_converter_->source_parameters(); | 181 return capture_converter_->source_parameters(); |
| 212 } | 182 } |
| 213 | 183 |
| 214 const media::AudioParameters& MediaStreamAudioProcessor::OutputFormat() const { | 184 const media::AudioParameters& MediaStreamAudioProcessor::OutputFormat() const { |
| 215 return capture_converter_->sink_parameters(); | 185 return capture_converter_->sink_parameters(); |
| 216 } | 186 } |
| 217 | 187 |
| 188 void MediaStreamAudioProcessor::OnPlayoutData(media::AudioBus* audio_bus, | |
| 189 int sample_rate, | |
| 190 int audio_delay_milliseconds) { | |
| 191 DCHECK(render_thread_checker_.CalledOnValidThread()); | |
| 192 DCHECK(audio_processing_->echo_cancellation()->is_enabled()); | |
|
tommi (sloooow) - chröme
2014/02/06 16:47:01
is this correct? will we only ever get this callb
no longer working on chromium
2014/02/06 17:20:14
the playout data is only needed when AEC is enable
tommi (sloooow) - chröme
2014/02/06 17:58:44
OK, cool.
| |
| 193 | |
| 194 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::OnPlayoutData"); | |
| 195 DCHECK_LT(audio_delay_milliseconds, | |
| 196 std::numeric_limits<base::subtle::Atomic32>::max()); | |
| 197 base::subtle::Release_Store(&render_delay_ms_, audio_delay_milliseconds); | |
| 198 | |
| 199 InitializeRenderConverterIfNeeded(sample_rate, audio_bus->channels(), | |
| 200 audio_bus->frames()); | |
| 201 | |
| 202 render_converter_->Push(audio_bus); | |
| 203 while (render_converter_->Convert(&render_frame_)) | |
| 204 audio_processing_->AnalyzeReverseStream(&render_frame_); | |
| 205 } | |
| 206 | |
| 218 void MediaStreamAudioProcessor::InitializeAudioProcessingModule( | 207 void MediaStreamAudioProcessor::InitializeAudioProcessingModule( |
| 219 const blink::WebMediaConstraints& constraints, int effects) { | 208 const blink::WebMediaConstraints& constraints, int effects) { |
| 220 DCHECK(!audio_processing_); | 209 DCHECK(!audio_processing_); |
| 221 if (!CommandLine::ForCurrentProcess()->HasSwitch( | 210 if (!CommandLine::ForCurrentProcess()->HasSwitch( |
| 222 switches::kEnableAudioTrackProcessing)) { | 211 switches::kEnableAudioTrackProcessing)) { |
| 223 return; | 212 return; |
| 224 } | 213 } |
| 225 | 214 |
| 226 RTCMediaConstraints native_constraints(constraints); | 215 RTCMediaConstraints native_constraints(constraints); |
| 227 ApplyFixedAudioConstraints(&native_constraints); | 216 ApplyFixedAudioConstraints(&native_constraints); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 269 } | 258 } |
| 270 | 259 |
| 271 // Create and configure the webrtc::AudioProcessing. | 260 // Create and configure the webrtc::AudioProcessing. |
| 272 audio_processing_.reset(webrtc::AudioProcessing::Create(0)); | 261 audio_processing_.reset(webrtc::AudioProcessing::Create(0)); |
| 273 | 262 |
| 274 // Enable the audio processing components. | 263 // Enable the audio processing components. |
| 275 if (enable_aec) { | 264 if (enable_aec) { |
| 276 EnableEchoCancellation(audio_processing_.get()); | 265 EnableEchoCancellation(audio_processing_.get()); |
| 277 if (enable_experimental_aec) | 266 if (enable_experimental_aec) |
| 278 EnableExperimentalEchoCancellation(audio_processing_.get()); | 267 EnableExperimentalEchoCancellation(audio_processing_.get()); |
| 268 | |
| 269 if (playout_data_source_) | |
| 270 playout_data_source_->AddPlayoutSink(this); | |
| 279 } | 271 } |
| 280 | 272 |
| 281 if (enable_ns) | 273 if (enable_ns) |
| 282 EnableNoiseSuppression(audio_processing_.get()); | 274 EnableNoiseSuppression(audio_processing_.get()); |
| 283 | 275 |
| 284 if (enable_high_pass_filter) | 276 if (enable_high_pass_filter) |
| 285 EnableHighPassFilter(audio_processing_.get()); | 277 EnableHighPassFilter(audio_processing_.get()); |
| 286 | 278 |
| 287 if (enable_typing_detection) | 279 if (enable_typing_detection) |
| 288 EnableTypingDetection(audio_processing_.get()); | 280 EnableTypingDetection(audio_processing_.get()); |
| (...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 401 // Return 0 if the volume has not been changed, otherwise return the new | 393 // Return 0 if the volume has not been changed, otherwise return the new |
| 402 // volume. | 394 // volume. |
| 403 return (agc->stream_analog_level() == volume) ? | 395 return (agc->stream_analog_level() == volume) ? |
| 404 0 : agc->stream_analog_level(); | 396 0 : agc->stream_analog_level(); |
| 405 } | 397 } |
| 406 | 398 |
| 407 void MediaStreamAudioProcessor::StopAudioProcessing() { | 399 void MediaStreamAudioProcessor::StopAudioProcessing() { |
| 408 if (!audio_processing_.get()) | 400 if (!audio_processing_.get()) |
| 409 return; | 401 return; |
| 410 | 402 |
| 403 if (playout_data_source_) | |
| 404 playout_data_source_->RemovePlayoutSink(this); | |
| 405 | |
| 411 audio_processing_.reset(); | 406 audio_processing_.reset(); |
| 412 } | 407 } |
| 413 | 408 |
| 414 } // namespace content | 409 } // namespace content |
| OLD | NEW |