Wed Jan 8 2020 09:50:11

Asterisk developer's documentation


dsp.c File Reference

Convenience Signal Processing routines. More...

#include "asterisk.h"
#include <math.h>
#include "asterisk/frame.h"
#include "asterisk/channel.h"
#include "asterisk/dsp.h"
#include "asterisk/ulaw.h"
#include "asterisk/alaw.h"
#include "asterisk/utils.h"
#include "asterisk/options.h"
#include "asterisk/config.h"

Go to the source code of this file.

Data Structures

struct  ast_dsp
 
struct  digit_detect_state_t
 
struct  dtmf_detect_state_t
 
struct  fragment_t
 
struct  goertzel_result_t
 
struct  goertzel_state_t
 
struct  mf_detect_state_t
 
struct  progalias
 
struct  progress
 
struct  tone_detect_state_t
 

Macros

#define BELL_MF_RELATIVE_PEAK   12.6 /* 11dB */
 
#define BELL_MF_THRESHOLD   1.6e9
 
#define BELL_MF_TWIST   4.0 /* 6dB */
 
#define CONFIG_FILE_NAME   "dsp.conf"
 
#define DEF_DTMF_HITS_TO_BEGIN   2
 
#define DEF_DTMF_MISSES_TO_END   3
 
#define DEF_DTMF_NORMAL_TWIST   6.31 /* 8.0dB */
 
#define DEF_DTMF_REVERSE_TWIST   2.51 /* 4.01dB */
 
#define DEF_RELAX_DTMF_NORMAL_TWIST   6.31 /* 8.0dB */
 
#define DEF_RELAX_DTMF_REVERSE_TWIST   3.98 /* 6.0dB */
 
#define DEFAULT_THRESHOLD   512
 This value is the minimum threshold, calculated by averaging all of the samples within a frame, for which a frame is determined to either be silence (below the threshold) or noise (above the threshold). Please note that while the default threshold is an even exponent of 2, there is no requirement that it be so. The threshold will accept any value between 0 and 32767. More...
 
#define DSP_HISTORY   15
 
#define DTMF_2ND_HARMONIC_COL   63.1 /* 18dB */
 
#define DTMF_2ND_HARMONIC_ROW   (relax ? 1.7 : 2.5) /* 4dB normal */
 
#define DTMF_GSIZE   102
 
#define DTMF_RELATIVE_PEAK_COL   6.3 /* 8dB */
 
#define DTMF_RELATIVE_PEAK_ROW   6.3 /* 8dB */
 
#define DTMF_THRESHOLD   8.0e7
 
#define DTMF_TO_TOTAL_ENERGY   42.0
 
#define FAX_2ND_HARMONIC   2.0 /* 4dB */
 
#define FAX_THRESHOLD   8.0e7
 
#define FAX_TONE_CED_DB   16
 
#define FAX_TONE_CED_DURATION   2600
 
#define FAX_TONE_CED_FREQ   2100
 
#define FAX_TONE_CNG_DB   16
 
#define FAX_TONE_CNG_DURATION   500
 
#define FAX_TONE_CNG_FREQ   1100
 
#define MAX_DTMF_DIGITS   128
 
#define MF_GSIZE   120
 
#define SAMPLE_RATE   8000
 
#define SAMPLES_IN_FRAME   160
 
#define TONE_MIN_THRESH   1e8
 
#define TONE_THRESH   10.0
 

Enumerations

enum  busy_detect {
  BUSY_PERCENT = 10, BUSY_PAT_PERCENT = 8, BUSY_THRESHOLD = 100, BUSY_MIN = 150,
  BUSY_MAX = 600
}
 
enum  freq_index {
  HZ_350 = 0, HZ_440, HZ_480, HZ_620,
  HZ_950, HZ_1400, HZ_1800, HZ_425 = 0,
  HZ_350UK = 0, HZ_400UK, HZ_440UK
}
 
enum  gsamp_size { GSAMP_SIZE_NA = 183, GSAMP_SIZE_CR = 188, GSAMP_SIZE_UK = 160 }
 
enum  gsamp_thresh {
  THRESH_RING = 8, THRESH_TALK = 2, THRESH_BUSY = 4, THRESH_CONGESTION = 4,
  THRESH_HANGUP = 60, THRESH_RING2ANSWER = 300
}
 
enum  prog_mode { PROG_MODE_NA = 0, PROG_MODE_CR, PROG_MODE_UK }
 

Functions

static int __ast_dsp_call_progress (struct ast_dsp *dsp, short *s, int len)
 
static int __ast_dsp_silence_noise (struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
 
static int _dsp_init (int reload)
 
static void ast_digit_detect_init (digit_detect_state_t *s, int mf)
 
int ast_dsp_busydetect (struct ast_dsp *dsp)
 Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called. More...
 
int ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf)
 Scans for progress indication in audio. More...
 
void ast_dsp_digitreset (struct ast_dsp *dsp)
 Reset DTMF detector. More...
 
void ast_dsp_free (struct ast_dsp *dsp)
 
int ast_dsp_get_tcount (struct ast_dsp *dsp)
 Get tcount (Threshold counter) More...
 
int ast_dsp_get_threshold_from_settings (enum threshold which)
 Get silence threshold from dsp.conf. More...
 
int ast_dsp_get_tstate (struct ast_dsp *dsp)
 Get tstate (Tone State) More...
 
int ast_dsp_init (void)
 Load dsp settings from dsp.conf. More...
 
struct ast_dspast_dsp_new (void)
 
int ast_dsp_noise (struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
 Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise. More...
 
struct ast_frameast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
 Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled. More...
 
static void ast_dsp_prog_reset (struct ast_dsp *dsp)
 
int ast_dsp_reload (void)
 Reloads dsp settings from dsp.conf. More...
 
void ast_dsp_reset (struct ast_dsp *dsp)
 Reset total silence count. More...
 
void ast_dsp_set_busy_compare (struct ast_dsp *dsp, int compare)
 Set if silence and noice lengths must be compared for busy. More...
 
void ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences)
 Set number of required cadences for busy. More...
 
void ast_dsp_set_busy_pattern (struct ast_dsp *dsp, int tonelength, int quietlength, int fuzzy)
 Set expected lengths of the busy tones. More...
 
int ast_dsp_set_call_progress_zone (struct ast_dsp *dsp, char *zone)
 Set zone for doing progress detection. More...
 
int ast_dsp_set_digitmode (struct ast_dsp *dsp, int digitmode)
 Set digit mode. More...
 
int ast_dsp_set_faxmode (struct ast_dsp *dsp, int faxmode)
 Set fax mode. More...
 
void ast_dsp_set_features (struct ast_dsp *dsp, int features)
 Select feature set. More...
 
void ast_dsp_set_threshold (struct ast_dsp *dsp, int threshold)
 Set threshold value for silence. More...
 
