2. Morse Generador de Tonos

Un generador de tonos permite «escuchar» la señal morse de forma similar a la tradicional del telégrafo.

telegrafooperadora

Un punto '.' es la referencia o marca para el sonido morse, teniendo que :

Para identificar los tonos que representan puntos, rayas o espacios, se intercala una pausa con la misma duración que una marca.

telegrafomarca

Para el ejemplo, un punto con una duración de 0.1 segundos se expresa con una señal sinusoidad de 440Hz (una marca, nota musical «La») realizado con muestreo de 11025 veces por segundo.

El resultado buscado para un mensaje completo en código Morse es por ejemplo:

  • mensaje = 'ESPOL impulsando la sociedad del conocimiento'
  • traducido = '. ... .--. --- .-.. .. -- .--. ..- .-.. ... .- -. -.. --- .-.. .- ... --- -.-. .. . -.. .- -.. -.. . .-.. -.-. --- -. --- -.-. .. -- .. . -. - --- '
  • sonido del mensaje morse: morsetonoESPOL.wav

Algoritmo en Python

Un tono para un punto '.', una raya '-', o un espacio ' ', puede ser generado con una función en python.

El tono se realiza con los valores muestreados del tono, separado del próximo '.' o un '-', añadiendo una pausa al final.

El resultado se prepara para ser guardado en un archivo.wav, haciendo que los valores tengan el formato dtype='int16' que es necesario para la generación del archivo de sonido.

# Código Morse -  Generador de tonos
# propuesta: edelros@espol.edu.ec
import numpy as np
import scipy.io.wavfile as waves

def morsetono(simbolo, duracion=0.1 , fs=440, muestreo=11025):
    # duracion=0.1   # segundos de '.' ó ' '
    # fs=440         # Hz del tono
    # muestreo=11025 #en .wav:44100,22050,11025

    marca = 2        # un punto y pausa
    if (simbolo=='-'):
        marca = 4    # raya y pausa
        
    tonodura = marca*duracion     # en segundos
    dt = 1/muestreo 
    t  = np.arange(0,tonodura,dt)  # marcas/tiempo
    tono = np.zeros(len(t), dtype='int16') #tono vacio
    
    volumen = 0.8      # rango [0,1)
    amplitud = int((2**15)*volumen)  #wav 16 bits
    w = 2*np.pi*fs     #frecuencia en radianes
    suena = int((marca-1)*duracion*muestreo)
      
    if (simbolo=='.' or simbolo=='-'):
        for i in range(0,suena):
            tono[i] = amplitud*(np.sin(w*t[i]))
    
    return(muestreo, tono)

Para realizar una prueba a la función, se puede generar un tono '.', '-' y escuchar el resultado en un archivo.wav, similar a los mostrados al inicio para cada símbolo.

# Una prueba
simbolo = '.'
muestreo, sonido=morsetono(simbolo)

# Salida # Archivo de audio.wav
waves.write('morsetonopunto.wav', muestreo, sonido)

Para crear los tonos de un mensaje y escucharlos en un archivo.wav, se procesa el mensaje traducido en morse, símbolo a símbolo, para añadir un punto, una raya o un espacio. Los resultados de cada símbolo se acumulan en el vector sonido.

# traducido = input('Escriba el mensaje morse: ')
traducido = '. ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- '
# archivo = input('nombre del archivo a guardar: ')
archivo = 'morsetonotest.wav'

# PROCEDIMIENTO
muestreo = 11025  # para .wav: 44100, 22050, 11025
duracion = 0.04

# morse en sonido, como lista por tamaño desconocido
sonido=[]
for i in range(0,len(traducido)):
    muestreo, untono = morsetono(traducido[i], duracion)
    for j in range(0,len(untono)):
        sonido.append(untono[j])
# para .wav convierte en arreglo numpy de 'int16' 
sonido = np.asarray(sonido, dtype='int16')

# SALIDA archivo.wav
print('muetreo: ',muestreo)
print('muestras sonido: ', len(sonido))
print('.... archivo: ' + archivo +'  guardado ....')
waves.write(archivo, muestreo, sonido)

Se crea un archivo.wav con la frecuencia de muestreo y el vector sonido, que puede ser ejecutado con un programa como «windows media player».

muetreo:  11025
muestras sonido:  180810
.... archivo: morsetonotest.wav  guardado ....

Referencia: Código Morse Wikipedia, Women in early radio, Recommendation ITU-R M.1677-1 (10/2009) International Morse code, Leon-Couch, 5–9 Señalización Pasabanda Modulada Binaria (OOK)

1. Morse Codificador y decodificador

Referencia: Leon-Couch, 5–9 Señalización Pasabanda Modulada Binaria (OOK), Código Morse Wikipedia , Telégrafo Wikipedia, Recommendation ITU-R M.1677-1 (10/2009) International Morse code,

Dato Histórico – 1844 Samuel F. B. Morse muestra la línea de telégrafo en Baltimore, MD y Washington, DC

telegrafollave

El código Morse fué muy usado en telegrafía, transmisiones por radio marítimas y aéreas.

Conocido también como alfabeto Morse, cambia los caracteres alfanuméricos a códigos morse combinando puntos '.' y rayas '-'. La separación entre códigos morse se realiza con un espacio ' ', mientras que en la separación entre palabras se usan 3 espacios ' '.

Ejemplo:
un mensaje: ESPOL impulsando la sociedad del conocimiento
. ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- 

