TinyModem
Header-only software audio modem library
Loading...
Searching...
No Matches
tinymodem::DTMFDecoder Class Reference

DTMF (touch tone) demodulator: the PCM audio data is written to the decoder and the received keys (0-9, *, #, A-D) are written to the output. The input can be 8, 16 or 32 bit signed samples with any number of channels (only DTMFConfig::channel is evaluated). More...

#include <DTMFDecoder.h>

Inheritance diagram for tinymodem::DTMFDecoder:
Collaboration diagram for tinymodem::DTMFDecoder:

Classes

struct  Window
 Goertzel filters of one window. More...

Public Member Functions

 DTMFDecoder ()=default
 DTMFDecoder (Print &out)
DTMFConfig defaultConfig ()
 Provides a default configuration.
void setAudioInfo (audio_tools::AudioInfo info) override
 Defines the format of the input audio data.
audio_tools::AudioInfo audioInfo () override
bool begin (DTMFConfig config)
 Starts the processing with the indicated configuration.
bool begin () override
void end () override
 Processes the remaining samples and reports the end of the carrier.
void flush () override
 Processes the remaining samples (e.g. at the end of the input).
size_t write (const uint8_t *data, size_t len) override
 Provide PCM data to the decoder.
bool isCarrier () override
 true from the first key until the end of the transmission
bool isFinished () override
 true if the decoding was stopped (rx_one)
char currentKey ()
 The key which is currently received or 0.
DTMFConfig & config ()
 The configuration which was provided in begin().
 operator bool () override
Public Member Functions inherited from tinymodem::ModemDecoder
void setStatusOutput (Print &out)
 Defines the output for the ### CARRIER / ### NOCARRIER messages.
void setQuiet (bool quiet)
 Suppresses the status messages.
const char * mime () override

Protected Member Functions

void resetState ()
void resetWindow (Window &w)
float noise ()
 uniform random value in the range -0.5 to 0.5
void addSample (float x, bool add_noise)
int detect (Window &w)
void decide (int key)
 Debouncing of the detected keys.
void startOfCarrier ()
void endOfCarrier ()
Protected Member Functions inherited from tinymodem::ModemDecoder
void status (const char *fmt,...)

Static Protected Member Functions

static int strongest (const float *amp)

Protected Attributes

DTMFConfig cfg
bool is_active = false
bool is_finished = false
PcmInput input
uint32_t noise_seed = 1
int window = 205
int step = 51
float coeff [TONES]
Window windows [WINDOWS]
uint32_t timeout = 0
float twist = 6.3f
float group_ratio = 4.0f
int candidate = -1
int hits = 0
int held = -1
int misses = 0
int last_key = -1
float last_level = 0
float level = 0
bool carrier = false
uint32_t idle_samples = 0
unsigned ndata = 0
Protected Attributes inherited from tinymodem::ModemDecoder
Print * p_status = nullptr
bool is_quiet = false

Static Protected Attributes

static constexpr int TONES = 8
static constexpr int WINDOWS = 4
static constexpr float WINDOW_SEC = 205.0f / 8000.0f
static constexpr int HITS = 3
static constexpr int MISSES = 3
static constexpr float ECHO_LEVEL = 0.5f
 the same key with a lower level (relative to the last one) is an echo
static constexpr float ENERGY_RATIO = 0.3f
 part of the signal energy which must be in the two tones

Detailed Description

DTMF (touch tone) demodulator: the PCM audio data is written to the decoder and the received keys (0-9, *, #, A-D) are written to the output. The input can be 8, 16 or 32 bit signed samples with any number of channels (only DTMFConfig::channel is evaluated).

The 8 tones are measured with Goertzel filters over windows of 25.6 ms (205 samples at 8000 Hz). Four windows overlap, so that a new result is available every 6.4 ms. A key is detected when the strongest row and column tone are clearly above the other tones of their group (DTMFConfig::group_ratio_db), have a similar level (DTMFConfig::max_twist_db) and contain most of the signal energy. A key is reported after 3 consecutive detections and released after 3 windows without it. The same key is only reported again if it is at least half as strong as before: this ignores the echo at the end of a tone.

A transmission ends after DTMFConfig::rx_timeout_ms without a key: this is reported with ### NOCARRIER.

Constructor & Destructor Documentation

◆ DTMFDecoder() [1/2]

tinymodem::DTMFDecoder::DTMFDecoder ( )
default

◆ DTMFDecoder() [2/2]

tinymodem::DTMFDecoder::DTMFDecoder ( Print & out)
inline

Member Function Documentation

◆ addSample()

void tinymodem::DTMFDecoder::addSample ( float x,
bool add_noise )
inlineprotected

◆ audioInfo()

audio_tools::AudioInfo tinymodem::DTMFDecoder::audioInfo ( )
inlineoverride

◆ begin() [1/2]

bool tinymodem::DTMFDecoder::begin ( )
inlineoverride

◆ begin() [2/2]

bool tinymodem::DTMFDecoder::begin ( DTMFConfig config)
inline

Starts the processing with the indicated configuration.

◆ config()

DTMFConfig & tinymodem::DTMFDecoder::config ( )
inline

The configuration which was provided in begin().

◆ currentKey()

char tinymodem::DTMFDecoder::currentKey ( )
inline

The key which is currently received or 0.

◆ decide()

void tinymodem::DTMFDecoder::decide ( int key)
inlineprotected

Debouncing of the detected keys.

◆ defaultConfig()

DTMFConfig tinymodem::DTMFDecoder::defaultConfig ( )
inline

Provides a default configuration.

◆ detect()

int tinymodem::DTMFDecoder::detect ( Window & w)
inlineprotected

Evaluates a completed window: returns the key index (row * 4 + column) or -1

◆ end()

void tinymodem::DTMFDecoder::end ( )
inlineoverride

Processes the remaining samples and reports the end of the carrier.

◆ endOfCarrier()

void tinymodem::DTMFDecoder::endOfCarrier ( )
inlineprotected

◆ flush()

void tinymodem::DTMFDecoder::flush ( )
inlineoverridevirtual

Processes the remaining samples (e.g. at the end of the input).

Implements tinymodem::ModemDecoder.

◆ isCarrier()

bool tinymodem::DTMFDecoder::isCarrier ( )
inlineoverridevirtual

true from the first key until the end of the transmission

Implements tinymodem::ModemDecoder.

◆ isFinished()

bool tinymodem::DTMFDecoder::isFinished ( )
inlineoverridevirtual

true if the decoding was stopped (rx_one)

Implements tinymodem::ModemDecoder.

◆ noise()

float tinymodem::DTMFDecoder::noise ( )
inlineprotected

uniform random value in the range -0.5 to 0.5

◆ operator bool()

tinymodem::DTMFDecoder::operator bool ( )
inlineoverride

◆ resetState()

void tinymodem::DTMFDecoder::resetState ( )
inlineprotected

◆ resetWindow()

void tinymodem::DTMFDecoder::resetWindow ( Window & w)
inlineprotected

◆ setAudioInfo()

void tinymodem::DTMFDecoder::setAudioInfo ( audio_tools::AudioInfo info)
inlineoverride

Defines the format of the input audio data.

◆ startOfCarrier()

void tinymodem::DTMFDecoder::startOfCarrier ( )
inlineprotected

◆ strongest()

int tinymodem::DTMFDecoder::strongest ( const float * amp)
inlinestaticprotected

◆ write()

size_t tinymodem::DTMFDecoder::write ( const uint8_t * data,
size_t len )
inlineoverride

Provide PCM data to the decoder.

Member Data Documentation

◆ candidate

int tinymodem::DTMFDecoder::candidate = -1
protected

◆ carrier

bool tinymodem::DTMFDecoder::carrier = false
protected

◆ cfg

DTMFConfig tinymodem::DTMFDecoder::cfg
protected

◆ coeff

float tinymodem::DTMFDecoder::coeff[TONES]
protected

◆ ECHO_LEVEL

float tinymodem::DTMFDecoder::ECHO_LEVEL = 0.5f
staticconstexprprotected

the same key with a lower level (relative to the last one) is an echo

◆ ENERGY_RATIO

float tinymodem::DTMFDecoder::ENERGY_RATIO = 0.3f
staticconstexprprotected

part of the signal energy which must be in the two tones

◆ group_ratio

float tinymodem::DTMFDecoder::group_ratio = 4.0f
protected

◆ held

int tinymodem::DTMFDecoder::held = -1
protected

◆ HITS

int tinymodem::DTMFDecoder::HITS = 3
staticconstexprprotected

◆ hits

int tinymodem::DTMFDecoder::hits = 0
protected

◆ idle_samples

uint32_t tinymodem::DTMFDecoder::idle_samples = 0
protected

◆ input

PcmInput tinymodem::DTMFDecoder::input
protected

◆ is_active

bool tinymodem::DTMFDecoder::is_active = false
protected

◆ is_finished

bool tinymodem::DTMFDecoder::is_finished = false
protected

◆ last_key

int tinymodem::DTMFDecoder::last_key = -1
protected

◆ last_level

float tinymodem::DTMFDecoder::last_level = 0
protected

◆ level

float tinymodem::DTMFDecoder::level = 0
protected

◆ MISSES

int tinymodem::DTMFDecoder::MISSES = 3
staticconstexprprotected

◆ misses

int tinymodem::DTMFDecoder::misses = 0
protected

◆ ndata

unsigned tinymodem::DTMFDecoder::ndata = 0
protected

◆ noise_seed

uint32_t tinymodem::DTMFDecoder::noise_seed = 1
protected

◆ step

int tinymodem::DTMFDecoder::step = 51
protected

◆ timeout

uint32_t tinymodem::DTMFDecoder::timeout = 0
protected

◆ TONES

int tinymodem::DTMFDecoder::TONES = 8
staticconstexprprotected

◆ twist

float tinymodem::DTMFDecoder::twist = 6.3f
protected

◆ window

int tinymodem::DTMFDecoder::window = 205
protected

◆ WINDOW_SEC

float tinymodem::DTMFDecoder::WINDOW_SEC = 205.0f / 8000.0f
staticconstexprprotected

◆ WINDOWS

int tinymodem::DTMFDecoder::WINDOWS = 4
staticconstexprprotected

◆ windows

Window tinymodem::DTMFDecoder::windows[WINDOWS]
protected

The documentation for this class was generated from the following file: