RTS API Documentation  1.10.11
Macros | Functions | Variables
libteletone_detect.c File Reference
#include <libteletone_detect.h>
#include <stdint.h>
#include <string.h>
#include <stdio.h>
#include <time.h>
#include <fcntl.h>
+ Include dependency graph for libteletone_detect.c:

Go to the source code of this file.

Macros

#define LOW_ENG   10000000
 
#define ZC   2
 
#define teletone_goertzel_result(gs)   (double)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac))
 

Functions

static void goertzel_init (teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc)
 
void teletone_goertzel_update (teletone_goertzel_state_t *goertzel_state, int16_t sample_buffer[], int samples)
 Step through the Goertzel Algorithm for each sample in a buffer. More...
 
void teletone_dtmf_detect_init (teletone_dtmf_detect_state_t *dtmf_detect_state, int sample_rate)
 Initilize a DTMF detection state object. More...
 
void teletone_multi_tone_init (teletone_multi_tone_t *mt, teletone_tone_map_t *map)
 Initilize a multi-frequency tone detector. More...
 
int teletone_multi_tone_detect (teletone_multi_tone_t *mt, int16_t sample_buffer[], int samples)
 Check a sample buffer for the presence of the mulit-frequency tone described by mt. More...
 
teletone_hit_type_t teletone_dtmf_detect (teletone_dtmf_detect_state_t *dtmf_detect_state, int16_t sample_buffer[], int samples)
 Check a sample buffer for the presence of DTMF digits. More...
 
int teletone_dtmf_get (teletone_dtmf_detect_state_t *dtmf_detect_state, char *buf, unsigned int *dur)
 retrieve any collected digits into a string buffer More...
 

Variables

static teletone_detection_descriptor_t dtmf_detect_row [GRID_FACTOR]
 
static teletone_detection_descriptor_t dtmf_detect_col [GRID_FACTOR]
 
static teletone_detection_descriptor_t dtmf_detect_row_2nd [GRID_FACTOR]
 
static teletone_detection_descriptor_t dtmf_detect_col_2nd [GRID_FACTOR]
 
static float dtmf_row [] = {697.0f, 770.0f, 852.0f, 941.0f}
 
static float dtmf_col [] = {1209.0f, 1336.0f, 1477.0f, 1633.0f}
 
static char dtmf_positions [] = "123A" "456B" "789C" "*0#D"
 

Macro Definition Documentation

◆ LOW_ENG

#define LOW_ENG   10000000

Definition at line 103 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect().

◆ teletone_goertzel_result

#define teletone_goertzel_result (   gs)    (double)(((gs)->v3 * (gs)->v3 + (gs)->v2 * (gs)->v2 - (gs)->v2 * (gs)->v3 * (gs)->fac))

Definition at line 137 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect(), and teletone_multi_tone_detect().

◆ ZC

#define ZC   2

Definition at line 104 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect().

Function Documentation

◆ goertzel_init()

static void goertzel_init ( teletone_goertzel_state_t goertzel_state,
teletone_detection_descriptor_t tdesc 
)
static

◆ teletone_dtmf_detect()

teletone_hit_type_t teletone_dtmf_detect ( teletone_dtmf_detect_state_t dtmf_detect_state,
int16_t  sample_buffer[],
int  samples 
)

Check a sample buffer for the presence of DTMF digits.

Parameters
dtmf_detect_statethe detection state object to check
sample_bufferan array aof 16 bit signed linear samples
samplesthe number of samples present in sample_buffer
Returns
true when DTMF was detected or false when it is not

Definition at line 307 of file libteletone_detect.c.

References BLOCK_LEN, teletone_dtmf_detect_state_t::col_out, teletone_dtmf_detect_state_t::col_out2nd, teletone_dtmf_detect_state_t::current_digits, teletone_dtmf_detect_state_t::current_sample, teletone_dtmf_detect_state_t::detected_digits, teletone_dtmf_detect_state_t::digit, teletone_dtmf_detect_state_t::digit_hits, DTMF_2ND_HARMONIC_COL, DTMF_2ND_HARMONIC_ROW, DTMF_NORMAL_TWIST, dtmf_positions, DTMF_RELATIVE_PEAK_COL, DTMF_RELATIVE_PEAK_ROW, DTMF_REVERSE_TWIST, DTMF_THRESHOLD, teletone_dtmf_detect_state_t::dur, teletone_dtmf_detect_state_t::energy, teletone_goertzel_state_t::fac, goertzel_init(), GRID_FACTOR, teletone_dtmf_detect_state_t::hit1, teletone_dtmf_detect_state_t::hit2, teletone_dtmf_detect_state_t::hit3, teletone_dtmf_detect_state_t::lenergy, teletone_dtmf_detect_state_t::lost_digits, LOW_ENG, teletone_dtmf_detect_state_t::row_out, teletone_dtmf_detect_state_t::row_out2nd, teletone_goertzel_result, TELETONE_MAX_DTMF_DIGITS, TT_HIT_BEGIN, TT_HIT_END, TT_HIT_MIDDLE, teletone_goertzel_state_t::v2, teletone_goertzel_state_t::v3, ZC, and teletone_dtmf_detect_state_t::zc.

