/*
 *  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,
                                 int num_bands,
                                 int num_frames)
    : num_bands_(num_bands) {
  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) {
  DCHECK_EQ(num_bands_, bands->num_bands());
  DCHECK_EQ(data->num_channels(), bands->num_channels());
  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) {
  DCHECK_EQ(num_bands_, bands->num_bands());
  DCHECK_EQ(data->num_channels(), bands->num_channels());
  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) {
  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) {
  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) {
  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) {
  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
