📄 dtmf.h
字号:
/*---------------------------------------------------------------------*
* *
* THIS IS AN UNPUBLISHED WORK CONTAINING CONFIDENTIAL AND PROPRIETARY *
* INFORMATION. IF PUBLICATION OCCURS, THE FOLLOWING NOTICE APPLIES: *
* "COPYRIGHT 2001 MIKET DSP SOLUTIONS, ALL RIGHTS RESERVED" *
* *
*---------------------------------------------------------------------*/
/* DESCRIPTION:
ENHANCED LOW-MIPS DTMF DETECTOR.
This is more a technology rather than a product.
It has its roots in sub-band echo cancellation technology and
a parametric version of maximum likehood spectrum estimatiom mathod.
It is not based on Goertzel.
It can serve as a basis to build fast voice-fax-modem discriminators,
MF, CP detector, etc.
The design is tailered to the newest DSPs (C55x in particulary)
with dual MAC and 3+ data read paths.
MIPS:
current estimate: 0.25 MIPS (or less...).
pure MMACS ~0.3.
CODE SIZE:
currently unknown.
CHARACTERIZATION:
See test doc.
*/
#ifndef _dtmf_h
#define _dtmf_h 1
#include "stddefs.h"
/*--------------------- local defs ------------------------------------*/
/* definitions of the report word, returned by DTMF_process() */
/* MSByte of Report */
/* Normally, user shall get a sequence of
EV_EARLY_ON,
EV_START,
EV_END.
*/
/* no changes happened this frame */
#define DTMF_EV_NONE ((S16)(0<<8))
/* that's probably a tone. This event is reported after 3.7...4.6 frames,
if the frame is 5ms. It gives 18..23 ms of accumulation time.
given that last frame shall not be processed by a vocoder,
and that minimal delay of 'heavy vocoders' (G.729) is 5ms,
(7.5ms for G.723.1),
only up to 13 ms of DTMF will 'leak' into bearer.
this number is OK with ATM forum documents, prescribing
that less than 20 ms of DTMF tone may be trasmitted.
No additional system delay to accomodate for dtmf relay required. */
#define DTMF_EV_EARLY_ON ((S16)(1<<8))
/* that's is not a tone.
after EV_EARLY_ON was sent, DTMF detector may send EV_EARLY_OFF
event to notify system that previous notification was false. */
#define DTMF_EV_EARLY_OFF ((S16)(2<<8))
/* The tone was OK for prescibed MinToneDuration.
that's a tone for sure, we can say now. */
#define DTMF_EV_START ((S16)(3<<8))
/* The tone is over now. Clean and clear finish.
The tone was followed by a relative 'silence'
with the power level less than the threshold. */
#define DTMF_EV_END ((S16)(4<<8))
/* something is wrong with this tone.
It started Ok, went on ok for several frames,
but something went wrong afterwards.
As the result, it did not end properly. */
#define DTMF_EV_ABORT ((S16)(5<<8))
/* LSByte of Report. */
#define DTMF_TONE_0 (0)
#define DTMF_TONE_1 (1)
#define DTMF_TONE_2 (2)
#define DTMF_TONE_3 (3)
#define DTMF_TONE_4 (4)
#define DTMF_TONE_5 (5)
#define DTMF_TONE_6 (6)
#define DTMF_TONE_7 (7)
#define DTMF_TONE_8 (8)
#define DTMF_TONE_9 (9)
#define DTMF_TONE_A (10)
#define DTMF_TONE_B (11)
#define DTMF_TONE_C (12)
#define DTMF_TONE_D (13)
#define DTMF_TONE_STAR (14)
#define DTMF_TONE_POUND (15)
/* definition of Cmd param of DTMF_control(), to be or'ed
OFF:
disable detector from running.
function DTMF_process will return almost immediately.
RESET:
reset database variables, data saving buffers, statistics, etc.
preserves ptr to config data. */
#define DTMF_CMD_OFF (1)
#define DTMF_CMD_RESET (2)
/* All relevant parameters are expressed in dB, scaled up with a coeff,
so that
1 dB corresponds to 512/3.0103 ~ 170.083 ~ 170
The same definition is applied to Freq deviation, but here
1% of freq deviation corresponds to 170.083 (the same value).
The scaling was chosen as a compromise:
- to make log scale computation fast and simple;
- to allow enough breathing space to run averaging;
- leave some headroom for data manipulation;
- allow non-integer values;
- 0 corresponds to 0dBm signal (averaged over 40 samples),
mu-law data (8159*4 max);
- negative values for attenuated signal;
- min value corresponds to approx. -82.5 dBm;
- precision is about 0.25 dB. */
#define DTMF_1DB (170)
/* DTMF detector allows user to set several thresholds
to customize detector for particular circumstances.
This is provided because the requirements for DTMF receiver
differ from country to country, from application to
application. COs, PBXs, IVRs, Call centers, etc may have quite different
view of what signal shall be rejected and which shall be
accepted.
While setting configuration is left to discretion of the
user, it is recommended to be aware of the consequences.
If you 'open gates' too wide, talk-off imminuty will suffer.
If you 'close the gates' to minimal levels,
DTMF detector may reject slightly noisy signals, or
signals with echoed voice (IVR w/o EC specific).
The run-time configuration fields include:
sNoiseThr:
Max frame energy of backgrown noise relative to signal level.
It also should cover max level of so called 'echo DTMF'.
Recommended range: 6...15 dB.
sMinEnThr:
Min frame energy to count a frame as valid.
The major usage of this thr is to accomodate for input data
which is not MSB scaled.
If the input data is scaled down so that +3.17 dBm corresponds
to 8159 amplitude (pure mu-law) or whatever else number,
change this threshold proportionally lower.
Recommended range -35...-25 dB.
A note of caution:
DTMF detector may and will detect DTMF signals
as low as -60...65 dBm, but it is not recommended
to stretch acceptance range towards such low values
without a practical need.
Imagine an office with 2 people in it, both using phones.
if one person in this office dials on his/her handsfree phone
which echos it back as DTMF, then this echo might be picked up by
another person's handset and sent towards, possibly,
this DTMF detector, and thus reported as a normal dialed digit
[by the second person].
sSumEnThr:
To set how cumulative energy in bands of
680...950Hz
1200...1650Hz
340...450 Hz
is allowed to differ from 'raw' frame energy.
If high talk-down immunity is required,
then allow for bigger discrepancy.
Recommended range 1.5...5 dB.
s2kUpThr:
The signal above 2kHz shall be lower than the signal below 2kHz
by at least this threshold.
Recommended range 10...20 dB.
sVarThr:
How current frame energy for either low freq or high freq is allowed
to differ from it's average value.
Recommended range 1...3 dB.
sFwdTwistThr:
As per spec definiton (Fwd or Standard ...).
The value has about 0.5dB headroom,
but allow more headroom for very noisy conditons.
Recommended value for US, CA 4dB.
sRevTwistThr:
As per spec definiton.
The value has about 0.5dB headroom,
but allow more headroom for very noisy conditons.
Recommended value for US, CA 8dB.
sPartThr:
A low/high frequency might be lower than the respective band energy
no more than the value.
Recommended range 1.5...3 dB.
sCleanThr:
How energy of max component in band shall be higher than
any other components.
Recommended range 6...13 dB.
Values above 13 dB will not work at all.
sMaxFreqDevThr:
Max allowed deviation of an 'instanteneous' frame frequency
from the standartized value, in percents (see DTMF_1DB notes).
As a guideline (in 'usual' conditions), acceptance margin will be
sMaxFreqDevThr - 0.35%
rejection margin will be
sMaxFreqDevThr + 0.15%.
Range tested: 1.0...3.0%.
Note that the margins for sMaxFreqDevThr > 2.5% will be 'wider'.
Note that the amount of EV_EARLY_ON will grow if 'gates are wide open'.
BellCore test gives the number of EV_EARLY_ONs almost doubling
per 0.5% increase in sMaxFreqDevThr.
sMinToneDuration:
How long after EV_EARLY_ON was send we wait before sending
event EV_START.
The mapping to DTMF durations (approximate):
Rejected if duration < sMinToneDuration*5 + 17ms.
Accepted if duration > sMinToneDuration*5 + 22ms.
sMinPostSilenceDuration:
For how long relative silence (sNoiseThr) shall be present after
the tone has ended. If so called 'echo DTMF' is present,
adjust both sNoiseThr and sMinPostSilenceDuration to
ignore this 'echo'.
Recommended range 3...6 (15..30ms).
S16 sAbortTimeout:
If a faulty tone happened, ignore the signal for
for the given number of 5ms frames.
Recommended range 3...6 (15..30ms).
sNoiseThr, sSumEnThr, s2kUpThr, sVarThr, sPartThr, sCleanThr
are the major configuration component that affect
noise performance, talk-off immunity, and talk-down
performance (DTMF on the backgrownd of voice),
By proper configuring those thresholds, user can achieve
desired balance. */
typedef struct DTMF_tCfg {
S16 sNoiseThr;
S16 sMinEnThr;
S16 sSumEnThr;
S16 sVarThr;
S16 s2kUpThr;
S16 sFwdTwistThr;
S16 sRevTwistThr;
S16 sPartThr;
S16 sCleanThr;
S16 sMaxFreqDevThr;
S16 sMinToneDuration;
S16 sMinPostSilenceDuration;
S16 sAbortTimeout;
} DTMF_tCfg;
/* DTMF detector calculates statistics of the signal
when it decides that it is a valid digit.
The statistics include:
sEn:
Average frame energy.
sLoEn:
sHiEn:
Average energy of the max freq component in low/high band
(on or about 697, 770, 852, 941 Hz)/
(on or about 1209, 1336, 1477, 1633 Hz).
The measurements are corrected to be 'precise'
if the actual frequency differs from the nominal value
by <= 2%.
Average energy of the max freq component in low band
sLoFreqDev:
sHiFreqDev:
Average devation of the frequency off the 'standard',
mentioned above values.
DTMF detector keeps this data for sMinPostSilenceDuration or
sAbortTimeout frames after the digit ended.
User shall retrieve this data beforehand if required.
Data precision depends on noise and tone duration.
If used in low-noise conditions with long digits (200ms+),
the energies are correct with precision of about 0.6 dB,
and offsets are correct with precision of about 0.2%.
For AWGN 15dB SNR, 50 ms digits, freq dev < 2%,
freq measurement sigma ~0.5Hz for low band and ~1.5Hz for high band. */
typedef struct DTMF_tStats
{
S16 sEn;
S16 sLoEn;
S16 sHiEn;
S16 sLoFreqDev;
S16 sHiFreqDev;
} DTMF_tStats;
/*--------------------- public vars- ----------------------------------*/
/*--------------------- local vars ------------------------------------*/
/*--------------------- local functions -------------------------------*/
/*--------------------- public functions -----------------------------*/
/* Native API */
/* returns ptr, incremented by DTMF database size (currently 92 words)
pFrom must be be long word aligned.
it is sufficient [from MIPS point of view] to allocate database in SARAM */
extern void* DTMF_create(void *pFrom);
/* Initialises database.
pCfg can point to the same config data for any number of DTMF
detector instances. */
extern void DTMF_init (void *pDb, void *pCfg);
/* returns state of DTMF detector. 0 is idle.
Cmd is OFF and/or RESET.
If RESET is not or-ed with OFF, the detector starts running.
It is not recommened to apply OFF without RESET due to
the obvious consequences of calling _control(pDb, 0); afterwards.
Asynchronous calling _control() and _process() from different tasks
is not recommended. */
extern S32 DTMF_control(void *pDb, S16 Cmd);
/* copies statistics data to the buffer provided by user */
extern void DTMF_get_stats (void * p2db, DTMF_tStats *pStats);
/* returns report word:
- MSByte as event and
- LSByte as tone ID.
pDb must point to initialized database.
pScratch must be long-word aligned, current size = 186w.
pScratch shall point to DARAM if max speed is required,
otherwise MIPS will almost double.
pIn shall point to a frame (40 samples) of continuous data.
If DTMF receiver was turned off, then pScratch and pIn
can point anywhere. */
extern S16 DTMF_process(void *pDb, void *pScratch, S16 *pIn);
/*---------------------------------------------------------------------*/
#endif /* _dtmf_h_ */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -