Add empty 3 band splitting filter API

This is only an empty API that will never be used. For now is 48kHz not supported in AudioProcessing. For that it needs to be added in InitializeLocked. But before the 3 band filter bank needs to be populated.

BUG=webrtc:3146
R=bjornv@webrtc.org, kwiberg@webrtc.org

Review URL: https://webrtc-codereview.appspot.com/30139004

git-svn-id: http://webrtc.googlecode.com/svn/trunk@7715 4adac7df-926f-26a2-2b94-8c16560cd09d
diff --git a/webrtc/modules/audio_processing/audio_buffer.cc b/webrtc/modules/audio_processing/audio_buffer.cc
index 2556bcd..2746e615 100644
--- a/webrtc/modules/audio_processing/audio_buffer.cc
+++ b/webrtc/modules/audio_processing/audio_buffer.cc
@@ -20,7 +20,8 @@
 enum {
   kSamplesPer8kHzChannel = 80,
   kSamplesPer16kHzChannel = 160,
-  kSamplesPer32kHzChannel = 320
+  kSamplesPer32kHzChannel = 320,
+  kSamplesPer48kHzChannel = 480
 };
 
 bool HasKeyboardChannel(AudioProcessing::ChannelLayout layout) {
@@ -171,13 +172,18 @@
     }
   }
 
-  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 @@
       : 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::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 7faa8a1..471fe7b 100644
--- a/webrtc/modules/audio_processing/audio_buffer.h
+++ b/webrtc/modules/audio_processing/audio_buffer.h
@@ -78,6 +78,8 @@
   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 @@
   scoped_ptr<IFChannelBuffer> channels_;
   scoped_ptr<IFChannelBuffer> split_channels_low_;
   scoped_ptr<IFChannelBuffer> split_channels_high_;
+  scoped_ptr<IFChannelBuffer> split_channels_super_high_;
   scoped_ptr<SplittingFilter> splitting_filter_;
   scoped_ptr<ChannelBuffer<int16_t> > mixed_low_pass_channels_;
   scoped_ptr<ChannelBuffer<int16_t> > 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 61a6f00..1b16c7c 100644
--- a/webrtc/modules/audio_processing/audio_processing_impl.cc
+++ b/webrtc/modules/audio_processing/audio_processing_impl.cc
@@ -262,7 +262,8 @@
   // 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 @@
   // 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 @@
   // 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::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 10d2b8b..1cca0ed 100644
--- a/webrtc/modules/audio_processing/include/audio_processing.h
+++ b/webrtc/modules/audio_processing/include/audio_processing.h
@@ -380,7 +380,8 @@
   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 d2b5cc0..8765dc9 100644
--- a/webrtc/modules/audio_processing/splitting_filter.cc
+++ b/webrtc/modules/audio_processing/splitting_filter.cc
@@ -46,4 +46,20 @@
   }
 }
 
+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 d316d95..1e9269e 100644
--- a/webrtc/modules/audio_processing/splitting_filter.h
+++ b/webrtc/modules/audio_processing/splitting_filter.h
@@ -47,6 +47,18 @@
                          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_;