miniDSP
A small C library for audio DSP
Loading...
Searching...
No Matches
minidsp_dtmf.c File Reference

DTMF tone detection and generation. More...

#include "minidsp.h"
Include dependency graph for minidsp_dtmf.c:

Go to the source code of this file.

Functions

static void dtmf_char_to_freqs (char ch, double *row_freq, double *col_freq)
 Map a DTMF character to its row and column frequencies.
 
static double peak_near_bin (const double *mag, unsigned num_bins, unsigned bin)
 Peak magnitude in bins [bin-1, bin, bin+1], clamped to [0, num_bins).
 
static char detect_frame (const double *mag, unsigned num_bins, unsigned N, double sample_rate)
 Detect the DTMF digit present in a single normalised magnitude frame.
 
unsigned MD_dtmf_detect (const double *signal, unsigned signal_len, double sample_rate, MD_DTMFTone *tones_out, unsigned max_tones)
 Detect DTMF tones in an audio signal.
 
void MD_dtmf_generate (double *output, const char *digits, double sample_rate, unsigned tone_ms, unsigned pause_ms)
 Generate a DTMF tone sequence.
 
unsigned MD_dtmf_signal_length (unsigned num_digits, double sample_rate, unsigned tone_ms, unsigned pause_ms)
 Calculate the number of samples needed for MD_dtmf_generate().
 

Variables

static const double dtmf_row_freqs [4] = {697.0, 770.0, 852.0, 941.0}
 
static const double dtmf_col_freqs [4] = {1209.0, 1336.0, 1477.0, 1633.0}
 
static const char dtmf_keypad [4][4]
 

Detailed Description

DTMF tone detection and generation.

Detection uses frame-based FFT magnitude analysis with a state machine enforcing ITU-T Q.24 minimum timing (40 ms tone-on, 40 ms pause).

Generation superimposes row + column sinusoids via MD_sine_wave().

Definition in file minidsp_dtmf.c.

Function Documentation

◆ detect_frame()

static char detect_frame ( const double *  mag,
unsigned  num_bins,
unsigned  N,
double  sample_rate 
)
static

Detect the DTMF digit present in a single normalised magnitude frame.

Returns the digit character, or '\0' if no valid DTMF pair is found.

Definition at line 80 of file minidsp_dtmf.c.

◆ dtmf_char_to_freqs()

static void dtmf_char_to_freqs ( char  ch,
double *  row_freq,
double *  col_freq 
)
static

Map a DTMF character to its row and column frequencies.

Asserts on invalid characters (structural misuse).

Definition at line 40 of file minidsp_dtmf.c.

◆ MD_dtmf_detect()

unsigned MD_dtmf_detect ( const double *  signal,
unsigned  signal_len,
double  sample_rate,
MD_DTMFTone tones_out,
unsigned  max_tones 
)

Detect DTMF tones in an audio signal.

Slides a Hanning-windowed FFT frame across the signal and checks each frame for a valid row + column frequency pair. A tone is reported only after it persists for at least 40 ms (ITU-T Q.24), and a new tone is not accepted until at least 40 ms of silence separates it from the previous one.

The FFT size is the largest power of two whose window fits within 35 ms, keeping it shorter than the 40 ms Q.24 minimum pause so the state machine can resolve inter-digit gaps. The hop size is N/4 (75 % overlap).

