Trabajo Final de Procesamiento Digital de Señales
Trabajo Final de Procesamiento Digital de Señales
Trabajo Final de Procesamiento Digital de Señales
Marco teórico:
Filtro digital:
Un filtro digital es un tipo de filtro que opera sobre señales discretas y cuantizadas,
implementado con tecnología digital, bien como un circuito digital o como un programa
informático.
Como sabemos un filtro digital de respuesta infinita (IIR) tiene la siguiente forma:
Algunos de los tipos de filtros analógicos más conocidos son los siguientes:
1. Butterworth: Presenta una respuesta monótona (sin rizado) tanto en la banda de paso
como en la de paro. Es por esta razón que tiene una considerable anchura de la banda de
transición.
2. Chevyshev tipo I: Presenta rizado en la banda de paso y respuesta monótona en la banda
de paro.
3. Chevyshev tipo II: Presenta rizado en la banda de paro y respuesta monótona en la
banda de paso.
4. Elíptico: Presenta el mismo rizado en ambas bandas.
De estos filtros más conocidos vamos a usar el Butterworth debido a que no presenta rizados en
ninguna de las bandas, donde también vamos a ver que existen de diferentes tipos de orden N.
El orden del filtro nos indica la pendiente de bajada del filtro, mientras el orden sea mayor
tendera a ser una ventana rectangular generando un filtro ideal, pero por costos en el
desarrollo del filtro en la vida real consideramos que el orden debe no ser muy alto debido a
que crear dicho filtro nos elevaría considerablemente el costo de ello.
a) Convertir el archivo seleccionado x(t) a un archivo x[n] en formato SonidoK.txt.
1.- Se procede a importar las librerías necesarias para la conversión a x[n] del archivo .wav
correspondiente, en la línea 8 importaremos la librería numpy que es usada para trabajar con
arreglos, en la línea 9 tenemos a scipy.io del cual importaremos wavfile para procesar la señal y así
obtener su información.
2.- Una vez importadas las librerías se procede a utilizarlas, en la línea 13 mediante el método read
leemos el archivo Pajaros_01.wav del cual obtendremos la frecuencia de muestreo y la data del
archivo.
3.- En la línea 14 se procede a hacer el guardado de data en SonidoK.txt
4.- De la línea 15 se imprimirá el valor de la frecuencia de muestreo por consola.
RESULTADOS:
Archivo SonidoK.txt generado
Frecuencia de muestreo presentado en consola:
Generando lo siguiente:
Y nos damos cuenta que según el audio en dominio del tiempo es el mismo sin embargo el espectro
en frecuencia se ve modificado por el cambio de canal de estéreo a mono.
Haciendo un zoom en la gráfica de la Transformada rápida de Fourier tomaremos las frecuencias de
interés.
Según esta figura el análisis podemos hacerlo desde 1 KHz hasta 5 KHz y también se genra un
archivo .txt que guardará el cambio correspondiente, dicho archivo lo guardaremos como
SonidoK1.txt
c) Diseñar un filtro pasabanda (IIR o FIR) con frecuencia central y ancho de banda de
acuerdo con los resultados de (b).
Como resultado de esta etapa:
Como podemos apreciar en la figura1 y 2 estos filtros están diseñados con OPAM, y también
podemos apreciar que esta compuesta por etapas de acuerdo con el orden que deseamos
desarrollar. Si queremos desarrollar un filtro Butterworth de manera física nos genera más
costo en componentes cuando desarrollemos de orden superior, por eso nosotros hemos optado
por desarrollar un filtro digital Butterworth de manera computacional en el Software Python de
orden 6 porque nos parece conveniente y óptimo debido a que su pendiente no sea muy
inclinada ni muy pronunciada.
Para el diseño del filtro tendremos en cuenta las frecuencias de corte inferior en 1 KHz hasta 5 KHz
para la primera prueba, la segunda prueba será de 2 KHz hasta 5 KHz y la tercera prueba será de 2
KHz hasta 4.5 KHz.
Para las pruebas debemos aclarar que grabaremos el audio para filtrar los ruidos del medio por lo
que se usará el siguiente código escrito en Python grabación_y_filtrado.py (Código
grabación_y_filtrado.py)
1.- Comenzaremos importando las librerías, las cuales son, en la línea 8 importamos time para el
ocasionar un delay más adelante, en la línea 9 está pyaudio para el procesado de la grabación, en la
línea 10 estará wave que nos ayudará a crear el archivo.wav donde se guardará el audio, en la línea
11 se usará la librería sounddevice, en la línea 12 se importó wavfile para el procesado de la señal,
en la línea 13 se tiene la librería matplotlib.pyplot que servirá para plotear las gráficas necesarias, en
la línea 14 usaremos la librería numpy para la representación en arreglos, en la línea 15
importaremos freqz, butter y filtfilt, en la línea 16 desde matplotlib importaremos patches.
2.- En la línea 21 dará el mensaje de bienvenida y en la línea 22 se mostrará un mensaje para la
duración en segundos, la línea 23 almacenará el valor numérico entero en la variable tiempo.
3.- Desde la línea 24 hasta la línea 29 se definen los parámetros para la grabación de la señal en la
que se tiene el formato, el canal mono (1) o estéreo (2), la velocidad de muestreo que ya obtuvimos
en el apartado a), los trozos a los cuales será muestreado, la duración que tendrá nuestro audio y el
nombre del archivo con el que será guardado.
4.- En la línea 31 se llama al la librería pyaudio la cual almacenaremos en la variable audio para
iniciar el stream o grabación de acuerdo a los parámetros antes fijados.
5.- Desde la línea 36 hasta la línea 50 se tendrá se procederá a la grabación, para esto crearemos un
arreglo vacío en el cual será almacenada la data, luego tendremos la finalización de la grabación y
se procederá con la creación del archivo en el cual será almacenada la información de acuerdo a los
parámetros antes mencionados.
6.- Desde la línea 53 hasta la línea 58 tendremos el análisis en frecuencia para la señal empezando
por abrir el archivo .wav generado mediante wavfile.read obteniendo así su frecuencia de muestreo
y su data, luego hallaremos su longitud, la fft a la data, la fft a la longitud y luego la multiplicamos
por la frecuencia de muestreo para obtener la frecuencia en Hz.
7.- Para cuestiones del filtro una vez hecho el análisis del apartado b) pondremos las frecuencias
convenientes que se guardarán en las variables corteinf(frecuencia de corte inferior) y
cortesup(frecuencia de corte superior) para el filtro, tomaremos también un orden 6 por condiciones
medias y luego corteinf se guardará en lowcut mientras cortesup se guardará en highcut.
En la línea 70 se define la función butter_passband que nos devolverá los coeficientes a y b,
denominador y numerador del filtro tomando como datos de entrada la frecuencia de corte inferior,
frecuencia de corte superior, frecuencia de muestreo y el orden.
En la línea 78 se define la función butter_bandpass_filter que aplicará el filtro antes definido a la
data para proceder con el filtrado, para esto necesitará los parámetros tales como data, frecuencia de
corte inferior, frecuencia de corte superior, frecuencia de muestreo y orden del filtro, obteniendo así
la función Y filtrada.
8.- En la línea 84 se reemplazan los valores guardados en las variables para proceder con el filtro,
en la línea 86 se obtienen los parámetros w y h, los cuales son los coeficientes para la respuesta en
frecuencia de acuerdo con los coeficientes del filtro diseñado, en la línea 89 se tiene la función Y
que será la aplicación del filtro a la data teniendo los valores guardados en las variables
correspondientes, luego se hallará su fft en la línea 92.
9.- Desde la línea 94 a 99 se tiene la muestra del audio filtrado en el que se tendrá como entrada la
función Y (señal filtrada) en formato int16 y se podrá reproducir mediante la función sd.play, luego
se guardará la señal en el archivo SresultadoK.text
10.- Desde la línea 101 hasta la 154 se tomarán los coeficientes del filtro para la gráfica en el plano
complejo z para la ROC.
11.- Para las gráficas en la línea se empezará por la figura 1 en la que tendrá 2 subplots, una que
representará la señal en función del tiempo y en la segunda se verá la fft en función de la frecuencia,
para la figura 2 se graficará el filtro Butter de sexto orden en función de la frecuencia, en la figura 3
se comparará la señal original y la señal filtrada, ambas en el dominio del tiempo, la figura 4 es la
fft de la señal filtrada y la figura 5 grafica la ROC del filtro una vez obtenidos los coeficientes.
RESULTADOS
Primera muestra.
Para una frecuencia de corte inferior de 1 KHz hasta 5 KHz
Segunda muestra.
Para 2 KHz y 5 KHz:
Tercera muestra.
Para 2 KHz y 4.5 KHz:
d) Aplicar x [n] al filtro desarrollado y el resultado registrarlo y luego convertirlo a tiempo
discreto en formato SresultadoK.txt y seguidamente a tiempo continuo.
Obtendremos el archivo .txt al que llamaremos Sresultado.txt, en la línea 99 del código se generará
el archivo y estará en el mismo directorio en donde se generó el archivo Python.
Concusiones.
Del análisis de los audios dados para realizar el trabajo hemos podido apreciar que por
defecto viene en modo estéreo y para realizar el trabajo de manera mas cómoda con el
software Python lo pasaremos a canal mono y de ahí podremos hacer el estudio donde
obtuvimos que los FFT de las dos formas tenemos diferencias debido a la acumulación
de la magnitud de frecuencia.
También hemos podido apreciar de como guardamos en archivos txt. Del software y
así poder analizar los valores discretos que nos arroja el análisis de ello.
Para el filtro hemos desarrollado 3 de prueba donde vamos a tomar distintos anchos de
banda que iremos desarrollando, apreciando donde está la concentración de
frecuencias y buscar el optimo rango para que la señal grabada se pueda parecer a l de
la grabación.
Del análisis de los filtros podemos observar que cuando requerimos un orden mayor
vamos a requerir mayor cantidad de componentes que aumentan espacios y costos del
proyecto, lo cual seria una desventaja si se trata de optimizar el filtrado es por ello se
prefiere un filtro IIR a un FIR.
ANEXOS:
Código toma_de_muestras.py
import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt
#fsonido=frecuencia sonido
# INGRESO
Código análisis_frecuencia.py
import numpy as np
from scipy.io import wavfile
import matplotlib.pyplot as plt
#fsonido=frecuencia sonido
# INGRESO
fs, data = wavfile.read('Pajaros_01.wav')
np.savetxt('SonidoK.txt', data)
print(fs)
VEL=22050#Velocidad de muestreo
#print(fs)
L = len(data)
c = np.fft.fft(data) #FFT a la data.
freq = np.fft.fftfreq(L)#FFT a la longitud para la frecuencia
freq_in_hertz = abs(freq * fs)#Frecuencia en Hz.
#-----------INICIO DE LA
GRÁFICA--------------------------------------------
#Se generan los subplot
fig,(ax1,ax2)=plt.subplots(1,2)
sound = AudioSegment.from_wav("D:/PDS/Pajaros_01.wav")
sound = sound.set_channels(1)
sound.export("Pajaros_011", format("wav"))
VEL=22050#Velocidad de muestreo
archivo="Pajaros_011.wav"#Nombre con el que se guardará el archivo.
np.savetxt('SonidoK1.txt', data)
#-----------INICIO DE LA GRÁFICA--------------------------------------------
#Se generan los subplot
fig,(ax1,ax2)=plt.subplots(1,2)
plt.show()
Código grabación_y_filtrado.py
import time
import pyaudio
import wave
import sounddevice as sd
from scipy.io import wavfile
import matplotlib.pyplot as plt
import numpy as np
from scipy.signal import freqz, butter,filtfilt
from matplotlib import patches
audio=pyaudio.PyAudio()
stream=audio.open(format=FORMATO,channels=CANALES,rate=VEL,
input=True,frames_per_buffer=TROZOS)
print("Grabando...")
frames=[]
for i in range(0,int((VEL/TROZOS)*DURACION)):
data=stream.read(TROZOS)
frames.append(data)
print("Grabación terminada")
stream.stop_stream()#Deja de grabar.
stream.close()#Se cierra el stream.
audio.terminate()#Se termina el proceso completo de grabación de audio.
#Se procede a procesar el audio y guardarlo con las características escogidas.
waveFile=wave.open(archivo,'wb')#wb es para ponerlo en modo de solo escritura.
waveFile.setnchannels(CANALES)#Para el número de canales en audio, 1 para mono y 2
para stéreo.
waveFile.setsampwidth(audio.get_sample_size(FORMATO))#Se establece el ancho de
muestras en "n" bits.
waveFile.setframerate(VEL)#Se establece la velocidad de los fotogramas.
waveFile.writeframes(b''.join(frames))#Escribe los cuadros de audio.
waveFile.close()#Se completa el guardado del archivo.
def zplane(b,a,filename=None):
"""Plot the complex z-plane given a transfer function.
"""
# get a figure/plot
ax = plt.subplot(111)
ax.spines['left'].set_position('center')
ax.spines['bottom'].set_position('center')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
if filename is None:
plt.show()
else:
plt.savefig(filename)
return z, p, k
#------------------------INICIO DE LA GRÁFICA----------------------------------
#Se generan los subplot
fig,(ax1,ax2)=plt.subplots(1,2)