A zero-heap, Rust backed, const-first DTMF keypad frequency table with runtime tolerance helpers.
Project description
A lightweight, dependency-free Python implementation of the standard DTMF (Dual-Tone Multi-Frequency) keypad used in telephony systems.
This library provides safe mappings between keypad keys and their canonical low/high frequencies, together with practical runtime helpers for resolving noisy frequency estimates produced by FFT-based audio pipelines.
The API is intentionally small, predictable, and suitable for both batch analysis and real-time signal processing.
Features
-
Canonical forward and reverse mappings between DTMF keys and frequencies
-
Closed key representation Invalid keys cannot be constructed; all validation happens at creation time
-
Zero external dependencies
-
Runtime helpers:
- Tolerance-based reverse lookup (e.g. from FFT peak estimates)
- Nearest snapping for noisy frequency measurements
- Iteration over all keys and tones
Installation
pip install dtmf-table
Quick Example
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)
Design Rationale
DTMF tone mappings are fixed, tiny (a 4×4 keypad), and stable. Rather than exposing a mutable lookup table or relying on dynamic configuration, the mapping is encoded directly in the library and validated eagerly.
This yields:
- Deterministic behaviour with no hidden state
- Early detection of invalid keys and invalid frequency pairs
- Predictable performance characteristics for tight audio loops
While Python cannot provide compile-time guarantees, the API enforces the same invariants at runtime.
API Overview
Core Types
DtmfKey
Represents a valid DTMF keypad key.
-
DtmfKey.from_char(char) -> DtmfKeyCreate a key from a character. Raises if invalid. -
key.to_char() -> strConvert a key back to its character representation. -
key.freqs() -> (int, int)Return the canonical(low_freq, high_freq)pair.
DtmfTable
Provides lookup and matching utilities.
-
DtmfTable.lookup_key(key) -> (int, int)Forward lookup: key → frequencies. -
DtmfTable.from_pair_exact(low, high) -> Optional[DtmfKey]Reverse lookup requiring an exact frequency match. -
DtmfTable.from_pair_normalised(f1, f2) -> Optional[DtmfKey]Reverse lookup ignoring frequency order. -
DtmfTable.from_pair_tol_f64(f1, f2, tol) -> Optional[DtmfKey]Reverse lookup allowing tolerance in Hz. -
DtmfTable.nearest_u32(f1, f2) -> (DtmfKey, int, int)Snap noisy integer frequency estimates to the nearest canonical pair. -
DtmfTable.nearest_f64(f1, f2) -> (DtmfKey, float, float)Float variant of nearest snapping. -
DtmfTable.all_keys() -> list[DtmfKey]Return all valid keys. -
DtmfTable.all_tones() -> list[(DtmfKey, int, int)]Return all keys with their canonical frequencies.
Integration Example
A typical audio workflow looks like:
- Extract an audio segment
- Compute an FFT magnitude spectrum
- Identify two dominant frequency peaks
- Resolve the DTMF key using tolerance or snapping
# 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()}")
This keeps the signal-processing logic decoupled from keypad semantics while remaining simple to integrate.
Documentation
- Python API: https://jmg049.github.io/dtmf_table/
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file dtmf_table-1.1.2.tar.gz.
File metadata
- Download URL: dtmf_table-1.1.2.tar.gz
- Upload date:
- Size: 9.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
bd91e624369a466a776d3f3a788057572eeb65ab9e2ce8d751366b14ea861e62
|
|
| MD5 |
096b38338f7d38826295a577aad36892
|
|
| BLAKE2b-256 |
9a81f6f10f2a686b41c774a203d57770be2fb2682ee3cb67122f966a9de1c995
|
File details
Details for the file dtmf_table-1.1.2-cp314-cp314-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: dtmf_table-1.1.2-cp314-cp314-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 247.5 kB
- Tags: CPython 3.14, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? No
- Uploaded via: maturin/1.11.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
08bd5d8ba1b219bc404ded571692d5bf1c62ad1ee2435fe6bb01df68a0f7425d
|
|
| MD5 |
00ab407d047fbfde282a1666d67ef1ba
|
|
| BLAKE2b-256 |
566d81007c9836fa9eb4ef151a161835bb05a98c2720fcb53ad65942fc90dfd9
|