Referenced by inband_dtmf_callback().

310 {
311  float row_energy[GRID_FACTOR];
312  float col_energy[GRID_FACTOR];
313  float famp;
314  float v1;
315  int i;
316  int j;
317  int sample;
318  int best_row;
319  int best_col;
320  char hit = 0;
321  int limit;
322  teletone_hit_type_t r = 0;
323 
324  for (sample = 0; sample < samples; sample = limit) {
325  /* BLOCK_LEN is optimised to meet the DTMF specs. */
326  if ((samples - sample) >= (BLOCK_LEN - dtmf_detect_state->current_sample)) {
327  limit = sample + (BLOCK_LEN - dtmf_detect_state->current_sample);
328  } else {
329  limit = samples;
330  }
331 
332  for (j = sample; j < limit; j++) {
333  int x = 0;
334  famp = sample_buffer[j];
335 
336  dtmf_detect_state->energy += famp*famp;
337 
338  for(x = 0; x < GRID_FACTOR; x++) {
339  v1 = dtmf_detect_state->row_out[x].v2;
340  dtmf_detect_state->row_out[x].v2 = dtmf_detect_state->row_out[x].v3;
341  dtmf_detect_state->row_out[x].v3 = (float)(dtmf_detect_state->row_out[x].fac*dtmf_detect_state->row_out[x].v2 - v1 + famp);
342 
343  v1 = dtmf_detect_state->col_out[x].v2;
344  dtmf_detect_state->col_out[x].v2 = dtmf_detect_state->col_out[x].v3;
345  dtmf_detect_state->col_out[x].v3 = (float)(dtmf_detect_state->col_out[x].fac*dtmf_detect_state->col_out[x].v2 - v1 + famp);
346 
347  v1 = dtmf_detect_state->col_out2nd[x].v2;
348  dtmf_detect_state->col_out2nd[x].v2 = dtmf_detect_state->col_out2nd[x].v3;
349  dtmf_detect_state->col_out2nd[x].v3 = (float)(dtmf_detect_state->col_out2nd[x].fac*dtmf_detect_state->col_out2nd[x].v2 - v1 + famp);
350 
351  v1 = dtmf_detect_state->row_out2nd[x].v2;
352  dtmf_detect_state->row_out2nd[x].v2 = dtmf_detect_state->row_out2nd[x].v3;
353  dtmf_detect_state->row_out2nd[x].v3 = (float)(dtmf_detect_state->row_out2nd[x].fac*dtmf_detect_state->row_out2nd[x].v2 - v1 + famp);
354  }
355 
356  }
357 
358  if (dtmf_detect_state->zc > 0) {
359  if (dtmf_detect_state->energy < LOW_ENG && dtmf_detect_state->lenergy < LOW_ENG) {
360  if (!--dtmf_detect_state->zc) {
361  /* Reinitialise the detector for the next block */
362  dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
363  for (i = 0; i < GRID_FACTOR; i++) {
364  goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
365  goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
366  goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
367  goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
368  }
369  dtmf_detect_state->dur -= samples;
370  return TT_HIT_END;
371  }
372  }
373 
374  dtmf_detect_state->dur += samples;
375  dtmf_detect_state->lenergy = dtmf_detect_state->energy;
376  dtmf_detect_state->energy = 0.0;
377  dtmf_detect_state->current_sample = 0;
378  return TT_HIT_MIDDLE;
379  } else if (dtmf_detect_state->digit) {
380  return TT_HIT_END;
381  }
382 
383 
384  dtmf_detect_state->current_sample += (limit - sample);
385  if (dtmf_detect_state->current_sample < BLOCK_LEN) {
386  continue;
387  }
388  /* We are at the end of a DTMF detection block */
389  /* Find the peak row and the peak column */
390  row_energy[0] = teletone_goertzel_result (&dtmf_detect_state->row_out[0]);
391  col_energy[0] = teletone_goertzel_result (&dtmf_detect_state->col_out[0]);
392 
393  for (best_row = best_col = 0, i = 1; i < GRID_FACTOR; i++) {
394  row_energy[i] = teletone_goertzel_result (&dtmf_detect_state->row_out[i]);
395  if (row_energy[i] > row_energy[best_row]) {
396  best_row = i;
397  }
398  col_energy[i] = teletone_goertzel_result (&dtmf_detect_state->col_out[i]);
399  if (col_energy[i] > col_energy[best_col]) {
400  best_col = i;
401  }
402  }
403  hit = 0;
404  /* Basic signal level test and the twist test */
405  if (row_energy[best_row] >= DTMF_THRESHOLD &&
406  col_energy[best_col] >= DTMF_THRESHOLD &&
407  col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
408  col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
409  /* Relative peak test */
410  for (i = 0; i < GRID_FACTOR; i++) {
411  if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
412  (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
413  break;
414  }
415  }
416  /* ... and second harmonic test */
417  if (i >= GRID_FACTOR && (row_energy[best_row] + col_energy[best_col]) > 42.0*dtmf_detect_state->energy &&
418  teletone_goertzel_result (&dtmf_detect_state->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col] &&
419  teletone_goertzel_result (&dtmf_detect_state->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
420  hit = dtmf_positions[(best_row << 2) + best_col];
421  /* Look for two successive similar results */
422  /* The logic in the next test is:
423  We need two successive identical clean detects, with
424  something different preceeding it. This can work with
425  back to back differing digits. More importantly, it
426  can work with nasty phones that give a very wobbly start
427  to a digit. */
428  if (! r && hit == dtmf_detect_state->hit3 && dtmf_detect_state->hit3 != dtmf_detect_state->hit2) {
429  dtmf_detect_state->digit_hits[(best_row << 2) + best_col]++;
430  dtmf_detect_state->detected_digits++;
431  if (dtmf_detect_state->current_digits < TELETONE_MAX_DTMF_DIGITS) {
432  dtmf_detect_state->digit = hit;
433  } else {
434  dtmf_detect_state->lost_digits++;
435  }
436 
437  if (!dtmf_detect_state->zc) {
438  dtmf_detect_state->zc = ZC;
439  dtmf_detect_state->dur = 0;
440  r = TT_HIT_BEGIN;
441  break;
442  }
443 
444  }
445  }
446  }
447 
448  dtmf_detect_state->hit1 = dtmf_detect_state->hit2;
449  dtmf_detect_state->hit2 = dtmf_detect_state->hit3;
450  dtmf_detect_state->hit3 = hit;
451 
452  dtmf_detect_state->energy = 0.0;
453  dtmf_detect_state->current_sample = 0;
454 
455  }
456 
457  return r;
458 }
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR]
#define DTMF_THRESHOLD
teletone_goertzel_state_t row_out[GRID_FACTOR]
#define ZC
#define LOW_ENG
teletone_hit_type_t
#define GRID_FACTOR
#define DTMF_RELATIVE_PEAK_COL
teletone_goertzel_state_t row_out2nd[GRID_FACTOR]
teletone_goertzel_state_t col_out2nd[GRID_FACTOR]
#define BLOCK_LEN
#define TELETONE_MAX_DTMF_DIGITS
Definition: libteletone.h:80
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR]
static char dtmf_positions[]
#define DTMF_RELATIVE_PEAK_ROW
#define DTMF_NORMAL_TWIST
#define teletone_goertzel_result(gs)
static teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR]
static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc)
#define DTMF_2ND_HARMONIC_COL
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR]
teletone_goertzel_state_t col_out[GRID_FACTOR]
#define DTMF_2ND_HARMONIC_ROW
#define DTMF_REVERSE_TWIST

