/* the given sample is decoded. if the sample is not long enough for a *completeframe,thedecodingisfinishedandcontinuedwiththenext *callofthisfunction. * *thealgorithmisverygoodfordetectionwithaminimumoferrors.i *testeditallot.itevenworkswithveryshorttones(40ms).theonly *disadvantageis,thatitdoesn'tworkgoodwithdifferentvolumesofboth *tones.thiswillhappen,ifaccousticallycoupleddialersareused. *itsometimesdetectstonesduringspeech,whichisnormalfordecoders. *usesequencestogivencommandsduringcalls. * *dtmf-pointstoastructureofthecurrentdtmfstate *splandlen-thesample *fmt-0=alaw,1=ulaw,2=coefficientsfromHFCDTMFhw-decoder
*/
u8
*dsp_dtmf_goertzel_decode(struct dsp *dsp, u8 *data, int len, int fmt)
{
u8 what; int size; signedshort *buf;
s32 sk, sk1, sk2; int k, n, i;
s32 *hfccoeff;
s32 result[NCOEFF], tresh, treshl; int lowgroup, highgroup;
s64 cos2pik_;
dsp->dtmf.digits[0] = '\0';
/* Note: The function will loop until the buffer has not enough samples *lefttodecodeafullframe.
*/
again: /* convert samples */
size = dsp->dtmf.size;
buf = dsp->dtmf.buffer; switch (fmt) { case0: /* alaw */ case1: /* ulaw */ while (size < DSP_DTMF_NPOINTS && len) {
buf[size++] = dsp_audio_law_to_s32[*data++];
len--;
} break;
if (size < DSP_DTMF_NPOINTS) return dsp->dtmf.digits;
dsp->dtmf.size = 0;
/* now we have a full buffer of signed long samples - we do goertzel */ for (k = 0; k < NCOEFF; k++) {
sk = 0;
sk1 = 0;
sk2 = 0;
buf = dsp->dtmf.buffer;
cos2pik_ = cos2pik[k]; for (n = 0; n < DSP_DTMF_NPOINTS; n++) {
sk = ((cos2pik_ * sk1) >> 15) - sk2 + (*buf++);
sk2 = sk1;
sk1 = sk;
}
sk >>= 8;
sk2 >>= 8; if (sk > 32767 || sk < -32767 || sk2 > 32767 || sk2 < -32767)
printk(KERN_WARNING "DTMF-Detection overflow\n"); /* compute |X(k)|**2 */
result[k] =
(sk * sk) -
(((cos2pik[k] * sk) >> 15) * sk2) +
(sk2 * sk2);
}
/* our (squared) coefficients have been calculated, we need to process *them.
*/
coefficients:
tresh = 0; for (i = 0; i < NCOEFF; i++) { if (result[i] < 0)
result[i] = 0; if (result[i] > dsp->dtmf.treshold) { if (result[i] > tresh)
tresh = result[i];
}
}
if (tresh == 0) {
what = 0; goto storedigit;
}
if (dsp_debug & DEBUG_DSP_DTMFCOEFF) {
s32 tresh_100 = tresh/100;
/* calc digit (lowgroup/highgroup) */
lowgroup = -1;
highgroup = -1;
treshl = tresh >> 3; /* tones which are not on, must be below 9 dB */
tresh = tresh >> 2; /* touchtones must match within 6 dB */ for (i = 0; i < NCOEFF; i++) { if (result[i] < treshl) continue; /* ignore */ if (result[i] < tresh) {
lowgroup = -1;
highgroup = -1; break; /* noise in between */
} /* good level found. This is allowed only one time per group */ if (i < NCOEFF / 2) { /* lowgroup */ if (lowgroup >= 0) { /* Bad. Another tone found. */
lowgroup = -1; break;
} else
lowgroup = i;
} else { /* higroup */ if (highgroup >= 0) { /* Bad. Another tone found. */
highgroup = -1; break;
} else
highgroup = i - (NCOEFF / 2);
}
}
/* get digit or null */
what = 0; if (lowgroup >= 0 && highgroup >= 0)
what = dtmf_matrix[lowgroup][highgroup];
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.