Parameters
signalAudio samples (mono).
signal_lenNumber of samples. Must be > 0.
sample_rateSampling rate in Hz. Must be >= 4000 (Nyquist for the highest DTMF frequency, 1633 Hz).
tones_outOutput array for detected tones (caller-allocated).
max_tonesSize of tones_out. Must be > 0.
Returns
Number of tones detected (<= max_tones).
// Generate a short DTMF sequence and detect it
const char *digits = "5551234";
unsigned len = MD_dtmf_signal_length(7, 8000.0, 70, 70);
double *sig = malloc(len * sizeof(double));
MD_dtmf_generate(sig, digits, 8000.0, 70, 70);
MD_DTMFTone tones[16];
unsigned n = MD_dtmf_detect(sig, len, 8000.0, tones, 16);
for (unsigned i = 0; i < n; i++)
printf("%c %.3f--%.3f s\n", tones[i].digit,
tones[i].start_s, tones[i].end_s);
free(sig);
unsigned MD_dtmf_detect(const double *signal, unsigned signal_len, double sample_rate, MD_DTMFTone *tones_out, unsigned max_tones)
Detect DTMF tones in an audio signal.
void MD_dtmf_generate(double *output, const char *digits, double sample_rate, unsigned tone_ms, unsigned pause_ms)
Generate a DTMF tone sequence.
unsigned MD_dtmf_signal_length(unsigned num_digits, double sample_rate, unsigned tone_ms, unsigned pause_ms)
Calculate the number of samples needed for MD_dtmf_generate().
A single detected DTMF tone with timing information.
Definition minidsp.h:1112

Definition at line 135 of file minidsp_dtmf.c.

◆ MD_dtmf_generate()

void MD_dtmf_generate ( double *  output,
const char *  digits,
double  sample_rate,
unsigned  tone_ms,
unsigned  pause_ms 
)

Generate a DTMF tone sequence.

Each digit is rendered as the sum of its row and column sinusoids, each at amplitude 0.5 (peak sum = 1.0). Digits are separated by silent gaps. Use MD_dtmf_signal_length() to pre-compute the required output buffer size.

Timing constraints follow ITU-T Q.24:

  • tone_ms >= 40 (minimum recognisable tone)
  • pause_ms >= 40 (minimum inter-digit pause)
Parameters
outputOutput buffer (caller-allocated, length from MD_dtmf_signal_length()).
digitsNull-terminated string of valid DTMF characters: '0'–'9', 'A'–'D' (case-insensitive), '*', '#'. An invalid character triggers an assertion failure.
sample_rateSampling rate in Hz. Must be > 0.
tone_msDuration of each tone in milliseconds (>= 40).
pause_msDuration of silence between tones in ms (>= 40).
unsigned len = MD_dtmf_signal_length(3, 8000.0, 70, 70);
double *sig = malloc(len * sizeof(double));
MD_dtmf_generate(sig, "911", 8000.0, 70, 70);
// sig now contains 3 tones of 70 ms each with 70 ms gaps
free(sig);

Definition at line 319 of file minidsp_dtmf.c.

◆ MD_dtmf_signal_length()

unsigned MD_dtmf_signal_length ( unsigned  num_digits,
double  sample_rate,
unsigned  tone_ms,
unsigned  pause_ms 
)

Calculate the number of samples needed for MD_dtmf_generate().

\[ N = D \cdot \left\lfloor \frac{t_{\text{tone}} \cdot f_s}{1000} \right\rfloor + (D - 1) \cdot \left\lfloor \frac{t_{\text{pause}} \cdot f_s}{1000} \right\rfloor \]

where \(D\) is the number of digits.

Parameters
num_digitsNumber of digits in the sequence.
sample_rateSampling rate in Hz. Must be > 0.
tone_msTone duration in milliseconds.
pause_msPause duration in milliseconds.
Returns
Total number of samples (0 if num_digits == 0).

Definition at line 361 of file minidsp_dtmf.c.

◆ peak_near_bin()

static double peak_near_bin ( const double *  mag,
unsigned  num_bins,
unsigned  bin 
)
static

Peak magnitude in bins [bin-1, bin, bin+1], clamped to [0, num_bins).

Definition at line 68 of file minidsp_dtmf.c.

Variable Documentation

◆ dtmf_col_freqs

const double dtmf_col_freqs[4] = {1209.0, 1336.0, 1477.0, 1633.0}
static

Definition at line 18 of file minidsp_dtmf.c.

◆ dtmf_keypad

const char dtmf_keypad[4][4]
static
Initial value:
= {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
}

Definition at line 27 of file minidsp_dtmf.c.

◆ dtmf_row_freqs

const double dtmf_row_freqs[4] = {697.0, 770.0, 852.0, 941.0}
static

Definition at line 17 of file minidsp_dtmf.c.