◆ teletone_dtmf_detect_init()

void teletone_dtmf_detect_init ( teletone_dtmf_detect_state_t dtmf_detect_state,
int  sample_rate 
)

Initilize a DTMF detection state object.

Parameters
dtmf_detect_statethe DTMF detection state to initilize
sample_ratethe desired sample rate

Definition at line 139 of file libteletone_detect.c.

References teletone_dtmf_detect_state_t::col_out, teletone_dtmf_detect_state_t::col_out2nd, teletone_dtmf_detect_state_t::current_sample, teletone_dtmf_detect_state_t::detected_digits, teletone_dtmf_detect_state_t::digit, dtmf_col, dtmf_row, teletone_dtmf_detect_state_t::dur, teletone_dtmf_detect_state_t::energy, teletone_detection_descriptor_t::fac, goertzel_init(), GRID_FACTOR, teletone_dtmf_detect_state_t::hit1, teletone_dtmf_detect_state_t::hit2, teletone_dtmf_detect_state_t::lost_digits, M_TWO_PI, teletone_dtmf_detect_state_t::row_out, and teletone_dtmf_detect_state_t::row_out2nd.

Referenced by switch_ivr_inband_dtmf_session().

140 {
141  int i;
142  float theta;
143 
144  if (!sample_rate) {
145  sample_rate = 8000;
146  }
147 
148  dtmf_detect_state->hit1 = dtmf_detect_state->hit2 = 0;
149 
150  for (i = 0; i < GRID_FACTOR; i++) {
151  theta = (float)(M_TWO_PI*(dtmf_row[i]/(float)sample_rate));
152  dtmf_detect_row[i].fac = (float)(2.0*cos(theta));
153 
154  theta = (float)(M_TWO_PI*(dtmf_col[i]/(float)sample_rate));
155  dtmf_detect_col[i].fac = (float)(2.0*cos(theta));
156 
157  theta = (float)(M_TWO_PI*(dtmf_row[i]*2.0/(float)sample_rate));
158  dtmf_detect_row_2nd[i].fac = (float)(2.0*cos(theta));
159 
160  theta = (float)(M_TWO_PI*(dtmf_col[i]*2.0/(float)sample_rate));
161  dtmf_detect_col_2nd[i].fac = (float)(2.0*cos(theta));
162 
163  goertzel_init (&dtmf_detect_state->row_out[i], &dtmf_detect_row[i]);
164  goertzel_init (&dtmf_detect_state->col_out[i], &dtmf_detect_col[i]);
165  goertzel_init (&dtmf_detect_state->row_out2nd[i], &dtmf_detect_row_2nd[i]);
166  goertzel_init (&dtmf_detect_state->col_out2nd[i], &dtmf_detect_col_2nd[i]);
167 
168  dtmf_detect_state->energy = 0.0;
169  }
170  dtmf_detect_state->current_sample = 0;
171  dtmf_detect_state->detected_digits = 0;
172  dtmf_detect_state->lost_digits = 0;
173  dtmf_detect_state->digit = 0;
174  dtmf_detect_state->dur = 0;
175 }
static teletone_detection_descriptor_t dtmf_detect_row[GRID_FACTOR]
teletone_goertzel_state_t row_out[GRID_FACTOR]
#define GRID_FACTOR
static float dtmf_col[]
teletone_goertzel_state_t row_out2nd[GRID_FACTOR]
static float dtmf_row[]
teletone_goertzel_state_t col_out2nd[GRID_FACTOR]
static teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR]
#define M_TWO_PI
static teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR]
static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc)
static teletone_detection_descriptor_t dtmf_detect_col[GRID_FACTOR]
teletone_goertzel_state_t col_out[GRID_FACTOR]