int ast_dsp_silence (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
 Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence. More...
 
int ast_dsp_was_muted (struct ast_dsp *dsp)
 Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio. More...
 
static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
 
static void ast_fax_detect_init (struct ast_dsp *s)
 
static void ast_mf_detect_init (mf_detect_state_t *s)
 
static void ast_tone_detect_init (tone_detect_state_t *s, int freq, int duration, int amp)
 
static int dtmf_detect (struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
 
static void goertzel_init (goertzel_state_t *s, float freq, int samples)
 
static void goertzel_reset (goertzel_state_t *s)
 
static float goertzel_result (goertzel_state_t *s)
 
static void goertzel_sample (goertzel_state_t *s, short sample)
 
static void goertzel_update (goertzel_state_t *s, short *samps, int count)
 
static int mf_detect (struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
 
static void mute_fragment (struct ast_dsp *dsp, fragment_t *fragment)
 
static int pair_there (float p1, float p2, float i1, float i2, float e)
 
static void store_digit (digit_detect_state_t *s, char digit)
 
static int tone_detect (struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
 

Variables

static struct progalias aliases []
 
static const char bell_mf_positions [] = "1247C-358A--69*---0B----#"
 
static const int DEFAULT_SILENCE_THRESHOLD = 256
 The default silence threshold we will use if an alternate configured value is not present or is invalid. More...
 
static const float dtmf_col []
 
static int dtmf_hits_to_begin
 
static int dtmf_misses_to_end
 
static float dtmf_normal_twist
 
static const char dtmf_positions [] = "123A" "456B" "789C" "*0#D"
 
static float dtmf_reverse_twist
 
static const float dtmf_row []
 
static const float mf_tones []
 
static struct progress modes []
 
static float relax_dtmf_normal_twist
 
static float relax_dtmf_reverse_twist
 
static int thresholds [THRESHOLD_MAX]
 

Detailed Description

Convenience Signal Processing routines.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Steve Underwood steve.nosp@m.u@co.nosp@m.ppice.nosp@m..org

Definition in file dsp.c.

Macro Definition Documentation

#define BELL_MF_RELATIVE_PEAK   12.6 /* 11dB */

Definition at line 184 of file dsp.c.

Referenced by mf_detect().

#define BELL_MF_THRESHOLD   1.6e9

Definition at line 182 of file dsp.c.

Referenced by mf_detect().

#define BELL_MF_TWIST   4.0 /* 6dB */

Definition at line 183 of file dsp.c.

Referenced by mf_detect().

#define CONFIG_FILE_NAME   "dsp.conf"

Definition at line 237 of file dsp.c.

Referenced by _dsp_init().

#define DEF_DTMF_HITS_TO_BEGIN   2

Definition at line 224 of file dsp.c.

Referenced by _dsp_init().

#define DEF_DTMF_MISSES_TO_END   3

Definition at line 229 of file dsp.c.

Referenced by _dsp_init().

#define DEF_DTMF_NORMAL_TWIST   6.31 /* 8.0dB */

Definition at line 165 of file dsp.c.

Referenced by _dsp_init().

#define DEF_DTMF_REVERSE_TWIST   2.51 /* 4.01dB */

Definition at line 172 of file dsp.c.

Referenced by _dsp_init().

#define DEF_RELAX_DTMF_NORMAL_TWIST   6.31 /* 8.0dB */

Definition at line 166 of file dsp.c.

Referenced by _dsp_init().

#define DEF_RELAX_DTMF_REVERSE_TWIST   3.98 /* 6.0dB */

Definition at line 173 of file dsp.c.

Referenced by _dsp_init().

#define DEFAULT_THRESHOLD   512

This value is the minimum threshold, calculated by averaging all of the samples within a frame, for which a frame is determined to either be silence (below the threshold) or noise (above the threshold). Please note that while the default threshold is an even exponent of 2, there is no requirement that it be so. The threshold will accept any value between 0 and 32767.

Definition at line 121 of file dsp.c.

Referenced by ast_dsp_new().

#define DSP_HISTORY   15

Remember last 15 units

Definition at line 132 of file dsp.c.

Referenced by __ast_dsp_silence_noise(), ast_dsp_busydetect(), ast_dsp_new(), and ast_dsp_set_busy_count().

#define DTMF_2ND_HARMONIC_COL   63.1 /* 18dB */

Definition at line 179 of file dsp.c.

#define DTMF_2ND_HARMONIC_ROW   (relax ? 1.7 : 2.5) /* 4dB normal */

Definition at line 178 of file dsp.c.

#define DTMF_GSIZE   102

Definition at line 219 of file dsp.c.

Referenced by ast_dtmf_detect_init(), and dtmf_detect().

#define DTMF_RELATIVE_PEAK_COL   6.3 /* 8dB */

Definition at line 177 of file dsp.c.

Referenced by dtmf_detect().

#define DTMF_RELATIVE_PEAK_ROW   6.3 /* 8dB */

Definition at line 176 of file dsp.c.

Referenced by dtmf_detect().

#define DTMF_THRESHOLD   8.0e7

Definition at line 161 of file dsp.c.

Referenced by dtmf_detect().

#define DTMF_TO_TOTAL_ENERGY   42.0

Definition at line 180 of file dsp.c.

Referenced by dtmf_detect().

#define FAX_2ND_HARMONIC   2.0 /* 4dB */

Definition at line 163 of file dsp.c.

#define FAX_THRESHOLD   8.0e7

Definition at line 162 of file dsp.c.

#define FAX_TONE_CED_DB   16

Definition at line 203 of file dsp.c.

Referenced by ast_fax_detect_init().

#define FAX_TONE_CED_DURATION   2600

Definition at line 202 of file dsp.c.

Referenced by ast_fax_detect_init().

#define FAX_TONE_CED_FREQ   2100

Definition at line 201 of file dsp.c.

Referenced by ast_fax_detect_init().

#define FAX_TONE_CNG_DB   16

Definition at line 195 of file dsp.c.

Referenced by ast_fax_detect_init().

#define FAX_TONE_CNG_DURATION   500

Definition at line 194 of file dsp.c.

Referenced by ast_fax_detect_init().

#define FAX_TONE_CNG_FREQ   1100

Definition at line 193 of file dsp.c.

Referenced by ast_fax_detect_init().

#define MAX_DTMF_DIGITS   128

Definition at line 147 of file dsp.c.

Referenced by store_digit().

#define MF_GSIZE   120

Definition at line 216 of file dsp.c.

Referenced by ast_mf_detect_init(), and mf_detect().

#define SAMPLE_RATE   8000

Definition at line 205 of file dsp.c.

Referenced by ast_dsp_process(), ast_tone_detect_init(), and goertzel_init().

#define SAMPLES_IN_FRAME   160

Definition at line 213 of file dsp.c.

Referenced by ast_tone_detect_init().

#define TONE_MIN_THRESH   1e8

How much tone there should be at least to attempt

Definition at line 135 of file dsp.c.

Referenced by __ast_dsp_call_progress(), and pair_there().

#define TONE_THRESH   10.0

How much louder the tone should be than channel energy

Definition at line 134 of file dsp.c.

Referenced by __ast_dsp_call_progress(), and pair_there().

Enumeration Type Documentation

Enumerator
BUSY_PERCENT 

The percentage difference between the two last tone periods

BUSY_PAT_PERCENT 

The percentage difference between measured and actual pattern

BUSY_THRESHOLD 

Max number of ms difference between max and min times in busy

BUSY_MIN 

Busy must be at least 150 ms in half-cadence

BUSY_MAX 

Busy can't be longer than 600 ms in half-cadence

Definition at line 123 of file dsp.c.

123  {
124  BUSY_PERCENT = 10, /*!< The percentage difference between the two last tone periods */
125  BUSY_PAT_PERCENT = 8, /*!< The percentage difference between measured and actual pattern */
126  BUSY_THRESHOLD = 100, /*!< Max number of ms difference between max and min times in busy */
127  BUSY_MIN = 150, /*!< Busy must be at least 150 ms in half-cadence */
128  BUSY_MAX = 600 /*!< Busy can't be longer than 600 ms in half-cadence */
129 };
Definition: dsp.c:128
Definition: dsp.c:127
enum freq_index
Enumerator
HZ_350 

For US modes {

HZ_440 
HZ_480 
HZ_620 
HZ_950 
HZ_1400 
HZ_1800 

}

HZ_425 

For CR/BR modes

HZ_350UK 

For UK mode

HZ_400UK 
HZ_440UK 

Definition at line 75 of file dsp.c.

75  {
76  /*! For US modes { */
77  HZ_350 = 0,
78  HZ_440,
79  HZ_480,
80  HZ_620,
81  HZ_950,
82  HZ_1400,
83  HZ_1800, /*!< } */
84 
85  /*! For CR/BR modes */
86  HZ_425 = 0,
87 
88  /*! For UK mode */
89  HZ_350UK = 0,
90  HZ_400UK,
91  HZ_440UK
92 };
Definition: dsp.c:86
Definition: dsp.c:91
Definition: dsp.c:78
Definition: dsp.c:80
Definition: dsp.c:89
Definition: dsp.c:82
Definition: dsp.c:77
Definition: dsp.c:81
Definition: dsp.c:83
Definition: dsp.c:79
Definition: dsp.c:90
enum gsamp_size

Number of goertzels for progress detect

Enumerator
GSAMP_SIZE_NA 

North America - 350, 440, 480, 620, 950, 1400, 1800 Hz

GSAMP_SIZE_CR 

Costa Rica, Brazil - Only care about 425 Hz

GSAMP_SIZE_UK 

UK disconnect goertzel feed - should trigger 400hz

Definition at line 63 of file dsp.c.

63  {
64  GSAMP_SIZE_NA = 183, /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
65  GSAMP_SIZE_CR = 188, /*!< Costa Rica, Brazil - Only care about 425 Hz */
66  GSAMP_SIZE_UK = 160 /*!< UK disconnect goertzel feed - should trigger 400hz */
67 };

All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms)

Enumerator
THRESH_RING 

Need at least 150ms ring to accept

THRESH_TALK 

Talk detection does not work continuously

THRESH_BUSY 

Need at least 80ms to accept

THRESH_CONGESTION 

Need at least 80ms to accept

THRESH_HANGUP 

Need at least 1300ms to accept hangup

THRESH_RING2ANSWER 

Timeout from start of ring to answer (about 6600 ms)

Definition at line 138 of file dsp.c.

138  {
139  THRESH_RING = 8, /*!< Need at least 150ms ring to accept */
140  THRESH_TALK = 2, /*!< Talk detection does not work continuously */
141  THRESH_BUSY = 4, /*!< Need at least 80ms to accept */
142  THRESH_CONGESTION = 4, /*!< Need at least 80ms to accept */
143  THRESH_HANGUP = 60, /*!< Need at least 1300ms to accept hangup */
144  THRESH_RING2ANSWER = 300 /*!< Timeout from start of ring to answer (about 6600 ms) */
145 };
enum prog_mode
Enumerator
PROG_MODE_NA 
PROG_MODE_CR 
PROG_MODE_UK 

Definition at line 69 of file dsp.c.

69  {
70  PROG_MODE_NA = 0,
73 };

Function Documentation

static int __ast_dsp_call_progress ( struct ast_dsp dsp,
short *  s,
int  len 
)
static

Definition at line 1036 of file dsp.c.

References AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_log(), DSP_FEATURE_CALL_PROGRESS, DSP_PROGRESS_BUSY, DSP_PROGRESS_CONGESTION, DSP_PROGRESS_RINGING, DSP_PROGRESS_TALK, DSP_TONE_STATE_BUSY, DSP_TONE_STATE_DIALTONE, DSP_TONE_STATE_HUNGUP, DSP_TONE_STATE_RINGING, DSP_TONE_STATE_SILENCE, DSP_TONE_STATE_SPECIAL1, DSP_TONE_STATE_SPECIAL2, DSP_TONE_STATE_SPECIAL3, DSP_TONE_STATE_TALKING, ast_dsp::features, ast_dsp::freqcount, ast_dsp::freqs, ast_dsp::genergy, goertzel_result(), goertzel_sample(), ast_dsp::gsamp_size, ast_dsp::gsamps, HZ_1400, HZ_1800, HZ_350, HZ_350UK, HZ_400UK, HZ_425, HZ_440, HZ_440UK, HZ_480, HZ_620, HZ_950, len(), LOG_WARNING, pair_there(), pass, PROG_MODE_CR, PROG_MODE_NA, PROG_MODE_UK, ast_dsp::progmode, ast_dsp::ringtimeout, ast_dsp::tcount, THRESH_BUSY, THRESH_CONGESTION, THRESH_HANGUP, THRESH_RING, THRESH_RING2ANSWER, THRESH_TALK, TONE_MIN_THRESH, TONE_THRESH, ast_dsp::tstate, goertzel_state_t::v2, and goertzel_state_t::v3.

Referenced by ast_dsp_call_progress(), and ast_dsp_process().

1037 {
1038  int x;
1039  int y;
1040  int pass;
1041  int newstate = DSP_TONE_STATE_SILENCE;
1042  int res = 0;
1043  while (len) {
1044  /* Take the lesser of the number of samples we need and what we have */
1045  pass = len;
1046  if (pass > dsp->gsamp_size - dsp->gsamps) {
1047  pass = dsp->gsamp_size - dsp->gsamps;
1048  }
1049  for (x = 0; x < pass; x++) {
1050  for (y = 0; y < dsp->freqcount; y++) {
1051  goertzel_sample(&dsp->freqs[y], s[x]);
1052  }
1053  dsp->genergy += s[x] * s[x];
1054  }
1055  s += pass;
1056  dsp->gsamps += pass;
1057  len -= pass;
1058  if (dsp->gsamps == dsp->gsamp_size) {
1059  float hz[7];
1060  for (y = 0; y < 7; y++) {
1061  hz[y] = goertzel_result(&dsp->freqs[y]);
1062  }
1063  switch (dsp->progmode) {
1064  case PROG_MODE_NA:
1065  if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
1066  newstate = DSP_TONE_STATE_BUSY;
1067  } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
1068  newstate = DSP_TONE_STATE_RINGING;
1069  } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
1070  newstate = DSP_TONE_STATE_DIALTONE;
1071  } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
1072  newstate = DSP_TONE_STATE_SPECIAL1;
1073  } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
1074  /* End of SPECIAL1 or middle of SPECIAL2 */
1076  newstate = DSP_TONE_STATE_SPECIAL2;
1077  }
1078  } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
1079  /* End of SPECIAL2 or middle of SPECIAL3 */
1081  newstate = DSP_TONE_STATE_SPECIAL3;
1082  }
1083  } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1084  newstate = DSP_TONE_STATE_TALKING;
1085  } else {
1086  newstate = DSP_TONE_STATE_SILENCE;
1087  }
1088  break;
1089  case PROG_MODE_CR:
1090  if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
1091  newstate = DSP_TONE_STATE_RINGING;
1092  } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
1093  newstate = DSP_TONE_STATE_TALKING;
1094  } else {
1095  newstate = DSP_TONE_STATE_SILENCE;
1096  }
1097  break;
1098  case PROG_MODE_UK:
1099  if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
1100  newstate = DSP_TONE_STATE_HUNGUP;
1101  } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
1102  newstate = DSP_TONE_STATE_DIALTONE;
1103  }
1104  break;
1105  default:
1106  ast_log(LOG_WARNING, "Can't process in unknown prog mode '%u'\n", dsp->progmode);
1107  }
1108  if (newstate == dsp->tstate) {
1109  dsp->tcount++;
1110  if (dsp->ringtimeout) {
1111  dsp->ringtimeout++;
1112  }
1113  switch (dsp->tstate) {
1115  if ((dsp->features & DSP_PROGRESS_RINGING) &&
1116  (dsp->tcount == THRESH_RING)) {
1117  res = AST_CONTROL_RINGING;
1118  dsp->ringtimeout = 1;
1119  }
1120  break;
1121  case DSP_TONE_STATE_BUSY:
1122  if ((dsp->features & DSP_PROGRESS_BUSY) &&
1123  (dsp->tcount == THRESH_BUSY)) {
1124  res = AST_CONTROL_BUSY;
1126  }
1127  break;
1129  if ((dsp->features & DSP_PROGRESS_TALK) &&
1130  (dsp->tcount == THRESH_TALK)) {
1131  res = AST_CONTROL_ANSWER;
1133  }
1134  break;
1136  if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
1137  (dsp->tcount == THRESH_CONGESTION)) {
1138  res = AST_CONTROL_CONGESTION;
1140  }
1141  break;
1142  case DSP_TONE_STATE_HUNGUP:
1143  if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
1144  (dsp->tcount == THRESH_HANGUP)) {
1145  res = AST_CONTROL_HANGUP;
1147  }
1148  break;
1149  }
1150  if (dsp->ringtimeout == THRESH_RING2ANSWER) {
1151  ast_debug(1, "Consider call as answered because of timeout after last ring\n");
1152  res = AST_CONTROL_ANSWER;
1154  }
1155  } else {
1156  ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
1157  ast_debug(5, "Start state %d\n", newstate);
1158  dsp->tstate = newstate;
1159  dsp->tcount = 1;
1160  }
1161 
1162  /* Reset goertzel */
1163  for (x = 0; x < 7; x++) {
1164  dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1165  }
1166  dsp->gsamps = 0;
1167  dsp->genergy = 0.0;
1168  }
1169  }
1170 
1171  return res;
1172 }
static char pass[512]
#define DSP_PROGRESS_RINGING
Definition: dsp.h:40
float genergy
Definition: dsp.c:417
#define DSP_TONE_STATE_HUNGUP
Definition: dsp.h:58
#define DSP_PROGRESS_BUSY
Definition: dsp.h:41
#define LOG_WARNING
Definition: logger.h:144
Definition: dsp.c:86
Definition: dsp.c:91
#define DSP_PROGRESS_TALK
Definition: dsp.h:39
#define DSP_FEATURE_CALL_PROGRESS
Definition: dsp.h:43
Definition: dsp.c:78
#define DSP_TONE_STATE_DIALTONE
Definition: dsp.h:52
Definition: dsp.c:80
#define DSP_PROGRESS_CONGESTION
Definition: dsp.h:42
#define DSP_TONE_STATE_TALKING
Definition: dsp.h:53
#define TONE_THRESH
Definition: dsp.c:134
Definition: dsp.c:89
Definition: dsp.c:82
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define DSP_TONE_STATE_SPECIAL2
Definition: dsp.h:56
enum gsamp_size gsamp_size
Definition: dsp.c:409
#define DSP_TONE_STATE_RINGING
Definition: dsp.h:51
#define DSP_TONE_STATE_BUSY
Definition: dsp.h:54
int freqcount
Definition: dsp.c:407
#define DSP_TONE_STATE_SPECIAL3
Definition: dsp.h:57
Definition: dsp.c:77
#define DSP_TONE_STATE_SPECIAL1
Definition: dsp.h:55
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
Definition: dsp.c:81
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Definition: dsp.c:83
goertzel_state_t freqs[7]
Definition: dsp.c:406
int tcount
Definition: dsp.c:412
#define TONE_MIN_THRESH
Definition: dsp.c:135
int gsamps
Definition: dsp.c:408
int features
Definition: dsp.c:395
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:325
Definition: dsp.c:79
static float goertzel_result(goertzel_state_t *s)
Definition: dsp.c:351
int tstate
Definition: dsp.c:411
#define DSP_TONE_STATE_SILENCE
Definition: dsp.h:50
Definition: dsp.c:90
int ringtimeout
Definition: dsp.c:396
static int pair_there(float p1, float p2, float i1, float i2, float e)
Definition: dsp.c:1013
enum prog_mode progmode
Definition: dsp.c:410
static int __ast_dsp_silence_noise ( struct ast_dsp dsp,
short *  s,
int  len,
int *  totalsilence,
int *  totalnoise 
)
static

Definition at line 1187 of file dsp.c.

