{"id":29482888,"url":"https://github.com/eoommaa/dtmf","last_synced_at":"2026-01-20T16:26:22.015Z","repository":{"id":302762148,"uuid":"1008626739","full_name":"eoommaa/DTMF","owner":"eoommaa","description":"DTMF project using DFT, Goertzel algorithm, and Spectrogram for Signal Processing class","archived":false,"fork":false,"pushed_at":"2025-07-24T19:50:02.000Z","size":544,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2025-07-24T22:51:59.565Z","etag":null,"topics":["dft","digital-signal-processing","discrete-fourier-transform","discrete-time-fourier-transform","dsp","dtft","dtmf","dtmf-tones","dual-tone-multi-frequency","fast-fourier-transform","fft","goertzel","goertzel-algorithm","matlab","signal-processing"],"latest_commit_sha":null,"homepage":"","language":"MATLAB","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eoommaa.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2025-06-25T20:56:54.000Z","updated_at":"2025-07-24T19:50:06.000Z","dependencies_parsed_at":"2025-07-04T05:31:30.095Z","dependency_job_id":"31d02fdd-78d4-4c1a-9ef5-2a421012aa5f","html_url":"https://github.com/eoommaa/DTMF","commit_stats":null,"previous_names":["eoommaa/dtmf"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/eoommaa/DTMF","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eoommaa%2FDTMF","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eoommaa%2FDTMF/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eoommaa%2FDTMF/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eoommaa%2FDTMF/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eoommaa","download_url":"https://codeload.github.com/eoommaa/DTMF/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eoommaa%2FDTMF/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":268832518,"owners_count":24314421,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-08-05T02:00:12.334Z","response_time":2576,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dft","digital-signal-processing","discrete-fourier-transform","discrete-time-fourier-transform","dsp","dtft","dtmf","dtmf-tones","dual-tone-multi-frequency","fast-fourier-transform","fft","goertzel","goertzel-algorithm","matlab","signal-processing"],"created_at":"2025-07-15T02:02:03.550Z","updated_at":"2026-01-20T16:26:21.976Z","avatar_url":"https://github.com/eoommaa.png","language":"MATLAB","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Dual-Tone Multi-Frequency (DTMF)\n- Dual-tone multi-frequency (DTMF) - The basis for voice communications control and is used worldwide in modern telephony to dial numbers and configure switch board\n- DTMF tone - Commonly known as a digit, is a signal consisting the sum of two sinusoids or tones with frequencies from two exclusive groups (low and high group frequency)\n  \n  A DTMF signal is expressed as $d_N[n] = sin(\\omega_on) + sin(\\omega_1n)$, where $d_N[n]$ is the digit of keypad of a discrete time index $n$, and $\\omega_o$ and $\\omega_1$ are the low and high DTMF in radians/sample.\n  \n  By using $ω_{o/1} = 2 \\times \\pi \\times f_n$ and the normalized frequency $f_n = \\frac {f_{L/H}}{F_s}$, a DTMF signal is expressed as $d_N[n] = sin(2 \\times \\pi \\times \\frac {f_{L}}{F_s} \\times n) + sin(2 \\times \\pi \\times \\frac {f_{H}}{F_s} \\times n)$ in Hz.\n- Frequencies are chosen to prevent any harmonic from being incorrectly detected by the receiver as some other DTMF tone\n\n***DTFT[^1] Frequencies for Digits Sampled at F\u003csub\u003es\u003c/sub\u003e = 8192 Hz***\n|  | 1209 Hz | 1336 Hz | 1477 Hz |\n| :-: | :-: | :-: | :-: |\n| **697 Hz** | 1 | 2 | 3 |\n| **770 Hz** | 4 | 5 | 6 |\n| **852 Hz** | 7 | 8 | 9 |\n| **941 Hz** | * | 0 | # |\n- Ex: Digit 1 is represented by the signal $d_1[n] = sin(2 \\times \\pi \\times \\frac {697}{F_s} \\times n) + sin(2 \\times \\pi \\times \\frac{1209}{F_s} \\times n)$\n\n\n# DFT Based Implementation\n## DTMF Tones Corresponding to Digits 0-9 When Pressed on a Telephone Keypad[^2]\n- Digits 0-9 are defined in a matrix called `dtmf` over interval $0 \\le n \\le 999$, where $n$ is the sample indices\n  - The matrix stores each DTMF tone as a pair of frequencies defined as as $[f_L, f_H]$\n- **Task:** Listen to each DTMF tone using the MATLAB function `sound`\n\n### Results\n*Note: First beep is Digit 0*\n\nhttps://github.com/user-attachments/assets/d005f1db-a5e3-4964-b408-3e9c4b268e8b\n\n\n## Corresponding Index $k$ for DTMF Digits[^2][^3]\n- **Task:** Compute 2048 samples of $X(e^{j\\omega})$ to determine its corresponding index $k$ using the MATLAB function `fft`[^4]\n  \n### Results\n| Frequency (Hz) | Index $k$ |\n| :-: | :-: |\n| 697 | 175 |\n| 770 | 193 |\n| 852 | 214 |\n| 941 | 236 |\n| 1209 | 303 |\n| 1336 | 335 |\n| 1477 | 370 |\n\n\n## Energy Spectrum of DTMF for Digit 8[^2]\n**Energy Spectrum and Digit 8 Frequencies**\n- $|X(e^{j\\omega _k})|^2$ - Energy in a signal at frequency $\\omega_k$\n- Digit 8's DTMF - $f_L$ = 852 Hz and $f_H$ = 1336 Hz\n- **Task:** Compute Digit 8's energy $|D_8(e^{j\\omega _k})|^2$ using the MATLAB function `ftt`\n\n### Results\n***DFT Based Implementation's Magnitude \u0026 Energy***\n| Frequency (Hz) | Magnitude | Energy |\n| :-: | :-: | :-: |\n| 697 | 1.9029 | 3.6209 |\n| 770 | 13.015 | 169.39 |\n| `852` | 500.51 | 2.5051e+05 |\n| 941 | 7.1501 | 51.124 |\n| 1209 | 6.9656 | 48.519 |\n| `1336` | 500.26 | 2.5026e+05 |\n| 1477 | 3.0512 | 9.3098 |\n\n\u003cbr\u003e\n\n***Energy Spectrum of Digit 8 Using DFT Based Implementation***\n![image](./plots/dtmf_g.png)\n\n\n## `ttdecode(x)` Function[^3]\n- `ttdecode` - MATLAB function that accepts a touch-tone signal as the input with 1000 samples for each digit and is separated by 100 samples of silence, and decodes the input to return it as a phone number\n- **Task:** Test the MATLAB function `ttdecode` on the signals\n\n### Results\n\u003e Test output to ensure the code can output all digits: 1     2     3     4     5     6     7     8     9     0\n\n\u003e Output that satisfies the scope of the project: 5     5     5     7     3     1     9\n\n\n## `ttdecode2(x)` Function[^3]\n- `ttdecode2` - MATLAB function that accepts a touch-tone signal as the input, where digits and silence can have varying lengths, and decodes the input to return it as a phone number\n  - MATLAB code loads [`touch.mat`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/touch.mat) to decode two input signals stored as vectors named `hardx1` and `hardx2`\n- **Task:** Test the MATLAB function `ttdecode2` on the two input signals in `touch.mat`\n\n### Results\n\u003e Digits from `hardx1`: 4  9  1  5  8  7  7\n\n\u003e Digits from `hardx2`: 2  5  3  1  0  0  0\n\n# Goertzel Algorithm Based Decoder Implementation\n## DFT Magnitude and Energy Spectrum of DTMF for Digit 8[^2]\n- Goertzel algorithm - An efficent method to compute the spectrum of a signal when only a small number of spectral values or frequency bins needs computing\n  - Full length of DFT does not need to be computed \n- **Task:** Compute Digit 8's DFT magnitude $|D_8[k]|$ and energy $|D_8[k]|^2$ using the MATLAB function `goertzel`[^5]\n\n### Results\n***Goertzel Algorithm's DFT Implementation's Magnitude \u0026 Energy***\n| Frequency (Hz) | Magnitude | Energy |\n| :-: | :-: | :-: |\n| 697 | 5.4727e-12 | 2.9951e-23 |\n| 770 | 8.1237e-13 | 6.5995e-25 |\n| `852` | 1024 | 1.0486e+06 |\n| 941 | 1.7206e-12 | 2.9604e-24 |\n| 1209 | 1.419e-12 | 2.0135e-24 |\n| `1336` | 1024 | 1.0486e+06 |\n| 1477 | 6.9756e-13 | 4.8659e-25 |\n\n\u003cbr\u003e\n\n***DFT Magnitude and Energy Spectrum of Digit 8 Using Goertzel Algorithm***\n![image](./plots/dtmf_goertzel_alg.png)\n\n\n# Spectrogram\n## Digit 012 Spectrogram[^2]\n- `pspectrum` - MATLAB function that computes an FFT-based spectral estimate over each sliding window and visualizes how the frequency content of the signal changes over time[^7]\n  - Signals are divided into segments, known as windows, affecting spectrogram depending on the window length due to the inverse relationship between frequency and time, expressed as $T = \\frac {1}{F_s}$\n- Digit 012 is chosen as a three-digit encoded test telephone number\n- **Task:** Compute the spectrogram of a three-digit encoded test telephone number\n\n### Windowing and Resolution\n- **Short window:** Good time resolution and choppy transitions\n- **Longer window:** Good frequency resolution and smooth transitions\n\n  For a rectangular window, the frequency resolution is the width of the main lobe, expressed as $\\Delta \\omega \\approx \\frac {4\\pi}{M+1}$ in radians or $\\Delta F = \\frac {\\Delta \\omega}{2\\pi} \\times Fs$ in Hz.\n\n  The time resolution of a signal is expressed as $\\Delta t = MT$, where $M$ is the number of samples in the window.\n\n### Results\n*Note: A rectangular window (`Leakage = 1`) is used in `pspectrum` to improve frequency resolution*\n\n***Digit 012 Signal in Time and Frequency Domain***\n![image](./plots/spectrogram_1.png)\n\n***Three-Digit DTMF Peak Frequencies***\n| Digit | Low Frequency (Hz) | High Frequency (Hz) |\n| :-: | :-: | :-: |\n| 0 | 941 | 1336 |\n| 1 | 697 | 1209 |\n| 2 | 697 | 1336 |\n\n\u003cbr\u003e\n\n***Power Spectra of Digits 0-2***\n![image](./plots/spectrogram_2.png)\n\n***Digit 012 DTMF Spectrograms***\n\n*Note: Spectrograms with different [`pspectrum` parameters](https://github.com/eoommaa/DTMF/blob/23265028efedc3723cc8f73f632df4f716a25a4b/Spectrogram/dtmf_spectrogram.m#L125-L132)[^8]*\n\n- Ex: Spectrogram 1 (Default Balance of $\\Delta F$ \u0026 $\\Delta t$)\n```matlab\n% Spectrogram 1: No ΔF \u0026 0% overlap, 'pspectrum' will find a good balance bet ΔF \u0026 Δt according to the 3-digit signal length\npspectrum(full_signal,Fs,\"spectrogram\",Leakage=1,OverlapPercent=0, ...      % 0% overlap to see the signal duration and locations in time\n    MinThreshold=-10,FrequencyLimits=[650, 1500]);                          % MinThreshold = -10dB to visualize the main freq components\n```\n\n![image](./plots/spectrogram_3.png)\n\n\n[^1]: Discrete-Time Fourier Transform (DTFT). DTFT {x[n]} ⇔ DTFT\u003csup\u003e-1\u003c/sup\u003e {X(e\u003csup\u003ejω\u003c/sup\u003e)}\n[^2]: Code by [`eoommaa`](https://github.com/eoommaa) ([`dtmf_a.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_a.m), [`dtmf_f.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_f.m),\n[`dtmf_g.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_g.m), [`dtmf_goertzel_alg.m`](https://github.com/eoommaa/DTMF/blob/main/Goertzel%20Algorithm/dtmf_goertzel_alg.m),\n\u0026 [`dtmf_spectrogram.m`](https://github.com/eoommaa/DTMF/blob/main/Spectrogram/dtmf_spectrogram.m))\n[^3]: Code by [`TeddyDo915K`](https://github.com/TeddyDo915K) ([`dtmf_f.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_f.m), [`dtmf_h.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_h.m), \u0026 [`dtmf_i.m`](https://github.com/eoommaa/DTMF/blob/main/DTF%20Based%20Implementation/dtmf_i.m))\n[^4]: [MATLAB function `fft` documentation](https://www.mathworks.com/help/matlab/ref/fft.html)\n[^5]: [MATLAB function `goertzel` documentation](https://www.mathworks.com/help/signal/ref/goertzel.html?searchHighlight=Goertzel\u0026s_tid=srchtitle_support_results_1_Goertzel)\n[^6]: [DFT Estimation with the Goertzel Algorithm](https://www.mathworks.com/help/signal/ug/dft-estimation-with-the-goertzel-algorithm.html)\n[^7]: [Practical Introduction to Time-Frequency Analysis MATLAB documentation](https://www.mathworks.com/help/signal/ug/practical-introduction-to-time-frequency-analysis.html)\n[^8]: `pspectrum` Parameters (Spectrogram [1](https://github.com/eoommaa/DTMF/blob/95b5676741261cf0e957216341d240d338d8a714/Spectrogram/dtmf_spectrogram.m#L115-L116),\n[2](https://github.com/eoommaa/DTMF/blob/95b5676741261cf0e957216341d240d338d8a714/Spectrogram/dtmf_spectrogram.m#L137-L138),\n[3](https://github.com/eoommaa/DTMF/blob/95b5676741261cf0e957216341d240d338d8a714/Spectrogram/dtmf_spectrogram.m#L146-L147), \u0026\n[4](https://github.com/eoommaa/DTMF/blob/95b5676741261cf0e957216341d240d338d8a714/Spectrogram/dtmf_spectrogram.m#L155-L156))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feoommaa%2Fdtmf","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feoommaa%2Fdtmf","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feoommaa%2Fdtmf/lists"}