Wed Oct 28 11:45:37 2009

Asterisk developer's documentation


dsp.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2005, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * Goertzel routines are borrowed from Steve Underwood's tremendous work on the
00009  * DTMF detector.
00010  *
00011  * See http://www.asterisk.org for more information about
00012  * the Asterisk project. Please do not directly contact
00013  * any of the maintainers of this project for assistance;
00014  * the project provides a web site, mailing lists and IRC
00015  * channels for your use.
00016  *
00017  * This program is free software, distributed under the terms of
00018  * the GNU General Public License Version 2. See the LICENSE file
00019  * at the top of the source tree.
00020  */
00021 
00022 /*! \file
00023  *
00024  * \brief Convenience Signal Processing routines
00025  *
00026  * \author Mark Spencer <markster@digium.com>
00027  * \author Steve Underwood <steveu@coppice.org>
00028  */
00029 
00030 /* Some routines from tone_detect.c by Steven Underwood as published under the zapata library */
00031 /*
00032    tone_detect.c - General telephony tone detection, and specific
00033                detection of DTMF.
00034 
00035    Copyright (C) 2001  Steve Underwood <steveu@coppice.org>
00036 
00037    Despite my general liking of the GPL, I place this code in the
00038    public domain for the benefit of all mankind - even the slimy
00039    ones who might try to proprietize my work and use it to my
00040    detriment.
00041 */
00042 
00043 #include "asterisk.h"
00044 
00045 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 224933 $")
00046 
00047 #include <math.h>
00048 
00049 #include "asterisk/frame.h"
00050 #include "asterisk/channel.h"
00051 #include "asterisk/dsp.h"
00052 #include "asterisk/ulaw.h"
00053 #include "asterisk/alaw.h"
00054 #include "asterisk/utils.h"
00055 #include "asterisk/options.h"
00056 
00057 /*! Number of goertzels for progress detect */
00058 enum gsamp_size {
00059    GSAMP_SIZE_NA = 183,       /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
00060    GSAMP_SIZE_CR = 188,       /*!< Costa Rica, Brazil - Only care about 425 Hz */
00061    GSAMP_SIZE_UK = 160        /*!< UK disconnect goertzel feed - should trigger 400hz */
00062 };
00063 
00064 enum prog_mode {
00065    PROG_MODE_NA = 0,
00066    PROG_MODE_CR,
00067    PROG_MODE_UK
00068 };
00069 
00070 enum freq_index { 
00071    /*! For US modes { */
00072    HZ_350 = 0,
00073    HZ_440,
00074    HZ_480,
00075    HZ_620,
00076    HZ_950,
00077    HZ_1400,
00078    HZ_1800, /*!< } */
00079 
00080    /*! For CR/BR modes */
00081    HZ_425 = 0,
00082 
00083    /*! For UK mode */
00084    HZ_400 = 0
00085 };
00086 
00087 static struct progalias {
00088    char *name;
00089    enum prog_mode mode;
00090 } aliases[] = {
00091    { "us", PROG_MODE_NA },
00092    { "ca", PROG_MODE_NA },
00093    { "cr", PROG_MODE_CR },
00094    { "br", PROG_MODE_CR },
00095    { "uk", PROG_MODE_UK },
00096 };
00097 
00098 static struct progress {
00099    enum gsamp_size size;
00100    int freqs[7];
00101 } modes[] = {
00102    { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
00103    { GSAMP_SIZE_CR, { 425 } },                                 /*!< Costa Rica, Brazil */
00104    { GSAMP_SIZE_UK, { 400 } },                                 /*!< UK */
00105 };
00106 
00107 #define DEFAULT_THRESHOLD  512
00108 
00109 enum busy_detect {
00110    BUSY_PERCENT = 10,      /*!< The percentage difference between the two last silence periods */
00111    BUSY_PAT_PERCENT = 7,   /*!< The percentage difference between measured and actual pattern */
00112    BUSY_THRESHOLD = 100,   /*!< Max number of ms difference between max and min times in busy */
00113    BUSY_MIN = 75,          /*!< Busy must be at least 80 ms in half-cadence */
00114    BUSY_MAX =3100          /*!< Busy can't be longer than 3100 ms in half-cadence */
00115 };
00116 
00117 /*! Remember last 15 units */
00118 #define DSP_HISTORY     15
00119 
00120 #define TONE_THRESH     10.0  /*!< How much louder the tone should be than channel energy */
00121 #define TONE_MIN_THRESH    1e8   /*!< How much tone there should be at least to attempt */
00122 
00123 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
00124 enum gsamp_thresh {
00125    THRESH_RING = 8,           /*!< Need at least 150ms ring to accept */
00126    THRESH_TALK = 2,           /*!< Talk detection does not work continuously */
00127    THRESH_BUSY = 4,           /*!< Need at least 80ms to accept */
00128    THRESH_CONGESTION = 4,     /*!< Need at least 80ms to accept */
00129    THRESH_HANGUP = 60,        /*!< Need at least 1300ms to accept hangup */
00130    THRESH_RING2ANSWER = 300   /*!< Timeout from start of ring to answer (about 6600 ms) */
00131 };
00132 
00133 #define  MAX_DTMF_DIGITS      128
00134 
00135 /* Basic DTMF specs:
00136  *
00137  * Minimum tone on = 40ms
00138  * Minimum tone off = 50ms
00139  * Maximum digit rate = 10 per second
00140  * Normal twist <= 8dB accepted
00141  * Reverse twist <= 4dB accepted
00142  * S/N >= 15dB will detect OK
00143  * Attenuation <= 26dB will detect OK
00144  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
00145  */
00146 
00147 #define DTMF_THRESHOLD     8.0e7
00148 #define FAX_THRESHOLD      8.0e7
00149 #define FAX_2ND_HARMONIC   2.0     /* 4dB */
00150 #define DTMF_NORMAL_TWIST  6.3     /* 8dB */
00151 #ifdef   RADIO_RELAX
00152 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 6.5 : 2.5)     /* 4dB normal */
00153 #else
00154 #define DTMF_REVERSE_TWIST          ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 4.0 : 2.5)     /* 4dB normal */
00155 #endif
00156 #define DTMF_RELATIVE_PEAK_ROW   6.3     /* 8dB */
00157 #define DTMF_RELATIVE_PEAK_COL   6.3     /* 8dB */
00158 #define DTMF_2ND_HARMONIC_ROW       ((digitmode & DSP_DIGITMODE_RELAXDTMF) ? 1.7 : 2.5)     /* 4dB normal */
00159 #define DTMF_2ND_HARMONIC_COL 63.1    /* 18dB */
00160 #define DTMF_TO_TOTAL_ENERGY  42.0
00161 
00162 #define BELL_MF_THRESHOLD  1.6e9
00163 #define BELL_MF_TWIST      4.0     /* 6dB */
00164 #define BELL_MF_RELATIVE_PEAK 12.6    /* 11dB */
00165 
00166 #if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
00167 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
00168 #endif
00169 
00170 /* The CNG signal consists of the transmission of 1100 Hz for 1/2 second,
00171  * followed by a 3 second silent (2100 Hz OFF) period.
00172  */
00173 #define FAX_TONE_CNG_FREQ  1100
00174 #define FAX_TONE_CNG_DURATION 500
00175 #define FAX_TONE_CNG_DB    16
00176 
00177 /* This signal may be sent by the Terminating FAX machine anywhere between
00178  * 1.8 to 2.5 seconds AFTER answering the call.  The CED signal consists
00179  * of a 2100 Hz tone that is from 2.6 to 4 seconds in duration.
00180 */
00181 #define FAX_TONE_CED_FREQ  2100
00182 #define FAX_TONE_CED_DURATION 2600
00183 #define FAX_TONE_CED_DB    16
00184 
00185 #define SAMPLE_RATE     8000
00186 
00187 /* How many samples a frame has.  This constant is used when calculating
00188  * Goertzel block size for tone_detect.  It is only important if we want to
00189  * remove (squelch) the tone. In this case it is important to have block
00190  * size not to exceed size of voice frame.  Otherwise by the moment the tone
00191  * is detected it is too late to squelch it from previous frames.
00192  */
00193 #define SAMPLES_IN_FRAME   160
00194 
00195 
00196 typedef struct {
00197    int v2;
00198    int v3;
00199    int chunky;
00200    int fac;
00201    int samples;
00202 } goertzel_state_t;
00203 
00204 typedef struct {
00205    int value;
00206    int power;
00207 } goertzel_result_t;
00208 
00209 typedef struct
00210 {
00211    int freq;
00212    int block_size;
00213    int squelch;      /* Remove (squelch) tone */
00214    goertzel_state_t tone;
00215    float energy;     /* Accumulated energy of the current block */
00216    int samples_pending; /* Samples remain to complete the current block */
00217 
00218    int hits_required;   /* How many successive blocks with tone we are looking for */
00219    float threshold;  /* Energy of the tone relative to energy from all other signals to consider a hit */
00220 
00221    int hit_count;    /* How many successive blocks we consider tone present */
00222    int last_hit;     /* Indicates if the last processed block was a hit */
00223 
00224 } tone_detect_state_t;
00225 
00226 typedef struct
00227 {
00228    goertzel_state_t row_out[4];
00229    goertzel_state_t col_out[4];
00230    int lasthit;
00231    int current_hit;
00232    float energy;
00233    int current_sample;
00234 } dtmf_detect_state_t;
00235 
00236 typedef struct
00237 {
00238    goertzel_state_t tone_out[6];
00239    int current_hit;
00240    int hits[5];
00241    int current_sample;
00242 } mf_detect_state_t;
00243 
00244 typedef struct
00245 {
00246    char digits[MAX_DTMF_DIGITS + 1];
00247    int current_digits;
00248    int detected_digits;
00249    int lost_digits;
00250 
00251    union {
00252       dtmf_detect_state_t dtmf;
00253       mf_detect_state_t mf;
00254    } td;
00255 } digit_detect_state_t;
00256 
00257 static float dtmf_row[] =
00258 {
00259    697.0,  770.0,  852.0,  941.0
00260 };
00261 static float dtmf_col[] =
00262 {
00263    1209.0, 1336.0, 1477.0, 1633.0
00264 };
00265 
00266 static float mf_tones[] =
00267 {
00268    700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00269 };
00270 
00271 static char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
00272 
00273 static char bell_mf_positions[] = "1247C-358A--69*---0B----#";
00274 
00275 static inline void goertzel_sample(goertzel_state_t *s, short sample)
00276 {
00277    int v1;
00278    
00279    v1 = s->v2;
00280    s->v2 = s->v3;
00281    
00282    s->v3 = (s->fac * s->v2) >> 15;
00283    s->v3 = s->v3 - v1 + (sample >> s->chunky);
00284    if (abs(s->v3) > 32768) {
00285       s->chunky++;
00286       s->v3 = s->v3 >> 1;
00287       s->v2 = s->v2 >> 1;
00288       v1 = v1 >> 1;
00289    }
00290 }
00291 
00292 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
00293 {
00294    int i;
00295    
00296    for (i=0;i<count;i++) 
00297       goertzel_sample(s, samps[i]);
00298 }
00299 
00300 
00301 static inline float goertzel_result(goertzel_state_t *s)
00302 {
00303    goertzel_result_t r;
00304    r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
00305    r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
00306    r.power = s->chunky * 2;
00307    return (float)r.value * (float)(1 << r.power);
00308 }
00309 
00310 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
00311 {
00312    s->v2 = s->v3 = s->chunky = 0.0;
00313    s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
00314    s->samples = samples;
00315 }
00316 
00317 static inline void goertzel_reset(goertzel_state_t *s)
00318 {
00319    s->v2 = s->v3 = s->chunky = 0.0;
00320 }
00321 
00322 struct ast_dsp {
00323    struct ast_frame f;
00324    int threshold;
00325    int totalsilence;
00326    int totalnoise;
00327    int features;
00328    int ringtimeout;
00329    int busymaybe;
00330    int busycount;
00331    int busy_tonelength;
00332    int busy_quietlength;
00333    int historicnoise[DSP_HISTORY];
00334    int historicsilence[DSP_HISTORY];
00335    goertzel_state_t freqs[7];
00336    int freqcount;
00337    int gsamps;
00338    enum gsamp_size gsamp_size;
00339    enum prog_mode progmode;
00340    int tstate;
00341    int tcount;
00342    int digitmode;
00343    int faxmode;
00344    int thinkdigit;
00345    float genergy;
00346    digit_detect_state_t digit_state;
00347    tone_detect_state_t cng_tone_state;
00348    tone_detect_state_t ced_tone_state;
00349 };
00350 
00351 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00352 {
00353    int duration_samples;
00354    float x;
00355    int periods_in_block;
00356 
00357    s->freq = freq;
00358 
00359    /* Desired tone duration in samples */
00360    duration_samples = duration * SAMPLE_RATE / 1000;
00361    /* We want to allow 10% deviation of tone duration */
00362    duration_samples = duration_samples * 9 / 10;
00363 
00364    /* If we want to remove tone, it is important to have block size not
00365       to exceed frame size. Otherwise by the moment tone is detected it is too late
00366       to squelch it from previous frames */
00367    s->block_size = SAMPLES_IN_FRAME;
00368 
00369    periods_in_block = s->block_size * freq / SAMPLE_RATE;
00370 
00371    /* Make sure we will have at least 5 periods at target frequency for analisys.
00372       This may make block larger than expected packet and will make squelching impossible
00373       but at least we will be detecting the tone */
00374    if (periods_in_block < 5)
00375       periods_in_block = 5;
00376 
00377    /* Now calculate final block size. It will contain integer number of periods */
00378    s->block_size = periods_in_block * SAMPLE_RATE / freq;
00379 
00380    /* tone_detect is currently only used to detect fax tones and we
00381       do not need suqlching the fax tones */
00382    s->squelch = 0;
00383 
00384    /* Account for the first and the last block to be incomplete
00385       and thus no tone will be detected in them */
00386    s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00387 
00388    goertzel_init(&s->tone, freq, s->block_size);
00389 
00390    s->samples_pending = s->block_size;
00391    s->hit_count = 0;
00392    s->last_hit = 0;
00393    s->energy = 0.0;
00394 
00395    /* We want tone energy to be amp decibels above the rest of the signal (the noise).
00396       According to Parseval's theorem the energy computed in time domain equals to energy
00397       computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
00398       from the energy in the time domain we will get energy of the remaining signal (without the tone
00399       we are detecting). We will be checking that
00400       10*log(Ew / (Et - Ew)) > amp
00401       Calculate threshold so that we will be actually checking
00402       Ew > Et * threshold
00403    */
00404 
00405    x = pow(10.0, amp / 10.0);
00406    s->threshold = x / (x + 1);
00407 
00408    ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00409 }
00410 
00411 static void ast_fax_detect_init(struct ast_dsp *s)
00412 {
00413    ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00414    ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00415 }
00416 
00417 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00418 {
00419    int i;
00420 
00421    s->lasthit = 0;
00422    s->current_hit = 0;
00423    for (i = 0;  i < 4;  i++) {
00424       goertzel_init (&s->row_out[i], dtmf_row[i], 102);
00425       goertzel_init (&s->col_out[i], dtmf_col[i], 102);
00426       s->energy = 0.0;
00427    }
00428    s->current_sample = 0;
00429 }
00430 
00431 static void ast_mf_detect_init (mf_detect_state_t *s)
00432 {
00433    int i;
00434    s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00435    for (i = 0;  i < 6;  i++) {
00436       goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00437    }
00438    s->current_sample = 0;
00439    s->current_hit = 0;
00440 }
00441 
00442 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00443 {
00444    s->current_digits = 0;
00445    s->detected_digits = 0;
00446    s->lost_digits = 0;
00447    s->digits[0] = '\0';
00448 
00449    if (mf)
00450       ast_mf_detect_init(&s->td.mf);
00451    else
00452       ast_dtmf_detect_init(&s->td.dtmf);
00453 }
00454 
00455 static int tone_detect(tone_detect_state_t *s, int16_t *amp, int samples, 
00456        int *writeback)
00457 {
00458    float tone_energy;
00459    int i;
00460    int hit = 0;
00461    int limit;
00462    int res = 0;
00463    int16_t *ptr;
00464 
00465    while (1) {
00466       /* Process in blocks. */
00467       limit = (samples < s->samples_pending) ? samples : s->samples_pending;
00468 
00469       for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00470          /* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
00471          s->energy += (int32_t) *ptr * (int32_t) *ptr;
00472 
00473          goertzel_sample(&s->tone, *ptr);
00474       }
00475 
00476       s->samples_pending -= limit;
00477 
00478       if (s->samples_pending) {
00479          /* Finished incomplete (last) block */
00480          if (s->last_hit && s->squelch) {
00481             /* If we had a hit last time, go ahead and clear this out since likely it
00482                will be another hit */
00483             memset(amp, 0, sizeof(*amp) * limit);
00484             if (writeback)
00485                *writeback = 1;
00486          }
00487          break;
00488       }
00489 
00490 
00491       tone_energy = goertzel_result(&s->tone);
00492 
00493       /* Scale to make comparable */
00494       tone_energy *= 2.0;
00495       s->energy *= s->block_size;
00496 
00497       ast_debug(10, "tone %d, Ew=%f, Et=%f, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
00498       hit = 0;
00499       if (tone_energy > s->energy * s->threshold) {
00500 
00501          ast_debug(10, "Hit! count=%d\n", s->hit_count);
00502          hit = 1;
00503 
00504          if (s->squelch) {
00505             /* Zero out frame data */
00506             memset(amp, 0, sizeof(*amp) * limit);
00507             if (writeback)
00508                *writeback = 1;
00509          }
00510       }
00511 
00512       if (s->hit_count)
00513          s->hit_count++;
00514 
00515       if (hit == s->last_hit) {
00516          if (!hit) {
00517             /* Two successive misses. Tone ended */
00518             s->hit_count = 0;
00519          } else if (!s->hit_count) {
00520             s->hit_count++;
00521          }
00522 
00523       }
00524 
00525       if (s->hit_count == s->hits_required) {
00526          ast_debug(1, "%d Hz done detected\n", s->freq);
00527          res = 1;
00528       }
00529 
00530       s->last_hit = hit;
00531 
00532       /* Reset for the next block */
00533       goertzel_reset(&s->tone);
00534 
00535       /* Advance to the next block */
00536       s->energy = 0.0;
00537       s->samples_pending = s->block_size;
00538 
00539       amp += limit;
00540       samples -= limit;
00541    }
00542 
00543    return res;
00544 }
00545 
00546 static void store_digit(digit_detect_state_t *s, char digit)
00547 {
00548    s->detected_digits++;
00549    if (s->current_digits < MAX_DTMF_DIGITS) {
00550       s->digits[s->current_digits++] = digit;
00551       s->digits[s->current_digits] = '\0';
00552    } else {
00553       ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00554       s->lost_digits++;
00555    }
00556 }
00557 
00558 static int dtmf_detect(digit_detect_state_t *s, int16_t amp[], int samples, 
00559        int digitmode, int *writeback)
00560 {
00561    float row_energy[4];
00562    float col_energy[4];
00563    float famp;
00564    int i;
00565    int j;
00566    int sample;
00567    int best_row;
00568    int best_col;
00569    int hit;
00570    int limit;
00571 
00572    hit = 0;
00573    for (sample = 0;  sample < samples;  sample = limit) {
00574       /* 102 is optimised to meet the DTMF specs. */
00575       if ((samples - sample) >= (102 - s->td.dtmf.current_sample))
00576          limit = sample + (102 - s->td.dtmf.current_sample);
00577       else
00578          limit = samples;
00579       /* The following unrolled loop takes only 35% (rough estimate) of the 
00580          time of a rolled loop on the machine on which it was developed */
00581       for (j = sample; j < limit; j++) {
00582          famp = amp[j];
00583          s->td.dtmf.energy += famp*famp;
00584          /* With GCC 2.95, the following unrolled code seems to take about 35%
00585             (rough estimate) as long as a neat little 0-3 loop */
00586          goertzel_sample(s->td.dtmf.row_out, amp[j]);
00587          goertzel_sample(s->td.dtmf.col_out, amp[j]);
00588          goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
00589          goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
00590          goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
00591          goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
00592          goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
00593          goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
00594       }
00595       s->td.dtmf.current_sample += (limit - sample);
00596       if (s->td.dtmf.current_sample < 102) {
00597          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00598             /* If we had a hit last time, go ahead and clear this out since likely it
00599                will be another hit */
00600             for (i=sample;i<limit;i++) 
00601                amp[i] = 0;
00602             *writeback = 1;
00603          }
00604          continue;
00605       }
00606       /* We are at the end of a DTMF detection block */
00607       /* Find the peak row and the peak column */
00608       row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00609       col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00610 
00611       for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
00612          row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00613          if (row_energy[i] > row_energy[best_row])
00614             best_row = i;
00615          col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00616          if (col_energy[i] > col_energy[best_col])
00617             best_col = i;
00618       }
00619       hit = 0;
00620       /* Basic signal level test and the twist test */
00621       if (row_energy[best_row] >= DTMF_THRESHOLD && 
00622           col_energy[best_col] >= DTMF_THRESHOLD &&
00623           col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
00624           col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
00625          /* Relative peak test */
00626          for (i = 0;  i < 4;  i++) {
00627             if ((i != best_col &&
00628                 col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00629                 (i != best_row 
00630                  && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00631                break;
00632             }
00633          }
00634          /* ... and fraction of total energy test */
00635          if (i >= 4 &&
00636              (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy) {
00637             /* Got a hit */
00638             hit = dtmf_positions[(best_row << 2) + best_col];
00639             if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00640                /* Zero out frame data if this is part DTMF */
00641                for (i=sample;i<limit;i++) 
00642                   amp[i] = 0;
00643                *writeback = 1;
00644             }
00645          }
00646       } 
00647 
00648       /* The logic in the next test is:
00649          For digits we need two successive identical clean detects, with
00650          something different preceeding it. This can work with
00651          back to back differing digits. More importantly, it
00652          can work with nasty phones that give a very wobbly start
00653          to a digit */
00654       if (hit != s->td.dtmf.current_hit) {
00655          if (hit && s->td.dtmf.lasthit == hit) {
00656             s->td.dtmf.current_hit = hit;
00657             store_digit(s, hit);
00658          } else if (s->td.dtmf.lasthit != s->td.dtmf.current_hit) {
00659             s->td.dtmf.current_hit = 0;
00660          }
00661       }
00662       s->td.dtmf.lasthit = hit;
00663 
00664       /* Reinitialise the detector for the next block */
00665       for (i = 0;  i < 4;  i++) {
00666          goertzel_reset(&s->td.dtmf.row_out[i]);
00667          goertzel_reset(&s->td.dtmf.col_out[i]);
00668       }
00669       s->td.dtmf.energy = 0.0;
00670       s->td.dtmf.current_sample = 0;
00671    }
00672    return (s->td.dtmf.current_hit); /* return the debounced hit */
00673 }
00674 
00675 /* MF goertzel size */
00676 #define MF_GSIZE 120
00677 
00678 static int mf_detect(digit_detect_state_t *s, int16_t amp[],
00679    int samples, int digitmode, int *writeback)
00680 {
00681    float energy[6];
00682    int best;
00683    int second_best;
00684    float famp;
00685    int i;
00686    int j;
00687    int sample;
00688    int hit;
00689    int limit;
00690 
00691    hit = 0;
00692    for (sample = 0;  sample < samples;  sample = limit) {
00693       /* 80 is optimised to meet the MF specs. */
00694       if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
00695          limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00696       else
00697          limit = samples;
00698       /* The following unrolled loop takes only 35% (rough estimate) of the 
00699          time of a rolled loop on the machine on which it was developed */
00700       for (j = sample;  j < limit;  j++) {
00701          famp = amp[j];
00702          /* With GCC 2.95, the following unrolled code seems to take about 35%
00703             (rough estimate) as long as a neat little 0-3 loop */
00704          goertzel_sample(s->td.mf.tone_out, amp[j]);
00705          goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
00706          goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
00707          goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
00708          goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
00709          goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
00710       }
00711       s->td.mf.current_sample += (limit - sample);
00712       if (s->td.mf.current_sample < MF_GSIZE) {
00713          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00714             /* If we had a hit last time, go ahead and clear this out since likely it
00715                will be another hit */
00716             for (i=sample;i<limit;i++) 
00717                amp[i] = 0;
00718             *writeback = 1;
00719          }
00720          continue;
00721       }
00722       /* We're at the end of an MF detection block.  */
00723       /* Find the two highest energies. The spec says to look for
00724          two tones and two tones only. Taking this literally -ie
00725          only two tones pass the minimum threshold - doesn't work
00726          well. The sinc function mess, due to rectangular windowing
00727          ensure that! Find the two highest energies and ensure they
00728          are considerably stronger than any of the others. */
00729       energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00730       energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00731       if (energy[0] > energy[1]) {
00732          best = 0;
00733          second_best = 1;
00734       } else {
00735          best = 1;
00736          second_best = 0;
00737       }
00738       /*endif*/
00739       for (i=2;i<6;i++) {
00740          energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00741          if (energy[i] >= energy[best]) {
00742             second_best = best;
00743             best = i;
00744          } else if (energy[i] >= energy[second_best]) {
00745             second_best = i;
00746          }
00747       }
00748       /* Basic signal level and twist tests */
00749       hit = 0;
00750       if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00751                && energy[best] < energy[second_best]*BELL_MF_TWIST
00752                && energy[best]*BELL_MF_TWIST > energy[second_best]) {
00753          /* Relative peak test */
00754          hit = -1;
00755          for (i=0;i<6;i++) {
00756             if (i != best && i != second_best) {
00757                if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00758                   /* The best two are not clearly the best */
00759                   hit = 0;
00760                   break;
00761                }
00762             }
00763          }
00764       }
00765       if (hit) {
00766          /* Get the values into ascending order */
00767          if (second_best < best) {
00768             i = best;
00769             best = second_best;
00770             second_best = i;
00771          }
00772          best = best*5 + second_best - 1;
00773          hit = bell_mf_positions[best];
00774          /* Look for two successive similar results */
00775          /* The logic in the next test is:
00776             For KP we need 4 successive identical clean detects, with
00777             two blocks of something different preceeding it. For anything
00778             else we need two successive identical clean detects, with
00779             two blocks of something different preceeding it. */
00780          if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00781             ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00782              (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] && 
00783              hit != s->td.mf.hits[0]))) {
00784             store_digit(s, hit);
00785          }
00786       }
00787 
00788 
00789       if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00790          /* Two successive block without a hit terminate current digit */
00791          s->td.mf.current_hit = 0;
00792       }
00793 
00794       s->td.mf.hits[0] = s->td.mf.hits[1];
00795       s->td.mf.hits[1] = s->td.mf.hits[2];
00796       s->td.mf.hits[2] = s->td.mf.hits[3];
00797       s->td.mf.hits[3] = s->td.mf.hits[4];
00798       s->td.mf.hits[4] = hit;
00799       /* Reinitialise the detector for the next block */
00800       for (i = 0;  i < 6;  i++)
00801          goertzel_reset(&s->td.mf.tone_out[i]);
00802       s->td.mf.current_sample = 0;
00803    }
00804 
00805    return (s->td.mf.current_hit); /* return the debounced hit */
00806 }
00807 
00808 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
00809 {
00810    int res = 0;
00811    
00812    if ((dsp->features & DSP_FEATURE_DTMF_DETECT) && (dsp->digitmode & DSP_DIGITMODE_MF))
00813       res = mf_detect(&dsp->digit_state, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00814    else if (dsp->features & DSP_FEATURE_DTMF_DETECT)
00815       res = dtmf_detect(&dsp->digit_state, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00816 
00817    if ((dsp->features & DSP_FEATURE_FAX_DETECT) && (dsp->faxmode & DSP_FAXMODE_DETECT_CNG)) {
00818       if (tone_detect(&dsp->cng_tone_state, s, len, NULL)) {
00819          store_digit(&dsp->digit_state, 'f');
00820          res = 'f';
00821       }
00822    }
00823 
00824    if ((dsp->features & DSP_FEATURE_FAX_DETECT) && (dsp->faxmode & DSP_FAXMODE_DETECT_CED)) {
00825       if (tone_detect(&dsp->ced_tone_state, s, len, NULL)) {
00826          store_digit(&dsp->digit_state, 'e');
00827          res = 'e';
00828       }
00829    }
00830 
00831    return res;
00832 }
00833 
00834 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
00835 {
00836    short *s;
00837    int len;
00838    int ign=0;
00839 
00840    if (inf->frametype != AST_FRAME_VOICE) {
00841       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00842       return 0;
00843    }
00844    if (inf->subclass != AST_FORMAT_SLINEAR) {
00845       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00846       return 0;
00847    }
00848    s = inf->data;
00849    len = inf->datalen / 2;
00850    return __ast_dsp_digitdetect(dsp, s, len, &ign);
00851 }
00852 
00853 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00854 {
00855    /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
00856    /* Make sure absolute levels are high enough */
00857    if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
00858       return 0;
00859    /* Amplify ignored stuff */
00860    i2 *= TONE_THRESH;
00861    i1 *= TONE_THRESH;
00862    e *= TONE_THRESH;
00863    /* Check first tone */
00864    if ((p1 < i1) || (p1 < i2) || (p1 < e))
00865       return 0;
00866    /* And second */
00867    if ((p2 < i1) || (p2 < i2) || (p2 < e))
00868       return 0;
00869    /* Guess it's there... */
00870    return 1;
00871 }
00872 
00873 int ast_dsp_getdigits(struct ast_dsp *dsp, char *buf, int max)
00874 {
00875    if (max > dsp->digit_state.current_digits)
00876       max = dsp->digit_state.current_digits;
00877    if (max > 0) {
00878       memcpy(buf, dsp->digit_state.digits, max);
00879       memmove(dsp->digit_state.digits, dsp->digit_state.digits + max, dsp->digit_state.current_digits - max);
00880       dsp->digit_state.current_digits -= max;
00881    }
00882    buf[max] = '\0';
00883    return  max;
00884 }
00885 
00886 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00887 {
00888    int x;
00889    int y;
00890    int pass;
00891    int newstate = DSP_TONE_STATE_SILENCE;
00892    int res = 0;
00893    while (len) {
00894       /* Take the lesser of the number of samples we need and what we have */
00895       pass = len;
00896       if (pass > dsp->gsamp_size - dsp->gsamps) 
00897          pass = dsp->gsamp_size - dsp->gsamps;
00898       for (x=0;x<pass;x++) {
00899          for (y=0;y<dsp->freqcount;y++) 
00900             goertzel_sample(&dsp->freqs[y], s[x]);
00901          dsp->genergy += s[x] * s[x];
00902       }
00903       s += pass;
00904       dsp->gsamps += pass;
00905       len -= pass;
00906       if (dsp->gsamps == dsp->gsamp_size) {
00907          float hz[7];
00908          for (y=0;y<7;y++)
00909             hz[y] = goertzel_result(&dsp->freqs[y]);
00910          switch (dsp->progmode) {
00911          case PROG_MODE_NA:
00912             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
00913                newstate = DSP_TONE_STATE_BUSY;
00914             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
00915                newstate = DSP_TONE_STATE_RINGING;
00916             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
00917                newstate = DSP_TONE_STATE_DIALTONE;
00918             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
00919                newstate = DSP_TONE_STATE_SPECIAL1;
00920             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
00921                if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
00922                   newstate = DSP_TONE_STATE_SPECIAL2;
00923             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
00924                if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
00925                   newstate = DSP_TONE_STATE_SPECIAL3;
00926             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00927                newstate = DSP_TONE_STATE_TALKING;
00928             } else
00929                newstate = DSP_TONE_STATE_SILENCE;
00930             break;
00931          case PROG_MODE_CR:
00932             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
00933                newstate = DSP_TONE_STATE_RINGING;
00934             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00935                newstate = DSP_TONE_STATE_TALKING;
00936             } else
00937                newstate = DSP_TONE_STATE_SILENCE;
00938             break;
00939          case PROG_MODE_UK:
00940             if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
00941                newstate = DSP_TONE_STATE_HUNGUP;
00942             }
00943             break;
00944          default:
00945             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
00946          }
00947          if (newstate == dsp->tstate) {
00948             dsp->tcount++;
00949             if (dsp->ringtimeout)
00950                dsp->ringtimeout++;
00951             switch (dsp->tstate) {
00952                case DSP_TONE_STATE_RINGING:
00953                   if ((dsp->features & DSP_PROGRESS_RINGING) &&
00954                       (dsp->tcount==THRESH_RING)) {
00955                      res = AST_CONTROL_RINGING;
00956                      dsp->ringtimeout= 1;
00957                   }
00958                   break;
00959                case DSP_TONE_STATE_BUSY:
00960                   if ((dsp->features & DSP_PROGRESS_BUSY) &&
00961                       (dsp->tcount==THRESH_BUSY)) {
00962                      res = AST_CONTROL_BUSY;
00963                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00964                   }
00965                   break;
00966                case DSP_TONE_STATE_TALKING:
00967                   if ((dsp->features & DSP_PROGRESS_TALK) &&
00968                       (dsp->tcount==THRESH_TALK)) {
00969                      res = AST_CONTROL_ANSWER;
00970                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00971                   }
00972                   break;
00973                case DSP_TONE_STATE_SPECIAL3:
00974                   if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
00975                       (dsp->tcount==THRESH_CONGESTION)) {
00976                      res = AST_CONTROL_CONGESTION;
00977                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00978                   }
00979                   break;
00980                case DSP_TONE_STATE_HUNGUP:
00981                   if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
00982                       (dsp->tcount==THRESH_HANGUP)) {
00983                      res = AST_CONTROL_HANGUP;
00984                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00985                   }
00986                   break;
00987             }
00988             if (dsp->ringtimeout==THRESH_RING2ANSWER) {
00989                ast_debug(1, "Consider call as answered because of timeout after last ring\n");
00990                res = AST_CONTROL_ANSWER;
00991                dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00992             }
00993          } else {
00994             ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
00995             ast_debug(5, "Start state %d\n", newstate);
00996             dsp->tstate = newstate;
00997             dsp->tcount = 1;
00998          }
00999          
01000          /* Reset goertzel */                
01001          for (x=0;x<7;x++)
01002             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01003          dsp->gsamps = 0;
01004          dsp->genergy = 0.0;
01005       }
01006    }
01007 
01008    return res;
01009 }
01010 
01011 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01012 {
01013    if (inf->frametype != AST_FRAME_VOICE) {
01014       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01015       return 0;
01016    }
01017    if (inf->subclass != AST_FORMAT_SLINEAR) {
01018       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01019       return 0;
01020    }
01021    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01022 }
01023 
01024 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01025 {
01026    int accum;
01027    int x;
01028    int res = 0;
01029 
01030    if (!len)
01031       return 0;
01032    accum = 0;
01033    for (x=0;x<len; x++) 
01034       accum += abs(s[x]);
01035    accum /= len;
01036    if (accum < dsp->threshold) {
01037       /* Silent */
01038       dsp->totalsilence += len/8;
01039       if (dsp->totalnoise) {
01040          /* Move and save history */
01041          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount +1, dsp->busycount*sizeof(dsp->historicnoise[0]));
01042          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01043 /* we don't want to check for busydetect that frequently */
01044 #if 0
01045          dsp->busymaybe = 1;
01046 #endif
01047       }
01048       dsp->totalnoise = 0;
01049       res = 1;
01050    } else {
01051       /* Not silent */
01052       dsp->totalnoise += len/8;
01053       if (dsp->totalsilence) {
01054          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01055          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01056          /* Move and save history */
01057          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount*sizeof(dsp->historicsilence[0]));
01058          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01059          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
01060          if (silence1 < silence2) {
01061             if (silence1 + silence1*BUSY_PERCENT/100 >= silence2)
01062                dsp->busymaybe = 1;
01063             else 
01064                dsp->busymaybe = 0;
01065          } else {
01066             if (silence1 - silence1*BUSY_PERCENT/100 <= silence2)
01067                dsp->busymaybe = 1;
01068             else 
01069                dsp->busymaybe = 0;
01070          }
01071       }
01072       dsp->totalsilence = 0;
01073    }
01074    if (totalsilence)
01075       *totalsilence = dsp->totalsilence;
01076    return res;
01077 }
01078 
01079 int ast_dsp_busydetect(struct ast_dsp *dsp)
01080 {
01081    int res = 0, x;
01082 #ifndef BUSYDETECT_TONEONLY
01083    int avgsilence = 0, hitsilence = 0;
01084 #endif
01085    int avgtone = 0, hittone = 0;
01086    if (!dsp->busymaybe)
01087       return res;
01088    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01089 #ifndef BUSYDETECT_TONEONLY
01090       avgsilence += dsp->historicsilence[x];
01091 #endif
01092       avgtone += dsp->historicnoise[x];
01093    }
01094 #ifndef BUSYDETECT_TONEONLY
01095    avgsilence /= dsp->busycount;
01096 #endif
01097    avgtone /= dsp->busycount;
01098    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01099 #ifndef BUSYDETECT_TONEONLY
01100       if (avgsilence > dsp->historicsilence[x]) {
01101          if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01102             hitsilence++;
01103       } else {
01104          if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01105             hitsilence++;
01106       }
01107 #endif
01108       if (avgtone > dsp->historicnoise[x]) {
01109          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01110             hittone++;
01111       } else {
01112          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01113             hittone++;
01114       }
01115    }
01116 #ifndef BUSYDETECT_TONEONLY
01117    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
01118        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
01119        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01120 #else
01121    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01122 #endif
01123 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01124       if (avgtone > avgsilence) {
01125          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01126             res = 1;
01127       } else {
01128          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01129             res = 1;
01130       }
01131 #else
01132       res = 1;
01133 #endif
01134    }
01135    /* If we know the expected busy tone length, check we are in the range */
01136    if (res && (dsp->busy_tonelength > 0)) {
01137       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*BUSY_PAT_PERCENT/100)) {
01138 #ifdef BUSYDETECT_DEBUG
01139          ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01140             avgtone, dsp->busy_tonelength);
01141 #endif
01142          res = 0;
01143       }
01144    }
01145 #ifndef BUSYDETECT_TONEONLY
01146    /* If we know the expected busy tone silent-period length, check we are in the range */
01147    if (res && (dsp->busy_quietlength > 0)) {
01148       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*BUSY_PAT_PERCENT/100)) {
01149 #ifdef BUSYDETECT_DEBUG
01150       ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01151          avgsilence, dsp->busy_quietlength);
01152 #endif
01153          res = 0;
01154       }
01155    }
01156 #endif
01157 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01158    if (res) {
01159       ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01160    } else {
01161       ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01162    }
01163 #endif
01164    return res;
01165 }
01166 
01167 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01168 {
01169    short *s;
01170    int len;
01171    
01172    if (f->frametype != AST_FRAME_VOICE) {
01173       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01174       return 0;
01175    }
01176    if (f->subclass != AST_FORMAT_SLINEAR) {
01177       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01178       return 0;
01179    }
01180    s = f->data;
01181    len = f->datalen/2;
01182    return __ast_dsp_silence(dsp, s, len, totalsilence);
01183 }
01184 
01185 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01186 {
01187    int silence;
01188    int res;
01189    int digit;
01190    int x;
01191    short *shortdata;
01192    unsigned char *odata;
01193    int len;
01194    int writeback = 0;
01195 
01196 #define FIX_INF(inf) do { \
01197       if (writeback) { \
01198          switch (inf->subclass) { \
01199          case AST_FORMAT_SLINEAR: \
01200             break; \
01201          case AST_FORMAT_ULAW: \
01202             for (x=0;x<len;x++) \
01203                odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01204             break; \
01205          case AST_FORMAT_ALAW: \
01206             for (x=0;x<len;x++) \
01207                odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01208             break; \
01209          } \
01210       } \
01211    } while(0) 
01212 
01213    if (!af)
01214       return NULL;
01215    if (af->frametype != AST_FRAME_VOICE)
01216       return af;
01217    odata = af->data;
01218    len = af->datalen;
01219    /* Make sure we have short data */
01220    switch (af->subclass) {
01221    case AST_FORMAT_SLINEAR:
01222       shortdata = af->data;
01223       len = af->datalen / 2;
01224       break;
01225    case AST_FORMAT_ULAW:
01226       shortdata = alloca(af->datalen * 2);
01227       for (x = 0;x < len; x++) 
01228          shortdata[x] = AST_MULAW(odata[x]);
01229       break;
01230    case AST_FORMAT_ALAW:
01231       shortdata = alloca(af->datalen * 2);
01232       for (x = 0; x < len; x++) 
01233          shortdata[x] = AST_ALAW(odata[x]);
01234       break;
01235    default:
01236       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01237       return af;
01238    }
01239    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01240    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01241       memset(&dsp->f, 0, sizeof(dsp->f));
01242       dsp->f.frametype = AST_FRAME_NULL;
01243       ast_frfree(af);
01244       return ast_frisolate(&dsp->f);
01245    }
01246    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01247       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01248       memset(&dsp->f, 0, sizeof(dsp->f));
01249       dsp->f.frametype = AST_FRAME_CONTROL;
01250       dsp->f.subclass = AST_CONTROL_BUSY;
01251       ast_frfree(af);
01252       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01253       return ast_frisolate(&dsp->f);
01254    }
01255    if (((dsp->features & DSP_FEATURE_DTMF_DETECT) || (dsp->features & DSP_FEATURE_FAX_DETECT))) {
01256       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01257 #if 0
01258       if (digit)
01259          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01260 #endif
01261       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01262          if (!dsp->thinkdigit) {
01263             if (digit) {
01264                /* Looks like we might have something.  
01265                 * Request a conference mute for the moment */
01266                memset(&dsp->f, 0, sizeof(dsp->f));
01267                dsp->f.frametype = AST_FRAME_DTMF;
01268                dsp->f.subclass = 'm';
01269                dsp->thinkdigit = 'x';
01270                FIX_INF(af);
01271                if (chan)
01272                   ast_queue_frame(chan, af);
01273                ast_frfree(af);
01274                return ast_frisolate(&dsp->f);
01275             }
01276          } else {
01277             if (digit) {
01278                /* Thought we saw one last time.  Pretty sure we really have now */
01279                if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01280                   /* If we found a digit, and we're changing digits, go
01281                      ahead and send this one, but DON'T stop confmute because
01282                      we're detecting something else, too... */
01283                   memset(&dsp->f, 0, sizeof(dsp->f));
01284                   dsp->f.frametype = AST_FRAME_DTMF_END;
01285                   dsp->f.subclass = dsp->thinkdigit;
01286                   FIX_INF(af);
01287                   if (chan)
01288                      ast_queue_frame(chan, af);
01289                   ast_frfree(af);
01290                } else {
01291                   dsp->thinkdigit = digit;
01292                   memset(&dsp->f, 0, sizeof(dsp->f));
01293                   dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01294                   dsp->f.subclass = dsp->thinkdigit;
01295                   FIX_INF(af);
01296                   if (chan)
01297                      ast_queue_frame(chan, af);
01298                   ast_frfree(af);
01299                }
01300                return ast_frisolate(&dsp->f);
01301             } else {
01302                memset(&dsp->f, 0, sizeof(dsp->f));
01303                if (dsp->thinkdigit != 'x') {
01304                   /* If we found a digit, send it now */
01305                   dsp->f.frametype = AST_FRAME_DTMF_END;
01306                   dsp->f.subclass = dsp->thinkdigit;
01307                   dsp->thinkdigit = 0;
01308                } else {
01309                   dsp->f.frametype = AST_FRAME_DTMF;
01310                   dsp->f.subclass = 'u';
01311                   dsp->thinkdigit = 0;
01312                }
01313                FIX_INF(af);
01314                if (chan)
01315                   ast_queue_frame(chan, af);
01316                ast_frfree(af);
01317                return ast_frisolate(&dsp->f);
01318             }
01319          }
01320       } else if (dsp->digit_state.current_digits > 1 ||
01321          (dsp->digit_state.current_digits == 1 && digit != dsp->digit_state.digits[0])) {
01322          /* Since we basically generate DTMF_END frames we do it only when a digit
01323             has finished. */
01324 
01325          memset(&dsp->f, 0, sizeof(dsp->f));
01326          dsp->f.frametype = AST_FRAME_DTMF;
01327          dsp->f.subclass = dsp->digit_state.digits[0];
01328          memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
01329          dsp->digit_state.current_digits--;
01330          FIX_INF(af);
01331          if (chan)
01332             ast_queue_frame(chan, af);
01333          ast_frfree(af);
01334          return ast_frisolate(&dsp->f);
01335       }
01336    }
01337    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01338       res = __ast_dsp_call_progress(dsp, shortdata, len);
01339       if (res) {
01340          switch (res) {
01341          case AST_CONTROL_ANSWER:
01342          case AST_CONTROL_BUSY:
01343          case AST_CONTROL_RINGING:
01344          case AST_CONTROL_CONGESTION:
01345          case AST_CONTROL_HANGUP:
01346             memset(&dsp->f, 0, sizeof(dsp->f));
01347             dsp->f.frametype = AST_FRAME_CONTROL;
01348             dsp->f.subclass = res;
01349             dsp->f.src = "dsp_progress";
01350             if (chan) 
01351                ast_queue_frame(chan, &dsp->f);
01352             break;
01353          default:
01354             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01355          }
01356       }
01357    }
01358    FIX_INF(af);
01359    return af;
01360 }
01361 
01362 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01363 {
01364    int max = 0;
01365    int x;
01366    
01367    dsp->gsamp_size = modes[dsp->progmode].size;
01368    dsp->gsamps = 0;
01369    for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01370       if (modes[dsp->progmode].freqs[x]) {
01371          goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01372          max = x + 1;
01373       }
01374    }
01375    dsp->freqcount = max;
01376    dsp->ringtimeout= 0;
01377 }
01378 
01379 struct ast_dsp *ast_dsp_new(void)
01380 {
01381    struct ast_dsp *dsp;
01382    
01383    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01384       dsp->threshold = DEFAULT_THRESHOLD;
01385       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01386       dsp->busycount = DSP_HISTORY;
01387       dsp->digitmode = DSP_DIGITMODE_DTMF;
01388       dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01389       /* Initialize digit detector */
01390       ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01391       /* Initialize initial DSP progress detect parameters */
01392       ast_dsp_prog_reset(dsp);
01393       /* Initialize fax detector */
01394       ast_fax_detect_init(dsp);
01395    }
01396    return dsp;
01397 }
01398 
01399 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01400 {
01401    dsp->features = features;
01402 }
01403 
01404 void ast_dsp_free(struct ast_dsp *dsp)
01405 {
01406    ast_free(dsp);
01407 }
01408 
01409 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01410 {
01411    dsp->threshold = threshold;
01412 }
01413 
01414 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01415 {
01416    if (cadences < 4)
01417       cadences = 4;
01418    if (cadences > DSP_HISTORY)
01419       cadences = DSP_HISTORY;
01420    dsp->busycount = cadences;
01421 }
01422 
01423 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01424 {
01425    dsp->busy_tonelength = tonelength;
01426    dsp->busy_quietlength = quietlength;
01427    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01428 }
01429 
01430 void ast_dsp_digitreset(struct ast_dsp *dsp)
01431 {
01432    int i;
01433    
01434    dsp->thinkdigit = 0;
01435    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01436       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01437       /* Reinitialise the detector for the next block */
01438       for (i = 0;  i < 6;  i++) {
01439          goertzel_reset(&s->tone_out[i]);
01440       }
01441       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01442       s->current_sample = 0;
01443    } else {
01444       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01445       /* Reinitialise the detector for the next block */
01446       for (i = 0;  i < 4;  i++) {
01447          goertzel_reset(&s->row_out[i]);
01448          goertzel_reset(&s->col_out[i]);
01449       }
01450       s->lasthit = s->current_hit = 0;
01451       s->energy = 0.0;
01452       s->current_sample = 0;
01453    }
01454 
01455    dsp->digit_state.digits[0] = '\0';
01456    dsp->digit_state.current_digits = 0;
01457 }
01458 
01459 void ast_dsp_reset(struct ast_dsp *dsp)
01460 {
01461    int x;
01462    
01463    dsp->totalsilence = 0;
01464    dsp->gsamps = 0;
01465    for (x=0;x<4;x++)
01466       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01467    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01468    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01469    dsp->ringtimeout= 0;
01470 }
01471 
01472 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01473 {
01474    int new;
01475    int old;
01476    
01477    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01478    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01479    if (old != new) {
01480       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01481       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01482    }
01483    dsp->digitmode = digitmode;
01484    return 0;
01485 }
01486 
01487 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01488 {
01489    if (dsp->faxmode != faxmode) {
01490       ast_fax_detect_init(dsp);
01491    }
01492    dsp->faxmode = faxmode;
01493    return 0;
01494 }
01495 
01496 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01497 {
01498    int x;
01499    
01500    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01501       if (!strcasecmp(aliases[x].name, zone)) {
01502          dsp->progmode = aliases[x].mode;
01503          ast_dsp_prog_reset(dsp);
01504          return 0;
01505       }
01506    }
01507    return -1;
01508 }
01509 
01510 int ast_dsp_get_tstate(struct ast_dsp *dsp) 
01511 {
01512    return dsp->tstate;
01513 }
01514 
01515 int ast_dsp_get_tcount(struct ast_dsp *dsp) 
01516 {
01517    return dsp->tcount;
01518 }
01519 

Generated on Wed Oct 28 11:45:37 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.6