References BUSY_PERCENT, ast_dsp::busycount, ast_dsp::busymaybe, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, len(), ast_dsp::totalnoise, and ast_dsp::totalsilence.

Referenced by ast_dsp_noise(), ast_dsp_process(), and ast_dsp_silence().

1188 {
1189  int accum;
1190  int x;
1191  int res = 0;
1192 
1193  if (!len) {
1194  return 0;
1195  }
1196  accum = 0;
1197  for (x = 0; x < len; x++) {
1198  accum += abs(s[x]);
1199  }
1200  accum /= len;
1201  if (accum < dsp->threshold) {
1202  /* Silent */
1203  dsp->totalsilence += len / 8;
1204 #ifdef DEBUG_DSP_BUSYDETECT
1205  fprintf(stderr, "SILENCE: len = %d, level = %d\n", dsp->totalsilence, accum);
1206 #endif
1207  if (dsp->totalnoise) {
1208  /* Move and save history */
1209  memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicnoise[0]));
1210  dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
1211  /* check if previous tone differs BUSY_PERCENT from the one before it */
1212  int tone1 = dsp->historicnoise[DSP_HISTORY - 1];
1213  int tone2 = dsp->historicnoise[DSP_HISTORY - 2];
1214  if (tone1 < tone2) {
1215  if ((tone1 + tone1*BUSY_PERCENT/100) >= tone2)
1216  dsp->busymaybe = 1;
1217  else
1218  dsp->busymaybe = 0;
1219  } else {
1220  if ((tone1 - tone1*BUSY_PERCENT/100) <= tone2)
1221  dsp->busymaybe = 1;
1222  else
1223  dsp->busymaybe = 0;
1224  }
1225  }
1226  dsp->totalnoise = 0;
1227  res = 1;
1228  } else {
1229  /* Not silent */
1230  dsp->totalnoise += len / 8;
1231 #ifdef DEBUG_DSP_BUSYDETECT
1232  fprintf(stderr, "NOISE: len = %d, level = %d\n", dsp->totalnoise, accum);
1233 #endif
1234  if (dsp->totalsilence) {
1235  /* Move and save history */
1236  memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1) * sizeof(dsp->historicsilence[0]));
1237  dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
1238  }
1239  dsp->totalsilence = 0;
1240  }
1241  if (totalsilence) {
1242  *totalsilence = dsp->totalsilence;
1243  }
1244  if (totalnoise) {
1245  *totalnoise = dsp->totalnoise;
1246  }
1247  return res;
1248 }
int busymaybe
Definition: dsp.c:397
int historicsilence[DSP_HISTORY]
Definition: dsp.c:405
int historicnoise[DSP_HISTORY]
Definition: dsp.c:404
int totalsilence
Definition: dsp.c:393
threshold
Definition: dsp.h:62
int busycount
Definition: dsp.c:398
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
int totalnoise
Definition: dsp.c:394
#define DSP_HISTORY
Definition: dsp.c:132
static int _dsp_init ( int  reload)
static

Definition at line 1792 of file dsp.c.

References ast_config_destroy(), ast_config_load2(), ast_log(), ast_variable_browse(), CONFIG_FILE_NAME, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, DEF_DTMF_HITS_TO_BEGIN, DEF_DTMF_MISSES_TO_END, DEF_DTMF_NORMAL_TWIST, DEF_DTMF_REVERSE_TWIST, DEF_RELAX_DTMF_NORMAL_TWIST, DEF_RELAX_DTMF_REVERSE_TWIST, DEFAULT_SILENCE_THRESHOLD, LOG_WARNING, ast_variable::name, ast_variable::next, THRESHOLD_SILENCE, and ast_variable::value.

Referenced by ast_dsp_init(), and ast_dsp_reload().

1793 {
1794  struct ast_config *cfg;
1795  struct ast_variable *v;
1796  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
1797  int cfg_threshold;
1798  float cfg_twist;
1799 
1800  if ((cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
1801  return 0;
1802  }
1803 
1811 
1813  return 0;
1814  }
1815 
1816  for (v = ast_variable_browse(cfg, "default"); v; v = v->next) {
1817  if (!strcasecmp(v->name, "silencethreshold")) {
1818  if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1819  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1820  } else if (cfg_threshold < 0) {
1821  ast_log(LOG_WARNING, "Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
1822  } else {
1823  thresholds[THRESHOLD_SILENCE] = cfg_threshold;
1824  }
1825  } else if (!strcasecmp(v->name, "dtmf_normal_twist")) {
1826  if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1827  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1828  } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1829  ast_log(LOG_WARNING, "Invalid dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_normal_twist);
1830  } else {
1831  dtmf_normal_twist = cfg_twist;
1832  }
1833  } else if (!strcasecmp(v->name, "dtmf_reverse_twist")) {
1834  if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1835  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1836  } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1837  ast_log(LOG_WARNING, "Invalid dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_reverse_twist);
1838  } else {
1839  dtmf_reverse_twist = cfg_twist;
1840  }
1841  } else if (!strcasecmp(v->name, "relax_dtmf_normal_twist")) {
1842  if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1843  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1844  } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1845  ast_log(LOG_WARNING, "Invalid relax_dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_normal_twist);
1846  } else {
1847  relax_dtmf_normal_twist = cfg_twist;
1848  }
1849  } else if (!strcasecmp(v->name, "relax_dtmf_reverse_twist")) {
1850  if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
1851  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1852  } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) { /* < 3.0dB or > 20dB */
1853  ast_log(LOG_WARNING, "Invalid relax_dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_reverse_twist);
1854  } else {
1855  relax_dtmf_reverse_twist = cfg_twist;
1856  }
1857  } else if (!strcasecmp(v->name, "dtmf_hits_to_begin")) {
1858  if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1859  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1860  } else if (cfg_threshold < 1) { /* must be 1 or greater */
1861  ast_log(LOG_WARNING, "Invalid dtmf_hits_to_begin value '%d' specified, using default of %d\n", cfg_threshold, dtmf_hits_to_begin);
1862  } else {
1863  dtmf_hits_to_begin = cfg_threshold;
1864  }
1865  } else if (!strcasecmp(v->name, "dtmf_misses_to_end")) {
1866  if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
1867  ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
1868  } else if (cfg_threshold < 1) { /* must be 1 or greater */
1869  ast_log(LOG_WARNING, "Invalid dtmf_misses_to_end value '%d' specified, using default of %d\n", cfg_threshold, dtmf_misses_to_end);
1870  } else {
1871  dtmf_misses_to_end = cfg_threshold;
1872  }
1873  }
1874  }
1875  ast_config_destroy(cfg);
1876 
1877  return 0;
1878 }
static float relax_dtmf_reverse_twist
Definition: dsp.c:321
#define LOG_WARNING
Definition: logger.h:144
struct ast_variable * ast_variable_browse(const struct ast_config *config, const char *category)
Goes through variables.
Definition: config.c:597
static const int DEFAULT_SILENCE_THRESHOLD
The default silence threshold we will use if an alternate configured value is not present or is inval...
Definition: dsp.c:235
#define DEF_DTMF_NORMAL_TWIST
Definition: dsp.c:165
Structure for variables, used for configurations and for channel variables.
Definition: config.h:75
#define DEF_DTMF_HITS_TO_BEGIN
Definition: dsp.c:224
#define CONFIG_FILE_NAME
Definition: dsp.c:237
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
static int dtmf_hits_to_begin
Definition: dsp.c:322
#define DEF_DTMF_REVERSE_TWIST
Definition: dsp.c:172
const char * value
Definition: config.h:79
static int dtmf_misses_to_end
Definition: dsp.c:323
#define DEF_DTMF_MISSES_TO_END
Definition: dsp.c:229
const char * name
Definition: config.h:77
#define DEF_RELAX_DTMF_NORMAL_TWIST
Definition: dsp.c:166
static int reload(void)
Definition: app_amd.c:497
static float dtmf_normal_twist
Definition: dsp.c:318
static float relax_dtmf_normal_twist
Definition: dsp.c:320
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
struct ast_variable * next
Definition: config.h:82
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static float dtmf_reverse_twist
Definition: dsp.c:319
#define DEF_RELAX_DTMF_REVERSE_TWIST
Definition: dsp.c:173
static int thresholds[THRESHOLD_MAX]
Definition: dsp.c:317
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static void ast_digit_detect_init ( digit_detect_state_t s,
int  mf 
)
static

Definition at line 528 of file dsp.c.

References ast_dtmf_detect_init(), ast_mf_detect_init(), digit_detect_state_t::current_digits, digit_detect_state_t::detected_digits, digit_detect_state_t::digits, digit_detect_state_t::dtmf, digit_detect_state_t::lost_digits, digit_detect_state_t::mf, and digit_detect_state_t::td.

Referenced by ast_dsp_new(), and ast_dsp_set_digitmode().

529 {
530  s->current_digits = 0;
531  s->detected_digits = 0;
532  s->lost_digits = 0;
533  s->digits[0] = '\0';
534 
535  if (mf) {
536  ast_mf_detect_init(&s->td.mf);
537  } else {
539  }
540 }
int current_digits
Definition: dsp.c:296
static void ast_mf_detect_init(mf_detect_state_t *s)
Definition: dsp.c:517
char digits[MAX_DTMF_DIGITS+1]
Definition: dsp.c:294
dtmf_detect_state_t dtmf
Definition: dsp.c:301
int detected_digits
Definition: dsp.c:297
union digit_detect_state_t::@254 td
mf_detect_state_t mf
Definition: dsp.c:302
static void ast_dtmf_detect_init(dtmf_detect_state_t *s)
Definition: dsp.c:501
int ast_dsp_busydetect ( struct ast_dsp dsp)

Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been called.

Definition at line 1250 of file dsp.c.

References ast_debug, ast_log(), BUSY_MAX, BUSY_MIN, ast_dsp::busy_pattern_fuzzy, BUSY_PERCENT, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busymaybe, ast_dsp::busytoneonly, DSP_HISTORY, ast_dsp::historicnoise, ast_dsp::historicsilence, LOG_ERROR, LOG_NOTICE, MAX, and option_debug.

Referenced by ast_dsp_process().

1251 {
1252  int res = 0, x;
1253  int avgsilence = 0, hitsilence = 0;
1254  int avgtone = 0, hittone = 0;
1255 #ifdef DEBUG_DSP_BUSYDETECT
1256  char buf[16];
1257  char silence_list[64]="", tone_list[64]="";
1258 #endif
1259 
1260  if (!dsp->busymaybe) {
1261  return res;
1262  }
1263  dsp->busymaybe = 0;
1264 
1265  for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
1266  avgsilence += dsp->historicsilence[x];
1267  avgtone += dsp->historicnoise[x];
1268  }
1269  avgsilence /= dsp->busycount;
1270  avgtone /= dsp->busycount;
1271 #ifdef DEBUG_DSP_BUSYDETECT
1272  sprintf(silence_list,"Silences: ");
1273  sprintf(tone_list,"Tones: ");
1274 #endif
1275  for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
1276 #ifdef DEBUG_DSP_BUSYDETECT
1277  snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
1278  strcat(silence_list, buf);
1279  snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
1280  strcat(tone_list, buf);
1281 #endif
1282  if (!dsp->busytoneonly) {
1283  if (avgsilence > dsp->historicsilence[x]) {
1284  if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
1285  hitsilence++;
1286  } else {
1287  if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
1288  hitsilence++;
1289  }
1290  }
1291  if (avgtone > dsp->historicnoise[x]) {
1292  if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
1293  hittone++;
1294  }
1295  } else {
1296  if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
1297  hittone++;
1298  }
1299  }
1300  }
1301 #ifdef DEBUG_DSP_BUSYDETECT
1302  fprintf(stderr, "BUSY DETECTOR\n");
1303  fprintf(stderr, "%s\n", tone_list);
1304  fprintf(stderr, "%s\n", silence_list)
1305 #endif
1306  if ((dsp->busytoneonly ||
1307  (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
1308  (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
1309  if (dsp->busycompare) {
1310  if (dsp->busytoneonly) {
1311  res = 1;
1312  ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
1313  } else {
1314  if (avgtone > avgsilence) {
1315  if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
1316  res = 1;
1317  } else {
1318  if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
1319  res = 1;
1320  }
1321  }
1322  } else {
1323  res = 1;
1324  }
1325  }
1326  /* If we know the expected busy tone length, check we are in the range */
1327  if (res && (dsp->busy_tonelength > 0)) {
1328  if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100, 20)) {
1329 #ifdef BUSYDETECT_DEBUG
1330  ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
1331  avgtone, dsp->busy_tonelength);
1332 #endif
1333  res = 0;
1334  }
1335  }
1336  /* If we know the expected busy tone silent-period length, check we are in the range */
1337  if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
1338  if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100, 20)) {
1339 #ifdef BUSYDETECT_DEBUG
1340  ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
1341  avgsilence, dsp->busy_quietlength);
1342 #endif
1343  res = 0;
1344  }
1345  }
1346  if (res) {
1347  if (option_debug)
1348  ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1349  } else {
1350  ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
1351  }
1352  return res;
1353 }
int busymaybe
Definition: dsp.c:397
Definition: dsp.c:128
Definition: dsp.c:127
int option_debug
Definition: asterisk.c:182
int busytoneonly
Definition: dsp.c:399
int historicsilence[DSP_HISTORY]
Definition: dsp.c:405
int busy_pattern_fuzzy
Definition: dsp.c:403
int historicnoise[DSP_HISTORY]
Definition: dsp.c:404
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define MAX(a, b)
Definition: utils.h:228
int busycount
Definition: dsp.c:398
int busy_tonelength
Definition: dsp.c:401
int busy_quietlength
Definition: dsp.c:402
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
int busycompare
Definition: dsp.c:400
#define DSP_HISTORY
Definition: dsp.c:132
int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Scans for progress indication in audio.

