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 | |
ast_dsp * | ast_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) |
ast_frame * | ast_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) |
|
Definition at line 23 of file dsp.h. Referenced by ast_dsp_digitmode(). |
|
Definition at line 24 of file dsp.h. Referenced by ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_getdigits(), and ast_dsp_process(). |
|
Definition at line 27 of file dsp.h. Referenced by ast_dsp_digitmode(), and ast_dsp_process(). |
|
Definition at line 28 of file dsp.h. Referenced by ast_dsp_digitmode(), and ast_dsp_process(). |
|
|
|
|
|
Definition at line 18 of file dsp.h. Referenced by ast_dsp_process(). |
|
Definition at line 19 of file dsp.h. Referenced by ast_dsp_process(). |
|
Definition at line 20 of file dsp.h. Referenced by ast_dsp_process(). |
|
|
|
Definition at line 17 of file dsp.h. Referenced by ast_dsp_new(), and ast_dsp_process(). |
|
Referenced by ast_dsp_process(). |
|
Definition at line 1214 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass. 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 }
|
|
Definition at line 1047 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass. 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 }
|
|
Definition at line 1718 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, and ast_dsp::td. 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 }
|
|
Definition at line 1657 of file dsp.c. References DSP_DIGITMODE_MF. 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 }
|
|
Definition at line 1638 of file dsp.c. References free. Referenced by ast_app_getvoice(), and ast_play_and_record(). 01639 { 01640 free(dsp); 01641 }
|
|
Definition at line 1085 of file dsp.c. References DSP_DIGITMODE_MF. 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 }
|
|
Definition at line 1616 of file dsp.c. References DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, and malloc. Referenced by ast_app_getvoice(), ast_play_and_prepend(), and ast_play_and_record(). 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 }
|
|
Definition at line 1410 of file dsp.c. References ast_channel::_softhangup, AST_ALAW, AST_CONTROL_ANSWER, AST_CONTROL_BUSY, AST_CONTROL_CONGESTION, AST_CONTROL_RINGING, ast_dsp_busydetect(), AST_FORMAT_ALAW, AST_FORMAT_SLINEAR, AST_FORMAT_ULAW, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, AST_FRAME_VOICE, ast_frfree(), ast_getformatname(), ast_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, ast_frame::datalen, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, DSP_FEATURE_BUSY_DETECT, DSP_FEATURE_CALL_PROGRESS, DSP_FEATURE_DTMF_DETECT, DSP_FEATURE_SILENCE_SUPPRESS, ast_dsp::f, ast_dsp::features, FIX_INF, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_channel::name, and ast_frame::subclass. 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 }
|
|
Definition at line 1706 of file dsp.c. References ast_dsp::freqs, ast_dsp::gsamps, ast_dsp::historicnoise, ast_dsp::historicsilence, ast_dsp::totalsilence, goertzel_state_t::v2, and goertzel_state_t::v3. 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 }
|
|
Definition at line 1648 of file dsp.c. References ast_dsp::busycount, and DSP_HISTORY. 01649 { 01650 if (cadences < 4) 01651 cadences = 4; 01652 if (cadences > DSP_HISTORY) 01653 cadences = DSP_HISTORY; 01654 dsp->busycount = cadences; 01655 }
|
|
Definition at line 1734 of file dsp.c. References ast_dsp::progmode. 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 }
|
|
Definition at line 1633 of file dsp.c. References ast_dsp::features.
|
|
Definition at line 1643 of file dsp.c. References ast_dsp::threshold. Referenced by ast_play_and_prepend(), and ast_play_and_record().
|
|
Definition at line 1392 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass. Referenced by ast_app_getvoice(), ast_play_and_prepend(), and ast_play_and_record(). 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 }
|