diff --git a/README.md b/README.md index 5cbf6f3..413c6e9 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ $ sudo cp dtmf.py /usr/local/bin/dtmf You have to give a wav file (you can try to convert it with `ffmpeg -i audio.mp3 audio.wav` for example). ``` -Usage: dtmf [-h] [-v] [-l] [-r] [-d] [-t F] [-i T] file.wav +Usage: dtmf [-h] [-v] [-l] [-r] [-d] [-t F] [-i T] [-p] file.wav optional arguments: -h, --help show this help message and exit @@ -29,6 +29,7 @@ optional arguments: -d, --debug show graphs to debug -t F acceptable frequency error (in hertz, 20 by default) -i T process by T seconds intervals (0.05 by default) + -p, --processletters process keypad mapping (contigent on having a proper decode using the basic feature without --verbose mode) ``` ## Examples @@ -45,6 +46,13 @@ $ dtmf perfect-example.wav ``` As you can see it works perfectly, we have a classical French phone number. +``` +$ dtmf -p perfect-example2.wav +62#74#23#43#81#93 +Result: 62#74#23#43#81#93 +Decoded result based on Keypad: NSCITY +``` + #### The non-perfect case ``` $ dtmf not-perfect-example.wav diff --git a/dtmf.py b/dtmf.py index 7c17e83..fb225f1 100755 --- a/dtmf.py +++ b/dtmf.py @@ -5,6 +5,32 @@ from scipy.io import wavfile import argparse +keypad = { + "2": "ABC", + "3": "DEF", + "4": "GHI", + "5": "JKL", + "6": "MNO", + "7": "PQRS", + "8": "TUV", + "9": "WXYZ" +} + +def decode_sequence(sequence: str) -> str: + parts = sequence.split("#") + decoded = [] + + for part in parts: + if len(part) != 2: # must be 2 digits + continue + digit, index = part[0], int(part[1]) + + if digit in keypad and 1 <= index <= len(keypad[digit]): + decoded.append(keypad[digit][index - 1]) + else: + decoded.append("?") + return "".join(decoded) + dtmf = {(697, 1209): "1", (697, 1336): "2", (697, 1477): "3", (770, 1209): "4", (770, 1336): "5", (770, 1477): "6", (852, 1209): "7", (852, 1336): "8", (852, 1477): "9", (941, 1209): "*", (941, 1336): "0", (941, 1477): "#", (697, 1633): "A", (770, 1633): "B", (852, 1633): "C", (941, 1633): "D"} @@ -15,6 +41,7 @@ parser.add_argument("-d", "--debug", help="show graphs to debug", action="store_true") parser.add_argument("-t", type=int, metavar="F", help="acceptable frequency error (in hertz, 20 by default)", default=20) parser.add_argument("-i", type=float, metavar='T', help="process by T seconds intervals (0.04 by default)", default=0.04) +parser.add_argument("-p", "--processletters", help="process keypad mapping", action="store_true") parser.add_argument('file', type=argparse.FileType('r')) @@ -63,6 +90,7 @@ debug = args.debug verbose = args.verbose c = "" +final_result = "" if debug: print("Warning:\nThe debug mode is very uncomfortable: you need to close each window to continue.\nFeel free to kill the process doing CTRL+C and then close the window.\n") @@ -164,6 +192,7 @@ c = "" elif dtmf[(lf,hf)] != c or verbose: c = dtmf[(lf,hf)] + final_result = final_result + c print(c, end='', flush=True) if debug: @@ -171,5 +200,10 @@ print() + print("Result: ", final_result) + + if args.processletters: + print("Decoded result based on Keypad: ", decode_sequence(final_result)) + except KeyboardInterrupt: print("\nCTRL+C detected: exiting...")