/*
 *  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.
 */

#include "webrtc/modules/audio_processing/splitting_filter.h"

#include "webrtc/base/checks.h"
#include "webrtc/common_audio/signal_processing/include/signal_processing_library.h"
#include "webrtc/common_audio/channel_buffer.h"

namespace webrtc {

SplittingFilter::SplittingFilter(size_t num_channels,
                                 size_t num_bands,
                                 size_t num_frames)
    : num_bands_(num_bands) {
  RTC_CHECK(num_bands_ == 2 || num_bands_ == 3);
  if (num_bands_ == 2) {
    two_bands_states_.resize(num_channels);
  } else if (num_bands_ == 3) {
    for (size_t i = 0; i < num_channels; ++i) {
      three_band_filter_banks_.push_back(std::unique_ptr<ThreeBandFilterBank>(
          new ThreeBandFilterBank(num_frames)));
    }
  }
}

void SplittingFilter::Analysis(const IFChannelBuffer* data,
                               IFChannelBuffer* bands) {
  RTC_DCHECK_EQ(num_bands_, bands->num_bands());
  RTC_DCHECK_EQ(data->num_channels(), bands->num_channels());
  RTC_DCHECK_EQ(data->num_frames(),
                bands->num_frames_per_band() * bands->num_bands());
  if (bands->num_bands() == 2) {
    TwoBandsAnalysis(data, bands);
  } else if (bands->num_bands() == 3) {
    ThreeBandsAnalysis(data, bands);
  }
}

void SplittingFilter::Synthesis(const IFChannelBuffer* bands,
                                IFChannelBuffer* data) {
  RTC_DCHECK_EQ(num_bands_, bands->num_bands());
  RTC_DCHECK_EQ(data->num_channels(), bands->num_channels());
  RTC_DCHECK_EQ(data->num_frames(),
                bands->num_frames_per_band() * bands->num_bands());
  if (bands->num_bands() == 2) {
    TwoBandsSynthesis(bands, data);
  } else if (bands->num_bands() == 3) {
    ThreeBandsSynthesis(bands, data);
  }
}

void SplittingFilter::TwoBandsAnalysis(const IFChannelBuffer* data,
                                       IFChannelBuffer* bands) {
  RTC_DCHECK_EQ(two_bands_states_.size(), data->num_channels());
  for (size_t i = 0; i < two_bands_states_.size(); ++i) {
    WebRtcSpl_AnalysisQMF(data->ibuf_const()->channels()[i],
                          data->num_frames(),
                          bands->ibuf()->channels(0)[i],
                          bands->ibuf()->channels(1)[i],
                          two_bands_states_[i].analysis_state1,
                          two_bands_states_[i].analysis_state2);
  }
}

void SplittingFilter::TwoBandsSynthesis(const IFChannelBuffer* bands,
                                        IFChannelBuffer* data) {
  RTC_DCHECK_EQ(two_bands_states_.size(), data->num_channels());
  for (size_t i = 0; i < two_bands_states_.size(); ++i) {
    WebRtcSpl_SynthesisQMF(bands->ibuf_const()->channels(0)[i],
                           bands->ibuf_const()->channels(1)[i],
                           bands->num_frames_per_band(),
                           data->ibuf()->channels()[i],
                           two_bands_states_[i].synthesis_state1,
                           two_bands_states_[i].synthesis_state2);
  }
}

void SplittingFilter::ThreeBandsAnalysis(const IFChannelBuffer* data,
                                         IFChannelBuffer* bands) {
  RTC_DCHECK_EQ(three_band_filter_banks_.size(), data->num_channels());
  for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) {
    three_band_filter_banks_[i]->Analysis(data->fbuf_const()->channels()[i],
                                          data->num_frames(),
                                          bands->fbuf()->bands(i));
  }
}

void SplittingFilter::ThreeBandsSynthesis(const IFChannelBuffer* bands,
                                          IFChannelBuffer* data) {
  RTC_DCHECK_EQ(three_band_filter_banks_.size(), data->num_channels());
  for (size_t i = 0; i < three_band_filter_banks_.size(); ++i) {
    three_band_filter_banks_[i]->Synthesis(bands->fbuf_const()->bands(i),
                                           bands->num_frames_per_band(),
                                           data->fbuf()->channels()[i]);
  }
}

}  // namespace webrtc
