/*
 *  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(int 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 (int i = 0; i < num_channels; ++i) {
      three_band_filter_banks_.push_back(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(static_cast<int>(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(static_cast<int>(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(static_cast<int>(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(static_cast<int>(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
