mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-23 05:40:52 +00:00
Merge twisted's dsp formatting fixes (bug #3218)
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4638 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
303
dsp.c
303
dsp.c
@@ -149,7 +149,6 @@ typedef struct {
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
||||||
goertzel_state_t row_out[4];
|
goertzel_state_t row_out[4];
|
||||||
goertzel_state_t col_out[4];
|
goertzel_state_t col_out[4];
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
@@ -173,12 +172,11 @@ typedef struct
|
|||||||
int current_sample;
|
int current_sample;
|
||||||
|
|
||||||
char digits[MAX_DTMF_DIGITS + 1];
|
char digits[MAX_DTMF_DIGITS + 1];
|
||||||
|
|
||||||
int current_digits;
|
int current_digits;
|
||||||
int detected_digits;
|
int detected_digits;
|
||||||
int lost_digits;
|
int lost_digits;
|
||||||
int digit_hits[16];
|
int digit_hits[16];
|
||||||
|
|
||||||
|
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
int fax_hits;
|
int fax_hits;
|
||||||
#endif
|
#endif
|
||||||
@@ -198,9 +196,10 @@ typedef struct
|
|||||||
#else
|
#else
|
||||||
int hits[5];
|
int hits[5];
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int current_sample;
|
int current_sample;
|
||||||
|
|
||||||
char digits[MAX_DTMF_DIGITS + 1];
|
char digits[MAX_DTMF_DIGITS + 1];
|
||||||
|
|
||||||
int current_digits;
|
int current_digits;
|
||||||
int detected_digits;
|
int detected_digits;
|
||||||
int lost_digits;
|
int lost_digits;
|
||||||
@@ -246,6 +245,7 @@ static inline void goertzel_sample(goertzel_state_t *s, short sample)
|
|||||||
{
|
{
|
||||||
float v1;
|
float v1;
|
||||||
float fsamp = sample;
|
float fsamp = sample;
|
||||||
|
|
||||||
v1 = s->v2;
|
v1 = s->v2;
|
||||||
s->v2 = s->v3;
|
s->v2 = s->v3;
|
||||||
s->v3 = s->fac * s->v2 - v1 + fsamp;
|
s->v3 = s->fac * s->v2 - v1 + fsamp;
|
||||||
@@ -254,6 +254,7 @@ static inline void goertzel_sample(goertzel_state_t *s, short sample)
|
|||||||
static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
|
static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0;i<count;i++)
|
for (i=0;i<count;i++)
|
||||||
goertzel_sample(s, samps[i]);
|
goertzel_sample(s, samps[i]);
|
||||||
}
|
}
|
||||||
@@ -317,9 +318,7 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
|
|||||||
#else
|
#else
|
||||||
s->hits[0] = s->hits[1] = s->hits[2] = 0;
|
s->hits[0] = s->hits[1] = s->hits[2] = 0;
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++) {
|
||||||
{
|
|
||||||
|
|
||||||
goertzel_init (&s->row_out[i], dtmf_row[i], 102);
|
goertzel_init (&s->row_out[i], dtmf_row[i], 102);
|
||||||
goertzel_init (&s->col_out[i], dtmf_col[i], 102);
|
goertzel_init (&s->col_out[i], dtmf_col[i], 102);
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
@@ -328,7 +327,6 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
|
|||||||
#endif
|
#endif
|
||||||
s->energy = 0.0;
|
s->energy = 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
/* Same for the fax dector */
|
/* Same for the fax dector */
|
||||||
goertzel_init (&s->fax_tone, fax_freq, 102);
|
goertzel_init (&s->fax_tone, fax_freq, 102);
|
||||||
@@ -338,7 +336,6 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
|
|||||||
goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
|
goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102);
|
||||||
#endif
|
#endif
|
||||||
#endif /* FAX_DETECT */
|
#endif /* FAX_DETECT */
|
||||||
|
|
||||||
s->current_sample = 0;
|
s->current_sample = 0;
|
||||||
s->detected_digits = 0;
|
s->detected_digits = 0;
|
||||||
s->current_digits = 0;
|
s->current_digits = 0;
|
||||||
@@ -350,24 +347,19 @@ static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
|
|||||||
static void ast_mf_detect_init (mf_detect_state_t *s)
|
static void ast_mf_detect_init (mf_detect_state_t *s)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
s->hit1 =
|
s->hit1 =
|
||||||
s->hit2 = 0;
|
s->hit2 = 0;
|
||||||
#else
|
#else
|
||||||
s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
|
s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
|
||||||
#endif
|
#endif
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++) {
|
||||||
{
|
|
||||||
|
|
||||||
goertzel_init (&s->tone_out[i], mf_tones[i], 160);
|
goertzel_init (&s->tone_out[i], mf_tones[i], 160);
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
|
goertzel_init (&s->tone_out2nd[i], mf_tones[i] * 2.0, 160);
|
||||||
s->energy = 0.0;
|
s->energy = 0.0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
s->current_digits = 0;
|
s->current_digits = 0;
|
||||||
memset(&s->digits, 0, sizeof(s->digits));
|
memset(&s->digits, 0, sizeof(s->digits));
|
||||||
s->current_sample = 0;
|
s->current_sample = 0;
|
||||||
@@ -377,12 +369,9 @@ static void ast_mf_detect_init (mf_detect_state_t *s)
|
|||||||
s->mhit = 0;
|
s->mhit = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dtmf_detect (dtmf_detect_state_t *s,
|
static int dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples,
|
||||||
int16_t amp[],
|
|
||||||
int samples,
|
|
||||||
int digitmode, int *writeback, int faxdetect)
|
int digitmode, int *writeback, int faxdetect)
|
||||||
{
|
{
|
||||||
|
|
||||||
float row_energy[4];
|
float row_energy[4];
|
||||||
float col_energy[4];
|
float col_energy[4];
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
@@ -402,8 +391,7 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
int limit;
|
int limit;
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
for (sample = 0; sample < samples; sample = limit)
|
for (sample = 0; sample < samples; sample = limit) {
|
||||||
{
|
|
||||||
/* 102 is optimised to meet the DTMF specs. */
|
/* 102 is optimised to meet the DTMF specs. */
|
||||||
if ((samples - sample) >= (102 - s->current_sample))
|
if ((samples - sample) >= (102 - s->current_sample))
|
||||||
limit = sample + (102 - s->current_sample);
|
limit = sample + (102 - s->current_sample);
|
||||||
@@ -421,46 +409,35 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
#else
|
#else
|
||||||
/* The following unrolled loop takes only 35% (rough estimate) of the
|
/* The following unrolled loop takes only 35% (rough estimate) of the
|
||||||
time of a rolled loop on the machine on which it was developed */
|
time of a rolled loop on the machine on which it was developed */
|
||||||
for (j = sample; j < limit; j++)
|
for (j=sample;j<limit;j++) {
|
||||||
{
|
|
||||||
famp = amp[j];
|
famp = amp[j];
|
||||||
|
|
||||||
s->energy += famp*famp;
|
s->energy += famp*famp;
|
||||||
|
|
||||||
/* With GCC 2.95, the following unrolled code seems to take about 35%
|
/* With GCC 2.95, the following unrolled code seems to take about 35%
|
||||||
(rough estimate) as long as a neat little 0-3 loop */
|
(rough estimate) as long as a neat little 0-3 loop */
|
||||||
v1 = s->row_out[0].v2;
|
v1 = s->row_out[0].v2;
|
||||||
s->row_out[0].v2 = s->row_out[0].v3;
|
s->row_out[0].v2 = s->row_out[0].v3;
|
||||||
s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
|
s->row_out[0].v3 = s->row_out[0].fac*s->row_out[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out[0].v2;
|
v1 = s->col_out[0].v2;
|
||||||
s->col_out[0].v2 = s->col_out[0].v3;
|
s->col_out[0].v2 = s->col_out[0].v3;
|
||||||
s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
|
s->col_out[0].v3 = s->col_out[0].fac*s->col_out[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out[1].v2;
|
v1 = s->row_out[1].v2;
|
||||||
s->row_out[1].v2 = s->row_out[1].v3;
|
s->row_out[1].v2 = s->row_out[1].v3;
|
||||||
s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
|
s->row_out[1].v3 = s->row_out[1].fac*s->row_out[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out[1].v2;
|
v1 = s->col_out[1].v2;
|
||||||
s->col_out[1].v2 = s->col_out[1].v3;
|
s->col_out[1].v2 = s->col_out[1].v3;
|
||||||
s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
|
s->col_out[1].v3 = s->col_out[1].fac*s->col_out[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out[2].v2;
|
v1 = s->row_out[2].v2;
|
||||||
s->row_out[2].v2 = s->row_out[2].v3;
|
s->row_out[2].v2 = s->row_out[2].v3;
|
||||||
s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
|
s->row_out[2].v3 = s->row_out[2].fac*s->row_out[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out[2].v2;
|
v1 = s->col_out[2].v2;
|
||||||
s->col_out[2].v2 = s->col_out[2].v3;
|
s->col_out[2].v2 = s->col_out[2].v3;
|
||||||
s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
|
s->col_out[2].v3 = s->col_out[2].fac*s->col_out[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out[3].v2;
|
v1 = s->row_out[3].v2;
|
||||||
s->row_out[3].v2 = s->row_out[3].v3;
|
s->row_out[3].v2 = s->row_out[3].v3;
|
||||||
s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
|
s->row_out[3].v3 = s->row_out[3].fac*s->row_out[3].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out[3].v2;
|
v1 = s->col_out[3].v2;
|
||||||
s->col_out[3].v2 = s->col_out[3].v3;
|
s->col_out[3].v2 = s->col_out[3].v3;
|
||||||
s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
|
s->col_out[3].v3 = s->col_out[3].fac*s->col_out[3].v2 - v1 + famp;
|
||||||
|
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
/* Update fax tone */
|
/* Update fax tone */
|
||||||
v1 = s->fax_tone.v2;
|
v1 = s->fax_tone.v2;
|
||||||
@@ -471,36 +448,27 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
v1 = s->col_out2nd[0].v2;
|
v1 = s->col_out2nd[0].v2;
|
||||||
s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
|
s->col_out2nd[0].v2 = s->col_out2nd[0].v3;
|
||||||
s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
|
s->col_out2nd[0].v3 = s->col_out2nd[0].fac*s->col_out2nd[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out2nd[0].v2;
|
v1 = s->row_out2nd[0].v2;
|
||||||
s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
|
s->row_out2nd[0].v2 = s->row_out2nd[0].v3;
|
||||||
s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
|
s->row_out2nd[0].v3 = s->row_out2nd[0].fac*s->row_out2nd[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out2nd[1].v2;
|
v1 = s->col_out2nd[1].v2;
|
||||||
s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
|
s->col_out2nd[1].v2 = s->col_out2nd[1].v3;
|
||||||
s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
|
s->col_out2nd[1].v3 = s->col_out2nd[1].fac*s->col_out2nd[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out2nd[1].v2;
|
v1 = s->row_out2nd[1].v2;
|
||||||
s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
|
s->row_out2nd[1].v2 = s->row_out2nd[1].v3;
|
||||||
s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
|
s->row_out2nd[1].v3 = s->row_out2nd[1].fac*s->row_out2nd[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out2nd[2].v2;
|
v1 = s->col_out2nd[2].v2;
|
||||||
s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
|
s->col_out2nd[2].v2 = s->col_out2nd[2].v3;
|
||||||
s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
|
s->col_out2nd[2].v3 = s->col_out2nd[2].fac*s->col_out2nd[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out2nd[2].v2;
|
v1 = s->row_out2nd[2].v2;
|
||||||
s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
|
s->row_out2nd[2].v2 = s->row_out2nd[2].v3;
|
||||||
s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
|
s->row_out2nd[2].v3 = s->row_out2nd[2].fac*s->row_out2nd[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->col_out2nd[3].v2;
|
v1 = s->col_out2nd[3].v2;
|
||||||
s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
|
s->col_out2nd[3].v2 = s->col_out2nd[3].v3;
|
||||||
s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
|
s->col_out2nd[3].v3 = s->col_out2nd[3].fac*s->col_out2nd[3].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->row_out2nd[3].v2;
|
v1 = s->row_out2nd[3].v2;
|
||||||
s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
|
s->row_out2nd[3].v2 = s->row_out2nd[3].v3;
|
||||||
s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
|
s->row_out2nd[3].v3 = s->row_out2nd[3].fac*s->row_out2nd[3].v2 - v1 + famp;
|
||||||
|
|
||||||
|
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
/* Update fax tone */
|
/* Update fax tone */
|
||||||
v1 = s->fax_tone.v2;
|
v1 = s->fax_tone.v2;
|
||||||
@@ -521,19 +489,16 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
/* Detect the fax energy, too */
|
/* Detect the fax energy, too */
|
||||||
fax_energy = goertzel_result(&s->fax_tone);
|
fax_energy = goertzel_result(&s->fax_tone);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* We are at the end of a DTMF detection block */
|
/* We are at the end of a DTMF detection block */
|
||||||
/* Find the peak row and the peak column */
|
/* Find the peak row and the peak column */
|
||||||
row_energy[0] = goertzel_result (&s->row_out[0]);
|
row_energy[0] = goertzel_result (&s->row_out[0]);
|
||||||
col_energy[0] = goertzel_result (&s->col_out[0]);
|
col_energy[0] = goertzel_result (&s->col_out[0]);
|
||||||
|
|
||||||
for (best_row = best_col = 0, i = 1; i < 4; i++)
|
for (best_row = best_col = 0, i = 1; i < 4; i++) {
|
||||||
{
|
|
||||||
row_energy[i] = goertzel_result (&s->row_out[i]);
|
row_energy[i] = goertzel_result (&s->row_out[i]);
|
||||||
if (row_energy[i] > row_energy[best_row])
|
if (row_energy[i] > row_energy[best_row])
|
||||||
best_row = i;
|
best_row = i;
|
||||||
@@ -543,40 +508,30 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
}
|
}
|
||||||
hit = 0;
|
hit = 0;
|
||||||
/* Basic signal level test and the twist test */
|
/* Basic signal level test and the twist test */
|
||||||
if (row_energy[best_row] >= DTMF_THRESHOLD
|
if (row_energy[best_row] >= DTMF_THRESHOLD &&
|
||||||
&&
|
col_energy[best_col] >= DTMF_THRESHOLD &&
|
||||||
col_energy[best_col] >= DTMF_THRESHOLD
|
col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
|
||||||
&&
|
col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
|
||||||
col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST
|
|
||||||
&&
|
|
||||||
col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row])
|
|
||||||
{
|
|
||||||
/* Relative peak test */
|
/* Relative peak test */
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++) {
|
||||||
{
|
if ((i != best_col &&
|
||||||
if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col])
|
col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
|
||||||
||
|
(i != best_row
|
||||||
(i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row]))
|
&& row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
|
||||||
{
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
/* ... and second harmonic test */
|
/* ... and second harmonic test */
|
||||||
if (i >= 4
|
if (i >= 4 &&
|
||||||
&&
|
(row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy &&
|
||||||
(row_energy[best_row] + col_energy[best_col]) > 42.0*s->energy
|
goertzel_result(&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
|
||||||
&&
|
&& goertzel_result(&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row]) {
|
||||||
goertzel_result (&s->col_out2nd[best_col])*DTMF_2ND_HARMONIC_COL < col_energy[best_col]
|
|
||||||
&&
|
|
||||||
goertzel_result (&s->row_out2nd[best_row])*DTMF_2ND_HARMONIC_ROW < row_energy[best_row])
|
|
||||||
#else
|
#else
|
||||||
/* ... and fraction of total energy test */
|
/* ... and fraction of total energy test */
|
||||||
if (i >= 4
|
if (i >= 4 &&
|
||||||
&&
|
(row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) {
|
||||||
(row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy)
|
|
||||||
#endif
|
#endif
|
||||||
{
|
|
||||||
/* Got a hit */
|
/* Got a hit */
|
||||||
hit = dtmf_positions[(best_row << 2) + best_col];
|
hit = dtmf_positions[(best_row << 2) + best_col];
|
||||||
if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
|
if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
|
||||||
@@ -591,37 +546,28 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
something different preceeding it. This can work with
|
something different preceeding it. This can work with
|
||||||
back to back differing digits. More importantly, it
|
back to back differing digits. More importantly, it
|
||||||
can work with nasty phones that give a very wobbly start
|
can work with nasty phones that give a very wobbly start
|
||||||
to a digit. */
|
to a digit */
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
if (hit == s->hit3 && s->hit3 != s->hit2)
|
if (hit == s->hit3 && s->hit3 != s->hit2) {
|
||||||
{
|
|
||||||
s->mhit = hit;
|
s->mhit = hit;
|
||||||
s->digit_hits[(best_row << 2) + best_col]++;
|
s->digit_hits[(best_row << 2) + best_col]++;
|
||||||
s->detected_digits++;
|
s->detected_digits++;
|
||||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
if (s->current_digits < MAX_DTMF_DIGITS) {
|
||||||
{
|
|
||||||
s->digits[s->current_digits++] = hit;
|
s->digits[s->current_digits++] = hit;
|
||||||
s->digits[s->current_digits] = '\0';
|
s->digits[s->current_digits] = '\0';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
s->lost_digits++;
|
s->lost_digits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
if (hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0])
|
if (hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0]) {
|
||||||
{
|
|
||||||
s->mhit = hit;
|
s->mhit = hit;
|
||||||
s->digit_hits[(best_row << 2) + best_col]++;
|
s->digit_hits[(best_row << 2) + best_col]++;
|
||||||
s->detected_digits++;
|
s->detected_digits++;
|
||||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
if (s->current_digits < MAX_DTMF_DIGITS) {
|
||||||
{
|
|
||||||
s->digits[s->current_digits++] = hit;
|
s->digits[s->current_digits++] = hit;
|
||||||
s->digits[s->current_digits] = '\0';
|
s->digits[s->current_digits] = '\0';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
s->lost_digits++;
|
s->lost_digits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -629,26 +575,24 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifdef FAX_DETECT
|
#ifdef FAX_DETECT
|
||||||
if (!hit && (fax_energy >= FAX_THRESHOLD) && (fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) && (faxdetect)) {
|
if (!hit && (fax_energy >= FAX_THRESHOLD) &&
|
||||||
|
(fax_energy >= DTMF_TO_TOTAL_ENERGY*s->energy) &&
|
||||||
|
(faxdetect)) {
|
||||||
#if 0
|
#if 0
|
||||||
printf("Fax energy/Second Harmonic: %f\n", fax_energy);
|
printf("Fax energy/Second Harmonic: %f\n", fax_energy);
|
||||||
#endif
|
#endif
|
||||||
/* XXX Probably need better checking than just this the energy XXX */
|
/* XXX Probably need better checking than just this the energy XXX */
|
||||||
hit = 'f';
|
hit = 'f';
|
||||||
s->fax_hits++;
|
s->fax_hits++;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (s->fax_hits > 5) {
|
if (s->fax_hits > 5) {
|
||||||
hit = 'f';
|
hit = 'f';
|
||||||
s->mhit = 'f';
|
s->mhit = 'f';
|
||||||
s->detected_digits++;
|
s->detected_digits++;
|
||||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
if (s->current_digits < MAX_DTMF_DIGITS) {
|
||||||
{
|
|
||||||
s->digits[s->current_digits++] = hit;
|
s->digits[s->current_digits++] = hit;
|
||||||
s->digits[s->current_digits] = '\0';
|
s->digits[s->current_digits] = '\0';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
s->lost_digits++;
|
s->lost_digits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -665,8 +609,7 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
s->hits[2] = hit;
|
s->hits[2] = hit;
|
||||||
#endif
|
#endif
|
||||||
/* Reinitialise the detector for the next block */
|
/* Reinitialise the detector for the next block */
|
||||||
for (i = 0; i < 4; i++)
|
for (i = 0; i < 4; i++) {
|
||||||
{
|
|
||||||
goertzel_reset(&s->row_out[i]);
|
goertzel_reset(&s->row_out[i]);
|
||||||
goertzel_reset(&s->col_out[i]);
|
goertzel_reset(&s->col_out[i]);
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
@@ -683,8 +626,7 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
s->energy = 0.0;
|
s->energy = 0.0;
|
||||||
s->current_sample = 0;
|
s->current_sample = 0;
|
||||||
}
|
}
|
||||||
if ((!s->mhit) || (s->mhit != hit))
|
if ((!s->mhit) || (s->mhit != hit)) {
|
||||||
{
|
|
||||||
s->mhit = 0;
|
s->mhit = 0;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@@ -698,12 +640,9 @@ static int dtmf_detect (dtmf_detect_state_t *s,
|
|||||||
#define MF_GSIZE 120
|
#define MF_GSIZE 120
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int mf_detect (mf_detect_state_t *s,
|
static int mf_detect (mf_detect_state_t *s, int16_t amp[],
|
||||||
int16_t amp[],
|
int samples, int digitmode, int *writeback)
|
||||||
int samples,
|
|
||||||
int digitmode, int *writeback)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
float tone_energy[6];
|
float tone_energy[6];
|
||||||
int best1;
|
int best1;
|
||||||
@@ -724,8 +663,7 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
int limit;
|
int limit;
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
for (sample = 0; sample < samples; sample = limit)
|
for (sample = 0; sample < samples; sample = limit) {
|
||||||
{
|
|
||||||
/* 80 is optimised to meet the MF specs. */
|
/* 80 is optimised to meet the MF specs. */
|
||||||
if ((samples - sample) >= (MF_GSIZE - s->current_sample))
|
if ((samples - sample) >= (MF_GSIZE - s->current_sample))
|
||||||
limit = sample + (MF_GSIZE - s->current_sample);
|
limit = sample + (MF_GSIZE - s->current_sample);
|
||||||
@@ -743,61 +681,47 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
#else
|
#else
|
||||||
/* The following unrolled loop takes only 35% (rough estimate) of the
|
/* The following unrolled loop takes only 35% (rough estimate) of the
|
||||||
time of a rolled loop on the machine on which it was developed */
|
time of a rolled loop on the machine on which it was developed */
|
||||||
for (j = sample; j < limit; j++)
|
for (j = sample; j < limit; j++) {
|
||||||
{
|
|
||||||
famp = amp[j];
|
famp = amp[j];
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
s->energy += famp*famp;
|
s->energy += famp*famp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* With GCC 2.95, the following unrolled code seems to take about 35%
|
/* With GCC 2.95, the following unrolled code seems to take about 35%
|
||||||
(rough estimate) as long as a neat little 0-3 loop */
|
(rough estimate) as long as a neat little 0-3 loop */
|
||||||
v1 = s->tone_out[0].v2;
|
v1 = s->tone_out[0].v2;
|
||||||
s->tone_out[0].v2 = s->tone_out[0].v3;
|
s->tone_out[0].v2 = s->tone_out[0].v3;
|
||||||
s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
|
s->tone_out[0].v3 = s->tone_out[0].fac*s->tone_out[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out[1].v2;
|
v1 = s->tone_out[1].v2;
|
||||||
s->tone_out[1].v2 = s->tone_out[1].v3;
|
s->tone_out[1].v2 = s->tone_out[1].v3;
|
||||||
s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
|
s->tone_out[1].v3 = s->tone_out[1].fac*s->tone_out[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out[2].v2;
|
v1 = s->tone_out[2].v2;
|
||||||
s->tone_out[2].v2 = s->tone_out[2].v3;
|
s->tone_out[2].v2 = s->tone_out[2].v3;
|
||||||
s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
|
s->tone_out[2].v3 = s->tone_out[2].fac*s->tone_out[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out[3].v2;
|
v1 = s->tone_out[3].v2;
|
||||||
s->tone_out[3].v2 = s->tone_out[3].v3;
|
s->tone_out[3].v2 = s->tone_out[3].v3;
|
||||||
s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
|
s->tone_out[3].v3 = s->tone_out[3].fac*s->tone_out[3].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out[4].v2;
|
v1 = s->tone_out[4].v2;
|
||||||
s->tone_out[4].v2 = s->tone_out[4].v3;
|
s->tone_out[4].v2 = s->tone_out[4].v3;
|
||||||
s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
|
s->tone_out[4].v3 = s->tone_out[4].fac*s->tone_out[4].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out[5].v2;
|
v1 = s->tone_out[5].v2;
|
||||||
s->tone_out[5].v2 = s->tone_out[5].v3;
|
s->tone_out[5].v2 = s->tone_out[5].v3;
|
||||||
s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
|
s->tone_out[5].v3 = s->tone_out[5].fac*s->tone_out[5].v2 - v1 + famp;
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
v1 = s->tone_out2nd[0].v2;
|
v1 = s->tone_out2nd[0].v2;
|
||||||
s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
|
s->tone_out2nd[0].v2 = s->tone_out2nd[0].v3;
|
||||||
s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
|
s->tone_out2nd[0].v3 = s->tone_out2nd[0].fac*s->tone_out2nd[0].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out2nd[1].v2;
|
v1 = s->tone_out2nd[1].v2;
|
||||||
s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
|
s->tone_out2nd[1].v2 = s->tone_out2nd[1].v3;
|
||||||
s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
|
s->tone_out2nd[1].v3 = s->tone_out2nd[1].fac*s->tone_out2nd[1].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out2nd[2].v2;
|
v1 = s->tone_out2nd[2].v2;
|
||||||
s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
|
s->tone_out2nd[2].v2 = s->tone_out2nd[2].v3;
|
||||||
s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
|
s->tone_out2nd[2].v3 = s->tone_out2nd[2].fac*s->tone_out2nd[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out2nd[3].v2;
|
v1 = s->tone_out2nd[3].v2;
|
||||||
s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
|
s->tone_out2nd[3].v2 = s->tone_out2nd[3].v3;
|
||||||
s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
|
s->tone_out2nd[3].v3 = s->tone_out2nd[3].fac*s->tone_out2nd[3].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out2nd[4].v2;
|
v1 = s->tone_out2nd[4].v2;
|
||||||
s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
|
s->tone_out2nd[4].v2 = s->tone_out2nd[4].v3;
|
||||||
s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
|
s->tone_out2nd[4].v3 = s->tone_out2nd[4].fac*s->tone_out2nd[2].v2 - v1 + famp;
|
||||||
|
|
||||||
v1 = s->tone_out2nd[3].v2;
|
v1 = s->tone_out2nd[3].v2;
|
||||||
s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
|
s->tone_out2nd[5].v2 = s->tone_out2nd[6].v3;
|
||||||
s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
|
s->tone_out2nd[5].v3 = s->tone_out2nd[6].fac*s->tone_out2nd[3].v2 - v1 + famp;
|
||||||
@@ -815,8 +739,6 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifdef OLD_DSP_ROUTINES
|
#ifdef OLD_DSP_ROUTINES
|
||||||
/* We're at the end of an MF detection block. Go ahead and calculate
|
/* We're at the end of an MF detection block. Go ahead and calculate
|
||||||
all the energies. */
|
all the energies. */
|
||||||
@@ -849,14 +771,17 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
best2 = i;
|
best2 = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
if (best1 != best2) sofarsogood=1;
|
if (best1 != best2)
|
||||||
else sofarsogood=0;
|
sofarsogood=1;
|
||||||
|
else
|
||||||
|
sofarsogood=0;
|
||||||
/* Check for relative energies */
|
/* Check for relative energies */
|
||||||
for (i=0;i<6;i++) {
|
for (i=0;i<6;i++) {
|
||||||
if (i == best1) continue;
|
if (i == best1)
|
||||||
if (i == best2) continue;
|
continue;
|
||||||
|
if (i == best2)
|
||||||
|
continue;
|
||||||
if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
|
if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) {
|
||||||
sofarsogood = 0;
|
sofarsogood = 0;
|
||||||
break;
|
break;
|
||||||
@@ -899,8 +824,7 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
s->hit2 = s->hit3;
|
s->hit2 = s->hit3;
|
||||||
s->hit3 = hit;
|
s->hit3 = hit;
|
||||||
/* Reinitialise the detector for the next block */
|
/* Reinitialise the detector for the next block */
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++) {
|
||||||
{
|
|
||||||
goertzel_reset(&s->tone_out[i]);
|
goertzel_reset(&s->tone_out[i]);
|
||||||
goertzel_reset(&s->tone_out2nd[i]);
|
goertzel_reset(&s->tone_out2nd[i]);
|
||||||
}
|
}
|
||||||
@@ -917,48 +841,33 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
are considerably stronger than any of the others. */
|
are considerably stronger than any of the others. */
|
||||||
energy[0] = goertzel_result(&s->tone_out[0]);
|
energy[0] = goertzel_result(&s->tone_out[0]);
|
||||||
energy[1] = goertzel_result(&s->tone_out[1]);
|
energy[1] = goertzel_result(&s->tone_out[1]);
|
||||||
if (energy[0] > energy[1])
|
if (energy[0] > energy[1]) {
|
||||||
{
|
|
||||||
best = 0;
|
best = 0;
|
||||||
second_best = 1;
|
second_best = 1;
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
best = 1;
|
best = 1;
|
||||||
second_best = 0;
|
second_best = 0;
|
||||||
}
|
}
|
||||||
/*endif*/
|
/*endif*/
|
||||||
for (i = 2; i < 6; i++)
|
for (i=2;i<6;i++) {
|
||||||
{
|
|
||||||
energy[i] = goertzel_result(&s->tone_out[i]);
|
energy[i] = goertzel_result(&s->tone_out[i]);
|
||||||
if (energy[i] >= energy[best])
|
if (energy[i] >= energy[best]) {
|
||||||
{
|
|
||||||
second_best = best;
|
second_best = best;
|
||||||
best = i;
|
best = i;
|
||||||
}
|
} else if (energy[i] >= energy[second_best]) {
|
||||||
else if (energy[i] >= energy[second_best])
|
|
||||||
{
|
|
||||||
second_best = i;
|
second_best = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Basic signal level and twist tests */
|
/* Basic signal level and twist tests */
|
||||||
hit = 0;
|
hit = 0;
|
||||||
if (energy[best] >= BELL_MF_THRESHOLD
|
if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
|
||||||
&&
|
&& energy[best] < energy[second_best]*BELL_MF_TWIST
|
||||||
energy[second_best] >= BELL_MF_THRESHOLD
|
&& energy[best]*BELL_MF_TWIST > energy[second_best]) {
|
||||||
&&
|
|
||||||
energy[best] < energy[second_best]*BELL_MF_TWIST
|
|
||||||
&&
|
|
||||||
energy[best]*BELL_MF_TWIST > energy[second_best])
|
|
||||||
{
|
|
||||||
/* Relative peak test */
|
/* Relative peak test */
|
||||||
hit = -1;
|
hit = -1;
|
||||||
for (i = 0; i < 6; i++)
|
for (i=0;i<6;i++) {
|
||||||
{
|
if (i != best && i != second_best) {
|
||||||
if (i != best && i != second_best)
|
if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
|
||||||
{
|
|
||||||
if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best])
|
|
||||||
{
|
|
||||||
/* The best two are not clearly the best */
|
/* The best two are not clearly the best */
|
||||||
hit = 0;
|
hit = 0;
|
||||||
break;
|
break;
|
||||||
@@ -966,11 +875,9 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (hit)
|
if (hit) {
|
||||||
{
|
|
||||||
/* Get the values into ascending order */
|
/* Get the values into ascending order */
|
||||||
if (second_best < best)
|
if (second_best < best) {
|
||||||
{
|
|
||||||
i = best;
|
i = best;
|
||||||
best = second_best;
|
best = second_best;
|
||||||
second_best = i;
|
second_best = i;
|
||||||
@@ -983,28 +890,19 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
two blocks of something different preceeding it. For anything
|
two blocks of something different preceeding it. For anything
|
||||||
else we need two successive identical clean detects, with
|
else we need two successive identical clean detects, with
|
||||||
two blocks of something different preceeding it. */
|
two blocks of something different preceeding it. */
|
||||||
if (hit == s->hits[4]
|
if (hit == s->hits[4] && hit == s->hits[3] &&
|
||||||
&&
|
((hit != '*' && hit != s->hits[2] && hit != s->hits[1])||
|
||||||
hit == s->hits[3]
|
(hit == '*' && hit == s->hits[2] && hit != s->hits[1] &&
|
||||||
&&
|
hit != s->hits[0]))) {
|
||||||
((hit != '*' && hit != s->hits[2] && hit != s->hits[1])
|
|
||||||
||
|
|
||||||
(hit == '*' && hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0])))
|
|
||||||
{
|
|
||||||
s->detected_digits++;
|
s->detected_digits++;
|
||||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
if (s->current_digits < MAX_DTMF_DIGITS) {
|
||||||
{
|
|
||||||
s->digits[s->current_digits++] = hit;
|
s->digits[s->current_digits++] = hit;
|
||||||
s->digits[s->current_digits] = '\0';
|
s->digits[s->current_digits] = '\0';
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
s->lost_digits++;
|
s->lost_digits++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else
|
|
||||||
{
|
|
||||||
hit = 0;
|
hit = 0;
|
||||||
}
|
}
|
||||||
s->hits[0] = s->hits[1];
|
s->hits[0] = s->hits[1];
|
||||||
@@ -1018,8 +916,7 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
s->current_sample = 0;
|
s->current_sample = 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if ((!s->mhit) || (s->mhit != hit))
|
if ((!s->mhit) || (s->mhit != hit)) {
|
||||||
{
|
|
||||||
s->mhit = 0;
|
s->mhit = 0;
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
@@ -1029,6 +926,7 @@ static int mf_detect (mf_detect_state_t *s,
|
|||||||
static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
|
static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (dsp->digitmode & DSP_DIGITMODE_MF)
|
if (dsp->digitmode & DSP_DIGITMODE_MF)
|
||||||
res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
|
res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
|
||||||
else
|
else
|
||||||
@@ -1041,6 +939,7 @@ int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
|
|||||||
short *s;
|
short *s;
|
||||||
int len;
|
int len;
|
||||||
int ign=0;
|
int ign=0;
|
||||||
|
|
||||||
if (inf->frametype != AST_FRAME_VOICE) {
|
if (inf->frametype != AST_FRAME_VOICE) {
|
||||||
ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
|
ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1074,17 +973,14 @@ static inline int pair_there(float p1, float p2, float i1, float i2, float e)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_dsp_getdigits (struct ast_dsp *dsp,
|
int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
|
||||||
char *buf,
|
|
||||||
int max)
|
|
||||||
{
|
{
|
||||||
if (dsp->digitmode & DSP_DIGITMODE_MF) {
|
if (dsp->digitmode & DSP_DIGITMODE_MF) {
|
||||||
if (max > dsp->td.mf.current_digits)
|
if (max > dsp->td.mf.current_digits)
|
||||||
max = dsp->td.mf.current_digits;
|
max = dsp->td.mf.current_digits;
|
||||||
if (max > 0)
|
if (max > 0) {
|
||||||
{
|
memcpy(buf, dsp->td.mf.digits, max);
|
||||||
memcpy (buf, dsp->td.mf.digits, max);
|
memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
|
||||||
memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
|
|
||||||
dsp->td.mf.current_digits -= max;
|
dsp->td.mf.current_digits -= max;
|
||||||
}
|
}
|
||||||
buf[max] = '\0';
|
buf[max] = '\0';
|
||||||
@@ -1092,8 +988,7 @@ int ast_dsp_getdigits (struct ast_dsp *dsp,
|
|||||||
} else {
|
} else {
|
||||||
if (max > dsp->td.dtmf.current_digits)
|
if (max > dsp->td.dtmf.current_digits)
|
||||||
max = dsp->td.dtmf.current_digits;
|
max = dsp->td.dtmf.current_digits;
|
||||||
if (max > 0)
|
if (max > 0) {
|
||||||
{
|
|
||||||
memcpy (buf, dsp->td.dtmf.digits, max);
|
memcpy (buf, dsp->td.dtmf.digits, max);
|
||||||
memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
|
memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
|
||||||
dsp->td.dtmf.current_digits -= max;
|
dsp->td.dtmf.current_digits -= max;
|
||||||
@@ -1166,19 +1061,22 @@ static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
|
|||||||
if (newstate == dsp->tstate) {
|
if (newstate == dsp->tstate) {
|
||||||
dsp->tcount++;
|
dsp->tcount++;
|
||||||
if (dsp->tcount == COUNT_THRESH) {
|
if (dsp->tcount == COUNT_THRESH) {
|
||||||
if ((dsp->features & DSP_PROGRESS_BUSY) && dsp->tstate == DSP_TONE_STATE_BUSY) {
|
if ((dsp->features & DSP_PROGRESS_BUSY) &&
|
||||||
|
dsp->tstate == DSP_TONE_STATE_BUSY) {
|
||||||
res = AST_CONTROL_BUSY;
|
res = AST_CONTROL_BUSY;
|
||||||
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
||||||
} else if ((dsp->features & DSP_PROGRESS_TALK) && dsp->tstate == DSP_TONE_STATE_TALKING) {
|
} else if ((dsp->features & DSP_PROGRESS_TALK) &&
|
||||||
|
dsp->tstate == DSP_TONE_STATE_TALKING) {
|
||||||
res = AST_CONTROL_ANSWER;
|
res = AST_CONTROL_ANSWER;
|
||||||
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
||||||
} else if ((dsp->features & DSP_PROGRESS_RINGING) && dsp->tstate == DSP_TONE_STATE_RINGING)
|
} else if ((dsp->features & DSP_PROGRESS_RINGING) &&
|
||||||
|
dsp->tstate == DSP_TONE_STATE_RINGING)
|
||||||
res = AST_CONTROL_RINGING;
|
res = AST_CONTROL_RINGING;
|
||||||
else if ((dsp->features & DSP_PROGRESS_CONGESTION) && dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
|
else if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
|
||||||
|
dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
|
||||||
res = AST_CONTROL_CONGESTION;
|
res = AST_CONTROL_CONGESTION;
|
||||||
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
#if 0
|
#if 0
|
||||||
@@ -1223,7 +1121,6 @@ static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totals
|
|||||||
|
|
||||||
if (!len)
|
if (!len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
accum = 0;
|
accum = 0;
|
||||||
for (x=0;x<len; x++)
|
for (x=0;x<len; x++)
|
||||||
accum += abs(s[x]);
|
accum += abs(s[x]);
|
||||||
@@ -1261,7 +1158,6 @@ static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totals
|
|||||||
else
|
else
|
||||||
dsp->busymaybe = 0;
|
dsp->busymaybe = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
dsp->totalsilence = 0;
|
dsp->totalsilence = 0;
|
||||||
}
|
}
|
||||||
@@ -1308,7 +1204,9 @@ int ast_dsp_busydetect(struct ast_dsp *dsp)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef BUSYDETECT_TONEONLY
|
#ifndef BUSYDETECT_TONEONLY
|
||||||
if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
|
if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) &&
|
||||||
|
(avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) &&
|
||||||
|
(avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
|
||||||
#else
|
#else
|
||||||
if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
|
if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
|
||||||
#endif
|
#endif
|
||||||
@@ -1483,7 +1381,8 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
|
|||||||
if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
|
if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
|
||||||
if (!dsp->thinkdigit) {
|
if (!dsp->thinkdigit) {
|
||||||
if (digit) {
|
if (digit) {
|
||||||
/* Looks like we might have something. Request a conference mute for the moment */
|
/* Looks like we might have something.
|
||||||
|
* Request a conference mute for the moment */
|
||||||
memset(&dsp->f, 0, sizeof(dsp->f));
|
memset(&dsp->f, 0, sizeof(dsp->f));
|
||||||
dsp->f.frametype = AST_FRAME_DTMF;
|
dsp->f.frametype = AST_FRAME_DTMF;
|
||||||
dsp->f.subclass = 'm';
|
dsp->f.subclass = 'm';
|
||||||
@@ -1594,6 +1493,7 @@ static void ast_dsp_prog_reset(struct ast_dsp *dsp)
|
|||||||
{
|
{
|
||||||
int max = 0;
|
int max = 0;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
dsp->gsamp_size = modes[dsp->progmode].size;
|
dsp->gsamp_size = modes[dsp->progmode].size;
|
||||||
dsp->gsamps = 0;
|
dsp->gsamps = 0;
|
||||||
for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
|
for (x=0;x<sizeof(modes[dsp->progmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) {
|
||||||
@@ -1608,6 +1508,7 @@ static void ast_dsp_prog_reset(struct ast_dsp *dsp)
|
|||||||
struct ast_dsp *ast_dsp_new(void)
|
struct ast_dsp *ast_dsp_new(void)
|
||||||
{
|
{
|
||||||
struct ast_dsp *dsp;
|
struct ast_dsp *dsp;
|
||||||
|
|
||||||
dsp = malloc(sizeof(struct ast_dsp));
|
dsp = malloc(sizeof(struct ast_dsp));
|
||||||
if (dsp) {
|
if (dsp) {
|
||||||
memset(dsp, 0, sizeof(struct ast_dsp));
|
memset(dsp, 0, sizeof(struct ast_dsp));
|
||||||
@@ -1649,6 +1550,7 @@ void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
|
|||||||
void ast_dsp_digitreset(struct ast_dsp *dsp)
|
void ast_dsp_digitreset(struct ast_dsp *dsp)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
dsp->thinkdigit = 0;
|
dsp->thinkdigit = 0;
|
||||||
if (dsp->digitmode & DSP_DIGITMODE_MF) {
|
if (dsp->digitmode & DSP_DIGITMODE_MF) {
|
||||||
memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
|
memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
|
||||||
@@ -1698,18 +1600,20 @@ void ast_dsp_digitreset(struct ast_dsp *dsp)
|
|||||||
void ast_dsp_reset(struct ast_dsp *dsp)
|
void ast_dsp_reset(struct ast_dsp *dsp)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
dsp->totalsilence = 0;
|
dsp->totalsilence = 0;
|
||||||
dsp->gsamps = 0;
|
dsp->gsamps = 0;
|
||||||
for (x=0;x<4;x++)
|
for (x=0;x<4;x++)
|
||||||
dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
|
dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
|
||||||
memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
|
memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
|
||||||
memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
|
memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
|
int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
|
||||||
{
|
{
|
||||||
int new, old;
|
int new;
|
||||||
|
int old;
|
||||||
|
|
||||||
old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
|
old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
|
||||||
new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
|
new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
|
||||||
if (old != new) {
|
if (old != new) {
|
||||||
@@ -1726,6 +1630,7 @@ int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
|
|||||||
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
|
int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
|
||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
|
for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
|
||||||
if (!strcasecmp(aliases[x].name, zone)) {
|
if (!strcasecmp(aliases[x].name, zone)) {
|
||||||
dsp->progmode = aliases[x].mode;
|
dsp->progmode = aliases[x].mode;
|
||||||
@@ -1741,9 +1646,7 @@ int ast_dsp_get_tstate(struct ast_dsp *dsp)
|
|||||||
return dsp->tstate;
|
return dsp->tstate;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int ast_dsp_get_tcount(struct ast_dsp *dsp)
|
int ast_dsp_get_tcount(struct ast_dsp *dsp)
|
||||||
{
|
{
|
||||||
return dsp->tcount;
|
return dsp->tcount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user