Sat Apr 26 2014 22:01:35

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