en es en es es gl es es en es hbs_lat es es es en es en es en en en en en en en fa en en en en en en es es es es es es es en es es en es es es en es es es es es es es es es es es es en es it en es en en en en en es es pt it es es es pt it es pt it es es es es es pt es es es es pt it es es es es es es es en es es es es es es gl es es hbs_lat es es es
The following Python script extracts the content of an article using Readibility (ported to Python), converts it to voice using the Amazon Polly service and finally sends the audio as a voice note to a given user in Telegram using Telethon (Telegram client for Python).
For running the script you will need to install the following Python packages:
pip install boto3 pip install awscli pip install readability-lxml pip install telethon
Also, you will need to create a AWS account. If you already have an AWS account, make sure that you have a user created in the IAM Management Console with the following permissions:
When creating this user, make sure you write down its ID access key and its secret access key. You will need them to configure the aws-cli client.
With this Amazon credentials, you can configure the AWS client by executing the following command:
In this step, you will need to fulfill the details with the user credentials you wrote down when creating it.
Now, you will need to create a Telegram API ID. For this, you can go to the Telegram section «Create an Application«. After following the steps described in the official documentation, you will obtain an API ID (it’s a number) and a API hash (it’s a string).
With these steps already completed, you can place all the needed details in the script and run it.
import boto3 import textwrap import requests import re from readability import Document from telethon import TelegramClient, events, sync import time import os #-------------------------------------------------------------------- # Configuration #-------------------------------------------------------------------- ##### Article ##### # Define URL url = "PLACE_THE_URL_HERE" ##### Telegram ##### # Telegram API credentials api_id = PLACE_API_ID_HERE api_hash = 'PLACE_API_HASH_HERE' # Telegram user to send messages telegram_user = "PLACE_TELEGRAM_USER_HERE" # Create Telegram client telegram_client = TelegramClient('session_name', api_id, api_hash) telegram_client.start() ##### AWS configuration ##### # Get S3 session session = boto3.Session(profile_name='default') # Get polly client polly = session.client('polly') # Create a S3 client to retrieve the file content s3 = session.client('s3') # Define bucket name bucket_name = 'PLACE_BUCKET_NAME_HERE' #-------------------------------------------------------------------- # Get HTML from the article #-------------------------------------------------------------------- # Get HTML response = requests.get(url) # Extract content with Readibility doc = Document(response.text) # Get article body html_text = doc.summary() # Regular expression to identify HTML tags, e.g.: html_tag_re = r" ]+>" # Remove HTML tags from the article body text_only = re.sub( html_tag_re, "", html_text,) # Send message to user pointing to the URL that is going to be converted telegram_client.send_message(telegram_user, "Converting: %s" % url) #-------------------------------------------------------------------- # Convert text to voice #-------------------------------------------------------------------- # Start Polly task to save in a Bucket resp = polly.start_speech_synthesis_task(OutputFormat='mp3', OutputS3BucketName=bucket_name, Text=text_only, VoiceId='Enrique') # Get Polly task task = polly.get_speech_synthesis_task(TaskId=resp['SynthesisTask']['TaskId']) # Monitor task status until it is completed while task['SynthesisTask']['TaskStatus'] != 'completed': # Wait 2 seconds between server poll time.sleep(2) # Get Polly task task = polly.get_speech_synthesis_task(TaskId=task['SynthesisTask']['TaskId']) # Print the status of the task print("Task status: %s" % task['SynthesisTask']['TaskStatus']) print("Task completed!") #-------------------------------------------------------------------- # Retrieve file and send to Telegram user #-------------------------------------------------------------------- # Regular expression to extract the key (file name) of the synthesized file key_re = r'/([0-9A-Za-z-.]+)$' # Search the regular expression in the OutputUri regex_search = re.search(key_re, task['SynthesisTask']['OutputUri']) # Take only the first group of the re (key) file_key = regex_search.group(1) # Get file name to store in local title_sanitized = doc.short_title().replace('"', '') title_sanitized = title_sanitized.replace(':', '') file_name = "%s.mp3" % title_sanitized # Download file from the bucket and store it in a MP3 local file with open(file_name, 'wb') as data: s3.download_fileobj(bucket_name, file_key, data) # Delete remote bucket file s3.delete_object(Bucket=bucket_name,Key=file_key) # Delete local file if os.path.isfile(file_key): os.remove(file_key) # Send MP3 file as a voice note to the telegram user telegram_client.send_file(telegram_user, file_name, voice_note=True) # Send signature telegram_client.send_message(telegram_user, "Message sent from Romancero bot.")
The user you specified will receive a message like this:
Extracción de parámetros para reconocimiento de voz
2 septiembre 201613 abril 2022 rubensm
A la hora de conformar una vocal, las cuerdas vocales vibran, produciendo una vibración en el aire en forma de tren de pulsos. A su vez, este tren de pulsos pasa a través del tracto vocal, el cual, dependiendo del fonema que se ha pronunciado actuará como un filtro y modificará las componentes frecuenciales del tren de pulsos.
Para cada fonema, el filtro resultante del tracto vocal es diferente. Mientras hablamos, el responsable de que una palabra o un fonema suene de una manera particular es el tracto vocal. Se puede ver un ejemplo intentando decir ‘Hola’ con la boca cerrada o sin mover la boca. Aunque las cuerdas vocales vibran de la misma manera que lo hacen cuando la boca está abierta, no se entiende bien.
Por tanto, en reconocimiento de voz es interesante poder extraer características del tracto vocal, que corresponde a la forma de la envolvente del sonido visto desde el punto de vista frecuencial. Entonces, ¿cómo extraemos la envolvente? Utilizando el análisis cepstral.
El cepstrum de una señal es el resultado de calcular la transformada de Fourier (FT, del inglés Fourier Transform) del espectro de la señal estudiada en escala logarítmica (dB). El nombre cepstrum deriva de invertir las cuatro primeras letras de spectrum. El cepstrum puede ser visto como una información del ritmo de cambio de las diferentes bandas de un espectro.
El cepstrum o análisis cepstral aplicado a una voz equivale a:
La voz \(V\left(f\right) = P \left(f \right) \cdot T\left( f \right)\), donde \(P \left(f \right)\) son las componentes frecuenciales producidas por las cuerdas vocales y \(T \left(f \right)\) es el filtro equivalente del tracto vocal.
Si aplicamos logaritmo a \(V\left( f\right)\), tenemos \(\log{\left[ V\left( f \right) \right]} = \log{\left[ P\left( f \right) \right]} + \log{\left[ T\left( t \right) \right]}\)
La transformada de Fourier de \(T\left( f \right)\) tiene bajas frecuencias. Por otra parte, la transformada de Fourier de \(P\left( f \right)\) contiene altas frecuencias.
De esta manera, si volvemos a hacer la transformada de Fourier de \(V\left( f \right)\) y nos quedamos solo con las bajas frecuencias, habremos eliminado la componente de \(P\left( f \right)\) y tendremos solo la información de \(T\left( f \right)\). Hay que pensar en el concepto de Transformada de Fourier de la Transformada de Fourier \(\left(FFT\left\{ FFT \left\{ x \right\} \right\} \right)\).
Sin embargo, en audio no se utiliza exactamente de esta manera, si no que además se aplica un banco de filtros Mel y se utiliza como segunda transformada la DCT en lugar de la transformada de Fourier debido a sus propiedades de compresión de información (consigue concentrar la mayor parte de la información en pocos coeficientes). Es por ello que en la extracción de parámetros para reconocimiento de voz se utilizan los Mel Frequency Cepstral Coefficients (MFCC).
Mel Frequency Cepstral Coefficients (MFCC)
Para empezar a extraer los parámetros MFCC de un archivo de audio, el audio se enventana. En lugar de extraer los parámetros MFCC de una pieza de 1 segundo (que podría ser aproximadamente la duración de una palabra), se extraen los MFCC de segmentos de 25 ms. La ventana es una ventana de tipo Hanning o Hamming para evitar los armónicos artificiales que aparecen al utilizar ventanas cuadradas. Cada ventana se desplaza 10 ms en tiempo, por lo que existe una superposición entre una ventana y otra.
A cada una de estas ventanas se aplica la FFT.
A la FFT de cada ventana se le aplica el banco de filtros MEL.
Se calcula el logaritmo
Se hace la transformada discreta del coseno (DCT)
Nos quedamos con los N primeros coeficientes (baja frecuencia). Normalmente 12 coeficientes. O también 12 para bajas frecuencias y 1 para la energía media de la ventana.
Como ya habíamos dicho la diferencia entre los cepstrum y los MFCC, es que una vez hecho la FFT en el paso 1, se filtra mediante los filtros MEL y en lugar de aplicar en el paso 4 otra vez una FFT, se aplica la DCT .
Cabe destacar que en reconocimiento de voz no se reconocen fonemas sino palabras. Por tanto, para un archivo de audio de 1 segundo, tendremos \(\frac{1~seg-25~ms}{10~ms} = 97.5 \approx 98\)
parámetros MFCC \(\left( \left\{p_1, p_2, …, p_m \right\} \right)\) y cada parámetro MFCC contendrá N elementos \(\left( p_m = \left\{c_1, c_2, …, c_N \right\} \right)\).
Función para la extracción de MFCC en MATLAB de Kamil Wojcicki
Parámetros típicos de la función mfcc.m:
Si la señal por ejemplo está grabada a 16 kHz, tiene componentes frcuenciales hasta 8 kHz. 7 kHz como frecuencia superior máxima es una buena elección para no tener en cuenta las frecuencias próximas a Nyquist que suelen verse atenuadas y porque hasta 7 kHz hay suficiente información de voz. Por debajo se puede limitar a 50 Hz, dado que la voz humana no tiene apenas información por debajo y así se puede evitar ruidos.
Tw = 25; % analysis frame duration (ms) Ts = 10; % analysis frame shift (ms) alpha = 0.97; % preemphasis coefficient M = 23; % number of filterbank channels C = 12; % number of cepstral coefficients L = 22; % cepstral sine lifter parameter LF = 50; % lower frequency limit (Hz) HF = 7000; % upper frequency limit (Hz)