Morse Code with Python

Posted on Updated on

Morse code is a method used in telecommunication to encode text characters as standardized sequences of two different signal duration, called dots and dashes. Morse code is named after Samuel Morse, one of the inventors of the telegraph (wikipedia).

The example code below illustrates taking input from the terminal, converting it into Morse code, playing the Morse code sound signal, then converts the Morse code back into plain text and prints this to the screen. This is a base set of code you can use and can be easily extended to make it more interactive.

When working with sound and audio in Python there are lots of different libraries available for this. But some of the challenges is trying to pick a suitable one, and one that is still supported in more recent times. One of the most commonly referenced library is called Winsound, but that is for Windows based computers. Not everyone uses Windows machines, just like myself using a Mac. So Winsound wasn’t an option. I selected to use the playsound library, mainly based on how commonly referenced it is.

To play the dots and dashs, I needed some sound files and these were originally sources from Wikimedia. The sound files are available on wikimedia, but these come in ogg file formats. I’ve converted the dot and dash files to mp3 files and theses can be downloaded from here, dot download and dash download. I also included a Error sound file in my code for when an error occurs! Error download.

When you download the code and sound files, you might need to adjust the timing for playing the Morse code sound files, as this might be dependent on your computer

The Morse code mapping was setup as a dictionary and a reverse mapping of this dictionary was used to translate morse code into plain text.

import time
from playsound import playsound

toMorse = {'a': ".-",    'b': "-...", 
           'c': "-.-.",  'd': "-..", 
           'e': ".",     'f': "..-.", 
           'g': "--.",   'h': "....", 
           'i': "..",    'j': ".---", 
           'k': "-.-",   'l': ".-..", 
           'm': "--",    'n': "-.", 
           'o': "---",   'p': ".--.", 
           'q': "--.-",  'r': ".-.", 
           's': "...",   't': "-", 
           'u': "..-",   'v': "...-", 
           'w': ".--",   'x': "-..-", 
           'y': "-.--",  'z': "--..",
           '1': ".----", '2': "..---", 
           '3': "...--", '4': "....-", 
           '5': ".....", '6': "-....", 
           '7': "--...", '8': "---..", 
           '9': "----.", '0': "-----",
           ' ': " ",   '.': ".-.-.-", 
           ',': "--..--", '?': "..--..", 
           "'": ".----.", '@': ".--.-.", 
           '-': "-....-", '"': ".-..-.", 
           ':': "---...", ';': "---...",
           '=': "-...-",  '!': "-.-.--", 
           '/': "-..-.",  '(': "-.--.", 
           ')': "-.--.-", 'á': ".--.-", 
           'é': "..-.."}

#sounds from https://commons.wikimedia.org/wiki/Morse_code
soundPath = "/Users/brendan.tierney/Dropbox/4-Datasets/morse_code_audio/"
#adjust this value to change time between dots/dashes
tBetween = 0.1

def play_morse_beep():
    playsound(soundPath + 'Dot_morse_code.mp3')
    time.sleep(1 * tBetween)
    
def play_morse_dash():
    playsound(soundPath + 'Dash_morse_code.mp3')
    time.sleep(2 * tBetween)
    
def play_morse_space():
    time.sleep(2 * tBetween)

def play_morse_error():
    playsound(soundPath + 'Error_invalid_char.mp3')
    time.sleep(2 * tBetween)

def text_to_morse(inStr):
    mStr = ""
    for c in [x for x in inStr]:
        m = toMorse[c]
        mStr += m + ' '

    print("morse=",mStr) 
    return mStr

def play_morse(inMorse):
    for m in inMorse:
        if m == ".":
            play_morse_beep()
        elif m == "-":
            play_morse_dash()
        elif m == " ":
            play_morse_space()
        else:
            play_morse_error()
            
#Get Input Text
from colorama import Fore, Back, Style

print(Fore.RED + '')

inputStr = input("Enter text -> morse :").lower() #.strip()
print(Fore.BLACK + '' + inputStr)

mStr = text_to_morse(inputStr)
play_morse(mStr)

play_morse(mStr)

Then to reverse the Morse code.

#reverse the k,v 
mToE = {}
for key, value in toMorse.items():
        mToE[value] = key

def morse_to_english(inStr):
    inStr = inStr.split(" ")
    engStr = [] 
    for c in inStr:
        if c in mToE:
            engStr.append(mToE[c])

    return "".join(engStr)

x=morse_to_english(mStr)
print(x)
Advertisement