dsp.h File Reference

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Defines

#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)
#define DSP_FEATURE_BUSY_DETECT   (1 << 1)
#define DSP_FEATURE_CALL_PROGRESS   (1 << 2)
#define DSP_FEATURE_DTMF_DETECT   (1 << 3)
#define DSP_FEATURE_FAX_DETECT   (1 << 4)
#define DSP_DIGITMODE_DTMF   0
#define DSP_DIGITMODE_MF   1
#define DSP_DIGITMODE_NOQUELCH   (1 << 8)
#define DSP_DIGITMODE_MUTECONF   (1 << 9)
#define DSP_DIGITMODE_MUTEMAX   (1 << 10)
#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)

Functions

struct ast_dspast_dsp_new (void)
void ast_dsp_free (struct ast_dsp *dsp)
void ast_dsp_set_threshold (struct ast_dsp *dsp, int threshold)
void ast_dsp_set_busy_count (struct ast_dsp *dsp, int cadences)
int ast_dsp_call_progress (struct ast_dsp *dsp, struct ast_frame *inf)
int ast_dsp_set_call_progress_zone (struct ast_dsp *dsp, char *zone)
struct ast_frameast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf)
int ast_dsp_silence (struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
int ast_dsp_busydetect (struct ast_dsp *dsp)
int ast_dsp_digitdetect (struct ast_dsp *dsp, struct ast_frame *f)
void ast_dsp_reset (struct ast_dsp *dsp)
void ast_dsp_digitreset (struct ast_dsp *dsp)
void ast_dsp_set_features (struct ast_dsp *dsp, int features)
int ast_dsp_getdigits (struct ast_dsp *dsp, char *buf, int max)
int ast_dsp_digitmode (struct ast_dsp *dsp, int digitmode)


Define Documentation

#define DSP_DIGITMODE_DTMF   0

Definition at line 23 of file dsp.h.

#define DSP_DIGITMODE_MF   1

Definition at line 24 of file dsp.h.

#define DSP_DIGITMODE_MUTECONF   (1 << 9)

Definition at line 27 of file dsp.h.

#define DSP_DIGITMODE_MUTEMAX   (1 << 10)

Definition at line 28 of file dsp.h.

#define DSP_DIGITMODE_NOQUELCH   (1 << 8)

Definition at line 26 of file dsp.h.

#define DSP_DIGITMODE_RELAXDTMF   (1 << 11)

Definition at line 29 of file dsp.h.

#define DSP_FEATURE_BUSY_DETECT   (1 << 1)

Definition at line 18 of file dsp.h.

#define DSP_FEATURE_CALL_PROGRESS   (1 << 2)

Definition at line 19 of file dsp.h.

#define DSP_FEATURE_DTMF_DETECT   (1 << 3)

Definition at line 20 of file dsp.h.

#define DSP_FEATURE_FAX_DETECT   (1 << 4)

Definition at line 21 of file dsp.h.

#define DSP_FEATURE_SILENCE_SUPPRESS   (1 << 0)

Definition at line 17 of file dsp.h.


Function Documentation

int ast_dsp_busydetect ( struct ast_dsp dsp  ) 

int ast_dsp_call_progress ( struct ast_dsp dsp,
struct ast_frame inf 
)

Definition at line 1214 of file dsp.c.

01215 {
01216    if (inf->frametype != AST_FRAME_VOICE) {
01217       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01218       return 0;
01219    }
01220    if (inf->subclass != AST_FORMAT_SLINEAR) {
01221       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01222       return 0;
01223    }
01224    return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01225 }

int ast_dsp_digitdetect ( struct ast_dsp dsp,
struct ast_frame f 
)

Definition at line 1047 of file dsp.c.

01048 {
01049    short *s;
01050    int len;
01051    int ign=0;
01052    if (inf->frametype != AST_FRAME_VOICE) {
01053       ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01054       return 0;
01055    }
01056    if (inf->subclass != AST_FORMAT_SLINEAR) {
01057       ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01058       return 0;
01059    }
01060    s = inf->data;
01061    len = inf->datalen / 2;
01062    return __ast_dsp_digitdetect(dsp, s, len, &ign);
01063 }

int ast_dsp_digitmode ( struct ast_dsp dsp,
int  digitmode 
)

Definition at line 1718 of file dsp.c.

01719 {
01720    int new, old;
01721    old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01722    new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01723    if (old != new) {
01724       /* Must initialize structures if switching from MF to DTMF or vice-versa */
01725       if (new & DSP_DIGITMODE_MF)
01726          ast_mf_detect_init(&dsp->td.mf);
01727       else
01728          ast_dtmf_detect_init(&dsp->td.dtmf);
01729    }
01730    dsp->digitmode = digitmode;
01731    return 0;
01732 }

void ast_dsp_digitreset ( struct ast_dsp dsp  ) 

Definition at line 1657 of file dsp.c.

01658 {
01659    int i;
01660    dsp->thinkdigit = 0;
01661    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01662       memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01663       dsp->td.mf.current_digits = 0;
01664       /* Reinitialise the detector for the next block */
01665       for (i = 0;  i < 6;  i++) {
01666             goertzel_reset(&dsp->td.mf.tone_out[i]);
01667 #ifdef OLD_DSP_ROUTINES
01668           goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01669 #endif         
01670       }
01671 #ifdef OLD_DSP_ROUTINES
01672       dsp->td.mf.energy = 0.0;
01673        dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01674 #else
01675        dsp->td.mf.hits[4] = dsp->td.mf.hits[3] = dsp->td.mf.hits[2] = dsp->td.mf.hits[1] = dsp->td.mf.hits[0] = dsp->td.mf.mhit = 0;
01676 #endif      
01677       dsp->td.mf.current_sample = 0;
01678    } else {
01679       memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01680       dsp->td.dtmf.current_digits = 0;
01681       /* Reinitialise the detector for the next block */
01682       for (i = 0;  i < 4;  i++) {
01683             goertzel_reset(&dsp->td.dtmf.row_out[i]);
01684           goertzel_reset(&dsp->td.dtmf.col_out[i]);
01685 #ifdef OLD_DSP_ROUTINES
01686          goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01687          goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01688 #endif         
01689       }
01690 #ifdef FAX_DETECT
01691        goertzel_reset (&dsp->td.dtmf.fax_tone);
01692 #endif
01693 #ifdef OLD_DSP_ROUTINES
01694 #ifdef FAX_DETECT
01695        goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01696 #endif
01697        dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01698 #else
01699        dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] =  dsp->td.dtmf.mhit = 0;
01700 #endif      
01701       dsp->td.dtmf.energy = 0.0;
01702       dsp->td.dtmf.current_sample = 0;
01703    }
01704 }

