| Index: webrtc/modules/audio_processing/audio_processing_impl.cc | 
| diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| index 87b82a6a3509131adae9ed698cc0f896fd01d4c0..cdc5b041ed5deb6b853424be51b44cd76723fa94 100644 | 
| --- a/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| +++ b/webrtc/modules/audio_processing/audio_processing_impl.cc | 
| @@ -28,6 +28,7 @@ extern "C" { | 
| #include "webrtc/modules/audio_processing/echo_control_mobile_impl.h" | 
| #include "webrtc/modules/audio_processing/gain_control_impl.h" | 
| #include "webrtc/modules/audio_processing/high_pass_filter_impl.h" | 
| +#include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h" | 
| #include "webrtc/modules/audio_processing/level_estimator_impl.h" | 
| #include "webrtc/modules/audio_processing/noise_suppression_impl.h" | 
| #include "webrtc/modules/audio_processing/processing_component.h" | 
| @@ -195,7 +196,8 @@ AudioProcessingImpl::AudioProcessingImpl(const Config& config, | 
| beamformer_enabled_(config.Get<Beamforming>().enabled), | 
| beamformer_(beamformer), | 
| array_geometry_(config.Get<Beamforming>().array_geometry), | 
| -      supports_48kHz_(config.Get<AudioProcessing48kHzSupport>().enabled) { | 
| +      supports_48kHz_(config.Get<AudioProcessing48kHzSupport>().enabled), | 
| +      intelligibility_enabled_(config.Get<Intelligibility>().enabled) { | 
| echo_cancellation_ = new EchoCancellationImpl(this, crit_); | 
| component_list_.push_back(echo_cancellation_); | 
|  | 
| @@ -305,6 +307,8 @@ int AudioProcessingImpl::InitializeLocked() { | 
|  | 
| InitializeBeamformer(); | 
|  | 
| +  InitializeIntelligibility(); | 
| + | 
| #ifdef WEBRTC_AUDIOPROC_DEBUG_DUMP | 
| if (debug_file_->Open()) { | 
| int err = WriteInitMessage(); | 
| @@ -599,6 +603,7 @@ int AudioProcessingImpl::ProcessStreamLocked() { | 
| MaybeUpdateHistograms(); | 
|  | 
| AudioBuffer* ca = capture_audio_.get();  // For brevity. | 
| + | 
| if (use_new_agc_ && gain_control_->is_enabled()) { | 
| agc_manager_->AnalyzePreProcess(ca->channels()[0], | 
| ca->num_channels(), | 
| @@ -610,6 +615,11 @@ int AudioProcessingImpl::ProcessStreamLocked() { | 
| ca->SplitIntoFrequencyBands(); | 
| } | 
|  | 
| +  if (intelligibility_enabled_) { | 
| +    intelligibility_enhancer_->AnalyzeCaptureAudio( | 
| +        ca->split_channels_f(kBand0To8kHz), split_rate_, ca->num_channels()); | 
| +  } | 
| + | 
| if (beamformer_enabled_) { | 
| beamformer_->ProcessChunk(*ca->split_data_f(), ca->split_data_f()); | 
| ca->set_num_channels(1); | 
| @@ -664,9 +674,22 @@ int AudioProcessingImpl::ProcessStreamLocked() { | 
| return kNoError; | 
| } | 
|  | 
| +int AudioProcessingImpl::ProcessReverseStream(float* const* data, | 
| +                                              int samples_per_channel, | 
| +                                              int rev_sample_rate_hz, | 
| +                                              ChannelLayout layout) { | 
| +  RETURN_ON_ERR(AnalyzeReverseStream(data, samples_per_channel, | 
| +                                     rev_sample_rate_hz, layout)); | 
| +  if (intelligibility_enabled_) { | 
| +    render_audio_->CopyTo(samples_per_channel, layout, data); | 
| +  } | 
| + | 
| +  return kNoError; | 
| +} | 
| + | 
| int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, | 
| int samples_per_channel, | 
| -                                              int sample_rate_hz, | 
| +                                              int rev_sample_rate_hz, | 
| ChannelLayout layout) { | 
| CriticalSectionScoped crit_scoped(crit_); | 
| if (data == NULL) { | 
| @@ -674,12 +697,10 @@ int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, | 
| } | 
|  | 
| const int num_channels = ChannelsFromLayout(layout); | 
| -  RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(), | 
| -                                      fwd_out_format_.rate(), | 
| -                                      sample_rate_hz, | 
| -                                      fwd_in_format_.num_channels(), | 
| -                                      fwd_out_format_.num_channels(), | 
| -                                      num_channels)); | 
| +  RETURN_ON_ERR( | 
| +      MaybeInitializeLocked(fwd_in_format_.rate(), fwd_out_format_.rate(), | 
| +                            rev_sample_rate_hz, fwd_in_format_.num_channels(), | 
| +                            fwd_out_format_.num_channels(), num_channels)); | 
| if (samples_per_channel != rev_in_format_.samples_per_channel()) { | 
| return kBadDataLengthError; | 
| } | 
| @@ -697,7 +718,7 @@ int AudioProcessingImpl::AnalyzeReverseStream(const float* const* data, | 
| #endif | 
|  | 
| render_audio_->CopyFrom(data, samples_per_channel, layout); | 
| -  return AnalyzeReverseStreamLocked(); | 
| +  return ProcessReverseStreamLocked(); | 
| } | 
|  | 
| int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { | 
| @@ -716,7 +737,6 @@ int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { | 
| if (frame->sample_rate_hz_ != fwd_in_format_.rate()) { | 
| return kBadSampleRateError; | 
| } | 
| - | 
| RETURN_ON_ERR(MaybeInitializeLocked(fwd_in_format_.rate(), | 
| fwd_out_format_.rate(), | 
| frame->sample_rate_hz_, | 
| @@ -738,23 +758,34 @@ int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { | 
| RETURN_ON_ERR(WriteMessageToDebugFile()); | 
| } | 
| #endif | 
| - | 
| render_audio_->DeinterleaveFrom(frame); | 
| -  return AnalyzeReverseStreamLocked(); | 
| +  RETURN_ON_ERR(ProcessReverseStreamLocked()); | 
| +  render_audio_->InterleaveTo(frame, intelligibility_enabled_); | 
| + | 
| +  return kNoError; | 
| } | 
|  | 
| -int AudioProcessingImpl::AnalyzeReverseStreamLocked() { | 
| +int AudioProcessingImpl::ProcessReverseStreamLocked() { | 
| AudioBuffer* ra = render_audio_.get();  // For brevity. | 
| if (rev_proc_format_.rate() == kSampleRate32kHz) { | 
| ra->SplitIntoFrequencyBands(); | 
| } | 
|  | 
| +  if (intelligibility_enabled_) { | 
| +    intelligibility_enhancer_->ProcessRenderAudio( | 
| +        ra->split_channels_f(kBand0To8kHz), split_rate_, ra->num_channels()); | 
| +  } | 
| + | 
| RETURN_ON_ERR(echo_cancellation_->ProcessRenderAudio(ra)); | 
| RETURN_ON_ERR(echo_control_mobile_->ProcessRenderAudio(ra)); | 
| if (!use_new_agc_) { | 
| RETURN_ON_ERR(gain_control_->ProcessRenderAudio(ra)); | 
| } | 
|  | 
| +  if (rev_proc_format_.rate() == kSampleRate32kHz) { | 
| +    ra->MergeFrequencyBands(); | 
| +  } | 
| + | 
| return kNoError; | 
| } | 
|  | 
| @@ -1001,6 +1032,16 @@ void AudioProcessingImpl::InitializeBeamformer() { | 
| } | 
| } | 
|  | 
| +void AudioProcessingImpl::InitializeIntelligibility() { | 
| +  if (intelligibility_enabled_) { | 
| +    IntelligibilityEnhancer::Config config; | 
| +    config.sample_rate_hz = split_rate_; | 
| +    config.num_capture_channels = capture_audio_->num_channels(); | 
| +    config.num_render_channels = render_audio_->num_channels(); | 
| +    intelligibility_enhancer_.reset(new IntelligibilityEnhancer(config)); | 
| +  } | 
| +} | 
| + | 
| void AudioProcessingImpl::MaybeUpdateHistograms() { | 
| static const int kMinDiffDelayMs = 60; | 
|  | 
|  |