• No se han encontrado resultados

Taller 3. Representación de las señales en tiempo y frecuencia.

N/A
N/A
Protected

Academic year: 2021

Share "Taller 3. Representación de las señales en tiempo y frecuencia."

Copied!
6
0
0

Texto completo

(1)

Taller 3. Representación de las señales en tiempo y frecuencia.

En esta práctica comenzaremos a dar los primeros pasos para acercarnos a los temas de comunicaciones inalámbricas y procesamiento de señales. Con esta excusa, empezaremos tratando de entender algunos conceptos importantes, en particular el de frecuencia.

A lo largo de todo el taller, las preguntas que se plantean se deben entender como guía. Toda exploración por fuera del camino marcado es más que bienvenida. Se espera que cada grupo lleve cuenta de los distintos experimentos realizados y respuestas a las preguntas planteadas. En general a lo largo del taller vamos a ir acumulando, es decir los ejemplos o ejercicios de un taller servirán como base para los futuros talleres. Por eso es importante que cada grupo vaya guardando y documentando prolijamente los experimentos realizados y el código generado. Empecemos por ver cómo manejar el sonido y las señales de audio con las que trabajaremos inicialmente desde Python.

Antes de comenzar con los temas de este Taller es importante entender básicamente cómo se almacenan las variables enteras y reales en una computadora. Para eso le recomendamos que lean el siguiente enlace y realicen el ejercicio 1 :

https://users.dcc.uchile.cl/~lmateu/CC10A/Apuntes/rep/index.html

Ejercicio 1:

A) Estudie la función de numpy fromstring. Vea por ejemplo cómo convierte estos 3 strings: ‘aa’ o ‘aaaa’ o ‘\0\0’ a un array de enteros de 16 bits llamando en el intérprete Python:

import numpy as np

data = np.fromstring('aa','int16') print data

print bin(data)

La función bin(entero) muestra un entero en formato binario. Trate de darle una explicación al resultado obtenido.

B) Si quiere convertir uno de los arrays obtenidos en la parte anterior en un array donde cada elemento sea un float de 32 bits que varíe entre 0 y 1. Estudie que hace la función de numpy astype( np.float32 ) y explique por qué el siguiente código hace esa conversión:

import numpy as np

(2)

1. Manejo de archivos wav:

Buscar en Internet que es el formato wav de archivos de audio. Leer la documentación de como leer y escribir archivos wav https://docs.python.org/2/library/wave.html

Y de la siguientes funciones de la biblioteca numpy: fromstring y concatenate Explicar el código de la siguiente función:

import numpy as np import wave

def read_wav( wavname ):

wf = wave.open(wavname, 'rb') CHUNK = 1024

frames = []

#leer una parte del archivo como una cadena de bytes data_str = wf.readframes(CHUNK)

while data_str != '':

# convertir de string a entero (asume .wav en int16, habitualmente cada muestra se codifica en 16 bits)

data_int = np.fromstring( data_str, 'int16')

data_flt = data_int.astype( np.float32 ) / 32767.0 # convierte de int a float32 y en el rango de 0 a 1 para que al escucharlo no distorsione.

frames.append( data_flt ) #se agrega a la lista de reales

data_str = wf.readframes(CHUNK) #leer siguiente parte del archivo return np.concatenate( frames )

2. Escuchar audio en el parlante de la PC, tasa de muestreo.

Leer la documentación de la biblioteca pyaudio: https://people.csail.mit.edu/hubert/pyaudio/docs/ Explicar el código de la siguiente función

Import pyaudio

def play_audio( data, fs):

# data - audio data array

# fs - tasa de muestreo, cantidad de muestras de la señal por segundo. p = pyaudio.PyAudio()

# abrir el objeto pyaudio para escribir en él a la tasa fs

ostream = p.open(format=pyaudio.paFloat32, channels=1, rate=fs,output=True) # play audio

(3)

p.terminate()

Ejercicio 2: Escribir un programa que contenga estas dos funciones y se le pase un archivo wav a la función read y luego de leerlo lo reproduzca en el parlante. La tasa de muestreo de los archivos wav es habitualmente de 44100 muestras/s.

