Mon Apr 28 2014 10:05:42

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 /*** MODULEINFO
00044    <support_level>core</support_level>
00045  ***/
00046 
00047 #include "asterisk.h"
00048 
00049 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 374479 $")
00050 
00051 #include <math.h>
00052 
00053 #include "asterisk/frame.h"
00054 #include "asterisk/channel.h"
00055 #include "asterisk/dsp.h"
00056 #include "asterisk/ulaw.h"
00057 #include "asterisk/alaw.h"
00058 #include "asterisk/utils.h"
00059 #include "asterisk/options.h"
00060 #include "asterisk/config.h"
00061 
00062 /*! Number of goertzels for progress detect */
00063 enum gsamp_size {
00064    GSAMP_SIZE_NA = 183,       /*!< North America - 350, 440, 480, 620, 950, 1400, 1800 Hz */
00065    GSAMP_SIZE_CR = 188,       /*!< Costa Rica, Brazil - Only care about 425 Hz */
00066    GSAMP_SIZE_UK = 160        /*!< UK disconnect goertzel feed - should trigger 400hz */
00067 };
00068 
00069 enum prog_mode {
00070    PROG_MODE_NA = 0,
00071    PROG_MODE_CR,
00072    PROG_MODE_UK
00073 };
00074 
00075 enum freq_index { 
00076    /*! For US modes { */
00077    HZ_350 = 0,
00078    HZ_440,
00079    HZ_480,
00080    HZ_620,
00081    HZ_950,
00082    HZ_1400,
00083    HZ_1800, /*!< } */
00084 
00085    /*! For CR/BR modes */
00086    HZ_425 = 0,
00087 
00088    /*! For UK mode */
00089    HZ_350UK = 0,
00090    HZ_400UK,
00091    HZ_440UK
00092 };
00093 
00094 static struct progalias {
00095    char *name;
00096    enum prog_mode mode;
00097 } aliases[] = {
00098    { "us", PROG_MODE_NA },
00099    { "ca", PROG_MODE_NA },
00100    { "cr", PROG_MODE_CR },
00101    { "br", PROG_MODE_CR },
00102    { "uk", PROG_MODE_UK },
00103 };
00104 
00105 static struct progress {
00106    enum gsamp_size size;
00107    int freqs[7];
00108 } modes[] = {
00109    { GSAMP_SIZE_NA, { 350, 440, 480, 620, 950, 1400, 1800 } }, /*!< North America */
00110    { GSAMP_SIZE_CR, { 425 } },                                 /*!< Costa Rica, Brazil */
00111    { GSAMP_SIZE_UK, { 350, 400, 440 } },                                   /*!< UK */
00112 };
00113 
00114 /*!\brief This value is the minimum threshold, calculated by averaging all
00115  * of the samples within a frame, for which a frame is determined to either
00116  * be silence (below the threshold) or noise (above the threshold).  Please
00117  * note that while the default threshold is an even exponent of 2, there is
00118  * no requirement that it be so.  The threshold will accept any value between
00119  * 0 and 32767.
00120  */
00121 #define DEFAULT_THRESHOLD  512
00122 
00123 enum busy_detect {
00124    BUSY_PERCENT = 10,      /*!< The percentage difference between the two last silence periods */
00125    BUSY_PAT_PERCENT = 7,   /*!< The percentage difference between measured and actual pattern */
00126    BUSY_THRESHOLD = 100,   /*!< Max number of ms difference between max and min times in busy */
00127    BUSY_MIN = 75,          /*!< Busy must be at least 80 ms in half-cadence */
00128    BUSY_MAX =3100          /*!< Busy can't be longer than 3100 ms in half-cadence */
00129 };
00130 
00131 /*! Remember last 15 units */
00132 #define DSP_HISTORY     15
00133 
00134 #define TONE_THRESH     10.0  /*!< How much louder the tone should be than channel energy */
00135 #define TONE_MIN_THRESH    1e8   /*!< How much tone there should be at least to attempt */
00136 
00137 /*! All THRESH_XXX values are in GSAMP_SIZE chunks (us = 22ms) */
00138 enum gsamp_thresh {
00139    THRESH_RING = 8,           /*!< Need at least 150ms ring to accept */
00140    THRESH_TALK = 2,           /*!< Talk detection does not work continuously */
00141    THRESH_BUSY = 4,           /*!< Need at least 80ms to accept */
00142    THRESH_CONGESTION = 4,     /*!< Need at least 80ms to accept */
00143    THRESH_HANGUP = 60,        /*!< Need at least 1300ms to accept hangup */
00144    THRESH_RING2ANSWER = 300   /*!< Timeout from start of ring to answer (about 6600 ms) */
00145 };
00146 
00147 #define  MAX_DTMF_DIGITS      128
00148 
00149 /* Basic DTMF (AT&T) specs:
00150  *
00151  * Minimum tone on = 40ms
00152  * Minimum tone off = 50ms
00153  * Maximum digit rate = 10 per second
00154  * Normal twist <= 8dB accepted
00155  * Reverse twist <= 4dB accepted
00156  * S/N >= 15dB will detect OK
00157  * Attenuation <= 26dB will detect OK
00158  * Frequency tolerance +- 1.5% will detect, +-3.5% will reject
00159  */
00160 
00161 #define DTMF_THRESHOLD     8.0e7
00162 #define FAX_THRESHOLD      8.0e7
00163 #define FAX_2ND_HARMONIC   2.0     /* 4dB */
00164 
00165 #define DEF_DTMF_NORMAL_TWIST    6.31   /* 8.0dB */
00166 #define DEF_RELAX_DTMF_NORMAL_TWIST 6.31   /* 8.0dB */
00167 
00168 #ifdef   RADIO_RELAX
00169 #define DEF_DTMF_REVERSE_TWIST      2.51   /* 4.01dB */
00170 #define DEF_RELAX_DTMF_REVERSE_TWIST   6.61   /* 8.2dB */
00171 #else
00172 #define DEF_DTMF_REVERSE_TWIST      2.51   /* 4.01dB */
00173 #define DEF_RELAX_DTMF_REVERSE_TWIST   3.98   /* 6.0dB */
00174 #endif
00175 
00176 #define DTMF_RELATIVE_PEAK_ROW   6.3     /* 8dB */
00177 #define DTMF_RELATIVE_PEAK_COL   6.3     /* 8dB */
00178 #define DTMF_2ND_HARMONIC_ROW       (relax ? 1.7 : 2.5)     /* 4dB normal */
00179 #define DTMF_2ND_HARMONIC_COL 63.1    /* 18dB */
00180 #define DTMF_TO_TOTAL_ENERGY  42.0
00181 
00182 #define BELL_MF_THRESHOLD  1.6e9
00183 #define BELL_MF_TWIST      4.0     /* 6dB */
00184 #define BELL_MF_RELATIVE_PEAK 12.6    /* 11dB */
00185 
00186 #if defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_COMPARE_TONE_AND_SILENCE)
00187 #error You cant use BUSYDETECT_TONEONLY together with BUSYDETECT_COMPARE_TONE_AND_SILENCE
00188 #endif
00189 
00190 /* The CNG signal consists of the transmission of 1100 Hz for 1/2 second,
00191  * followed by a 3 second silent (2100 Hz OFF) period.
00192  */
00193 #define FAX_TONE_CNG_FREQ  1100
00194 #define FAX_TONE_CNG_DURATION 500
00195 #define FAX_TONE_CNG_DB    16
00196 
00197 /* This signal may be sent by the Terminating FAX machine anywhere between
00198  * 1.8 to 2.5 seconds AFTER answering the call.  The CED signal consists
00199  * of a 2100 Hz tone that is from 2.6 to 4 seconds in duration.
00200 */
00201 #define FAX_TONE_CED_FREQ  2100
00202 #define FAX_TONE_CED_DURATION 2600
00203 #define FAX_TONE_CED_DB    16
00204 
00205 #define SAMPLE_RATE     8000
00206 
00207 /* How many samples a frame has.  This constant is used when calculating
00208  * Goertzel block size for tone_detect.  It is only important if we want to
00209  * remove (squelch) the tone. In this case it is important to have block
00210  * size not to exceed size of voice frame.  Otherwise by the moment the tone
00211  * is detected it is too late to squelch it from previous frames.
00212  */
00213 #define SAMPLES_IN_FRAME   160
00214 
00215 /* MF goertzel size */
00216 #define MF_GSIZE     120
00217 
00218 /* DTMF goertzel size */
00219 #define DTMF_GSIZE      102
00220 
00221 /* How many successive hits needed to consider begin of a digit
00222  * IE. Override with dtmf_hits_to_begin=4 in dsp.conf
00223  */
00224 #define DEF_DTMF_HITS_TO_BEGIN   2
00225 
00226 /* How many successive misses needed to consider end of a digit
00227  * IE. Override with dtmf_misses_to_end=4 in dsp.conf
00228  */
00229 #define DEF_DTMF_MISSES_TO_END   3
00230 
00231 /*!
00232  * \brief The default silence threshold we will use if an alternate
00233  * configured value is not present or is invalid.
00234  */
00235 static const int DEFAULT_SILENCE_THRESHOLD = 256;
00236 
00237 #define CONFIG_FILE_NAME "dsp.conf"
00238 
00239 typedef struct {
00240    int v2;
00241    int v3;
00242    int chunky;
00243    int fac;
00244    int samples;
00245 } goertzel_state_t;
00246 
00247 typedef struct {
00248    int value;
00249    int power;
00250 } goertzel_result_t;
00251 
00252 typedef struct
00253 {
00254    int freq;
00255    int block_size;
00256    int squelch;      /* Remove (squelch) tone */
00257    goertzel_state_t tone;
00258    float energy;     /* Accumulated energy of the current block */
00259    int samples_pending; /* Samples remain to complete the current block */
00260    int mute_samples; /* How many additional samples needs to be muted to suppress already detected tone */
00261 
00262    int hits_required;   /* How many successive blocks with tone we are looking for */
00263    float threshold;  /* Energy of the tone relative to energy from all other signals to consider a hit */
00264 
00265    int hit_count;    /* How many successive blocks we consider tone present */
00266    int last_hit;     /* Indicates if the last processed block was a hit */
00267 
00268 } tone_detect_state_t;
00269 
00270 typedef struct
00271 {
00272    goertzel_state_t row_out[4];
00273    goertzel_state_t col_out[4];
00274    int hits;         /* How many successive hits we have seen already */
00275    int misses;       /* How many successive misses we have seen already */
00276    int lasthit;
00277    int current_hit;
00278    float energy;
00279    int current_sample;
00280    int mute_samples;
00281 } dtmf_detect_state_t;
00282 
00283 typedef struct
00284 {
00285    goertzel_state_t tone_out[6];
00286    int current_hit;
00287    int hits[5];
00288    int current_sample;
00289    int mute_samples;
00290 } mf_detect_state_t;
00291 
00292 typedef struct
00293 {
00294    char digits[MAX_DTMF_DIGITS + 1];
00295    int digitlen[MAX_DTMF_DIGITS + 1];
00296    int current_digits;
00297    int detected_digits;
00298    int lost_digits;
00299 
00300    union {
00301       dtmf_detect_state_t dtmf;
00302       mf_detect_state_t mf;
00303    } td;
00304 } digit_detect_state_t;
00305 
00306 static const float dtmf_row[] = {
00307    697.0,  770.0,  852.0,  941.0
00308 };
00309 static const float dtmf_col[] = {
00310    1209.0, 1336.0, 1477.0, 1633.0
00311 };
00312 static const float mf_tones[] = {
00313    700.0, 900.0, 1100.0, 1300.0, 1500.0, 1700.0
00314 };
00315 static const char dtmf_positions[] = "123A" "456B" "789C" "*0#D";
00316 static const char bell_mf_positions[] = "1247C-358A--69*---0B----#";
00317 static int thresholds[THRESHOLD_MAX];
00318 static float dtmf_normal_twist;     /* AT&T = 8dB */
00319 static float dtmf_reverse_twist; /* AT&T = 4dB */
00320 static float relax_dtmf_normal_twist;  /* AT&T = 8dB */
00321 static float relax_dtmf_reverse_twist; /* AT&T = 6dB */
00322 static int dtmf_hits_to_begin;      /* How many successive hits needed to consider begin of a digit */
00323 static int dtmf_misses_to_end;      /* How many successive misses needed to consider end of a digit */
00324 
00325 static inline void goertzel_sample(goertzel_state_t *s, short sample)
00326 {
00327    int v1;
00328    
00329    v1 = s->v2;
00330    s->v2 = s->v3;
00331    
00332    s->v3 = (s->fac * s->v2) >> 15;
00333    s->v3 = s->v3 - v1 + (sample >> s->chunky);
00334    if (abs(s->v3) > 32768) {
00335       s->chunky++;
00336       s->v3 = s->v3 >> 1;
00337       s->v2 = s->v2 >> 1;
00338    }
00339 }
00340 
00341 static inline void goertzel_update(goertzel_state_t *s, short *samps, int count)
00342 {
00343    int i;
00344    
00345    for (i = 0; i < count; i++) {
00346       goertzel_sample(s, samps[i]);
00347    }
00348 }
00349 
00350 
00351 static inline float goertzel_result(goertzel_state_t *s)
00352 {
00353    goertzel_result_t r;
00354    r.value = (s->v3 * s->v3) + (s->v2 * s->v2);
00355    r.value -= ((s->v2 * s->v3) >> 15) * s->fac;
00356    r.power = s->chunky * 2;
00357    return (float)r.value * (float)(1 << r.power);
00358 }
00359 
00360 static inline void goertzel_init(goertzel_state_t *s, float freq, int samples)
00361 {
00362    s->v2 = s->v3 = s->chunky = 0.0;
00363    s->fac = (int)(32768.0 * 2.0 * cos(2.0 * M_PI * freq / SAMPLE_RATE));
00364    s->samples = samples;
00365 }
00366 
00367 static inline void goertzel_reset(goertzel_state_t *s)
00368 {
00369    s->v2 = s->v3 = s->chunky = 0.0;
00370 }
00371 
00372 typedef struct {
00373    int start;
00374    int end;
00375 } fragment_t;
00376 
00377 /* Note on tone suppression (squelching). Individual detectors (DTMF/MF/generic tone)
00378  * report fragments of the frame in which detected tone resides and which needs
00379  * to be "muted" in order to suppress the tone. To mark fragment for muting,
00380  * detectors call mute_fragment passing fragment_t there. Multiple fragments
00381  * can be marked and ast_dsp_process later will mute all of them.
00382  *
00383  * Note: When tone starts in the middle of a Goertzel block, it won't be properly
00384  * detected in that block, only in the next. If we only mute the next block
00385  * where tone is actually detected, the user will still hear beginning
00386  * of the tone in preceeding block. This is why we usually want to mute some amount
00387  * of samples preceeding and following the block where tone was detected.
00388 */
00389 
00390 struct ast_dsp {
00391    struct ast_frame f;
00392    int threshold;
00393    int totalsilence;
00394    int totalnoise;
00395    int features;
00396    int ringtimeout;
00397    int busymaybe;
00398    int busycount;
00399    int busy_tonelength;
00400    int busy_quietlength;
00401    int historicnoise[DSP_HISTORY];
00402    int historicsilence[DSP_HISTORY];
00403    goertzel_state_t freqs[7];
00404    int freqcount;
00405    int gsamps;
00406    enum gsamp_size gsamp_size;
00407    enum prog_mode progmode;
00408    int tstate;
00409    int tcount;
00410    int digitmode;
00411    int faxmode;
00412    int dtmf_began;
00413    int display_inband_dtmf_warning;
00414    float genergy;
00415    int mute_fragments;
00416    fragment_t mute_data[5];
00417    digit_detect_state_t digit_state;
00418    tone_detect_state_t cng_tone_state;
00419    tone_detect_state_t ced_tone_state;
00420 };
00421 
00422 static void mute_fragment(struct ast_dsp *dsp, fragment_t *fragment)
00423 {
00424    if (dsp->mute_fragments >= ARRAY_LEN(dsp->mute_data)) {
00425       ast_log(LOG_ERROR, "Too many fragments to mute. Ignoring\n");
00426       return;
00427    }
00428 
00429    dsp->mute_data[dsp->mute_fragments++] = *fragment;
00430 }
00431 
00432 static void ast_tone_detect_init(tone_detect_state_t *s, int freq, int duration, int amp)
00433 {
00434    int duration_samples;
00435    float x;
00436    int periods_in_block;
00437 
00438    s->freq = freq;
00439 
00440    /* Desired tone duration in samples */
00441    duration_samples = duration * SAMPLE_RATE / 1000;
00442    /* We want to allow 10% deviation of tone duration */
00443    duration_samples = duration_samples * 9 / 10;
00444 
00445    /* If we want to remove tone, it is important to have block size not
00446       to exceed frame size. Otherwise by the moment tone is detected it is too late
00447       to squelch it from previous frames */
00448    s->block_size = SAMPLES_IN_FRAME;
00449 
00450    periods_in_block = s->block_size * freq / SAMPLE_RATE;
00451 
00452    /* Make sure we will have at least 5 periods at target frequency for analisys.
00453       This may make block larger than expected packet and will make squelching impossible
00454       but at least we will be detecting the tone */
00455    if (periods_in_block < 5)
00456       periods_in_block = 5;
00457 
00458    /* Now calculate final block size. It will contain integer number of periods */
00459    s->block_size = periods_in_block * SAMPLE_RATE / freq;
00460 
00461    /* tone_detect is currently only used to detect fax tones and we
00462       do not need squelching the fax tones */
00463    s->squelch = 0;
00464 
00465    /* Account for the first and the last block to be incomplete
00466       and thus no tone will be detected in them */
00467    s->hits_required = (duration_samples - (s->block_size - 1)) / s->block_size;
00468 
00469    goertzel_init(&s->tone, freq, s->block_size);
00470 
00471    s->samples_pending = s->block_size;
00472    s->hit_count = 0;
00473    s->last_hit = 0;
00474    s->energy = 0.0;
00475 
00476    /* We want tone energy to be amp decibels above the rest of the signal (the noise).
00477       According to Parseval's theorem the energy computed in time domain equals to energy
00478       computed in frequency domain. So subtracting energy in the frequency domain (Goertzel result)
00479       from the energy in the time domain we will get energy of the remaining signal (without the tone
00480       we are detecting). We will be checking that
00481       10*log(Ew / (Et - Ew)) > amp
00482       Calculate threshold so that we will be actually checking
00483       Ew > Et * threshold
00484    */
00485 
00486    x = pow(10.0, amp / 10.0);
00487    s->threshold = x / (x + 1);
00488 
00489    ast_debug(1, "Setup tone %d Hz, %d ms, block_size=%d, hits_required=%d\n", freq, duration, s->block_size, s->hits_required);
00490 }
00491 
00492 static void ast_fax_detect_init(struct ast_dsp *s)
00493 {
00494    ast_tone_detect_init(&s->cng_tone_state, FAX_TONE_CNG_FREQ, FAX_TONE_CNG_DURATION, FAX_TONE_CNG_DB);
00495    ast_tone_detect_init(&s->ced_tone_state, FAX_TONE_CED_FREQ, FAX_TONE_CED_DURATION, FAX_TONE_CED_DB);
00496 }
00497 
00498 static void ast_dtmf_detect_init (dtmf_detect_state_t *s)
00499 {
00500    int i;
00501 
00502    s->lasthit = 0;
00503    s->current_hit = 0;
00504    for (i = 0;  i < 4;  i++) {
00505       goertzel_init(&s->row_out[i], dtmf_row[i], DTMF_GSIZE);
00506       goertzel_init(&s->col_out[i], dtmf_col[i], DTMF_GSIZE);
00507       s->energy = 0.0;
00508    }
00509    s->current_sample = 0;
00510    s->hits = 0;
00511    s->misses = 0;
00512 }
00513 
00514 static void ast_mf_detect_init (mf_detect_state_t *s)
00515 {
00516    int i;
00517    s->hits[0] = s->hits[1] = s->hits[2] = s->hits[3] = s->hits[4] = 0;
00518    for (i = 0;  i < 6;  i++) {
00519       goertzel_init (&s->tone_out[i], mf_tones[i], MF_GSIZE);
00520    }
00521    s->current_sample = 0;
00522    s->current_hit = 0;
00523 }
00524 
00525 static void ast_digit_detect_init(digit_detect_state_t *s, int mf)
00526 {
00527    s->current_digits = 0;
00528    s->detected_digits = 0;
00529    s->lost_digits = 0;
00530    s->digits[0] = '\0';
00531 
00532    if (mf) {
00533       ast_mf_detect_init(&s->td.mf);
00534    } else {
00535       ast_dtmf_detect_init(&s->td.dtmf);
00536    }
00537 }
00538 
00539 static int tone_detect(struct ast_dsp *dsp, tone_detect_state_t *s, int16_t *amp, int samples)
00540 {
00541    float tone_energy;
00542    int i;
00543    int hit = 0;
00544    int limit;
00545    int res = 0;
00546    int16_t *ptr;
00547    short samp;
00548    int start, end;
00549    fragment_t mute = {0, 0};
00550 
00551    if (s->squelch && s->mute_samples > 0) {
00552       mute.end = (s->mute_samples < samples) ? s->mute_samples : samples;
00553       s->mute_samples -= mute.end;
00554    }
00555 
00556    for (start = 0;  start < samples;  start = end) {
00557       /* Process in blocks. */
00558       limit = samples - start;
00559       if (limit > s->samples_pending) {
00560          limit = s->samples_pending;
00561       }
00562       end = start + limit;
00563 
00564       for (i = limit, ptr = amp ; i > 0; i--, ptr++) {
00565          samp = *ptr;
00566          /* signed 32 bit int should be enough to square any possible signed 16 bit value */
00567          s->energy += (int32_t) samp * (int32_t) samp;
00568 
00569          goertzel_sample(&s->tone, samp);
00570       }
00571 
00572       s->samples_pending -= limit;
00573 
00574       if (s->samples_pending) {
00575          /* Finished incomplete (last) block */
00576          break;
00577       }
00578 
00579       tone_energy = goertzel_result(&s->tone);
00580 
00581       /* Scale to make comparable */
00582       tone_energy *= 2.0;
00583       s->energy *= s->block_size;
00584 
00585       ast_debug(10, "tone %d, Ew=%.2E, Et=%.2E, s/n=%10.2f\n", s->freq, tone_energy, s->energy, tone_energy / (s->energy - tone_energy));
00586       hit = 0;
00587       if (tone_energy > s->energy * s->threshold) {
00588          ast_debug(10, "Hit! count=%d\n", s->hit_count);
00589          hit = 1;
00590       }
00591 
00592       if (s->hit_count) {
00593          s->hit_count++;
00594       }
00595 
00596       if (hit == s->last_hit) {
00597          if (!hit) {
00598             /* Two successive misses. Tone ended */
00599             s->hit_count = 0;
00600          } else if (!s->hit_count) {
00601             s->hit_count++;
00602          }
00603 
00604       }
00605 
00606       if (s->hit_count == s->hits_required) {
00607          ast_debug(1, "%d Hz done detected\n", s->freq);
00608          res = 1;
00609       }
00610 
00611       s->last_hit = hit;
00612 
00613       /* If we had a hit in this block, include it into mute fragment */
00614       if (s->squelch && hit) {
00615          if (mute.end < start - s->block_size) {
00616             /* There is a gap between fragments */
00617             mute_fragment(dsp, &mute);
00618             mute.start = (start > s->block_size) ? (start - s->block_size) : 0;
00619          }
00620          mute.end = end + s->block_size;
00621       }
00622 
00623       /* Reinitialise the detector for the next block */
00624       /* Reset for the next block */
00625       goertzel_reset(&s->tone);
00626 
00627       /* Advance to the next block */
00628       s->energy = 0.0;
00629       s->samples_pending = s->block_size;
00630 
00631       amp += limit;
00632    }
00633 
00634    if (s->squelch && mute.end) {
00635       if (mute.end > samples) {
00636          s->mute_samples = mute.end - samples;
00637          mute.end = samples;
00638       }
00639       mute_fragment(dsp, &mute);
00640    }
00641 
00642    return res;
00643 }
00644 
00645 static void store_digit(digit_detect_state_t *s, char digit)
00646 {
00647    s->detected_digits++;
00648    if (s->current_digits < MAX_DTMF_DIGITS) {
00649       s->digitlen[s->current_digits] = 0;
00650       s->digits[s->current_digits++] = digit;
00651       s->digits[s->current_digits] = '\0';
00652    } else {
00653       ast_log(LOG_WARNING, "Digit lost due to full buffer\n");
00654       s->lost_digits++;
00655    }
00656 }
00657 
00658 static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax)
00659 {
00660    float row_energy[4];
00661    float col_energy[4];
00662    int i;
00663    int j;
00664    int sample;
00665    short samp;
00666    int best_row;
00667    int best_col;
00668    int hit;
00669    int limit;
00670    fragment_t mute = {0, 0};
00671 
00672    if (squelch && s->td.dtmf.mute_samples > 0) {
00673       mute.end = (s->td.dtmf.mute_samples < samples) ? s->td.dtmf.mute_samples : samples;
00674       s->td.dtmf.mute_samples -= mute.end;
00675    }
00676 
00677    hit = 0;
00678    for (sample = 0; sample < samples; sample = limit) {
00679       /* DTMF_GSIZE is optimised to meet the DTMF specs. */
00680       if ((samples - sample) >= (DTMF_GSIZE - s->td.dtmf.current_sample)) {
00681          limit = sample + (DTMF_GSIZE - s->td.dtmf.current_sample);
00682       } else {
00683          limit = samples;
00684       }
00685       /* The following unrolled loop takes only 35% (rough estimate) of the 
00686          time of a rolled loop on the machine on which it was developed */
00687       for (j = sample; j < limit; j++) {
00688          samp = amp[j];
00689          s->td.dtmf.energy += (int32_t) samp * (int32_t) samp;
00690          /* With GCC 2.95, the following unrolled code seems to take about 35%
00691             (rough estimate) as long as a neat little 0-3 loop */
00692          goertzel_sample(s->td.dtmf.row_out, samp);
00693          goertzel_sample(s->td.dtmf.col_out, samp);
00694          goertzel_sample(s->td.dtmf.row_out + 1, samp);
00695          goertzel_sample(s->td.dtmf.col_out + 1, samp);
00696          goertzel_sample(s->td.dtmf.row_out + 2, samp);
00697          goertzel_sample(s->td.dtmf.col_out + 2, samp);
00698          goertzel_sample(s->td.dtmf.row_out + 3, samp);
00699          goertzel_sample(s->td.dtmf.col_out + 3, samp);
00700       }
00701       s->td.dtmf.current_sample += (limit - sample);
00702       if (s->td.dtmf.current_sample < DTMF_GSIZE) {
00703          continue;
00704       }
00705       /* We are at the end of a DTMF detection block */
00706       /* Find the peak row and the peak column */
00707       row_energy[0] = goertzel_result (&s->td.dtmf.row_out[0]);
00708       col_energy[0] = goertzel_result (&s->td.dtmf.col_out[0]);
00709 
00710       for (best_row = best_col = 0, i = 1;  i < 4;  i++) {
00711          row_energy[i] = goertzel_result (&s->td.dtmf.row_out[i]);
00712          if (row_energy[i] > row_energy[best_row]) {
00713             best_row = i;
00714          }
00715          col_energy[i] = goertzel_result (&s->td.dtmf.col_out[i]);
00716          if (col_energy[i] > col_energy[best_col]) {
00717             best_col = i;
00718          }
00719       }
00720       hit = 0;
00721       /* Basic signal level test and the twist test */
00722       if (row_energy[best_row] >= DTMF_THRESHOLD && 
00723           col_energy[best_col] >= DTMF_THRESHOLD &&
00724           col_energy[best_col] < row_energy[best_row] * (relax ? relax_dtmf_reverse_twist : dtmf_reverse_twist) &&
00725           row_energy[best_row] < col_energy[best_col] * (relax ? relax_dtmf_normal_twist : dtmf_normal_twist)) {
00726          /* Relative peak test */
00727          for (i = 0;  i < 4;  i++) {
00728             if ((i != best_col &&
00729                 col_energy[i] * DTMF_RELATIVE_PEAK_COL > col_energy[best_col]) ||
00730                 (i != best_row 
00731                  && row_energy[i] * DTMF_RELATIVE_PEAK_ROW > row_energy[best_row])) {
00732                break;
00733             }
00734          }
00735          /* ... and fraction of total energy test */
00736          if (i >= 4 &&
00737              (row_energy[best_row] + col_energy[best_col]) > DTMF_TO_TOTAL_ENERGY * s->td.dtmf.energy) {
00738             /* Got a hit */
00739             hit = dtmf_positions[(best_row << 2) + best_col];
00740          }
00741       } 
00742 
00743 /*
00744  * Adapted from ETSI ES 201 235-3 V1.3.1 (2006-03)
00745  * (40ms reference is tunable with hits_to_begin and misses_to_end)
00746  * each hit/miss is 12.75ms with DTMF_GSIZE at 102
00747  *
00748  * Character recognition: When not DRC *(1) and then
00749  *      Shall exist VSC > 40 ms (hits_to_begin)
00750  *      May exist 20 ms <= VSC <= 40 ms
00751  *      Shall not exist VSC < 20 ms
00752  *
00753  * Character recognition: When DRC and then
00754  *      Shall cease Not VSC > 40 ms (misses_to_end)
00755  *      May cease 20 ms >= Not VSC >= 40 ms
00756  *      Shall not cease Not VSC < 20 ms
00757  *
00758  * *(1) or optionally a different digit recognition condition
00759  *
00760  * Legend: VSC The continuous existence of a valid signal condition.
00761  *      Not VSC The continuous non-existence of valid signal condition.
00762  *      DRC The existence of digit recognition condition.
00763  *      Not DRC The non-existence of digit recognition condition.
00764  */
00765 
00766 /*
00767  * Example: hits_to_begin=2 misses_to_end=3
00768  * -------A last_hit=A hits=0&1
00769  * ------AA hits=2 current_hit=A misses=0       BEGIN A
00770  * -----AA- misses=1 last_hit=' ' hits=0
00771  * ----AA-- misses=2
00772  * ---AA--- misses=3 current_hit=' '            END A
00773  * --AA---B last_hit=B hits=0&1
00774  * -AA---BC last_hit=C hits=0&1
00775  * AA---BCC hits=2 current_hit=C misses=0       BEGIN C
00776  * A---BCC- misses=1 last_hit=' ' hits=0
00777  * ---BCC-C misses=0 last_hit=C hits=0&1
00778  * --BCC-CC misses=0
00779  *
00780  * Example: hits_to_begin=3 misses_to_end=2
00781  * -------A last_hit=A hits=0&1
00782  * ------AA hits=2
00783  * -----AAA hits=3 current_hit=A misses=0       BEGIN A
00784  * ----AAAB misses=1 last_hit=B hits=0&1
00785  * ---AAABB misses=2 current_hit=' ' hits=2     END A
00786  * --AAABBB hits=3 current_hit=B misses=0       BEGIN B
00787  * -AAABBBB misses=0
00788  *
00789  * Example: hits_to_begin=2 misses_to_end=2
00790  * -------A last_hit=A hits=0&1
00791  * ------AA hits=2 current_hit=A misses=0       BEGIN A
00792  * -----AAB misses=1 hits=0&1
00793  * ----AABB misses=2 current_hit=' ' hits=2 current_hit=B misses=0 BEGIN B
00794  * ---AABBB misses=0
00795  */
00796 
00797       if (s->td.dtmf.current_hit) {
00798          /* We are in the middle of a digit already */
00799          if (hit != s->td.dtmf.current_hit) {
00800             s->td.dtmf.misses++;
00801             if (s->td.dtmf.misses == dtmf_misses_to_end) {
00802                /* There were enough misses to consider digit ended */
00803                s->td.dtmf.current_hit = 0;
00804             }
00805          } else {
00806             s->td.dtmf.misses = 0;
00807             /* Current hit was same as last, so increment digit duration (of last digit) */
00808             s->digitlen[s->current_digits - 1] += DTMF_GSIZE;
00809          }
00810       }
00811 
00812       /* Look for a start of a new digit no matter if we are already in the middle of some
00813          digit or not. This is because hits_to_begin may be smaller than misses_to_end
00814          and we may find begin of new digit before we consider last one ended. */
00815 
00816       if (hit != s->td.dtmf.lasthit) {
00817          s->td.dtmf.lasthit = hit;
00818          s->td.dtmf.hits = 0;
00819       }
00820       if (hit && hit != s->td.dtmf.current_hit) {
00821          s->td.dtmf.hits++;
00822          if (s->td.dtmf.hits == dtmf_hits_to_begin) {
00823             store_digit(s, hit);
00824             s->digitlen[s->current_digits - 1] = dtmf_hits_to_begin * DTMF_GSIZE;
00825             s->td.dtmf.current_hit = hit;
00826             s->td.dtmf.misses = 0;
00827          }
00828       }
00829 
00830       /* If we had a hit in this block, include it into mute fragment */
00831       if (squelch && hit) {
00832          if (mute.end < sample - DTMF_GSIZE) {
00833             /* There is a gap between fragments */
00834             mute_fragment(dsp, &mute);
00835             mute.start = (sample > DTMF_GSIZE) ? (sample - DTMF_GSIZE) : 0;
00836          }
00837          mute.end = limit + DTMF_GSIZE;
00838       }
00839 
00840       /* Reinitialise the detector for the next block */
00841       for (i = 0; i < 4; i++) {
00842          goertzel_reset(&s->td.dtmf.row_out[i]);
00843          goertzel_reset(&s->td.dtmf.col_out[i]);
00844       }
00845       s->td.dtmf.energy = 0.0;
00846       s->td.dtmf.current_sample = 0;
00847    }
00848 
00849    if (squelch && mute.end) {
00850       if (mute.end > samples) {
00851          s->td.dtmf.mute_samples = mute.end - samples;
00852          mute.end = samples;
00853       }
00854       mute_fragment(dsp, &mute);
00855    }
00856 
00857    return (s->td.dtmf.current_hit); /* return the debounced hit */
00858 }
00859 
00860 static int mf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[],
00861                  int samples, int squelch, int relax)
00862 {
00863    float energy[6];
00864    int best;
00865    int second_best;
00866    int i;
00867    int j;
00868    int sample;
00869    short samp;
00870    int hit;
00871    int limit;
00872    fragment_t mute = {0, 0};
00873 
00874    if (squelch && s->td.mf.mute_samples > 0) {
00875       mute.end = (s->td.mf.mute_samples < samples) ? s->td.mf.mute_samples : samples;
00876       s->td.mf.mute_samples -= mute.end;
00877    }
00878 
00879    hit = 0;
00880    for (sample = 0;  sample < samples;  sample = limit) {
00881       /* 80 is optimised to meet the MF specs. */
00882       /* XXX So then why is MF_GSIZE defined as 120? */
00883       if ((samples - sample) >= (MF_GSIZE - s->td.mf.current_sample)) {
00884          limit = sample + (MF_GSIZE - s->td.mf.current_sample);
00885       } else {
00886          limit = samples;
00887       }
00888       /* The following unrolled loop takes only 35% (rough estimate) of the 
00889          time of a rolled loop on the machine on which it was developed */
00890       for (j = sample;  j < limit;  j++) {
00891          /* With GCC 2.95, the following unrolled code seems to take about 35%
00892             (rough estimate) as long as a neat little 0-3 loop */
00893          samp = amp[j];
00894          goertzel_sample(s->td.mf.tone_out, samp);
00895          goertzel_sample(s->td.mf.tone_out + 1, samp);
00896          goertzel_sample(s->td.mf.tone_out + 2, samp);
00897          goertzel_sample(s->td.mf.tone_out + 3, samp);
00898          goertzel_sample(s->td.mf.tone_out + 4, samp);
00899          goertzel_sample(s->td.mf.tone_out + 5, samp);
00900       }
00901       s->td.mf.current_sample += (limit - sample);
00902       if (s->td.mf.current_sample < MF_GSIZE) {
00903          continue;
00904       }
00905       /* We're at the end of an MF detection block.  */
00906       /* Find the two highest energies. The spec says to look for
00907          two tones and two tones only. Taking this literally -ie
00908          only two tones pass the minimum threshold - doesn't work
00909          well. The sinc function mess, due to rectangular windowing
00910          ensure that! Find the two highest energies and ensure they
00911          are considerably stronger than any of the others. */
00912       energy[0] = goertzel_result(&s->td.mf.tone_out[0]);
00913       energy[1] = goertzel_result(&s->td.mf.tone_out[1]);
00914       if (energy[0] > energy[1]) {
00915          best = 0;
00916          second_best = 1;
00917       } else {
00918          best = 1;
00919          second_best = 0;
00920       }
00921       /*endif*/
00922       for (i = 2; i < 6; i++) {
00923          energy[i] = goertzel_result(&s->td.mf.tone_out[i]);
00924          if (energy[i] >= energy[best]) {
00925             second_best = best;
00926             best = i;
00927          } else if (energy[i] >= energy[second_best]) {
00928             second_best = i;
00929          }
00930       }
00931       /* Basic signal level and twist tests */
00932       hit = 0;
00933       if (energy[best] >= BELL_MF_THRESHOLD && energy[second_best] >= BELL_MF_THRESHOLD
00934                && energy[best] < energy[second_best]*BELL_MF_TWIST
00935                && energy[best] * BELL_MF_TWIST > energy[second_best]) {
00936          /* Relative peak test */
00937          hit = -1;
00938          for (i = 0; i < 6; i++) {
00939             if (i != best && i != second_best) {
00940                if (energy[i]*BELL_MF_RELATIVE_PEAK >= energy[second_best]) {
00941                   /* The best two are not clearly the best */
00942                   hit = 0;
00943                   break;
00944                }
00945             }
00946          }
00947       }
00948       if (hit) {
00949          /* Get the values into ascending order */
00950          if (second_best < best) {
00951             i = best;
00952             best = second_best;
00953             second_best = i;
00954          }
00955          best = best * 5 + second_best - 1;
00956          hit = bell_mf_positions[best];
00957          /* Look for two successive similar results */
00958          /* The logic in the next test is:
00959             For KP we need 4 successive identical clean detects, with
00960             two blocks of something different preceeding it. For anything
00961             else we need two successive identical clean detects, with
00962             two blocks of something different preceeding it. */
00963          if (hit == s->td.mf.hits[4] && hit == s->td.mf.hits[3] &&
00964             ((hit != '*' && hit != s->td.mf.hits[2] && hit != s->td.mf.hits[1])||
00965              (hit == '*' && hit == s->td.mf.hits[2] && hit != s->td.mf.hits[1] && 
00966              hit != s->td.mf.hits[0]))) {
00967             store_digit(s, hit);
00968          }
00969       }
00970 
00971 
00972       if (hit != s->td.mf.hits[4] && hit != s->td.mf.hits[3]) {
00973          /* Two successive block without a hit terminate current digit */
00974          s->td.mf.current_hit = 0;
00975       }
00976 
00977       s->td.mf.hits[0] = s->td.mf.hits[1];
00978       s->td.mf.hits[1] = s->td.mf.hits[2];
00979       s->td.mf.hits[2] = s->td.mf.hits[3];
00980       s->td.mf.hits[3] = s->td.mf.hits[4];
00981       s->td.mf.hits[4] = hit;
00982 
00983       /* If we had a hit in this block, include it into mute fragment */
00984       if (squelch && hit) {
00985          if (mute.end < sample - MF_GSIZE) {
00986             /* There is a gap between fragments */
00987             mute_fragment(dsp, &mute);
00988             mute.start = (sample > MF_GSIZE) ? (sample - MF_GSIZE) : 0;
00989          }
00990          mute.end = limit + MF_GSIZE;
00991       }
00992 
00993       /* Reinitialise the detector for the next block */
00994       for (i = 0;  i < 6;  i++)
00995          goertzel_reset(&s->td.mf.tone_out[i]);
00996       s->td.mf.current_sample = 0;
00997    }
00998 
00999    if (squelch && mute.end) {
01000       if (mute.end > samples) {
01001          s->td.mf.mute_samples = mute.end - samples;
01002          mute.end = samples;
01003       }
01004       mute_fragment(dsp, &mute);
01005    }
01006 
01007    return (s->td.mf.current_hit); /* return the debounced hit */
01008 }
01009 
01010 static inline int pair_there(float p1, float p2, float i1, float i2, float e)
01011 {
01012    /* See if p1 and p2 are there, relative to i1 and i2 and total energy */
01013    /* Make sure absolute levels are high enough */
01014    if ((p1 < TONE_MIN_THRESH) || (p2 < TONE_MIN_THRESH)) {
01015       return 0;
01016    }
01017    /* Amplify ignored stuff */
01018    i2 *= TONE_THRESH;
01019    i1 *= TONE_THRESH;
01020    e *= TONE_THRESH;
01021    /* Check first tone */
01022    if ((p1 < i1) || (p1 < i2) || (p1 < e)) {
01023       return 0;
01024    }
01025    /* And second */
01026    if ((p2 < i1) || (p2 < i2) || (p2 < e)) {
01027       return 0;
01028    }
01029    /* Guess it's there... */
01030    return 1;
01031 }
01032 
01033 static int __ast_dsp_call_progress(struct ast_dsp *dsp, short *s, int len)
01034 {
01035    int x;
01036    int y;
01037    int pass;
01038    int newstate = DSP_TONE_STATE_SILENCE;
01039    int res = 0;
01040    while (len) {
01041       /* Take the lesser of the number of samples we need and what we have */
01042       pass = len;
01043       if (pass > dsp->gsamp_size - dsp->gsamps) {
01044          pass = dsp->gsamp_size - dsp->gsamps;
01045       }
01046       for (x = 0; x < pass; x++) {
01047          for (y = 0; y < dsp->freqcount; y++) {
01048             goertzel_sample(&dsp->freqs[y], s[x]);
01049          }
01050          dsp->genergy += s[x] * s[x];
01051       }
01052       s += pass;
01053       dsp->gsamps += pass;
01054       len -= pass;
01055       if (dsp->gsamps == dsp->gsamp_size) {
01056          float hz[7];
01057          for (y = 0; y < 7; y++) {
01058             hz[y] = goertzel_result(&dsp->freqs[y]);
01059          }
01060          switch (dsp->progmode) {
01061          case PROG_MODE_NA:
01062             if (pair_there(hz[HZ_480], hz[HZ_620], hz[HZ_350], hz[HZ_440], dsp->genergy)) {
01063                newstate = DSP_TONE_STATE_BUSY;
01064             } else if (pair_there(hz[HZ_440], hz[HZ_480], hz[HZ_350], hz[HZ_620], dsp->genergy)) {
01065                newstate = DSP_TONE_STATE_RINGING;
01066             } else if (pair_there(hz[HZ_350], hz[HZ_440], hz[HZ_480], hz[HZ_620], dsp->genergy)) {
01067                newstate = DSP_TONE_STATE_DIALTONE;
01068             } else if (hz[HZ_950] > TONE_MIN_THRESH * TONE_THRESH) {
01069                newstate = DSP_TONE_STATE_SPECIAL1;
01070             } else if (hz[HZ_1400] > TONE_MIN_THRESH * TONE_THRESH) {
01071                /* End of SPECIAL1 or middle of SPECIAL2 */
01072                if (dsp->tstate == DSP_TONE_STATE_SPECIAL1 || dsp->tstate == DSP_TONE_STATE_SPECIAL2) {
01073                   newstate = DSP_TONE_STATE_SPECIAL2;
01074                }
01075             } else if (hz[HZ_1800] > TONE_MIN_THRESH * TONE_THRESH) {
01076                /* End of SPECIAL2 or middle of SPECIAL3 */
01077                if (dsp->tstate == DSP_TONE_STATE_SPECIAL2 || dsp->tstate == DSP_TONE_STATE_SPECIAL3) {
01078                   newstate = DSP_TONE_STATE_SPECIAL3;
01079                }
01080             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01081                newstate = DSP_TONE_STATE_TALKING;
01082             } else {
01083                newstate = DSP_TONE_STATE_SILENCE;
01084             }
01085             break;
01086          case PROG_MODE_CR:
01087             if (hz[HZ_425] > TONE_MIN_THRESH * TONE_THRESH) {
01088                newstate = DSP_TONE_STATE_RINGING;
01089             } else if (dsp->genergy > TONE_MIN_THRESH * TONE_THRESH) {
01090                newstate = DSP_TONE_STATE_TALKING;
01091             } else {
01092                newstate = DSP_TONE_STATE_SILENCE;
01093             }
01094             break;
01095          case PROG_MODE_UK:
01096             if (hz[HZ_400UK] > TONE_MIN_THRESH * TONE_THRESH) {
01097                newstate = DSP_TONE_STATE_HUNGUP;
01098             } else if (pair_there(hz[HZ_350UK], hz[HZ_440UK], hz[HZ_400UK], hz[HZ_400UK], dsp->genergy)) {
01099                newstate = DSP_TONE_STATE_DIALTONE;
01100             }
01101             break;
01102          default:
01103             ast_log(LOG_WARNING, "Can't process in unknown prog mode '%d'\n", dsp->progmode);
01104          }
01105          if (newstate == dsp->tstate) {
01106             dsp->tcount++;
01107             if (dsp->ringtimeout) {
01108                dsp->ringtimeout++;
01109             }
01110             switch (dsp->tstate) {
01111             case DSP_TONE_STATE_RINGING:
01112                if ((dsp->features & DSP_PROGRESS_RINGING) &&
01113                    (dsp->tcount == THRESH_RING)) {
01114                   res = AST_CONTROL_RINGING;
01115                   dsp->ringtimeout = 1;
01116                }
01117                break;
01118             case DSP_TONE_STATE_BUSY:
01119                if ((dsp->features & DSP_PROGRESS_BUSY) &&
01120                    (dsp->tcount == THRESH_BUSY)) {
01121                   res = AST_CONTROL_BUSY;
01122                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01123                }
01124                break;
01125             case DSP_TONE_STATE_TALKING:
01126                if ((dsp->features & DSP_PROGRESS_TALK) &&
01127                    (dsp->tcount == THRESH_TALK)) {
01128                   res = AST_CONTROL_ANSWER;
01129                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01130                }
01131                break;
01132             case DSP_TONE_STATE_SPECIAL3:
01133                if ((dsp->features & DSP_PROGRESS_CONGESTION) &&
01134                    (dsp->tcount == THRESH_CONGESTION)) {
01135                   res = AST_CONTROL_CONGESTION;
01136                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01137                }
01138                break;
01139             case DSP_TONE_STATE_HUNGUP:
01140                if ((dsp->features & DSP_FEATURE_CALL_PROGRESS) &&
01141                    (dsp->tcount == THRESH_HANGUP)) {
01142                   res = AST_CONTROL_HANGUP;
01143                   dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01144                }
01145                break;
01146             }
01147             if (dsp->ringtimeout == THRESH_RING2ANSWER) {
01148                ast_debug(1, "Consider call as answered because of timeout after last ring\n");
01149                res = AST_CONTROL_ANSWER;
01150                dsp->features &= ~DSP_FEATURE_CALL_PROGRESS;
01151             }
01152          } else {
01153             ast_debug(5, "Stop state %d with duration %d\n", dsp->tstate, dsp->tcount);
01154             ast_debug(5, "Start state %d\n", newstate);
01155             dsp->tstate = newstate;
01156             dsp->tcount = 1;
01157          }
01158 
01159          /* Reset goertzel */
01160          for (x = 0; x < 7; x++) {
01161             dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01162          }
01163          dsp->gsamps = 0;
01164          dsp->genergy = 0.0;
01165       }
01166    }
01167 
01168    return res;
01169 }
01170 
01171 int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
01172 {
01173    if (inf->frametype != AST_FRAME_VOICE) {
01174       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01175       return 0;
01176    }
01177    if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
01178       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01179       return 0;
01180    }
01181    return __ast_dsp_call_progress(dsp, inf->data.ptr, inf->datalen / 2);
01182 }
01183 
01184 static int __ast_dsp_silence_noise(struct ast_dsp *dsp, short *s, int len, int *totalsilence, int *totalnoise)
01185 {
01186    int accum;
01187    int x;
01188    int res = 0;
01189 
01190    if (!len) {
01191       return 0;
01192    }
01193    accum = 0;
01194    for (x = 0; x < len; x++) {
01195       accum += abs(s[x]);
01196    }
01197    accum /= len;
01198    if (accum < dsp->threshold) {
01199       /* Silent */
01200       dsp->totalsilence += len / 8;
01201       if (dsp->totalnoise) {
01202          /* Move and save history */
01203          memmove(dsp->historicnoise + DSP_HISTORY - dsp->busycount, dsp->historicnoise + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicnoise[0]));
01204          dsp->historicnoise[DSP_HISTORY - 1] = dsp->totalnoise;
01205 /* we don't want to check for busydetect that frequently */
01206 #if 0
01207          dsp->busymaybe = 1;
01208 #endif
01209       }
01210       dsp->totalnoise = 0;
01211       res = 1;
01212    } else {
01213       /* Not silent */
01214       dsp->totalnoise += len / 8;
01215       if (dsp->totalsilence) {
01216          int silence1 = dsp->historicsilence[DSP_HISTORY - 1];
01217          int silence2 = dsp->historicsilence[DSP_HISTORY - 2];
01218          /* Move and save history */
01219          memmove(dsp->historicsilence + DSP_HISTORY - dsp->busycount, dsp->historicsilence + DSP_HISTORY - dsp->busycount + 1, dsp->busycount * sizeof(dsp->historicsilence[0]));
01220          dsp->historicsilence[DSP_HISTORY - 1] = dsp->totalsilence;
01221          /* check if the previous sample differs only by BUSY_PERCENT from the one before it */
01222          if (silence1 < silence2) {
01223             if (silence1 + silence1 * BUSY_PERCENT / 100 >= silence2) {
01224                dsp->busymaybe = 1;
01225             } else {
01226                dsp->busymaybe = 0;
01227             }
01228          } else {
01229             if (silence1 - silence1 * BUSY_PERCENT / 100 <= silence2) {
01230                dsp->busymaybe = 1;
01231             } else {
01232                dsp->busymaybe = 0;
01233             }
01234          }
01235       }
01236       dsp->totalsilence = 0;
01237    }
01238    if (totalsilence) {
01239       *totalsilence = dsp->totalsilence;
01240    }
01241    if (totalnoise) {
01242       *totalnoise = dsp->totalnoise;
01243    }
01244    return res;
01245 }
01246 
01247 int ast_dsp_busydetect(struct ast_dsp *dsp)
01248 {
01249    int res = 0, x;
01250 #ifndef BUSYDETECT_TONEONLY
01251    int avgsilence = 0, hitsilence = 0;
01252 #endif
01253    int avgtone = 0, hittone = 0;
01254    if (!dsp->busymaybe) {
01255       return res;
01256    }
01257    for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01258 #ifndef BUSYDETECT_TONEONLY
01259       avgsilence += dsp->historicsilence[x];
01260 #endif
01261       avgtone += dsp->historicnoise[x];
01262    }
01263 #ifndef BUSYDETECT_TONEONLY
01264    avgsilence /= dsp->busycount;
01265 #endif
01266    avgtone /= dsp->busycount;
01267    for (x = DSP_HISTORY - dsp->busycount; x < DSP_HISTORY; x++) {
01268 #ifndef BUSYDETECT_TONEONLY
01269       if (avgsilence > dsp->historicsilence[x]) {
01270          if (avgsilence - (avgsilence * BUSY_PERCENT / 100) <= dsp->historicsilence[x]) {
01271             hitsilence++;
01272          }
01273       } else {
01274          if (avgsilence + (avgsilence * BUSY_PERCENT / 100) >= dsp->historicsilence[x]) {
01275             hitsilence++;
01276          }
01277       }
01278 #endif
01279       if (avgtone > dsp->historicnoise[x]) {
01280          if (avgtone - (avgtone * BUSY_PERCENT / 100) <= dsp->historicnoise[x]) {
01281             hittone++;
01282          }
01283       } else {
01284          if (avgtone + (avgtone * BUSY_PERCENT / 100) >= dsp->historicnoise[x]) {
01285             hittone++;
01286          }
01287       }
01288    }
01289 #ifndef BUSYDETECT_TONEONLY
01290    if ((hittone >= dsp->busycount - 1) && (hitsilence >= dsp->busycount - 1) && 
01291        (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX) && 
01292        (avgsilence >= BUSY_MIN && avgsilence <= BUSY_MAX)) {
01293 #else
01294    if ((hittone >= dsp->busycount - 1) && (avgtone >= BUSY_MIN && avgtone <= BUSY_MAX)) {
01295 #endif
01296 #ifdef BUSYDETECT_COMPARE_TONE_AND_SILENCE
01297       if (avgtone > avgsilence) {
01298          if (avgtone - avgtone*BUSY_PERCENT/100 <= avgsilence) {
01299             res = 1;
01300          }
01301       } else {
01302          if (avgtone + avgtone*BUSY_PERCENT/100 >= avgsilence) {
01303             res = 1;
01304          }
01305       }
01306 #else
01307       res = 1;
01308 #endif
01309    }
01310    /* If we know the expected busy tone length, check we are in the range */
01311    if (res && (dsp->busy_tonelength > 0)) {
01312       if (abs(avgtone - dsp->busy_tonelength) > MAX(dsp->busy_tonelength*BUSY_PAT_PERCENT/100, 20)) {
01313 #ifdef BUSYDETECT_DEBUG
01314          ast_debug(5, "busy detector: avgtone of %d not close enough to desired %d\n",
01315             avgtone, dsp->busy_tonelength);
01316 #endif
01317          res = 0;
01318       }
01319    }
01320 #ifndef BUSYDETECT_TONEONLY
01321    /* If we know the expected busy tone silent-period length, check we are in the range */
01322    if (res && (dsp->busy_quietlength > 0)) {
01323       if (abs(avgsilence - dsp->busy_quietlength) > MAX(dsp->busy_quietlength*BUSY_PAT_PERCENT/100, 20)) {
01324 #ifdef BUSYDETECT_DEBUG
01325       ast_debug(5, "busy detector: avgsilence of %d not close enough to desired %d\n",
01326          avgsilence, dsp->busy_quietlength);
01327 #endif
01328          res = 0;
01329       }
01330    }
01331 #endif
01332 #if !defined(BUSYDETECT_TONEONLY) && defined(BUSYDETECT_DEBUG)
01333    if (res) {
01334       ast_debug(5, "ast_dsp_busydetect detected busy, avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01335    } else {
01336       ast_debug(5, "busy detector: FAILED with avgtone: %d, avgsilence %d\n", avgtone, avgsilence);
01337    }
01338 #endif
01339    return res;
01340 }
01341 
01342 int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
01343 {
01344    short *s;
01345    int len;
01346    
01347    if (f->frametype != AST_FRAME_VOICE) {
01348       ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01349       return 0;
01350    }
01351    if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01352       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01353       return 0;
01354    }
01355    s = f->data.ptr;
01356    len = f->datalen/2;
01357    return __ast_dsp_silence_noise(dsp, s, len, totalsilence, NULL);
01358 }
01359 
01360 int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
01361 {
01362        short *s;
01363        int len;
01364 
01365        if (f->frametype != AST_FRAME_VOICE) {
01366                ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
01367                return 0;
01368        }
01369        if (f->subclass.codec != AST_FORMAT_SLINEAR) {
01370                ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
01371                return 0;
01372        }
01373        s = f->data.ptr;
01374        len = f->datalen/2;
01375        return __ast_dsp_silence_noise(dsp, s, len, NULL, totalnoise);
01376 }
01377 
01378 
01379 struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *af)
01380 {
01381    int silence;
01382    int res;
01383    int digit = 0, fax_digit = 0;
01384    int x;
01385    short *shortdata;
01386    unsigned char *odata;
01387    int len;
01388    struct ast_frame *outf = NULL;
01389 
01390    if (!af) {
01391       return NULL;
01392    }
01393    if (af->frametype != AST_FRAME_VOICE) {
01394       return af;
01395    }
01396 
01397    odata = af->data.ptr;
01398    len = af->datalen;
01399    /* Make sure we have short data */
01400    switch (af->subclass.codec) {
01401    case AST_FORMAT_SLINEAR:
01402       shortdata = af->data.ptr;
01403       len = af->datalen / 2;
01404       break;
01405    case AST_FORMAT_ULAW:
01406    case AST_FORMAT_TESTLAW:
01407       shortdata = ast_alloca(af->datalen * 2);
01408       for (x = 0;x < len; x++) {
01409          shortdata[x] = AST_MULAW(odata[x]);
01410       }
01411       break;
01412    case AST_FORMAT_ALAW:
01413       shortdata = ast_alloca(af->datalen * 2);
01414       for (x = 0; x < len; x++) {
01415          shortdata[x] = AST_ALAW(odata[x]);
01416       }
01417       break;
01418    default:
01419       /*Display warning only once. Otherwise you would get hundreds of warnings every second */
01420       if (dsp->display_inband_dtmf_warning)
01421          ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
01422       dsp->display_inband_dtmf_warning = 0;
01423       return af;
01424    }
01425 
01426    /* Initially we do not want to mute anything */
01427    dsp->mute_fragments = 0;
01428 
01429    /* Need to run the silence detection stuff for silence suppression and busy detection */
01430    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) || (dsp->features & DSP_FEATURE_BUSY_DETECT)) {
01431       res = __ast_dsp_silence_noise(dsp, shortdata, len, &silence, NULL);
01432    }
01433 
01434    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01435       memset(&dsp->f, 0, sizeof(dsp->f));
01436       dsp->f.frametype = AST_FRAME_NULL;
01437       ast_frfree(af);
01438       return ast_frisolate(&dsp->f);
01439    }
01440    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01441       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01442       memset(&dsp->f, 0, sizeof(dsp->f));
01443       dsp->f.frametype = AST_FRAME_CONTROL;
01444       dsp->f.subclass.integer = AST_CONTROL_BUSY;
01445       ast_frfree(af);
01446       ast_debug(1, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01447       return ast_frisolate(&dsp->f);
01448    }
01449 
01450    if ((dsp->features & DSP_FEATURE_FAX_DETECT)) {
01451       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CNG) && tone_detect(dsp, &dsp->cng_tone_state, shortdata, len)) {
01452          fax_digit = 'f';
01453       }
01454 
01455       if ((dsp->faxmode & DSP_FAXMODE_DETECT_CED) && tone_detect(dsp, &dsp->ced_tone_state, shortdata, len)) {
01456          fax_digit = 'e';
01457       }
01458    }
01459 
01460    if (dsp->features & (DSP_FEATURE_DIGIT_DETECT | DSP_FEATURE_BUSY_DETECT)) {
01461       if (dsp->digitmode & DSP_DIGITMODE_MF)
01462          digit = mf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01463       else
01464          digit = dtmf_detect(dsp, &dsp->digit_state, shortdata, len, (dsp->digitmode & DSP_DIGITMODE_NOQUELCH) == 0, (dsp->digitmode & DSP_DIGITMODE_RELAXDTMF));
01465 
01466       if (dsp->digit_state.current_digits) {
01467          int event = 0, event_len = 0;
01468          char event_digit = 0;
01469 
01470          if (!dsp->dtmf_began) {
01471             /* We have not reported DTMF_BEGIN for anything yet */
01472 
01473             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01474                event = AST_FRAME_DTMF_BEGIN;
01475                event_digit = dsp->digit_state.digits[0];
01476             }
01477             dsp->dtmf_began = 1;
01478 
01479          } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) {
01480             /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */
01481             if (dsp->features & DSP_FEATURE_DIGIT_DETECT) {
01482                event = AST_FRAME_DTMF_END;
01483                event_digit = dsp->digit_state.digits[0];
01484                event_len = dsp->digit_state.digitlen[0] * 1000 / SAMPLE_RATE;
01485             }
01486             memmove(&dsp->digit_state.digits[0], &dsp->digit_state.digits[1], dsp->digit_state.current_digits);
01487             memmove(&dsp->digit_state.digitlen[0], &dsp->digit_state.digitlen[1], dsp->digit_state.current_digits * sizeof(dsp->digit_state.digitlen[0]));
01488             dsp->digit_state.current_digits--;
01489             dsp->dtmf_began = 0;
01490 
01491             if (dsp->features & DSP_FEATURE_BUSY_DETECT) {
01492                /* Reset Busy Detector as we have some confirmed activity */ 
01493                memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01494                memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01495                ast_debug(1, "DTMF Detected - Reset busydetector\n");
01496             }
01497          }
01498 
01499          if (event) {
01500             memset(&dsp->f, 0, sizeof(dsp->f));
01501             dsp->f.frametype = event;
01502             dsp->f.subclass.integer = event_digit;
01503             dsp->f.len = event_len;
01504             outf = &dsp->f;
01505             goto done;
01506          }
01507       }
01508    }
01509 
01510    if (fax_digit) {
01511       /* Fax was detected - digit is either 'f' or 'e' */
01512 
01513       memset(&dsp->f, 0, sizeof(dsp->f));
01514       dsp->f.frametype = AST_FRAME_DTMF;
01515       dsp->f.subclass.integer = fax_digit;
01516       outf = &dsp->f;
01517       goto done;
01518    }
01519 
01520    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01521       res = __ast_dsp_call_progress(dsp, shortdata, len);
01522       if (res) {
01523          switch (res) {
01524          case AST_CONTROL_ANSWER:
01525          case AST_CONTROL_BUSY:
01526          case AST_CONTROL_RINGING:
01527          case AST_CONTROL_CONGESTION:
01528          case AST_CONTROL_HANGUP:
01529             memset(&dsp->f, 0, sizeof(dsp->f));
01530             dsp->f.frametype = AST_FRAME_CONTROL;
01531             dsp->f.subclass.integer = res;
01532             dsp->f.src = "dsp_progress";
01533             if (chan) 
01534                ast_queue_frame(chan, &dsp->f);
01535             break;
01536          default:
01537             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01538          }
01539       }
01540    } else if ((dsp->features & DSP_FEATURE_WAITDIALTONE)) {
01541       res = __ast_dsp_call_progress(dsp, shortdata, len);
01542    }
01543 
01544 done:
01545    /* Mute fragment of the frame */
01546    for (x = 0; x < dsp->mute_fragments; x++) {
01547       memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
01548    }
01549 
01550    switch (af->subclass.codec) {
01551    case AST_FORMAT_SLINEAR:
01552       break;
01553    case AST_FORMAT_ULAW:
01554       for (x = 0; x < len; x++) {
01555          odata[x] = AST_LIN2MU((unsigned short) shortdata[x]);
01556       }
01557       break;
01558    case AST_FORMAT_ALAW:
01559       for (x = 0; x < len; x++) {
01560          odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
01561       }
01562       break;
01563    }
01564 
01565    if (outf) {
01566       if (chan) {
01567          ast_queue_frame(chan, af);
01568       }
01569       ast_frfree(af);
01570       return ast_frisolate(outf);
01571    } else {
01572       return af;
01573    }
01574 }
01575 
01576 static void ast_dsp_prog_reset(struct ast_dsp *dsp)
01577 {
01578    int max = 0;
01579    int x;
01580    
01581    dsp->gsamp_size = modes[dsp->progmode].size;
01582    dsp->gsamps = 0;
01583    for (x = 0; x < ARRAY_LEN(modes[dsp->progmode].freqs); x++) {
01584       if (modes[dsp->progmode].freqs[x]) {
01585          goertzel_init(&dsp->freqs[x], (float)modes[dsp->progmode].freqs[x], dsp->gsamp_size);
01586          max = x + 1;
01587       }
01588    }
01589    dsp->freqcount = max;
01590    dsp->ringtimeout= 0;
01591 }
01592 
01593 struct ast_dsp *ast_dsp_new(void)
01594 {
01595    struct ast_dsp *dsp;
01596    
01597    if ((dsp = ast_calloc(1, sizeof(*dsp)))) {      
01598       dsp->threshold = DEFAULT_THRESHOLD;
01599       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01600       dsp->busycount = DSP_HISTORY;
01601       dsp->digitmode = DSP_DIGITMODE_DTMF;
01602       dsp->faxmode = DSP_FAXMODE_DETECT_CNG;
01603       /* Initialize digit detector */
01604       ast_digit_detect_init(&dsp->digit_state, dsp->digitmode & DSP_DIGITMODE_MF);
01605       dsp->display_inband_dtmf_warning = 1;
01606       /* Initialize initial DSP progress detect parameters */
01607       ast_dsp_prog_reset(dsp);
01608       /* Initialize fax detector */
01609       ast_fax_detect_init(dsp);
01610    }
01611    return dsp;
01612 }
01613 
01614 void ast_dsp_set_features(struct ast_dsp *dsp, int features)
01615 {
01616    dsp->features = features;
01617    if (!(features & DSP_FEATURE_DIGIT_DETECT)) {
01618       dsp->display_inband_dtmf_warning = 0;
01619    }
01620 }
01621 
01622 void ast_dsp_free(struct ast_dsp *dsp)
01623 {
01624    ast_free(dsp);
01625 }
01626 
01627 void ast_dsp_set_threshold(struct ast_dsp *dsp, int threshold)
01628 {
01629    dsp->threshold = threshold;
01630 }
01631 
01632 void ast_dsp_set_busy_count(struct ast_dsp *dsp, int cadences)
01633 {
01634    if (cadences < 4) {
01635       cadences = 4;
01636    }
01637    if (cadences > DSP_HISTORY) {
01638       cadences = DSP_HISTORY;
01639    }
01640    dsp->busycount = cadences;
01641 }
01642 
01643 void ast_dsp_set_busy_pattern(struct ast_dsp *dsp, int tonelength, int quietlength)
01644 {
01645    dsp->busy_tonelength = tonelength;
01646    dsp->busy_quietlength = quietlength;
01647    ast_debug(1, "dsp busy pattern set to %d,%d\n", tonelength, quietlength);
01648 }
01649 
01650 void ast_dsp_digitreset(struct ast_dsp *dsp)
01651 {
01652    int i;
01653    
01654    dsp->dtmf_began = 0;
01655    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01656       mf_detect_state_t *s = &dsp->digit_state.td.mf;
01657       /* Reinitialise the detector for the next block */
01658       for (i = 0;  i < 6;  i++) {
01659          goertzel_reset(&s->tone_out[i]);
01660       }
01661       s->hits[4] = s->hits[3] = s->hits[2] = s->hits[1] = s->hits[0] = s->current_hit = 0;
01662       s->current_sample = 0;
01663    } else {
01664       dtmf_detect_state_t *s = &dsp->digit_state.td.dtmf;
01665       /* Reinitialise the detector for the next block */
01666       for (i = 0;  i < 4;  i++) {
01667          goertzel_reset(&s->row_out[i]);
01668          goertzel_reset(&s->col_out[i]);
01669       }
01670       s->lasthit = s->current_hit = 0;
01671       s->energy = 0.0;
01672       s->current_sample = 0;
01673       s->hits = 0;
01674       s->misses = 0;
01675    }
01676 
01677    dsp->digit_state.digits[0] = '\0';
01678    dsp->digit_state.current_digits = 0;
01679 }
01680 
01681 void ast_dsp_reset(struct ast_dsp *dsp)
01682 {
01683    int x;
01684    
01685    dsp->totalsilence = 0;
01686    dsp->gsamps = 0;
01687    for (x = 0; x < 4; x++) {
01688       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01689    }
01690    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01691    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));  
01692    dsp->ringtimeout= 0;
01693 }
01694 
01695 int ast_dsp_set_digitmode(struct ast_dsp *dsp, int digitmode)
01696 {
01697    int new;
01698    int old;
01699    
01700    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01701    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01702    if (old != new) {
01703       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01704       ast_digit_detect_init(&dsp->digit_state, new & DSP_DIGITMODE_MF);
01705    }
01706    dsp->digitmode = digitmode;
01707    return 0;
01708 }
01709 
01710 int ast_dsp_set_faxmode(struct ast_dsp *dsp, int faxmode)
01711 {
01712    if (dsp->faxmode != faxmode) {
01713       ast_fax_detect_init(dsp);
01714    }
01715    dsp->faxmode = faxmode;
01716    return 0;
01717 }
01718 
01719 int ast_dsp_set_call_progress_zone(struct ast_dsp *dsp, char *zone)
01720 {
01721    int x;
01722    
01723    for (x = 0; x < ARRAY_LEN(aliases); x++) {
01724       if (!strcasecmp(aliases[x].name, zone)) {
01725          dsp->progmode = aliases[x].mode;
01726          ast_dsp_prog_reset(dsp);
01727          return 0;
01728       }
01729    }
01730    return -1;
01731 }
01732 
01733 int ast_dsp_was_muted(struct ast_dsp *dsp)
01734 {
01735    return (dsp->mute_fragments > 0);
01736 }
01737 
01738 int ast_dsp_get_tstate(struct ast_dsp *dsp) 
01739 {
01740    return dsp->tstate;
01741 }
01742 
01743 int ast_dsp_get_tcount(struct ast_dsp *dsp) 
01744 {
01745    return dsp->tcount;
01746 }
01747 
01748 static int _dsp_init(int reload)
01749 {
01750    struct ast_config *cfg;
01751    struct ast_variable *v;
01752    struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
01753    int cfg_threshold;
01754    float cfg_twist;
01755 
01756    if ((cfg = ast_config_load2(CONFIG_FILE_NAME, "dsp", config_flags)) == CONFIG_STATUS_FILEUNCHANGED) {
01757       return 0;
01758    }
01759 
01760    thresholds[THRESHOLD_SILENCE] = DEFAULT_SILENCE_THRESHOLD;
01761    dtmf_normal_twist = DEF_DTMF_NORMAL_TWIST;
01762    dtmf_reverse_twist = DEF_DTMF_REVERSE_TWIST;
01763    relax_dtmf_normal_twist = DEF_RELAX_DTMF_NORMAL_TWIST;
01764    relax_dtmf_reverse_twist = DEF_RELAX_DTMF_REVERSE_TWIST;
01765         dtmf_hits_to_begin = DEF_DTMF_HITS_TO_BEGIN;
01766         dtmf_misses_to_end = DEF_DTMF_MISSES_TO_END;
01767 
01768    if (cfg == CONFIG_STATUS_FILEMISSING || cfg == CONFIG_STATUS_FILEINVALID) {
01769       return 0;
01770    }
01771 
01772    for (v = ast_variable_browse(cfg, "default"); v; v = v->next) {
01773       if (!strcasecmp(v->name, "silencethreshold")) {
01774          if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
01775             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01776          } else if (cfg_threshold < 0) {
01777             ast_log(LOG_WARNING, "Invalid silence threshold '%d' specified, using default\n", cfg_threshold);
01778          } else {
01779             thresholds[THRESHOLD_SILENCE] = cfg_threshold;
01780          }
01781       } else if (!strcasecmp(v->name, "dtmf_normal_twist")) {
01782          if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
01783             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01784          } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {      /* < 3.0dB or > 20dB */
01785             ast_log(LOG_WARNING, "Invalid dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_normal_twist);
01786          } else {
01787             dtmf_normal_twist = cfg_twist;
01788          }
01789       } else if (!strcasecmp(v->name, "dtmf_reverse_twist")) {
01790          if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
01791             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01792          } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {      /* < 3.0dB or > 20dB */
01793             ast_log(LOG_WARNING, "Invalid dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, dtmf_reverse_twist);
01794          } else {
01795             dtmf_reverse_twist = cfg_twist;
01796          }
01797       } else if (!strcasecmp(v->name, "relax_dtmf_normal_twist")) {
01798          if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
01799             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01800          } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {      /* < 3.0dB or > 20dB */
01801             ast_log(LOG_WARNING, "Invalid relax_dtmf_normal_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_normal_twist);
01802          } else {
01803             relax_dtmf_normal_twist = cfg_twist;
01804          }
01805       } else if (!strcasecmp(v->name, "relax_dtmf_reverse_twist")) {
01806          if (sscanf(v->value, "%30f", &cfg_twist) < 1) {
01807             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01808          } else if ((cfg_twist < 2.0) || (cfg_twist > 100.0)) {      /* < 3.0dB or > 20dB */
01809             ast_log(LOG_WARNING, "Invalid relax_dtmf_reverse_twist value '%.2f' specified, using default of %.2f\n", cfg_twist, relax_dtmf_reverse_twist);
01810          } else {
01811             relax_dtmf_reverse_twist = cfg_twist;
01812          }
01813       } else if (!strcasecmp(v->name, "dtmf_hits_to_begin")) {
01814          if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
01815             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01816          } else if (cfg_threshold < 1) {     /* must be 1 or greater */
01817             ast_log(LOG_WARNING, "Invalid dtmf_hits_to_begin value '%d' specified, using default of %d\n", cfg_threshold, dtmf_hits_to_begin);
01818          } else {
01819             dtmf_hits_to_begin = cfg_threshold;
01820          }
01821       } else if (!strcasecmp(v->name, "dtmf_misses_to_end")) {
01822          if (sscanf(v->value, "%30d", &cfg_threshold) < 1) {
01823             ast_log(LOG_WARNING, "Unable to convert '%s' to a numeric value.\n", v->value);
01824          } else if (cfg_threshold < 1) {     /* must be 1 or greater */
01825             ast_log(LOG_WARNING, "Invalid dtmf_misses_to_end value '%d' specified, using default of %d\n", cfg_threshold, dtmf_misses_to_end);
01826          } else {
01827             dtmf_misses_to_end = cfg_threshold;
01828          }
01829       }
01830    }
01831    ast_config_destroy(cfg);
01832 
01833    return 0;
01834 }
01835 
01836 int ast_dsp_get_threshold_from_settings(enum threshold which)
01837 {
01838    return thresholds[which];
01839 }
01840 
01841 int ast_dsp_init(void)
01842 {
01843    return _dsp_init(0);
01844 }
01845 
01846 int ast_dsp_reload(void)
01847 {
01848    return _dsp_init(1);
01849 }