/*
 *  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_processing/utility/delay_estimator_wrapper.h"

#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "webrtc/modules/audio_processing/utility/delay_estimator.h"
#include "webrtc/modules/audio_processing/utility/delay_estimator_internal.h"
#include "webrtc/system_wrappers/interface/compile_assert_c.h"

// Only bit |kBandFirst| through bit |kBandLast| are processed and
// |kBandFirst| - |kBandLast| must be < 32.
enum { kBandFirst = 12 };
enum { kBandLast = 43 };

static __inline uint32_t SetBit(uint32_t in, int pos) {
  uint32_t mask = (1 << pos);
  uint32_t out = (in | mask);

  return out;
}

// Calculates the mean recursively. Same version as WebRtc_MeanEstimatorFix(),
// but for float.
//
// Inputs:
//    - new_value             : New additional value.
//    - scale                 : Scale for smoothing (should be less than 1.0).
//
// Input/Output:
//    - mean_value            : Pointer to the mean value for updating.
//
static void MeanEstimatorFloat(float new_value,
                               float scale,
                               float* mean_value) {
  assert(scale < 1.0f);
  *mean_value += (new_value - *mean_value) * scale;
}

// Computes the binary spectrum by comparing the input |spectrum| with a
// |threshold_spectrum|. Float and fixed point versions.
//
// Inputs:
//      - spectrum            : Spectrum of which the binary spectrum should be
//                              calculated.
//      - threshold_spectrum  : Threshold spectrum with which the input
//                              spectrum is compared.
// Return:
//      - out                 : Binary spectrum.
//
static uint32_t BinarySpectrumFix(const uint16_t* spectrum,
                                  SpectrumType* threshold_spectrum,
                                  int q_domain,
                                  int* threshold_initialized) {
  int i = kBandFirst;
  uint32_t out = 0;

  assert(q_domain < 16);

  if (!(*threshold_initialized)) {
    // Set the |threshold_spectrum| to half the input |spectrum| as starting
    // value. This speeds up the convergence.
    for (i = kBandFirst; i <= kBandLast; i++) {
      if (spectrum[i] > 0) {
        // Convert input spectrum from Q(|q_domain|) to Q15.
        int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
        threshold_spectrum[i].int32_ = (spectrum_q15 >> 1);
        *threshold_initialized = 1;
      }
    }
  }
  for (i = kBandFirst; i <= kBandLast; i++) {
    // Convert input spectrum from Q(|q_domain|) to Q15.
    int32_t spectrum_q15 = ((int32_t) spectrum[i]) << (15 - q_domain);
    // Update the |threshold_spectrum|.
    WebRtc_MeanEstimatorFix(spectrum_q15, 6, &(threshold_spectrum[i].int32_));
    // Convert |spectrum| at current frequency bin to a binary value.
    if (spectrum_q15 > threshold_spectrum[i].int32_) {
      out = SetBit(out, i - kBandFirst);
    }
  }

  return out;
}

static uint32_t BinarySpectrumFloat(const float* spectrum,
                                    SpectrumType* threshold_spectrum,
                                    int* threshold_initialized) {
  int i = kBandFirst;
  uint32_t out = 0;
  const float kScale = 1 / 64.0;

  if (!(*threshold_initialized)) {
    // Set the |threshold_spectrum| to half the input |spectrum| as starting
    // value. This speeds up the convergence.
    for (i = kBandFirst; i <= kBandLast; i++) {
      if (spectrum[i] > 0.0f) {
        threshold_spectrum[i].float_ = (spectrum[i] / 2);
        *threshold_initialized = 1;
      }
    }
  }

  for (i = kBandFirst; i <= kBandLast; i++) {
    // Update the |threshold_spectrum|.
    MeanEstimatorFloat(spectrum[i], kScale, &(threshold_spectrum[i].float_));
    // Convert |spectrum| at current frequency bin to a binary value.
    if (spectrum[i] > threshold_spectrum[i].float_) {
      out = SetBit(out, i - kBandFirst);
    }
  }

  return out;
}

void WebRtc_FreeDelayEstimatorFarend(void* handle) {
  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;

  if (handle == NULL) {
    return;
  }

  free(self->mean_far_spectrum);
  self->mean_far_spectrum = NULL;

  WebRtc_FreeBinaryDelayEstimatorFarend(self->binary_farend);
  self->binary_farend = NULL;

  free(self);
}

void* WebRtc_CreateDelayEstimatorFarend(int spectrum_size, int history_size) {
  DelayEstimatorFarend* self = NULL;

  // Check if the sub band used in the delay estimation is small enough to fit
  // the binary spectra in a uint32_t.
  COMPILE_ASSERT(kBandLast - kBandFirst < 32);

  if (spectrum_size >= kBandLast) {
    self = malloc(sizeof(DelayEstimatorFarend));
  }

  if (self != NULL) {
    int memory_fail = 0;

    // Allocate memory for the binary far-end spectrum handling.
    self->binary_farend = WebRtc_CreateBinaryDelayEstimatorFarend(history_size);
    memory_fail |= (self->binary_farend == NULL);

    // Allocate memory for spectrum buffers.
    self->mean_far_spectrum = malloc(spectrum_size * sizeof(SpectrumType));
    memory_fail |= (self->mean_far_spectrum == NULL);

    self->spectrum_size = spectrum_size;

    if (memory_fail) {
      WebRtc_FreeDelayEstimatorFarend(self);
      self = NULL;
    }
  }

  return self;
}

int WebRtc_InitDelayEstimatorFarend(void* handle) {
  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;

  if (self == NULL) {
    return -1;
  }

  // Initialize far-end part of binary delay estimator.
  WebRtc_InitBinaryDelayEstimatorFarend(self->binary_farend);

  // Set averaged far and near end spectra to zero.
  memset(self->mean_far_spectrum, 0,
         sizeof(SpectrumType) * self->spectrum_size);
  // Reset initialization indicators.
  self->far_spectrum_initialized = 0;

  return 0;
}

void WebRtc_SoftResetDelayEstimatorFarend(void* handle, int delay_shift) {
  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
  assert(self != NULL);
  WebRtc_SoftResetBinaryDelayEstimatorFarend(self->binary_farend, delay_shift);
}

int WebRtc_AddFarSpectrumFix(void* handle,
                             const uint16_t* far_spectrum,
                             int spectrum_size,
                             int far_q) {
  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
  uint32_t binary_spectrum = 0;

  if (self == NULL) {
    return -1;
  }
  if (far_spectrum == NULL) {
    // Empty far end spectrum.
    return -1;
  }
  if (spectrum_size != self->spectrum_size) {
    // Data sizes don't match.
    return -1;
  }
  if (far_q > 15) {
    // If |far_q| is larger than 15 we cannot guarantee no wrap around.
    return -1;
  }

  // Get binary spectrum.
  binary_spectrum = BinarySpectrumFix(far_spectrum, self->mean_far_spectrum,
                                      far_q, &(self->far_spectrum_initialized));
  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);

  return 0;
}

int WebRtc_AddFarSpectrumFloat(void* handle,
                               const float* far_spectrum,
                               int spectrum_size) {
  DelayEstimatorFarend* self = (DelayEstimatorFarend*) handle;
  uint32_t binary_spectrum = 0;

  if (self == NULL) {
    return -1;
  }
  if (far_spectrum == NULL) {
    // Empty far end spectrum.
    return -1;
  }
  if (spectrum_size != self->spectrum_size) {
    // Data sizes don't match.
    return -1;
  }

  // Get binary spectrum.
  binary_spectrum = BinarySpectrumFloat(far_spectrum, self->mean_far_spectrum,
                                        &(self->far_spectrum_initialized));
  WebRtc_AddBinaryFarSpectrum(self->binary_farend, binary_spectrum);

  return 0;
}

void WebRtc_FreeDelayEstimator(void* handle) {
  DelayEstimator* self = (DelayEstimator*) handle;

  if (handle == NULL) {
    return;
  }

  free(self->mean_near_spectrum);
  self->mean_near_spectrum = NULL;

  WebRtc_FreeBinaryDelayEstimator(self->binary_handle);
  self->binary_handle = NULL;

  free(self);
}

void* WebRtc_CreateDelayEstimator(void* farend_handle, int max_lookahead) {
  DelayEstimator* self = NULL;
  DelayEstimatorFarend* farend = (DelayEstimatorFarend*) farend_handle;

  if (farend_handle != NULL) {
    self = malloc(sizeof(DelayEstimator));
  }

  if (self != NULL) {
    int memory_fail = 0;

    // Allocate memory for the farend spectrum handling.
    self->binary_handle =
        WebRtc_CreateBinaryDelayEstimator(farend->binary_farend, max_lookahead);
    memory_fail |= (self->binary_handle == NULL);

    // Allocate memory for spectrum buffers.
    self->mean_near_spectrum = malloc(farend->spectrum_size *
                                      sizeof(SpectrumType));
    memory_fail |= (self->mean_near_spectrum == NULL);

    self->spectrum_size = farend->spectrum_size;

    if (memory_fail) {
      WebRtc_FreeDelayEstimator(self);
      self = NULL;
    }
  }

  return self;
}

int WebRtc_InitDelayEstimator(void* handle) {
  DelayEstimator* self = (DelayEstimator*) handle;

  if (self == NULL) {
    return -1;
  }

  // Initialize binary delay estimator.
  WebRtc_InitBinaryDelayEstimator(self->binary_handle);

  // Set averaged far and near end spectra to zero.
  memset(self->mean_near_spectrum, 0,
         sizeof(SpectrumType) * self->spectrum_size);
  // Reset initialization indicators.
  self->near_spectrum_initialized = 0;

  return 0;
}

int WebRtc_SoftResetDelayEstimator(void* handle, int delay_shift) {
  DelayEstimator* self = (DelayEstimator*) handle;
  assert(self != NULL);
  return WebRtc_SoftResetBinaryDelayEstimator(self->binary_handle, delay_shift);
}

int WebRtc_set_history_size(void* handle, int history_size) {
  DelayEstimator* self = handle;

  if ((self == NULL) || (history_size <= 1)) {
    return -1;
  }
  return WebRtc_AllocateHistoryBufferMemory(self->binary_handle, history_size);
}

int WebRtc_history_size(const void* handle) {
  const DelayEstimator* self = handle;

  if (self == NULL) {
    return -1;
  }
  if (self->binary_handle->farend->history_size !=
      self->binary_handle->history_size) {
    // Non matching history sizes.
    return -1;
  }
  return self->binary_handle->history_size;
}

int WebRtc_set_lookahead(void* handle, int lookahead) {
  DelayEstimator* self = (DelayEstimator*) handle;
  assert(self != NULL);
  assert(self->binary_handle != NULL);
  if ((lookahead > self->binary_handle->near_history_size - 1) ||
      (lookahead < 0)) {
    return -1;
  }
  self->binary_handle->lookahead = lookahead;
  return self->binary_handle->lookahead;
}

int WebRtc_lookahead(void* handle) {
  DelayEstimator* self = (DelayEstimator*) handle;
  assert(self != NULL);
  assert(self->binary_handle != NULL);
  return self->binary_handle->lookahead;
}

int WebRtc_set_allowed_offset(void* handle, int allowed_offset) {
  DelayEstimator* self = (DelayEstimator*) handle;

  if ((self == NULL) || (allowed_offset < 0)) {
    return -1;
  }
  self->binary_handle->allowed_offset = allowed_offset;
  return 0;
}

int WebRtc_get_allowed_offset(const void* handle) {
  const DelayEstimator* self = (const DelayEstimator*) handle;

  if (self == NULL) {
    return -1;
  }
  return self->binary_handle->allowed_offset;
}

int WebRtc_enable_robust_validation(void* handle, int enable) {
  DelayEstimator* self = (DelayEstimator*) handle;

  if (self == NULL) {
    return -1;
  }
  if ((enable < 0) || (enable > 1)) {
    return -1;
  }
  assert(self->binary_handle != NULL);
  self->binary_handle->robust_validation_enabled = enable;
  return 0;
}

int WebRtc_is_robust_validation_enabled(const void* handle) {
  const DelayEstimator* self = (const DelayEstimator*) handle;

  if (self == NULL) {
    return -1;
  }
  return self->binary_handle->robust_validation_enabled;
}

int WebRtc_DelayEstimatorProcessFix(void* handle,
                                    const uint16_t* near_spectrum,
                                    int spectrum_size,
                                    int near_q) {
  DelayEstimator* self = (DelayEstimator*) handle;
  uint32_t binary_spectrum = 0;

  if (self == NULL) {
    return -1;
  }
  if (near_spectrum == NULL) {
    // Empty near end spectrum.
    return -1;
  }
  if (spectrum_size != self->spectrum_size) {
    // Data sizes don't match.
    return -1;
  }
  if (near_q > 15) {
    // If |near_q| is larger than 15 we cannot guarantee no wrap around.
    return -1;
  }

  // Get binary spectra.
  binary_spectrum = BinarySpectrumFix(near_spectrum,
                                      self->mean_near_spectrum,
                                      near_q,
                                      &(self->near_spectrum_initialized));

  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
}

int WebRtc_DelayEstimatorProcessFloat(void* handle,
                                      const float* near_spectrum,
                                      int spectrum_size) {
  DelayEstimator* self = (DelayEstimator*) handle;
  uint32_t binary_spectrum = 0;

  if (self == NULL) {
    return -1;
  }
  if (near_spectrum == NULL) {
    // Empty near end spectrum.
    return -1;
  }
  if (spectrum_size != self->spectrum_size) {
    // Data sizes don't match.
    return -1;
  }

  // Get binary spectrum.
  binary_spectrum = BinarySpectrumFloat(near_spectrum, self->mean_near_spectrum,
                                        &(self->near_spectrum_initialized));

  return WebRtc_ProcessBinarySpectrum(self->binary_handle, binary_spectrum);
}

int WebRtc_last_delay(void* handle) {
  DelayEstimator* self = (DelayEstimator*) handle;

  if (self == NULL) {
    return -1;
  }

  return WebRtc_binary_last_delay(self->binary_handle);
}

float WebRtc_last_delay_quality(void* handle) {
  DelayEstimator* self = (DelayEstimator*) handle;
  assert(self != NULL);
  return WebRtc_binary_last_delay_quality(self->binary_handle);
}
