diff -urN asterisk-1.6.2.7-rc2_orig/main/dsp.c asterisk-1.6.2.7-rc2/main/dsp.c --- asterisk-1.6.2.7-rc2_orig/main/dsp.c 2010-04-30 00:12:31.000000000 +0200 +++ asterisk-1.6.2.7-rc2/main/dsp.c 2010-04-30 00:25:50.000000000 +0200 @@ -272,7 +272,13 @@ typedef struct { - char digits[MAX_DTMF_DIGITS + 1]; + char value; + long samples; +} digit_t; + +typedef struct +{ + digit_t digits[MAX_DTMF_DIGITS + 1]; int current_digits; int detected_digits; int lost_digits; @@ -513,7 +519,8 @@ s->current_digits = 0; s->detected_digits = 0; s->lost_digits = 0; - s->digits[0] = '\0'; + s->digits[0].value = '\0'; + s->digits[0].samples = 0; if (mf) { ast_mf_detect_init(&s->td.mf); @@ -630,14 +637,22 @@ { s->detected_digits++; if (s->current_digits < MAX_DTMF_DIGITS) { - s->digits[s->current_digits++] = digit; - s->digits[s->current_digits] = '\0'; + s->digits[s->current_digits].value = digit; + s->digits[s->current_digits].samples = 0; + s->current_digits++; + s->digits[s->current_digits].value = '\0'; + s->digits[s->current_digits].samples = 0; } else { ast_log(LOG_WARNING, "Digit lost due to full buffer\n"); s->lost_digits++; } } +static void store_digit_samples(digit_detect_state_t *s, long samples) +{ + s->digits[s->current_digits - 1].samples = samples; +} + static int dtmf_detect(struct ast_dsp *dsp, digit_detect_state_t *s, int16_t amp[], int samples, int squelch, int relax) { float row_energy[4]; @@ -726,6 +741,8 @@ if (s->td.dtmf.current_hit) { /* We are in the middle of a digit already */ if (hit != s->td.dtmf.current_hit) { + /* Save number of samples on first miss */ + if (!s->td.dtmf.misses) store_digit_samples(s, s->td.dtmf.hits * DTMF_GSIZE); s->td.dtmf.misses++; if (s->td.dtmf.misses == s->td.dtmf.misses_to_end) { /* There were enough misses to consider digit ended */ @@ -1394,23 +1411,25 @@ if (dsp->digit_state.current_digits) { int event = 0; char event_digit = 0; + long event_len = 0; if (!dsp->dtmf_began) { /* We have not reported DTMF_BEGIN for anything yet */ if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { event = AST_FRAME_DTMF_BEGIN; - event_digit = dsp->digit_state.digits[0]; + event_digit = dsp->digit_state.digits[0].value; } dsp->dtmf_began = 1; - } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0]) { + } else if (dsp->digit_state.current_digits > 1 || digit != dsp->digit_state.digits[0].value) { /* Digit changed. This means digit we have reported with DTMF_BEGIN ended */ if (dsp->features & DSP_FEATURE_DIGIT_DETECT) { event = AST_FRAME_DTMF_END; - event_digit = dsp->digit_state.digits[0]; + event_digit = dsp->digit_state.digits[0].value; + event_len = dsp->digit_state.digits[0].samples * 1000 / SAMPLE_RATE; } - memmove(dsp->digit_state.digits, dsp->digit_state.digits + 1, dsp->digit_state.current_digits); + memmove(dsp->digit_state.digits, dsp->digit_state.digits + sizeof(digit_t), dsp->digit_state.current_digits * sizeof(digit_t)); dsp->digit_state.current_digits--; dsp->dtmf_began = 0; @@ -1426,6 +1445,7 @@ memset(&dsp->f, 0, sizeof(dsp->f)); dsp->f.frametype = event; dsp->f.subclass = event_digit; + dsp->f.len = event_len; outf = &dsp->f; goto done; } @@ -1607,7 +1627,7 @@ s->misses = 0; } - dsp->digit_state.digits[0] = '\0'; + dsp->digit_state.digits[0].value = '\0'; dsp->digit_state.current_digits = 0; }