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

//
//  Implements core class for intelligibility enhancer.
//
//  Details of the model and algorithm can be found in the original paper:
//  http://ieeexplore.ieee.org/stamp/stamp.jsp?tp=&arnumber=6882788
//

#include "webrtc/modules/audio_processing/intelligibility/intelligibility_enhancer.h"

#include <math.h>
#include <stdlib.h>
#include <algorithm>
#include <numeric>

#include "webrtc/base/checks.h"
#include "webrtc/common_audio/include/audio_util.h"
#include "webrtc/common_audio/window_generator.h"

namespace webrtc {

namespace {

const size_t kErbResolution = 2;
const int kWindowSizeMs = 2;
const int kChunkSizeMs = 10;  // Size provided by APM.
const float kClipFreq = 200.0f;
const float kConfigRho = 0.02f;  // Default production and interpretation SNR.
const float kKbdAlpha = 1.5f;
const float kLambdaBot = -1.0f;      // Extreme values in bisection
const float kLambdaTop = -10e-18f;  // search for lamda.

}  // namespace

using std::complex;
using std::max;
using std::min;
using VarianceType = intelligibility::VarianceArray::StepType;

IntelligibilityEnhancer::TransformCallback::TransformCallback(
    IntelligibilityEnhancer* parent,
    IntelligibilityEnhancer::AudioSource source)
    : parent_(parent), source_(source) {
}

void IntelligibilityEnhancer::TransformCallback::ProcessAudioBlock(
    const complex<float>* const* in_block,
    int in_channels,
    size_t frames,
    int /* out_channels */,
    complex<float>* const* out_block) {
  DCHECK_EQ(parent_->freqs_, frames);
  for (int i = 0; i < in_channels; ++i) {
    parent_->DispatchAudio(source_, in_block[i], out_block[i]);
  }
}

IntelligibilityEnhancer::IntelligibilityEnhancer()
    : IntelligibilityEnhancer(IntelligibilityEnhancer::Config()) {
}

IntelligibilityEnhancer::IntelligibilityEnhancer(const Config& config)
    : freqs_(RealFourier::ComplexLength(
          RealFourier::FftOrder(config.sample_rate_hz * kWindowSizeMs / 1000))),
      window_size_(static_cast<size_t>(1 << RealFourier::FftOrder(freqs_))),
      chunk_length_(
          static_cast<size_t>(config.sample_rate_hz * kChunkSizeMs / 1000)),
      bank_size_(GetBankSize(config.sample_rate_hz, kErbResolution)),
      sample_rate_hz_(config.sample_rate_hz),
      erb_resolution_(kErbResolution),
      num_capture_channels_(config.num_capture_channels),
      num_render_channels_(config.num_render_channels),
      analysis_rate_(config.analysis_rate),
      active_(true),
      clear_variance_(freqs_,
                      config.var_type,
                      config.var_window_size,
                      config.var_decay_rate),
      noise_variance_(freqs_,
                      config.var_type,
                      config.var_window_size,
                      config.var_decay_rate),
      filtered_clear_var_(new float[bank_size_]),
      filtered_noise_var_(new float[bank_size_]),
      filter_bank_(bank_size_),
      center_freqs_(new float[bank_size_]),
      rho_(new float[bank_size_]),
      gains_eq_(new float[bank_size_]),
      gain_applier_(freqs_, config.gain_change_limit),
      temp_render_out_buffer_(chunk_length_, num_render_channels_),
      temp_capture_out_buffer_(chunk_length_, num_capture_channels_),
      kbd_window_(new float[window_size_]),
      render_callback_(this, AudioSource::kRenderStream),
      capture_callback_(this, AudioSource::kCaptureStream),
      block_count_(0),
      analysis_step_(0) {
  DCHECK_LE(config.rho, 1.0f);

  CreateErbBank();

  // Assumes all rho equal.
  for (size_t i = 0; i < bank_size_; ++i) {
    rho_[i] = config.rho * config.rho;
  }

  float freqs_khz = kClipFreq / 1000.0f;
  size_t erb_index = static_cast<size_t>(ceilf(
      11.17f * logf((freqs_khz + 0.312f) / (freqs_khz + 14.6575f)) + 43.0f));
  start_freq_ = std::max(static_cast<size_t>(1), erb_index * erb_resolution_);

  WindowGenerator::KaiserBesselDerived(kKbdAlpha, window_size_,
                                       kbd_window_.get());
  render_mangler_.reset(new LappedTransform(
      num_render_channels_, num_render_channels_, chunk_length_,
      kbd_window_.get(), window_size_, window_size_ / 2, &render_callback_));
  capture_mangler_.reset(new LappedTransform(
      num_capture_channels_, num_capture_channels_, chunk_length_,
      kbd_window_.get(), window_size_, window_size_ / 2, &capture_callback_));
}

void IntelligibilityEnhancer::ProcessRenderAudio(float* const* audio,
                                                 int sample_rate_hz,
                                                 int num_channels) {
  CHECK_EQ(sample_rate_hz_, sample_rate_hz);
  CHECK_EQ(num_render_channels_, num_channels);

  if (active_) {
    render_mangler_->ProcessChunk(audio, temp_render_out_buffer_.channels());
  }

  if (active_) {
    for (int i = 0; i < num_render_channels_; ++i) {
      memcpy(audio[i], temp_render_out_buffer_.channels()[i],
             chunk_length_ * sizeof(**audio));
    }
  }
}

void IntelligibilityEnhancer::AnalyzeCaptureAudio(float* const* audio,
                                                  int sample_rate_hz,
                                                  int num_channels) {
  CHECK_EQ(sample_rate_hz_, sample_rate_hz);
  CHECK_EQ(num_capture_channels_, num_channels);

  capture_mangler_->ProcessChunk(audio, temp_capture_out_buffer_.channels());
}

void IntelligibilityEnhancer::DispatchAudio(
    IntelligibilityEnhancer::AudioSource source,
    const complex<float>* in_block,
    complex<float>* out_block) {
  switch (source) {
    case kRenderStream:
      ProcessClearBlock(in_block, out_block);
      break;
    case kCaptureStream:
      ProcessNoiseBlock(in_block, out_block);
      break;
  }
}

void IntelligibilityEnhancer::ProcessClearBlock(const complex<float>* in_block,
                                                complex<float>* out_block) {
  if (block_count_ < 2) {
    memset(out_block, 0, freqs_ * sizeof(*out_block));
    ++block_count_;
    return;
  }

  // TODO(ekm): Use VAD to |Step| and |AnalyzeClearBlock| only if necessary.
  if (true) {
    clear_variance_.Step(in_block, false);
    if (block_count_ % analysis_rate_ == analysis_rate_ - 1) {
      const float power_target = std::accumulate(
          clear_variance_.variance(), clear_variance_.variance() + freqs_, 0.f);
      AnalyzeClearBlock(power_target);
      ++analysis_step_;
    }
    ++block_count_;
  }

  if (active_) {
    gain_applier_.Apply(in_block, out_block);
  }
}

void IntelligibilityEnhancer::AnalyzeClearBlock(float power_target) {
  FilterVariance(clear_variance_.variance(), filtered_clear_var_.get());
  FilterVariance(noise_variance_.variance(), filtered_noise_var_.get());

  SolveForGainsGivenLambda(kLambdaTop, start_freq_, gains_eq_.get());
  const float power_top =
      DotProduct(gains_eq_.get(), filtered_clear_var_.get(), bank_size_);
  SolveForGainsGivenLambda(kLambdaBot, start_freq_, gains_eq_.get());
  const float power_bot =
      DotProduct(gains_eq_.get(), filtered_clear_var_.get(), bank_size_);
  if (power_target >= power_bot && power_target <= power_top) {
    SolveForLambda(power_target, power_bot, power_top);
    UpdateErbGains();
  }  // Else experiencing variance underflow, so do nothing.
}

void IntelligibilityEnhancer::SolveForLambda(float power_target,
                                             float power_bot,
                                             float power_top) {
  const float kConvergeThresh = 0.001f;  // TODO(ekmeyerson): Find best values
  const int kMaxIters = 100;             // for these, based on experiments.

  const float reciprocal_power_target = 1.f / power_target;
  float lambda_bot = kLambdaBot;
  float lambda_top = kLambdaTop;
  float power_ratio = 2.0f;  // Ratio of achieved power to target power.
  int iters = 0;
  while (std::fabs(power_ratio - 1.0f) > kConvergeThresh &&
         iters <= kMaxIters) {
    const float lambda = lambda_bot + (lambda_top - lambda_bot) / 2.0f;
    SolveForGainsGivenLambda(lambda, start_freq_, gains_eq_.get());
    const float power =
        DotProduct(gains_eq_.get(), filtered_clear_var_.get(), bank_size_);
    if (power < power_target) {
      lambda_bot = lambda;
    } else {
      lambda_top = lambda;
    }
    power_ratio = std::fabs(power * reciprocal_power_target);
    ++iters;
  }
}

void IntelligibilityEnhancer::UpdateErbGains() {
  // (ERB gain) = filterbank' * (freq gain)
  float* gains = gain_applier_.target();
  for (size_t i = 0; i < freqs_; ++i) {
    gains[i] = 0.0f;
    for (size_t j = 0; j < bank_size_; ++j) {
      gains[i] = fmaf(filter_bank_[j][i], gains_eq_[j], gains[i]);
    }
  }
}

void IntelligibilityEnhancer::ProcessNoiseBlock(const complex<float>* in_block,
                                                complex<float>* /*out_block*/) {
  noise_variance_.Step(in_block);
}

size_t IntelligibilityEnhancer::GetBankSize(int sample_rate,
                                            size_t erb_resolution) {
  float freq_limit = sample_rate / 2000.0f;
  size_t erb_scale = static_cast<size_t>(ceilf(
      11.17f * logf((freq_limit + 0.312f) / (freq_limit + 14.6575f)) + 43.0f));
  return erb_scale * erb_resolution;
}

void IntelligibilityEnhancer::CreateErbBank() {
  size_t lf = 1, rf = 4;

  for (size_t i = 0; i < bank_size_; ++i) {
    float abs_temp = fabsf((i + 1.0f) / static_cast<float>(erb_resolution_));
    center_freqs_[i] = 676170.4f / (47.06538f - expf(0.08950404f * abs_temp));
    center_freqs_[i] -= 14678.49f;
  }
  float last_center_freq = center_freqs_[bank_size_ - 1];
  for (size_t i = 0; i < bank_size_; ++i) {
    center_freqs_[i] *= 0.5f * sample_rate_hz_ / last_center_freq;
  }

  for (size_t i = 0; i < bank_size_; ++i) {
    filter_bank_[i].resize(freqs_);
  }

  for (size_t i = 1; i <= bank_size_; ++i) {
    size_t lll, ll, rr, rrr;
    static const size_t kOne = 1;  // Avoids repeated static_cast<>s below.
    lll = static_cast<size_t>(round(
        center_freqs_[max(kOne, i - lf) - 1] * freqs_ /
            (0.5f * sample_rate_hz_)));
    ll = static_cast<size_t>(round(
        center_freqs_[max(kOne, i) - 1] * freqs_ / (0.5f * sample_rate_hz_)));
    lll = min(freqs_, max(lll, kOne)) - 1;
    ll = min(freqs_, max(ll, kOne)) - 1;

    rrr = static_cast<size_t>(round(
        center_freqs_[min(bank_size_, i + rf) - 1] * freqs_ /
            (0.5f * sample_rate_hz_)));
    rr = static_cast<size_t>(round(
        center_freqs_[min(bank_size_, i + 1) - 1] * freqs_ /
            (0.5f * sample_rate_hz_)));
    rrr = min(freqs_, max(rrr, kOne)) - 1;
    rr = min(freqs_, max(rr, kOne)) - 1;

    float step, element;

    step = 1.0f / (ll - lll);
    element = 0.0f;
    for (size_t j = lll; j <= ll; ++j) {
      filter_bank_[i - 1][j] = element;
      element += step;
    }
    step = 1.0f / (rrr - rr);
    element = 1.0f;
    for (size_t j = rr; j <= rrr; ++j) {
      filter_bank_[i - 1][j] = element;
      element -= step;
    }
    for (size_t j = ll; j <= rr; ++j) {
      filter_bank_[i - 1][j] = 1.0f;
    }
  }

  float sum;
  for (size_t i = 0; i < freqs_; ++i) {
    sum = 0.0f;
    for (size_t j = 0; j < bank_size_; ++j) {
      sum += filter_bank_[j][i];
    }
    for (size_t j = 0; j < bank_size_; ++j) {
      filter_bank_[j][i] /= sum;
    }
  }
}

void IntelligibilityEnhancer::SolveForGainsGivenLambda(float lambda,
                                                       size_t start_freq,
                                                       float* sols) {
  bool quadratic = (kConfigRho < 1.0f);
  const float* var_x0 = filtered_clear_var_.get();
  const float* var_n0 = filtered_noise_var_.get();

  for (size_t n = 0; n < start_freq; ++n) {
    sols[n] = 1.0f;
  }

  // Analytic solution for optimal gains. See paper for derivation.
  for (size_t n = start_freq - 1; n < bank_size_; ++n) {
    float alpha0, beta0, gamma0;
    gamma0 = 0.5f * rho_[n] * var_x0[n] * var_n0[n] +
             lambda * var_x0[n] * var_n0[n] * var_n0[n];
    beta0 = lambda * var_x0[n] * (2 - rho_[n]) * var_x0[n] * var_n0[n];
    if (quadratic) {
      alpha0 = lambda * var_x0[n] * (1 - rho_[n]) * var_x0[n] * var_x0[n];
      sols[n] =
          (-beta0 - sqrtf(beta0 * beta0 - 4 * alpha0 * gamma0)) / (2 * alpha0);
    } else {
      sols[n] = -gamma0 / beta0;
    }
    sols[n] = fmax(0, sols[n]);
  }
}

void IntelligibilityEnhancer::FilterVariance(const float* var, float* result) {
  DCHECK_GT(freqs_, 0u);
  for (size_t i = 0; i < bank_size_; ++i) {
    result[i] = DotProduct(&filter_bank_[i][0], var, freqs_);
  }
}

float IntelligibilityEnhancer::DotProduct(const float* a,
                                          const float* b,
                                          size_t length) {
  float ret = 0.0f;

  for (size_t i = 0; i < length; ++i) {
    ret = fmaf(a[i], b[i], ret);
  }
  return ret;
}

bool IntelligibilityEnhancer::active() const {
  return active_;
}

}  // namespace webrtc
