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 1213 of file dsp.c. References ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, and ast_frame::subclass.
01214 {
01215 if (inf->frametype != AST_FRAME_VOICE) {
01216 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01217 return 0;
01218 }
01219 if (inf->subclass != AST_FORMAT_SLINEAR) {
01220 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01221 return 0;
01222 }
01223 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01224 }
|
|
||||||||||||
|
Definition at line 1047 of file dsp.c. References ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, s, 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 1717 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, and ast_dsp::td.
01718 {
01719 int new, old;
01720 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01721 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01722 if (old != new) {
01723 /* Must initialize structures if switching from MF to DTMF or vice-versa */
01724 if (new & DSP_DIGITMODE_MF)
01725 ast_mf_detect_init(&dsp->td.mf);
01726 else
01727 ast_dtmf_detect_init(&dsp->td.dtmf);
01728 }
01729 dsp->digitmode = digitmode;
01730 return 0;
01731 }
|
|
|
Definition at line 1656 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, ast_dsp::td, and ast_dsp::thinkdigit.
01657 {
01658 int i;
01659 dsp->thinkdigit = 0;
01660 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01661 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01662 dsp->td.mf.current_digits = 0;
01663 /* Reinitialise the detector for the next block */
01664 for (i = 0; i < 6; i++) {
01665 goertzel_reset(&dsp->td.mf.tone_out[i]);
01666 #ifdef OLD_DSP_ROUTINES
01667 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01668 #endif
01669 }
01670 #ifdef OLD_DSP_ROUTINES
01671 dsp->td.mf.energy = 0.0;
01672 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01673 #else
01674 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;
01675 #endif
01676 dsp->td.mf.current_sample = 0;
01677 } else {
01678 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01679 dsp->td.dtmf.current_digits = 0;
01680 /* Reinitialise the detector for the next block */
01681 for (i = 0; i < 4; i++) {
01682 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01683 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01684 #ifdef OLD_DSP_ROUTINES
01685 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01686 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01687 #endif
01688 }
01689 #ifdef FAX_DETECT
01690 goertzel_reset (&dsp->td.dtmf.fax_tone);
01691 #endif
01692 #ifdef OLD_DSP_ROUTINES
01693 #ifdef FAX_DETECT
01694 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01695 #endif
01696 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01697 #else
01698 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
01699 #endif
01700 dsp->td.dtmf.energy = 0.0;
01701 dsp->td.dtmf.current_sample = 0;
01702 }
01703 }
|
|
|
Definition at line 1637 of file dsp.c. References free. Referenced by ast_app_getvoice().
01638 {
01639 free(dsp);
01640 }
|
|
||||||||||||||||
|
Definition at line 1085 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, and ast_dsp::td.
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 1615 of file dsp.c. References ast_dsp::busycount, DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::features, malloc, ast_dsp::td, and ast_dsp::threshold. Referenced by ast_app_getvoice(), ast_play_and_prepend(), and ast_play_and_record().
01616 {
01617 struct ast_dsp *dsp;
01618 dsp = malloc(sizeof(struct ast_dsp));
01619 if (dsp) {
01620 memset(dsp, 0, sizeof(struct ast_dsp));
01621 dsp->threshold = DEFAULT_THRESHOLD;
01622 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01623 dsp->busycount = DSP_HISTORY;
01624 /* Initialize DTMF detector */
01625 ast_dtmf_detect_init(&dsp->td.dtmf);
01626 /* Initialize initial DSP progress detect parameters */
01627 ast_dsp_prog_reset(dsp);
01628 }
01629 return dsp;
01630 }
|
|
||||||||||||||||
|
Definition at line 1409 of file dsp.c. References AST_ALAW, ast_codec2str(), ast_dsp_busydetect(), ast_frfree(), 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_frame::frametype, LOG_DEBUG, LOG_WARNING, and ast_frame::subclass.
01410 {
01411 int silence;
01412 int res;
01413 int digit;
01414 int x;
01415 unsigned short *shortdata;
01416 unsigned char *odata;
01417 int len;
01418 int writeback = 0;
01419
01420 #define FIX_INF(inf) do { \
01421 if (writeback) { \
01422 switch(inf->subclass) { \
01423 case AST_FORMAT_SLINEAR: \
01424 break; \
01425 case AST_FORMAT_ULAW: \
01426 for (x=0;x<len;x++) \
01427 odata[x] = AST_LIN2MU(shortdata[x]); \
01428 break; \
01429 case AST_FORMAT_ALAW: \
01430 for (x=0;x<len;x++) \
01431 odata[x] = AST_LIN2A(shortdata[x]); \
01432 break; \
01433 } \
01434 } \
01435 } while(0)
01436
01437 if (!af)
01438 return NULL;
01439 if (af->frametype != AST_FRAME_VOICE)
01440 return af;
01441 odata = af->data;
01442 len = af->datalen;
01443 /* Make sure we have short data */
01444 switch(af->subclass) {
01445 case AST_FORMAT_SLINEAR:
01446 shortdata = af->data;
01447 len = af->datalen / 2;
01448 break;
01449 case AST_FORMAT_ULAW:
01450 shortdata = alloca(af->datalen * 2);
01451 if (!shortdata) {
01452 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01453 return af;
01454 }
01455 for (x=0;x<len;x++)
01456 shortdata[x] = AST_MULAW(odata[x]);
01457 break;
01458 case AST_FORMAT_ALAW:
01459 shortdata = alloca(af->datalen * 2);
01460 if (!shortdata) {
01461 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01462 return af;
01463 }
01464 for (x=0;x<len;x++)
01465 shortdata[x] = AST_ALAW(odata[x]);
01466 break;
01467 default:
01468 ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_codec2str(af->subclass));
01469 return af;
01470 }
01471 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01472 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01473 memset(&dsp->f, 0, sizeof(dsp->f));
01474 dsp->f.frametype = AST_FRAME_NULL;
01475 return &dsp->f;
01476 }
01477 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01478 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01479 memset(&dsp->f, 0, sizeof(dsp->f));
01480 dsp->f.frametype = AST_FRAME_CONTROL;
01481 dsp->f.subclass = AST_CONTROL_BUSY;
01482 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01483 return &dsp->f;
01484 }
01485 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01486 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01487 #if 0
01488 if (digit)
01489 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01490 #endif
01491 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01492 if (!dsp->thinkdigit) {
01493 if (digit) {
01494 /* Looks like we might have something. Request a conference mute for the moment */
01495 memset(&dsp->f, 0, sizeof(dsp->f));
01496 dsp->f.frametype = AST_FRAME_DTMF;
01497 dsp->f.subclass = 'm';
01498 dsp->thinkdigit = 'x';
01499 FIX_INF(af);
01500 if (chan)
01501 ast_queue_frame(chan, af);
01502 ast_frfree(af);
01503 return &dsp->f;
01504 }
01505 } else {
01506 if (digit) {
01507 /* Thought we saw one last time. Pretty sure we really have now */
01508 if (dsp->thinkdigit) {
01509 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01510 /* If we found a digit, and we're changing digits, go
01511 ahead and send this one, but DON'T stop confmute because
01512 we're detecting something else, too... */
01513 memset(&dsp->f, 0, sizeof(dsp->f));
01514 dsp->f.frametype = AST_FRAME_DTMF;
01515 dsp->f.subclass = dsp->thinkdigit;
01516 FIX_INF(af);
01517 if (chan)
01518 ast_queue_frame(chan, af);
01519 ast_frfree(af);
01520 }
01521 dsp->thinkdigit = digit;
01522 return &dsp->f;
01523 }
01524 dsp->thinkdigit = digit;
01525 } else {
01526 if (dsp->thinkdigit) {
01527 memset(&dsp->f, 0, sizeof(dsp->f));
01528 if (dsp->thinkdigit != 'x') {
01529 /* If we found a digit, send it now */
01530 dsp->f.frametype = AST_FRAME_DTMF;
01531 dsp->f.subclass = dsp->thinkdigit;
01532 dsp->thinkdigit = 0;
01533 } else {
01534 dsp->f.frametype = AST_FRAME_DTMF;
01535 dsp->f.subclass = 'u';
01536 dsp->thinkdigit = 0;
01537 }
01538 FIX_INF(af);
01539 if (chan)
01540 ast_queue_frame(chan, af);
01541 ast_frfree(af);
01542 return &dsp->f;
01543 }
01544 }
01545 }
01546 } else if (!digit) {
01547 /* Only check when there is *not* a hit... */
01548 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01549 if (dsp->td.mf.current_digits) {
01550 memset(&dsp->f, 0, sizeof(dsp->f));
01551 dsp->f.frametype = AST_FRAME_DTMF;
01552 dsp->f.subclass = dsp->td.mf.digits[0];
01553 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01554 dsp->td.mf.current_digits--;
01555 FIX_INF(af);
01556 if (chan)
01557 ast_queue_frame(chan, af);
01558 ast_frfree(af);
01559 return &dsp->f;
01560 }
01561 } else {
01562 if (dsp->td.dtmf.current_digits) {
01563 memset(&dsp->f, 0, sizeof(dsp->f));
01564 dsp->f.frametype = AST_FRAME_DTMF;
01565 dsp->f.subclass = dsp->td.dtmf.digits[0];
01566 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01567 dsp->td.dtmf.current_digits--;
01568 FIX_INF(af);
01569 if (chan)
01570 ast_queue_frame(chan, af);
01571 ast_frfree(af);
01572 return &dsp->f;
01573 }
01574 }
01575 }
01576 }
01577 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01578 res = __ast_dsp_call_progress(dsp, shortdata, len);
01579 memset(&dsp->f, 0, sizeof(dsp->f));
01580 dsp->f.frametype = AST_FRAME_CONTROL;
01581 if (res) {
01582 switch(res) {
01583 case AST_CONTROL_ANSWER:
01584 case AST_CONTROL_BUSY:
01585 case AST_CONTROL_RINGING:
01586 case AST_CONTROL_CONGESTION:
01587 dsp->f.subclass = res;
01588 if (chan)
01589 ast_queue_frame(chan, &dsp->f);
01590 break;
01591 default:
01592 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01593 }
01594 }
01595 }
01596 FIX_INF(af);
01597 return af;
01598 }
|
|
|
Definition at line 1705 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.
01706 {
01707 int x;
01708 dsp->totalsilence = 0;
01709 dsp->gsamps = 0;
01710 for (x=0;x<4;x++)
01711 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01712 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01713 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01714
01715 }
|
|
||||||||||||
|
Definition at line 1647 of file dsp.c. References ast_dsp::busycount, and DSP_HISTORY.
01648 {
01649 if (cadences < 4)
01650 cadences = 4;
01651 if (cadences > DSP_HISTORY)
01652 cadences = DSP_HISTORY;
01653 dsp->busycount = cadences;
01654 }
|
|
||||||||||||
|
Definition at line 1733 of file dsp.c. References ast_dsp::progmode.
01734 {
01735 int x;
01736 for (x=0;x<sizeof(aliases) / sizeof(aliases[0]);x++) {
01737 if (!strcasecmp(aliases[x].name, zone)) {
01738 dsp->progmode = aliases[x].mode;
01739 ast_dsp_prog_reset(dsp);
01740 return 0;
01741 }
01742 }
01743 return -1;
01744 }
|
|
||||||||||||
|
Definition at line 1632 of file dsp.c. References ast_dsp::features.
01633 {
01634 dsp->features = features;
01635 }
|
|
||||||||||||
|
Definition at line 1642 of file dsp.c. References ast_dsp::threshold. Referenced by ast_play_and_prepend(), and ast_play_and_record().
01643 {
01644 dsp->threshold = threshold;
01645 }
|
|
||||||||||||||||
|
Definition at line 1391 of file dsp.c. References ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, s, and ast_frame::subclass. Referenced by ast_app_getvoice(), ast_play_and_prepend(), and ast_play_and_record().
01392 {
01393 short *s;
01394 int len;
01395
01396 if (f->frametype != AST_FRAME_VOICE) {
01397 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01398 return 0;
01399 }
01400 if (f->subclass != AST_FORMAT_SLINEAR) {
01401 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01402 return 0;
01403 }
01404 s = f->data;
01405 len = f->datalen/2;
01406 return __ast_dsp_silence(dsp, s, len, totalsilence);
01407 }
|
1.2.15