| 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/metrics/field_trial.h" | 8 #include "base/metrics/field_trial.h" |
| 9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
| 10 #include "base/trace_event/trace_event.h" | 10 #include "base/trace_event/trace_event.h" |
| (...skipping 11 matching lines...) Expand all Loading... |
| 22 | 22 |
| 23 namespace content { | 23 namespace content { |
| 24 | 24 |
| 25 namespace { | 25 namespace { |
| 26 | 26 |
| 27 using webrtc::AudioProcessing; | 27 using webrtc::AudioProcessing; |
| 28 using webrtc::NoiseSuppression; | 28 using webrtc::NoiseSuppression; |
| 29 | 29 |
| 30 const int kAudioProcessingNumberOfChannels = 1; | 30 const int kAudioProcessingNumberOfChannels = 1; |
| 31 | 31 |
| 32 // Minimum duration of any detectable audio repetition. |
| 33 const int kMinLengthMs = 1; |
| 34 |
| 35 // The following variables defines the look back time of audio repetitions that |
| 36 // will be logged. The complexity of the detector is proportional to the number |
| 37 // of look back times we keep track. |
| 38 const int kMinLookbackTimeMs = 10; |
| 39 const int kMaxLookbackTimeMs = 200; |
| 40 const int kLookbackTimeStepMs = 10; |
| 41 |
| 42 // Maximum frames of any input chunk of audio. Used by |
| 43 // |MediaStreamAudioProcessor::audio_repetition_detector_|. Input longer than |
| 44 // |kMaxFrames| won't cause any problem, and will only affect computational |
| 45 // efficiency. |
| 46 const size_t kMaxFrames = 480; // 10 ms * 48 kHz |
| 47 |
| 48 // Send UMA report on an audio repetition being detected. |look_back_ms| |
| 49 // provides the look back time of the detected repetition. This function is |
| 50 // called back by |MediaStreamAudioProcessor::audio_repetition_detector_|. |
| 51 void ReportRepetition(int look_back_ms) { |
| 52 UMA_HISTOGRAM_CUSTOM_COUNTS( |
| 53 "Media.AudioCapturerRepetition", look_back_ms, |
| 54 kMinLookbackTimeMs, kMaxLookbackTimeMs, |
| 55 (kMaxLookbackTimeMs - kMinLookbackTimeMs) / kLookbackTimeStepMs + 1); |
| 56 } |
| 57 |
| 32 AudioProcessing::ChannelLayout MapLayout(media::ChannelLayout media_layout) { | 58 AudioProcessing::ChannelLayout MapLayout(media::ChannelLayout media_layout) { |
| 33 switch (media_layout) { | 59 switch (media_layout) { |
| 34 case media::CHANNEL_LAYOUT_MONO: | 60 case media::CHANNEL_LAYOUT_MONO: |
| 35 return AudioProcessing::kMono; | 61 return AudioProcessing::kMono; |
| 36 case media::CHANNEL_LAYOUT_STEREO: | 62 case media::CHANNEL_LAYOUT_STEREO: |
| 37 return AudioProcessing::kStereo; | 63 return AudioProcessing::kStereo; |
| 38 case media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC: | 64 case media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC: |
| 39 return AudioProcessing::kStereoAndKeyboard; | 65 return AudioProcessing::kStereoAndKeyboard; |
| 40 default: | 66 default: |
| 41 NOTREACHED() << "Layout not supported: " << media_layout; | 67 NOTREACHED() << "Layout not supported: " << media_layout; |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 244 capture_thread_checker_.DetachFromThread(); | 270 capture_thread_checker_.DetachFromThread(); |
| 245 render_thread_checker_.DetachFromThread(); | 271 render_thread_checker_.DetachFromThread(); |
| 246 InitializeAudioProcessingModule(constraints, input_params); | 272 InitializeAudioProcessingModule(constraints, input_params); |
| 247 | 273 |
| 248 aec_dump_message_filter_ = AecDumpMessageFilter::Get(); | 274 aec_dump_message_filter_ = AecDumpMessageFilter::Get(); |
| 249 // In unit tests not creating a message filter, |aec_dump_message_filter_| | 275 // In unit tests not creating a message filter, |aec_dump_message_filter_| |
| 250 // will be NULL. We can just ignore that. Other unit tests and browser tests | 276 // will be NULL. We can just ignore that. Other unit tests and browser tests |
| 251 // ensure that we do get the filter when we should. | 277 // ensure that we do get the filter when we should. |
| 252 if (aec_dump_message_filter_.get()) | 278 if (aec_dump_message_filter_.get()) |
| 253 aec_dump_message_filter_->AddDelegate(this); | 279 aec_dump_message_filter_->AddDelegate(this); |
| 280 |
| 281 // Create and configure |audio_repetition_detector_|. |
| 282 std::vector<int> look_back_times; |
| 283 for (int time = kMaxLookbackTimeMs; time >= kMinLookbackTimeMs; |
| 284 time -= kLookbackTimeStepMs) { |
| 285 look_back_times.push_back(time); |
| 286 } |
| 287 audio_repetition_detector_.reset( |
| 288 new AudioRepetitionDetector(kMinLengthMs, kMaxFrames, look_back_times, |
| 289 base::Bind(&ReportRepetition))); |
| 254 } | 290 } |
| 255 | 291 |
| 256 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { | 292 MediaStreamAudioProcessor::~MediaStreamAudioProcessor() { |
| 257 DCHECK(main_thread_checker_.CalledOnValidThread()); | 293 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| 258 Stop(); | 294 Stop(); |
| 259 } | 295 } |
| 260 | 296 |
| 261 void MediaStreamAudioProcessor::OnCaptureFormatChanged( | 297 void MediaStreamAudioProcessor::OnCaptureFormatChanged( |
| 262 const media::AudioParameters& input_format) { | 298 const media::AudioParameters& input_format) { |
| 263 DCHECK(main_thread_checker_.CalledOnValidThread()); | 299 DCHECK(main_thread_checker_.CalledOnValidThread()); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 289 DCHECK(processed_data); | 325 DCHECK(processed_data); |
| 290 DCHECK(capture_delay); | 326 DCHECK(capture_delay); |
| 291 DCHECK(new_volume); | 327 DCHECK(new_volume); |
| 292 | 328 |
| 293 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::ProcessAndConsumeData"); | 329 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::ProcessAndConsumeData"); |
| 294 | 330 |
| 295 MediaStreamAudioBus* process_bus; | 331 MediaStreamAudioBus* process_bus; |
| 296 if (!capture_fifo_->Consume(&process_bus, capture_delay)) | 332 if (!capture_fifo_->Consume(&process_bus, capture_delay)) |
| 297 return false; | 333 return false; |
| 298 | 334 |
| 335 // Detect bit-exact repetition of audio present in the captured audio. |
| 336 // We detect only one channel. |
| 337 audio_repetition_detector_->Detect(process_bus->bus()->channel(0), |
| 338 process_bus->bus()->frames(), |
| 339 1, // number of channels |
| 340 input_format_.sample_rate()); |
| 341 |
| 299 // Use the process bus directly if audio processing is disabled. | 342 // Use the process bus directly if audio processing is disabled. |
| 300 MediaStreamAudioBus* output_bus = process_bus; | 343 MediaStreamAudioBus* output_bus = process_bus; |
| 301 *new_volume = 0; | 344 *new_volume = 0; |
| 302 if (audio_processing_) { | 345 if (audio_processing_) { |
| 303 output_bus = output_bus_.get(); | 346 output_bus = output_bus_.get(); |
| 304 *new_volume = ProcessData(process_bus->channel_ptrs(), | 347 *new_volume = ProcessData(process_bus->channel_ptrs(), |
| 305 process_bus->bus()->frames(), *capture_delay, | 348 process_bus->bus()->frames(), *capture_delay, |
| 306 volume, key_pressed, output_bus->channel_ptrs()); | 349 volume, key_pressed, output_bus->channel_ptrs()); |
| 307 } | 350 } |
| 308 | 351 |
| (...skipping 369 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 678 if (echo_information_) { | 721 if (echo_information_) { |
| 679 echo_information_.get()->UpdateAecDelayStats(ap->echo_cancellation()); | 722 echo_information_.get()->UpdateAecDelayStats(ap->echo_cancellation()); |
| 680 } | 723 } |
| 681 | 724 |
| 682 // Return 0 if the volume hasn't been changed, and otherwise the new volume. | 725 // Return 0 if the volume hasn't been changed, and otherwise the new volume. |
| 683 return (agc->stream_analog_level() == volume) ? | 726 return (agc->stream_analog_level() == volume) ? |
| 684 0 : agc->stream_analog_level(); | 727 0 : agc->stream_analog_level(); |
| 685 } | 728 } |
| 686 | 729 |
| 687 } // namespace content | 730 } // namespace content |
| OLD | NEW |