void ast_dsp_free ( struct ast_dsp dsp  ) 

Definition at line 1638 of file dsp.c.

01639 {
01640    free(dsp);
01641 }

int ast_dsp_getdigits ( struct ast_dsp dsp,
char *  buf,
int  max 
)

Definition at line 1085 of file dsp.c.

01088 {
01089    if (dsp->digitmode & DSP_DIGITMODE_MF) {
01090        if (max > dsp->td.mf.current_digits)
01091            max = dsp->td.mf.current_digits;
01092        if (max > 0)
01093        {
01094            memcpy (buf, dsp->td.mf.digits, max);
01095            memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01096            dsp->td.mf.current_digits -= max;
01097        }
01098        buf[max] = '\0';
01099        return  max;
01100    } else {
01101        if (max > dsp->td.dtmf.current_digits)
01102            max = dsp->td.dtmf.current_digits;
01103        if (max > 0)
01104        {
01105            memcpy (buf, dsp->td.dtmf.digits, max);
01106            memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01107            dsp->td.dtmf.current_digits -= max;
01108        }
01109        buf[max] = '\0';
01110        return  max;
01111    }
01112 }

struct ast_dsp* ast_dsp_new ( void   )  [read]

Definition at line 1616 of file dsp.c.

01617 {
01618    struct ast_dsp *dsp;
01619    dsp = malloc(sizeof(struct ast_dsp));
01620    if (dsp) {
01621       memset(dsp, 0, sizeof(struct ast_dsp));
01622       dsp->threshold = DEFAULT_THRESHOLD;
01623       dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01624       dsp->busycount = DSP_HISTORY;
01625       /* Initialize DTMF detector */
01626       ast_dtmf_detect_init(&dsp->td.dtmf);
01627       /* Initialize initial DSP progress detect parameters */
01628       ast_dsp_prog_reset(dsp);
01629    }
01630    return dsp;
01631 }

struct ast_frame* ast_dsp_process ( struct ast_channel chan,
struct ast_dsp dsp,
struct ast_frame inf 
) [read]

Definition at line 1410 of file dsp.c.

