sipxmedialib  Version 3.3
Private Member Functions | Private Attributes | Static Private Attributes | List of all members
MpDtmfDetector Class Reference

A simple DTMF detector class that uses the Goertzel algorithm. More...

#include <MpDTMFDetector.h>

Public Member Functions

Creators
 MpDtmfDetector (const unsigned samplesPerSec, const unsigned nProcessSamples)
 Default constructor. More...
 
virtual ~MpDtmfDetector ()
 Destructor. More...
 
Manipulators
void reset ()
 Reset the state of the detector. More...
 
void setSamplesPerSec (const unsigned samplesPerSec)
 Set the sample rate. More...
 
void setNumProcessSamples (const unsigned nProcessSamples)
 Set the number of samples to use to detect frequencies on. More...
 
UtlBoolean processSample (const MpAudioSample sample)
 Process a sample through the detector. More...
 
Accessors
unsigned getSamplesPerSec () const
 Get the sample rate. More...
 
unsigned getNumProcessSamples () const
 Get the number of samples that this detector uses to determine frequencies on. More...
 
char getLastDetectedDTMF () const
 Get the last DTMF tone that the detector detected. More...
 

Private Member Functions

void calcCoeffs ()
 Calculate coefficients needed for the goertzel algorithm. More...
 
void dtmfValidation ()
 Validate the detected frequencies detected by processSample. More...
 

Private Attributes

unsigned mSamplesPerSec
 
unsigned mNumProcessSamples
 
uint32_t mSampleCount
 
double * mQ1
 
double * mQ2
 
double * mR
 
double * mCoefs
 
char mLastDetectedDTMF
 

Static Private Attributes

static double sFreqs_to_detect []
 
static uint8_t snFreqsToDetect = sizeof(MpDtmfDetector::sFreqs_to_detect)/sizeof(double)
 

Detailed Description

A simple DTMF detector class that uses the Goertzel algorithm.

The MpDtmfDetector is a simple class that implements the goertzel algorithm for detecting multiple frequencies. It also incorporates some other checks to make sure that the DTMF tones pass other tests that are needed for working with bell standards (i.e. twist is in-range, etc).

Full Disclosure: This code is based off of the Goertzel example C code in wikipedia: http://en.wikipedia.org/w/index.php?title=Goertzel_algorithm&oldid=179514279 It has been heavily re-worked by Keith Kyzivat, but important parts may be identical.

Usage: To use this, construct it with your sample rate and an adequate value for number of samples to do the goertzel algorithm on. Then just call processSample repeatedly as you get samples. It will return /p FALSE, until /p nProcessSamples samples have been processed, after which time it will return /p TRUE. You then can get the detected DTMF using getLastDetectedDTMF(). If no DTMF was properly detected, NULL will be returned.

Constructor & Destructor Documentation

MpDtmfDetector ( const unsigned  samplesPerSec,
const unsigned  nProcessSamples 
)

Default constructor.

~MpDtmfDetector ( )
virtual

Destructor.

Member Function Documentation

void reset ( )

Reset the state of the detector.

Reset all accumulators, last detected DTMF, and recalculate coefficients.

void setSamplesPerSec ( const unsigned  samplesPerSec)

Set the sample rate.

Parameters
[in]samplesPerSec- The new sample rate to use.

This resets the object state and recalculates coefficients.

void setNumProcessSamples ( const unsigned  nProcessSamples)

Set the number of samples to use to detect frequencies on.

This sets the number of samples that are collected before running the goertzel algorithm. The Goertzel algorithm will then be run on the collected samples.

92 is shown in wikipedia, 205 is mentioned in some mailing lists as a good choice – both are only for 8khz.

Parameters
[in]nProcessSamples- the number of samples that are collected before running the goertzel algorithm.
UtlBoolean processSample ( const MpAudioSample  sample)

Process a sample through the detector.

When getNumProcessSamples() samples are processed, a DTMF tone is either detected or not. In either case, the stored last DTMF tone detected is overwritten with the current detection value.

See also
getLastDetectedDTMF()
Returns
/p FALSE if this has not yet processed a multiple of getNumProcessSamples(), /p TRUE if this has processed a multiple of getNumProcessSamples()
unsigned getSamplesPerSec ( ) const

Get the sample rate.

unsigned getNumProcessSamples ( ) const

Get the number of samples that this detector uses to determine frequencies on.

char getLastDetectedDTMF ( ) const

Get the last DTMF tone that the detector detected.

When processSample() processes getNumProcessSamples() samples, the last detected DTMF tone will be stored. Use this to access the detected tone.

If getNumProcessSamples() samples have not been processed yet, or if a tone was not detected during the last getNumProcessSamples(), then NULL will be returned here.

Returns
the last detected DTMF tone. If no tone has been detected,
void calcCoeffs ( )
private

Calculate coefficients needed for the goertzel algorithm.

These coefficients are dependent on the sample rate, so new coefficients need to be calculated whenever the sample rate changes.

From Wikipedia:

coef = 2.0 * cos( (2.0 * PI * k) / (float)GOERTZEL_N)) ; Where k = (int) (0.5 + ((float)GOERTZEL_N * target_freq) / SAMPLING_RATE));

More simply: coef = 2.0 * cos( (2.0 * PI * target_freq) / SAMPLING_RATE );

void dtmfValidation ( )
private

Validate the detected frequencies detected by processSample.

This looks at the detected frequencies, and determines if it conforms to DTMF rules as specified by bell, and others – i.e. can work well with PSTN.

Member Data Documentation

unsigned mSamplesPerSec
private
unsigned mNumProcessSamples
private
uint32_t mSampleCount
private
double sFreqs_to_detect
staticprivate
Initial value:
=
{
697, 770, 852, 941,
1209, 1336, 1477, 1633
}
uint8_t snFreqsToDetect = sizeof(MpDtmfDetector::sFreqs_to_detect)/sizeof(double)
staticprivate
double* mQ1
private
double* mQ2
private
double* mR
private
double* mCoefs
private
char mLastDetectedDTMF
private