◆ teletone_dtmf_get()

int teletone_dtmf_get ( teletone_dtmf_detect_state_t dtmf_detect_state,
char *  buf,
unsigned int *  dur 
)

retrieve any collected digits into a string buffer

Parameters
dtmf_detect_statethe detection state object to check
bufthe string buffer to write to
maxthe maximum length of buf
Returns
the number of characters written to buf

Definition at line 461 of file libteletone_detect.c.

References teletone_dtmf_detect_state_t::digit, teletone_dtmf_detect_state_t::dur, and teletone_dtmf_detect_state_t::zc.

Referenced by inband_dtmf_callback().

462 {
463  if (!dtmf_detect_state->digit) {
464  return 0;
465  }
466 
467  *buf = dtmf_detect_state->digit;
468 
469  *dur = dtmf_detect_state->dur;
470 
471  if (!dtmf_detect_state->zc) {
472  dtmf_detect_state->dur = 0;
473  dtmf_detect_state->digit = 0;
474  }
475 
476  return 1;
477 }
switch_byte_t switch_byte_t * buf

◆ teletone_goertzel_update()

void teletone_goertzel_update ( teletone_goertzel_state_t goertzel_state,
int16_t  sample_buffer[],
int  samples 
)

Step through the Goertzel Algorithm for each sample in a buffer.

