/*---------------------------------------------------------------------------*/
/*
  File: noisesup.h

  Noise suppression.
*/
/*---------------------------------------------------------------------------*/

#ifndef NOISESUP_H_
#define NOISESUP_H_

#ifndef SDSPUTIL_H_
#include "sdsputil.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif
/*---------------------------------------------------------------------------*/

#define NOISESUPP_SAMPLE_RATE             16000
#define NOISESUPP_SAMPLE_RATE_HALF        (NOISESUPP_SAMPLE_RATE >> 1)
#define NOISESUPP_FFT_SIZE_EXP            9
#define NOISESUPP_FFT_SIZE_HALF           (1 << (NOISESUPP_FFT_SIZE_EXP - 1))
#define NOISESUPP_FFT_SIZE                (1 << NOISESUPP_FFT_SIZE_EXP)
#define NOISESUPP_BLOCK_SIZE              NOISESUPP_FFT_SIZE_HALF
#define NOISESUPP_FREQ_GROUP_COUNT_EXP    4
#define NOISESUPP_FREQ_GROUP_COUNT        (1 << NOISESUPP_FREQ_GROUP_COUNT_EXP)
#define NOISESUPP_FREQ_GROUP_TAPS_EXP     (NOISESUPP_FFT_SIZE_EXP - 1 - NOISESUPP_FREQ_GROUP_COUNT_EXP)
#define NOISESUPP_FREQ_GROUP_TAPS         (1 << NOISESUPP_FREQ_GROUP_TAPS_EXP)
#define NOISESUPP_ENERGY_HISTORY_SIZE     12
#define NOISESUPP_MAGNITUDE_WORDS         NOISESUPP_FFT_SIZE_HALF
#define NOISESUPP_ATTENUATION_WORDS       NOISESUPP_FFT_SIZE_HALF


typedef struct tag_noise_suppressor
{
  t_complex_short *fft_buffer;
  short last_input[NOISESUPP_FFT_SIZE_HALF];
  short last_output[NOISESUPP_FFT_SIZE_HALF];
  dword noise_magnitudes[NOISESUPP_FFT_SIZE_HALF];
  word *magnitude_buffer;
  word *attenuations;

  short energy_history_table[NOISESUPP_FREQ_GROUP_COUNT][NOISESUPP_ENERGY_HISTORY_SIZE];
  word energy_history_pos_table[NOISESUPP_FREQ_GROUP_COUNT];

  short sample_block[NOISESUPP_FFT_SIZE_HALF];
  word sample_pos;
  byte voice_active;
} t_noise_suppressor;


void noise_suppressor_init (t_noise_suppressor *p_noisesupp,
  t_complex_short *fft_buffer,
  word *magnitude_buffer, word *attenuations);
void noise_suppressor_process (t_noise_suppressor *p_noisesupp,
  short *input_sample_block, short *output_sample_block);
void noise_suppressor_exec (t_noise_suppressor *p_noisesupp,
  short *sample_buffer, word sample_count);
#define noise_suppressor_voice_active(p_noisesupp) ((p_noisesupp)->voice_active)


/*---------------------------------------------------------------------------*/
#ifdef __cplusplus
}
#endif

#endif

/*---------------------------------------------------------------------------*/
