/usr/include/sipxtapi/mp/MpDTMFDetector.h is in libsipxtapi-dev 3.3.0~test17-2.1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 | //
// Copyright (C) 2007 SIPfoundry Inc.
// Licensed by SIPfoundry under the LGPL license.
//
// Copyright (C) 2007 SIPez LLC.
// Licensed to SIPfoundry under a Contributor Agreement.
//
// $$
//////////////////////////////////////////////////////////////////////////////
// Author: Keith Kyzivat <kkyzivat AT SIPez DOT com>
#ifndef _MpDTMFDetector_h_
#define _MpDTMFDetector_h_
// SYSTEM INCLUDES
// APPLICATION INCLUDES
#include <os/OsIntTypes.h>
#include <mp/MpTypes.h>
#include <utl/UtlDefs.h> // UtlBoolean
// DEFINES
// EXTERNAL FUNCTIONS
// EXTERNAL VARIABLES
// CONSTANTS
// STRUCTS
// TYPEDEFS
// MACROS
// FORWARD DECLARATIONS
/**
* @brief 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.
*
*/
class MpDtmfDetector
{
/* //////////////////////////// PUBLIC //////////////////////////////////// */
public:
/* ============================ CREATORS ================================== */
///@name Creators
//@{
/// Default constructor
MpDtmfDetector(const unsigned samplesPerSec, const unsigned nProcessSamples);
/// Destructor
virtual ~MpDtmfDetector();
//@}
/* ============================ MANIPULATORS ============================== */
///@name Manipulators
//@{
/// Reset the state of the detector.
void reset();
/**<
* Reset all accumulators, last detected DTMF, and recalculate coefficients.
*/
/// Set the sample rate.
void setSamplesPerSec(const unsigned samplesPerSec);
/**<
* @param[in] samplesPerSec - The new sample rate to use.
*
* @NOTE This resets the object state and recalculates coefficients.
*/
/// Set the number of samples to use to detect frequencies on.
void setNumProcessSamples(const unsigned nProcessSamples);
/**<
* 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.
*
* @NOTE 92 is shown in wikipedia, 205 is mentioned in some mailing lists
* as a good choice -- both are only for 8khz.
*
* @param[in] nProcessSamples - the number of samples that are collected
* before running the goertzel algorithm.
*/
/// Process a sample through the detector.
UtlBoolean processSample(const MpAudioSample sample);
/**<
* 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 getLastDetectedDTMF()
*
* @return /p FALSE if this has not yet processed a multiple of getNumProcessSamples(),
* /p TRUE if this has processed a multiple of getNumProcessSamples()
*
*/
//@}
/* ============================ ACCESSORS ================================= */
///@name Accessors
//@{
/// Get the sample rate.
unsigned getSamplesPerSec() const;
/// Get the number of samples that this detector uses to determine frequencies on.
unsigned getNumProcessSamples() const;
/// Get the last DTMF tone that the detector detected.
char getLastDetectedDTMF() const;
/**<
* When processSample() processes getNumProcessSamples() samples,
* the last detected DTMF tone will be stored. Use this to access the
* detected tone.
*
* @NOTE 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.
*
* @return the last detected DTMF tone. If no tone has been detected,
*/
//@}
/* ============================ INQUIRY =================================== */
///@name Inquiry
//@{
//@}
/* //////////////////////////// PROTECTED ///////////////////////////////// */
protected:
/* //////////////////////////// PRIVATE /////////////////////////////////// */
private:
/// Calculate coefficients needed for the goertzel algorithm
void calcCoeffs();
/**<
* 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 );
*/
/// Validate the detected frequencies detected by processSample.
void dtmfValidation();
/**<
* 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.
*/
private:
unsigned mSamplesPerSec;
unsigned mNumProcessSamples;
uint32_t mSampleCount;
static double sFreqs_to_detect[];
static uint8_t snFreqsToDetect;
double* mQ1;
double* mQ2;
double* mR;
double* mCoefs;
char mLastDetectedDTMF;
};
/* ============================ INLINE METHODS ============================ */
#endif // _MpDTMFDetector_h_
|