Parameters
goertzel_statethe goertzel state to step the samples through
sample_bufferan array aof 16 bit signed linear samples
samplesthe number of samples present in sample_buffer

Definition at line 120 of file libteletone_detect.c.

References teletone_goertzel_state_t::fac, teletone_goertzel_state_t::v2, and teletone_goertzel_state_t::v3.

123 {
124  int i;
125  float v1;
126 
127  for (i = 0; i < samples; i++) {
128  v1 = goertzel_state->v2;
129  goertzel_state->v2 = goertzel_state->v3;
130  goertzel_state->v3 = (float)(goertzel_state->fac*goertzel_state->v2 - v1 + sample_buffer[i]);
131  }
132 }

◆ teletone_multi_tone_detect()

int teletone_multi_tone_detect ( teletone_multi_tone_t mt,
int16_t  sample_buffer[],
int  samples 
)

Check a sample buffer for the presence of the mulit-frequency tone described by mt.

Parameters
mtthe multi-frequency tone descriptor
sample_bufferan array aof 16 bit signed linear samples
samplesthe number of samples present in sample_buffer
Returns
true when the tone was detected or false when it is not

Definition at line 217 of file libteletone_detect.c.

References teletone_multi_tone_t::current_sample, teletone_multi_tone_t::energy, teletone_goertzel_state_t::fac, goertzel_init(), teletone_multi_tone_t::gs, teletone_multi_tone_t::gs2, teletone_multi_tone_t::hit_factor, teletone_multi_tone_t::hits, teletone_multi_tone_t::min_samples, teletone_multi_tone_t::negative_factor, teletone_multi_tone_t::negatives, teletone_multi_tone_t::positive_factor, teletone_multi_tone_t::positives, teletone_multi_tone_t::tdd, teletone_goertzel_result, TELETONE_MAX_TONES, teletone_multi_tone_t::tone_count, teletone_multi_tone_t::total_samples, teletone_goertzel_state_t::v2, and teletone_goertzel_state_t::v3.

Referenced by tone_detect_callback().

220 {
221  int sample, limit = 0, j, x = 0;
222  float v1, famp;
223  float eng_sum = 0, eng_all[TELETONE_MAX_TONES] = {0.0};
224  int gtest = 0, see_hit = 0;
225 
226  for (sample = 0; sample >= 0 && sample < samples; sample = limit) {
227  mt->total_samples++;
228 
229  if ((samples - sample) >= (mt->min_samples - mt->current_sample)) {
230  limit = sample + (mt->min_samples - mt->current_sample);
231  } else {
232  limit = samples;
233  }
234  if (limit < 0 || limit > samples) {
235  limit = samples;
236  }
237 
238  for (j = sample; j < limit; j++) {
239  famp = sample_buffer[j];
240 
241  mt->energy += famp*famp;
242 
243  for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
244  v1 = mt->gs[x].v2;
245  mt->gs[x].v2 = mt->gs[x].v3;
246  mt->gs[x].v3 = (float)(mt->gs[x].fac * mt->gs[x].v2 - v1 + famp);
247 
248  v1 = mt->gs2[x].v2;
249  mt->gs2[x].v2 = mt->gs2[x].v3;
250  mt->gs2[x].v3 = (float)(mt->gs2[x].fac*mt->gs2[x].v2 - v1 + famp);
251  }
252  }
253 
254  mt->current_sample += (limit - sample);
255  if (mt->current_sample < mt->min_samples) {
256  continue;
257  }
258 
259  eng_sum = 0;
260  for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
261  eng_all[x] = (float)(teletone_goertzel_result (&mt->gs[x]));
262  eng_sum += eng_all[x];
263  }
264 
265  gtest = 0;
266  for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
267  gtest += teletone_goertzel_result (&mt->gs2[x]) < eng_all[x] ? 1 : 0;
268  }
269 
270  if ((gtest >= 2 || gtest == mt->tone_count) && eng_sum > 42.0 * mt->energy) {
271  if(mt->negatives) {
272  mt->negatives--;
273  }
274  mt->positives++;
275 
276  if(mt->positives >= mt->positive_factor) {
277  mt->hits++;
278  }
279  if (mt->hits >= mt->hit_factor) {
280  see_hit++;
281  mt->positives = mt->negatives = mt->hits = 0;
282  }
283  } else {
284  mt->negatives++;
285  if(mt->positives) {
286  mt->positives--;
287  }
288  if(mt->negatives > mt->negative_factor) {
289  mt->positives = mt->hits = 0;
290  }
291  }
292 
293  /* Reinitialise the detector for the next block */
294  for(x = 0; x < TELETONE_MAX_TONES && x < mt->tone_count; x++) {
295  goertzel_init (&mt->gs[x], &mt->tdd[x]);
296  goertzel_init (&mt->gs2[x], &mt->tdd[x]);
297  }
298 
299  mt->energy = 0.0;
300  mt->current_sample = 0;
301  }
302 
303  return see_hit;
304 }
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
teletone_goertzel_state_t gs[TELETONE_MAX_TONES]
teletone_goertzel_state_t gs2[TELETONE_MAX_TONES]
#define teletone_goertzel_result(gs)
static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc)
teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES]