Definition at line 1174 of file dsp.c.

References __ast_dsp_call_progress(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

1175 {
1176  if (inf->frametype != AST_FRAME_VOICE) {
1177  ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
1178  return 0;
1179  }
1180  if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
1181  ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
1182  return 0;
1183  }
1184  return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
1185 }
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
Definition: dsp.c:1036
format_t codec
Definition: frame.h:137
int datalen
Definition: frame.h:148
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
void ast_dsp_digitreset ( struct ast_dsp dsp)

Reset DTMF detector.

Definition at line 1694 of file dsp.c.

References dtmf_detect_state_t::col_out, digit_detect_state_t::current_digits, dtmf_detect_state_t::current_hit, mf_detect_state_t::current_hit, dtmf_detect_state_t::current_sample, mf_detect_state_t::current_sample, ast_dsp::digit_state, ast_dsp::digitmode, digit_detect_state_t::digits, DSP_DIGITMODE_MF, digit_detect_state_t::dtmf, ast_dsp::dtmf_began, dtmf_detect_state_t::energy, goertzel_reset(), dtmf_detect_state_t::hits, mf_detect_state_t::hits, dtmf_detect_state_t::lasthit, digit_detect_state_t::mf, dtmf_detect_state_t::misses, dtmf_detect_state_t::row_out, digit_detect_state_t::td, and mf_detect_state_t::tone_out.

Referenced by analog_ss_thread(), and my_dsp_reset_and_flush_digits().

1695 {
1696  int i;
1697 
1698  dsp->dtmf_began = 0;
1699  if (dsp->digitmode & DSP_DIGITMODE_MF) {
1700  mf_detect_state_t *s = &dsp->digit_state.td.mf;
1701  /* Reinitialise the detector for the next block */
1702  for (i = 0; i < 6; i++) {
1703  goertzel_reset(&s->tone_out[i]);
1704  }
1705  s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
1706  s->current_sample = 0;
1707  } else {
1709  /* Reinitialise the detector for the next block */
1710  for (i = 0; i < 4; i++) {
1711  goertzel_reset(&s->row_out[i]);
1712  goertzel_reset(&s->col_out[i]);
1713  }
1714  s->lasthit = s->current_hit = 0;
1715  s->energy = 0.0;
1716  s->current_sample = 0;
1717  s->hits = 0;
1718  s->misses = 0;
1719  }
1720 
1721  dsp->digit_state.digits[0] = '\0';
1722  dsp->digit_state.current_digits = 0;
1723 }
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
int current_digits
Definition: dsp.c:296
goertzel_state_t tone_out[6]
Definition: dsp.c:285
static void goertzel_reset(goertzel_state_t *s)
Definition: dsp.c:367
digit_detect_state_t digit_state
Definition: dsp.c:420
char digits[MAX_DTMF_DIGITS+1]
Definition: dsp.c:294
dtmf_detect_state_t dtmf
Definition: dsp.c:301
int current_sample
Definition: dsp.c:279
goertzel_state_t col_out[4]
Definition: dsp.c:273
int hits[5]
Definition: dsp.c:287
int dtmf_began
Definition: dsp.c:415
int digitmode
Definition: dsp.c:413
int current_sample
Definition: dsp.c:288
float energy
Definition: dsp.c:278
int current_hit
Definition: dsp.c:286
union digit_detect_state_t::@254 td
mf_detect_state_t mf
Definition: dsp.c:302
goertzel_state_t row_out[4]
Definition: dsp.c:272
int ast_dsp_get_tcount ( struct ast_dsp dsp)

Get tcount (Threshold counter)

Definition at line 1787 of file dsp.c.

References ast_dsp::tcount.

Referenced by dahdi_read().

1788 {
1789  return dsp->tcount;
1790 }
int tcount
Definition: dsp.c:412
int ast_dsp_get_threshold_from_settings ( enum threshold  which)

Get silence threshold from dsp.conf.

Since
1.6.1

Definition at line 1880 of file dsp.c.

Referenced by actual_load_config(), app_exec(), ast_record_review(), conf_run(), do_waiting(), handle_recordfile(), load_config(), record_exec(), and setup_privacy_args().

1881 {
1882  return thresholds[which];
1883 }
static int thresholds[THRESHOLD_MAX]
Definition: dsp.c:317
int ast_dsp_get_tstate ( struct ast_dsp dsp)

Get tstate (Tone State)

Definition at line 1782 of file dsp.c.

References ast_dsp::tstate.

Referenced by dahdi_read().

1783 {
1784  return dsp->tstate;
1785 }
int tstate
Definition: dsp.c:411
int ast_dsp_init ( void  )

Load dsp settings from dsp.conf.

Since
1.6.1

Definition at line 1885 of file dsp.c.

References _dsp_init().

Referenced by main().

1886 {
1887  return _dsp_init(0);
1888 }
static int _dsp_init(int reload)
Definition: dsp.c:1792
struct ast_dsp* ast_dsp_new ( void  )

Definition at line 1607 of file dsp.c.

References ast_calloc, ast_digit_detect_init(), ast_dsp_prog_reset(), ast_fax_detect_init(), BUSY_PAT_PERCENT, ast_dsp::busy_pattern_fuzzy, ast_dsp::busycompare, ast_dsp::busycount, ast_dsp::busytoneonly, DEFAULT_THRESHOLD, ast_dsp::digit_state, ast_dsp::digitmode, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::faxmode, ast_dsp::features, and ast_dsp::threshold.

Referenced by __ast_play_and_record(), __oh323_new(), background_detect_exec(), conf_run(), dahdi_new(), do_waiting(), enable_dsp_detect(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), mgcp_new(), misdn_set_opt_exec(), my_dsp_set_digitmode(), read_config(), and record_exec().

1608 {
1609  struct ast_dsp *dsp;
1610 
1611  if ((dsp = ast_calloc(1, sizeof(*dsp)))) {
1614  dsp->busycount = DSP_HISTORY;
1618 #ifdef BUSYDETECT_TONEONLY
1619  dsp->busytoneonly = 1;
1620 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1621 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
1622 #endif
1623 #else
1624  dsp->busytoneonly = 0;
1625 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
1626  dsp->busycompare = 1;
1627 #else
1628  dsp->busycompare = 0;
1629 #endif
1630 #endif
1631  /* Initialize digit detector */
1633  dsp->display_inband_dtmf_warning = 1;
1634  /* Initialize initial DSP progress detect parameters */
1635  ast_dsp_prog_reset(dsp);
1636  /* Initialize fax detector */
1637  ast_fax_detect_init(dsp);
1638  }
1639  return dsp;
1640 }
int busytoneonly
Definition: dsp.c:399
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
int busy_pattern_fuzzy
Definition: dsp.c:403
static void ast_dsp_prog_reset(struct ast_dsp *dsp)
Definition: dsp.c:1590
digit_detect_state_t digit_state
Definition: dsp.c:420
static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
Definition: dsp.c:528
int faxmode
Definition: dsp.c:414
int busycount
Definition: dsp.c:398
Definition: dsp.c:390
#define DSP_FEATURE_SILENCE_SUPPRESS
Definition: dsp.h:26
#define DEFAULT_THRESHOLD
This value is the minimum threshold, calculated by averaging all of the samples within a frame...
Definition: dsp.c:121
int threshold
Definition: dsp.c:392
int digitmode
Definition: dsp.c:413
static void ast_fax_detect_init(struct ast_dsp *s)
Definition: dsp.c:495
int features
Definition: dsp.c:395
#define ast_calloc(a, b)
Definition: astmm.h:82
int display_inband_dtmf_warning
Definition: dsp.c:416
int busycompare
Definition: dsp.c:400
#define DSP_FAXMODE_DETECT_CNG
Definition: dsp.h:46
#define DSP_HISTORY
Definition: dsp.c:132
int ast_dsp_noise ( struct ast_dsp dsp,
struct ast_frame f,
int *  totalnoise 
)

Return non-zero if this is noise. Updates "totalnoise" with the total number of seconds of noise.

Since
1.6.1

Definition at line 1373 of file dsp.c.

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

Referenced by do_waiting().

1374 {
1375  short *s;
1376  int len;
1377 
1378  if (f->frametype != AST_FRAME_VOICE) {
1379  ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
1380  return 0;
1381  }
1382  if (f->subclass.codec != AST_FORMAT_SLINEAR) {
1383  ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
1384  return 0;
1385  }
1386  s = f->data.ptr;
1387  len = f->datalen/2;
1388  return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
1389 }
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
Definition: dsp.c:1187
format_t codec
Definition: frame.h:137
int datalen
Definition: frame.h:148
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
int totalnoise
Definition: dsp.c:394
struct ast_frame* ast_dsp_process ( struct ast_channel chan,
struct ast_dsp dsp,
struct ast_frame af 
)

Return AST_FRAME_NULL frames when there is silence, AST_FRAME_BUSY on busies, and call progress, all dependent upon which features are enabled.

Definition at line 1392 of file dsp.c.

References __ast_dsp_call_progress(), __ast_dsp_silence_noise(), ast_channel::_softhangup, AST_ALAW, ast_alloca, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_HANGUP, AST_CONTROL_RINGING, ast_debug, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_TESTLAW, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree, ast_frisolate(), ast_getformatname(), AST_LIN2A, AST_LIN2MU, ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_dsp::ced_tone_state, ast_dsp::cng_tone_state, ast_frame_subclass::codec, digit_detect_state_t::current_digits, ast_frame::data, ast_frame::datalen, ast_dsp::digit_state, digit_detect_state_t::digitlen, ast_dsp::digitmode, digit_detect_state_t::digits, ast_dsp::display_inband_dtmf_warning, DSP_DIGITMODE_MF, DSP_DIGITMODE_NOQUELCH, DSP_DIGITMODE_RELAXDTMF, DSP_FAXMODE_DETECT_CED, DSP_FAXMODE_DETECT_CNG, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DIGIT_DETECT, DSP_FEATURE_FAX_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, DSP_FEATURE_WAITDIALTONE, ast_dsp::dtmf_began, dtmf_detect(), fragment_t::end, ast_dsp::f, ast_dsp::faxmode, ast_dsp::features, ast_frame::frametype, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_frame_subclass::integer, ast_frame::len, len(), LOG_WARNING, mf_detect(), ast_dsp::mute_data, ast_dsp::mute_fragments, ast_channel::name, ast_frame::ptr, SAMPLE_RATE, ast_frame::src, fragment_t::start, ast_frame::subclass, and tone_detect().

Referenced by dahdi_read(), mgcp_rtp_read(), oh323_rtp_read(), process_ast_dsp(), and sip_rtp_read().