La tasa de muestreo es lo siguiente. Pensemos como ejemplo en la grabación de la voz de una persona. Cuando alguien habla se genera una onda sonora que se corresponde a variaciones de presión del aire. Estas variaciones de presión llegan a un micrófono (el de la computadora por ejemplo) y son convertidas en una variación de voltaje como el de la figura:

Ahora bien, las computadoras no trabajan con señales que puedan tomar cualquier valor y que sean continuas en el tiempo. Se trabaja tomando muestras (valores de la señal) cada cierto tiempo periódico. Por lo tanto, si trabajo a 44100 muestras por segundo quiere decir que cada un tiempo igual a 1/44100 segundos guardo el valor del voltaje en ese momento. Además como ese valor lo voy a guardar con una cantidad de bits fijos (si fuera 1 byte por ejemplo, me daría la posibilidad de tener una escala con 256 valores). Lo que se hace es dividir el rango máximo entre esa cantidad de valores y aproximar el voltaje en un punto al valor de la escala más cercano. Por ejemplo si el micrófono sacara una señal cuyo rango fuera entre +/- 2V como en la figura y tuviera un byte para representar el valor de cada muestra tendría que dividir 4V/256 y eso me daría los escalones posibles a los cuales aproximar el valor de la señal en cada muestra. Es decir por ejemplo -2V corresponde al 0, 2V a 255, 128 al 0V, etc.

(4)

Una señal muestreada en Python será par nosotros un vector (un numpy array) o una lista de Python donde los valores del vector serán las muestras de la señal. La frecuencia de muestreo será un dato externo que no estará en el vector. Por ejemplo, si tengo una señal que es una recta que pasa por el origen y crece de a un volt cada segundo. Si la muestreo a una tasa de 5 muestras por segundo durante el primer segundo obtengo (asumiendo que la primera muestra sea en cero) el vector [0, 0.2, 0.4, 0.6, 0.8]; o si la primera muestra no cae en 0 sino en 0.1 V será [0.1,0.3,0.5,0.7,0.9]. En cambio si esa misma señal la muestreo durante un segundo a una tasa de 10 muestras por segundo se obtiene el vector: [0.0,0.1,0.2,0.3,0.4,0.5,0.6,0.7,0.8,0.9].

Ejercicio 3:

A) Genere un programa en Python que calcule el vector correspondiente una señal lineal como la anterior (que pasa por el origen y crece de a un volt por segundo) muestreada a una tasa de 10 muestras por segundo durante un segundo. El primer punto de muestreo es un valor aleatorio entre 0.0 y 0.1 segundos.

(5)

3. El concepto de frecuencia

Ahora nos enfocaremos en señales más sencillas que la voz humana, la música o el canto de los pájaros. En particular, vamos a enfocarnos en notas musicales. Por ejemplo, la nota La estándar (cuarta octava) está en 440 Hz. ¿Qué significa eso?

Para empezar, ``Hz'' es la abreviación de ``Hertz'', que es una unidad que mide algo periódico (que sucede cada cierto tiempo fijo). En particular, 1Hz indica algo que sucede una vez por segundo. Quizá hayan escuchado hablar de las RPM (revoluciones por minuto) que por ejemplo se usa para indicar cuántas vueltas da el eje de un motor en un minuto (mucho autos lo incluyen en su tablero). Pues esto es lo mismo, pero medido cada un segundo en vez de un minuto. En todos los casos se lo denomina Frecuencia.

Ejercicio 4:

Escriba un programa que genere el vector correspondiente a una sinusoide muestreada a 44100 muestras por segundo de duración medio segundo y que tenga una frecuencia de 440 Hz. Generar una señal que su amplitud varíe entre +/- 0.5. Escuche la señal generada utilizando la función play_audio. Muestre en un gráfico utilizando la función plot de la biblioteca matplotlib como varían en el tiempo las primeras doscientas muestras. Verifique que la amplitud y el período de la sinusoide son los correctos. La gráfica debe mostrar con un marcador el valor de cada muestra.

Posteriormente haga lo mismo para las notas Do, Re, Mi, Fa, Sol, La, Si de la cuarta octava y de la quinta octava. Busque en Internet una fórmula para calcular la frecuencia de cualquier nota en cualquier octava e impleméntelo. Haga una función a la que le pase la nota, la octava y el tiempo de ejecución y la escuche utilizando la función play audio. Componga una melodía utilizando la función anterior.

