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

Generated on Thu Apr 16 06:27:33 2015 for Asterisk - The Open Source Telephony Project by  doxygen 1.5.6