01411 {
01412    int silence;
01413    int res;
01414    int digit;
01415    int x;
01416    unsigned short *shortdata;
01417    unsigned char *odata;
01418    int len;
01419    int writeback = 0;
01420 
01421 #define FIX_INF(inf) do { \
01422       if (writeback) { \
01423          switch(inf->subclass) { \
01424          case AST_FORMAT_SLINEAR: \
01425             break; \
01426          case AST_FORMAT_ULAW: \
01427             for (x=0;x<len;x++) \
01428                odata[x] = AST_LIN2MU(shortdata[x]); \
01429             break; \
01430          case AST_FORMAT_ALAW: \
01431             for (x=0;x<len;x++) \
01432                odata[x] = AST_LIN2A(shortdata[x]); \
01433             break; \
01434          } \
01435       } \
01436    } while(0) 
01437 
01438    if (!af)
01439       return NULL;
01440    if (af->frametype != AST_FRAME_VOICE)
01441       return af;
01442    odata = af->data;
01443    len = af->datalen;
01444    /* Make sure we have short data */
01445    switch(af->subclass) {
01446    case AST_FORMAT_SLINEAR:
01447       shortdata = af->data;
01448       len = af->datalen / 2;
01449       break;
01450    case AST_FORMAT_ULAW:
01451       shortdata = alloca(af->datalen * 2);
01452       if (!shortdata) {
01453          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01454          return af;
01455       }
01456       for (x=0;x<len;x++) 
01457          shortdata[x] = AST_MULAW(odata[x]);
01458       break;
01459    case AST_FORMAT_ALAW:
01460       shortdata = alloca(af->datalen * 2);
01461       if (!shortdata) {
01462          ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01463          return af;
01464       }
01465       for (x=0;x<len;x++) 
01466          shortdata[x] = AST_ALAW(odata[x]);
01467       break;
01468    default:
01469       ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass));
01470       return af;
01471    }
01472    silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01473    if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01474       memset(&dsp->f, 0, sizeof(dsp->f));
01475       dsp->f.frametype = AST_FRAME_NULL;
01476       return &dsp->f;
01477    }
01478    if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01479       chan->_softhangup |= AST_SOFTHANGUP_DEV;
01480       memset(&dsp->f, 0, sizeof(dsp->f));
01481       dsp->f.frametype = AST_FRAME_CONTROL;
01482       dsp->f.subclass = AST_CONTROL_BUSY;
01483       ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01484       return &dsp->f;
01485    }
01486    if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01487       digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01488 #if 0
01489       if (digit)
01490          printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01491 #endif         
01492       if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01493          if (!dsp->thinkdigit) {
01494             if (digit) {
01495                /* Looks like we might have something.  Request a conference mute for the moment */
01496                memset(&dsp->f, 0, sizeof(dsp->f));
01497                dsp->f.frametype = AST_FRAME_DTMF;
01498                dsp->f.subclass = 'm';
01499                dsp->thinkdigit = 'x';
01500                FIX_INF(af);
01501                if (chan)
01502                   ast_queue_frame(chan, af);
01503                ast_frfree(af);
01504                return &dsp->f;
01505             }
01506          } else {
01507             if (digit) {
01508                /* Thought we saw one last time.  Pretty sure we really have now */
01509                if (dsp->thinkdigit) {
01510                   if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01511                      /* If we found a digit, and we're changing digits, go
01512                         ahead and send this one, but DON'T stop confmute because
01513                         we're detecting something else, too... */
01514                      memset(&dsp->f, 0, sizeof(dsp->f));
01515                      dsp->f.frametype = AST_FRAME_DTMF;
01516                      dsp->f.subclass = dsp->thinkdigit;
01517                      FIX_INF(af);
01518                      if (chan)
01519                         ast_queue_frame(chan, af);
01520                      ast_frfree(af);
01521                   }
01522                   dsp->thinkdigit = digit;
01523                   return &dsp->f;
01524                }
01525                dsp->thinkdigit = digit;
01526             } else {
01527                if (dsp->thinkdigit) {
01528                   memset(&dsp->f, 0, sizeof(dsp->f));
01529                   if (dsp->thinkdigit != 'x') {
01530                      /* If we found a digit, send it now */
01531                      dsp->f.frametype = AST_FRAME_DTMF;
01532                      dsp->f.subclass = dsp->thinkdigit;
01533                      dsp->thinkdigit = 0;
01534                   } else {
01535                      dsp->f.frametype = AST_FRAME_DTMF;
01536                      dsp->f.subclass = 'u';
01537                      dsp->thinkdigit = 0;
01538                   }
01539                   FIX_INF(af);
01540                   if (chan)
01541                      ast_queue_frame(chan, af);
01542                   ast_frfree(af);
01543                   return &dsp->f;
01544                }
01545             }
01546          }
01547       } else if (!digit) {
01548          /* Only check when there is *not* a hit... */
01549          if (dsp->digitmode & DSP_DIGITMODE_MF) {
01550             if (dsp->td.mf.current_digits) {
01551                memset(&dsp->f, 0, sizeof(dsp->f));
01552                dsp->f.frametype = AST_FRAME_DTMF;
01553                dsp->f.subclass = dsp->td.mf.digits[0];
01554                memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01555                dsp->td.mf.current_digits--;
01556                FIX_INF(af);
01557                if (chan)
01558                   ast_queue_frame(chan, af);
01559                ast_frfree(af);
01560                return &dsp->f;
01561             }
01562          } else {
01563             if (dsp->td.dtmf.current_digits) {
01564                memset(&dsp->f, 0, sizeof(dsp->f));
01565                dsp->f.frametype = AST_FRAME_DTMF;
01566                dsp->f.subclass = dsp->td.dtmf.digits[0];
01567                memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01568                dsp->td.dtmf.current_digits--;
01569                FIX_INF(af);
01570                if (chan)
01571                   ast_queue_frame(chan, af);
01572                ast_frfree(af);
01573                return &dsp->f;
01574             }
01575          }
01576       }
01577    }
01578    if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01579       res = __ast_dsp_call_progress(dsp, shortdata, len);
01580       memset(&dsp->f, 0, sizeof(dsp->f));
01581       dsp->f.frametype = AST_FRAME_CONTROL;
01582       if (res) {
01583          switch(res) {
01584          case AST_CONTROL_ANSWER:
01585          case AST_CONTROL_BUSY:
01586          case AST_CONTROL_RINGING:
01587          case AST_CONTROL_CONGESTION:
01588             dsp->f.subclass = res;
01589             if (chan) 
01590                ast_queue_frame(chan, &dsp->f);
01591             break;
01592          default:
01593             ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01594          }
01595       }
01596    }
01597    FIX_INF(af);
01598    return af;
01599 }

