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)