Index: dsp.c =================================================================== RCS file: /usr/cvsroot/asterisk/dsp.c,v retrieving revision 1.34 diff -u -r1.34 dsp.c --- dsp.c 1 Dec 2004 21:41:21 -0000 1.34 +++ dsp.c 2 Jan 2005 08:37:14 -0000 @@ -80,7 +80,7 @@ { GSAMP_SIZE_CR, { 425 } }, }; -#define DEFAULT_THRESHOLD 512 +#define DEFAULT_THRESHOLD 512 #define BUSY_PERCENT 10 /* The percentage diffrence between the two last silence periods */ #define BUSY_THRESHOLD 100 /* Max number of ms difference between max and min times in busy */ @@ -88,16 +88,16 @@ #define BUSY_MAX 1100 /* Busy can't be longer than 1100 ms in half-cadence */ /* Remember last 15 units */ -#define DSP_HISTORY 15 +#define DSP_HISTORY 15 /* Define if you want the fax detector -- NOT RECOMMENDED IN -STABLE */ #define FAX_DETECT -#define TONE_THRESH 10.0 /* How much louder the tone should be than channel energy */ -#define TONE_MIN_THRESH 1e8 /* How much tone there should be at least to attempt */ -#define COUNT_THRESH 3 /* Need at least 50ms of stuff to count it */ +#define TONE_THRESH 10.0 /* How much louder the tone should be than channel energy */ +#define TONE_MIN_THRESH 1e8 /* How much tone there should be at least to attempt */ +#define COUNT_THRESH 3 /* Need at least 50ms of stuff to count it */ -#define MAX_DTMF_DIGITS 128 +#define MAX_DTMF_DIGITS 128 /* Basic DTMF specs: * @@ -111,31 +111,31 @@ * Frequency tolerance +- 1.5% will detect, +-3.5% will reject */ -#define DTMF_THRESHOLD 8.0e7 -#define FAX_THRESHOLD 8.0e7 -#define FAX_2ND_HARMONIC 2.0 /* 4dB */ -#define DTMF_NORMAL_TWIST 6.3 /* 8dB */ +#define DTMF_THRESHOLD 8.0e7 +#define FAX_THRESHOLD 8.0e7 +#define FAX_2ND_HARMONIC 2.0 /* 4dB */ +#define DTMF_NORMAL_TWIST 6.3 /* 8dB */ #ifdef RADIO_RELAX #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5) /* 4dB normal */ #else #define DTMF_REVERSE_TWIST ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5) /* 4dB normal */ #endif -#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ -#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ +#define DTMF_RELATIVE_PEAK_ROW 6.3 /* 8dB */ +#define DTMF_RELATIVE_PEAK_COL 6.3 /* 8dB */ #define DTMF_2ND_HARMONIC_ROW ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5) /* 4dB normal */ -#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ -#define DTMF_TO_TOTAL_ENERGY 42.0 +#define DTMF_2ND_HARMONIC_COL 63.1 /* 18dB */ +#define DTMF_TO_TOTAL_ENERGY 42.0 #ifdef OLD_DSP_ROUTINES -#define MF_THRESHOLD 8.0e7 -#define MF_NORMAL_TWIST 5.3 /* 8dB */ -#define MF_REVERSE_TWIST 4.0 /* was 2.5 */ -#define MF_RELATIVE_PEAK 5.3 /* 8dB */ -#define MF_2ND_HARMONIC 1.7 /* was 2.5 */ +#define MF_THRESHOLD 8.0e7 +#define MF_NORMAL_TWIST 5.3 /* 8dB */ +#define MF_REVERSE_TWIST 4.0 /* was 2.5 */ +#define MF_RELATIVE_PEAK 5.3 /* 8dB */ +#define MF_2ND_HARMONIC 1.7 /* was 2.5 */ #else -#define BELL_MF_THRESHOLD 1.6e9 -#define BELL_MF_TWIST 4.0 /* 6dB */ -#define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */ +#define BELL_MF_THRESHOLD 1.6e9 +#define BELL_MF_TWIST 4.0 /* 6dB */ +#define BELL_MF_RELATIVE_PEAK 12.6 /* 11dB */ #endif typedef struct { @@ -149,36 +149,34 @@ typedef struct { - - goertzel_state_t row_out[4]; - goertzel_state_t col_out[4]; + goertzel_state_t row_out[4]; + goertzel_state_t col_out[4]; #ifdef FAX_DETECT goertzel_state_t fax_tone; #endif #ifdef OLD_DSP_ROUTINES - goertzel_state_t row_out2nd[4]; - goertzel_state_t col_out2nd[4]; + goertzel_state_t row_out2nd[4]; + goertzel_state_t col_out2nd[4]; #ifdef FAX_DETECT goertzel_state_t fax_tone2nd; #endif - int hit1; - int hit2; - int hit3; - int hit4; + int hit1; + int hit2; + int hit3; + int hit4; #else - int hits[3]; + int hits[3]; #endif - int mhit; - float energy; - int current_sample; - - char digits[MAX_DTMF_DIGITS + 1]; - int current_digits; - int detected_digits; - int lost_digits; - int digit_hits[16]; - + int mhit; + float energy; + int current_sample; + char digits[MAX_DTMF_DIGITS + 1]; + + int current_digits; + int detected_digits; + int lost_digits; + int digit_hits[16]; #ifdef FAX_DETECT int fax_hits; #endif @@ -186,24 +184,25 @@ typedef struct { - goertzel_state_t tone_out[6]; - int mhit; + goertzel_state_t tone_out[6]; + int mhit; #ifdef OLD_DSP_ROUTINES - int hit1; - int hit2; - int hit3; - int hit4; - goertzel_state_t tone_out2nd[6]; - float energy; + int hit1; + int hit2; + int hit3; + int hit4; + goertzel_state_t tone_out2nd[6]; + float energy; #else - int hits[5]; + int hits[5]; #endif + int current_sample; + + char digits[MAX_DTMF_DIGITS + 1]; - int current_sample; - char digits[MAX_DTMF_DIGITS + 1]; - int current_digits; - int detected_digits; - int lost_digits; + int current_digits; + int detected_digits; + int lost_digits; #ifdef FAX_DETECT int fax_hits; #endif @@ -211,11 +210,11 @@ static float dtmf_row[] = { - 697.0, 770.0, 852.0, 941.0 + 697.0, 770.0, 852.0, 941.0 }; static float dtmf_col[] = { - 1209.0, 1336.0, 1477.0, 1633.0 + 1209.0, 1336.0, 1477.0, 1633.0 }; static float mf_tones[] = @@ -246,6 +245,7 @@ { float v1; float fsamp = sample; + v1 = s->v2; s->v2 = s->v3; s->v3 = s->fac * s->v2 - v1 + fsamp; @@ -254,6 +254,7 @@ static inline void goertzel_update(goertzel_state_t *s, short *samps, int count) { int i; + for (i=0;ihit1 = - s->mhit = + s->hit1 = + s->mhit = s->hit3 = s->hit4 = - s->hit2 = 0; + s->hit2 = 0; #else s->hits[0] = s->hits[1] = s->hits[2] = 0; #endif - for (i = 0; i < 4; i++) - { - - goertzel_init (&s->row_out[i], dtmf_row[i], 102); - goertzel_init (&s->col_out[i], dtmf_col[i], 102); + for (i = 0; i < 4; i++) { + goertzel_init (&s->row_out[i], dtmf_row[i], 102); + goertzel_init (&s->col_out[i], dtmf_col[i], 102); #ifdef OLD_DSP_ROUTINES - goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102); - goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102); + goertzel_init (&s->row_out2nd[i], dtmf_row[i] * 2.0, 102); + goertzel_init (&s->col_out2nd[i], dtmf_col[i] * 2.0, 102); #endif s->energy = 0.0; - } - + } #ifdef FAX_DETECT /* Same for the fax dector */ - goertzel_init (&s->fax_tone, fax_freq, 102); + goertzel_init (&s->fax_tone, fax_freq, 102); #ifdef OLD_DSP_ROUTINES /* Same for the fax dector 2nd harmonic */ - goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102); + goertzel_init (&s->fax_tone2nd, fax_freq * 2.0, 102); #endif #endif /* FAX_DETECT */ - - s->current_sample = 0; - s->detected_digits = 0; + s->current_sample = 0; + s->detected_digits = 0; s->current_digits = 0; memset(&s->digits, 0, sizeof(s->digits)); - s->lost_digits = 0; - s->digits[0] = '\0'; + s->lost_digits = 0; + s->digits[0] = '\0'; } static void ast_mf_detect_init (mf_detect_state_t *s) { - int i; - + int i; #ifdef OLD_DSP_ROUTINES - s->hit1 = - s->hit2 = 0; + s->hit1 = + s->hit2 = 0; #else s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0; #endif - for (i = 0; i < 6; i++) - { - - goertzel_init (&s->tone_out[i], mf_tones[i], 160); + for (i = 0; i < 6; i++) { + goertzel_init (&s->tone_out[i], mf_tones[i], 160); #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; #endif - - } - + } s->current_digits = 0; memset(&s->digits, 0, sizeof(s->digits)); - s->current_sample = 0; - s->detected_digits = 0; - s->lost_digits = 0; - s->digits[0] = '\0'; - s->mhit = 0; + s->current_sample = 0; + s->detected_digits = 0; + s->lost_digits = 0; + s->digits[0] = '\0'; + s->mhit = 0; } -static int dtmf_detect (dtmf_detect_state_t *s, - int16_t amp[], - int samples, +static int dtmf_detect (dtmf_detect_state_t *s, int16_t amp[], int samples, int digitmode, int *writeback, int faxdetect) { - - float row_energy[4]; - float col_energy[4]; + float row_energy[4]; + float col_energy[4]; #ifdef FAX_DETECT - float fax_energy; + float fax_energy; #ifdef OLD_DSP_ROUTINES - float fax_energy_2nd; + float fax_energy_2nd; #endif #endif /* FAX_DETECT */ - float famp; - float v1; - int i; - int j; - int sample; - int best_row; - int best_col; - int hit; - int limit; - - hit = 0; - for (sample = 0; sample < samples; sample = limit) - { - /* 102 is optimised to meet the DTMF specs. */ - if ((samples - sample) >= (102 - s->current_sample)) - limit = sample + (102 - s->current_sample); - else - limit = samples; + float famp; + float v1; + int i; + int j; + int sample; + int best_row; + int best_col; + int hit; + int limit; + + hit = 0; + for (sample = 0; sample < samples; sample = limit) { + /* 102 is optimised to meet the DTMF specs. */ + if ((samples - sample) >= (102 - s->current_sample)) + limit = sample + (102 - s->current_sample); + else + limit = samples; #if defined(USE_3DNOW) - _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); - _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); #ifdef OLD_DSP_ROUTINES - _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); - _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); + _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); + _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); #endif /* XXX Need to fax detect for 3dnow too XXX */ #warning "Fax Support Broken" #else - /* The following unrolled loop takes only 35% (rough estimate) of the - time of a rolled loop on the machine on which it was developed */ - for (j = sample; j < limit; j++) - { - famp = amp[j]; - - s->energy += famp*famp; - - /* With GCC 2.95, the following unrolled code seems to take about 35% - (rough estimate) as long as a neat little 0-3 loop */ - v1 = s->row_out[0].v2; - 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; - - v1 = s->col_out[0].v2; - 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; - - v1 = s->row_out[1].v2; - 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; - - v1 = s->col_out[1].v2; - 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; - - v1 = s->row_out[2].v2; - 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; - - v1 = s->col_out[2].v2; - 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; - - v1 = s->row_out[3].v2; - 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; - - v1 = s->col_out[3].v2; - 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; - + /* The following unrolled loop takes only 35% (rough estimate) of the + time of a rolled loop on the machine on which it was developed */ + for (j=sample;jenergy += famp*famp; + /* With GCC 2.95, the following unrolled code seems to take about 35% + (rough estimate) as long as a neat little 0-3 loop */ + v1 = s->row_out[0].v2; + 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; + v1 = s->col_out[0].v2; + 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; + v1 = s->row_out[1].v2; + 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; + v1 = s->col_out[1].v2; + 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; + v1 = s->row_out[2].v2; + 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; + v1 = s->col_out[2].v2; + 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; + v1 = s->row_out[3].v2; + 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; + v1 = s->col_out[3].v2; + 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; #ifdef FAX_DETECT /* Update fax tone */ - v1 = s->fax_tone.v2; - s->fax_tone.v2 = s->fax_tone.v3; - s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp; + v1 = s->fax_tone.v2; + s->fax_tone.v2 = s->fax_tone.v3; + s->fax_tone.v3 = s->fax_tone.fac*s->fax_tone.v2 - v1 + famp; #endif /* FAX_DETECT */ #ifdef OLD_DSP_ROUTINES - v1 = s->col_out2nd[0].v2; - 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; - - v1 = s->row_out2nd[0].v2; - 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; - - v1 = s->col_out2nd[1].v2; - 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; - - v1 = s->row_out2nd[1].v2; - 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; - - v1 = s->col_out2nd[2].v2; - 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; - - v1 = s->row_out2nd[2].v2; - 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; - - v1 = s->col_out2nd[3].v2; - 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; - - v1 = s->row_out2nd[3].v2; - 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; - - + v1 = s->col_out2nd[0].v2; + 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; + v1 = s->row_out2nd[0].v2; + 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; + v1 = s->col_out2nd[1].v2; + 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; + v1 = s->row_out2nd[1].v2; + 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; + v1 = s->col_out2nd[2].v2; + 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; + v1 = s->row_out2nd[2].v2; + 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; + v1 = s->col_out2nd[3].v2; + 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; + v1 = s->row_out2nd[3].v2; + 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; #ifdef FAX_DETECT - /* Update fax tone */ - v1 = s->fax_tone.v2; - s->fax_tone2nd.v2 = s->fax_tone2nd.v3; - s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp; + /* Update fax tone */ + v1 = s->fax_tone.v2; + s->fax_tone2nd.v2 = s->fax_tone2nd.v3; + s->fax_tone2nd.v3 = s->fax_tone2nd.fac*s->fax_tone2nd.v2 - v1 + famp; #endif /* FAX_DETECT */ #endif - } + } #endif - s->current_sample += (limit - sample); - if (s->current_sample < 102) { + s->current_sample += (limit - sample); + if (s->current_sample < 102) { if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) { /* If we had a hit last time, go ahead and clear this out since likely it will be another hit */ @@ -519,176 +487,150 @@ amp[i] = 0; *writeback = 1; } - continue; + continue; } - #ifdef FAX_DETECT /* Detect the fax energy, too */ fax_energy = goertzel_result(&s->fax_tone); #endif - - /* We are at the end of a DTMF detection block */ - /* Find the peak row and the peak column */ - row_energy[0] = goertzel_result (&s->row_out[0]); - col_energy[0] = goertzel_result (&s->col_out[0]); - - for (best_row = best_col = 0, i = 1; i < 4; i++) - { - row_energy[i] = goertzel_result (&s->row_out[i]); - if (row_energy[i] > row_energy[best_row]) - best_row = i; - col_energy[i] = goertzel_result (&s->col_out[i]); - if (col_energy[i] > col_energy[best_col]) - best_col = i; - } - hit = 0; - /* Basic signal level test and the twist test */ - if (row_energy[best_row] >= 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]) - { - /* Relative peak test */ - for (i = 0; i < 4; i++) - { - if ((i != best_col && col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) - || - (i != best_row && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) - { - break; - } - } -#ifdef OLD_DSP_ROUTINES - /* ... and second harmonic test */ - if (i >= 4 - && - (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]) + /* We are at the end of a DTMF detection block */ + /* Find the peak row and the peak column */ + row_energy[0] = goertzel_result (&s->row_out[0]); + col_energy[0] = goertzel_result (&s->col_out[0]); + + for (best_row = best_col = 0, i = 1; i < 4; i++) { + row_energy[i] = goertzel_result (&s->row_out[i]); + if (row_energy[i] > row_energy[best_row]) + best_row = i; + col_energy[i] = goertzel_result (&s->col_out[i]); + if (col_energy[i] > col_energy[best_col]) + best_col = i; + } + hit = 0; + /* Basic signal level test and the twist test */ + if (row_energy[best_row] >= 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]) { + /* Relative peak test */ + for (i = 0; i < 4; i++) { + if ((i != best_col && + col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) || + (i != best_row + && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) { + break; + } + } +#ifdef OLD_DSP_ROUTINES + /* ... and second harmonic test */ + if (i >= 4 && + (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]) { #else - /* ... and fraction of total energy test */ - if (i >= 4 - && - (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) + /* ... and fraction of total energy test */ + if (i >= 4 && + (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->energy) { #endif - { /* Got a hit */ - hit = dtmf_positions[(best_row << 2) + best_col]; + hit = dtmf_positions[(best_row << 2) + best_col]; if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) { /* Zero out frame data if this is part DTMF */ for (i=sample;ihit3 && s->hit3 != s->hit2) - { - s->mhit = hit; - s->digit_hits[(best_row << 2) + best_col]++; - s->detected_digits++; - if (s->current_digits < MAX_DTMF_DIGITS) - { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } - else - { - s->lost_digits++; - } - } + /* Look for two successive similar results */ + /* The logic in the next test is: + We need two successive identical clean detects, with + something different preceeding it. This can work with + back to back differing digits. More importantly, it + can work with nasty phones that give a very wobbly start + to a digit */ +#ifdef OLD_DSP_ROUTINES + if (hit == s->hit3 && s->hit3 != s->hit2) { + s->mhit = hit; + s->digit_hits[(best_row << 2) + best_col]++; + s->detected_digits++; + if (s->current_digits < MAX_DTMF_DIGITS) { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } else { + s->lost_digits++; + } + } #else - if (hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0]) - { - s->mhit = hit; - s->digit_hits[(best_row << 2) + best_col]++; - s->detected_digits++; - if (s->current_digits < MAX_DTMF_DIGITS) - { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } - else - { - s->lost_digits++; - } - } + if (hit == s->hits[2] && hit != s->hits[1] && hit != s->hits[0]) { + s->mhit = hit; + s->digit_hits[(best_row << 2) + best_col]++; + s->detected_digits++; + if (s->current_digits < MAX_DTMF_DIGITS) { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } else { + s->lost_digits++; + } + } #endif - } - } + } + } #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 - printf("Fax energy/Second Harmonic: %f\n", fax_energy); + printf("Fax energy/Second Harmonic: %f\n", fax_energy); #endif - /* XXX Probably need better checking than just this the energy XXX */ - hit = 'f'; - s->fax_hits++; - } - else { + /* XXX Probably need better checking than just this the energy XXX */ + hit = 'f'; + s->fax_hits++; + } else { if (s->fax_hits > 5) { - hit = 'f'; - s->mhit = 'f'; - s->detected_digits++; - if (s->current_digits < MAX_DTMF_DIGITS) - { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } - else - { - s->lost_digits++; - } + hit = 'f'; + s->mhit = 'f'; + s->detected_digits++; + if (s->current_digits < MAX_DTMF_DIGITS) { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } else { + s->lost_digits++; + } } s->fax_hits = 0; } #endif /* FAX_DETECT */ #ifdef OLD_DSP_ROUTINES - s->hit1 = s->hit2; - s->hit2 = s->hit3; - s->hit3 = hit; + s->hit1 = s->hit2; + s->hit2 = s->hit3; + s->hit3 = hit; #else - s->hits[0] = s->hits[1]; - s->hits[1] = s->hits[2]; - s->hits[2] = hit; + s->hits[0] = s->hits[1]; + s->hits[1] = s->hits[2]; + s->hits[2] = hit; #endif - /* Reinitialise the detector for the next block */ - for (i = 0; i < 4; i++) - { - goertzel_reset(&s->row_out[i]); - goertzel_reset(&s->col_out[i]); + /* Reinitialise the detector for the next block */ + for (i = 0; i < 4; i++) { + goertzel_reset(&s->row_out[i]); + goertzel_reset(&s->col_out[i]); #ifdef OLD_DSP_ROUTINES - goertzel_reset(&s->row_out2nd[i]); - goertzel_reset(&s->col_out2nd[i]); + goertzel_reset(&s->row_out2nd[i]); + goertzel_reset(&s->col_out2nd[i]); #endif - } + } #ifdef FAX_DETECT - goertzel_reset (&s->fax_tone); + goertzel_reset (&s->fax_tone); #ifdef OLD_DSP_ROUTINES - goertzel_reset (&s->fax_tone2nd); + goertzel_reset (&s->fax_tone2nd); #endif #endif s->energy = 0.0; - s->current_sample = 0; - } - if ((!s->mhit) || (s->mhit != hit)) - { - s->mhit = 0; - return(0); - } - return (hit); + s->current_sample = 0; + } + if ((!s->mhit) || (s->mhit != hit)) { + s->mhit = 0; + return(0); + } + return (hit); } /* MF goertzel size */ @@ -698,114 +640,96 @@ #define MF_GSIZE 120 #endif -static int mf_detect (mf_detect_state_t *s, - int16_t amp[], - int samples, - int digitmode, int *writeback) +static int mf_detect (mf_detect_state_t *s, int16_t amp[], + int samples, int digitmode, int *writeback) { - #ifdef OLD_DSP_ROUTINES - float tone_energy[6]; - int best1; - int best2; + float tone_energy[6]; + int best1; + int best2; float max; int sofarsogood; #else - float energy[6]; - int best; - int second_best; -#endif - float famp; - float v1; - int i; - int j; - int sample; - int hit; - int limit; - - hit = 0; - for (sample = 0; sample < samples; sample = limit) - { - /* 80 is optimised to meet the MF specs. */ - if ((samples - sample) >= (MF_GSIZE - s->current_sample)) - limit = sample + (MF_GSIZE - s->current_sample); - else - limit = samples; + float energy[6]; + int best; + int second_best; +#endif + float famp; + float v1; + int i; + int j; + int sample; + int hit; + int limit; + + hit = 0; + for (sample = 0; sample < samples; sample = limit) { + /* 80 is optimised to meet the MF specs. */ + if ((samples - sample) >= (MF_GSIZE - s->current_sample)) + limit = sample + (MF_GSIZE - s->current_sample); + else + limit = samples; #if defined(USE_3DNOW) - _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); - _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->row_out, amp + sample, limit - sample); + _dtmf_goertzel_update (s->col_out, amp + sample, limit - sample); #ifdef OLD_DSP_ROUTINES - _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); - _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); + _dtmf_goertzel_update (s->row_out2nd, amp + sample, limit2 - sample); + _dtmf_goertzel_update (s->col_out2nd, amp + sample, limit2 - sample); #endif /* XXX Need to fax detect for 3dnow too XXX */ #warning "Fax Support Broken" #else - /* The following unrolled loop takes only 35% (rough estimate) of the - time of a rolled loop on the machine on which it was developed */ - for (j = sample; j < limit; j++) - { - famp = amp[j]; - -#ifdef OLD_DSP_ROUTINES - s->energy += famp*famp; -#endif - - /* With GCC 2.95, the following unrolled code seems to take about 35% - (rough estimate) as long as a neat little 0-3 loop */ - v1 = s->tone_out[0].v2; - 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; - - v1 = s->tone_out[1].v2; - 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; - - v1 = s->tone_out[2].v2; - 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; - - v1 = s->tone_out[3].v2; - 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; - - v1 = s->tone_out[4].v2; - 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; - - v1 = s->tone_out[5].v2; - 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; - -#ifdef OLD_DSP_ROUTINES - v1 = s->tone_out2nd[0].v2; - 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; - - v1 = s->tone_out2nd[1].v2; - 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; - - v1 = s->tone_out2nd[2].v2; - 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; - - v1 = s->tone_out2nd[3].v2; - 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; - - v1 = s->tone_out2nd[4].v2; - 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; - - v1 = s->tone_out2nd[3].v2; - 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; + /* The following unrolled loop takes only 35% (rough estimate) of the + time of a rolled loop on the machine on which it was developed */ + for (j = sample; j < limit; j++) { + famp = amp[j]; +#ifdef OLD_DSP_ROUTINES + s->energy += famp*famp; +#endif + /* With GCC 2.95, the following unrolled code seems to take about 35% + (rough estimate) as long as a neat little 0-3 loop */ + v1 = s->tone_out[0].v2; + 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; + v1 = s->tone_out[1].v2; + 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; + v1 = s->tone_out[2].v2; + 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; + v1 = s->tone_out[3].v2; + 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; + v1 = s->tone_out[4].v2; + 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; + v1 = s->tone_out[5].v2; + 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; +#ifdef OLD_DSP_ROUTINES + v1 = s->tone_out2nd[0].v2; + 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; + v1 = s->tone_out2nd[1].v2; + 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; + v1 = s->tone_out2nd[2].v2; + 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; + v1 = s->tone_out2nd[3].v2; + 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; + v1 = s->tone_out2nd[4].v2; + 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; + v1 = s->tone_out2nd[3].v2; + 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; #endif - } + } #endif - s->current_sample += (limit - sample); - if (s->current_sample < MF_GSIZE) { + s->current_sample += (limit - sample); + if (s->current_sample < MF_GSIZE) { if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) { /* If we had a hit last time, go ahead and clear this out since likely it will be another hit */ @@ -813,10 +737,8 @@ amp[i] = 0; *writeback = 1; } - continue; + continue; } - - #ifdef OLD_DSP_ROUTINES /* We're at the end of an MF detection block. Go ahead and calculate all the energies. */ @@ -849,14 +771,17 @@ best2 = i; } } - - hit = 0; - if (best1 != best2) sofarsogood=1; - else sofarsogood=0; + hit = 0; + if (best1 != best2) + sofarsogood=1; + else + sofarsogood=0; /* Check for relative energies */ for (i=0;i<6;i++) { - if (i == best1) continue; - if (i == best2) continue; + if (i == best1) + continue; + if (i == best2) + continue; if (tone_energy[best1] < tone_energy[i] * MF_RELATIVE_PEAK) { sofarsogood = 0; break; @@ -895,140 +820,113 @@ } } - s->hit1 = s->hit2; - s->hit2 = s->hit3; - s->hit3 = hit; - /* Reinitialise the detector for the next block */ - for (i = 0; i < 6; i++) - { - goertzel_reset(&s->tone_out[i]); - goertzel_reset(&s->tone_out2nd[i]); - } + s->hit1 = s->hit2; + s->hit2 = s->hit3; + s->hit3 = hit; + /* Reinitialise the detector for the next block */ + for (i = 0; i < 6; i++) { + goertzel_reset(&s->tone_out[i]); + goertzel_reset(&s->tone_out2nd[i]); + } s->energy = 0.0; - s->current_sample = 0; - } + s->current_sample = 0; + } #else /* We're at the end of an MF detection block. */ - /* Find the two highest energies. The spec says to look for - two tones and two tones only. Taking this literally -ie - only two tones pass the minimum threshold - doesn't work - well. The sinc function mess, due to rectangular windowing - ensure that! Find the two highest energies and ensure they - are considerably stronger than any of the others. */ - energy[0] = goertzel_result(&s->tone_out[0]); - energy[1] = goertzel_result(&s->tone_out[1]); - if (energy[0] > energy[1]) - { - best = 0; - second_best = 1; - } - else - { - best = 1; - second_best = 0; - } - /*endif*/ - for (i = 2; i < 6; i++) - { - energy[i] = goertzel_result(&s->tone_out[i]); - if (energy[i] >= energy[best]) - { - second_best = best; - best = i; - } - else if (energy[i] >= energy[second_best]) - { - second_best = i; - } - } - /* Basic signal level and twist tests */ - hit = 0; - if (energy[best] >= BELL_MF_THRESHOLD - && - energy[second_best] >= BELL_MF_THRESHOLD - && - energy[best] < energy[second_best]*BELL_MF_TWIST - && - energy[best]*BELL_MF_TWIST > energy[second_best]) - { - /* Relative peak test */ - hit = -1; - for (i = 0; i < 6; i++) - { - if (i != best && i != second_best) - { - if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) - { - /* The best two are not clearly the best */ - hit = 0; - break; - } - } - } - } - if (hit) - { - /* Get the values into ascending order */ - if (second_best < best) - { - i = best; - best = second_best; - second_best = i; - } - best = best*5 + second_best - 1; - hit = bell_mf_positions[best]; - /* Look for two successive similar results */ - /* The logic in the next test is: - For KP we need 4 successive identical clean detects, with - two blocks of something different preceeding it. For anything - else we need two successive identical clean detects, with - two blocks of something different preceeding it. */ - if (hit == s->hits[4] - && - hit == s->hits[3] - && - ((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++; - if (s->current_digits < MAX_DTMF_DIGITS) - { - s->digits[s->current_digits++] = hit; - s->digits[s->current_digits] = '\0'; - } - else - { - s->lost_digits++; - } - } - } - else - { - hit = 0; - } - s->hits[0] = s->hits[1]; - s->hits[1] = s->hits[2]; - s->hits[2] = s->hits[3]; - s->hits[3] = s->hits[4]; - s->hits[4] = hit; - /* Reinitialise the detector for the next block */ - for (i = 0; i < 6; i++) - goertzel_reset(&s->tone_out[i]); - s->current_sample = 0; - } + /* Find the two highest energies. The spec says to look for + two tones and two tones only. Taking this literally -ie + only two tones pass the minimum threshold - doesn't work + well. The sinc function mess, due to rectangular windowing + ensure that! Find the two highest energies and ensure they + are considerably stronger than any of the others. */ + energy[0] = goertzel_result(&s->tone_out[0]); + energy[1] = goertzel_result(&s->tone_out[1]); + if (energy[0] > energy[1]) { + best = 0; + second_best = 1; + } else { + best = 1; + second_best = 0; + } + /*endif*/ + for (i=2;i<6;i++) { + energy[i] = goertzel_result(&s->tone_out[i]); + if (energy[i] >= energy[best]) { + second_best = best; + best = i; + } else if (energy[i] >= energy[second_best]) { + second_best = i; + } + } + /* Basic signal level and twist tests */ + hit = 0; + if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD + && energy[best] < energy[second_best]*BELL_MF_TWIST + && energy[best]*BELL_MF_TWIST > energy[second_best]) { + /* Relative peak test */ + hit = -1; + for (i=0;i<6;i++) { + if (i != best && i != second_best) { + if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) { + /* The best two are not clearly the best */ + hit = 0; + break; + } + } + } + } + if (hit) { + /* Get the values into ascending order */ + if (second_best < best) { + i = best; + best = second_best; + second_best = i; + } + best = best*5 + second_best - 1; + hit = bell_mf_positions[best]; + /* Look for two successive similar results */ + /* The logic in the next test is: + For KP we need 4 successive identical clean detects, with + two blocks of something different preceeding it. For anything + else we need two successive identical clean detects, with + two blocks of something different preceeding it. */ + if (hit == s->hits[4] && hit == s->hits[3] && + ((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++; + if (s->current_digits < MAX_DTMF_DIGITS) { + s->digits[s->current_digits++] = hit; + s->digits[s->current_digits] = '\0'; + } else { + s->lost_digits++; + } + } + } else { + hit = 0; + } + s->hits[0] = s->hits[1]; + s->hits[1] = s->hits[2]; + s->hits[2] = s->hits[3]; + s->hits[3] = s->hits[4]; + s->hits[4] = hit; + /* Reinitialise the detector for the next block */ + for (i = 0; i < 6; i++) + goertzel_reset(&s->tone_out[i]); + s->current_sample = 0; + } #endif - if ((!s->mhit) || (s->mhit != hit)) - { + if ((!s->mhit) || (s->mhit != hit)) { s->mhit = 0; return(0); - } - return (hit); + } + return (hit); } static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback) { int res; + if (dsp->digitmode & DSP_DIGITMODE_MF) res = mf_detect(&dsp->td.mf, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback); else @@ -1041,6 +939,7 @@ short *s; int len; int ign=0; + if (inf->frametype != AST_FRAME_VOICE) { ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n"); return 0; @@ -1074,32 +973,28 @@ return 1; } -int ast_dsp_getdigits (struct ast_dsp *dsp, - char *buf, - int max) +int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max) { if (dsp->digitmode & DSP_DIGITMODE_MF) { - if (max > dsp->td.mf.current_digits) - max = dsp->td.mf.current_digits; - if (max > 0) - { - memcpy (buf, dsp->td.mf.digits, max); - memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max); - dsp->td.mf.current_digits -= max; - } - buf[max] = '\0'; - return max; + if (max > dsp->td.mf.current_digits) + max = dsp->td.mf.current_digits; + if (max > 0) { + memcpy(buf, dsp->td.mf.digits, max); + memmove(dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max); + dsp->td.mf.current_digits -= max; + } + buf[max] = '\0'; + return max; } else { - if (max > dsp->td.dtmf.current_digits) - max = dsp->td.dtmf.current_digits; - if (max > 0) - { - memcpy (buf, dsp->td.dtmf.digits, max); - memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max); - dsp->td.dtmf.current_digits -= max; - } - buf[max] = '\0'; - return max; + if (max > dsp->td.dtmf.current_digits) + max = dsp->td.dtmf.current_digits; + if (max > 0) { + memcpy (buf, dsp->td.dtmf.digits, max); + memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max); + dsp->td.dtmf.current_digits -= max; + } + buf[max] = '\0'; + return max; } } @@ -1166,19 +1061,22 @@ if (newstate == dsp->tstate) { dsp->tcount++; 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; 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; 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; - 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; dsp->features &= ~DSP_FEATURE_CALL_PROGRESS; } - } } else { #if 0 @@ -1223,7 +1121,6 @@ if (!len) return 0; - accum = 0; for (x=0;xbusymaybe = 0; } - } dsp->totalsilence = 0; } @@ -1308,7 +1204,9 @@ } } #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 if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) { #endif @@ -1483,7 +1381,8 @@ if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) { if (!dsp->thinkdigit) { 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)); dsp->f.frametype = AST_FRAME_DTMF; dsp->f.subclass = 'm'; @@ -1594,6 +1493,7 @@ { int max = 0; int x; + dsp->gsamp_size = modes[dsp->progmode].size; dsp->gsamps = 0; for (x=0;xprogmode].freqs) / sizeof(modes[dsp->progmode].freqs[0]);x++) { @@ -1608,6 +1508,7 @@ struct ast_dsp *ast_dsp_new(void) { struct ast_dsp *dsp; + dsp = malloc(sizeof(struct ast_dsp)); if (dsp) { memset(dsp, 0, sizeof(struct ast_dsp)); @@ -1649,22 +1550,23 @@ void ast_dsp_digitreset(struct ast_dsp *dsp) { int i; + dsp->thinkdigit = 0; if (dsp->digitmode & DSP_DIGITMODE_MF) { memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits)); dsp->td.mf.current_digits = 0; /* Reinitialise the detector for the next block */ for (i = 0; i < 6; i++) { - goertzel_reset(&dsp->td.mf.tone_out[i]); + goertzel_reset(&dsp->td.mf.tone_out[i]); #ifdef OLD_DSP_ROUTINES - goertzel_reset(&dsp->td.mf.tone_out2nd[i]); + goertzel_reset(&dsp->td.mf.tone_out2nd[i]); #endif } #ifdef OLD_DSP_ROUTINES dsp->td.mf.energy = 0.0; - dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0; + dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0; #else - dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0; + dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0; #endif dsp->td.mf.current_sample = 0; } else { @@ -1672,23 +1574,23 @@ dsp->td.dtmf.current_digits = 0; /* Reinitialise the detector for the next block */ for (i = 0; i < 4; i++) { - goertzel_reset(&dsp->td.dtmf.row_out[i]); - goertzel_reset(&dsp->td.dtmf.col_out[i]); + goertzel_reset(&dsp->td.dtmf.row_out[i]); + goertzel_reset(&dsp->td.dtmf.col_out[i]); #ifdef OLD_DSP_ROUTINES - goertzel_reset(&dsp->td.dtmf.row_out2nd[i]); - goertzel_reset(&dsp->td.dtmf.col_out2nd[i]); + goertzel_reset(&dsp->td.dtmf.row_out2nd[i]); + goertzel_reset(&dsp->td.dtmf.col_out2nd[i]); #endif } #ifdef FAX_DETECT - goertzel_reset (&dsp->td.dtmf.fax_tone); + goertzel_reset (&dsp->td.dtmf.fax_tone); #endif #ifdef OLD_DSP_ROUTINES #ifdef FAX_DETECT - goertzel_reset (&dsp->td.dtmf.fax_tone2nd); + goertzel_reset (&dsp->td.dtmf.fax_tone2nd); #endif - dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0; + dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0; #else - dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0; + dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0; #endif dsp->td.dtmf.energy = 0.0; dsp->td.dtmf.current_sample = 0; @@ -1698,18 +1600,20 @@ void ast_dsp_reset(struct ast_dsp *dsp) { int x; + dsp->totalsilence = 0; dsp->gsamps = 0; for (x=0;x<4;x++) dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0; 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 new, old; + int new; + int old; + 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); if (old != new) { @@ -1726,6 +1630,7 @@ int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone) { int x; + for (x=0;xprogmode = aliases[x].mode; @@ -1741,9 +1646,7 @@ return dsp->tstate; } - int ast_dsp_get_tcount(struct ast_dsp *dsp) { return dsp->tcount; } -