DTMF encoder (phone dial tones)

Build a DTMF encoder.  The Wikipedia page for DTMF gives a table of the tonal frequencies.  For each keypress of a telephone keypad, the system combines a row tone and a column tone and sends both.

Your code should take a string of arbitrary length, e.g., “(123)-456-7890” and encode the values that correspond to valid keys and ignore the rest.  E.g., “12  34aB-cd$%^&76” should output the tones for “1234abcd76” (allow both ‘b’ and ‘B’, etc.).   Make each keypress a half second long and put a tenth of a second of silence between the keypresses.  Do not add a silence period at the end.  Ideally, both the silence length and the keypress length should be easily settable (and resettable) parameters.

Use Fs=8000, the standard sampling rate for telephone quality audio.

an .ipynb file (iPython notebook) 

Solution

{

“cells”: [

{

“cell_type”: “markdown”,

“metadata”: {},

“source”: [

“## DTMF decoder\n”,

“This is a DTMF recoder written in Python. It requires pyaudio and numpy modules. ”

]

},

{

“cell_type”: “code”,

“execution_count”: null,

“metadata”: {},

“outputs”: [],

“source”: [

“importpyaudio\n”,

“importnumpy as np\n”,

“\n”,

“# Main function\n”,

“def main():\n”,

“\n”,

”    # Playback parameter\n”,

”    silence_length = 0.1\n”,

”    tone_length    = 0.5\n”,

”    sampling_freq  = 8000\n”,

”    volume         = 0.5\n”,

“\n”,

”    # Define frequencies\n”,

”    freq = [697.0, 770.0, 852.0, 941.0, 1209.0, 1336.0, 1477.0, 1633.0]\n”,

“\n”,

”    # Define tones (combinations of two frequencies)\n”,

”    tones = {\n”,

”        ‘1’: (freq[0],freq[4]),\n”,

”        ‘2’: (freq[0],freq[5]),\n”,

”        ‘3’: (freq[0],freq[6]),\n”,

”        ‘A’: (freq[0],freq[7]),\n”,

”        ‘4’: (freq[1],freq[4]),\n”,

”        ‘5’: (freq[1],freq[5]),\n”,

”        ‘6’: (freq[1],freq[6]),\n”,

”        ‘B’: (freq[1],freq[7]),\n”,

”        ‘7’: (freq[2],freq[4]),\n”,

”        ‘8’: (freq[2],freq[5]),\n”,

”        ‘9’: (freq[2],freq[6]),\n”,

”        ‘C’: (freq[2],freq[7]),\n”,

”        ‘*’: (freq[3],freq[4]),\n”,

”        ‘0’: (freq[3],freq[5]),\n”,

”        ‘#’: (freq[3],freq[6]),\n”,

”        ‘D’: (freq[3],freq[7]),\n”,

”    }\n”,

“\n”,

”    # Generate time axis\n”,

”    t = np.linspace(0,tone_length,int(sampling_freq*tone_length)+1)\n”,

“\n”,

”    # Generate silence (zero wave)\n”,

”    s = np.zeros(int(sampling_freq*silence_length),dtype=’float32′)\n”,

“\n”,

”    # Create audio instance\n”,

”    play = pyaudio.PyAudio()\n”,

”    sound = play.open(rate=sampling_freq, channels=1, format=pyaudio.paFloat32, output=True)\n”,

“\n”,

”    # Get input string from user\n”,

”    keys = input(‘Insert string:’).upper()\n”,

“\n”,

”    # Filter key\n”,

”    keys = [k for k in keys if k in tones]\n”,

“\n”,

”    # Function to play the tones\n”,

”    fork,key in enumerate(keys):\n”,

”        tone = tones[key]\n”,

“\n”,

”        # Generate sound wave\n”,

”        wave = volume*np.sin(2.0*np.pi*t*tone[0]) + np.sin(2.0*np.pi*t*tone[1])\n”,

”        wave = wave.astype(‘float32’)\n”,

“\n”,

”        # Send wave to sound stream\n”,

”        sound.write(wave.tostring())\n”,

“\n”,

”        # Silence\n”,

”        if k+1 != len(keys): sound.write(s.tostring())\n”,

“\n”,

”    # Close everything\n”,

”    sound.close()\n”,

”    play.terminate()\n”,

”    return\n”,

“\n”,

“if __name__ == \”__main__\”:\n”,

”    main()”

]

},

{

“cell_type”: “markdown”,

“metadata”: {},

“source”: []

}

],

“metadata”: {

“kernelspec”: {

“display_name”: “Python 3”,

“language”: “python”,

“name”: “python3”

},

“language_info”: {

“codemirror_mode”: {

“name”: “ipython”,

“version”: 3

},

“file_extension”: “.py”,

“mimetype”: “text/x-python”,

“name”: “python”,

“nbconvert_exporter”: “python”,

“pygments_lexer”: “ipython3”,

“version”: “3.4.3”

}

},

“nbformat”: 4,

“nbformat_minor”: 2

}