1393 {
1394  int silence;
1395  int res;
1396  int digit = 0, fax_digit = 0;
1397  int x;
1398  short *shortdata;
1399  unsigned char *odata;
1400  int len;
1401  struct ast_frame *outf = NULL;
1402 
1403  if (!af) {
1404  return NULL;
1405  }
1406  if (af->frametype != AST_FRAME_VOICE) {
1407  return af;
1408  }
1409 
1410  odata = af->data.ptr;
1411  len = af->datalen;
1412  /* Make sure we have short data */
1413  switch (af->subclass.codec) {
1414  case AST_FORMAT_SLINEAR:
1415  shortdata = af->data.ptr;
1416  len = af->datalen / 2;
1417  break;
1418  case AST_FORMAT_ULAW:
1419  case AST_FORMAT_TESTLAW:
1420  shortdata = ast_alloca(af->datalen * 2);
1421  for (x = 0;x < len; x++) {
1422  shortdata[x] = AST_MULAW(odata[x]);
1423  }
1424  break;
1425  case AST_FORMAT_ALAW:
1426  shortdata = ast_alloca(af->datalen * 2);
1427  for (x = 0; x < len; x++) {
1428  shortdata[x] = AST_ALAW(odata[x]);
1429  }
1430  break;
1431  default:
1432  /*Display warning only once. Otherwise you would get hundreds of warnings every second */
1433  if (dsp->display_inband_dtmf_warning)
1434  ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
1435  dsp->display_inband_dtmf_warning = 0;
1436  return af;
1437  }
1438 
1439  /* Initially we do not want to mute anything */
1440  dsp->mute_fragments = 0;
1441 
1442  /* Need to run the silence detection stuff for silence suppression and busy detection */
1444  res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
1445  }
1446 
1447  if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
1448  memset(&dsp->f, 0, sizeof(dsp->f));
1449  dsp->f.frametype = AST_FRAME_NULL;
1450  ast_frfree(af);
1451  return ast_frisolate(&dsp->f);
1452  }
1453  if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
1455  memset(&dsp->f, 0, sizeof(dsp->f));
1456  dsp->f.frametype = AST_FRAME_CONTROL;
1457  /* Signal this as it was a channel hangup, to avoid msg "channel.c:3473 ast_waitfordigit_full: Unexpected control subclass '5'" */
1459  ast_frfree(af);
1460  ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
1461  return ast_frisolate(&dsp->f);
1462  }
1463 
1464  if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
1465  if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
1466  fax_digit = 'f';
1467  }
1468 
1469  if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
1470  fax_digit = 'e';
1471  }
1472  }
1473 
1475  if (dsp->digitmode & DSP_DIGITMODE_MF)
1476  digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1477  else
1478  digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
1479 
1480  if (dsp->digit_state.current_digits) {
1481  int event = 0, event_len = 0;
1482  char event_digit = 0;
1483 
1484  if (!dsp->dtmf_began) {
1485  /* We have not reported DTMF_BEGIN for anything yet */
1486 
1487  if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
1488  event = AST_FRAME_DTMF_BEGIN;
1489  event_digit = dsp->digit_state.digits[0];
1490  }
1491  dsp->dtmf_began = 1;
1492 
1493  } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
1494  /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
1495  if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
1496  event = AST_FRAME_DTMF_END;
1497  event_digit = dsp->digit_state.digits[0];
1498  event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
1499  }
1500  memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
1501  memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
1502  dsp->digit_state.current_digits--;
1503  dsp->dtmf_began = 0;
1504 
1505  if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
1506  /* Reset Busy Detector as we have some confirmed activity */
1507  memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1508  memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1509  ast_debug(1, "DTMF Detected - Reset busydetector\n");
1510  }
1511  }
1512 
1513  if (event) {
1514  memset(&dsp->f, 0, sizeof(dsp->f));
1515  dsp->f.frametype = event;
1516  dsp->f.subclass.integer = event_digit;
1517  dsp->f.len = event_len;
1518  outf = &dsp->f;
1519  goto done;
1520  }
1521  }
1522  }
1523 
1524  if (fax_digit) {
1525  /* Fax was detected - digit is either 'f' or 'e' */
1526 
1527  memset(&dsp->f, 0, sizeof(dsp->f));
1528  dsp->f.frametype = AST_FRAME_DTMF;
1529  dsp->f.subclass.integer = fax_digit;
1530  outf = &dsp->f;
1531  goto done;
1532  }
1533 
1534  if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
1535  res = __ast_dsp_call_progress(dsp, shortdata, len);
1536  if (res) {
1537  switch (res) {
1538  case AST_CONTROL_ANSWER:
1539  case AST_CONTROL_BUSY:
1540  case AST_CONTROL_RINGING:
1542  case AST_CONTROL_HANGUP:
1543  memset(&dsp->f, 0, sizeof(dsp->f));
1544  dsp->f.frametype = AST_FRAME_CONTROL;
1545  dsp->f.subclass.integer = res;
1546  dsp->f.src = "dsp_progress";
1547  if (chan)
1548  ast_queue_frame(chan, &dsp->f);
1549  break;
1550  default:
1551  ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
1552  }
1553  }
1554  } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
1555  res = __ast_dsp_call_progress(dsp, shortdata, len);
1556  }
1557 
1558 done:
1559  /* Mute fragment of the frame */
1560  for (x = 0; x < dsp->mute_fragments; x++) {
1561  memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
1562  }
1563 
1564  switch (af->subclass.codec) {
1565  case AST_FORMAT_SLINEAR:
1566  break;
1567  case AST_FORMAT_ULAW:
1568  for (x = 0; x < len; x++) {
1569  odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
1570  }
1571  break;
1572  case AST_FORMAT_ALAW:
1573  for (x = 0; x < len; x++) {
1574  odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
1575  }
1576  break;
1577  }
1578 
1579  if (outf) {
1580  if (chan) {
1581  ast_queue_frame(chan, af);
1582  }
1583  ast_frfree(af);
1584  return ast_frisolate(outf);
1585  } else {
1586  return af;
1587  }
1588 }
union ast_frame_subclass subclass
Definition: frame.h:146
int start
Definition: dsp.c:373
#define ast_alloca(size)
call __builtin_alloca to ensure we get gcc builtin semantics
Definition: utils.h:653
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
void * ptr
Definition: frame.h:160
struct ast_frame f
Definition: dsp.c:391
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
#define LOG_WARNING
Definition: logger.h:144
#define AST_ALAW(a)
Definition: alaw.h:84
#define DSP_FEATURE_CALL_PROGRESS
Definition: dsp.h:43
#define AST_FRAME_DTMF
Definition: frame.h:128
static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
Definition: dsp.c:1036
int historicsilence[DSP_HISTORY]
Definition: dsp.c:405
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
Definition: dsp.c:1187
int current_digits
Definition: dsp.c:296
static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
Definition: dsp.c:661
struct ast_frame * ast_frisolate(struct ast_frame *fr)
Makes a frame independent of any static storage.
Definition: frame.c:391
format_t codec
Definition: frame.h:137
digit_detect_state_t digit_state
Definition: dsp.c:420
int historicnoise[DSP_HISTORY]
Definition: dsp.c:404
char digits[MAX_DTMF_DIGITS+1]
Definition: dsp.c:294
#define DSP_DIGITMODE_RELAXDTMF
Definition: dsp.h:37
int faxmode
Definition: dsp.c:414
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * src
Definition: frame.h:158
#define AST_FORMAT_ALAW
Definition: frame.h:248
#define AST_MULAW(a)
Definition: ulaw.h:85
int datalen
Definition: frame.h:148
#define DSP_FEATURE_SILENCE_SUPPRESS
Definition: dsp.h:26
#define DSP_FEATURE_FAX_DETECT
Definition: dsp.h:29
int ast_queue_frame(struct ast_channel *chan, struct ast_frame *f)
Queue one or more frames to a channel&#39;s frame queue.
Definition: channel.c:1558
int end
Definition: dsp.c:374
static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
Definition: dsp.c:863
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
int dtmf_began
Definition: dsp.c:415
#define AST_FORMAT_ULAW
Definition: frame.h:246
#define DSP_FAXMODE_DETECT_CED
Definition: dsp.h:47
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_FORMAT_TESTLAW
Definition: frame.h:303
int digitmode
Definition: dsp.c:413
const ast_string_field name
Definition: channel.h:787
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int _softhangup
Definition: channel.h:832
#define DSP_FEATURE_BUSY_DETECT
Definition: dsp.h:27
int mute_fragments
Definition: dsp.c:418
int features
Definition: dsp.c:395
tone_detect_state_t ced_tone_state
Definition: dsp.c:422
static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
Definition: dsp.c:542
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
int display_inband_dtmf_warning
Definition: dsp.c:416
#define SAMPLE_RATE
Definition: dsp.c:205
tone_detect_state_t cng_tone_state
Definition: dsp.c:421
Data structure associated with a single frame of data.
Definition: frame.h:142
int digitlen[MAX_DTMF_DIGITS+1]
Definition: dsp.c:295
#define DSP_FAXMODE_DETECT_CNG
Definition: dsp.h:46
fragment_t mute_data[5]
Definition: dsp.c:419
enum ast_frame_type frametype
Definition: frame.h:144
#define DSP_DIGITMODE_NOQUELCH
Definition: dsp.h:34
#define ast_frfree(fr)
Definition: frame.h:583
#define DSP_FEATURE_WAITDIALTONE
Definition: dsp.h:44
int ast_dsp_busydetect(struct ast_dsp *dsp)
Return non-zero if historically this should be a busy, request that ast_dsp_silence has already been ...
Definition: dsp.c:1250
union ast_frame::@172 data
long len
Definition: frame.h:170
#define AST_LIN2MU(a)
Definition: ulaw.h:49
#define AST_LIN2A(a)
Definition: alaw.h:50
static void ast_dsp_prog_reset ( struct ast_dsp dsp)
static

Definition at line 1590 of file dsp.c.

References ARRAY_LEN, ast_dsp::freqcount, progress::freqs, ast_dsp::freqs, goertzel_init(), ast_dsp::gsamp_size, ast_dsp::gsamps, modes, ast_dsp::progmode, ast_dsp::ringtimeout, and progress::size.

Referenced by ast_dsp_new(), and ast_dsp_set_call_progress_zone().

1591 {
1592  int max = 0;
1593  int x;
1594 
1595  dsp->gsamp_size = modes[dsp->progmode].size;
1596  dsp->gsamps = 0;
1597  for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
1598  if (modes[dsp->progmode].freqs[x]) {
1599  goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
1600  max = x + 1;
1601  }
1602  }
1603  dsp->freqcount = max;
1604  dsp->ringtimeout= 0;
1605 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
enum gsamp_size size
Definition: dsp.c:106
static struct progress modes[]
enum gsamp_size gsamp_size
Definition: dsp.c:409
int freqcount
Definition: dsp.c:407
int freqs[7]
Definition: dsp.c:107
goertzel_state_t freqs[7]
Definition: dsp.c:406
int gsamps
Definition: dsp.c:408
int ringtimeout
Definition: dsp.c:396
static void goertzel_init(goertzel_state_t *s, float freq, int samples)
Definition: dsp.c:360
enum prog_mode progmode
Definition: dsp.c:410
int ast_dsp_reload ( void  )

Reloads dsp settings from dsp.conf.

Since
1.6.1

Definition at line 1890 of file dsp.c.

References _dsp_init().

1891 {
1892  return _dsp_init(1);
1893 }
static int _dsp_init(int reload)
Definition: dsp.c:1792
void ast_dsp_reset ( struct ast_dsp dsp)

Reset total silence count.

Definition at line 1725 of file dsp.c.

References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::ringtimeout, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3.

Referenced by debug_check_frame_for_silence().

1726 {
1727  int x;
1728 
1729  dsp->totalsilence = 0;
1730  dsp->gsamps = 0;
1731  for (x = 0; x < 4; x++) {
1732  dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
1733  }
1734  memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
1735  memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
1736  dsp->ringtimeout= 0;
1737 }
int historicsilence[DSP_HISTORY]
Definition: dsp.c:405
int historicnoise[DSP_HISTORY]
Definition: dsp.c:404
int totalsilence
Definition: dsp.c:393
goertzel_state_t freqs[7]
Definition: dsp.c:406
int gsamps
Definition: dsp.c:408
int ringtimeout
Definition: dsp.c:396
void ast_dsp_set_busy_compare ( struct ast_dsp dsp,
int  compare 
)

Set if silence and noice lengths must be compared for busy.

Definition at line 1674 of file dsp.c.

References ast_dsp::busycompare.

Referenced by dahdi_new().

1675 {
1676  if (compare > 0)
1677  dsp->busycompare = 1;
1678  else
1679  dsp->busycompare = 0;
1680 }
static int compare(const char *text, const char *template)
int busycompare
Definition: dsp.c:400
void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Set number of required cadences for busy.

Definition at line 1663 of file dsp.c.

References ast_dsp::busycount, cadences, and DSP_HISTORY.

Referenced by dahdi_new().

1664 {
1665  if (cadences < 4) {
1666  cadences = 4;
1667  }
1668  if (cadences > DSP_HISTORY) {
1670  }
1671  dsp->busycount = cadences;
1672 }
int busycount
Definition: dsp.c:398
static struct dahdi_ring_cadence cadences[NUM_CADENCE_MAX]
Definition: chan_dahdi.c:393
#define DSP_HISTORY
Definition: dsp.c:132
void ast_dsp_set_busy_pattern ( struct ast_dsp dsp,
int  tonelength,
int  quietlength,
int  fuzzy 
)

Set expected lengths of the busy tones.

Definition at line 1682 of file dsp.c.

References ast_debug, ast_dsp::busy_pattern_fuzzy, ast_dsp::busy_quietlength, ast_dsp::busy_tonelength, and ast_dsp::busytoneonly.

Referenced by dahdi_new().

1683 {
1684  dsp->busy_tonelength = tonelength;
1685  if (quietlength > 0)
1686  dsp->busy_quietlength = quietlength;
1687  else
1688  dsp->busytoneonly = 1;
1689  ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
1690  if( fuzzy > 0 && fuzzy < 50 )
1691  dsp->busy_pattern_fuzzy = fuzzy;
1692 }
int busytoneonly
Definition: dsp.c:399
int busy_pattern_fuzzy
Definition: dsp.c:403
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
int busy_tonelength
Definition: dsp.c:401
int busy_quietlength
Definition: dsp.c:402
int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Set zone for doing progress detection.

Definition at line 1763 of file dsp.c.

References aliases, ARRAY_LEN, ast_dsp_prog_reset(), progalias::mode, name, and ast_dsp::progmode.

Referenced by dahdi_new().