Un tema que permite revisar varios conceptos de telecomunicaciones es el telégrafo y el código Morse.

Los bloques de desarrollo usados en ésta sección se presentan el el siguiente diagrama

morsebloques


Codificador en Python

La traducción entre un caracter del alfabeto a un código morse se puede facilitar con una función dedicada a ésta tarea.

Para buscar un equivalente de un caracter en una tabla de conversión a código, por facilidad de usar como índice un caracter se propone usar un diccionario de python.

Algoritmo en Python

# Código Morse -  codificador
# propuesta: edelros@espol.edu.ec

def morsecodec(caracter):
    equivale={
        'A':'.-', 'B':'-...', 'C':'-.-.', 
        'CH':'----', 'D':'-..', 'E':'.', 
        'F':'..-.', 'G':'--.', 'H':'....', 
        'I':'..', 'J':'.---', 'K':'-.-',
        'L':'.-..', 'M':'--', 'N':'-.', 
        'Ñ':'--.--', 'O':'---', 'P':'.--.', 
        'Q':'--.-', 'R':'.-.', 'S':'...', 
        'T':'-', 'U':'..-', 'V':'...-',
        'W':'.--', 'X':'-..-', 'Y':'-.--', 
        'Z':'--..',
        '0':'-----', '1':'.----', '2':'..---', 
        '3':'...--', '4':'....-', '5':'.....', 
        '6':'-....', '7':'--...', '8':'---..', 
        '9':'----.', 
        '.':'.-.-.-', ',':'-.-.--', '?':'..--..', 
        '"':'.-..-.', '!':'--..--', ' ':' '}
    caracter=caracter.upper()
    codigo=equivale[caracter]
    return(codigo)

El programa para cambiar un mensaje a su versión morse se simplifica usando la función anterior.

# INGRESO
mensaje = input('un mensaje: ')
# mensaje= 'ESPOL impulsando la sociedad del conocimiento'

# PROCEDIMIENTO
n = len(mensaje)
traducido = ''
for caracter in mensaje:
    traducido = traducido + morsecodec(caracter) + ' '

# SALIDA
print(traducido)

La ejecución del programa y la función tiene el resultado mostrado en el ejemplo.

un mensaje: ESPOL impulsando la sociedad del conocimiento
. ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- 

Decodificador en Python

Para realizar el proceso inverso al codificador, se ingresa un código morse obtenido de un receptor a un decodificador.

Ejemplo:

mensaje en morse:
. ... .--. --- .-.. .. -- .--. ..- .-.. ... .- -. -.. --- .-.. .- ... --- -.-. .. . -.. .- -.. -.. . .-.. -.-. --- -. --- -.-. .. -- .. . -. - ---
ESPOL IMPULSANDO LA SOCIEDAD DEL CONOCIMIENTO

telegraforeceptor
telégrafo receptor

Decodificar Morse requiere usar una tabla de equivalentes descrita en el estándar internacional (ITU), en el orden contrario al codificador.

En un mensaje morse, las palabras son separadas por tres espacios ' '; en una palabra, cada código se separa por un espacio ' '.

Algoritmo en Python

La traducción de un codigo morse a un caracter del alfabeto, se puede realizar con una función.
De forma semejante al codificador, se usa la tabla de equivalentes como un diccionario.

# Código Morse -  DECOdificador
# propuesta: edelros@espol.edu.ec

def morsedeco(codigo): 
    equivale={ 
        '.-':'A', '-...':'B', '-.-.':'C', 
        '----':'CH', '-..':'D', '.':'E', 
        '..-.':'F', '--.':'G', '....':'H', 
        '..':'I', '.---':'J', '-.-':'K',
        '.-..':'L', '--':'M', '-.':'N', 
        '--.--':'Ñ', '---':'O', '.--.':'P', 
        '--.-':'Q', '.-.':'R', '...':'S', 
        '-':'T', '..-':'U', '...-':'V',
        '.--':'W', '-..-':'X', '-.--':'Y', 
        '--..':'Z',
        '-----':'0', '.----':'1', '..---':'2', 
        '...--':'3', '....-':'4', '.....':'5', 
        '-....':'6', '--...':'7', '---..':'8', 
        '----.':'9', 
        '.-.-.-':'.', '-.-.--':',', '..--..':'?', 
        '.-..-.':'"', '--..--':'!', '   ':' ', 
        ' ':' '}
    caracter=equivale[codigo]
    return(caracter)

El programa para cambiar un mensaje morse al alfabeto se simplifica usando la función anterior.

La ejecución del programa y la función tiene el resultado mostrado en el ejemplo.

# INGRESO
traducido = input('mensaje en morse: ')
# traducido='. ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- '
    
# PROCEDIMIENTO
mensaje  = ''
palabras = traducido.split('   ')
for unapalabra in palabras:
    letras = unapalabra.split(' ')
    for unaletra in letras:
        mensaje = mensaje+morsedeco(unaletra)
    mensaje = mensaje + ' '

# SALIDA
print('mensaje decodificado: ')
print(mensaje)

mensaje en morse:

. ... .--. --- .-.. .. -- .--. ..- .-.. ... .- -. -.. --- .-.. .- ... --- -.-. .. . -.. .- -.. -.. . .-.. -.-. --- -. --- -.-. .. -- .. . -. - ---

mensaje decodificado:
ESPOL IMPULSANDO LA SOCIEDAD DEL CONOCIMIENTO