4. Representación de la señal en frecuencia.

En la parte anterior se vio cómo variaba la señal en el tiempo. Esta es una posible representación de la señal. También se puede pensar en representar las señales por sus componentes en frecuencia en lugar de por sus valores en el tiempo. Para eso hay funciones que nos permiten dada una señal identificar qué frecuencias tiene. Un algoritmo para calcular los componentes en frecuencia de una señal muy utilizado se denomina Fast Fourier Transform (FFT). La siguiente función permite dada una señal obtener un gráfico de las componentes en frecuencia que tiene la señal.

def plot_frec(x,fs): m=4096 lx = len(x)

nt = (lx + m - 1) // m

(6)

xmw = np.reshape( xp, (m,nt), order='F') xmf = np.fft.fft(xmw,len(xmw),axis=0)/m xf = np.linspace(0, fs/2.0, m/2) plt.plot(xf,np.abs(xmf[0:m/2,0:lx/m-1]).mean(1)) plt.show() Ejercicio 5:

Utilice la función anterior para graficar las componentes en frecuencia de la sinusoide que generó de 440Hz pero con una señal que dure 10 segundos y no medio segundo como antes. Genere ahora una sinusoide de 4400 Hz y escúchela. ¿Cuál es la diferencia con la de 440 Hz? Grafique las primeras doscientas muestras de la sinusoide de 4400 Hz. Sume las dos sinusoides y grafique cómo varía la señal suma en el tiempo (primeras doscientas muestras) y cómo son sus componentes en frecuencia. Genere ahora sinusoides de frecuencias crecientes desde los 4.4 kHz hasta 20 kHz, por ejemplo de 8kHz, 10 kHz, 12 kHz, 14 kHz, 16 kHz, 18 KHz y 20kHz y escuche estas señales. ¿Por qué le parece que a medida que la frecuencia aumenta se escucha más débil? Pruebe hacer escuchar estas sinusoides de mayor frecuencia a una persona mayor a 30 años. ¿Cuál fue el resultado?

Grafique en el tiempo los primeros 200 puntos de la sinusoide de 18 kHz por ejemplo. ¿Se parece a una sinusoide? ¿Cómo explica lo que observa?

Sume ahora las sinusoides de 440Hz, 4400 Hz y 8 kHz escuche el resultado final y vea su respuesta en frecuencia y en el tiempo.

Ejercicio 6:

Por último analice la respuesta en frecuencia de algunos archivos wav y compare lo que escucha y la respuesta en frecuencia ¿Qué observa? ¿Cómo puede explicar lo que observa?

Para el próximo Taller debe traer un informe con los ejercicios 2 a 6.

Referencias

Documento similar

que hasta que llegue el tiempo en que su regia planta ; | pise el hispano suelo... que hasta que el

Para ello, trabajaremos con una colección de cartas redactadas desde allí, impresa en Évora en 1598 y otros documentos jesuitas: el Sumario de las cosas de Japón (1583),

Entre nosotros anda un escritor de cosas de filología, paisano de Costa, que no deja de tener ingenio y garbo; pero cuyas obras tienen de todo menos de ciencia, y aun

Habiendo organizado un movimiento revolucionario en Valencia a principios de 1929 y persistido en las reuniones conspirativo-constitucionalistas desde entonces —cierto que a aquellas

Tras establecer un programa de trabajo (en el que se fijaban pre- visiones para las reuniones que se pretendían celebrar los posteriores 10 de julio —actual papel de los

Por PEDRO A. EUROPEIZACIÓN DEL DERECHO PRIVADO. Re- laciones entre el Derecho privado y el ordenamiento comunitario. Ca- racterización del Derecho privado comunitario. A) Mecanismos

En el capítulo de desventajas o posibles inconvenientes que ofrece la forma del Organismo autónomo figura la rigidez de su régimen jurídico, absorbentemente de Derecho público por

b) El Tribunal Constitucional se encuadra dentro de una organiza- ción jurídico constitucional que asume la supremacía de los dere- chos fundamentales y que reconoce la separación