1764 {
1765  int x;
1766 
1767  for (x = 0; x < ARRAY_LEN(aliases); x++) {
1768  if (!strcasecmp(aliases[x].name, zone)) {
1769  dsp->progmode = aliases[x].mode;
1770  ast_dsp_prog_reset(dsp);
1771  return 0;
1772  }
1773  }
1774  return -1;
1775 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
static void ast_dsp_prog_reset(struct ast_dsp *dsp)
Definition: dsp.c:1590
static struct progalias aliases[]
static const char name[]
enum prog_mode mode
Definition: dsp.c:96
enum prog_mode progmode
Definition: dsp.c:410
int ast_dsp_set_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Set digit mode.

Version
1.6.1 renamed from ast_dsp_digitmode to ast_dsp_set_digitmode

Definition at line 1739 of file dsp.c.

References ast_digit_detect_init(), ast_dsp::digit_state, ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, and DSP_DIGITMODE_MUTEMAX.

Referenced by analog_ss_thread(), dahdi_hangup(), dahdi_new(), dahdi_setoption(), enable_dsp_detect(), mgcp_new(), mkintf(), and my_dsp_set_digitmode().

1740 {
1741  int new;
1742  int old;
1743 
1746  if (old != new) {
1747  /* Must initialize structures if switching from MF to DTMF or vice-versa */
1749  }
1750  dsp->digitmode = digitmode;
1751  return 0;
1752 }
#define DSP_DIGITMODE_DTMF
Definition: dsp.h:31
#define DSP_DIGITMODE_MF
Definition: dsp.h:32
#define DSP_DIGITMODE_MUTECONF
Definition: dsp.h:35
digit_detect_state_t digit_state
Definition: dsp.c:420
static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
Definition: dsp.c:528
#define DSP_DIGITMODE_MUTEMAX
Definition: dsp.h:36
int digitmode
Definition: dsp.c:413
int ast_dsp_set_faxmode ( struct ast_dsp dsp,
int  faxmode 
)

Set fax mode.

Definition at line 1754 of file dsp.c.

References ast_fax_detect_init(), and ast_dsp::faxmode.

1755 {
1756  if (dsp->faxmode != faxmode) {
1757  ast_fax_detect_init(dsp);
1758  }
1759  dsp->faxmode = faxmode;
1760  return 0;
1761 }
int faxmode
Definition: dsp.c:414
static void ast_fax_detect_init(struct ast_dsp *s)
Definition: dsp.c:495
void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

Select feature set.

Definition at line 1642 of file dsp.c.

References ast_dsp::display_inband_dtmf_warning, DSP_FEATURE_DIGIT_DETECT, and ast_dsp::features.

Referenced by __oh323_new(), dahdi_handle_dtmf(), dahdi_new(), dahdi_read(), dahdi_setoption(), disable_dtmf_detect(), enable_dsp_detect(), enable_dtmf_detect(), mgcp_new(), misdn_set_opt_exec(), my_handle_dtmf(), my_pri_ss7_open_media(), read_config(), and sip_rtp_read().

1643 {
1644  dsp->features = features;
1645  if (!(features & DSP_FEATURE_DIGIT_DETECT)) {
1646  dsp->display_inband_dtmf_warning = 0;
1647  }
1648 }
#define DSP_FEATURE_DIGIT_DETECT
Definition: dsp.h:28
int features
Definition: dsp.c:395
int display_inband_dtmf_warning
Definition: dsp.c:416
void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Set threshold value for silence.

Definition at line 1655 of file dsp.c.

References ast_dsp::threshold.

Referenced by __ast_play_and_record(), dahdi_new(), do_waiting(), fax_session_new(), handle_recordfile(), isAnsweringMachine(), and record_exec().

1656 {
1657  if (threshold < 256)
1658  dsp->threshold = 256;
1659  else
1660  dsp->threshold = threshold;
1661 }
threshold
Definition: dsp.h:62
int threshold
Definition: dsp.c:392
int ast_dsp_silence ( struct ast_dsp dsp,
struct ast_frame f,
int *  totalsilence 
)

Return non-zero if this is silence. Updates "totalsilence" with the total number of seconds of silence.

Definition at line 1355 of file dsp.c.

References __ast_dsp_silence_noise(), AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, len(), LOG_WARNING, ast_frame::ptr, and ast_frame::subclass.

Referenced by __ast_play_and_record(), background_detect_exec(), conf_run(), debug_check_frame_for_silence(), do_waiting(), handle_recordfile(), isAnsweringMachine(), and record_exec().

1356 {
1357  short *s;
1358  int len;
1359 
1360  if (f->frametype != AST_FRAME_VOICE) {
1361  ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
1362  return 0;
1363  }
1364  if (f->subclass.codec != AST_FORMAT_SLINEAR) {
1365  ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
1366  return 0;
1367  }
1368  s = f->data.ptr;
1369  len = f->datalen/2;
1370  return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
1371 }
union ast_frame_subclass subclass
Definition: frame.h:146
void * ptr
Definition: frame.h:160
#define LOG_WARNING
Definition: logger.h:144
static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
Definition: dsp.c:1187
format_t codec
Definition: frame.h:137
int datalen
Definition: frame.h:148
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
int ast_dsp_was_muted ( struct ast_dsp dsp)

Returns true if DSP code was muting any fragment of the last processed frame. Muting (squelching) happens when DSP code removes DTMF/MF/generic tones from the audio.

Since
1.6.1

Definition at line 1777 of file dsp.c.

References ast_dsp::mute_fragments.

Referenced by dahdi_read().

1778 {
1779  return (dsp->mute_fragments > 0);
1780 }
int mute_fragments
Definition: dsp.c:418
static void ast_dtmf_detect_init ( dtmf_detect_state_t s)
static

Definition at line 501 of file dsp.c.

References dtmf_detect_state_t::col_out, dtmf_detect_state_t::current_hit, dtmf_detect_state_t::current_sample, DTMF_GSIZE, dtmf_detect_state_t::energy, goertzel_init(), dtmf_detect_state_t::hits, dtmf_detect_state_t::lasthit, dtmf_detect_state_t::misses, and dtmf_detect_state_t::row_out.

Referenced by ast_digit_detect_init().

502 {
503  int i;
504 
505  s->lasthit = 0;
506  s->current_hit = 0;
507  for (i = 0; i < 4; i++) {
510  s->energy = 0.0;
511  }
512  s->current_sample = 0;
513  s->hits = 0;
514  s->misses = 0;
515 }
#define DTMF_GSIZE
Definition: dsp.c:219
static const float dtmf_col[]
Definition: dsp.c:309
static const float dtmf_row[]
Definition: dsp.c:306
int current_sample
Definition: dsp.c:279
goertzel_state_t col_out[4]
Definition: dsp.c:273
float energy
Definition: dsp.c:278
static void goertzel_init(goertzel_state_t *s, float freq, int samples)
Definition: dsp.c:360
goertzel_state_t row_out[4]
Definition: dsp.c:272
static void ast_fax_detect_init ( struct ast_dsp s)
static

Definition at line 495 of file dsp.c.

References ast_tone_detect_init(), ast_dsp::ced_tone_state, ast_dsp::cng_tone_state, FAX_TONE_CED_DB, FAX_TONE_CED_DURATION, FAX_TONE_CED_FREQ, FAX_TONE_CNG_DB, FAX_TONE_CNG_DURATION, and FAX_TONE_CNG_FREQ.

Referenced by ast_dsp_new(), and ast_dsp_set_faxmode().

496 {
499 }
#define FAX_TONE_CNG_FREQ
Definition: dsp.c:193
#define FAX_TONE_CED_DB
Definition: dsp.c:203
#define FAX_TONE_CNG_DURATION
Definition: dsp.c:194
#define FAX_TONE_CED_FREQ
Definition: dsp.c:201
#define FAX_TONE_CNG_DB
Definition: dsp.c:195
#define FAX_TONE_CED_DURATION
Definition: dsp.c:202
static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
Definition: dsp.c:435
tone_detect_state_t ced_tone_state
Definition: dsp.c:422
tone_detect_state_t cng_tone_state
Definition: dsp.c:421
static void ast_mf_detect_init ( mf_detect_state_t s)
static

Definition at line 517 of file dsp.c.

References mf_detect_state_t::current_hit, mf_detect_state_t::current_sample, goertzel_init(), mf_detect_state_t::hits, MF_GSIZE, and mf_detect_state_t::tone_out.

Referenced by ast_digit_detect_init().

518 {
519  int i;
520  s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
521  for (i = 0; i < 6; i++) {
522  goertzel_init (&s->tone_out[i], mf_tones[i], MF_GSIZE);
523  }
524  s->current_sample = 0;
525  s->current_hit = 0;
526 }
goertzel_state_t tone_out[6]
Definition: dsp.c:285
static const float mf_tones[]
Definition: dsp.c:312
int hits[5]
Definition: dsp.c:287
int current_sample
Definition: dsp.c:288
#define MF_GSIZE
Definition: dsp.c:216
int current_hit
Definition: dsp.c:286
static void goertzel_init(goertzel_state_t *s, float freq, int samples)
Definition: dsp.c:360
static void ast_tone_detect_init ( tone_detect_state_t s,
int  freq,
int  duration,
int  amp 
)
static

Definition at line 435 of file dsp.c.

References ast_debug, tone_detect_state_t::block_size, tone_detect_state_t::energy, tone_detect_state_t::freq, goertzel_init(), tone_detect_state_t::hit_count, tone_detect_state_t::hits_required, tone_detect_state_t::last_hit, SAMPLE_RATE, SAMPLES_IN_FRAME, tone_detect_state_t::samples_pending, tone_detect_state_t::squelch, tone_detect_state_t::threshold, and tone_detect_state_t::tone.

Referenced by ast_fax_detect_init().

436 {
437  int duration_samples;
438  float x;
439  int periods_in_block;
440 
441  s->freq = freq;
442 
443  /* Desired tone duration in samples */
444  duration_samples = duration * SAMPLE_RATE / 1000;
445  /* We want to allow 10% deviation of tone duration */
446  duration_samples = duration_samples * 9 / 10;
447 
448  /* If we want to remove tone, it is important to have block size not
449  to exceed frame size. Otherwise by the moment tone is detected it is too late
450  to squelch it from previous frames */
452 
453  periods_in_block = s->block_size * freq / SAMPLE_RATE;
454 
455  /* Make sure we will have at least 5 periods at target frequency for analisys.
456  This may make block larger than expected packet and will make squelching impossible
457  but at least we will be detecting the tone */
458  if (periods_in_block < 5)
459  periods_in_block = 5;
460 
461  /* Now calculate final block size. It will contain integer number of periods */
462  s->block_size = periods_in_block * SAMPLE_RATE / freq;
463 
464  /* tone_detect is currently only used to detect fax tones and we
465  do not need squelching the fax tones */
466  s->squelch = 0;
467 
468  /* Account for the first and the last block to be incomplete
469  and thus no tone will be detected in them */
470  s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
471 
472  goertzel_init(&s->tone, freq, s->block_size);
473 
474  s->samples_pending = s->block_size;
475  s->hit_count = 0;
476  s->last_hit = 0;
477  s->energy = 0.0;
478 
479  /* We want tone energy to be amp decibels above the rest of the signal (the noise).
480  According to Parseval's theorem the energy computed in time domain equals to energy
481  computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
482  from the energy in the time domain we will get energy of the remaining signal (without the tone
483  we are detecting). We will be checking that
484  10*log(Ew / (Et - Ew)) > amp
485  Calculate threshold so that we will be actually checking
486  Ew > Et * threshold
487  */
488 
489  x = pow(10.0, amp / 10.0);
490  s->threshold = x / (x + 1);
491 
492  ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
493 }
int hits_required
Definition: dsp.c:262
int samples_pending
Definition: dsp.c:259
float energy
Definition: dsp.c:258
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
float threshold
Definition: dsp.c:263
#define SAMPLES_IN_FRAME
Definition: dsp.c:213
#define SAMPLE_RATE
Definition: dsp.c:205
goertzel_state_t tone
Definition: dsp.c:257
static void goertzel_init(goertzel_state_t *s, float freq, int samples)
Definition: dsp.c:360
static int dtmf_detect ( struct ast_dsp dsp,
digit_detect_state_t s,
int16_t  amp[],
int  samples,
int  squelch,
int  relax 
)
static

Definition at line 661 of file dsp.c.

References dtmf_detect_state_t::col_out, digit_detect_state_t::current_digits, dtmf_detect_state_t::current_hit, dtmf_detect_state_t::current_sample, digit_detect_state_t::digitlen, digit_detect_state_t::dtmf, DTMF_GSIZE, DTMF_RELATIVE_PEAK_COL, DTMF_RELATIVE_PEAK_ROW, DTMF_THRESHOLD, DTMF_TO_TOTAL_ENERGY, fragment_t::end, dtmf_detect_state_t::energy, goertzel_reset(), goertzel_result(), goertzel_sample(), dtmf_detect_state_t::hits, dtmf_detect_state_t::lasthit, dtmf_detect_state_t::misses, mute, mute_fragment(), dtmf_detect_state_t::mute_samples, dtmf_detect_state_t::row_out, ast_frame::samples, fragment_t::start, store_digit(), and digit_detect_state_t::td.

Referenced by ast_dsp_process().

662 {
663  float row_energy[4];
664  float col_energy[4];
665  int i;
666  int j;
667  int sample;
668  short samp;
669  int best_row;
670  int best_col;
671  int hit;
672  int limit;
673  fragment_t mute = {0, 0};
674 
675  if (squelch && s->td.dtmf.mute_samples > 0) {
676  mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
677  s->td.dtmf.mute_samples -= mute.end;
678  }
679 
680  hit = 0;
681  for (sample = 0; sample < samples; sample = limit) {
682  /* DTMF_GSIZE is optimised to meet the DTMF specs. */
683  if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
684  limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
685  } else {
686  limit = samples;
687  }
688  /* The following unrolled loop takes only 35% (rough estimate) of the
689  time of a rolled loop on the machine on which it was developed */
690  for (j = sample; j < limit; j++) {
691  samp = amp[j];
692  s->td.dtmf.energy += (int32_t) samp * (int32_t) samp;
693  /* With GCC 2.95, the following unrolled code seems to take about 35%
694  (rough estimate) as long as a neat little 0-3 loop */
695  goertzel_sample(s->td.dtmf.row_out, samp);
696  goertzel_sample(s->td.dtmf.col_out, samp);
697  goertzel_sample(s->td.dtmf.row_out + 1, samp);
698  goertzel_sample(s->td.dtmf.col_out + 1, samp);
699  goertzel_sample(s->td.dtmf.row_out + 2, samp);
700  goertzel_sample(s->td.dtmf.col_out + 2, samp);
701  goertzel_sample(s->td.dtmf.row_out + 3, samp);
702  goertzel_sample(s->td.dtmf.col_out + 3, samp);
703  }
704  s->td.dtmf.current_sample += (limit - sample);
705  if (s->td.dtmf.current_sample < DTMF_GSIZE) {
706  continue;
707  }
708  /* We are at the end of a DTMF detection block */
709  /* Find the peak row and the peak column */
710  row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
711  col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
712 
713  for (best_row = best_col = 0, i = 1; i < 4; i++) {
714  row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
715  if (row_energy[i] > row_energy[best_row]) {
716  best_row = i;
717  }
718  col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
719  if (col_energy[i] > col_energy[best_col]) {
720  best_col = i;
721  }
722  }
723  hit = 0;
724  /* Basic signal level test and the twist test */
725  if (row_energy[best_row] >= DTMF_THRESHOLD &&
726  col_energy[best_col] >= DTMF_THRESHOLD &&
727  col_energy[best_col] < row_energy[best_row] * (relax ? relax_dtmf_reverse_twist : dtmf_reverse_twist) &&
728  row_energy[best_row] < col_energy[best_col] * (relax ? relax_dtmf_normal_twist : dtmf_normal_twist)) {
729  /* Relative peak test */
730  for (i = 0; i < 4; i++) {
731  if ((i != best_col &&
732  col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
733  (i != best_row
734  && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
735  break;
736  }
737  }
738  /* ... and fraction of total energy test */
739  if (i >= 4 &&
740  (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
741  /* Got a hit */
742  hit = dtmf_positions[(best_row << 2) + best_col];
743  }
744  }
745 
746 /*
747  * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
748  * (40ms reference is tunable with hits_to_begin and misses_to_end)
749  * each hit/miss is 12.75ms with DTMF_GSIZE at 102
750  *
751  * Character recognition: When not DRC *(1) and then
752  * Shall exist VSC > 40 ms (hits_to_begin)
753  * May exist 20 ms <= VSC <= 40 ms
754  * Shall not exist VSC < 20 ms
755  *
756  * Character recognition: When DRC and then
757  * Shall cease Not VSC > 40 ms (misses_to_end)
758  * May cease 20 ms >= Not VSC >= 40 ms
759  * Shall not cease Not VSC < 20 ms
760  *
761  * *(1) or optionally a different digit recognition condition
762  *
763  * Legend: VSC The continuous existence of a valid signal condition.
764  * Not VSC The continuous non-existence of valid signal condition.
765  * DRC The existence of digit recognition condition.
766  * Not DRC The non-existence of digit recognition condition.
767  */
768 
769 /*
770  * Example: hits_to_begin=2 misses_to_end=3
771  * -------A last_hit=A hits=0&1
772  * ------AA hits=2 current_hit=A misses=0 BEGIN A
773  * -----AA- misses=1 last_hit=' ' hits=0
774  * ----AA-- misses=2
775  * ---AA--- misses=3 current_hit=' ' END A
776  * --AA---B last_hit=B hits=0&1
777  * -AA---BC last_hit=C hits=0&1
778  * AA---BCC hits=2 current_hit=C misses=0 BEGIN C
779  * A---BCC- misses=1 last_hit=' ' hits=0
780  * ---BCC-C misses=0 last_hit=C hits=0&1
781  * --BCC-CC misses=0
782  *
783  * Example: hits_to_begin=3 misses_to_end=2
784  * -------A last_hit=A hits=0&1
785  * ------AA hits=2
786  * -----AAA hits=3 current_hit=A misses=0 BEGIN A
787  * ----AAAB misses=1 last_hit=B hits=0&1
788  * ---AAABB misses=2 current_hit=' ' hits=2 END A
789  * --AAABBB hits=3 current_hit=B misses=0 BEGIN B
790  * -AAABBBB misses=0
791  *
792  * Example: hits_to_begin=2 misses_to_end=2
793  * -------A last_hit=A hits=0&1
794  * ------AA hits=2 current_hit=A misses=0 BEGIN A
795  * -----AAB misses=1 hits=0&1
796  * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
797  * ---AABBB misses=0
798  */
799 
800  if (s->td.dtmf.current_hit) {
801  /* We are in the middle of a digit already */
802  if (hit != s->td.dtmf.current_hit) {
803  s->td.dtmf.misses++;
804  if (s->td.dtmf.misses == dtmf_misses_to_end) {
805  /* There were enough misses to consider digit ended */
806  s->td.dtmf.current_hit = 0;
807  }
808  } else {
809  s->td.dtmf.misses = 0;
810  /* Current hit was same as last, so increment digit duration (of last digit) */
811  s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
812  }
813  }
814 
815  /* Look for a start of a new digit no matter if we are already in the middle of some
816  digit or not. This is because hits_to_begin may be smaller than misses_to_end
817  and we may find begin of new digit before we consider last one ended. */
818 
819  if (hit != s->td.dtmf.lasthit) {
820  s->td.dtmf.lasthit = hit;
821  s->td.dtmf.hits = 0;
822  }
823  if (hit && hit != s->td.dtmf.current_hit) {
824  s->td.dtmf.hits++;
825  if (s->td.dtmf.hits == dtmf_hits_to_begin) {
826  store_digit(s, hit);
828  s->td.dtmf.current_hit = hit;
829  s->td.dtmf.misses = 0;
830  }
831  }
832 
833  /* If we had a hit in this block, include it into mute fragment */
834  if (squelch && hit) {
835  if (mute.end < sample - DTMF_GSIZE) {
836  /* There is a gap between fragments */
837  mute_fragment(dsp, &mute);
838  mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
839  }
840  mute.end = limit + DTMF_GSIZE;
841  }
842 
843  /* Reinitialise the detector for the next block */
844  for (i = 0; i < 4; i++) {
845  goertzel_reset(&s->td.dtmf.row_out[i]);
846  goertzel_reset(&s->td.dtmf.col_out[i]);
847  }
848  s->td.dtmf.energy = 0.0;
849  s->td.dtmf.current_sample = 0;
850  }
851 
852  if (squelch && mute.end) {
853  if (mute.end > samples) {
854  s->td.dtmf.mute_samples = mute.end - samples;
855  mute.end = samples;
856  }
857  mute_fragment(dsp, &mute);
858  }
859 
860  return (s->td.dtmf.current_hit); /* return the debounced hit */
861 }
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
Definition: dsp.c:425
static float relax_dtmf_reverse_twist
Definition: dsp.c:321
int start
Definition: dsp.c:373
#define DTMF_RELATIVE_PEAK_COL
Definition: dsp.c:177
int mute_samples
Definition: dsp.c:280
#define DTMF_RELATIVE_PEAK_ROW
Definition: dsp.c:176
#define DTMF_TO_TOTAL_ENERGY
Definition: dsp.c:180
#define DTMF_THRESHOLD
Definition: dsp.c:161
int current_digits
Definition: dsp.c:296
static const char dtmf_positions[]
Definition: dsp.c:315
#define DTMF_GSIZE
Definition: dsp.c:219
static void goertzel_reset(goertzel_state_t *s)
Definition: dsp.c:367
static int mute
Definition: chan_alsa.c:135
static int dtmf_hits_to_begin
Definition: dsp.c:322
dtmf_detect_state_t dtmf
Definition: dsp.c:301
static int dtmf_misses_to_end
Definition: dsp.c:323
int current_sample
Definition: dsp.c:279
goertzel_state_t col_out[4]
Definition: dsp.c:273
static void store_digit(digit_detect_state_t *s, char digit)
Definition: dsp.c:648
int end
Definition: dsp.c:374
static float dtmf_normal_twist
Definition: dsp.c:318
static float relax_dtmf_normal_twist
Definition: dsp.c:320
float energy
Definition: dsp.c:278
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:325
int digitlen[MAX_DTMF_DIGITS+1]
Definition: dsp.c:295
static float goertzel_result(goertzel_state_t *s)
Definition: dsp.c:351
static float dtmf_reverse_twist
Definition: dsp.c:319
union digit_detect_state_t::@254 td
int samples
Definition: frame.h:150
goertzel_state_t row_out[4]
Definition: dsp.c:272
static void goertzel_init ( goertzel_state_t s,
float  freq,
int  samples 
)
inlinestatic

Definition at line 360 of file dsp.c.

References goertzel_state_t::chunky, cos, goertzel_state_t::fac, M_PI, SAMPLE_RATE, goertzel_state_t::samples, goertzel_state_t::v2, and goertzel_state_t::v3.

Referenced by ast_dsp_prog_reset(), ast_dtmf_detect_init(), ast_mf_detect_init(), and ast_tone_detect_init().

361 {
362  s->v2 = s->v3 = s->chunky = 0.0;
363  s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
364  s->samples = samples;
365 }
#define M_PI
int samples
Definition: dsp.c:244
int chunky
Definition: dsp.c:242
#define SAMPLE_RATE
Definition: dsp.c:205
static unsigned int cos
Definition: chan_h323.c:147
int samples
Definition: frame.h:150
static void goertzel_reset ( goertzel_state_t s)
inlinestatic

Definition at line 367 of file dsp.c.

References goertzel_state_t::chunky, goertzel_state_t::v2, and goertzel_state_t::v3.

Referenced by ast_dsp_digitreset(), dtmf_detect(), mf_detect(), and tone_detect().

368 {
369  s->v2 = s->v3 = s->chunky = 0.0;
370 }
int chunky
Definition: dsp.c:242
static float goertzel_result ( goertzel_state_t s)
inlinestatic

Definition at line 351 of file dsp.c.

References goertzel_state_t::chunky, goertzel_state_t::fac, goertzel_result_t::power, goertzel_state_t::v2, goertzel_state_t::v3, and goertzel_result_t::value.

Referenced by __ast_dsp_call_progress(), dtmf_detect(), mf_detect(), and tone_detect().

352 {
354  r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
355  r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
356  r.power = s->chunky * 2;
357  return (float)r.value * (float)(1 << r.power);
358 }
int chunky
Definition: dsp.c:242
static void goertzel_sample ( goertzel_state_t s,
short  sample 
)
inlinestatic

Definition at line 325 of file dsp.c.

References goertzel_state_t::chunky, goertzel_state_t::fac, goertzel_state_t::v2, and goertzel_state_t::v3.

Referenced by __ast_dsp_call_progress(), dtmf_detect(), goertzel_update(), mf_detect(), and tone_detect().

326 {
327  int v1;
328 
329  v1 = s->v2;
330  s->v2 = s->v3;
331 
332  s->v3 = (s->fac * s->v2) >> 15;
333  s->v3 = s->v3 - v1 + (sample >> s->chunky);
334  if (abs(s->v3) > 32768) {
335  s->chunky++;
336  s->v3 = s->v3 >> 1;
337  s->v2 = s->v2 >> 1;
338  }
339 }
int chunky
Definition: dsp.c:242
static void goertzel_update ( goertzel_state_t s,
short *  samps,
int  count 
)
inlinestatic

Definition at line 341 of file dsp.c.

References goertzel_sample().

342 {
343  int i;
344 
345  for (i = 0; i < count; i++) {
346  goertzel_sample(s, samps[i]);
347  }
348 }
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:325
static int mf_detect ( struct ast_dsp dsp,
digit_detect_state_t s,
int16_t  amp[],
int  samples,
int  squelch,
int  relax 
)
static

Definition at line 863 of file dsp.c.

References BELL_MF_RELATIVE_PEAK, BELL_MF_THRESHOLD, BELL_MF_TWIST, mf_detect_state_t::current_hit, mf_detect_state_t::current_sample, fragment_t::end, goertzel_reset(), goertzel_result(), goertzel_sample(), mf_detect_state_t::hits, digit_detect_state_t::mf, MF_GSIZE, mute, mute_fragment(), mf_detect_state_t::mute_samples, ast_frame::samples, fragment_t::start, store_digit(), digit_detect_state_t::td, and mf_detect_state_t::tone_out.

Referenced by ast_dsp_process().

865 {
866  float energy[6];
867  int best;
868  int second_best;
869  int i;
870  int j;
871  int sample;
872  short samp;
873  int hit;
874  int limit;
875  fragment_t mute = {0, 0};
876 
877  if (squelch && s->td.mf.mute_samples > 0) {
878  mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
879  s->td.mf.mute_samples -= mute.end;
880  }
881 
882  hit = 0;
883  for (sample = 0; sample < samples; sample = limit) {
884  /* 80 is optimised to meet the MF specs. */
885  /* XXX So then why is MF_GSIZE defined as 120? */
886  if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
887  limit = sample + (MF_GSIZE - s->td.mf.current_sample);
888  } else {
889  limit = samples;
890  }
891  /* The following unrolled loop takes only 35% (rough estimate) of the
892  time of a rolled loop on the machine on which it was developed */
893  for (j = sample; j < limit; j++) {
894  /* With GCC 2.95, the following unrolled code seems to take about 35%
895  (rough estimate) as long as a neat little 0-3 loop */
896  samp = amp[j];
897  goertzel_sample(s->td.mf.tone_out, samp);
898  goertzel_sample(s->td.mf.tone_out + 1, samp);
899  goertzel_sample(s->td.mf.tone_out + 2, samp);
900  goertzel_sample(s->td.mf.tone_out + 3, samp);
901  goertzel_sample(s->td.mf.tone_out + 4, samp);
902  goertzel_sample(s->td.mf.tone_out + 5, samp);
903  }
904  s->td.mf.current_sample += (limit - sample);
905  if (s->td.mf.current_sample < MF_GSIZE) {
906  continue;
907  }
908  /* We're at the end of an MF detection block. */
909  /* Find the two highest energies. The spec says to look for
910  two tones and two tones only. Taking this literally -ie
911  only two tones pass the minimum threshold - doesn't work
912  well. The sinc function mess, due to rectangular windowing
913  ensure that! Find the two highest energies and ensure they
914  are considerably stronger than any of the others. */
915  energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
916  energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
917  if (energy[0] > energy[1]) {
918  best = 0;
919  second_best = 1;
920  } else {
921  best = 1;
922  second_best = 0;
923  }
924  /*endif*/
925  for (i = 2; i < 6; i++) {
926  energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
927  if (energy[i] >= energy[best]) {
928  second_best = best;
929  best = i;
930  } else if (energy[i] >= energy[second_best]) {
931  second_best = i;
932  }
933  }
934  /* Basic signal level and twist tests */
935  hit = 0;
936  if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
937  && energy[best] < energy[second_best]*BELL_MF_TWIST
938  && energy[best] * BELL_MF_TWIST > energy[second_best]) {
939  /* Relative peak test */
940  hit = -1;
941  for (i = 0; i < 6; i++) {
942  if (i != best && i != second_best) {
943  if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
944  /* The best two are not clearly the best */
945  hit = 0;
946  break;
947  }
948  }
949  }
950  }
951  if (hit) {
952  /* Get the values into ascending order */
953  if (second_best < best) {
954  i = best;
955  best = second_best;
956  second_best = i;
957  }
958  best = best * 5 + second_best - 1;
959  hit = bell_mf_positions[best];
960  /* Look for two successive similar results */
961  /* The logic in the next test is:
962  For KP we need 4 successive identical clean detects, with
963  two blocks of something different preceeding it. For anything
964  else we need two successive identical clean detects, with
965  two blocks of something different preceeding it. */
966  if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
967  ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
968  (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] &&
969  hit != s->td.mf.hits[0]))) {
970  store_digit(s, hit);
971  }
972  }
973 
974 
975  if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
976  /* Two successive block without a hit terminate current digit */
977  s->td.mf.current_hit = 0;
978  }
979 
980  s->td.mf.hits[0] = s->td.mf.hits[1];
981  s->td.mf.hits[1] = s->td.mf.hits[2];
982  s->td.mf.hits[2] = s->td.mf.hits[3];
983  s->td.mf.hits[3] = s->td.mf.hits[4];
984  s->td.mf.hits[4] = hit;
985 
986  /* If we had a hit in this block, include it into mute fragment */
987  if (squelch && hit) {
988  if (mute.end < sample - MF_GSIZE) {
989  /* There is a gap between fragments */
990  mute_fragment(dsp, &mute);
991  mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
992  }
993  mute.end = limit + MF_GSIZE;
994  }
995 
996  /* Reinitialise the detector for the next block */
997  for (i = 0; i < 6; i++)
998  goertzel_reset(&s->td.mf.tone_out[i]);
999  s->td.mf.current_sample = 0;
1000  }
1001 
1002  if (squelch && mute.end) {
1003  if (mute.end > samples) {
1004  s->td.mf.mute_samples = mute.end - samples;
1005  mute.end = samples;
1006  }
1007  mute_fragment(dsp, &mute);
1008  }
1009 
1010  return (s->td.mf.current_hit); /* return the debounced hit */
1011 }
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
Definition: dsp.c:425
int start
Definition: dsp.c:373
int mute_samples
Definition: dsp.c:289
static const char bell_mf_positions[]
Definition: dsp.c:316
goertzel_state_t tone_out[6]
Definition: dsp.c:285
static void goertzel_reset(goertzel_state_t *s)
Definition: dsp.c:367
#define BELL_MF_TWIST
Definition: dsp.c:183
static int mute
Definition: chan_alsa.c:135
static void store_digit(digit_detect_state_t *s, char digit)
Definition: dsp.c:648
int end
Definition: dsp.c:374
int hits[5]
Definition: dsp.c:287
int current_sample
Definition: dsp.c:288
#define MF_GSIZE
Definition: dsp.c:216
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:325
#define BELL_MF_RELATIVE_PEAK
Definition: dsp.c:184
#define BELL_MF_THRESHOLD
Definition: dsp.c:182
static float goertzel_result(goertzel_state_t *s)
Definition: dsp.c:351
int current_hit
Definition: dsp.c:286
union digit_detect_state_t::@254 td
mf_detect_state_t mf
Definition: dsp.c:302
int samples
Definition: frame.h:150
static void mute_fragment ( struct ast_dsp dsp,
fragment_t fragment 
)
static