void ast_dsp_reset ( struct ast_dsp dsp  ) 

Definition at line 1706 of file dsp.c.

01707 {
01708    int x;
01709    dsp->totalsilence = 0;
01710    dsp->gsamps = 0;
01711    for (x=0;x<4;x++)
01712       dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01713    memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01714    memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01715    
01716 }

void ast_dsp_set_busy_count ( struct ast_dsp dsp,
int  cadences 
)

Definition at line 1648 of file dsp.c.

01649 {
01650    if (cadences < 4)
01651       cadences = 4;
01652    if (cadences > DSP_HISTORY)
01653       cadences = DSP_HISTORY;
01654    dsp->busycount = cadences;
01655 }

int ast_dsp_set_call_progress_zone ( struct ast_dsp dsp,
char *  zone 
)

Definition at line 1734 of file dsp.c.

01735 {
01736    int x;
01737    for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01738       if (!strcasecmp(aliases[x].name, zone)) {
01739          dsp->progmode = aliases[x].mode;
01740          ast_dsp_prog_reset(dsp);
01741          return 0;
01742       }
01743    }
01744    return -1;
01745 }

void ast_dsp_set_features ( struct ast_dsp dsp,
int  features 
)

Definition at line 1633 of file dsp.c.

01634 {
01635    dsp->features = features;
01636 }

void ast_dsp_set_threshold ( struct ast_dsp dsp,
int  threshold 
)

Definition at line 1643 of file dsp.c.

01644 {
01645    dsp->threshold = threshold;
01646 }

int ast_dsp_silence ( struct ast_dsp dsp,
struct ast_frame f,
int *  totalsilence 
)

Definition at line 1392 of file dsp.c.

01393 {
01394    short *s;
01395    int len;
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 (f->subclass != AST_FORMAT_SLINEAR) {
01402       ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01403       return 0;
01404    }
01405    s = f->data;
01406    len = f->datalen/2;
01407    return __ast_dsp_silence(dsp, s, len, totalsilence);
01408 }


Generated on Wed Oct 28 17:00:53 2009 for Asterisk by  doxygen 1.5.6