◆ teletone_multi_tone_init()

void teletone_multi_tone_init ( teletone_multi_tone_t mt,
teletone_tone_map_t map 
)

Initilize a multi-frequency tone detector.

Parameters
mtthe multi-frequency tone descriptor
mapa representation of the multi-frequency tone

Definition at line 177 of file libteletone_detect.c.

References teletone_detection_descriptor_t::fac, teletone_tone_map_t::freqs, goertzel_init(), teletone_multi_tone_t::gs, teletone_multi_tone_t::gs2, teletone_multi_tone_t::hit_factor, M_TWO_PI, teletone_multi_tone_t::min_samples, teletone_multi_tone_t::negative_factor, teletone_multi_tone_t::positive_factor, teletone_multi_tone_t::sample_rate, teletone_multi_tone_t::tdd, TELETONE_MAX_TONES, and teletone_multi_tone_t::tone_count.

Referenced by switch_ivr_tone_detect_session().

178 {
179  float theta = 0;
180  int x = 0;
181 
182  if (!mt->sample_rate) {
183  mt->sample_rate = 8000;
184  }
185 
186  if (!mt->min_samples) {
187  mt->min_samples = 102;
188  }
189 
190  mt->min_samples *= (mt->sample_rate / 8000);
191 
192  if (!mt->positive_factor) {
193  mt->positive_factor = 2;
194  }
195 
196  if(!mt->negative_factor) {
197  mt->negative_factor = 10;
198  }
199 
200  if (!mt->hit_factor) {
201  mt->hit_factor = 2;
202  }
203 
204  for(x = 0; x < TELETONE_MAX_TONES; x++) {
205  if ((int) map->freqs[x] == 0) {
206  break;
207  }
208  mt->tone_count++;
209  theta = (float)(M_TWO_PI*(map->freqs[x]/(float)mt->sample_rate));
210  mt->tdd[x].fac = (float)(2.0 * cos(theta));
211  goertzel_init (&mt->gs[x], &mt->tdd[x]);
212  goertzel_init (&mt->gs2[x], &mt->tdd[x]);
213  }
214 
215 }
#define TELETONE_MAX_TONES
Definition: libteletone.h:81
teletone_goertzel_state_t gs[TELETONE_MAX_TONES]
teletone_process_t freqs[TELETONE_MAX_TONES]
Definition: libteletone.h:95
teletone_goertzel_state_t gs2[TELETONE_MAX_TONES]
#define M_TWO_PI
static void goertzel_init(teletone_goertzel_state_t *goertzel_state, teletone_detection_descriptor_t *tdesc)
teletone_detection_descriptor_t tdd[TELETONE_MAX_TONES]

Variable Documentation

◆ dtmf_col

float dtmf_col[] = {1209.0f, 1336.0f, 1477.0f, 1633.0f}
static

Definition at line 111 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect_init().

◆ dtmf_detect_col

Definition at line 106 of file libteletone_detect.c.

◆ dtmf_detect_col_2nd

teletone_detection_descriptor_t dtmf_detect_col_2nd[GRID_FACTOR]
static

Definition at line 108 of file libteletone_detect.c.

◆ dtmf_detect_row

Definition at line 105 of file libteletone_detect.c.

◆ dtmf_detect_row_2nd

teletone_detection_descriptor_t dtmf_detect_row_2nd[GRID_FACTOR]
static

Definition at line 107 of file libteletone_detect.c.

◆ dtmf_positions

char dtmf_positions[] = "123A" "456B" "789C" "*0#D"
static

Definition at line 113 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect().

◆ dtmf_row

float dtmf_row[] = {697.0f, 770.0f, 852.0f, 941.0f}
static

Definition at line 110 of file libteletone_detect.c.

Referenced by teletone_dtmf_detect_init().