Definition at line 425 of file dsp.c.

References ARRAY_LEN, ast_log(), LOG_ERROR, ast_dsp::mute_data, and ast_dsp::mute_fragments.

Referenced by dtmf_detect(), mf_detect(), and tone_detect().

426 {
427  if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
428  ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
429  return;
430  }
431 
432  dsp->mute_data[dsp->mute_fragments++] = *fragment;
433 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
#define LOG_ERROR
Definition: logger.h:155
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int mute_fragments
Definition: dsp.c:418
fragment_t mute_data[5]
Definition: dsp.c:419
static int pair_there ( float  p1,
float  p2,
float  i1,
float  i2,
float  e 
)
inlinestatic

Definition at line 1013 of file dsp.c.

References TONE_MIN_THRESH, and TONE_THRESH.

Referenced by __ast_dsp_call_progress().

1014 {
1015  /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
1016  /* Make sure absolute levels are high enough */
1017  if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
1018  return 0;
1019  }
1020  /* Amplify ignored stuff */
1021  i2 *= TONE_THRESH;
1022  i1 *= TONE_THRESH;
1023  e *= TONE_THRESH;
1024  /* Check first tone */
1025  if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
1026  return 0;
1027  }
1028  /* And second */
1029  if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
1030  return 0;
1031  }
1032  /* Guess it's there... */
1033  return 1;
1034 }
#define TONE_THRESH
Definition: dsp.c:134
#define TONE_MIN_THRESH
Definition: dsp.c:135
static void store_digit ( digit_detect_state_t s,
char  digit 
)
static

