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_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) |
| ast_frame * | ast_dsp_process (struct ast_channel *chan, struct ast_dsp *dsp, struct ast_frame *inf, int needlock) |
| 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 22 of file dsp.h. Referenced by ast_dsp_digitmode(). |
|
|
Definition at line 23 of file dsp.h. Referenced by ast_dsp_digitmode(), ast_dsp_digitreset(), ast_dsp_getdigits(), and ast_dsp_process(). |
|
|
Definition at line 26 of file dsp.h. Referenced by ast_dsp_digitmode(), and ast_dsp_process(). |
|
|
Definition at line 27 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 1172 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.
01173 {
01174 if (inf->frametype != AST_FRAME_VOICE) {
01175 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01176 return 0;
01177 }
01178 if (inf->subclass != AST_FORMAT_SLINEAR) {
01179 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01180 return 0;
01181 }
01182 return __ast_dsp_call_progress(dsp, inf->data, inf->datalen / 2);
01183 }
|
|
||||||||||||
|
Definition at line 1004 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, s, and ast_frame::subclass.
01005 {
01006 short *s;
01007 int len;
01008 int ign=0;
01009 if (inf->frametype != AST_FRAME_VOICE) {
01010 ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
01011 return 0;
01012 }
01013 if (inf->subclass != AST_FORMAT_SLINEAR) {
01014 ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
01015 return 0;
01016 }
01017 s = inf->data;
01018 len = inf->datalen / 2;
01019 return __ast_dsp_digitdetect(dsp, s, len, &ign);
01020 }
|
|
||||||||||||
|
Definition at line 1660 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_DTMF, DSP_DIGITMODE_MF, DSP_DIGITMODE_MUTECONF, DSP_DIGITMODE_MUTEMAX, and ast_dsp::td.
01661 {
01662 int new, old;
01663 old = dsp->digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01664 new = digitmode & (DSP_DIGITMODE_DTMF | DSP_DIGITMODE_MF | DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX);
01665 if (old != new) {
01666 /* Must initialize structures if switching from MF to DTMF or vice-versa */
01667 if (new & DSP_DIGITMODE_MF)
01668 ast_mf_detect_init(&dsp->td.mf);
01669 else
01670 ast_dtmf_detect_init(&dsp->td.dtmf);
01671 }
01672 dsp->digitmode = digitmode;
01673 return 0;
01674 }
|
|
|
Definition at line 1603 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, ast_dsp::td, and ast_dsp::thinkdigit.
01604 {
01605 int i;
01606 dsp->thinkdigit = 0;
01607 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01608 memset(dsp->td.mf.digits, 0, sizeof(dsp->td.mf.digits));
01609 dsp->td.mf.current_digits = 0;
01610 /* Reinitialise the detector for the next block */
01611 for (i = 0; i < 6; i++) {
01612 goertzel_reset(&dsp->td.mf.tone_out[i]);
01613 #ifdef OLD_DSP_ROUTINES
01614 goertzel_reset(&dsp->td.mf.tone_out2nd[i]);
01615 #endif
01616 }
01617 #ifdef OLD_DSP_ROUTINES
01618 dsp->td.mf.energy = 0.0;
01619 dsp->td.mf.hit1 = dsp->td.mf.hit2 = dsp->td.mf.hit3 = dsp->td.mf.hit4 = dsp->td.mf.mhit = 0;
01620 #else
01621 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;
01622 #endif
01623 dsp->td.mf.current_sample = 0;
01624 } else {
01625 memset(dsp->td.dtmf.digits, 0, sizeof(dsp->td.dtmf.digits));
01626 dsp->td.dtmf.current_digits = 0;
01627 /* Reinitialise the detector for the next block */
01628 for (i = 0; i < 4; i++) {
01629 goertzel_reset(&dsp->td.dtmf.row_out[i]);
01630 goertzel_reset(&dsp->td.dtmf.col_out[i]);
01631 #ifdef OLD_DSP_ROUTINES
01632 goertzel_reset(&dsp->td.dtmf.row_out2nd[i]);
01633 goertzel_reset(&dsp->td.dtmf.col_out2nd[i]);
01634 #endif
01635 }
01636 goertzel_reset (&dsp->td.dtmf.fax_tone);
01637 #ifdef OLD_DSP_ROUTINES
01638 goertzel_reset (&dsp->td.dtmf.fax_tone2nd);
01639 dsp->td.dtmf.hit1 = dsp->td.dtmf.hit2 = dsp->td.dtmf.hit3 = dsp->td.dtmf.hit4 = dsp->td.dtmf.mhit = 0;
01640 #else
01641 dsp->td.dtmf.hits[2] = dsp->td.dtmf.hits[1] = dsp->td.dtmf.hits[0] = dsp->td.dtmf.mhit = 0;
01642 #endif
01643 dsp->td.dtmf.energy = 0.0;
01644 dsp->td.dtmf.current_sample = 0;
01645 }
01646 }
|
|
|
Definition at line 1584 of file dsp.c. References free. Referenced by ast_app_getvoice().
01585 {
01586 free(dsp);
01587 }
|
|
||||||||||||||||
|
Definition at line 1042 of file dsp.c. References ast_dsp::digitmode, DSP_DIGITMODE_MF, and ast_dsp::td.
01045 {
01046 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01047 if (max > dsp->td.mf.current_digits)
01048 max = dsp->td.mf.current_digits;
01049 if (max > 0)
01050 {
01051 memcpy (buf, dsp->td.mf.digits, max);
01052 memmove (dsp->td.mf.digits, dsp->td.mf.digits + max, dsp->td.mf.current_digits - max);
01053 dsp->td.mf.current_digits -= max;
01054 }
01055 buf[max] = '\0';
01056 return max;
01057 } else {
01058 if (max > dsp->td.dtmf.current_digits)
01059 max = dsp->td.dtmf.current_digits;
01060 if (max > 0)
01061 {
01062 memcpy (buf, dsp->td.dtmf.digits, max);
01063 memmove (dsp->td.dtmf.digits, dsp->td.dtmf.digits + max, dsp->td.dtmf.current_digits - max);
01064 dsp->td.dtmf.current_digits -= max;
01065 }
01066 buf[max] = '\0';
01067 return max;
01068 }
01069 }
|
|
|
Definition at line 1556 of file dsp.c. References ast_dsp::busycount, DEFAULT_THRESHOLD, DSP_FEATURE_SILENCE_SUPPRESS, DSP_HISTORY, ast_dsp::features, ast_dsp::freqs, GSAMP_SIZE, HZ_1400, HZ_1800, HZ_350, HZ_440, HZ_480, HZ_620, HZ_950, malloc, ast_dsp::td, and ast_dsp::threshold. Referenced by ast_app_getvoice().
01557 {
01558 struct ast_dsp *dsp;
01559 dsp = malloc(sizeof(struct ast_dsp));
01560 if (dsp) {
01561 memset(dsp, 0, sizeof(struct ast_dsp));
01562 dsp->threshold = DEFAULT_THRESHOLD;
01563 dsp->features = DSP_FEATURE_SILENCE_SUPPRESS;
01564 dsp->busycount = DSP_HISTORY;
01565 /* Initialize goertzels */
01566 goertzel_init(&dsp->freqs[HZ_350], 350.0, GSAMP_SIZE);
01567 goertzel_init(&dsp->freqs[HZ_440], 440.0, GSAMP_SIZE);
01568 goertzel_init(&dsp->freqs[HZ_480], 480.0, GSAMP_SIZE);
01569 goertzel_init(&dsp->freqs[HZ_620], 620.0, GSAMP_SIZE);
01570 goertzel_init(&dsp->freqs[HZ_950], 950.0, GSAMP_SIZE);
01571 goertzel_init(&dsp->freqs[HZ_1400], 1400.0, GSAMP_SIZE);
01572 goertzel_init(&dsp->freqs[HZ_1800], 1800.0, GSAMP_SIZE);
01573 /* Initialize DTMF detector */
01574 ast_dtmf_detect_init(&dsp->td.dtmf);
01575 }
01576 return dsp;
01577 }
|
|
||||||||||||||||||||
|
Definition at line 1365 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_log(), AST_MULAW, ast_queue_frame(), AST_SOFTHANGUP_DEV, ast_frame::data, ast_frame::datalen, ast_dsp::digitmode, 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, ast_frame::subclass, ast_dsp::td, and ast_dsp::thinkdigit.
01366 {
01367 int silence;
01368 int res;
01369 int digit;
01370 int x;
01371 unsigned short *shortdata;
01372 unsigned char *odata;
01373 int len;
01374 int writeback = 0;
01375
01376 #define FIX_INF(inf) do { \
01377 if (writeback) { \
01378 switch(inf->subclass) { \
01379 case AST_FORMAT_SLINEAR: \
01380 break; \
01381 case AST_FORMAT_ULAW: \
01382 for (x=0;x<len;x++) \
01383 odata[x] = AST_LIN2MU(shortdata[x]); \
01384 break; \
01385 case AST_FORMAT_ALAW: \
01386 for (x=0;x<len;x++) \
01387 odata[x] = AST_LIN2A(shortdata[x]); \
01388 break; \
01389 } \
01390 } \
01391 } while(0)
01392
01393 if (!af)
01394 return NULL;
01395 if (af->frametype != AST_FRAME_VOICE)
01396 return af;
01397 odata = af->data;
01398 len = af->datalen;
01399 /* Make sure we have short data */
01400 switch(af->subclass) {
01401 case AST_FORMAT_SLINEAR:
01402 shortdata = af->data;
01403 len = af->datalen / 2;
01404 break;
01405 case AST_FORMAT_ULAW:
01406 shortdata = alloca(af->datalen * 2);
01407 if (!shortdata) {
01408 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01409 return af;
01410 }
01411 for (x=0;x<len;x++)
01412 shortdata[x] = AST_MULAW(odata[x]);
01413 break;
01414 case AST_FORMAT_ALAW:
01415 shortdata = alloca(af->datalen * 2);
01416 if (!shortdata) {
01417 ast_log(LOG_WARNING, "Unable to allocate stack space for data: %s\n", strerror(errno));
01418 return af;
01419 }
01420 for (x=0;x<len;x++)
01421 shortdata[x] = AST_ALAW(odata[x]);
01422 break;
01423 default:
01424 ast_log(LOG_WARNING, "Unable to process inband DTMF on %d frames\n", af->subclass);
01425 return af;
01426 }
01427 silence = __ast_dsp_silence(dsp, shortdata, len, NULL);
01428 if ((dsp->features & DSP_FEATURE_SILENCE_SUPPRESS) && silence) {
01429 memset(&dsp->f, 0, sizeof(dsp->f));
01430 dsp->f.frametype = AST_FRAME_NULL;
01431 return &dsp->f;
01432 }
01433 if ((dsp->features & DSP_FEATURE_BUSY_DETECT) && ast_dsp_busydetect(dsp)) {
01434 chan->_softhangup |= AST_SOFTHANGUP_DEV;
01435 memset(&dsp->f, 0, sizeof(dsp->f));
01436 dsp->f.frametype = AST_FRAME_CONTROL;
01437 dsp->f.subclass = AST_CONTROL_BUSY;
01438 ast_log(LOG_DEBUG, "Requesting Hangup because the busy tone was detected on channel %s\n", chan->name);
01439 return &dsp->f;
01440 }
01441 if ((dsp->features & DSP_FEATURE_DTMF_DETECT)) {
01442 digit = __ast_dsp_digitdetect(dsp, shortdata, len, &writeback);
01443 #if 0
01444 if (digit)
01445 printf("Performing digit detection returned %d, digitmode is %d\n", digit, dsp->digitmode);
01446 #endif
01447 if (dsp->digitmode & (DSP_DIGITMODE_MUTECONF | DSP_DIGITMODE_MUTEMAX)) {
01448 if (!dsp->thinkdigit) {
01449 if (digit) {
01450 /* Looks like we might have something. Request a conference mute for the moment */
01451 memset(&dsp->f, 0, sizeof(dsp->f));
01452 dsp->f.frametype = AST_FRAME_DTMF;
01453 dsp->f.subclass = 'm';
01454 dsp->thinkdigit = 'x';
01455 FIX_INF(af);
01456 if (chan)
01457 ast_queue_frame(chan, af, needlock);
01458 ast_frfree(af);
01459 return &dsp->f;
01460 }
01461 } else {
01462 if (digit) {
01463 /* Thought we saw one last time. Pretty sure we really have now */
01464 if (dsp->thinkdigit) {
01465 if ((dsp->thinkdigit != 'x') && (dsp->thinkdigit != digit)) {
01466 /* If we found a digit, and we're changing digits, go
01467 ahead and send this one, but DON'T stop confmute because
01468 we're detecting something else, too... */
01469 memset(&dsp->f, 0, sizeof(dsp->f));
01470 dsp->f.frametype = AST_FRAME_DTMF;
01471 dsp->f.subclass = dsp->thinkdigit;
01472 FIX_INF(af);
01473 if (chan)
01474 ast_queue_frame(chan, af, needlock);
01475 ast_frfree(af);
01476 }
01477 dsp->thinkdigit = digit;
01478 return &dsp->f;
01479 }
01480 dsp->thinkdigit = digit;
01481 } else {
01482 if (dsp->thinkdigit) {
01483 memset(&dsp->f, 0, sizeof(dsp->f));
01484 if (dsp->thinkdigit != 'x') {
01485 /* If we found a digit, send it now */
01486 dsp->f.frametype = AST_FRAME_DTMF;
01487 dsp->f.subclass = dsp->thinkdigit;
01488 dsp->thinkdigit = 0;
01489 } else {
01490 dsp->f.frametype = AST_FRAME_DTMF;
01491 dsp->f.subclass = 'u';
01492 dsp->thinkdigit = 0;
01493 }
01494 FIX_INF(af);
01495 if (chan)
01496 ast_queue_frame(chan, af, needlock);
01497 ast_frfree(af);
01498 return &dsp->f;
01499 }
01500 }
01501 }
01502 } else if (!digit) {
01503 /* Only check when there is *not* a hit... */
01504 if (dsp->digitmode & DSP_DIGITMODE_MF) {
01505 if (dsp->td.mf.current_digits) {
01506 memset(&dsp->f, 0, sizeof(dsp->f));
01507 dsp->f.frametype = AST_FRAME_DTMF;
01508 dsp->f.subclass = dsp->td.mf.digits[0];
01509 memmove(dsp->td.mf.digits, dsp->td.mf.digits + 1, dsp->td.mf.current_digits);
01510 dsp->td.mf.current_digits--;
01511 FIX_INF(af);
01512 if (chan)
01513 ast_queue_frame(chan, af, needlock);
01514 ast_frfree(af);
01515 return &dsp->f;
01516 }
01517 } else {
01518 if (dsp->td.dtmf.current_digits) {
01519 memset(&dsp->f, 0, sizeof(dsp->f));
01520 dsp->f.frametype = AST_FRAME_DTMF;
01521 dsp->f.subclass = dsp->td.dtmf.digits[0];
01522 memmove(dsp->td.dtmf.digits, dsp->td.dtmf.digits + 1, dsp->td.dtmf.current_digits);
01523 dsp->td.dtmf.current_digits--;
01524 FIX_INF(af);
01525 if (chan)
01526 ast_queue_frame(chan, af, needlock);
01527 ast_frfree(af);
01528 return &dsp->f;
01529 }
01530 }
01531 }
01532 }
01533 if ((dsp->features & DSP_FEATURE_CALL_PROGRESS)) {
01534 res = __ast_dsp_call_progress(dsp, shortdata, len);
01535 memset(&dsp->f, 0, sizeof(dsp->f));
01536 dsp->f.frametype = AST_FRAME_CONTROL;
01537 if (res) {
01538 switch(res) {
01539 case AST_CONTROL_ANSWER:
01540 case AST_CONTROL_BUSY:
01541 case AST_CONTROL_RINGING:
01542 case AST_CONTROL_CONGESTION:
01543 dsp->f.subclass = res;
01544 if (chan)
01545 ast_queue_frame(chan, &dsp->f, needlock);
01546 break;
01547 default:
01548 ast_log(LOG_WARNING, "Don't know how to represent call progress message %d\n", res);
01549 }
01550 }
01551 }
01552 FIX_INF(af);
01553 return af;
01554 }
|
|
|
Definition at line 1648 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.
01649 {
01650 int x;
01651 dsp->totalsilence = 0;
01652 dsp->gsamps = 0;
01653 for (x=0;x<4;x++)
01654 dsp->freqs[x].v2 = dsp->freqs[x].v3 = 0.0;
01655 memset(dsp->historicsilence, 0, sizeof(dsp->historicsilence));
01656 memset(dsp->historicnoise, 0, sizeof(dsp->historicnoise));
01657
01658 }
|
|
||||||||||||
|
Definition at line 1594 of file dsp.c. References ast_dsp::busycount, and DSP_HISTORY.
01595 {
01596 if (cadences < 4)
01597 cadences = 4;
01598 if (cadences > DSP_HISTORY)
01599 cadences = DSP_HISTORY;
01600 dsp->busycount = cadences;
01601 }
|
|
||||||||||||
|
Definition at line 1579 of file dsp.c. References ast_dsp::features.
01580 {
01581 dsp->features = features;
01582 }
|
|
||||||||||||
|
Definition at line 1589 of file dsp.c. References ast_dsp::threshold.
01590 {
01591 dsp->threshold = threshold;
01592 }
|
|
||||||||||||||||
|
Definition at line 1347 of file dsp.c. References AST_FORMAT_SLINEAR, AST_FRAME_VOICE, ast_log(), ast_frame::data, ast_frame::datalen, ast_frame::frametype, LOG_WARNING, s, and ast_frame::subclass. Referenced by ast_app_getvoice().
01348 {
01349 short *s;
01350 int len;
01351
01352 if (f->frametype != AST_FRAME_VOICE) {
01353 ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
01354 return 0;
01355 }
01356 if (f->subclass != AST_FORMAT_SLINEAR) {
01357 ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
01358 return 0;
01359 }
01360 s = f->data;
01361 len = f->datalen/2;
01362 return __ast_dsp_silence(dsp, s, len, totalsilence);
01363 }
|
1.3.5