Skip to main content

A zero-heap, no_std, const-first DTMF keypad frequency table with runtime tolerance helpers.

Project description

DTMF Table

A zero-heap, no_std friendly, const-first implementation of the standard DTMF (Dual-Tone Multi-Frequency) keypad used in telephony systems.

Available for both Rust and Python, this library provides compile-time safe mappings between keypad keys and their canonical low/high frequencies, along with runtime helpers for practical audio processing.


Features

  • Const-evaluated forward and reverse mappings between DTMF keys and frequencies
  • Closed enum for keys — invalid keys are unrepresentable
  • Zero allocations, works in no_std environments (Rust)
  • Runtime helpers:
    • Tolerance-based reverse lookup (e.g., from FFT peaks)
    • Nearest snapping for noisy frequency estimates
    • Iteration over all tones and keys

Installation

Rust

cargo add dtmf_tones

The Rust crate is no_std by default and does not pull in any dependencies.

Python

pip install dtmf-table

The Python package provides the same functionality with a Pythonic API built on fast Rust bindings.


Quick Example

Rust Python
use dtmf_table::{DtmfTable, DtmfKey};

fn main() {
    // Construct a zero-sized table instance
    let table = DtmfTable::new();

    // Forward lookup from key to canonical frequencies
    let (low, high) = DtmfTable::lookup_key(DtmfKey::K8);
    assert_eq!((low, high), (852, 1336));

    // Reverse lookup with tolerance (e.g., from FFT bin centres)
    let key = table.from_pair_tol_f64(770.2, 1335.6, 6.0).unwrap();
    assert_eq!(key.to_char(), '5');

    // Nearest snapping for noisy estimates
    let (k, snapped_low, snapped_high) = table.nearest_u32(768, 1342);
    assert_eq!(k.to_char(), '5');
    assert_eq!((snapped_low, snapped_high), (770, 1336));
}
from dtmf_table import DtmfTable, DtmfKey

# Construct a table instance
table = DtmfTable()

# Forward lookup from key to canonical frequencies
key = DtmfKey.from_char('8')
low, high = key.freqs()
assert (low, high) == (852, 1336)

# Reverse lookup with tolerance (e.g., from FFT bin centres)
key = table.from_pair_tol_f64(770.2, 1335.6, 6.0)
assert key.to_char() == '5'

# Nearest snapping for noisy estimates
key, snapped_low, snapped_high = table.nearest_u32(768, 1342)
assert key.to_char() == '5'
assert (snapped_low, snapped_high) == (770, 1336)

Why Const-First?

Most DTMF tone mappings are fixed, known at compile time, and tiny (4×4 keypad). By making the mapping fully const, you can:

  • Use it inside const fn, static initialisers, or const generic contexts
  • Catch invalid keys at compile time
  • Eliminate runtime table lookups entirely

API Overview

Core Functions

Rust Function Python Equivalent Description Rust const
DtmfKey::from_char DtmfKey.from_char Convert a char to a key (fallible)
DtmfKey::from_char_or_panic N/A (raises exception) Convert a char to a key, panics at compile time if invalid
DtmfKey::to_char DtmfKey.to_char Convert key to char
DtmfKey::freqs DtmfKey.freqs Get frequencies for a key
DtmfTable::lookup_key DtmfTable.lookup_key Forward lookup: key → (low, high)
DtmfTable::from_pair_exact DtmfTable.from_pair_exact Reverse lookup: exact pair → key
DtmfTable::from_pair_normalised DtmfTable.from_pair_normalised Reverse lookup: order-insensitive
DtmfTable::from_pair_tol_f64 DtmfTable.from_pair_tol_f64 Reverse lookup with tolerance
DtmfTable::nearest_u32 DtmfTable.nearest_u32 Snap noisy frequencies to nearest canonical pair
DtmfTable::iter_tones DtmfTable.all_tones Iterate over all tones

Python-Specific Features

Function Description
DtmfTable.all_keys() Get all DTMF keys as a list
DtmfTable.all_tones() Get all DTMF tones as a list
DtmfTable.nearest_f64() Float version of nearest snapping

Integration Example

This library pairs naturally with audio analysis pipelines. For example:

  • Take an audio segment
  • Compute FFT magnitude
  • Pick two frequency peaks
  • Use from_pair_tol_f64 or nearest_f64 to resolve the DTMF key
Rust Python
// freq1 and freq2 are the peak frequencies extracted from your FFT
let key = table.from_pair_tol_f64(freq1, freq2, 5.0);
if let Some(k) = key {
    println!("Detected key: {}", k.to_char());
}
# freq1 and freq2 are the peak frequencies extracted from your FFT
key = table.from_pair_tol_f64(freq1, freq2, 5.0)
if key is not None:
    print(f"Detected key: {key.to_char()}")

Documentation


License

This project is licensed under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

dtmf_table-1.0.3.tar.gz (19.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

dtmf_table-1.0.3-cp312-cp312-manylinux_2_34_x86_64.whl (232.9 kB view details)

Uploaded CPython 3.12manylinux: glibc 2.34+ x86-64

File details

Details for the file dtmf_table-1.0.3.tar.gz.

File metadata

  • Download URL: dtmf_table-1.0.3.tar.gz
  • Upload date:
  • Size: 19.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: maturin/1.9.0

File hashes

Hashes for dtmf_table-1.0.3.tar.gz
Algorithm Hash digest
SHA256 46c751efa8e94c7b27e3cef3606bb57cba4e8f024a71cd190d53142c711ebeb1
MD5 ba9a00d7cab007eece9566852caece78
BLAKE2b-256 dcb63c204b901c883701ffc6b4537dab55bf830f77f27d01213b36b2e86df4bc

See more details on using hashes here.

File details

Details for the file dtmf_table-1.0.3-cp312-cp312-manylinux_2_34_x86_64.whl.

File metadata

File hashes

Hashes for dtmf_table-1.0.3-cp312-cp312-manylinux_2_34_x86_64.whl
Algorithm Hash digest
SHA256 b03f53f7d1f2b638e1bbcaa3a5818aed8d40825ad8419e92f3750d4cf82f2b7e
MD5 b25e1edd46a375f553d2064811e8ad0f
BLAKE2b-256 ac649f5ee9242d1d3320631144995d9de6489cccc06defc2c493341cdd9043b2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page