Definition at line 648 of file dsp.c.

References ast_log(), digit_detect_state_t::current_digits, digit_detect_state_t::detected_digits, digit_detect_state_t::digitlen, digit_detect_state_t::digits, LOG_WARNING, digit_detect_state_t::lost_digits, and MAX_DTMF_DIGITS.

Referenced by dtmf_detect(), and mf_detect().

649 {
650  s->detected_digits++;
651  if (s->current_digits < MAX_DTMF_DIGITS) {
652  s->digitlen[s->current_digits] = 0;
653  s->digits[s->current_digits++] = digit;
654  s->digits[s->current_digits] = '\0';
655  } else {
656  ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
657  s->lost_digits++;
658  }
659 }
#define LOG_WARNING
Definition: logger.h:144
int current_digits
Definition: dsp.c:296
char digits[MAX_DTMF_DIGITS+1]
Definition: dsp.c:294
#define MAX_DTMF_DIGITS
Definition: dsp.c:147
int detected_digits
Definition: dsp.c:297
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int digitlen[MAX_DTMF_DIGITS+1]
Definition: dsp.c:295
static int tone_detect ( struct ast_dsp dsp,
tone_detect_state_t s,
int16_t *  amp,
int  samples 
)
static

Definition at line 542 of file dsp.c.

References ast_debug, tone_detect_state_t::block_size, fragment_t::end, tone_detect_state_t::energy, tone_detect_state_t::freq, goertzel_reset(), goertzel_result(), goertzel_sample(), tone_detect_state_t::hit_count, tone_detect_state_t::hits_required, tone_detect_state_t::last_hit, mute, mute_fragment(), tone_detect_state_t::mute_samples, ast_frame::ptr, ast_frame::samples, tone_detect_state_t::samples_pending, tone_detect_state_t::squelch, fragment_t::start, tone_detect_state_t::threshold, and tone_detect_state_t::tone.

Referenced by ast_dsp_process().

543 {
544  float tone_energy;
545  int i;
546  int hit = 0;
547  int limit;
548  int res = 0;
549  int16_t *ptr;
550  short samp;
551  int start, end;
552  fragment_t mute = {0, 0};
553 
554  if (s->squelch && s->mute_samples > 0) {
555  mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
556  s->mute_samples -= mute.end;
557  }
558 
559  for (start = 0; start < samples; start = end) {
560  /* Process in blocks. */
561  limit = samples - start;
562  if (limit > s->samples_pending) {
563  limit = s->samples_pending;
564  }
565  end = start + limit;
566 
567  for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
568  samp = *ptr;
569  /* signed 32 bit int should be enough to square any possible signed 16 bit value */
570  s->energy += (int32_t) samp * (int32_t) samp;
571 
572  goertzel_sample(&s->tone, samp);
573  }
574 
575  s->samples_pending -= limit;
576 
577  if (s->samples_pending) {
578  /* Finished incomplete (last) block */
579  break;
580  }
581 
582  tone_energy = goertzel_result(&s->tone);
583 
584  /* Scale to make comparable */
585  tone_energy *= 2.0;
586  s->energy *= s->block_size;
587 
588  ast_debug(10, "tone %d, Ew=%.2E, Et=%.2E, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
589  hit = 0;
590  if (tone_energy > s->energy * s->threshold) {
591  ast_debug(10, "Hit! count=%d\n", s->hit_count);
592  hit = 1;
593  }
594 
595  if (s->hit_count) {
596  s->hit_count++;
597  }
598 
599  if (hit == s->last_hit) {
600  if (!hit) {
601  /* Two successive misses. Tone ended */
602  s->hit_count = 0;
603  } else if (!s->hit_count) {
604  s->hit_count++;
605  }
606 
607  }
608 
609  if (s->hit_count == s->hits_required) {
610  ast_debug(1, "%d Hz done detected\n", s->freq);
611  res = 1;
612  }
613 
614  s->last_hit = hit;
615 
616  /* If we had a hit in this block, include it into mute fragment */
617  if (s->squelch && hit) {
618  if (mute.end < start - s->block_size) {
619  /* There is a gap between fragments */
620  mute_fragment(dsp, &mute);
621  mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
622  }
623  mute.end = end + s->block_size;
624  }
625 
626  /* Reinitialise the detector for the next block */
627  /* Reset for the next block */
628  goertzel_reset(&s->tone);
629 
630  /* Advance to the next block */
631  s->energy = 0.0;
632  s->samples_pending = s->block_size;
633 
634  amp += limit;
635  }
636 
637  if (s->squelch && mute.end) {
638  if (mute.end > samples) {
639  s->mute_samples = mute.end - samples;
640  mute.end = samples;
641  }
642  mute_fragment(dsp, &mute);
643  }
644 
645  return res;
646 }
static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
Definition: dsp.c:425
int hits_required
Definition: dsp.c:262
int start
Definition: dsp.c:373
void * ptr
Definition: frame.h:160
int samples_pending
Definition: dsp.c:259
float energy
Definition: dsp.c:258
static void goertzel_reset(goertzel_state_t *s)
Definition: dsp.c:367
static int mute
Definition: chan_alsa.c:135
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
float threshold
Definition: dsp.c:263
int end
Definition: dsp.c:374
static void goertzel_sample(goertzel_state_t *s, short sample)
Definition: dsp.c:325
static float goertzel_result(goertzel_state_t *s)
Definition: dsp.c:351
goertzel_state_t tone
Definition: dsp.c:257
int mute_samples
Definition: dsp.c:260
int samples
Definition: frame.h:150

Variable Documentation

struct progalias aliases[]
static
const char bell_mf_positions[] = "1247C-358A--69*---0B----#"
static

Definition at line 316 of file dsp.c.

const int DEFAULT_SILENCE_THRESHOLD = 256
static

The default silence threshold we will use if an alternate configured value is not present or is invalid.

Definition at line 235 of file dsp.c.

Referenced by _dsp_init().

const float dtmf_col[]
static
Initial value:
= {
1209.0, 1336.0, 1477.0, 1633.0
}

Definition at line 309 of file dsp.c.

int dtmf_hits_to_begin
static

Definition at line 322 of file dsp.c.

int dtmf_misses_to_end
static

Definition at line 323 of file dsp.c.

float dtmf_normal_twist
static

Definition at line 318 of file dsp.c.

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

Definition at line 315 of file dsp.c.

float dtmf_reverse_twist
static

Definition at line 319 of file dsp.c.

const float dtmf_row[]
static
Initial value:
= {
697.0, 770.0, 852.0, 941.0
}

Definition at line 306 of file dsp.c.

const float mf_tones[]
static
Initial value:
= {
700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
}

Definition at line 312 of file dsp.c.

struct progress modes[]
static
Initial value:
= {
{ GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } },
{ GSAMP_SIZE_CR, { 425 } },
{ GSAMP_SIZE_UK, { 350, 400, 440 } },
}

Referenced by ast_dsp_prog_reset().

float relax_dtmf_normal_twist
static

Definition at line 320 of file dsp.c.

float relax_dtmf_reverse_twist
static

Definition at line 321 of file dsp.c.

int thresholds[THRESHOLD_MAX]
static

Definition at line 317 of file dsp.c.