|  | /* | 
|  | *  Copyright (c) 2014 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #ifndef WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_ | 
|  | #define WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_ | 
|  |  | 
|  | #include <complex> | 
|  | #include <memory> | 
|  | #include <vector> | 
|  |  | 
|  | #include "webrtc/base/swap_queue.h" | 
|  | #include "webrtc/common_audio/channel_buffer.h" | 
|  | #include "webrtc/common_audio/lapped_transform.h" | 
|  | #include "webrtc/modules/audio_processing/audio_buffer.h" | 
|  | #include "webrtc/modules/audio_processing/intelligibility/intelligibility_utils.h" | 
|  | #include "webrtc/modules/audio_processing/render_queue_item_verifier.h" | 
|  | #include "webrtc/modules/audio_processing/vad/voice_activity_detector.h" | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | // Speech intelligibility enhancement module. Reads render and capture | 
|  | // audio streams and modifies the render stream with a set of gains per | 
|  | // frequency bin to enhance speech against the noise background. | 
|  | // Details of the model and algorithm can be found in the original paper: | 
|  | // http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6882788 | 
|  | class IntelligibilityEnhancer : public LappedTransform::Callback { | 
|  | public: | 
|  | IntelligibilityEnhancer(int sample_rate_hz, | 
|  | size_t num_render_channels, | 
|  | size_t num_bands, | 
|  | size_t num_noise_bins); | 
|  |  | 
|  | ~IntelligibilityEnhancer() override; | 
|  |  | 
|  | // Sets the capture noise magnitude spectrum estimate. | 
|  | void SetCaptureNoiseEstimate(std::vector<float> noise, float gain); | 
|  |  | 
|  | // Reads chunk of speech in time domain and updates with modified signal. | 
|  | void ProcessRenderAudio(AudioBuffer* audio); | 
|  | bool active() const; | 
|  |  | 
|  | protected: | 
|  | // All in frequency domain, receives input |in_block|, applies | 
|  | // intelligibility enhancement, and writes result to |out_block|. | 
|  | void ProcessAudioBlock(const std::complex<float>* const* in_block, | 
|  | size_t in_channels, | 
|  | size_t frames, | 
|  | size_t out_channels, | 
|  | std::complex<float>* const* out_block) override; | 
|  |  | 
|  | private: | 
|  | FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestRenderUpdate); | 
|  | FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestErbCreation); | 
|  | FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, TestSolveForGains); | 
|  | FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, | 
|  | TestNoiseGainHasExpectedResult); | 
|  | FRIEND_TEST_ALL_PREFIXES(IntelligibilityEnhancerTest, | 
|  | TestAllBandsHaveSameDelay); | 
|  |  | 
|  | // Updates the SNR estimation and enables or disables this component using a | 
|  | // hysteresis. | 
|  | void SnrBasedEffectActivation(); | 
|  |  | 
|  | // Bisection search for optimal |lambda|. | 
|  | void SolveForLambda(float power_target); | 
|  |  | 
|  | // Transforms freq gains to ERB gains. | 
|  | void UpdateErbGains(); | 
|  |  | 
|  | // Returns number of ERB filters. | 
|  | static size_t GetBankSize(int sample_rate, size_t erb_resolution); | 
|  |  | 
|  | // Initializes ERB filterbank. | 
|  | std::vector<std::vector<float>> CreateErbBank(size_t num_freqs); | 
|  |  | 
|  | // Analytically solves quadratic for optimal gains given |lambda|. | 
|  | // Negative gains are set to 0. Stores the results in |sols|. | 
|  | void SolveForGainsGivenLambda(float lambda, size_t start_freq, float* sols); | 
|  |  | 
|  | // Returns true if the audio is speech. | 
|  | bool IsSpeech(const float* audio); | 
|  |  | 
|  | // Delays the high bands to compensate for the processing delay in the low | 
|  | // band. | 
|  | void DelayHighBands(AudioBuffer* audio); | 
|  |  | 
|  | static const size_t kMaxNumNoiseEstimatesToBuffer = 5; | 
|  |  | 
|  | const size_t freqs_;         // Num frequencies in frequency domain. | 
|  | const size_t num_noise_bins_; | 
|  | const size_t chunk_length_;  // Chunk size in samples. | 
|  | const size_t bank_size_;     // Num ERB filters. | 
|  | const int sample_rate_hz_; | 
|  | const size_t num_render_channels_; | 
|  |  | 
|  | intelligibility::PowerEstimator<std::complex<float>> clear_power_estimator_; | 
|  | intelligibility::PowerEstimator<float> noise_power_estimator_; | 
|  | std::vector<float> filtered_clear_pow_; | 
|  | std::vector<float> filtered_noise_pow_; | 
|  | std::vector<float> center_freqs_; | 
|  | std::vector<std::vector<float>> capture_filter_bank_; | 
|  | std::vector<std::vector<float>> render_filter_bank_; | 
|  | size_t start_freq_; | 
|  |  | 
|  | std::vector<float> gains_eq_;  // Pre-filter modified gains. | 
|  | intelligibility::GainApplier gain_applier_; | 
|  |  | 
|  | std::unique_ptr<LappedTransform> render_mangler_; | 
|  |  | 
|  | VoiceActivityDetector vad_; | 
|  | std::vector<int16_t> audio_s16_; | 
|  | size_t chunks_since_voice_; | 
|  | bool is_speech_; | 
|  | float snr_; | 
|  | bool is_active_; | 
|  |  | 
|  | unsigned long int num_chunks_; | 
|  | unsigned long int num_active_chunks_; | 
|  |  | 
|  | std::vector<float> noise_estimation_buffer_; | 
|  | SwapQueue<std::vector<float>, RenderQueueItemVerifier<float>> | 
|  | noise_estimation_queue_; | 
|  |  | 
|  | std::vector<std::unique_ptr<intelligibility::DelayBuffer>> | 
|  | high_bands_buffers_; | 
|  | }; | 
|  |  | 
|  | }  // namespace webrtc | 
|  |  | 
|  | #endif  // WEBRTC_MODULES_AUDIO_PROCESSING_INTELLIGIBILITY_INTELLIGIBILITY_ENHANCER_H_ |