/*
 *  Copyright (c) 2012 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_coding/neteq4/comfort_noise.h"

#include <assert.h>

#include "webrtc/modules/audio_coding/codecs/cng/include/webrtc_cng.h"
#include "webrtc/modules/audio_coding/neteq4/decoder_database.h"
#include "webrtc/modules/audio_coding/neteq4/dsp_helper.h"
#include "webrtc/modules/audio_coding/neteq4/interface/audio_decoder.h"
#include "webrtc/modules/audio_coding/neteq4/sync_buffer.h"

namespace webrtc {

void ComfortNoise::Reset() {
  first_call_ = true;
  internal_error_code_ = 0;
}

int ComfortNoise::UpdateParameters(Packet* packet) {
  assert(packet);  // Existence is verified by caller.
  // Get comfort noise decoder.
  AudioDecoder* cng_decoder = decoder_database_->GetDecoder(
      packet->header.payloadType);
  if (!cng_decoder) {
    delete [] packet->payload;
    delete packet;
    return kUnknownPayloadType;
  }
  decoder_database_->SetActiveCngDecoder(packet->header.payloadType);
  CNG_dec_inst* cng_inst = static_cast<CNG_dec_inst*>(cng_decoder->state());
  int16_t ret = WebRtcCng_UpdateSid(cng_inst,
                                    packet->payload,
                                    packet->payload_length);
  delete [] packet->payload;
  delete packet;
  if (ret < 0) {
    internal_error_code_ = WebRtcCng_GetErrorCodeDec(cng_inst);
    return kInternalError;
  }
  return kOK;
}

int ComfortNoise::Generate(size_t requested_length,
                           AudioMultiVector<int16_t>* output) {
  // TODO(hlundin): Change to an enumerator and skip assert.
  assert(fs_hz_ == 8000 || fs_hz_ == 16000 || fs_hz_ ==  32000 ||
         fs_hz_ == 48000);
  assert(output->Channels() == 1);  // Not adapted for multi-channel yet.
  if (output->Channels() != 1) {
    return kMultiChannelNotSupported;
  }

  int16_t number_of_samples = requested_length;
  int16_t new_period = 0;
  if (first_call_) {
    // Generate noise and overlap slightly with old data.
    number_of_samples = requested_length + overlap_length_;
    new_period = 1;
  }
  output->AssertSize(number_of_samples);
  // Get the decoder from the database.
  AudioDecoder* cng_decoder = decoder_database_->GetActiveCngDecoder();
  if (!cng_decoder) {
    return kUnknownPayloadType;
  }
  CNG_dec_inst* cng_inst = static_cast<CNG_dec_inst*>(cng_decoder->state());
  // The expression &(*output)[0][0] is a pointer to the first element in
  // the first channel.
  if (WebRtcCng_Generate(cng_inst, &(*output)[0][0], number_of_samples,
                         new_period) < 0) {
    // Error returned.
    output->Zeros(requested_length);
    internal_error_code_ = WebRtcCng_GetErrorCodeDec(cng_inst);
    return kInternalError;
  }

  if (first_call_) {
    // Set tapering window parameters. Values are in Q15.
    int16_t muting_window;  // Mixing factor for overlap data.
    int16_t muting_window_increment;  // Mixing factor increment (negative).
    int16_t unmuting_window;  // Mixing factor for comfort noise.
    int16_t unmuting_window_increment;  // Mixing factor increment.
    if (fs_hz_ == 8000) {
      muting_window = DspHelper::kMuteFactorStart8kHz;
      muting_window_increment = DspHelper::kMuteFactorIncrement8kHz;
      unmuting_window = DspHelper::kUnmuteFactorStart8kHz;
      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement8kHz;
    } else if (fs_hz_ == 16000) {
      muting_window = DspHelper::kMuteFactorStart16kHz;
      muting_window_increment = DspHelper::kMuteFactorIncrement16kHz;
      unmuting_window = DspHelper::kUnmuteFactorStart16kHz;
      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement16kHz;
    } else if (fs_hz_ == 32000) {
      muting_window = DspHelper::kMuteFactorStart32kHz;
      muting_window_increment = DspHelper::kMuteFactorIncrement32kHz;
      unmuting_window = DspHelper::kUnmuteFactorStart32kHz;
      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement32kHz;
    } else {  // fs_hz_ == 48000
      muting_window = DspHelper::kMuteFactorStart48kHz;
      muting_window_increment = DspHelper::kMuteFactorIncrement48kHz;
      unmuting_window = DspHelper::kUnmuteFactorStart48kHz;
      unmuting_window_increment = DspHelper::kUnmuteFactorIncrement48kHz;
    }

    // Do overlap-add between new vector and overlap.
    size_t start_ix = sync_buffer_->Size() - overlap_length_;
    for (size_t i = 0; i < overlap_length_; i++) {
      /* overlapVec[i] = WinMute * overlapVec[i] + WinUnMute * outData[i] */
      // The expression (*output)[0][i] is the i-th element in the first
      // channel.
      (*sync_buffer_)[0][start_ix + i] =
          (((*sync_buffer_)[0][start_ix + i] * muting_window) +
              ((*output)[0][i] * unmuting_window) + 16384) >> 15;
      muting_window += muting_window_increment;
      unmuting_window += unmuting_window_increment;
    }
    // Remove |overlap_length_| samples from the front of |output| since they
    // were mixed into |sync_buffer_| above.
    output->PopFront(overlap_length_);
  }
  first_call_ = false;
  return kOK;
}

}  // namespace webrtc
