#ifndef SDTMF_H_
#define SDTMF_H_
/*---------------------------------------------------------------------------*/
/* sdtmf.h                                                                   */
/* copyright (c) innovaphone 2012                                            */
/*                                                                           */
/*---------------------------------------------------------------------------*/

NAMESPACE_BEGIN

#define SDTMF_TONE_INDEX_697_1209       0
#define SDTMF_TONE_INDEX_770_1209       1
#define SDTMF_TONE_INDEX_852_1209       2
#define SDTMF_TONE_INDEX_941_1209       3
#define SDTMF_TONE_INDEX_697_1336       4
#define SDTMF_TONE_INDEX_770_1336       5
#define SDTMF_TONE_INDEX_852_1336       6
#define SDTMF_TONE_INDEX_941_1336       7
#define SDTMF_TONE_INDEX_697_1477       8
#define SDTMF_TONE_INDEX_770_1477       9
#define SDTMF_TONE_INDEX_852_1477       10
#define SDTMF_TONE_INDEX_941_1477       11
#define SDTMF_TONE_INDEX_697_1633       12
#define SDTMF_TONE_INDEX_770_1633       13
#define SDTMF_TONE_INDEX_852_1633       14
#define SDTMF_TONE_INDEX_941_1633       15
#define SDTMF_TONE_INDEX_SILENCE        16
#define SDTMF_TONE_COUNT                17


typedef struct sdtmf_generator_s
{
  word state;
  word counter;
  word sample_period;
  word sample_pos;
  const short *sample_table;
  word tone_duration;
  word gap_duration;
} t_sdtmf_generator;


void sdtmf_generator_init (t_sdtmf_generator *p_generator);
void sdtmf_generator_start (t_sdtmf_generator *p_generator,
  word tone_index, word tone_duration, word gap_duration);
word sdtmf_generator_exec (t_sdtmf_generator *p_generator,
  short *sample_buffer, word sample_count, word sample_rate);
byte sdtmf_generator_active (t_sdtmf_generator *p_generator);


#define SDTMF_DIGIT_CODE_0              0x07
#define SDTMF_DIGIT_CODE_1              0x00
#define SDTMF_DIGIT_CODE_2              0x04
#define SDTMF_DIGIT_CODE_3              0x08
#define SDTMF_DIGIT_CODE_4              0x01
#define SDTMF_DIGIT_CODE_5              0x05
#define SDTMF_DIGIT_CODE_6              0x09
#define SDTMF_DIGIT_CODE_7              0x02
#define SDTMF_DIGIT_CODE_8              0x06
#define SDTMF_DIGIT_CODE_9              0x0a
#define SDTMF_DIGIT_CODE_STAR           0x03
#define SDTMF_DIGIT_CODE_HASHMARK       0x0b
#define SDTMF_DIGIT_CODE_A              0x0c
#define SDTMF_DIGIT_CODE_B              0x0d
#define SDTMF_DIGIT_CODE_C              0x0e
#define SDTMF_DIGIT_CODE_D              0x0f

#define SDTMF_MF_DIGIT_CODE_1           0x10
#define SDTMF_MF_DIGIT_CODE_2           0x11
#define SDTMF_MF_DIGIT_CODE_3           0x12
#define SDTMF_MF_DIGIT_CODE_4           0x13
#define SDTMF_MF_DIGIT_CODE_5           0x14
#define SDTMF_MF_DIGIT_CODE_6           0x15
#define SDTMF_MF_DIGIT_CODE_7           0x16
#define SDTMF_MF_DIGIT_CODE_8           0x17
#define SDTMF_MF_DIGIT_CODE_9           0x18
#define SDTMF_MF_DIGIT_CODE_0           0x19
#define SDTMF_MF_DIGIT_CODE_K1          0x1a
#define SDTMF_MF_DIGIT_CODE_K2          0x1b
#define SDTMF_MF_DIGIT_CODE_KP          0x1c
#define SDTMF_MF_DIGIT_CODE_S1          0x1d
#define SDTMF_MF_DIGIT_CODE_ST          0x1e
#define SDTMF_MF_DIGIT_CODE_NONE        0x1f


#define SDTMF_DETECTOR_MAX_FREQUENCIES      16
#define SDTMF_DETECTOR_DIGIT_BUFFER_SIZE    512

typedef struct sdtmf_detector_s
{
  unsigned total_frequencies;
  unsigned accumulate_cycles;
  const short *p_window_function;
  int32 goertzel_coef_table[SDTMF_DETECTOR_MAX_FREQUENCIES];
  int32 fundamental_offset;
  int32 fundamental_decrement;
  word low_group_min_level;
  word high_group_min_level;
  word max_high_low_twist;
  word max_low_high_twist;
  word guard_snr;
  unsigned min_gap_duration;
  unsigned min_digit_duration;
  bool dtmf_mode;
  byte digit_code_offset;

  int32 goertzel_buffer[2][SDTMF_DETECTOR_MAX_FREQUENCIES];
  unsigned decimation_counter;
  unsigned cycle_counter;
  unsigned current_digit_on_time;
  unsigned current_digit_off_time;
  byte current_digit_value;
  byte current_digit_ind;
} t_sdtmf_detector;


void sdtmf_detector_init (t_sdtmf_detector *p_detector);
word sdtmf_detector_exec (t_sdtmf_detector *p_detector,
  const short *sample_buffer, word sample_count, word sample_rate, byte *digit_buffer);

NAMESPACE_END

/*---------------------------------------------------------------------------*/
#endif /* SDTMF_H_ */
