diff --git a/webrtc/modules/audio_processing/audio_buffer.cc b/webrtc/modules/audio_processing/audio_buffer.cc index 2556bcda31..2746e61580 100644 --- a/webrtc/modules/audio_processing/audio_buffer.cc +++ b/webrtc/modules/audio_processing/audio_buffer.cc @@ -20,7 +20,8 @@ namespace { enum { kSamplesPer8kHzChannel = 80, kSamplesPer16kHzChannel = 160, - kSamplesPer32kHzChannel = 320 + kSamplesPer32kHzChannel = 320, + kSamplesPer48kHzChannel = 480 }; bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) { @@ -171,13 +172,18 @@ AudioBuffer::AudioBuffer(int input_samples_per_channel, } } - if (proc_samples_per_channel_ == kSamplesPer32kHzChannel) { + if (proc_samples_per_channel_ == kSamplesPer32kHzChannel || + proc_samples_per_channel_ == kSamplesPer48kHzChannel) { samples_per_split_channel_ = kSamplesPer16kHzChannel; split_channels_low_.reset(new IFChannelBuffer(samples_per_split_channel_, num_proc_channels_)); split_channels_high_.reset(new IFChannelBuffer(samples_per_split_channel_, num_proc_channels_)); splitting_filter_.reset(new SplittingFilter(num_proc_channels_)); + if (proc_samples_per_channel_ == kSamplesPer48kHzChannel) { + split_channels_super_high_.reset( + new IFChannelBuffer(samples_per_split_channel_, num_proc_channels_)); + } } } @@ -391,6 +397,18 @@ float* const* AudioBuffer::high_pass_split_channels_f() { : NULL; } +const float* const* AudioBuffer::super_high_pass_split_channels_f() const { + return split_channels_super_high_.get() + ? split_channels_super_high_->fbuf_const()->channels() + : NULL; +} + +float* const* AudioBuffer::super_high_pass_split_channels_f() { + return split_channels_super_high_.get() + ? split_channels_super_high_->fbuf()->channels() + : NULL; +} + const int16_t* AudioBuffer::mixed_low_pass_data() { // Currently only mixing stereo to mono is supported. assert(num_proc_channels_ == 1 || num_proc_channels_ == 2); @@ -513,15 +531,29 @@ void AudioBuffer::CopyLowPassToReference() { } void AudioBuffer::SplitIntoFrequencyBands() { - splitting_filter_->TwoBandsAnalysis( - channels(), samples_per_channel(), num_proc_channels_, - low_pass_split_channels(), high_pass_split_channels()); + if (samples_per_channel() == kSamplesPer32kHzChannel) { + splitting_filter_->TwoBandsAnalysis( + channels(), samples_per_channel(), num_proc_channels_, + low_pass_split_channels(), high_pass_split_channels()); + } else if (samples_per_channel() == kSamplesPer48kHzChannel) { + splitting_filter_->ThreeBandsAnalysis( + channels_f(), samples_per_channel(), num_proc_channels_, + low_pass_split_channels_f(), high_pass_split_channels_f(), + super_high_pass_split_channels_f()); + } } void AudioBuffer::MergeFrequencyBands() { - splitting_filter_->TwoBandsSynthesis( - low_pass_split_channels(), high_pass_split_channels(), - samples_per_split_channel(), num_proc_channels_, channels()); + if (samples_per_channel() == kSamplesPer32kHzChannel) { + splitting_filter_->TwoBandsSynthesis( + low_pass_split_channels(), high_pass_split_channels(), + samples_per_split_channel(), num_proc_channels_, channels()); + } else if (samples_per_channel() == kSamplesPer48kHzChannel) { + splitting_filter_->ThreeBandsSynthesis( + low_pass_split_channels_f(), high_pass_split_channels_f(), + super_high_pass_split_channels_f(), samples_per_split_channel(), + num_proc_channels_, channels_f()); + } } } // namespace webrtc diff --git a/webrtc/modules/audio_processing/audio_buffer.h b/webrtc/modules/audio_processing/audio_buffer.h index 7faa8a18c4..471fe7bc31 100644 --- a/webrtc/modules/audio_processing/audio_buffer.h +++ b/webrtc/modules/audio_processing/audio_buffer.h @@ -78,6 +78,8 @@ class AudioBuffer { const float* const* low_pass_split_channels_f() const; float* const* high_pass_split_channels_f(); const float* const* high_pass_split_channels_f() const; + float* const* super_high_pass_split_channels_f(); + const float* const* super_high_pass_split_channels_f() const; const float* keyboard_data() const; @@ -122,6 +124,7 @@ class AudioBuffer { scoped_ptr channels_; scoped_ptr split_channels_low_; scoped_ptr split_channels_high_; + scoped_ptr split_channels_super_high_; scoped_ptr splitting_filter_; scoped_ptr > mixed_low_pass_channels_; scoped_ptr > low_pass_reference_channels_; diff --git a/webrtc/modules/audio_processing/audio_processing_impl.cc b/webrtc/modules/audio_processing/audio_processing_impl.cc index 61a6f00f92..1b16c7c609 100644 --- a/webrtc/modules/audio_processing/audio_processing_impl.cc +++ b/webrtc/modules/audio_processing/audio_processing_impl.cc @@ -262,7 +262,8 @@ int AudioProcessingImpl::InitializeLocked(int input_sample_rate_hz, // demonstrated to work well for AEC in most practical scenarios. rev_proc_format_.set(rev_proc_rate, 1); - if (fwd_proc_format_.rate() == kSampleRate32kHz) { + if (fwd_proc_format_.rate() == kSampleRate32kHz || + fwd_proc_format_.rate() == kSampleRate48kHz) { split_rate_ = kSampleRate16kHz; } else { split_rate_ = fwd_proc_format_.rate(); @@ -404,7 +405,8 @@ int AudioProcessingImpl::ProcessStream(AudioFrame* frame) { // Must be a native rate. if (frame->sample_rate_hz_ != kSampleRate8kHz && frame->sample_rate_hz_ != kSampleRate16kHz && - frame->sample_rate_hz_ != kSampleRate32kHz) { + frame->sample_rate_hz_ != kSampleRate32kHz && + frame->sample_rate_hz_ != kSampleRate48kHz) { return kBadSampleRateError; } if (echo_control_mobile_->is_enabled() && @@ -540,7 +542,8 @@ int AudioProcessingImpl::AnalyzeReverseStream(AudioFrame* frame) { // Must be a native rate. if (frame->sample_rate_hz_ != kSampleRate8kHz && frame->sample_rate_hz_ != kSampleRate16kHz && - frame->sample_rate_hz_ != kSampleRate32kHz) { + frame->sample_rate_hz_ != kSampleRate32kHz && + frame->sample_rate_hz_ != kSampleRate48kHz) { return kBadSampleRateError; } // This interface does not tolerate different forward and reverse rates. @@ -775,14 +778,16 @@ bool AudioProcessingImpl::output_copy_needed(bool is_data_processed) const { } bool AudioProcessingImpl::synthesis_needed(bool is_data_processed) const { - return (is_data_processed && fwd_proc_format_.rate() == kSampleRate32kHz); + return (is_data_processed && (fwd_proc_format_.rate() == kSampleRate32kHz || + fwd_proc_format_.rate() == kSampleRate48kHz)); } bool AudioProcessingImpl::analysis_needed(bool is_data_processed) const { if (!is_data_processed && !voice_detection_->is_enabled()) { // Only level_estimator_ is enabled. return false; - } else if (fwd_proc_format_.rate() == kSampleRate32kHz) { + } else if (fwd_proc_format_.rate() == kSampleRate32kHz || + fwd_proc_format_.rate() == kSampleRate48kHz) { // Something besides level_estimator_ is enabled, and we have super-wb. return true; } diff --git a/webrtc/modules/audio_processing/include/audio_processing.h b/webrtc/modules/audio_processing/include/audio_processing.h index 10d2b8b8fc..1cca0edf57 100644 --- a/webrtc/modules/audio_processing/include/audio_processing.h +++ b/webrtc/modules/audio_processing/include/audio_processing.h @@ -380,7 +380,8 @@ class AudioProcessing { enum NativeRate { kSampleRate8kHz = 8000, kSampleRate16kHz = 16000, - kSampleRate32kHz = 32000 + kSampleRate32kHz = 32000, + kSampleRate48kHz = 48000 }; static const int kChunkSizeMs = 10; diff --git a/webrtc/modules/audio_processing/splitting_filter.cc b/webrtc/modules/audio_processing/splitting_filter.cc index d2b5cc072e..8765dc987f 100644 --- a/webrtc/modules/audio_processing/splitting_filter.cc +++ b/webrtc/modules/audio_processing/splitting_filter.cc @@ -46,4 +46,20 @@ void SplittingFilter::TwoBandsSynthesis(const int16_t* const* low_band, } } +void SplittingFilter::ThreeBandsAnalysis(const float* const* in_data, + int in_data_length, + int channels, + float* const* low_band, + float* const* high_band, + float* const* super_high_band) { +} + +void SplittingFilter::ThreeBandsSynthesis(const float* const* low_band, + const float* const* high_band, + const float* const* super_high_band, + int band_length, + int channels, + float* const* out_data) { +} + } // namespace webrtc diff --git a/webrtc/modules/audio_processing/splitting_filter.h b/webrtc/modules/audio_processing/splitting_filter.h index d316d9519a..1e9269ef0d 100644 --- a/webrtc/modules/audio_processing/splitting_filter.h +++ b/webrtc/modules/audio_processing/splitting_filter.h @@ -47,6 +47,18 @@ class SplittingFilter { int band_length, int channels, int16_t* const* out_data); + void ThreeBandsAnalysis(const float* const* in_data, + int in_data_length, + int channels, + float* const* low_band, + float* const* high_band, + float* const* super_high_band); + void ThreeBandsSynthesis(const float* const* low_band, + const float* const* high_band, + const float* const* super_high_band, + int band_length, + int channels, + float* const* out_data); private: int channels_;