{"id":42,"date":"2017-01-03T08:00:04","date_gmt":"2017-01-03T13:00:04","guid":{"rendered":"http:\/\/blog.espol.edu.ec\/estg1003\/?p=42"},"modified":"2026-04-16T09:26:15","modified_gmt":"2026-04-16T14:26:15","slug":"morse-tonos-codec-deco","status":"publish","type":"post","link":"https:\/\/blog.espol.edu.ec\/algoritmos101\/stp-aplica\/morse-tonos-codec-deco\/","title":{"rendered":"1.1. Morse por Tonos - codec y deco con Python"},"content":{"rendered":"\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"morsetono\">1. Morse - Tonos<\/h2>\n\n\n\n<p>Un generador de tonos permite \"escuchar\" la se\u00f1al morse de forma similar a la tradicional del tel\u00e9grafo.<\/p>\n\n\n\n<figure class=\"wp-block-image alignright\"><img decoding=\"async\" src=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/estg1003\/files\/2017\/04\/telegrafooperadora.png\" alt=\"telegrafooperadora\" \/><\/figure>\n\n\n\n<p>Un punto <code>'.'<\/code> es la referencia o <strong>marca<\/strong> para el <strong>sonido<\/strong> morse, teniendo que :<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>un punto <code>'.'<\/code>, cuenta como una marca : <a href=\"https:\/\/www.dropbox.com\/s\/wc909k0dffyikjq\/morsetonopunto.wav?dl=0\">morsetonopunto.wav<\/a><\/li>\n\n\n\n<li>una raya <code>'-'<\/code> dura 3 marcas : <a href=\"https:\/\/www.dropbox.com\/s\/l14ig6keoby64iy\/morsetonoraya.wav?dl=0\">morsetonoraya.wav<\/a><\/li>\n\n\n\n<li>espacio <code>' '<\/code>, que separa una palabra, dura una marca : <a href=\"https:\/\/www.dropbox.com\/s\/wwr7mkv0cafjvnp\/morsetonoespacio.wav?dl=0\">morsetonoespacio.wav<\/a><\/li>\n<\/ul>\n\n\n\n<p>Para identificar los tonos que representan puntos, rayas o <strong><em>espacios<\/em><\/strong>, se intercala una <em><strong>pausa<\/strong> <\/em>con la misma duraci\u00f3n que una <strong>marca<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"815\" height=\"615\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono01.png\" alt=\"morse codificadortono 01\" class=\"wp-image-49\" \/><\/figure>\n\n\n\n<p>Para el ejemplo, un punto con una <strong>duraci\u00f3n<\/strong> de 0.1 segundos se expresa con una se\u00f1al senoidal de 440Hz (una <strong>marca<\/strong>, nota musical \"La\") realizado con <strong>muestreo<\/strong> de 11025 veces por segundo.<\/p>\n\n\n\n<p>El resultado buscado para un mensaje completo en c\u00f3digo Morse es por ejemplo:<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>mensaje = <code>'ESPOL impulsando la sociedad del conocimiento'<\/code>\ntraducido = <code>'. ... .--. --- .-.. .. -- .--. ..- .-.. ... .- -. -.. --- .-.. .- ... --- -.-. .. . -.. .- -.. -.. . .-.. -.-. --- -. --- -.-. .. -- .. . -. - --- '<\/code><\/code><\/pre>\n\n\n\n<p>sonido del mensaje morse: <a href=\"https:\/\/www.dropbox.com\/s\/co3beeya63h69we\/morsetonosESPOL.wav?dl=0\">morsetonoESPOL.wav<\/a><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"codectono\">2. Morse un tono - Codec Algoritmo en Python<\/h2>\n\n\n\n<p>Un <strong>tono<\/strong> para un punto <code>'.'<\/code>, una raya <code>'-'<\/code>, o un espacio <code>' '<\/code>, puede ser generado con una funci\u00f3n en python.<\/p>\n\n\n\n<p>El <strong>tono<\/strong> se realiza con los valores muestreados del <strong>tono<\/strong>, separado del pr\u00f3ximo <code>'.'<\/code> o un <code>'-'<\/code>, a\u00f1adiendo una pausa al final.<\/p>\n\n\n\n<p>El resultado se prepara para ser guardado en un <strong>archivo.wav<\/strong>, haciendo que los valores tengan el formato <code>dtype='int16'<\/code> que es necesario para la generaci\u00f3n del archivo de sonido.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# C\u00f3digo Morse -  Generador de tonos\n# propuesta: edelros@espol.edu.ec\nimport numpy as np\nimport scipy.io.wavfile as waves\n\ndef morsetono(simbolo, duracion=0.1 , fs=440, muestreo=11025):\n    # duracion=0.1   # segundos de '.' \u00f3 ' '\n    # fs=440         # Hz del tono\n    # muestreo=11025 #en .wav:44100,22050,11025\n\n    marca = 2        # un punto y pausa\n    if (simbolo=='-'):\n        marca = 4    # raya y pausa\n        \n    tonodura = marca*duracion     # en segundos\n    dt = 1\/muestreo \n    t  = np.arange(0,tonodura,dt)  # marcas\/tiempo\n    tono = np.zeros(len(t), dtype='int16') #tono vacio\n    \n    volumen = 0.8      # rango &#x5B;0,1)\n    amplitud = int((2**15)*volumen)  #wav 16 bits\n    w = 2*np.pi*fs     #frecuencia en radianes\n    suena = int((marca-1)*duracion*muestreo)\n      \n    if (simbolo=='.' or simbolo=='-'):\n        for i in range(0,suena):\n            tono&#x5B;i] = amplitud*(np.sin(w*t&#x5B;i]))\n    \n    return(muestreo, tono)\n<\/pre><\/div>\n\n\n<p>Para realizar una prueba a la funci\u00f3n, se puede generar un tono <code>'.'<\/code>, <code>'-'<\/code> y escuchar el resultado en un <strong>archivo.wav<\/strong>, similar a los mostrados al inicio para cada <strong>s\u00edmbolo<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Una prueba\nsimbolo = '.'\nmuestreo, sonido=morsetono(simbolo)\n\n# Salida # Archivo de audio.wav\nwaves.write('morsetonopunto.wav', muestreo, sonido)\n<\/pre><\/div>\n\n\n<p>Para crear los tonos de un mensaje y escucharlos en un <strong>archivo.wav<\/strong>, se procesa el mensaje <strong>traducido<\/strong> en morse, s\u00edmbolo a s\u00edmbolo, para a\u00f1adir un punto, una raya o un espacio. Los resultados de cada s\u00edmbolo se acumulan en el vector <strong>sonido<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# traducido = input('Escriba el mensaje morse: ')\ntraducido = '. ... .--. --- .-..   .. -- .--. ..- .-.. ... .- -. -.. ---   .-.. .-   ... --- -.-. .. . -.. .- -..   -.. . .-..   -.-. --- -. --- -.-. .. -- .. . -. - --- '\n# archivo = input('nombre del archivo a guardar: ')\narchivo = 'morsetonotest.wav'\n\n# PROCEDIMIENTO\nmuestreo = 11025  # para .wav: 44100, 22050, 11025\nduracion = 0.04\n\n# morse en sonido, como lista por tama\u00f1o desconocido\nsonido=&#x5B;]\nfor i in range(0,len(traducido)):\n    muestreo, untono = morsetono(traducido&#x5B;i], duracion)\n    for j in range(0,len(untono)):\n        sonido.append(untono&#x5B;j])\n# para .wav convierte en arreglo numpy de 'int16' \nsonido = np.asarray(sonido, dtype='int16')\n\n# SALIDA archivo.wav\nprint('muetreo: ',muestreo)\nprint('muestras sonido: ', len(sonido))\nprint('.... archivo: ' + archivo +'  guardado ....')\nwaves.write(archivo, muestreo, sonido)\n<\/pre><\/div>\n\n\n<p>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\".<\/p>\n\n\n\n<pre class=\"wp-block-code alignwide\"><code>muetreo:  11025\nmuestras sonido:  180810\n.... archivo: morsetonotest.wav  guardado ....<\/code><\/pre>\n\n\n\n<p><strong><em>Referencia<\/em><\/strong>: <a href=\"https:\/\/es.wikipedia.org\/wiki\/C%C3%B3digo_morse\">C\u00f3digo Morse Wikipedia<\/a>, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Women_in_early_radio\">Women in early radio<\/a>, <a href=\"https:\/\/www.itu.int\/dms_pubrec\/itu-r\/rec\/m\/R-REC-M.1677-1-200910-I!!PDF-E.pdf\"> Recommendation ITU-R M.1677-1 (10\/2009) International Morse code<\/a>, Leon-Couch, 5\u20139 Se\u00f1alizaci\u00f3n Pasabanda Modulada Binaria (OOK)<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"decotono\">3. Morse un tono - Deco de s\u00edmbolos con Python<\/h2>\n\n\n\n<p><strong><em>Referencia<\/em><\/strong>: <a href=\"https:\/\/es.wikipedia.org\/wiki\/C%C3%B3digo_morse\">C\u00f3digo Morse Wikipedia<\/a>, <a href=\"https:\/\/www.itu.int\/dms_pubrec\/itu-r\/rec\/m\/R-REC-M.1677-1-200910-I!!PDF-E.pdf\"> Recommendation ITU-R M.1677-1 (10\/2009) International Morse code<\/a>, Leon-Couch, 5\u20139 Se\u00f1alizaci\u00f3n Pasabanda Modulada Binaria (OOK)<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Analisis de archivo.wav en python<\/h3>\n\n\n\n<p>Para analizar el sonido de un s\u00edmbolo Morse, se inicia por recordar la duraci\u00f3n de cada s\u00edmbolo:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>un punto <code>'.'<\/code>, cuenta como una marca : <a href=\"https:\/\/www.dropbox.com\/s\/wc909k0dffyikjq\/morsetonopunto.wav?dl=0\">morsetonopunto.wav<\/a><\/li>\n\n\n\n<li>una raya <code>'-'<\/code> dura 3 marcas : <a href=\"https:\/\/www.dropbox.com\/s\/l14ig6keoby64iy\/morsetonoraya.wav?dl=0\">morsetonoraya.wav<\/a><\/li>\n\n\n\n<li>espacio <code>' '<\/code>, que separa una palabra, dura una marca : <a href=\"https:\/\/www.dropbox.com\/s\/wwr7mkv0cafjvnp\/morsetonoespacio.wav?dl=0\">morsetonoespacio.wav<\/a><\/li>\n\n\n\n<li>una pausa se intercala al final del cada s\u00edmbolo convertido a un tono.<\/li>\n<\/ul>\n\n\n\n<p>Para la detecci\u00f3n de un tono, se revisa la frecuencia activa en varios intervalos de tiempo o <strong>ventanas<\/strong>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"815\" height=\"615\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono01.png\" alt=\"morse codificadortono 01\" class=\"wp-image-49\" \/><\/figure>\n\n\n\n<p>Al contar el n\u00famero de intervalos (<code>marcas<\/code>) que aparece un <em>tono<\/em> vs. el n\u00famero de intervalos de <em>pausa<\/em>, se podr\u00e1 determinar si el sonido corresponde a un punto, una raya o un espacio. Es el proceso contrario a lo realizado para crear el <em>tono<\/em>, contando las <strong>marcas<\/strong>, la relaci\u00f3n entre <strong>marcas<\/strong> y <em>pausas<\/em> indicar\u00e1 el s\u00edmbolo recibido.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">El sonido para el an\u00e1lisis se obtiene de un <strong>archivo.wav<\/strong>, creado con el generador de tonos para un punto <code>'.'<\/code> o raya <code>'-'<\/code>. La lectura del archivo proporciona los datos de <strong>sonido<\/strong>, y frecuencia de <strong>muestreo<\/strong>.<\/h3>\n\n\n\n<p>Para el an\u00e1lisis, se supondr\u00e1 que la <strong>ventana<\/strong> tiene la mitad de la <strong>duraci\u00f3n<\/strong> de un punto, para el ejercicio es 0.04 segundos. As\u00ed, una <strong>ventana<\/strong> tiene la mitad de <strong>muestras<\/strong> que una <strong>marca<\/strong> <code>'.'<\/code> o <em>pausa<\/em>, obteniendo al menos dos <strong>ventanas<\/strong> por cada punto o pausa y tres <strong>ventanas<\/strong> por cada raya. Se cuentan las <strong>ventanas<\/strong> que tienen sonido o pausa y se comparan para determinar el <strong>s\u00edmbolo<\/strong>.<\/p>\n\n\n\n<p>Que existan al menos dos <strong>ventanas<\/strong> por cada punto tienen relaci\u00f3n con el muestreo de Nyquist.<\/p>\n\n\n\n<p>Lo expuesto se prueba primero analizando solo una ventana:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# C\u00f3digo Morse -  Determina un simbolo a partir de UN sonido\n# propuesta: edelros@espol.edu.ec\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport scipy.io.wavfile as waves\nimport scipy.fftpack as fourier\n\n# INGRESO \n# archivo = input('nombre del archivo: ')\n# archivo = 'morsetonopunto.wav'\narchivo = 'morsetonoraya.wav'\nmuestreo, sonido = waves.read(archivo)\n\n# PROCEDIMIENTO\nduracion = 0.04   # segundos de un punto\npartes   = 2        # divisiones de un punto\n\n# Extraer ventanas para espectro por partes\ntventana = duracion\/partes\nmventana = int(muestreo * tventana) # muestras de una ventana\n\n# Observacion intermedia\nunaventana = sonido&#x5B;0:mventana]\n\n# SALIDA  GRAFICA\nprint('muestreo:', muestreo)\nprint('muestras en sonido', len(sonido))\nprint('intervalo de ventana: ', tventana)\nprint('muestras por ventana: ', mventana)\n\nplt.figure(1)\nplt.subplot(211)\nplt.plot(sonido, label='sonido')\nplt.xlabel('muestras')\nplt.ylabel('sonido y ventanas')\nk = 1\nfor i in range(0,int(len(sonido)\/mventana)):\n    plt.axvline(x=k*mventana, color='r', linestyle='--')\n    k = k + 1\nplt.subplot(212)\nplt.plot(unaventana)\nplt.xlabel('muestras')\nplt.ylabel('unaventana')\nplt.margins(0)\nplt.show()\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code\"><code>muestreo: 11025\nmuestras en sonido 1764\nintervalo de ventana: 0.02\nmuestras por ventana: 220<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono01.png\"><img loading=\"lazy\" decoding=\"async\" width=\"815\" height=\"615\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono01.png\" alt=\"\" class=\"wp-image-49\" \/><\/a><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"unaventana\">4. An\u00e1lisis de una ventana<\/h2>\n\n\n\n<p>Para determinar si existe un <strong>tono<\/strong> en <strong>una ventana<\/strong>, se analiza la existencia de una se\u00f1al observada en el dominio de la frecuencia.<\/p>\n\n\n\n<p>En el dominio de la frecuencia se requiere usar la \"Transformada de Fourier\" de la se\u00f1al en la <strong>ventana<\/strong>. La Transformada r\u00e1pida de Fourier <strong>fft()<\/strong> se encuentra disponible en las librer\u00edas \"<code>scipy<\/code>\" y el rango de frecuencias para la gr\u00e1fica se obtiene con <strong>fftfreq()<\/strong>.<\/p>\n\n\n\n<p>En el resultado se busca la frecuencia (<code>np.argmax()<\/code>) con mayor magnitud (<code>np.abs()<\/code>) y se determina si corresponde al \"<strong>tono<\/strong>\" morse esperado.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Espectro de Fourier de una ventana &#x5B;0:nventana]\nxf = fourier.fft(unaventana)\nxf = np.abs(xf)  # magnitud de xf\ntono = np.argmax(xf)  # tono en donde\n\n# frecuencias para eje\nfrq = fourier.fftfreq(mventana, 1\/muestreo ) \n\n# SALIDA  GRAFICA \/Observacion intermedia\nprint('frecuencia tono (Hz): ',frq&#x5B;tono])\n\nplt.figure(2)\nplt.xlabel('Frecuencia Hz')\nplt.ylabel('Magnitud')\nplt.stem(frq,xf)\nplt.show()\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code\"><code>frecuencia tono (Hz):  451.022727273<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/estg1003\/files\/2017\/04\/morsedecotono02.png\"><img loading=\"lazy\" decoding=\"async\" width=\"815\" height=\"615\" src=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/estg1003\/files\/2017\/04\/morsedecotono02.png\" alt=\"\" class=\"wp-image-50\" \/><\/a><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">An\u00e1lisis del archivo.wav de un s\u00edmbolo Morse<\/h3>\n\n\n\n<p>Para analizar todo el archivo de sonido, los datos se segmentan por \"<strong>ventanas<\/strong>\" en una matriz, cada fila corresponde a las muestras de <strong>una ventana<\/strong> de tiempo.<\/p>\n\n\n\n<p>La matriz debe ser rectangular, por lo que es necesario confirmar que el n\u00famero de muestras por ventana sean iguales. En caso de no ser as\u00ed, se realiza un ajuste del <strong>ancho del sonido<\/strong> para que el numero de muestras en el archivo sea m\u00faltiplo del n\u00famero de muestras por ventana.<\/p>\n\n\n\n<p>Observar el resultado de crear varias <strong>ventanas<\/strong> de tiempo, es semejante a tener un cuaderno en el que cada hoja tiene una imagen con los valores de la se\u00f1al en cada <strong>ventana<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Ajuste de muestras de ventanas para matriz\nantes = len(sonido)\nanchosonido = int(len(sonido)\/mventana)*mventana \nsonido   = np.resize(sonido,anchosonido)\nventanas = np.reshape(sonido,(-1,mventana))  \n# -1 indica que calcule las filas\n\n# SALIDA\nprint('muestras en sonido: ', antes)\nprint('muestras recortadas a: ', anchosonido)\nprint('ventanas: ')\nprint(ventanas)\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code\"><code>muestras en sonido:  1764\nmuestras recortadas a:  1760\nventanas: \n&#091;&#091;     0   6504  12602 ..., -22161 -24942 -26163]\n &#091;-25748 -23722 -20212 ...,   9594   3241  -3315]\n &#091; -9663 -15408 -20188 ...,  25762  26158  24919]\n ..., \n &#091;-15377  -9629  -3278 ...,  -9733 -15468 -20236]\n &#091;-23738 -25755 -26161 ...,      0      0      0]\n &#091;     0      0      0 ...,      0      0      0]]<\/code><\/pre>\n\n\n\n<p>Para observar el resultado se usa una gr\u00e1fica 3D de superficie.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Observacion intermedia\nfrom mpl_toolkits.mplot3d import Axes3D\nfrom matplotlib import cm\n\nnfilas,ncolumnas = np.shape(ventanas)\nx = np.arange(0,ncolumnas) # valores para cada eje\ny = np.arange(0,nfilas)\nX, Y = np.meshgrid(x, y) # valores para punto.\nZ = ventanas             # Matriz\n\n# Salida, gr\u00e1fico 3d\nfig  = plt.figure(3,figsize=plt.figaspect(0.5))\nax   = fig.add_subplot(1, 2, 1, projection='3d')\nsurf = ax.plot_surface(X, Y, Z, rstride=1, cstride=1,\n                       cmap=cm.coolwarm, linewidth=0,\n                       antialiased=False)\nplt.xlabel('muestras')\nplt.ylabel('ventana')\nplt.show()\n<\/pre><\/div>\n\n\n<figure class=\"wp-block-image\"><a href=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/estg1003\/files\/2017\/04\/morsedecotono03.png\"><img loading=\"lazy\" decoding=\"async\" width=\"387\" height=\"430\" src=\"https:\/\/blog.espol.edu.ec\/algoritmos101\/estg1003\/files\/2017\/04\/morsedecotono03.png\" alt=\"\" class=\"wp-image-51\" \/><\/a><\/figure>\n\n\n\n<p>El proceso de an\u00e1lisis se repite para cada <strong>ventana<\/strong> (una <code>fila<\/code>) en la matriz, guardando cada resultado en un vector \"<strong>marcas<\/strong>\".<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# Analiza con FFT todas las ventanas del sonido\nfilas, columnas = np.shape(ventanas)\nmarcas = np.zeros(filas,dtype=float)\n\n# Espectro de Fourier de cada ventana\n# frecuencias para eje\nfrq = fourier.fftfreq(mventana, 1\/muestreo)  \nfor fila in range(0,filas,1):\n    xf = fourier.fft(ventanas&#x5B;fila])\n    xf = np.abs(xf)        # magnitud de xf\n    tono = np.argmax(xf)   # tono, frecuencia mayor \n    marcas&#x5B;fila] = frq&#x5B;tono]\n<\/pre><\/div>\n\n\n<p>Observamos el resultado en una gr\u00e1fica 2D.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# SALIDA  GRAFICA  \/Observacion intermedia\nprint(marcas)\nplt.figure(4)\nplt.stem(marcas)\nplt.xlabel('n\u00famero de marca')\nplt.ylabel('frecuencia del tono mas fuerte.')\nplt.show()\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code alignwide\"><code>&#091; 451.02272727  451.02272727  451.02272727  451.02272727  451.02272727  451.02272727    0.            0.        ]<\/code><\/pre>\n\n\n\n<figure class=\"wp-block-image\"><a href=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono04.png\"><img loading=\"lazy\" decoding=\"async\" width=\"815\" height=\"615\" src=\"http:\/\/blog.espol.edu.ec\/algoritmos101\/files\/2017\/04\/morsedecotono04.png\" alt=\"\" class=\"wp-image-52\" \/><\/a><\/figure>\n\n\n\n<p>Para determinar si es punto <code>'.'<\/code>, raya<code>'-'<\/code> o espacio <code>' '<\/code>, se cuentan los <strong>noceros<\/strong> y los <strong>ceros<\/strong> del arreglo de <strong>marcas<\/strong>, la relaci\u00f3n entre ellos determina el <strong>s\u00edmbolo<\/strong> que representa el sonido del <strong>archivo.wav<\/strong>.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# determina el simbolo\nnoceros = np.count_nonzero(marcas)\nceros  = len(marcas)-noceros\nrelacion = int(noceros\/ceros)\nif (relacion==3):\n    simbolo = '-'\nif (relacion==1):\n    simbolo = '.'\nif (relacion==0):\n    simbolo = 'espacio'\n\n# SALIDA\nprint('relacion noceros\/ceros:', relacion)\nprint('simbolo morse detectado: ', simbolo)\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code alignwide\"><code>relacion noceros\/ceros: 3\nsimbolo morse detectado:  -<\/code><\/pre>\n\n\n\n<p><strong>Nota<\/strong>: Observe que cualquier frecuencia en una <strong>ventana<\/strong> marca un punto <code>'.'<\/code>. El detalle es tratado en \"Morse - Decodificador del sonido de un mensaje\" en : <code># Busca frecuencia del tono punto<\/code>.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"algoritmotonos\">5. Morse por tonos - Algoritmo con Python<\/h2>\n\n\n\n<p>El resultado del programa resumido se muestra a continuaci\u00f3n:<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code alignwide\"><pre class=\"brush: python; title: ; notranslate\" title=\"\">\n# C\u00f3digo Morse -  Determina un simbolo a partir de UN sonido\n# propuesta: edelros@espol.edu.ec\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport scipy.io.wavfile as waves\nimport scipy.fftpack as fourier\n\n# INGRESO \n# archivo = input('nombre del archivo: ')\n# archivo = 'morsetonopunto.wav'\narchivo = 'morsetonoraya.wav'\nmuestreo, sonido = waves.read(archivo)\n\n# PROCEDIMIENTO\nduracion = 0.04   # segundos de un punto\npartes   = 2      # divisiones de un punto\n\n# Extraer ventanas para espectro por partes\ntventana = duracion\/partes\nmventana = int(muestreo * tventana) # muestras de una ventana\n\n# Ajuste de muestras de ventanas para matriz\nantes = len(sonido)\nanchosonido = int(len(sonido)\/mventana)*mventana \nsonido   = np.resize(sonido,anchosonido)\nventanas = np.reshape(sonido,(-1,mventana))  \n# -1 indica que calcule las filas\n\n# Analiza con FFT todas las ventanas del sonido\nfilas, columnas = np.shape(ventanas)\nmarcas = np.zeros(filas,dtype=float)\n\n# Espectro de Fourier de cada ventana\n# frecuencias para eje\nfrq = fourier.fftfreq(mventana, 1\/muestreo)  \nfor f in range(0,filas,1):\n    xf = fourier.fft(ventanas&#x5B;f])\n    xf = np.abs(xf)        # magnitud de xf\n    tono = np.argmax(xf) # tono, frecuencia mayor \n    marcas&#x5B;f] = frq&#x5B;tono] \n\n# determina el simbolo\nnoceros  = np.count_nonzero(marcas)\nceros    = len(marcas)-noceros\nrelacion = int(noceros\/ceros)\nif (relacion==3):\n    simbolo = '-'\nif (relacion==1):\n    simbolo = '.'\nif (relacion==0):\n    simbolo = 'espacio'\n\n# SALIDA\nprint('relacion de marcas:', relacion)\nprint('simbolo morse detectado: ', simbolo)\n<\/pre><\/div>\n\n\n<pre class=\"wp-block-code\"><code>relacion de marcas: 3\nsimbolo morse detectado:  -<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n\n\n\n<div class=\"wp-block-group has-medium-font-size is-content-justification-left is-layout-flex wp-container-core-group-is-layout-bc8e6f51 wp-block-group-is-layout-flex\">\n<p><a href=\"#morsetono\">Morse Tonos<\/a><\/p>\n\n\n\n<p><a href=\"#codectono\">Codec tono<\/a><\/p>\n\n\n\n<p><a href=\"#decotono\">Deco tono<\/a><\/p>\n\n\n\n<p><a href=\"#unaventana\">analiza ventana<\/a><\/p>\n\n\n\n<p><a href=\"#algoritmotonos\">algoritmo<\/a><\/p>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\" \/>\n","protected":false},"excerpt":{"rendered":"<p>Morse Tonos Codec tono Deco tono analiza ventana algoritmo 1. Morse - Tonos Un generador de tonos permite \"escuchar\" la se\u00f1al morse de forma similar a la tradicional del tel\u00e9grafo. Un punto '.' es la referencia o marca para el sonido morse, teniendo que : Para identificar los tonos que representan puntos, rayas o espacios, [&hellip;]<\/p>\n","protected":false},"author":8043,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"wp-custom-template-entrada-stp-ejercicios","format":"standard","meta":{"footnotes":""},"categories":[202],"tags":[],"class_list":["post-42","post","type-post","status-publish","format-standard","hentry","category-stp-aplica"],"_links":{"self":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/42","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/users\/8043"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/comments?post=42"}],"version-history":[{"count":4,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/42\/revisions"}],"predecessor-version":[{"id":24318,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/posts\/42\/revisions\/24318"}],"wp:attachment":[{"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/media?parent=42"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/categories?post=42"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.espol.edu.ec\/algoritmos101\/wp-json\/wp\/v2\/tags?post=42"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}