Thu Jul 9 13:40:33 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: 130130 $")
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 tone periods */
00111    BUSY_PAT_PERCENT = 8,   /*!< 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 = 150,       /*!< Busy must be at least 150 ms in half-cadence */
00114    BUSY_MAX = 600          /*!< Busy can't be longer than 600 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 busytoneonly;
00332    int busycompare;
00333    int busy_tonelength;
00334    int busy_quietlength;
00335    int busy_pattern_fuzzy;
00336    int historicnoise[DSP_HISTORY];
00337    int historicsilence[DSP_HISTORY];
00338    goertzel_state_t freqs[7];
00339    int freqcount;
00340    int gsamps;
00341    enum gsamp_size gsamp_size;
00342    enum prog_mode progmode;
00343    int tstate;
00344    int tcount;
00345    int digitmode;
00346    int faxmode;
00347    int thinkdigit;
00348    float genergy;
00349    digit_detect_state_t digit_state;
00350    tone_detect_state_t cng_tone_state;
00351    tone_detect_state_t ced_tone_state;
00352 };
00353 
00354 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00355 {
00356    int duration_samples;
00357    float x;
00358    int periods_in_block;
00359 
00360    s->freq = freq;
00361 
00362    /* Desired tone duration in samples */
00363    duration_samples = duration * SAMPLE_RATE / 1000;
00364    /* We want to allow 10% deviation of tone duration */
00365    duration_samples = duration_samples * 9 / 10;
00366 
00367    /* If we want to remove tone, it is important to have block size not
00368       to exceed frame size. Otherwise by the moment tone is detected it is too late
00369       to squelch it from previous frames */
00370    s->block_size = SAMPLES_IN_FRAME;
00371 
00372    periods_in_block = s->block_size * freq / SAMPLE_RATE;
00373 
00374    /* Make sure we will have at least 5 periods at target frequency for analisys.
00375       This may make block larger than expected packet and will make squelching impossible
00376       but at least we will be detecting the tone */
00377    if (periods_in_block < 5)
00378       periods_in_block = 5;
00379 
00380    /* Now calculate final block size. It will contain integer number of periods */
00381    s->block_size = periods_in_block * SAMPLE_RATE / freq;
00382 
00383    /* tone_detect is currently only used to detect fax tones and we
00384       do not need suqlching the fax tones */
00385    s->squelch = 0;
00386 
00387    /* Account for the first and the last block to be incomplete
00388       and thus no tone will be detected in them */
00389    s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00390 
00391    goertzel_init(&s->tone, freq, s->block_size);
00392 
00393    s->samples_pending = s->block_size;
00394    s->hit_count = 0;
00395    s->last_hit = 0;
00396    s->energy = 0.0;
00397 
00398    /* We want tone energy to be amp decibels above the rest of the signal (the noise).
00399       According to Parseval's theorem the energy computed in time domain equals to energy
00400       computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
00401       from the energy in the time domain we will get energy of the remaining signal (without the tone
00402       we are detecting). We will be checking that
00403       10*log(Ew / (Et - Ew)) > amp
00404       Calculate threshold so that we will be actually checking
00405       Ew > Et * threshold
00406    */
00407 
00408    x = pow(10.0, amp / 10.0);
00409    s->threshold = x / (x + 1);
00410 
00411    ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00412 }
00413 
00414 static void ast_fax_detect_init(struct ast_dsp *s)
00415 {
00416    ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00417    ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00418 }
00419 
00420 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00421 {
00422    int i;
00423 
00424    s->lasthit = 0;
00425    s->current_hit = 0;
00426    for (i = 0;  i < 4;  i++) {
00427       goertzel_init (&s->row_out[i], dtmf_row[i], 102);
00428       goertzel_init (&s->col_out[i], dtmf_col[i], 102);
00429       s->energy = 0.0;
00430    }
00431    s->current_sample = 0;
00432 }
00433 
00434 static void ast_mf_detect_init (mf_detect_state_t *s)
00435 {
00436    int i;
00437    s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00438    for (i = 0;  i < 6;  i++) {
00439       goertzel_init (&s->tone_out[i], mf_tones[i], 160);
00440    }
00441    s->current_sample = 0;
00442    s->current_hit = 0;
00443 }
00444 
00445 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00446 {
00447    s->current_digits = 0;
00448    s->detected_digits = 0;
00449    s->lost_digits = 0;
00450    s->digits[0] = '\0';
00451 
00452    if (mf)
00453       ast_mf_detect_init(&s->td.mf);
00454    else
00455       ast_dtmf_detect_init(&s->td.dtmf);
00456 }
00457 
00458 static int tone_detect(tone_detect_state_t *s, int16_t *amp, int samples, 
00459        int *writeback)
00460 {
00461    float tone_energy;
00462    int i;
00463    int hit = 0;
00464    int limit;
00465    int res = 0;
00466    int16_t *ptr;
00467 
00468    while (1) {
00469       /* Process in blocks. */
00470       limit = (samples < s->samples_pending) ? samples : s->samples_pending;
00471 
00472       for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00473          /* signed 32 bit int should be enough to suqare any possible signed 16 bit value */
00474          s->energy += (int32_t) *ptr * (int32_t) *ptr;
00475 
00476          goertzel_sample(&s->tone, *ptr);
00477       }
00478 
00479       s->samples_pending -= limit;
00480 
00481       if (s->samples_pending) {
00482          /* Finished incomplete (last) block */
00483          if (s->last_hit && s->squelch) {
00484             /* If we had a hit last time, go ahead and clear this out since likely it
00485                will be another hit */
00486             memset(amp, 0, sizeof(*amp) * limit);
00487             if (writeback)
00488                *writeback = 1;
00489          }
00490          break;
00491       }
00492 
00493 
00494       tone_energy = goertzel_result(&s->tone);
00495 
00496       /* Scale to make comparable */
00497       tone_energy *= 2.0;
00498       s->energy *= s->block_size;
00499 
00500       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));
00501       hit = 0;
00502       if (tone_energy > s->energy * s->threshold) {
00503 
00504          ast_debug(10, "Hit! count=%d\n", s->hit_count);
00505          hit = 1;
00506 
00507          if (s->squelch) {
00508             /* Zero out frame data */
00509             memset(amp, 0, sizeof(*amp) * limit);
00510             if (writeback)
00511                *writeback = 1;
00512          }
00513       }
00514 
00515       if (s->hit_count)
00516          s->hit_count++;
00517 
00518       if (hit == s->last_hit) {
00519          if (!hit) {
00520             /* Two successive misses. Tone ended */
00521             s->hit_count = 0;
00522          } else if (!s->hit_count) {
00523             s->hit_count++;
00524          }
00525 
00526       }
00527 
00528       if (s->hit_count == s->hits_required) {
00529          ast_debug(1, "%d Hz done detected\n", s->freq);
00530          res = 1;
00531       }
00532 
00533       s->last_hit = hit;
00534 
00535       /* Reset for the next block */
00536       goertzel_reset(&s->tone);
00537 
00538       /* Advance to the next block */
00539       s->energy = 0.0;
00540       s->samples_pending = s->block_size;
00541 
00542       amp += limit;
00543       samples -= limit;
00544    }
00545 
00546    return res;
00547 }
00548 
00549 static void store_digit(digit_detect_state_t *s, char digit)
00550 {
00551    s->detected_digits++;
00552    if (s->current_digits < MAX_DTMF_DIGITS) {
00553       s->digits[s->current_digits++] = digit;
00554       s->digits[s->current_digits] = '\0';
00555    } else {
00556       ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00557       s->lost_digits++;
00558    }
00559 }
00560 
00561 static int dtmf_detect(digit_detect_state_t *s, int16_t amp[], int samples, 
00562        int digitmode, int *writeback)
00563 {
00564    float row_energy[4];
00565    float col_energy[4];
00566    float famp;
00567    int i;
00568    int j;
00569    int sample;
00570    int best_row;
00571    int best_col;
00572    int hit;
00573    int limit;
00574 
00575    hit = 0;
00576    for (sample = 0;  sample < samples;  sample = limit) {
00577       /* 102 is optimised to meet the DTMF specs. */
00578       if ((samples - sample) >= (102 - s->td.dtmf.current_sample))
00579          limit = sample + (102 - s->td.dtmf.current_sample);
00580       else
00581          limit = samples;
00582       /* The following unrolled loop takes only 35% (rough estimate) of the 
00583          time of a rolled loop on the machine on which it was developed */
00584       for (j = sample; j < limit; j++) {
00585          famp = amp[j];
00586          s->td.dtmf.energy += famp*famp;
00587          /* With GCC 2.95, the following unrolled code seems to take about 35%
00588             (rough estimate) as long as a neat little 0-3 loop */
00589          goertzel_sample(s->td.dtmf.row_out, amp[j]);
00590          goertzel_sample(s->td.dtmf.col_out, amp[j]);
00591          goertzel_sample(s->td.dtmf.row_out + 1, amp[j]);
00592          goertzel_sample(s->td.dtmf.col_out + 1, amp[j]);
00593          goertzel_sample(s->td.dtmf.row_out + 2, amp[j]);
00594          goertzel_sample(s->td.dtmf.col_out + 2, amp[j]);
00595          goertzel_sample(s->td.dtmf.row_out + 3, amp[j]);
00596          goertzel_sample(s->td.dtmf.col_out + 3, amp[j]);
00597       }
00598       s->td.dtmf.current_sample += (limit - sample);
00599       if (s->td.dtmf.current_sample < 102) {
00600          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00601             /* If we had a hit last time, go ahead and clear this out since likely it
00602                will be another hit */
00603             for (i=sample;i<limit;i++) 
00604                amp[i] = 0;
00605             *writeback = 1;
00606          }
00607          continue;
00608       }
00609       /* We are at the end of a DTMF detection block */
00610       /* Find the peak row and the peak column */
00611       row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00612       col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00613 
00614       for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
00615          row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00616          if (row_energy[i] > row_energy[best_row])
00617             best_row = i;
00618          col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00619          if (col_energy[i] > col_energy[best_col])
00620             best_col = i;
00621       }
00622       hit = 0;
00623       /* Basic signal level test and the twist test */
00624       if (row_energy[best_row] >= DTMF_THRESHOLD && 
00625           col_energy[best_col] >= DTMF_THRESHOLD &&
00626           col_energy[best_col] < row_energy[best_row]*DTMF_REVERSE_TWIST &&
00627           col_energy[best_col]*DTMF_NORMAL_TWIST > row_energy[best_row]) {
00628          /* Relative peak test */
00629          for (i = 0;  i < 4;  i++) {
00630             if ((i != best_col &&
00631                 col_energy[i]*DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00632                 (i != best_row 
00633                  && row_energy[i]*DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00634                break;
00635             }
00636          }
00637          /* ... and fraction of total energy test */
00638          if (i >= 4 &&
00639              (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY*s->td.dtmf.energy) {
00640             /* Got a hit */
00641             hit = dtmf_positions[(best_row << 2) + best_col];
00642             if (!(digitmode & DSP_DIGITMODE_NOQUELCH)) {
00643                /* Zero out frame data if this is part DTMF */
00644                for (i=sample;i<limit;i++) 
00645                   amp[i] = 0;
00646                *writeback = 1;
00647             }
00648          }
00649       } 
00650 
00651       /* The logic in the next test is:
00652          For digits we need two successive identical clean detects, with
00653          something different preceeding it. This can work with
00654          back to back differing digits. More importantly, it
00655          can work with nasty phones that give a very wobbly start
00656          to a digit */
00657       if (hit != s->td.dtmf.current_hit) {
00658          if (hit && s->td.dtmf.lasthit == hit) {
00659             s->td.dtmf.current_hit = hit;
00660             store_digit(s, hit);
00661          } else if (s->td.dtmf.lasthit != s->td.dtmf.current_hit) {
00662             s->td.dtmf.current_hit = 0;
00663          }
00664       }
00665       s->td.dtmf.lasthit = hit;
00666 
00667       /* Reinitialise the detector for the next block */
00668       for (i = 0;  i < 4;  i++) {
00669          goertzel_reset(&s->td.dtmf.row_out[i]);
00670          goertzel_reset(&s->td.dtmf.col_out[i]);
00671       }
00672       s->td.dtmf.energy = 0.0;
00673       s->td.dtmf.current_sample = 0;
00674    }
00675    return (s->td.dtmf.current_hit); /* return the debounced hit */
00676 }
00677 
00678 /* MF goertzel size */
00679 #define MF_GSIZE 120
00680 
00681 static int mf_detect(digit_detect_state_t *s, int16_t amp[],
00682    int samples, int digitmode, int *writeback)
00683 {
00684    float energy[6];
00685    int best;
00686    int second_best;
00687    float famp;
00688    int i;
00689    int j;
00690    int sample;
00691    int hit;
00692    int limit;
00693 
00694    hit = 0;
00695    for (sample = 0;  sample < samples;  sample = limit) {
00696       /* 80 is optimised to meet the MF specs. */
00697       if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample))
00698          limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00699       else
00700          limit = samples;
00701       /* The following unrolled loop takes only 35% (rough estimate) of the 
00702          time of a rolled loop on the machine on which it was developed */
00703       for (j = sample;  j < limit;  j++) {
00704          famp = amp[j];
00705          /* With GCC 2.95, the following unrolled code seems to take about 35%
00706             (rough estimate) as long as a neat little 0-3 loop */
00707          goertzel_sample(s->td.mf.tone_out, amp[j]);
00708          goertzel_sample(s->td.mf.tone_out + 1, amp[j]);
00709          goertzel_sample(s->td.mf.tone_out + 2, amp[j]);
00710          goertzel_sample(s->td.mf.tone_out + 3, amp[j]);
00711          goertzel_sample(s->td.mf.tone_out + 4, amp[j]);
00712          goertzel_sample(s->td.mf.tone_out + 5, amp[j]);
00713       }
00714       s->td.mf.current_sample += (limit - sample);
00715       if (s->td.mf.current_sample < MF_GSIZE) {
00716          if (hit && !((digitmode & DSP_DIGITMODE_NOQUELCH))) {
00717             /* If we had a hit last time, go ahead and clear this out since likely it
00718                will be another hit */
00719             for (i=sample;i<limit;i++) 
00720                amp[i] = 0;
00721             *writeback = 1;
00722          }
00723          continue;
00724       }
00725       /* We're at the end of an MF detection block.  */
00726       /* Find the two highest energies. The spec says to look for
00727          two tones and two tones only. Taking this literally -ie
00728          only two tones pass the minimum threshold - doesn't work
00729          well. The sinc function mess, due to rectangular windowing
00730          ensure that! Find the two highest energies and ensure they
00731          are considerably stronger than any of the others. */
00732       energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00733       energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00734       if (energy[0] > energy[1]) {
00735          best = 0;
00736          second_best = 1;
00737       } else {
00738          best = 1;
00739          second_best = 0;
00740       }
00741       /*endif*/
00742       for (i=2;i<6;i++) {
00743          energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00744          if (energy[i] >= energy[best]) {
00745             second_best = best;
00746             best = i;
00747          } else if (energy[i] >= energy[second_best]) {
00748             second_best = i;
00749          }
00750       }
00751       /* Basic signal level and twist tests */
00752       hit = 0;
00753       if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00754                && energy[best] < energy[second_best]*BELL_MF_TWIST
00755                && energy[best]*BELL_MF_TWIST > energy[second_best]) {
00756          /* Relative peak test */
00757          hit = -1;
00758          for (i=0;i<6;i++) {
00759             if (i != best && i != second_best) {
00760                if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00761                   /* The best two are not clearly the best */
00762                   hit = 0;
00763                   break;
00764                }
00765             }
00766          }
00767       }
00768       if (hit) {
00769          /* Get the values into ascending order */
00770          if (second_best < best) {
00771             i = best;
00772             best = second_best;
00773             second_best = i;
00774          }
00775          best = best*5 + second_best - 1;
00776          hit = bell_mf_positions[best];
00777          /* Look for two successive similar results */
00778          /* The logic in the next test is:
00779             For KP we need 4 successive identical clean detects, with
00780             two blocks of something different preceeding it. For anything
00781             else we need two successive identical clean detects, with
00782             two blocks of something different preceeding it. */
00783          if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00784             ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00785              (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] && 
00786              hit != s->td.mf.hits[0]))) {
00787             store_digit(s, hit);
00788          }
00789       }
00790 
00791 
00792       if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00793          /* Two successive block without a hit terminate current digit */
00794          s->td.mf.current_hit = 0;
00795       }
00796 
00797       s->td.mf.hits[0] = s->td.mf.hits[1];
00798       s->td.mf.hits[1] = s->td.mf.hits[2];
00799       s->td.mf.hits[2] = s->td.mf.hits[3];
00800       s->td.mf.hits[3] = s->td.mf.hits[4];
00801       s->td.mf.hits[4] = hit;
00802       /* Reinitialise the detector for the next block */
00803       for (i = 0;  i < 6;  i++)
00804          goertzel_reset(&s->td.mf.tone_out[i]);
00805       s->td.mf.current_sample = 0;
00806    }
00807 
00808    return (s->td.mf.current_hit); /* return the debounced hit */
00809 }
00810 
00811 static int __ast_dsp_digitdetect(struct ast_dsp *dsp, short *s, int len, int *writeback)
00812 {
00813    int res = 0;
00814    
00815    if ((dsp->features & DSP_FEATURE_DTMF_DETECT) && (dsp->digitmode & DSP_DIGITMODE_MF))
00816       res = mf_detect(&dsp->digit_state, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00817    else if (dsp->features & DSP_FEATURE_DTMF_DETECT)
00818       res = dtmf_detect(&dsp->digit_state, s, len, dsp->digitmode & DSP_DIGITMODE_RELAXDTMF, writeback);
00819 
00820    if ((dsp->features & DSP_FEATURE_FAX_DETECT) && (dsp->faxmode & DSP_FAXMODE_DETECT_CNG)) {
00821       if (tone_detect(&dsp->cng_tone_state, s, len, NULL)) {
00822          store_digit(&dsp->digit_state, 'f');
00823          res = 'f';
00824       }
00825    }
00826 
00827    if ((dsp->features & DSP_FEATURE_FAX_DETECT) && (dsp->faxmode & DSP_FAXMODE_DETECT_CED)) {
00828       if (tone_detect(&dsp->ced_tone_state, s, len, NULL)) {
00829          store_digit(&dsp->digit_state, 'e');
00830          res = 'e';
00831       }
00832    }
00833 
00834    return res;
00835 }
00836 
00837 int ast_dsp_digitdetect(struct ast_dsp *dsp, struct ast_frame *inf)
00838 {
00839    short *s;
00840    int len;
00841    int ign=0;
00842 
00843    if (inf->frametype != AST_FRAME_VOICE) {
00844       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
00845       return 0;
00846    }
00847    if (inf->subclass != AST_FORMAT_SLINEAR) {
00848       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
00849       return 0;
00850    }
00851    s = inf->data;
00852    len = inf->datalen / 2;
00853    return __ast_dsp_digitdetect(dsp, s, len, &ign);
00854 }
00855 
00856 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
00857 {
00858    /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
00859    /* Make sure absolute levels are high enough */
00860    if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH))
00861       return 0;
00862    /* Amplify ignored stuff */
00863    i2 *= TONE_THRESH;
00864    i1 *= TONE_THRESH;
00865    e *= TONE_THRESH;
00866    /* Check first tone */
00867    if ((p1 < i1) || (p1 < i2) || (p1 < e))
00868       return 0;
00869    /* And second */
00870    if ((p2 < i1) || (p2 < i2) || (p2 < e))
00871       return 0;
00872    /* Guess it's there... */
00873    return 1;
00874 }
00875 
00876 int ast_dsp_getdigits(struct ast_dsp *dsp, char *buf, int max)
00877 {
00878    if (max > dsp->digit_state.current_digits)
00879       max = dsp->digit_state.current_digits;
00880    if (max > 0) {
00881       memcpy(buf, dsp->digit_state.digits, max);
00882       memmove(dsp->digit_state.digits, dsp->digit_state.digits + max, dsp->digit_state.current_digits - max);
00883       dsp->digit_state.current_digits -= max;
00884    }
00885    buf[max] = '\0';
00886    return  max;
00887 }
00888 
00889 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
00890 {
00891    int x;
00892    int y;
00893    int pass;
00894    int newstate = DSP_TONE_STATE_SILENCE;
00895    int res = 0;
00896    while (len) {
00897       /* Take the lesser of the number of samples we need and what we have */
00898       pass = len;
00899       if (pass > dsp->gsamp_size - dsp->gsamps) 
00900          pass = dsp->gsamp_size - dsp->gsamps;
00901       for (x=0;x<pass;x++) {
00902          for (y=0;y<dsp->freqcount;y++) 
00903             goertzel_sample(&dsp->freqs[y], s[x]);
00904          dsp->genergy += s[x] * s[x];
00905       }
00906       s += pass;
00907       dsp->gsamps += pass;
00908       len -= pass;
00909       if (dsp->gsamps == dsp->gsamp_size) {
00910          float hz[7];
00911          for (y=0;y<7;y++)
00912             hz[y] = goertzel_result(&dsp->freqs[y]);
00913          switch (dsp->progmode) {
00914          case PROG_MODE_NA:
00915             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
00916                newstate = DSP_TONE_STATE_BUSY;
00917             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
00918                newstate = DSP_TONE_STATE_RINGING;
00919             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
00920                newstate = DSP_TONE_STATE_DIALTONE;
00921             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
00922                newstate = DSP_TONE_STATE_SPECIAL1;
00923             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
00924                if (dsp->tstate == DSP_TONE_STATE_SPECIAL1)
00925                   newstate = DSP_TONE_STATE_SPECIAL2;
00926             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
00927                if (dsp->tstate == DSP_TONE_STATE_SPECIAL2)
00928                   newstate = DSP_TONE_STATE_SPECIAL3;
00929             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00930                newstate = DSP_TONE_STATE_TALKING;
00931             } else
00932                newstate = DSP_TONE_STATE_SILENCE;
00933             break;
00934          case PROG_MODE_CR:
00935             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
00936                newstate = DSP_TONE_STATE_RINGING;
00937             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
00938                newstate = DSP_TONE_STATE_TALKING;
00939             } else
00940                newstate = DSP_TONE_STATE_SILENCE;
00941             break;
00942          case PROG_MODE_UK:
00943             if (hz[HZ_400] > TONE_MIN_THRESH * TONE_THRESH) {
00944                newstate = DSP_TONE_STATE_HUNGUP;
00945             }
00946             break;
00947          default:
00948             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
00949          }
00950          if (newstate == dsp->tstate) {
00951             dsp->tcount++;
00952             if (dsp->ringtimeout)
00953                dsp->ringtimeout++;
00954             switch (dsp->tstate) {
00955                case DSP_TONE_STATE_RINGING:
00956                   if ((dsp->features & DSP_PROGRESS_RINGING) &&
00957                       (dsp->tcount==THRESH_RING)) {
00958                      res = AST_CONTROL_RINGING;
00959                      dsp->ringtimeout= 1;
00960                   }
00961                   break;
00962                case DSP_TONE_STATE_BUSY:
00963                   if ((dsp->features & DSP_PROGRESS_BUSY) &&
00964                       (dsp->tcount==THRESH_BUSY)) {
00965                      res = AST_CONTROL_BUSY;
00966                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00967                   }
00968                   break;
00969                case DSP_TONE_STATE_TALKING:
00970                   if ((dsp->features & DSP_PROGRESS_TALK) &&
00971                       (dsp->tcount==THRESH_TALK)) {
00972                      res = AST_CONTROL_ANSWER;
00973                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00974                   }
00975                   break;
00976                case DSP_TONE_STATE_SPECIAL3:
00977                   if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
00978                       (dsp->tcount==THRESH_CONGESTION)) {
00979                      res = AST_CONTROL_CONGESTION;
00980                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00981                   }
00982                   break;
00983                case DSP_TONE_STATE_HUNGUP:
00984                   if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
00985                       (dsp->tcount==THRESH_HANGUP)) {
00986                      res = AST_CONTROL_HANGUP;
00987                      dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00988                   }
00989                   break;
00990             }
00991             if (dsp->ringtimeout==THRESH_RING2ANSWER) {
00992                ast_debug(1, "Consider call as answered because of timeout after last ring\n");
00993                res = AST_CONTROL_ANSWER;
00994                dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
00995             }
00996          } else {
00997             ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
00998             ast_debug(5, "Start state %d\n", newstate);
00999             dsp->tstate = newstate;
01000             dsp->tcount = 1;
01001          }
01002          
01003          /* Reset goertzel */                
01004          for (x=0;x<7;x++)
01005             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01006          dsp->gsamps = 0;
01007          dsp->genergy = 0.0;
01008       }
01009    }
01010 
01011    return res;
01012 }
01013 
01014 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01015 {
01016    if (inf->frametype != AST_FRAME_VOICE) {
01017       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01018       return 0;
01019    }
01020    if (inf->subclass != AST_FORMAT_SLINEAR) {
01021       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01022       return 0;
01023    }
01024    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01025 }
01026 
01027 static int __ast_dsp_silence(struct ast_dsp *dsp, short *s, int len, int *totalsilence)
01028 {
01029    int accum;
01030    int x;
01031    int res = 0;
01032 
01033    if (!len)
01034       return 0;
01035    accum = 0;
01036    for (x=0;x<len; x++) 
01037       accum += abs(s[x]);
01038    accum /= len;
01039    if (accum < dsp->threshold) {
01040       /* Silent */
01041       dsp->totalsilence += len/8;
01042 #ifdef DEBUG_DSP_BUSYDETECT
01043       fprintf(stderr, "SILENCE: len = %d, level = %d\n", dsp->totalsilence, accum);
01044 #endif
01045       if (dsp->totalnoise) {
01046          /* Move and save history */
01047          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1)*sizeof(dsp->historicnoise[0]));
01048          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01049          /* check if previous tone differs BUSY_PERCENT from the one before it */
01050          int tone1 = dsp->historicnoise[DSP_HISTORY - 1];
01051          int tone2 = dsp->historicnoise[DSP_HISTORY - 2];
01052          if (tone1 < tone2) {
01053            if ((tone1 + tone1*BUSY_PERCENT/100) >= tone2)
01054                dsp->busymaybe = 1;
01055            else
01056                dsp->busymaybe = 0;
01057          } else {
01058            if ((tone1 - tone1*BUSY_PERCENT/100) <= tone2)
01059                dsp->busymaybe = 1;
01060             else
01061                dsp->busymaybe = 0;
01062          }
01063       }
01064       dsp->totalnoise = 0;
01065       res = 1;
01066    } else {
01067       /* Not silent */
01068       dsp->totalnoise += len/8;
01069 #ifdef DEBUG_DSP_BUSYDETECT
01070       fprintf(stderr, "NOISE: len = %d, level = %d\n", dsp->totalnoise, accum);
01071 #endif     
01072       if (dsp->totalsilence) {
01073          /* Move and save history */
01074          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, (dsp->busycount-1)*sizeof(dsp->historicsilence[0]));
01075          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01076       }
01077       dsp->totalsilence = 0;
01078    }
01079    if (totalsilence)
01080       *totalsilence = dsp->totalsilence;
01081    return res;
01082 }
01083 
01084 int ast_dsp_busydetect(struct ast_dsp *dsp)
01085 {
01086    int res = 0, x;
01087    int avgsilence = 0, hitsilence = 0;
01088    int avgtone = 0, hittone = 0;
01089 #ifdef DEBUG_DSP_BUSYDETECT
01090    char buf[16];
01091    char silence_list[64]="", tone_list[64]="";
01092 #endif
01093    
01094    if (!dsp->busymaybe)
01095       return res;
01096    dsp->busymaybe = 0;
01097 
01098    for (x=DSP_HISTORY - dsp->busycount;x<DSP_HISTORY;x++) {
01099       avgsilence += dsp->historicsilence[x];
01100       avgtone += dsp->historicnoise[x];
01101    }
01102    avgsilence /= dsp->busycount;
01103    avgtone /= dsp->busycount;
01104 #ifdef DEBUG_DSP_BUSYDETECT
01105    sprintf(silence_list,"Silences: ");
01106    sprintf(tone_list,"Tones:    ");
01107 #endif
01108    for (x=DSP_HISTORY - dsp->busycount; x<DSP_HISTORY; x++) {
01109 #ifdef DEBUG_DSP_BUSYDETECT
01110       snprintf(buf, sizeof(buf), "%5d ", dsp->historicsilence[x]);
01111       strcat(silence_list, buf);
01112       snprintf(buf, sizeof(buf), "%5d ", dsp->historicnoise[x]);
01113       strcat(tone_list, buf); 
01114 #endif
01115       if (!dsp->busytoneonly) {
01116          if (avgsilence > dsp->historicsilence[x]) {
01117             if (avgsilence - (avgsilence*BUSY_PERCENT/100) <= dsp->historicsilence[x])
01118                hitsilence++;
01119          } else {
01120             if (avgsilence + (avgsilence*BUSY_PERCENT/100) >= dsp->historicsilence[x])
01121                hitsilence++;
01122          }
01123       }
01124       if (avgtone > dsp->historicnoise[x]) {
01125          if (avgtone - (avgtone*BUSY_PERCENT/100) <= dsp->historicnoise[x])
01126             hittone++;
01127       } else {
01128          if (avgtone + (avgtone*BUSY_PERCENT/100) >= dsp->historicnoise[x])
01129             hittone++;
01130       }
01131    }
01132 #ifdef DEBUG_DSP_BUSYDETECT
01133    fprintf(stderr, "BUSY DETECTOR\n");   
01134    fprintf(stderr, "%s\n", tone_list);
01135    fprintf(stderr, "%s\n", silence_list)
01136 #endif
01137    if ((dsp->busytoneonly || 
01138        (hitsilence >= dsp->busycount - 1 && avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) &&
01139       (hittone >= dsp->busycount - 1 && avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01140       if (dsp->busycompare) {
01141            if (dsp->busytoneonly) {
01142              res = 1;
01143             ast_log(LOG_ERROR, "You can't use busytoneonly together with busycompare");
01144          } else {
01145               if (avgtone > avgsilence) {
01146                  if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence)
01147                     res = 1;
01148             } else {
01149                  if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence)
01150                    res = 1;
01151             }
01152          }
01153       } else {
01154          res = 1;
01155       }
01156    }
01157    /* If we know the expected busy tone length, check we are in the range */
01158    if (res && (dsp->busy_tonelength > 0)) {
01159       if (abs(avgtone - dsp->busy_tonelength) > (dsp->busy_tonelength*dsp->busy_pattern_fuzzy/100)) {
01160 #ifdef BUSYDETECT_DEBUG
01161          if(option_debug) {
01162             ast_log(LOG_DEBUG, "busy detector: avgtone of %d not close enough to desired %d\n", avgtone, dsp->busy_tonelength);
01163          }
01164 #endif
01165          res = 0;
01166       }
01167    }
01168    /* If we know the expected busy tone silent-period length, check we are in the range */
01169    if (res && (!dsp->busytoneonly) && (dsp->busy_quietlength > 0)) {
01170       if (abs(avgsilence - dsp->busy_quietlength) > (dsp->busy_quietlength*dsp->busy_pattern_fuzzy/100)) {
01171 #ifdef BUSYDETECT_DEBUG
01172          if(option_debug) {
01173             ast_log(LOG_DEBUG, "busy detector: avgsilence of %d not close enough to desired %d\n", avgsilence, dsp->busy_quietlength);
01174          }
01175 #endif
01176          res = 0;
01177       }
01178    }
01179    if (res) {
01180       if (option_debug)
01181          ast_log(LOG_NOTICE, "ast_dsp_busydetect detected busy sequence, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01182    } else {
01183       if (option_debug)
01184          ast_log(LOG_NOTICE, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01185    }
01186    return res;
01187 }
01188 
01189 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01190 {
01191    short *s;
01192    int len;
01193    
01194    if (f->frametype != AST_FRAME_VOICE) {
01195       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01196       return 0;
01197    }
01198    if (f->subclass != AST_FORMAT_SLINEAR) {
01199       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01200       return 0;
01201    }
01202    s = f->data;
01203    len = f->datalen/2;
01204    return __ast_dsp_silence(dsp, s, len, totalsilence);
01205 }
01206 
01207 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01208 {
01209    int silence;
01210    int res;
01211    int digit;
01212    int x;
01213    short *shortdata;
01214    unsigned char *odata;
01215    int len;
01216    int writeback = 0;
01217 
01218 #define FIX_INF(inf) do { \
01219       if (writeback) { \
01220          switch (inf->subclass) { \
01221          case AST_FORMAT_SLINEAR: \
01222             break; \
01223          case AST_FORMAT_ULAW: \
01224             for (x=0;x<len;x++) \
01225                odata[x] = AST_LIN2MU((unsigned short)shortdata[x]); \
01226             break; \
01227          case AST_FORMAT_ALAW: \
01228             for (x=0;x<len;x++) \
01229                odata[x] = AST_LIN2A((unsigned short)shortdata[x]); \
01230             break; \
01231          } \
01232       } \
01233    } while(0) 
01234 
01235    if (!af)
01236       return NULL;
01237    if (af->frametype != AST_FRAME_VOICE)
01238       return af;
01239    odata = af->data;
01240    len = af->datalen;
01241    /* Make sure we have short data */
01242    switch (af->subclass) {
01243    case AST_FORMAT_SLINEAR:
01244       shortdata = af->data;
01245       len = af->datalen / 2;
01246       break;
01247    case AST_FORMAT_ULAW:
01248       shortdata = alloca(af->datalen * 2);
01249       for (x = 0;x < len; x++) 
01250          shortdata[x] = AST_MULAW(odata[x]);
01251       break;
01252    case AST_FORMAT_ALAW:
01253       shortdata = alloca(af->datalen * 2);
01254       for (x = 0; x < len; x++) 
01255          shortdata[x] = AST_ALAW(odata[x]);
01256       break;
01257    default:
01258       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01259       return af;
01260    }
01261    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01262    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01263       memset(&dsp->f, 0, sizeof(dsp->f));
01264       dsp->f.frametype = AST_FRAME_NULL;
01265       ast_frfree(af);
01266       ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01267       return &dsp->f;
01268    }
01269    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01270       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01271       memset(&dsp->f, 0, sizeof(dsp->f));
01272       dsp->f.frametype = AST_FRAME_CONTROL;
01273       dsp->f.subclass = AST_CONTROL_BUSY;
01274       ast_frfree(af);
01275       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01276       ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01277       return &dsp->f;
01278    }
01279    if (((dsp->features & DSP_FEATURE_DTMF_DETECT) || (dsp->features & DSP_FEATURE_FAX_DETECT))) {
01280       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01281 #if 0
01282       if (digit)
01283          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01284 #endif
01285       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01286          if (!dsp->thinkdigit) {
01287             if (digit) {
01288                /* Looks like we might have something.  
01289                 * Request a conference mute for the moment */
01290                memset(&dsp->f, 0, sizeof(dsp->f));
01291                dsp->f.frametype = AST_FRAME_DTMF;
01292                dsp->f.subclass = 'm';
01293                dsp->thinkdigit = 'x';
01294                FIX_INF(af);
01295                if (chan)
01296                   ast_queue_frame(chan, af);
01297                ast_frfree(af);
01298                ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01299                return &dsp->f;
01300             }
01301          } else {
01302             if (digit) {
01303                /* Thought we saw one last time.  Pretty sure we really have now */
01304                if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01305                   /* If we found a digit, and we're changing digits, go
01306                      ahead and send this one, but DON'T stop confmute because
01307                      we're detecting something else, too... */
01308                   memset(&dsp->f, 0, sizeof(dsp->f));
01309                   dsp->f.frametype = AST_FRAME_DTMF_END;
01310                   dsp->f.subclass = dsp->thinkdigit;
01311                   FIX_INF(af);
01312                   if (chan)
01313                      ast_queue_frame(chan, af);
01314                   ast_frfree(af);
01315                } else {
01316                   dsp->thinkdigit = digit;
01317                   memset(&dsp->f, 0, sizeof(dsp->f));
01318                   dsp->f.frametype = AST_FRAME_DTMF_BEGIN;
01319                   dsp->f.subclass = dsp->thinkdigit;
01320                   FIX_INF(af);
01321                   if (chan)
01322                      ast_queue_frame(chan, af);
01323                   ast_frfree(af);
01324                }
01325                ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01326                return &dsp->f;
01327             } else {
01328                memset(&dsp->f, 0, sizeof(dsp->f));
01329                if (dsp->thinkdigit != 'x') {
01330                   /* If we found a digit, send it now */
01331                   dsp->f.frametype = AST_FRAME_DTMF_END;
01332                   dsp->f.subclass = dsp->thinkdigit;
01333                   dsp->thinkdigit = 0;
01334                } else {
01335                   dsp->f.frametype = AST_FRAME_DTMF;
01336                   dsp->f.subclass = 'u';
01337                   dsp->thinkdigit = 0;
01338                }
01339                FIX_INF(af);
01340                if (chan)
01341                   ast_queue_frame(chan, af);
01342                ast_frfree(af);
01343                ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01344                return &dsp->f;
01345             }
01346          }
01347       } else if (dsp->digit_state.current_digits > 1 ||
01348          (dsp->digit_state.current_digits == 1 && digit != dsp->digit_state.digits[0])) {
01349          /* Since we basically generate DTMF_END frames we do it only when a digit
01350             has finished. */
01351 
01352          memset(&dsp->f, 0, sizeof(dsp->f));
01353          dsp->f.frametype = AST_FRAME_DTMF;
01354          dsp->f.subclass = dsp->digit_state.digits[0];
01355          memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits);
01356          dsp->digit_state.current_digits--;
01357          FIX_INF(af);
01358          if (chan)
01359             ast_queue_frame(chan, af);
01360          ast_frfree(af);
01361          ast_set_flag(&dsp->f, AST_FRFLAG_FROM_DSP);
01362          return &dsp->f;
01363       }
01364    }
01365    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01366       res = __ast_dsp_call_progress(dsp, shortdata, len);
01367       if (res) {
01368          switch (res) {
01369          case AST_CONTROL_ANSWER:
01370          case AST_CONTROL_BUSY:
01371          case AST_CONTROL_RINGING:
01372          case AST_CONTROL_CONGESTION:
01373          case AST_CONTROL_HANGUP:
01374             memset(&dsp->f, 0, sizeof(dsp->f));
01375             dsp->f.frametype = AST_FRAME_CONTROL;
01376             dsp->f.subclass = res;
01377             dsp->f.src = "dsp_progress";
01378             if (chan) 
01379                ast_queue_frame(chan, &dsp->f);
01380             break;
01381          default:
01382             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01383          }
01384       }
01385    }
01386    FIX_INF(af);
01387    return af;
01388 }
01389 
01390 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01391 {
01392    int max = 0;
01393    int x;
01394    
01395    dsp->gsamp_size = modes[dsp->progmode].size;
01396    dsp->gsamps = 0;
01397    for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01398       if (modes[dsp->progmode].freqs[x]) {
01399          goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01400          max = x + 1;
01401       }
01402    }
01403    dsp->freqcount = max;
01404    dsp->ringtimeout= 0;
01405 }
01406 
01407 struct ast_dsp *ast_dsp_new(void)
01408 {
01409    struct ast_dsp *dsp;
01410    
01411    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01412       dsp->threshold = DEFAULT_THRESHOLD;
01413       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01414       dsp->busycount = DSP_HISTORY;
01415       dsp->digitmode = DSP_DIGITMODE_DTMF;
01416       dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01417       dsp->busy_pattern_fuzzy = BUSY_PAT_PERCENT;
01418 #ifdef BUSYDETECT_TONEONLY
01419       dsp->busytoneonly = 1;
01420 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01421 #error "You can't use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE");
01422 #endif
01423 #else
01424    dsp->busytoneonly = 0;
01425 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01426    dsp->busycompare = 1;
01427 #else
01428    dsp->busycompare = 0;
01429 #endif
01430 #endif
01431       /* Initialize digit detector */
01432       ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01433       /* Initialize initial DSP progress detect parameters */
01434       ast_dsp_prog_reset(dsp);
01435       /* Initialize fax detector */
01436       ast_fax_detect_init(dsp);
01437    }
01438    return dsp;
01439 }
01440 
01441 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01442 {
01443    dsp->features = features;
01444 }
01445 
01446 void ast_dsp_free(struct ast_dsp *dsp)
01447 {
01448    if (ast_test_flag(&dsp->f, AST_FRFLAG_FROM_DSP)) {
01449       /* If this flag is still set, that means that the dsp's destruction 
01450        * been torn down, while we still have a frame out there being used.
01451        * When ast_frfree() gets called on that frame, this ast_trans_pvt
01452        * will get destroyed, too. */
01453 
01454       /* Set the magic flag to destroy the dsp when the frame is freed */
01455       dsp->freqcount = -1;
01456 
01457       return;
01458    }
01459    ast_free(dsp);
01460 }
01461 
01462 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01463 {
01464    if (threshold < 256)
01465      dsp->threshold = 256;
01466    else
01467      dsp->threshold = threshold;
01468 }
01469 
01470 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01471 {
01472    if (cadences < 4)
01473       cadences = 4;
01474    if (cadences > DSP_HISTORY)
01475       cadences = DSP_HISTORY;
01476    dsp->busycount = cadences;
01477 }
01478 
01479 void ast_dsp_set_busy_compare(struct ast_dsp *dsp, int compare)
01480 {
01481   if (compare > 0)
01482       dsp->busycompare = 1;
01483   else
01484       dsp->busycompare = 0;
01485 }
01486 
01487 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength, int fuzzy)
01488 {
01489    dsp->busy_tonelength = tonelength;
01490    if (quietlength > 0)
01491       dsp->busy_quietlength = quietlength;
01492    else 
01493      dsp->busytoneonly = 1;
01494    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01495    if( fuzzy > 0 && fuzzy < 50 ) 
01496       dsp->busy_pattern_fuzzy = fuzzy;
01497 }
01498 
01499 void ast_dsp_digitreset(struct ast_dsp *dsp)
01500 {
01501    int i;
01502    
01503    dsp->thinkdigit = 0;
01504    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01505       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01506       /* Reinitialise the detector for the next block */
01507       for (i = 0;  i < 6;  i++) {
01508          goertzel_reset(&s->tone_out[i]);
01509       }
01510       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01511       s->current_sample = 0;
01512    } else {
01513       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01514       /* Reinitialise the detector for the next block */
01515       for (i = 0;  i < 4;  i++) {
01516          goertzel_reset(&s->row_out[i]);
01517          goertzel_reset(&s->col_out[i]);
01518       }
01519       s->lasthit = s->current_hit = 0;
01520       s->energy = 0.0;
01521       s->current_sample = 0;
01522    }
01523 
01524    dsp->digit_state.digits[0] = '\0';
01525    dsp->digit_state.current_digits = 0;
01526 }
01527 
01528 void ast_dsp_reset(struct ast_dsp *dsp)
01529 {
01530    int x;
01531    
01532    dsp->totalsilence = 0;
01533    dsp->gsamps = 0;
01534    for (x=0;x<4;x++)
01535       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01536    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01537    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01538    dsp->ringtimeout= 0;
01539 }
01540 
01541 int ast_dsp_digitmode(struct ast_dsp *dsp, int digitmode)
01542 {
01543    int new;
01544    int old;
01545    
01546    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01547    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01548    if (old != new) {
01549       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01550       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01551    }
01552    dsp->digitmode = digitmode;
01553    return 0;
01554 }
01555 
01556 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01557 {
01558    if (dsp->faxmode != faxmode) {
01559       ast_fax_detect_init(dsp);
01560    }
01561    dsp->faxmode = faxmode;
01562    return 0;
01563 }
01564 
01565 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01566 {
01567    int x;
01568    
01569    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01570       if (!strcasecmp(aliases[x].name, zone)) {
01571          dsp->progmode = aliases[x].mode;
01572          ast_dsp_prog_reset(dsp);
01573          return 0;
01574       }
01575    }
01576    return -1;
01577 }
01578 
01579 int ast_dsp_get_tstate(struct ast_dsp *dsp) 
01580 {
01581    return dsp->tstate;
01582 }
01583 
01584 int ast_dsp_get_tcount(struct ast_dsp *dsp) 
01585 {
01586    return dsp->tcount;
01587 }
01588 
01589 void ast_dsp_frame_freed(struct ast_frame *fr)
01590 {
01591    struct ast_dsp *dsp;
01592 
01593    ast_clear_flag(fr, AST_FRFLAG_FROM_DSP);
01594 
01595    dsp = (struct ast_dsp *) (((char *) fr) - offsetof(struct ast_dsp, f));
01596 
01597    if (dsp->freqcount != -1)
01598       return;
01599    
01600    ast_dsp_free(dsp);
01601 }

Generated on Thu Jul 9 13:40:33 2009 for Asterisk - the Open Source PBX by  doxygen 1.4.7