Upload
phungnga
View
215
Download
0
Embed Size (px)
Citation preview
INSTITUTO POLITECNICO NACIONAL
ESCUELA SUPERIOR DE INGENIERIA MECANICA Y ELECTRICA
UNIDAD ZACATENCO
DISENO DE UN ECUALIZADOR GRAFICO DE SONIDO
Tesis que presenta
Juan Sımuta Pena
Para Obtener el Titulo de
Ingeniero en Comunicaciones y Electronica
En la Especialidad de
Acustica
Asesores:Dr. Maximino Pena Guerrero.
Ing. Jose de Jesus Negrete Redondo
Mexico D.F. 2006
Trabajo de tesis que forma parte de los resultados obtenidos con nuestro proyectode investigacion, KLDSP: Compilador de C para procesamiento de senales digitalesacusticas, numero de registro 20050293 asignado por la Coordinacon General de Pos-grado e Investigacion del Instituto Politecnico Nacional durante febrero 2005 a enero2006, desarrollado en el laboratorio de la academia de acustica de la ESIME Zacaten-co, y dirigido por Dr.Maximino Pena Guerrero, Ing. Jose de Jesus Negrete Redondoy Dr.Pablo Lizana Paulin.
ii
iii
RESUMEN
Un ecualizador o igualador es un dispositivo disenado para corregir, modificar,
compensar y acondicionar la respuesta a la frecuencia de un sistema de audio.
Lo anterior se realiza por medio del empleo de filtros, alterando mediante la ac-
tuacion sobre sus controles la senal recibida y obteniendo ası, la respuesta idonea
para el local y tipo de musica deseada. Ası al ser un procesador de sonido nos per-
mite particionar y obtener porciones de la senal de audio original y alterar su nivel
de volumen en forma independiente.
Basandonos en los algoritmos computacionales de la Transformada Rapida de
Fourier, hemos desarrollado un ecualizador grafico. Los componentes del ecualizador
se implementaron en Visual C++.NET, como son los potenciometros deslizables que
varıan la amplitud de las frecuencias que componen la senal de entrada. Esta es
mostrada en la pantalla grafica como espectro de frecuencias. Empleando la trans-
formada inversa de Fourier obtenemos la senal ecualizada en el dominio del tiempo,
la cual es procesada por las rutinas de sonido y enviadas a la tarjeta de audio de la
computadora.
iv
OBJETIVO
Desarrollar un ecualizador grafico con veinte bandas que controle multiples niveles
de sonido digital.
JUSTIFICACION
Un ecualizador nos permite amplificar o atenuar una amplia gama de sonidos,
para compensar la no linealidad y dado que ecualizar es fundamental en un sistema
de audio, se realizo el presente trabajo mediante un entorno de programacion que
pudiera utilizarse en versiones Windows 95 o superiores.
v
AgradecimientosA mis padres: Juan Sımuta Lazaro y Marina Pena Garcıa por su carino, su es-
fuerzo, sus ensenanzas y consejos, su ejemplo de trabajo, honradez y dedicacion, por
su fe y confianza que en mi depositaron y por darme la mejor de las herencias que yo
pueda recibir, con todo mi respeto les dedico este trabajo.
A mi hermana: Fabiola Sımuta Pena. Por apoyarme siempre, por ser una gran
amiga y una companıa en mi vida.
A los ingenieros y profesores: Maximino Pena Guerrero y Jose de Jesus Negrete
Redondo. Por su paciencia y excelente guıa para la realizacion del presente trabajo.
A mis maestros: Por compartir sus conocimientos, mismos que han sido funda-
mentales para mi formacion, tanto personal como academica.
Al Instituto Politecnico Nacional y a la E.S.I.M.E.: Por brindarme la oportunidad
de realizar una de mis metas en la vida y por todas las experiencias que en sus aulas
vivi, disfrute y por siempre recordare.
Y a las personas que directa o indirectamente colaboraron para la realizacion de
este trabajo.
Juan Simuta Pena
vi
Todo lo que vivamenteimaginamos, ardientementedeseamos, sinceramentecreamos y entusiasta-mente emprendemos ...in-evitablemente sucedera.
Anonimo
vii
Indice general
1. Introduccion 6
1.1. Antecedentes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Los Ecualizadores Graficos . . . . . . . . . . . . . . . . . . . . . . . . 6
1.3. Control de tonos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 8
1.4. Mi Trabajo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
2. Fundamentos de la Ecualizacion de Sonido 10
2.1. Principios de funcionamiento . . . . . . . . . . . . . . . . . . . . . . . 10
2.2. Metodos de programacion . . . . . . . . . . . . . . . . . . . . . . . . 11
3. Aspectos del Diseno de un Ecualizador 14
3.1. Filtros Pasivos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14
3.2. Filtros Activos . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.3. Filtros digitales . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
4. Diseno de Nuestro Ecualizador de Veinte Bandas 25
4.1. Computadoras digitales . . . . . . . . . . . . . . . . . . . . . . . . . . 25
4.2. Estructura de una tarjeta de sonido . . . . . . . . . . . . . . . . . . . 27
4.3. Estructuras del controlador de sonido . . . . . . . . . . . . . . . . . . 28
4.4. Programacion de una senal senoidal . . . . . . . . . . . . . . . . . . . 31
4.5. Graficacion y controles graficos . . . . . . . . . . . . . . . . . . . . . 33
4.6. Algoritmo computacional FFT . . . . . . . . . . . . . . . . . . . . . . 35
5. Pruebas y Resultados 39
5.1. Metodo Orientado a Procedimientos . . . . . . . . . . . . . . . . . . . 39
5.2. Trabajando con las barras verticales . . . . . . . . . . . . . . . . . . . 40
5.3. Normalizacion de las graficas . . . . . . . . . . . . . . . . . . . . . . . 42
5.4. Lectura de un archivo .wav . . . . . . . . . . . . . . . . . . . . . . . . 42
5.5. Formatos bigendian vs. littleendian . . . . . . . . . . . . . . . . . . . 46
5.6. Visualizacion de las senales . . . . . . . . . . . . . . . . . . . . . . . . 46
1
6. Conclusiones y Trabajos Futuros 51
6.1. Trabajos futuros . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
A. Transformada Rapida de Fourier 55
A.1. Algoritmo FFT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
A.2. Decimacion en Tiempo . . . . . . . . . . . . . . . . . . . . . . . . . . 56
A.3. Decimacion en frecuencia . . . . . . . . . . . . . . . . . . . . . . . . . 57
B. Codigo fuente del ecualizador 60
2
Indice de figuras
3.1. Filtro pasa altas desbalanceado de red en L (a) y de red en T (b). . . 16
3.2. Filtro pasa bajas desbalanceado de seccion en L (a) y de seccion pi (b). 17
3.3. Filtro pasa banda balanceado LC (a) y filtro pasa banda desbalanceado
LC (b). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18
3.4. Filtro de rechazo de banda LC balanceado (a) y filtro de rechazo de
banda LC desbalanceado (b). . . . . . . . . . . . . . . . . . . . . . . 19
3.5. Diagrama esquematico del filtro Butterworth para pasa bajas (a), pasa
altas (b) y pasa banda (c). . . . . . . . . . . . . . . . . . . . . . . . . 20
3.6. Diagrama esquematico del filtro Chebyshev para pasabajas (a), pasa
altas (b) y pasa banda (c). . . . . . . . . . . . . . . . . . . . . . . . . 21
3.7. Filtro activo pasabajos (a) y pendiente practica (b). . . . . . . . . . . 22
3.8. Filtro activo pasa altas (a) y respuesta del filtro (b). . . . . . . . . . . 23
3.9. Filtro activo pasa banda (a) y la respuesta del filtro (b). . . . . . . . 24
4.1. Diagrama en bloques de la organizacion de una computadora digital. 26
4.2. Diagrama en bloques de una tarjeta de sonido. . . . . . . . . . . . . . 27
4.3. A mayor numero de muestras se aprecia mejor el periodo de la onda
seno. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33
4.4. La regresion se realiza haciendo el if(fAngle > 2∗PI) y luego fAngle− =
2 ∗ PI. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34
4.5. Algunos ejemplos de recursos . . . . . . . . . . . . . . . . . . . . . . 35
5.1. Panel de control de 20 bandas . . . . . . . . . . . . . . . . . . . . . . 43
5.2. Senal de entrada senoidal . . . . . . . . . . . . . . . . . . . . . . . . . 46
5.3. Ruido blanco como senal de entrada . . . . . . . . . . . . . . . . . . . 47
5.4. Espectro de magnitud de la senal senoidal . . . . . . . . . . . . . . . 47
5.5. Espectro de magnitud del ruido blanco . . . . . . . . . . . . . . . . . 48
5.6. Senal senoidal resultante, una vez ecualizada . . . . . . . . . . . . . . 48
5.7. Ruido blanco una vez ecualizado . . . . . . . . . . . . . . . . . . . . . 48
5.8. Vista general del ecualizador grafico teniendo como senal ruido blanco. 49
3
5.9. Vista general del ecualizador grafico teniendo como senal una onda
senoidal. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
A.1. Separacion de la DFT de N puntos en dos DFT´s de N/2 puntos . . 57
A.2. Separacion de la DFT para la decimacion en frecuencia . . . . . . . . 58
A.3. Decimacion en tiempo para 8 muestras (N = 8) . . . . . . . . . . . . 58
A.4. Decimacion en frecuencia para 8 muestras (N = 8) . . . . . . . . . . 59
4
Indice de tablas
5.1. Encabezado de un archivo de sonido WAVE . . . . . . . . . . . . . . 43
5
Capıtulo 1
Introduccion
1.1. Antecedentes
Existen diferentes tipos de altavoces que producen una gran variedad de sonidos
cuando se emplean con el mismo amplificador; tambien, un juego de altavoces puede
tener diferentes sonidos cuando se emplea con diferentes sistemas de audio. Utilizando
un ecualizador, pueden evitarse estas discrepancias.
Un ecualizador o igualador es un dispositivo disenado para corregir, modificar,
compensar y acondicionar la respuesta a la frecuencia de un sistema de audio.
Lo anterior se realiza por medio del empleo de filtros, alterando mediante la ac-
tuacion sobre sus controles la senal recibida y obteniendo ası, la respuesta idonea
para el local y tipo de musica deseada. Ası al ser un procesador de sonido nos per-
mite particionar y obtener porciones de la senal de audio original y alterar su nivel
de volumen en forma independiente.
Los ecualizadores mas simples son los controles de graves-agudos, que tienen todos
los amplificadores estereofonicos, fonografos y tocacintas.
1.2. Los Ecualizadores Graficos
Algunos de los ecualizadores mas complejos tienen generalmente varios poten-
ciometros lineales de contacto deslizante, situados uno al lado del otro. Cada poten-
ciometro controla la ganancia en un intervalo de frecuencias diferente. Puede haber
6
ocho o mas de estos potenciometros. Ası, el ajuste de los potenciometros da la impre-
sion de un despliegue grafico de la curva de respuesta a la frecuencia que se aplica a
la senal. Por lo anterior expuesto es que se les denomina ecualizadores graficos.
Dependiendo del modelo y la marca,podemos encontrarnos con 15, 30 o 31 poten-
ciometros en los casos mas comunes. Cada banda se encarga de aumentar o disminuir
la senal de una frecuencia determinada, estas van desde los 20 Hz hasta los 20kHz.
Notese que aunque en principio con el uso de los ecualizadores lo que se persigue
es obtener una curva de comportamiento lo mas neutra posible, es decir, aquella en la
que los niveles de energıa se reparten por igual en cada octava, tambien es posible su
uso para la obtencion de ciertos modos acusticos preponderantes. Los ecualizadores
son sumamente utiles en sistemas de audio ubicados en salas de especial sonorizacion,
salas reverberantes y salas mal acondicionadas.
Otra caracterıstica de este tipo de ecualizador es que algunos de ellos disponen de
un led de color en cada potenciometro deslizante, lo cual permite una rapida vision
de ecualizacion realizada.
Uno de los ejemplos mas tıpicos del ecualizador grafico es el ecualizador de octava
en el que encontramos 10 puntos de control. Recordemos que el ancho de banda
audible recorre 10 octavas: 30, 60, 125, 250, 500 Hz, 1, 2, 4, 8 y 16 KHz, y estas
son las frecuencias de actuacion del ecualizador. En general los ecualizadores graficos
permiten reforzar o atenuar la senal en unos 6 a 15 dB, siempre sobre la misma
frecuencia de trabajo.
Habitualmente los ecualizadores profesionales suelen disponer de un selector de
BY-PASS o puenteado de la senal. Tambien es usual disponer de dos secciones de
filtrado independientes para los canales izquierdo y derecho del sistema. Sus acciones
seran totalmente independientes.
Otro tipo de ecualizadores que no podemos dejar pasar son los parametricos, que
controlan los tres parametros fundamentales: ancho de banda, frecuencia central de
actuacion (Q) y amplitud de la senal. Aunque hasta el momento los ecualizadores
7
mas difundidos son los graficos, cada dıa irrumpen con mas fuerza los parametricos
en el terreno profesional. Estos ecualizadores estan considerados como de los mas
potentes del mercado por su posibilidad de variacion sobre todos los parametros
del filtro. Se utilizan basicamente para corregir problemas puntuales, localizando la
frecuencia central en aquellos lugares exactos de la curva de respuesta en los que
haya irregularidades. Una vez posicionados, ajustaremos el ancho de banda para que
sea el mas parecido posible al de la irregularidad (cresta o valle) y se utilizara el
control de ganancia de manera inversa a la accion de la curva. Para tener acceso a
una buena ecualizacion son necesarios, al menos, cuatro filtros en paralelo, cada uno
correspondiente a las cuatro bandas en que dividimos el espectro (agudos, medios,
bajos y muy bajos). Funcion importante es que nos permite compensar, ajustar o
mejorar el sonido segun nuestros gustos.
1.3. Control de tonos
Un control de tonos funciona de la siguiente manera: A una frecuencia de 63 Hz
se destacan los sonidos graves masivos como los de tambores, organos, etc. dando una
sensacion de grandiosidad. Subiendo la frecuencia nos da una sensacion de plenitud,
esto es 125 Hz ya que si baja, aumenta la transparencia. Ahora bajando a 250 Hz el
control, disminuye el posible eco. Si uno aumenta a 500 Hz se entiende que aumenta
la fuerza del sonido pero si se baja da la sensacion de que el sonido no es completo.
A partir de aquı las frecuencias siguen en aumento y la frecuencia de 1 kHZ actua
sobre la voz del cantante y se puede dejar casi inaudible. Para 2 kHz se estimula el
oıdo, pero puede dar sensacion metalica, entonces hay que disminuirlo. En 4 kHz el
sonido puede estar muy alto y en consecuencia dar tambien una sensacion metalica
y dura. Una octava que aumenta la brillantez de instrumentos de cuerda y viento, es
la de 8 kHz y la de 16 kHz es la que aumenta la presencia de sonidos sutiles, como
platillos, triangulos, etc.
8
1.4. Mi Trabajo
Esta tesis presenta el diseno de un ecualizador grafico de sonido mediante ruti-
nas en lenguaje C y esta organizada de la siguiente manera: El segundo capıtulo son
los fundamentos necesarios para la ecualizacion de sonido tales como, ondas sonoras,
frecuencia, analisis de Fourier, entre otros. El tercer capıtulo esta enfocado a la expli-
cacion de los filtros, como lo son los pasivos los activos y los digitales que son parte
fundamental dentro de cualquier ecualizador. El cuarto capıtulo es entrar en materia
de programacion, es decir, la explicacion de diferentes estructuras computacionales
para la graficacion y la obtencion del sonido. En el capıtulo cinco se mostrara las
pruebas realizadas y por consecuencia los resultados obtenidos de estas mismas. Y
por ultimo, en el capitulo seis se presentaran las conclusiones que se obtuvieron del
presente trabajo asi como algunas propuestas para mejorar el mismo.
9
Capıtulo 2
Fundamentos de la Ecualizacion deSonido
En el presente capıtulo se daran algunas definiciones o conceptos, mismos que
son importantes en cuanto a su estudio para el tratamiento de esta tesis y que estan
estrechamente ligados con el tema del ecualizador virtual, algunos de estos conceptos
son: ondas sonoras, audio, sintetizador,graficos, herramientas de programacion entre
otros que son muy utiles e interesantes. Un ecualizador utiliza de cierta forma to-
dos estos conceptos del que por supuesto resalta el de frecuencia; ası que para este
concepto se explicara lo que es el analisis de Fourier.
2.1. Principios de funcionamiento
Para cualquier perturbacion periodica, la rapidez con la que se repite un ciclo se
le llama frecuencia. Su unidad es el Hertz (ciclos/seg.), y se abrevia Hz. El intervalo
de audiofrecuencias al cual puede detectar energıa acustica el oıdo humano, varıa
alrededor de 20 Hz a 20 KHz.
A un movimiento ondulatorio longitudinal que se produce mediante una pertur-
bacion periodica en el aire se le denomina onda sonora. De aquı se puede definir el
sonido como los perturbaciones longitudinales producidas en el aire que son percibidas
por el oıdo humano.
Un concepto ligado a los anteriores es el audio, que es la representacion electrica
10
del sonido, de tal manera que puede ser amplificada, atenuada, acoplada, medida,
transportada a grandes distancias, igualada, mezclada, grabada, procesada, distor-
sionada, retardada, transmitida por medios electromagneticos, etc.
Una herramienta matematica muy importante es el Analisis de Fourier, nombre
dado en honor de Jean-Baptiste-Joseph Fourier (1768-1830) matematico frances, in-
trodujo los metodos mas sencillos para la solucion de los problemas de valor en la
frontera, que se presentan en el tratamiento analıtico de la conduccion del calor. En
la actualidad se ha convertido en metodo indispensable para el tratamiento de casi
toda cuestion de fısica moderna, sistemas lineales, teorıa de comunicaciones, etc.
El metodo matematico que nos permite obtener el espectro de potencia como
funcion de la frecuencia para una forma de onda de la senal dada es la Transformada
de Fourier. Se utiliza para transformar una senal representada en el dominio del
tiempo al dominio de la frecuencia sin alterar su contenido de informacion, solo es
una forma diferente de representarla.
Estas transformaciones permiten la evaluacion de formas de onda, tanto periodicas
como aperiodicas. Cualquier forma de onda puede aproximarse matematicamente
sobre un intervalo finito, con tal de que exista un numero finito de maximos y mınimos
en el intervalo.
2.2. Metodos de programacion
Una de las tecnicas y de las capacidades mas importantes de las PC actuales para
comprender las relaciones entre conjuntos de datos es la graficacion, ya que sin esta
herramienta la mayorıa del trabajo de caracter administrativo, tecnico y cientıfico
se perderıa en un mar de datos. Para pintar graficos (incluyendo texto) ası como
para mostrar los elementos que componen una interfaz de usuario, Windows utiliza
la interfaz de dispositivos graficos (GDI: Graphics Device Interface), dicho de otra
forma, la GDI es el medio que Windows proporciona para dibujar sobre dispositivos
graficos.
11
Para el procesamiento informatico del sonido es necesario realizar su generacion
y captura mediante metodos computacionales y almacenarlo en su memoria o disco.
Existe una infinidad de tarjetas que pueden realizar la generacion y la captura, aunque
las mas implantadas son las Sound Blaster de Creative.
El proceso basico para la captura de sonidos se puede dividir en tres pasos:
Primero, el sonido se transmite por el aire hasta el microfono, el cual transforma
la senal acustica a niveles electricos. Segundo, la senal analogica pasa a traves de un
convertidor analogico-digital. Este resulta ser el elemento mas importante, sus carac-
terısticas establecen la frecuencia maxima a la que se puede trabajar y el numero de
bits que se utilizan para cuantificar cada muestra. Y, tercero, mediante un buffer de
audio se copia cada muestra a la memoria principal de la computadora .
Otra aplicacion muy util para la generacion y captura de sonido es Multimedia.
Esto quiere decir que es la capacidad para comunicarse en mas de una forma ademas
de ser una combinacion de animaciones, graficos, sonido, texto y video. Por supuesto
que para obtener una infinidad de sonidos la computadora debera de contar con una
tarjeta de sonido como la que se menciono arriba.
Algo muy importante para el desarrollo de la presente tesis son las Herramientas
de Programacion. Ası como los sistemas operativos tienen funciones especificas de
control y administracion , el software o programas de desarrollo se utilizan para crear
aplicaciones que resuelvan diversos problemas cientıficos, comerciales administrativos
o del cualquier tipo. Estos programas se denominan lenguajes de programacion y estan
integrados por programas y utilerıas que facilitan la construccion de las aplicaciones
para los usuarios del sistema informatico.
Un concepto que no se debe pasar por alto y que es basico para el entendimiento
de un lenguaje de programacion es el del algoritmo, que es una secuencia ordenada
de pasos, bien precisos, que permite obtener la solucion de un problema dado.
Es importante mencionar que estos lenguajes tienen un conjunto de sımbolos,
instrucciones y enunciados que estan sujetos a una serie de reglas y como cualquier
12
lenguaje humano utiliza un lexico, una sintaxis y un semantica.
Un entorno y un lenguaje de programacion denominado de alto nivel, en el que
se combinan la programacion orientada a objetos (C++) y el sistema de desarro-
llo disenado especialmente para crear aplicaciones graficas para Windows (SDK) es
Visual C++.
13
Capıtulo 3
Aspectos del Diseno de unEcualizador
Disenar es parte fundamental para la ciencia, ya que una vez que se ha madurado
una idea, esta se empieza a desarrollar, utilizando los componentes que para ello sean
necesarios. En este capıtulo se trataran los dispositivos que pueden se utilizados para
el diseno de un ecualizador, siendo los filtros parte esencial del mismo, sin olvidar,
por supuesto, algunas otras definiciones que estan inmersas en este tema como son:
la resistencia, la inductancia y la capacitancia, solo por mencionar algunas.
3.1. Filtros Pasivos
Empezare con los componentes basicos para este tipo de diseno, los cuales son
llamados pasivos. Uno de ellos es el capacitor, que tiene la capacidad de almacenar
la energıa electrica, a esta propiedad se le llama capacitancia, se representa por la
letra C y se mide en unidades llamadas farads. En relacion esto, otro componente
es el resistor, que proporciona un valor fijo para oponerse al paso de la corriente, a
esta propiedad se le llama resistencia, depende de las dimensiones del material y su
unidad es el ohm. Un componente mas es el inductor, que esta especialmente disenado
para proporcionar una cantidad controlada de inductancia, siendo esta propiedad, la
capacidad de almacenar energıa en forma de campo magnetico, se representa por la
letra L y su unidad es el henry.
14
Siguiendo con este contexto, dire que un filtro es una red capaz de hacer una
seleccion entre frecuencias, dejando pasar componentes o senales conducidas en una
banda de frecuencias y bloqueando el paso de estas mismas que van fuera de esa
banda de frecuencias.
Ahora, existen los filtros pasivos, que son redes disenadas con resistores, capaci-
tores e inductores conectados para ser selectivos en cuanto a la frecuencia, ademas, no
requieren de fuente externa de alimentacion para su operacion. Para la construccion
de diversas formas de filtros, atenuadores, etc., se utiliza una red pi que es un circuito
desbalanceado y que como se vera en el capıtulo, la mayorıa de los filtros la tienen
implementada.
Uno de ellos es el filtro pasa altas, que es una combinacion de capacitancia, induc-
tancia y/o resistencia, cuyo objetivo es producir un alto nivel de atenuacion debajo
de ciertas frecuencia y poca o nula atenuacion arriba de esa frecuencia. La frecuencia
a la que ocurre la transicion se llama frecuencia de corte. Los filtros pasaaltas mas
simples consisten en un inductor en paralelo y capacitores en serie. Los mas elabo-
rados tienen una combinacion de inductores en paralelo y capacitores en serie, como
los mostrados en la figura (3.1).
Una combinacion de capacitancia, inductancia y/o resistencia, que produce un alto
nivel de atenuacion arriba de una frecuencia especıfica, y poca o ninguna atenuacion
debajo de esa frecuencia es el filtro pasa bajas. En un filtro pasa bajas se pueden
sustituir los inductores por resistores. La figura (3.2) muestra los filtros pasaabajos
mas elaborados ya que tienen una combinacion de inductores en paralelo y capacitores
en serie.
Cualquier circuito resonante o combinacion de circuitos resonantes, disenado para
hacer discriminacion contra todas las frecuencias, con excepcion de una frecuencia
fo, o una banda de frecuencias comprendidas entre dos frecuencias limitadoras f0 y
f1 se llama filtro pasa banda, mostrado en la figura (3.3). Cabe mencionar que un
circuito resonante es aquel que contiene reactancias finitas que se cancelan entre si.
15
Figura 3.1: Filtro pasa altas desbalanceado de red en L (a) y de red en T (b).
Un filtro de rechazo de banda es un circuito resonante disenado para dejar pasar
energıa a todas las frecuencias, con excepcion de las comprendidas dentro de un cierto
intervalo. Este es mostrado en la figura (3.4). Existe cierta semejanza entre estos filtros
y los de pasa banda. La difrencia fundamental es que el filtro de rechazo de banda
esta formado por circuitos en paralelo LC conectados en serie con la trayectoria de la
senal o circuitos en serie LC conectados en paralelo con la trayectoria de la senal, en
cambio en los filtros pasabanda los circuitos resonantes en serie estan conectados en
serie, y los circuitos de resonancia en paralelo estan conectados en paralelo.
A un tipo especial de filtro selectivo, disenado para tener una respuesta plana en
su pasa banda y una caracterıstica uniforme de atenuacion progresiva, es denomina-
do, filtro Butterworth. Puede disenarse para respuesta de pasa bajas, pasa altas y
pasa banda. Deben escogerse correctamente las impedancias de entrada y de carga
para obtener un funcionamiento adecuado; los valores de los resistores, inductores y
16
Figura 3.2: Filtro pasa bajas desbalanceado de seccion en L (a) y de seccion pi (b).
capacitores del filtro dependen de las impedancias de entrada y carga. La figura (3.5)
muestra este tipo de filtro.
Otro filtro especial selectivo es el llamado filtro de Chebyshev (que tambien se
escribe Tschebyscheff, Tschebyshev) mostrado en la figura (3.6), su caracterıstica es
que tiene respuesta casi plana dentro de su pasa banda, atenuacion casi completa
fuera del pasabanda y respuesta de corte precisa. Puede disenarse para repuestas
iguales al de Butterworth.
Es importante mencionar lo que es el ancho de banda, ya que es un termino que se
usa para definir la frecuencia ocupada por una senal y la que se requiere paratransferir
efectivamente la informacion que va a portar la senal. Un filtro pasabanda tiene un
ancho de banda de una respuesta rectangular con la misma tasa de transferencia de
energıa y se le llama ancho de banda efectivo.
17
Figura 3.3: Filtro pasa banda balanceado LC (a) y filtro pasa banda desbalanceadoLC (b).
3.2. Filtros Activos
Antes de continuar con otro tipo de filtros es debido mencionar el dispositivo lla-
mado amplificador operacional, este amplificador exhibe una gran estabilidad, ademas
de tener una ganancia muy alta, con una elevada impedancia de entrada y una baja
impedancia de salida.
Esta mencion es importante debido a que los filtros activos incluyen un ampli-
ficador de este tipo, sin olvidar que tambien cuentan con elementos pasivos. Son
adecuados para circuitos de estado solido, porque eliminan la necesidad de inductores
abultados, por otra parte, pueden amplificar la senal o proporcionar ganancia, pero
requieren de una fuente de alimentacion y tienen un gran uso en audiofrecuencias.
Un filtro que suministra amplificacion desde dc hasta una frecuencia de corte y
luego no pasa senales por arriba de esas frecuencias, se dice que es un filtro pasa
18
Figura 3.4: Filtro de rechazo de banda LC balanceado (a) y filtro de rechazo de bandaLC desbalanceado (b).
bajas. Un filtro pasa bajas de primer orden usa un solo resistor y capacitor tiene una
pendiente practica de -20 dB por decada. Este es mostrado en la figura (3.7)
Al proporcionar o pasar senales por arriba de una frecuencia de corte, estamos
hablando de un filtro pasa altas. El filtro mostrado en la figura (3.8)es de primer
orden, dado que solo tiene un solo resistor y capacitor
Cuando el circuito de filtro pasa senales arriba de una frecuencia de corte y debajo
de una segunda frecuencia de corte, es llamado filtro pasa banda. La figura(3.9) nos
muestra que para conformar este filtro se utiliza la seccion pasa altas y la seccion
pasa bajas
Otro filtro activo de circuito integrado que no requiere para su operacion de capac-
itores ni de inductores discretos, es el filtro de capacitor conmutado , tambien es capaz
de remplazar a los filtros LC de inductancia-capacitancia. La figura(??) muestra un
19
Figura 3.5: Diagrama esquematico del filtro Butterworth para pasa bajas (a), pasaaltas (b) y pasa banda (c).
diagrama de un filtro de esta clase, formada por una seccion de conmutacion y un
amplificador operacional. Los interruptores S1 y S2 son transistores MOS disparados
por pulsos de reloj.
3.3. Filtros digitales
Inseparable es el proceso de filtrado para el audio digital. Se necesitan filtros
analogicos o digitales -y en ocasiones, ambos- en los ADC, DAC, en los canales de
datos de los grabadores digitales y en los sistemas de transmision, asi como en los
conversores y ecualizadores de la frecuencia de muestreo. La diferencia principal entre
los filtros analogicos y los digitales es que en dominio digital pueden construirse
arquitecturas muy complejas a bajo costo y que los calculos aritmeticos no estan
sujetos a la tolerancia o a las variaciones de los componentes.
20
Figura 3.6: Diagrama esquematico del filtro Chebyshev para pasabajas (a), pasa altas(b) y pasa banda (c).
El filtrado puede modificar la respuesta en frecuencia de un sistema y la respuesta
de fase. Toda combinacion entre la respuesta en frecuencia y la de fase determina la
respuesta impulsiva en el dominio temporal. En un filtro perfecto todas las frecuencias
deben experimentar el mismo retardo temporal. Dado que un impulso contiene un
espectro infinito, un filtro que presente un error de retardo de grupo separara las
distintas frecuencias de un impulso a lo largo del eje temporal.
Un retardo puro provoca un desplazamiento de fase proporcional a la frecuencia
y un filtro que presente esta caracteristica se dice que es de fase lineal. La respuesta
impulsiva de un filtro de fase lineal es simetrica. Es practicamente imposible fabricar
un filtro analogico con una fase lineal perfecta por lo que muchos filtros van seguidos
de una etapa de ecualizacion que a menudo es igual de compleja que el propio filtro.
En el dominio digital es facil realizar un filtro de fase lineal por lo que la ecualizacion
21
Figura 3.7: Filtro activo pasabajos (a) y pendiente practica (b).
de fase no es necesaria. Debido a la naturaleza muestreada de la senal cualquiera que
sea la respuesta a bajas frecuencias todos los canales digitales ( asi como los analogicos
muestreados) funcionan como filtros pasabajo de corte en el limite de Nyquist o a la
mitad de la frecuencia de muestreo.
22
Figura 3.8: Filtro activo pasa altas (a) y respuesta del filtro (b).
23
Figura 3.9: Filtro activo pasa banda (a) y la respuesta del filtro (b).
24
Capıtulo 4
Diseno de Nuestro Ecualizador deVeinte Bandas
He llegado al capıtulo en donde el ecualizador sera disenado mediante la imple-
mentacion del algoritmo computacional de la Transformada Rapida de Fourier, ası co-
mo tambien mediante la utilizacion de diversas estructuras de sonido, mismas que son
necesarias para que se pueda programar la tarjeta de sonido de nuestra computadora
digital.
4.1. Computadoras digitales
A todo dispositivo que ayude y facilite el calculo, ya sea desde un abaco hasta una
calculadora electronica se le puede llamar computadora. En la decada de los cincuentas
se le llamaron computadoras a los equipos electronicos, formados por potenciometros
y amplificadores operacionales con tubos al vacıo, siendo esta la primera generacion.
Con el paso del tiempo, se sustituyeron los tubos del vacıo por transistores siendo esta
la segunda generacion, luego vino la era del silicio y los circuitos integrados, esta fue
la llamada tercera generacion; la cuarta generacion son los microcomputadores y las
computadoras personales, mejor conocidas como PC (por sus siglas en ingles Personal
Computer)que se logro gracias a la miniaturizacion de los circuitos integrados. La era
en que vivimos es la quinta generacion donde el objetivo es que los mecanismos de
computo sean cada ves mas rapidos y pequenos.
25
Por otra parte, existen dos tipos basicos de computadoras electronicas: las analogi-
cas y las digitales, las primeras efectuan calculos en forma de analogıas electricas de
numeros o de variables fısicas. Las segundas ademas de contar, se distinguen de otros
dispositivos de calculo, por su velocidad, su memoria interna y la ejecucion automatica
de un programa +almacenado en su memoria.
En la siguiente ilustracion, se presenta un bosquejo general de la organizacion
de un computadora digital, de la cual nos interesan los dispositivos perifericos, en
especial uno, que es la tarjeta de sonido, ya que es la encargada de generar, capturar
y reproducir el sonido, aparte de que sin ella, simple y sencillamente seria muy difıcil
utilizar los programas multimedia.
Figura 4.1: Diagrama en bloques de la organizacion de una computadora digital.
26
4.2. Estructura de una tarjeta de sonido
Cuando una tarjeta crea un sonido, se dice que el sonido es sintetizado y es en-
tonces cuando actua como un instrumento musical. Esta se divide en dos partes ,
la parte analogica y la parte MIDI (MusicalIntrumentDigitalInterface) asi que a
nosotros nos corresponde trabajar con la parte analogica. Durante varios anos,han
creado efectos musicales por medio de una tecnologıa simple denominada sıntesis FM
misma que utilizan las tarjetas Sound Blaster. Hay otra tecnologıa que reemplaza a
la anterior y es la wavetable y es porque en esta tecnologıa ya no se crea musica con
tonos computarizados, mas bien, buscan el instrumento deseado en una tabla (una
seleccion integrada con grabaciones reales y crean el sonido con base a la muestra).
Figura 4.2: Diagrama en bloques de una tarjeta de sonido.
Estas tarjetas son basicas para poder trabajar con la combinacion que involucra
texto, sonido, video y animacion que sea producida por cualquier medio electronico,
27
para que una determinada presentacion cobre vida y se haga mas realista.
Para la creacion de sonidos, un metodo mas que utiliza la tarjeta de sonido consiste
en la reproduccion de muestras, esto es, de una prueba se hace el sonido realmente
grabado, mientras mas muestras haya en un archivo de sonido , mas real sonara este.
4.3. Estructuras del controlador de sonido
Entrando ahora en materia de programacion, es sabido que el presente trabajo se
realizara con el compilador Visual C++, ası que es importante hacer mencion de la
diferentes estructuras y funciones que se utilizaran para las pruebas y desarrollo del
ecualizador grafico virtual; dentro de este lenguaje se utiliza la notacion hungara, que
basicamente utiliza letras minusculas para indicar el inicio del nombre de la variable,
ası como su tipo.
A continuacion, se observara que las estructuras y definiciones usan la palabra
”WAVE”,(ONDA), porque se trabajaran con archivos de forma de onda,ası que para
comenzar tenemos la estructura WAV EFORMATEX que contiene la informacion
mas comun de los datos de una forma de onda y la cual define el formato. Cabe
mencionar que para formatos que requieren mayor informacion, esta se incluira como
primer miembro en otra estructura con la informacion adicional, la funcion tiene la
siguiente estructura:
typedef struct (WORD wFormatTag;WORD nChannels;DWORD nSamplesPerSec;DWORD nAvgBytesPerSec;WORD nBlockAlign;WORD wbitsPerSample;WORD CbSize; ) WAVEFORMATEX;
Se puede ver en la estructura que wFormatTag es del tipo WORD ya que es-
pecifica el tipo de formato de la forma de onda; nChannels, del tipo igual al anterior,
especifica el numero de canales a utilizar; del tipo DWORD es nSamplesPerSec,
que es el numero de muestras por segundo, que se reproduciran o grabaran en cada
28
canal y nAvgBytesPerSec que hace un promedio de la transferencia de datos en
bytes por segundo; para el alineamiento de bloques en bytes esta nBlockAlign, que
tambien es la unidad mınima de datos para el tipo de formato de la forma de onda y
wBitsperSample son los bits por muestra para wFormatTag.
Dado que un ecualizador utiliza senales de entrada y salida, a continuacion se
mencionaran las estructuras que sirven para este fin; primero mencionare la funcion
waveOutOpen, del tipo MMRESULT , la cual es la encargada de abrir el dispositivo
de salida, he aquı su estructura:
MMRESULT waveOutOpen(LPHWAVEOUT phwo,UINT uDeviceID,LPWAVEFORMATEX pwfx,DWORD dwCallBackInstance,DWORD fdwOpen );
De aquı se puede decir que phwo es del tipo LPHWAV EOUT y es ocupado para
identificar y relacionar las diferentes funciones de salida; para identificar el dispositivo
a utilizar ya sea de entrada o salida es uDeviceID que es del tipo UINT .
Otra funcion de salida es waveOutPrepareHader que es la que prepara un bloque
de datos de la forma de onda, para reproducirlo y su estructura es:
MMRESULT waveOutPrepareHeader (HWAVEOUT hwi,LPWAVEHDR phw,UINT cbwh );
Donde, el manejador del dispositivo de salida de la forma de onda es hwo; phw
es una direccion de la estructura WAV EHDR que es utilizada para definir los blo-
ques de datos que se van a preparar y cbwh es el tamano en bytes de la estructura
WAV EHDR.
Ligada a la anterior funcion es waveOutUnprepareHeader, solo que esta limpia
la preparacion que es realizada por waveOutPrepareHeader, la funcion debe ser
llamada despues de que el dispositivo termine con un bloque de datos y antes de
liberar el buffer. A continuacion se presenta su estructura.
29
MMRESULT waveOutUnprepareHeader (HWAVEOUT hwi,LPWAVEHDR phw,UINT cbwh );
Es importante mencionar que los parametros hwi, phw y cbwh funcionan de la
misma forma que en waveOutUnprapareHader y tambien son utilizados en la si-
guiente funcion que es la que manda un bloque de datos a la salida del dispositivo y
es denominada waveOutWrite siendo su estructura:
MMRESULT waveOutWrite (HWAVEOUT hwo,LPWAVEHDR pwh,UINT cbwh );
Para cerrar el dispositivo de salida de forma de onda existe la funcion llamada
waveOutClose y tiene una sencilla estructura como se muestra a continuacion:
MMRESULT waveOutClose(HWAVEOUT hwo );
Ası mismo la funcion con una estructura muy simple es waveOutReset, que detiene
el dispositivo de salida y reincia a cero.
MMRESULT waveOutReset (HWAVEOUT hwo );
Continuando, ahora se describiran las estructura y funciones de entrada, siendo
muy similares a las de salida.
Una de estas funciones es waveInOpen, que se requiere para abrir el dispositivo
de entrada de la forma de onda para despues grabarlo, su estructura es la siguiente:
MMRESULT waveInOpen (LPHWAVEIN phwi,UINT uDeviceID,LPWAVEFORMATEX pwfx,DWORD dwCallBackInstance,DWORD fdwOpen );
De la cual el parametro phwi es del tipo LPHWAV EIN y llena una direccion
con un manija identificada para abrir el dispositivo de entrada; uDeviceID es un
30
identificador de entrada del dispositivo; pwfx es para direccionar una estructura
WAV EFORMATEX,misma que identifica el formato deseado para grabar la forma
de onda; del tipo DWORD son dwCallback, dwCallbackInstance y fdwOpen.
Para cerrar el dispositivo dado de la forma de onda de audio se emplea la funcion
waveInClose, siendo su estructura:
MMRESULT waveInClose(HWAVEIN hwi );
Otra funcion es la que prepara un buffer para la forma de onda de audio y se
llama waveInPrepareHeader, y tiene como estructura:
MMRESULT waveInPrepareHeader (HWAVEIN hwi,LPWAVEHDR phwUINT cbwh );
Cuando se limpia la preparacion desarrollada por la anterior la funcion se denom-
ina waveInUnprepareHeader y puede ser llamada despues que el controlador del
dispositivo llena un buffer y retorna a esta aplicacion, su estructura es:
MMRESULT waveInUnprepareHeader (HWAVEIN hwi,LPWAVEHDR pwh,UINT cbwh );
Si uno desea detener la forma de onda de audio dada por el dispositivo y reiniciar
en la posicion de cero, se debe utilizar la funcion denominada waveInReset, esta
funcion tiene una estructura muy sencilla:
MMRESULT waveInReset (HWAVEIN hwi );
4.4. Programacion de una senal senoidal
A continuacion se tratara como generar la funcion seno, es decir algo como esto
f(x) = Asenwt, de donde se sabe que A representa a la amplitud de la onda y w es
la frecuencia angular multiplicada por el tiempo t. Este tipo de funcion utiliza una
31
medida angular o circular que se encuentra alrededor del perımetro de un cırculo sobre
una longitud igual al radio del circulo llamada radian. En relacion a esto se puede
decir que la circunferencia de una cırculo es 2π veces el radio, de manera que hay 2π
radianes en un cırculo de 360 grados, siendo los grados unidad de medida angular.
Tambien se utiliza los que es un fasor, y que es un numero complejo que expresa la
magnitud y la fase de una cantidad que varıa con el tiempo.
Pero, ¿cual es el problema de generar esta funcion por medio de algun lenguaje de
programacion? el problema radica en que no es nada facil intentar sacar o meter una
onda senoidal para poder escucharla, ası que continuacion se presenta una funcion
llamada fillbuffer (llenar buffer), escrita en lenguaje C, misma que sirve de apoyo y
es fundamental dentro del proceso del diseno. Sabiendo que, un buffer es un deposito
de datos intermedio, es decir, una parte reservada de la memoria donde los datos son
almacenados temporalmente y esta funcion ayuda al entendimiento de como es que
se llena un buffer y su relacion con la funcion seno.
VOID fillbuffer (LPBYTE Pbuffer, int iFreq){
static double fAngle;int i;
for (i=0 ; i<BUFFER_SIZE; i++){
pBuffer[i] = (BYTE) (127+127 * sin (fAngle);fAngle += 2* PI *iFreq / SAMPLE_RATE;
if (fAngle > 2 * PI)fAngle -= 2* PI ;
}}
Para el analisis de esta funcion, se debe tomar en cuenta que un buffer tiene valores
desde 0 hasta 256 (0-FF), por esta razon al parametro pBuffer realiza la operacion
que arriba se indica, esto es porque el producto de 127 ∗ sin(fAngle) nos da un valor
entre 0 y 127 (la funcion seno tiene un rango entre 1 y -1 ) y sumandole el otro 127
nos da como maximo 256 (FF), que es el tamano del buffer cuyos elementos del tipo
BYTE son de 8 bit por muestra. Ahora fAngle se refiere al valor del angulo, que es
32
resultado del producto 2 por PI por iFreq (que es la frecuencia que se desea) por
SAMPLERATE que es la razon de muestra, y que se puede explicar por medio del
teorema de Nyquist que nos dice que una senal (en este caso la onda seno) debe de ser
muestreada a una velocidad que sea por lo menos el doble de la frecuencia mas alta
que se encuentra en la senal, es decir, que si nuestra onda seno tiene un frecuencia
de 1000 Hz la frecuencia de muestreo debe de ser mınimo de 2000 Hz, o dicho de
otra forma, entre mas muestras se tengan de la senal mejor se podra trabajar con
ella, ya que se tendra mas informacion acerca de esta. Para que esto quede claro se
hara una analogıa de un buffer con un metro, siendo las rayitas”de los centımetros
las muestras.
Figura 4.3: A mayor numero de muestras se aprecia mejor el periodo de la onda seno.
La funcion entonces se encarga de llenar un buffer de datos que representan una
forma de onda, en este caso, una onda seno, para despues pasar a la Interface de
Programa de Aplicacion (API: Aplication Program Interface). Para una onda de am-
plitud continua, lo que hace la funcion es tomar solo un ciclo de esta onda, para que
cuando llegue a 2 veces π o 360◦ cumpla su proposito de llenar el buffer.
4.5. Graficacion y controles graficos
La graficacion como ya se menciono anteriormente, es parte fundamental dentro
del area de la informatica, en nuestro caso es basica para la programacion, es decir,
33
Figura 4.4: La regresion se realiza haciendo el if(fAngle > 2∗PI) y luego fAngle− =2 ∗ PI.
es una implementacion para obtener un resultado en forma de un dibujo. Para esto
su usan los pixeles, que son pequenos puntos que forman una extensa capa a lo largo
y ancho de la pantalla.
Como es sabido, se esta utilizando el lenguaje Visual C++ para el desarrollo de
programas que son de mucha utilidad, dentro del mismo existen los llamados recursos,
que vienen siendo los mapas de bits, el cursor, una caja de dialogo, un icono, una
barra de herramientas y la version, existiendo un editor para cada uno de estos tipos.
Tambien existen las ventanas, que son objetos con ciertas propiedades y a las
cuales se les asocia un codigo, ası que es evidente que la programacion de Windows
es orientada a objetos. generalmente una ventana principal (ventana madre), tiene
diferentes elementos como los son: un tıtulo con el nombre de la aplicacion, un menu,
bordes de tamano y cuando son necesarias barras de desplazamiento (horizontal y
vertical).Esta ventana, a su vez puede contener otras ventanas denominadas ventanas
hijas.
34
Figura 4.5: Algunos ejemplos de recursos
A las notificaciones que Windows envıa a una aplicacion que se esta ejecutando
para indicarle que algo ha sucedido se les llaman mensajes. Algunos ejemplos sencillos
pueden ser el hacer clic sobre un boton, mover el raton, pulsar una tecla, etc. En
un mapa de mensajes, se distinguen tres tipos de mensajes: mensajes de ordenes,
mensajes de notificacion y mensajes de ventana.
Y es precisamente en una ventana madre en donde colocaremos las barras de
desplazamiento, que son los recursos mas significativos a utilizar, cabe mencionar que
se trabaja con estas, dado que, pueden desplazar la informacion hacia arriba o hacia
abajo para representar un valor entero.
4.6. Algoritmo computacional FFT
Para trabajar dentro Visual C++ se implemento un programa escrito en lenguaje
C , que nos permite obtener de manera numerica y grafica los resultados que deseamos
35
obtener. Asi que una vez que realizamos la interface grafica agregamos el algoritmo
denominado mariposa que es el que nos permite realizar las operaciones con una
mayor velocidad de calculo. El programa utilizado es el siguiente:
#include<windows.h>#include<math.h>#define pi 3.1415926#define Tmuestreo 0.0000226757 //44.1 kHz#define frec 1000 //1 KHZvoid bitrev(int N, float XR[1024],float XI[1024]);main(){
int i, j, k, M,M1,M2;float C, S,tempr, tempi, XR[2048], XI[2048], WR[2048], WI[2048];int N=1024, L=10, N1, N2, I1, I2;
for(i=0;i<=N-1;i++){
WR[i] = cos(2*pi*i/N);WI[i] = -sin(2*pi*i/N);
}
for(i=0;i<=N-1;i++){
XR[i] = sin(2*pi*frec*Tmuestreo*i);XI[i] = 0.0;
}
N2 = N;
for(i=0;i<L;i++){
N1=N2;N2=N2/2;I1=0;I2=N/N1;
for(j=0;j<N2;j++){
C=WR[I1];S=WI[I1];I1=I1+I2;
for(k=j;k<N;k+=N1){
M=k+N2;
tempr=XR[k]-XR[M];XR[k]=XR[k]+XR[M];tempi=XI[k]-XI[M];XI[k]=XI[k]+XI[M];XR[M]=C*tempr-S*tempi;XI[M]=C*tempi+S*tempr;
36
}}
}
bitrev(N,XR,XI);
for(i=0;i<=(N-1)/2;i++){
X[i]=(sqrt(pow(XR[i],2)+pow(XI[i],2)));LineTo(hdc,i+100,(int)(200.0-X[i]));
}
En este programa se toma una muestra x[n] real con un numero de N muestras
potencia de dos, (es decir 2v = N) donde v es el numero de etapas de la Transformada
Rapida. Al observar el programa empieza con un desplegado en pantalla que pide el
numero de muestras que se desean transformar y las almacena en la variable N, a
continuacion llama a una funcion int log2(int N) que obtiene el numero de etapas de
la Transformada mediante el algoritmo base 2 del numero de muestras, luego, genera
una tabla con los valores WN y se almacena en los arreglos para la parte real y la
imaginaria WR[N] y WI[N]. Despues se hace una iteracion para pedir por el teclado
el valor de cada uno de los elementos del arreglo que representara a la muestra y se
almacena en el arreglo X[N], teniendo esto se procede a realizar el algoritmo.
Como se puede apreciar en el ultimo for es donde se localiza el resultado de la
Transformada, representado por cuestiones de graficacion por el valor absoluto.
Otro punto a tomar en cuenta es que, ya sea el metodo de decimacion en frecuencia
o en tiempo la secuencia de entrada es dada en orden normal y la salida queda con bits
invertidos, ası que para solucionar esta situacion, se realiza la funcion llamada bitrev
(inversion de bits) que permiten que una secuencia del calculo de la Transformada
Rapida sea reordenada para obtener el resultado deseado.
Se puede ilustrar con el caso N = 8, representado por tres bits. Los bits que deben
de ser cambiados de sus posiciones son el 3 y 1. Por ejemplo, (100)b queda (001)b.
Esto permite que el dato que estaba en la posicion de memoria 4 = (100)b pase a la
37
posicion 1 = (001)b.
Entonces, para que el resultado quede almacenado en los arreglos XR[N] y XI[N]
en orden natural, se utiliza la siguiente funcion:
void bitrev(int N, float XR[1024], float XI[1024]){
float temp;int i, j, k;j=0;
for(i=0;i<N-1;i++){if(i<j){temp=XR[j];XR[j]=XR[i];XR[i]=temp;temp=XI[j];XI[j]=XI[i];XI[i]=temp;k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;}else{k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;}}
}
38
Capıtulo 5
Pruebas y Resultados
En el presente capıtulo se presentan las pruebas efectuadas para diferentes tipos
de senales a el algoritmo de la transformadada rapida de fourier, tales como una onda
senoidal, ruido blanco y un archivo .wav, de las cuales se muestran los resultados
obtenidos. Tambien se muestra el procedimiento de programacion mediante el cual
se desarrollo nuestro panel de control, asi como tambien las graficas pertinentes para
cada tipo de senal.
5.1. Metodo Orientado a Procedimientos
Es importante mencionar que sigo trabajando dentro del entorno Visual C++ solo
que ahora sin clases, sino que adaptamos el codigo fuente llamado sinewave.c con los
respectivos archivos de recursos y de cabecera.
Entonces dado que la ruitna de sonido permite trabajar con 2 buffers para que se
oiga de una manera continua, lo que hicimos fue lo siguiente: ir adaptando las veinte
barras de desplazamiento vertical, el algoritmo de la FFT, los marcos, etc., como a
continuacion se explica:
La rutina de sonido se inicializa mediante la declaracion de 2 buffers (buffer1 y
buffer2), hecho esto realiza un direccionamiento a la memoria; despues por medio de
un boton genera un mensaje por el cual manda a llamar las funciones WaveOutWrite y
WaveOutprepareHeader que prepara el primer buffer para se tocado, a continuacion
39
el case WMDONE es el encargado de que mientras un buffer esta tocando (esta
lleno) el otro se esta llenando en espera de ser tocado y asi sucesivamente; esta accion
se termina cuando uno oprime otro boton que genera otro mensaje y manda llamar
las estructuras WaveOutClose y WaveUnprepareHeader.
5.2. Trabajando con las barras verticales
Continuando con las barras de desplazamiento, las cuales en este codigo fuente se
trabajaran con la diferencia de que ahora cada una tendra su propia estructura para
que de esta forma trabajen de una forma independiente una de otra. La estructura a
utilizar es la siguiente:
case WM_INITDIALOG:hsc = GetDlgItem (hwnd, IDC_SCROLL) ;SetScrollRange (hsc, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc, SB_CTL, 128,FALSE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE) ;...hsc = GetDlgItem (hwnd, IDC_SCROLL20) ;SetScrollRange (hsc20, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc20, SB_CTL, 128,FALSE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE) ;
case WM_LINELEFT:if(lParam==(LPARAM)hsc) var1--;...if(lParam==(LPARAM)hsc20) var20--;case WM_LINERIGHT:if(lParam==(LPARAM)hsc) var1++;...if(lParam==(LPARAM)hsc20) var20++;case SB_THUMBTRACK:if (lParam==(LPARAM)hsc) var1=HIWORD(wParam);...if (lParam==(LPARAM)hsc20) var20=HIWORD(wParam);case SB_BOTTOM:if (lParam==(LPARAM)hsc)GetScrollRange(hsc,SB_CTL,&iDummy,&var1);.
40
.
.if (lParam==(LPARAM)hsc20)
GetScrollRange(hsc,SB_CTL,&iDummy20,&var20);break ;
}SetScrollPos (hsc,SB_CTL,var1,TRUE);...SetScrollPos (hsc,SB_CTL,var20,TRUE);
SetDlgItemInt(hwnd,IDC_TEXT5,255-var1,TRUE);...SetDlgItemInt(hwnd,IDC_TEXT5,255-var20,TRUE);
Despues de esto se inserta el algoritmo de la FFT, el cual se hara de una manera
modular para facilitar su manejo, esto es que el codigo se ha ido separando en fun-
ciones, dado que de esta forma solo se manda a llamar la parte del programa con lo
que nos interesa trabajar, quedando lo anterior de la siguiente manera:
//funcionseno(entrada);ruidoblanco(entrada);graficarentrada(hwnd,1024,entrada);fft(nm,entrada,salida);modificarfft(nm,salida,salidafft);graficartransformadafft(hwnd,1024,salidafft);ifft(nm,salidafft,salida3);graficartransformadaifft(hwnd,1024,salida3);
Como se puede observar, como prueba se tienen dos senales, una es senoidal y otra
que genera ruido blanco. La senal que uno desee se toma como entrada para graficarse,
luego se le asigna a la Transformada Rapida de Fourier para obtener su espectro de
frecuencias, y aqui es donde se encuentra la parte medular de el presente trabajo: la
ecualizacion, misma que se obtiene al mover las barras, para que a continuacion este
resultado se le asigne a la Transformada Inversa de Fourier para quedar en el dominio
del tiempo nuevamente y asi poder esucharlo por medio de la tarjeta de sonido.
41
5.3. Normalizacion de las graficas
Para normalizar las graficas y presentarlas de una manera adecuada lo que se hizo
fue lo siguiente, se conocio el valor en pixels de cada uno de nuestros marcos mediante
las instrucciones MoveTo y LineTo obteniendo como resultado un marco de 1010 por
142 pixeles, y dado que los marcos son iguales se implemento la siguiente instruccion
dentro de nuestras funciones de graficacion
MoveToEx(hdc,0,y,NULL);
for(i=0;i<=1010;i++){
y=(bentrada[i]/255)*142;yy=y+240;LineTo(hdc,i,yy);
}
garantizando con esto que cualquier senal que nosotros queramos graficar no re-
basara los margenes de los marcos.
He dicho que para dar la impresion de atenuar o subir el nivel de la senal se
hara mediante las barras de desplazamiento; anteriormente se explico como se hara es-
to, recordando que son veinte, el primer paso fue colocar una por una y darles una
presentacion adecuada para mostrar el panel de control como en la figura (5.1). Como
se puede apreciar a cada barra le corresponde una frecuencia que estan divididas en
intervalos desde 20 hasta 20k Hz, con lo cual se trata de cubrir las frecuencias mas sig-
nificativas desde los agudas hasta las mas graves, obteniendo con esto la ecualizacion
de la senal senoidal.
5.4. Lectura de un archivo .wav
De acuerdo con la Figura (5.1), se puede ver de una manera detallada como ha sido
disenado el formato de un archivo .wav. Consideremos una matriz de m x n donde
n (0H-FH) son las filas, y m (0H-FH) son las columnas. Los elementos de la matriz
son numeros hexadecimales que constituyen cada uno de los campos que definen las
42
Figura 5.1: Panel de control de 20 bandas
caracteristicas de un archivo .wav. A continuacion se describen cada uno de dichos
campos.
0 1 2 3 4 5 6 7 8 9 A B C D E F
0 52 49 46 46 B0 B1 B2 B3 57 41 56 45 66 62 74 201 B0 B1 B2 B3 B0 B1 B0 B1 B0 B1 B2 B3 B0 B1 B2 B3
2 B0 B1 B0 B1 64 61 76 61 B0 B1 B2 B3 d0 d1 d2 d3
3 d4 d5 d6 d7 d8 d9 d10 d11 d12 d13 d14 d15 d16 d17 d18 d19
456789ABCDEF
Tabla 5.1: Encabezado de un archivo de sonido WAVE
El primer campo de la matriz ocupa los elementos 00, 01, 02 y 03. En ellos se en-
cuentran los cuatro numeros que identifican a un archivo de sonido WAV. Agrupando-
los en cuatro bytes corresponderan a una cadena de caracteres ASCII que contienen
la palabra RIFF la cual es conocida como ”numero magico”. Dichos numeros en
hexadecimal son: 52H, 49H, 46H, y 46H.
43
El siguiente campo corresponde al tamano del archivo que contiene el sonido
WAV. Estos numeros corresponden a la secuencia B0, B1, B2, y B3, los cuales ocupan
los elementos de la matriz 04, 05, 06, 07. Notese que primero se lee el byte menos
significativo, y hasta el ultimo se lee el byte mas significativo.
Continuando con nuestra descripcion, el siguiente campo numerado con los ele-
mentos 08,09,0A y 0B de la matriz contienen una cadena de caracteres ASCII que
corresponde a la palabra WAV E cuya secuencia de numeros en hexadecimal son 57H,
41H, 56H, y 45H.
En cuanto al siguente campo numerado con 0C,0D,0E y 0F, contiene una secuencia
de cracteres ASCII que corresponden a la palabra fmt. Notese que dicha palabra
termina con un espacio en blanco. Entonces, su secuencia de numeros hexadecimales
seran 66H, 6DH, 74H y 20H. Este ultimo corresponde al caracter espacio (20H).
Ahora bien, el campo que sigue se encuentra en las posiciones 10,11, 12 y 13 de
la matriz. En ellas se encuentra un numero entero de 4 bytes que nos especifica el
tamano del bloque. Este numero contiene la secuencia B0, B1, B2, y B3 semejante en
orden a como se ha descrito en el campo Tamano del Archivo. Es evidente que su
valor variara de acuerdo con un archivo.wav determinado.
Por otra parte, el siguiente campo (elementos 14 y 15) contienen un numero entero
formado por 2 bytes (B0 y B1) para indicar el tipo de formato. Si este numero es igual
a cero, entonces indica que el archivo se ha grabado de manera monoaural (un solo
microfono). Pero si dicho entero es igual a uno, entonces el sonido se grabado con dos
microfonos, es decir, en estereofonıa.
Prosiguiendo con la explicacion,en nuestro siguiente campo se tiene como con-
tenido el numero de canales utilizados por el archivo.wav. Este es un numero entero
de 2 bytes que tiene la secuencia B0 y B1, misma que esta contenida en los elementos
16 y 17 de la matriz en cuestion. Cabe mencionar que este numero tiene que ver con
la forma de grabacion del archivo.wav, es decir,que si es igual a uno entonces significa
que se grabo en formato monoaural, pero si es igual a dos, significa que se grabo en
44
formato estereo.
A continuacion, el campo siguiente se refiere a la frecuencia de muestreo del archi-
vo.wav, que puede tener un valor de 11,025, 22,050 o 44,100 Hz. Para este numero
entero de 4 bytes los elementos que le corresponden en la matriz son 18, 19, 1A y 1B,
con una secuencia dada por B0, B1, B2, y B3
El siguiente campo corresponde al numero de bytes por segundo que se deben
intercambiar con la tarjeta de sonido para poder grabar o reproducir un archivo.wav.
Este es un numero entero de 4 bytes que contiene una secuencia: B0, B1, B2, y B3 y
cuyas posiciones de los elementos en la matriz corresponden con 1C,1D, 1E y 1F.
Siguiendo con la descripcion, el siguiente campo nos indica los bytes por muestra
de nuestro archivo.wav. Este es un numero entero de 2 bytes que tiene una secuencia
dada por B0 y B1 y sus elementos en la matriz son 20 y 21. Es preciso decir que si este
numero es igual a uno tendremos ocho bits monoaurales, si es igual a 2 tendremos
ocho bits estereo o dieciseis monoaurales y si es igual a 4 tendremos dieciseis bits
estereo.
Para continuar con nuestro analisis, tenemos el campo que corresponde a los bits
por muestra, mismos que pueden ser ocho o dieciseis bits dependiendo de un determi-
nado archivo.wav. Esta caracterıstica es un numero entero de dos bytes cuya secuencia
corresponde con B0 y B1 y que tiene sus elementos de la matriz posicionados en 22 y
23.
El siguiente campo contiene una cadena de caracteres ASCII que forman la palabra
data cuyos elementos en la matriz estan ubicados en 24, 25, 26 y 27, teniendo una
secuencia de numeros hexadecimales dada por 64H, 61H, 76H y 61H
Finalmente tenemos la caracterıstica que corresponde a la cantidad de datos que
es casi igual al Tamano del Archivo. En consecuencia este tambien sera un numero
entero de cuatro bytes, al cual le corresponde una secuencia B0, B1, B2, y B3 y cuyos
elementos en la matriz tienen las posiciones 28,29, 2A y 2B.
Despues de las caracteristicas mencionadas, a los campos subsecuentes correspon-
45
deran los datos de audio del archivo.wav
5.5. Formatos bigendian vs. littleendian
Son formatos de almacenamiento de datos utilizados por los microprocesadores
para describir la relacion que existe entre el orden y el almacenamiento de los bytes
(el mas significativo o el menos significativo). Por ejemplo Intel y Motorola tienen sus
datos en memoria de formas opuestas, es decir que si el 80386 (Intel) almacena 1234
5678 el 68020 (Motorola) leera 7856 3412. Estos terminos fueron usados por Danny
Cohen en octubre de 1981.
5.6. Visualizacion de las senales
Ahora bien, teniendo como pruebas una senal senoidal igual con sen(2∗pi∗frec∗Tmuestreo∗i) y otra senal aleatoria que es la que nos genera el ruido blanco mostradas
en las Figuras (5.2) y (5.3) respectivamente:
Figura 5.2: Senal de entrada senoidal
y aplicando el programa de la Transformada Rapida se obtienen las figuras (5.4)
y (5.5), que nos muestran los espectros de magnitud para cada senal:
46
Figura 5.3: Ruido blanco como senal de entrada
Como se puede observar es el espectro de magnitud de la senal, mismo que se
controlara mediante una barra de desplazamiento vertical que dara la impresion de
atenuar o disminuir su amplitud.
Despues de esto, lo que se quiere es regresar al dominio del tiempo, y esto se logra
mediante la transformada inversa, que esencialmente es el mismo programa solo que
la entrada ahora sera el resultado de la Transformada Rapida, es decir, el espectro
de magnitud, obteniendo nuevamente la senal de entrada, pero ya ecualizada como
se muestra en las figuras (5.6) y (5.7):
47
Figura 5.4: Espectro de magnitud de la senal senoidal
Figura 5.5: Espectro de magnitud del ruido blanco
48
Figura 5.6: Senal senoidal resultante, una vez ecualizada
Figura 5.7: Ruido blanco una vez ecualizado
49
Figura 5.8: Vista general del ecualizador grafico teniendo como senal ruido blanco.
50
Figura 5.9: Vista general del ecualizador grafico teniendo como senal una ondasenoidal.
51
Capıtulo 6
Conclusiones y Trabajos Futuros
El mundo moderno en que vivimos, crece y evoluciona de una manera vertigi-
nosa, aplicandose esto a cualquier rubro, pero especialmente en la ciencia, que como
sabemos es una sola, pero para su estudio se divide en muchas ramas, lo cual nos per-
mite la posibilidad de estudiarla y comprenderla de una mejor manera. En nuestro
caso esta posibilidad la tomamos y aplicamos en ramas como las matematicas y la
computacion.
Como es sabido las matematicas las ha utilizado el hombre desde hace miles de
anos, y con el tiempo las ha ido razonando, estudiando y por consecuencia desarrollan-
do metodos que han ayudado a facilitar la forma de obtener los resultados deseados;
tal es el caso de Jean Baptiste Joseph Fourier, con su analisis sobre la conduccion del
calor.
Nosotros nos basamos en este analisis, especıficamente con la llamada Transfor-
mada de Fourier, y aquı es donde interviene la otra rama antes mencionada: la com-
putacion. Y es que en estos dıas es imprescindible esta poderosa herramienta, ya que
por principios de cuentas nos permite procesar grandes cantidades de informacion en
cuestion de segundos. Ası que utilizando este concepto se ha desarrollado un algo-
ritmo computacional llamado Transformada Rapida de Fourier, mismo que tomamos
como base para desarrollar el ecualizador grafico virtual.
Esto viene aunado a otra rama como lo es la acustica que es la encargada de
52
estudiar la generacion, propagacion y efecto de las ondas sonoras. Entonces una forma
de trabajar con el efecto de estas ondas es ecualizandolas, y para esto se utilizo el
algoritmo computacional antes mencionado.
El inicio de nuestro proyecto fue la eleccion de un lenguaje de programacion que
nos permitiera el diseno de una interfase grafica de acuerdo a nuestras necesidades.
Asi que de esta manera optamos por el lenguaje Visual C++ .NET, ya que este
lenguaje nos permitio un aprendizaje asi como tambien un facil manejo. Asi pues
el disenp de nuestro ecualizador grafico fue realizado con utilidades al alcanze de
cualquier usuario.
Desde un principio se tuvo presente que el metodo matematico en el cual deberi-
amos emplear seria la transformada rapida de Fourier (FFT ). Nuestros resultados
deberıan presentarse graficamente por medio de una ventana principal para poder
visualisar las diferentes formas de onda. Lo anterior se logro mediante ciertas tecnicas
de graficacion y la implementacion de una rutina para el algoritmo FFT realizada en
lenguaje C, la cual posteriormente fue insertada en el ambiente de Visual C++ .NET
para su compilacion.
De esta forma al momento de realizar las diferentes pruebas nos mostraron grafica
y correctamente los espectros de magnitud en el dominio de la frecuencia, asi como
tambien el resultado al regresar al dominio del tiempo una vez que se hubieron ecual-
izado las diversas senales con lo que pudimos comprobar que nuestros algoritmos FFT
y IFFT funcionaban correctamente
Nuestro siguiente paso fue comenzar a trabajar con el sonido, es decir enviar los
datos almacenados en un buffer a otro buffer que se esta incorporado al driver de
la tarjeta de sonido. En este punto nos topamos con otro problema, y es que al hacer
una investigacion acerca de este tema descubrimos que en Mexico existe muy poca
informacion al respecto, asi que lo que logro auxiliarnos fue el articulo encontrado en
una revista.
Entonces ahora si se comenzo a implementar la rutina la cual nos permitia llenar
53
en forma paulatina los buffers antes mencionados para que el sonida que se produjese
fuera constante. Nuevamente se probo con una onda senoidal, para despues probar
con la generacion de ruido blanco dandonos un resultado satisfactorio para las tres
senales.
Una vez hecho esto se juntaron ambas rutinas (la de la interfase grafica y la del
sonido) para que de esta forma se pudiera llevar a cabo la ecualizacion de las senales
mediante las barras verticales.
En resumen las contribuciones mas importante de esta tesis son:
- La implementacion de un algoritmo para la FFT mediante rutinas en lenguaje
C.
- La lectura de diversas senales de audio por medio de instrucciones de abjo nivel.
- Tecnicas de graficacion en Visual C++ .NET
- Y por ultimo un ecualizador grafico de veinte bandas que puede ejecutarse en
sistemas Windows 95 o superiores.
6.1. Trabajos futuros
A continuacion se presentan algunas sugerencias para la mejora y aplicacion del
presente trabajo. Para una mejor calidad de presentacion se pueden implementar
diversos elementos los cuales nos permitiran mejorar la apariencia, la funcionalidad
y la aplicacion cientıfica.
En lo que respecta a la estetica se puede mejorar la apariencia de las barras
verticales, dondoles por ejemplo una apariencia en tercera dimension o mediante un
programa de edicion hacer que esos controles se vean como en un ecualizador fısicas,
ademas de que las graficas pueden ser de colores diferentes.
En cuanto a la funcionalidad una de las mejoras que se podrian realizar es que
mediante diversos metodos de programacion se logre ecualizar en tiempo real con
cualquier tipo de archivo se sonido.
Ahora, como es sabido un ecualizador es fundamental es un sistema de audio
54
profesional asi que una utilidad futura seria que formara parte de uno, es decir, que
pueda se implementado a una consola, asi para un musico que disponga de una PC
podria utilizarlo de una manera rapida y facil.
Una utilidad muy interesante es la implementacion de un archivo .wav en tiempo
real la cual se seguira investigando y desarrollando.
Por otra parte la presente tesis puede utilizarse con fines academicos para un mejor
entendimiento del analisis de Fourier refiriendose esto a la transformada rapida. O
bien el algoritmo podria ser adaptado para realizar un analizador de espectro, o
implementarlo para que pueda ser utilizado como un sismografo, en fin estas solo son
algunas de las muchas aplicaciones que el algoritmo FFT pudiera tener.
Para finalizar, es importante mencionar la labor conjunta que se realizo con el
Dr. Maximino Pena Guerrero y el Ing. Jose de Jesus Negrete Redondo, profesores
de la academia de acustica de la ESIME-Zacatenco. Actualmente continuan con el
desarrollo de diversos proyectos en ciencia y tecnologıa acustica.
55
Anexo A
Transformada Rapida de Fourier
En este apendice se trata de una manera breve pero detallada como es que esta
basado el algoritmo de la FFT, es decir como es que la transformada de descomopone
en transformadas mas pequenas y a partir de este punto se combinan para obtener
la transformada final. Una observacion importante es que este algoritmo puede ser
realizado en los dominios del tiempo y de la frecuencia.
A.1. Algoritmo FFT
Partiremos a partir de la transformada discreta de donde el problema es obtener
la secuencia de longitud N de la siguiente formula:
X(k) =N−1∑n=0
x(n)W nk donde k = 0, 1....N − 1 y N = 2a, a = 1, 2, 3... (1)
El factor W = e−j2π
N con e−jx = cos(x)− jsen(x), en donde la expresion exponen-
cial representa un numero complejo en coordenadas polares.
De la ecuacion anterior, se puede calcular un punto de la transformada discreta
mismo que es dado por:
X(k) = x(0)W 0 + x(1)W k + x(2)W 2k + ....x(N − 1)W k(N−1) (2)
Si se desarrolla la ecuacion (2) para k con N valores posibles se obtendra una matriz
de tamano NxN y ademas se calcula el numero de operaciones necesarias para hacer
la transformacion de los datos mediante este algoritmo, ası que, el numero de sumas
complejas que se deben realizar es de (N − 1)N y la cantidad de multiplicaciones
56
complejas es igual a N2. Dado que es una cantidad de operaciones muy alta, el
calculo directo de la Transformada no resulta eficiente, debido a que no explota las
propiedades desimetrıa y periocidad del factor de fase Wn.
Observando la ecuacion (2) es claro que las N2 multiplicaciones no son necesarias
realizarlas porque los valores de los factores W 0 = 1 no son necesarios de multiplicar
A.2. Decimacion en Tiempo
Este proceso es conocido tambien con el nombre de ”mariposa”, siendo muy efi-
ciente para el calculo de la transformada de Fourier. El numero de muestras que se
tomaran en este proceso es una potencia de 2, es decir N = 2v. En este metodo
la aproximacion es realizada mediante la descomposicion de la transformada de N
puntos en dos transformadas de N/2 muestras, despues la descomposicion de cada
transformada de N puntos en dos transformadas de N/4 puntos, y se continua este
proceso hasta obtener transformadas de 2 puntos. Tomando la ecuacion (1) y divi-
diendola en dos partes, una para los valores con ındice par y otra para los valores con
ındice impar, se tiene:
X(k) =N−2∑n=0
x[n]W kn +N−1∑n=1
x[n]W kn (3)
Haciendo un arreglo para cada parte de X(k) en transformadas de N/2 puntos y
usando:
W 2kr = (W 2)rk = e(−j2π
N )(2kr) = e(−j2πN/2 )(kr) = W rk (4)
nos queda lo siguiente:
X(k) =N/2−1∑
r=1x[2r]W rk + W k
N/2∑r=0
x[2r + 1]W rk (5)
La ecuacion (5) puede ser escrita de la siguiente forma si G(k) y H(k) representan
las transformadas de N/2 puntos de la secuencia de valores con ındice par e impar:
X(k) = G(k) + W (H(k)) k = 0, 1, 2.... (6)
Este primer paso en la descomposicion divide la transformada en dos transfor-
madas de N/2 puntos y los factores proporcionan el algebra combinacional como se
muestra en la Fig. (A.1).
57
Figura A.1: Separacion de la DFT de N puntos en dos DFT´s de N/2 puntos
Como resultado de este proceso, las X quedan ordenadas en grupos de pares e
impares. El proceso de descomposicion puede ser repetido nuevamente pero esta vez
para N/4 y asi sucesivamente hasta llegar a la transformada de 2 puntos. En general
una FFT de N puntos tendra a etapas con N = 2a como lo muestra la Fig. (A.3).
A.3. Decimacion en frecuencia
Este procedimiento es dual al de la decimacion en tiempo, ya que tienen propiedades
similares, en este caso la entrada es dada en su orden natural, mientras que la salida
es con la inversion de bits. El numero total de mariposas, factores W , y operaciones
son identicas a aquellas que en la decimacion en tiempo, la Fig. (A.2) es un ejemplo
de ello
58
Figura A.2: Separacion de la DFT para la decimacion en frecuencia
Figura A.3: Decimacion en tiempo para 8 muestras (N = 8)
59
Figura A.4: Decimacion en frecuencia para 8 muestras (N = 8)
60
Anexo B
Codigo fuente del ecualizador
*------------------------------------------------------SINEWAVE.C -- Ecualizador Grafico de Sonido.
-- Dr.Maximino Pe~na Guerrero.Ing. Jose de Jesus Negrete Redondo.Juan Sımuta Pe~na.Mexico D.F. 2006.
------------------------------------------------------*/
#include <windows.h>#include <math.h>#include "resource.h"#include <mmsystem.h>
#define pi 3.14159#define Tmuestreo 0.0000226757 //44.1 MHz#define frec 1000 //1 KHz
void fft(int,float[],float[]);void ifft(int,float[],float[]);void bitrev(int N, float XR[1024],float XI[1024]);void bitrev2(int N, float XR2[1024],float XI2[1024]);
#define SAMPLE_RATE 44100#define FREQ_MIN 20#define FREQ_MAX 5000#define FREQ_INIT 127#define OUT_BUFFER_SIZE 4096#define PI 3.14159
static BOOL bShutOff, bClosing ;static HWAVEOUT hWaveOut ;static HWND hsc ;static HWND hsc2 ;static HWND hsc3 ;static HWND hsc4 ;static HWND hsc5 ;static HWND hsc6 ;static HWND hsc7 ;
61
static HWND hsc8 ;static HWND hsc9 ;static HWND hsc10;static HWND hsc11;static HWND hsc12;static HWND hsc13;static HWND hsc14;static HWND hsc15;static HWND hsc16;static HWND hsc17;static HWND hsc18;static HWND hsc19;static HWND hsc20;static HWND hsc21;
static int iFreq =128;static int var1 = 128;static int var2 = 128;static int var3 = 128;static int var4 = 128;static int var5 = 128;static int var6 = 128;static int var7 = 128;static int var8 = 128;static int var9 = 128;static int var10 =128;static int var11 =128;static int var12 =128;static int var13 =128;static int var14 =128;static int var15 =128;static int var16 =128;static int var17 =128;static int var18 =128;static int var19 =128;static int var20 =128;
static PBYTE pBuffer1, pBuffer2 ;static PWAVEHDR pWaveHdr1, pWaveHdr2 ;static WAVEFORMATEX waveformat ;static int iDummy ;static int iDummy2 ;static int iDummy3 ;static int iDummy4 ;static int iDummy5 ;static int iDummy6 ;static int iDummy7 ;static int iDummy8 ;static int iDummy9 ;static int iDummy10 ;static int iDummy11 ;static int iDummy12 ;static int iDummy13 ;
62
static int iDummy14 ;static int iDummy15 ;static int iDummy16 ;static int iDummy17 ;static int iDummy18 ;static int iDummy19 ;static int iDummy20 ;static int iDummy21 ;
BOOL CALLBACK DlgProc(HWND,UINT,WPARAM,LPARAM) ;VOID OnLoop(HWND,LPARAM);VOID OnAbrir(HWND);VOID OnCerrar(HWND);VOID FillBuffer(PBYTE,int);BOOL OnGenerar(HWND);VOID Repintar(HWND,LPARAM);VOID graficar(HWND);VOID ruidoblanco(PBYTE);VOID ondacuadrada(PBYTE);VOID graficarbuffer(HWND);VOID funcionseno(PBYTE);VOID graficarentrada(HWND);VOID graficartransformadafft(HWND);VOID graficartransformadaifft(HWND);VOID modificarfft(float[],float[]);VOID copiarbuffer(float[],float[]);
static HWAVEOUT hWaveOut;static int wVeces=0;static PBYTE pBuffer1;static PBYTE pBuffer2;static PWAVEHDR pWaveHdr1;static PWAVEHDR pWaveHdr2;static WAVEFORMATEX waveformat;static HWND hdlg;
int nm=1024;float entrada[1024];float salida[1024];float salida2[1024];float salidafft[1024];float salida3[1024];float salida4[1024];
TCHAR szAppName[]=TEXT("SineWave") ;
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow)
{if(-1==DialogBox(hInstance,szAppName,NULL,DlgProc))
{MessageBox(NULL,TEXT("Requiere Windows NT!"),szAppName,MB_ICONERROR);}
63
return(0);}
BOOL CALLBACK DlgProc(HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam){
switch (message){
case WM_PAINT://ruidoblanco(entrada);
funcionseno(entrada);
return 0;
case WM_INITDIALOG:
hsc = GetDlgItem (hwnd, IDC_SCROLL) ;SetScrollRange (hsc, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc, SB_CTL, 128,FALSE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE) ;
hsc2 = GetDlgItem (hwnd, IDC_SCROLL2) ;SetScrollRange (hsc2, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc2, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT5, FREQ_INIT, FALSE) ;
hsc3 = GetDlgItem (hwnd, IDC_SCROLL3) ;SetScrollRange (hsc3, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc3, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc4 = GetDlgItem (hwnd, IDC_SCROLL4) ;SetScrollRange (hsc4, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc4, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc5 = GetDlgItem (hwnd, IDC_SCROLL5) ;SetScrollRange (hsc5, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc5, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc6 = GetDlgItem (hwnd, IDC_SCROLL6) ;SetScrollRange (hsc6, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc6, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc7 = GetDlgItem (hwnd, IDC_SCROLL7) ;SetScrollRange (hsc7, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc7, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
64
hsc8 = GetDlgItem (hwnd, IDC_SCROLL8) ;SetScrollRange (hsc8, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc8, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc9 = GetDlgItem (hwnd, IDC_SCROLL9) ;SetScrollRange (hsc9, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc9, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc10 = GetDlgItem (hwnd, IDC_SCROLL10) ;SetScrollRange (hsc10, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc10, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc11 = GetDlgItem (hwnd, IDC_SCROLL11) ;SetScrollRange (hsc11, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc11, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc12 = GetDlgItem (hwnd, IDC_SCROLL12) ;SetScrollRange (hsc12, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc12, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc13 = GetDlgItem (hwnd, IDC_SCROLL13) ;SetScrollRange (hsc13, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc13, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc14 = GetDlgItem (hwnd, IDC_SCROLL14) ;SetScrollRange (hsc14, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc14, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc15 = GetDlgItem (hwnd, IDC_SCROLL15) ;SetScrollRange (hsc15, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc15, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc16 = GetDlgItem (hwnd, IDC_SCROLL16) ;SetScrollRange (hsc16, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc16, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc17 = GetDlgItem (hwnd, IDC_SCROLL17) ;SetScrollRange (hsc17, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc17, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
65
hsc18 = GetDlgItem (hwnd, IDC_SCROLL18) ;SetScrollRange (hsc18, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc18, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc19 = GetDlgItem (hwnd, IDC_SCROLL19) ;SetScrollRange (hsc19, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc19, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc20 = GetDlgItem (hwnd, IDC_SCROLL20) ;SetScrollRange (hsc20, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc20, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
hsc21 = GetDlgItem (hwnd, IDC_SCROLL21) ;SetScrollRange (hsc21, SB_CTL, 0, 255, FALSE) ;SetScrollPos (hsc21, SB_CTL, 128, TRUE) ;SetDlgItemInt (hwnd, IDC_TEXT, FREQ_INIT, FALSE);
break;
case WM_VSCROLL:switch (LOWORD (wParam)){
case SB_LINELif(lParam==(LPARAM)hsc) iFreq--;if(lParam==(LPARAM)hsc2) var1--;if(lParam==(LPARAM)hsc3) var2--;if(lParam==(LPARAM)hsc4) var3--;if(lParam==(LPARAM)hsc5) var4--;if(lParam==(LPARAM)hsc6) var5--;if(lParam==(LPARAM)hsc7) var6--;if(lParam==(LPARAM)hsc8) var7--;if(lParam==(LPARAM)hsc9) var8--;if(lParam==(LPARAM)hsc10) var9--;if(lParam==(LPARAM)hsc11) var10--;if(lParam==(LPARAM)hsc12) var11--;if(lParam==(LPARAM)hsc13) var12--;if(lParam==(LPARAM)hsc14) var13--;if(lParam==(LPARAM)hsc15) var14--;if(lParam==(LPARAM)hsc16) var15--;if(lParam==(LPARAM)hsc17) var16--;if(lParam==(LPARAM)hsc18) var17--;if(lParam==(LPARAM)hsc19) var18--;if(lParam==(LPARAM)hsc20) var19--;if(lParam==(LPARAM)hsc21) var20--;
break;
case SB_LINERIGHT:if(lParam==(LPARAM)hsc) iFreq++;if(lParam==(LPARAM)hsc2) var1++;if(lParam==(LPARAM)hsc3) var2++;if(lParam==(LPARAM)hsc4) var3++;
66
if(lParam==(LPARAM)hsc5) var4++;if(lParam==(LPARAM)hsc6) var5++;if(lParam==(LPARAM)hsc7) var6++;if(lParam==(LPARAM)hsc8) var7++;if(lParam==(LPARAM)hsc9) var8++;if(lParam==(LPARAM)hsc10) var9++;if(lParam==(LPARAM)hsc11) var10++;if(lParam==(LPARAM)hsc12) var11++;if(lParam==(LPARAM)hsc13) var12++;if(lParam==(LPARAM)hsc14) var13++;if(lParam==(LPARAM)hsc15) var14++;if(lParam==(LPARAM)hsc16) var15++;if(lParam==(LPARAM)hsc17) var16++;if(lParam==(LPARAM)hsc18) var17++;if(lParam==(LPARAM)hsc19) var18++;if(lParam==(LPARAM)hsc20) var19++;if(lParam==(LPARAM)hsc21) var20++;
break;
case SB_THUMBTRACK:if (lParam==(LPARAM)hsc) iFreq=HIWORD(wParam);if (lParam==(LPARAM)hsc2) var1=HIWORD(wParam);if (lParam==(LPARAM)hsc3) var2=HIWORD(wParam);if (lParam==(LPARAM)hsc4) var3=HIWORD(wParam);if (lParam==(LPARAM)hsc5) var4=HIWORD(wParam);if (lParam==(LPARAM)hsc6) var5=HIWORD(wParam);if (lParam==(LPARAM)hsc7) var6=HIWORD(wParam);if (lParam==(LPARAM)hsc8) var7=HIWORD(wParam);if (lParam==(LPARAM)hsc9) var8=HIWORD(wParam);if (lParam==(LPARAM)hsc10) var9=HIWORD(wParam);if (lParam==(LPARAM)hsc11) var10=HIWORD(wParam);if (lParam==(LPARAM)hsc12) var11=HIWORD(wParam);if (lParam==(LPARAM)hsc13) var12=HIWORD(wParam);if (lParam==(LPARAM)hsc14) var13=HIWORD(wParam);if (lParam==(LPARAM)hsc15) var14=HIWORD(wParam);if (lParam==(LPARAM)hsc16) var15=HIWORD(wParam);if (lParam==(LPARAM)hsc17) var16=HIWORD(wParam);if (lParam==(LPARAM)hsc18) var17=HIWORD(wParam);if (lParam==(LPARAM)hsc19) var18=HIWORD(wParam);if (lParam==(LPARAM)hsc20) var19=HIWORD(wParam);if (lParam==(LPARAM)hsc21) var20=HIWORD(wParam);break;
case SB_BOTTOM:if (lParam==(LPARAM)hsc)GetScrollRange(hsc,SB_CTL,&iDummy,&iFreq);
if (lParam==(LPARAM)hsc2)GetScrollRange(hsc2,SB_CTL,&iDummy2,&var1);
if (lParam==(LPARAM)hsc3)GetScrollRange(hsc3,SB_CTL,&iDummy3,&var2);
if (lParam==(LPARAM)hsc4)
67
GetScrollRange(hsc4,SB_CTL,&iDummy4,&var3);
if (lParam==(LPARAM)hsc5)GetScrollRange(hsc5,SB_CTL,&iDummy5,&var4);
if (lParam==(LPARAM)hsc6)GetScrollRange(hsc6,SB_CTL,&iDummy6,&var5);
if (lParam==(LPARAM)hsc7)GetScrollRange(hsc7,SB_CTL,&iDummy7,&var6);
if (lParam==(LPARAM)hsc8)GetScrollRange(hsc8,SB_CTL,&iDummy8,&var7);
if (lParam==(LPARAM)hsc9)GetScrollRange(hsc9,SB_CTL,&iDummy9,&var8);
if (lParam==(LPARAM)hsc10)GetScrollRange(hsc10,SB_CTL,&iDummy10,&var9);
if (lParam==(LPARAM)hsc11)GetScrollRange(hsc11,SB_CTL,&iDummy11,&var10);
if (lParam==(LPARAM)hsc12)GetScrollRange(hsc12,SB_CTL,&iDummy12,&var11);
if (lParam==(LPARAM)hsc13)GetScrollRange(hsc13,SB_CTL,&iDummy13,&var12);
if (lParam==(LPARAM)hsc14)GetScrollRange(hsc14,SB_CTL,&iDummy14,&var13);
if (lParam==(LPARAM)hsc15)GetScrollRange(hsc15,SB_CTL,&iDummy15,&var14);
if (lParam==(LPARAM)hsc16)GetScrollRange(hsc16,SB_CTL,&iDummy16,&var15);
if (lParam==(LPARAM)hsc17)GetScrollRange(hsc17,SB_CTL,&iDummy17,&var16);
if (lParam==(LPARAM)hsc18)GetScrollRange(hsc18,SB_CTL,&iDummy18,&var17);
if (lParam==(LPARAM)hsc19)GetScrollRange(hsc19,SB_CTL,&iDummy19,&var18);
if (lParam==(LPARAM)hsc20)GetScrollRange(hsc20,SB_CTL,&iDummy20,&var19);
if (lParam==(LPARAM)hsc21)GetScrollRange(hsc21,SB_CTL,&iDummy21,&var20);
break ;
68
}SetScrollPos (hsc,SB_CTL,iFreq,TRUE);SetScrollPos (hsc2,SB_CTL,var1,TRUE);SetScrollPos (hsc3,SB_CTL,var2,TRUE);SetScrollPos (hsc4,SB_CTL,var3,TRUE);SetScrollPos (hsc5,SB_CTL,var4,TRUE);SetScrollPos (hsc6,SB_CTL,var5,TRUE);SetScrollPos (hsc7,SB_CTL,var6,TRUE);SetScrollPos (hsc8,SB_CTL,var7,TRUE);SetScrollPos (hsc9,SB_CTL,var8,TRUE);SetScrollPos (hsc10,SB_CTL,var9,TRUE);SetScrollPos (hsc11,SB_CTL,var10,TRUE);SetScrollPos (hsc12,SB_CTL,var11,TRUE);SetScrollPos (hsc13,SB_CTL,var12,TRUE);SetScrollPos (hsc14,SB_CTL,var13,TRUE);SetScrollPos (hsc15,SB_CTL,var14,TRUE);SetScrollPos (hsc16,SB_CTL,var15,TRUE);SetScrollPos (hsc17,SB_CTL,var16,TRUE);SetScrollPos (hsc18,SB_CTL,var17,TRUE);SetScrollPos (hsc19,SB_CTL,var18,TRUE);SetScrollPos (hsc20,SB_CTL,var19,TRUE);SetScrollPos (hsc21,SB_CTL,var20,TRUE);
SetDlgItemInt(hwnd,IDC_TEXT5,255-var1,TRUE);SetDlgItemInt(hwnd,IDC_TEXT6,255-var2,TRUE);SetDlgItemInt(hwnd,IDC_TEXT7,255-var3,TRUE);SetDlgItemInt(hwnd,IDC_TEXT8,255-var4,TRUE);SetDlgItemInt(hwnd,IDC_TEXT9,255-var5,TRUE);SetDlgItemInt(hwnd,IDC_TEXT10,255-var6,TRUE);SetDlgItemInt(hwnd,IDC_TEXT11,255-var7,TRUE);SetDlgItemInt(hwnd,IDC_TEXT12,255-var8,TRUE);SetDlgItemInt(hwnd,IDC_TEXT13,255-var9,TRUE);SetDlgItemInt(hwnd,IDC_TEXT14,255-var10,TRUE);SetDlgItemInt(hwnd,IDC_TEXT15,255-var11,TRUE);SetDlgItemInt(hwnd,IDC_TEXT16,255-var12,TRUE);SetDlgItemInt(hwnd,IDC_TEXT17,255-var13,TRUE);SetDlgItemInt(hwnd,IDC_TEXT18,255-var14,TRUE);SetDlgItemInt(hwnd,IDC_TEXT19,255-var15,TRUE);SetDlgItemInt(hwnd,IDC_TEXT20,255-var16,TRUE);SetDlgItemInt(hwnd,IDC_TEXT21,255-var17,TRUE);SetDlgItemInt(hwnd,IDC_TEXT22,255-var18,TRUE);SetDlgItemInt(hwnd,IDC_TEXT23,255-var19,TRUE);SetDlgItemInt(hwnd,IDC_TEXT24,255-var20,TRUE);SetDlgItemInt(hwnd,IDC_TEXT25,255-iFreq,TRUE);
graficar(hwnd);
case WM_COMMAND:switch (wParam)
{
case IDC_GENERAR:
69
OnGenerar(hwnd);break;
case IDC_PARAR:waveOutReset(hWaveOut);
waveOutClose(hWaveOut);break;
}break;
case MM_WOM_OPEN: // Generado por waveOutOpen().OnAbrir(hwnd);break;
case MM_WOM_DONE: // Generado por waveOutWrite()OnLoop(hwnd,lParam);
break;
case MM_WOM_CLOSE: // Generado por waveOutClose()OnCerrar(hwnd);
break;
case WM_SYSCOMMAND:switch(wParam)
{case SC_CLOSE:
if (hWaveOut!=NULL)waveOutReset(hWaveOut);
elseEndDialog(hwnd,0);
return(TRUE);}break;
}return(FALSE);
}
VOID OnCerrar(HWND hwnd){
SetDlgItemText(hwnd,IDC_TEXT2,TEXT("MM_WOM_CLOSE:"));
waveOutUnprepareHeader(hWaveOut,pWaveHdr1,sizeof(WAVEHDR));waveOutUnprepareHeader(hWaveOut,pWaveHdr2,sizeof(WAVEHDR));free(pWaveHdr1);free(pWaveHdr2);free(pBuffer1);free(pBuffer2);
hWaveOut=NULL;}
VOID OnAbrir(HWND hwnd){SetDlgItemText(hwnd,IDC_TEXT2,TEXT("MM_WOM_OPEN:"));
70
//Enviar 2 buffers al driver de sonido.//FillBuffer(pBuffer1,1000) ;copiarbuffer(salida3,pBuffer1);waveOutWrite(hWaveOut,pWaveHdr1,sizeof(WAVEHDR)) ;copiarbuffer(salida3,pBuffer2);//FillBuffer(pBuffer2, 1000);
waveOutWrite (hWaveOut,pWaveHdr2,sizeof(WAVEHDR)) ;}
VOID OnLoop(HWND hwnd,LPARAM lParam){
SetDlgItemText(hwnd,IDC_TEXT2,TEXT("MM_WOM_DONE:"));SetDlgItemInt(hwnd,IDC_TEXT3,wVeces++,FALSE) ; // print intSetDlgItemInt(hwnd,IDC_TEXT4,((PWAVEHDR)lParam)->lpData ,FALSE) ;// Fill and send out a new buffer// FillBuffer(((PWAVEHDR)lParam)->lpData,1000);copiarbuffer(salida3,((PWAVEHDR)lParam)->lpData);waveOutWrite(hWaveOut,(PWAVEHDR)lParam, sizeof(WAVEHDR));
}
BOOL OnGenerar(HWND hwnd){if(hWaveOut) return(TRUE); // Ya esta inicializado el driver ?
// Memoria para 2 headers y 2 bufferspWaveHdr1 = malloc(sizeof (WAVEHDR)) ;pWaveHdr2 = malloc(sizeof (WAVEHDR)) ;pBuffer1 = malloc(OUT_BUFFER_SIZE) ;pBuffer2 = malloc(OUT_BUFFER_SIZE) ;
if (!pWaveHdr1 || !pWaveHdr2 || !pBuffer1 || !pBuffer2){
if (!pWaveHdr1) free (pWaveHdr1);if (!pWaveHdr2) free (pWaveHdr2);if (!pBuffer1) free (pBuffer1);if (!pBuffer2) free (pBuffer2);error("No hay memoria.");
}// Abrir el driver de salida.waveformat.wFormatTag = WAVE_FORMAT_PCM ;waveformat.nChannels = 1 ;waveformat.nSamplesPerSec = SAMPLE_RATE ;waveformat.nAvgBytesPerSec = SAMPLE_RATE ;waveformat.nBlockAlign = 1 ;waveformat.wBitsPerSample = 8 ;waveformat.cbSize = 0 ;
if(waveOutOpen(&hWaveOut,WAVE_MAPPER, &waveformat,(DWORD)hwnd,0,CALLBACK_WINDOW) != MMSYSERR_NOERROR)
{free(pWaveHdr1);free(pWaveHdr2);free(pBuffer1);free(pBuffer2);hWaveOut = NULL;
71
error("No driver.");}// Preparar dos descriptores.pWaveHdr1->lpData = pBuffer1 ;pWaveHdr1->dwBufferLength = OUT_BUFFER_SIZE ;pWaveHdr1->dwBytesRecorded = 0 ;pWaveHdr1->dwUser = 0 ;pWaveHdr1->dwFlags = 0 ;pWaveHdr1->dwLoops = 1 ;pWaveHdr1->lpNext = NULL ;pWaveHdr1->reserved = 0 ;
waveOutPrepareHeader(hWaveOut,pWaveHdr1,sizeof(WAVEHDR));
pWaveHdr2->lpData = pBuffer2 ;pWaveHdr2->dwBufferLength = OUT_BUFFER_SIZE ;pWaveHdr2->dwBytesRecorded = 0 ;pWaveHdr2->dwUser = 0 ;pWaveHdr2->dwFlags = 0 ;pWaveHdr2->dwLoops = 1 ;pWaveHdr2->lpNext = NULL ;pWaveHdr2->reserved = 0 ;
waveOutPrepareHeader(hWaveOut,pWaveHdr2,sizeof(WAVEHDR));
return(TRUE);}
VOID FillBuffer(PBYTE pBuffer,int iFreq){
int i;static double fAngle ;
for (i=0;i<OUT_BUFFER_SIZE;i++){
pBuffer[i]= (BYTE) (127+127*sin(fAngle));fAngle += 2 * PI * iFreq/SAMPLE_RATE;if (fAngle > 2*PI)
fAngle -= 2*PI;}
}
BOOL error(LPCSTR mmsg){
MessageBeep(MB_ICONEXCLAMATION);MessageBox(hdlg,mmsg,szAppName,MB_ICONEXCLAMATION | MB_OK);return(TRUE);
}
VOID graficar(HWND hwnd)//Pag: 1213 Petzold.{
72
int nm=1024; // Numero de muestras.HDC hdc;InvalidateRect(hwnd,NULL,TRUE);UpdateWindow(hwnd);hdc=GetDC(hwnd);
//----------------------------------------------------
graficarentrada(hwnd,1024,entrada);fft(nm,entrada,salida);modificarfft(nm,salida,salidafft);graficartransformadafft(hwnd,1024,salidafft);ifft(nm,salidafft,salida3);graficartransformadaifft(hwnd,1024,salida3);
//-----------------------------------------------------
ReleaseDC(hwnd,hdc);}
VOID graficarentrada(HWND hwnd,int n,float bentrada[]){
int i;int x,y,yy;HDC hdc;
UpdateWindow(hwnd);hdc=GetDC(hwnd);
MoveToEx(hdc,0,y,NULL);
for(i=0;i<=1010;i++){
y=(bentrada[i]/255)*142;yy=y+240;LineTo(hdc,i,yy);
}
ReleaseDC(hwnd,hdc);
}
VOID graficartransformadafft(HWND hwnd,int n, float bfft[]){
int i;int yy,y;HDC hdc;UpdateWindow(hwnd);hdc=GetDC(hwnd);
for(i=0;i<=1010;i=i++){
MoveToEx(hdc,i,540,NULL);
73
y=-(bfft[i]/0x0FFFFFF)*142;yy=(y+540);LineTo(hdc,i,yy);}
ReleaseDC(hwnd,hdc);}
VOID graficartransformadaifft(HWND hwnd,int n, float bifft[]){
int i,x,y,yy;HDC hdc;UpdateWindow(hwnd);
hdc=GetDC(hwnd);MoveToEx(hdc,0,y,NULL);
for(i=0;i<=1010;i++){y=-(bifft[i]/0x0FFFFFFF)*142;yy=y+635;LineTo(hdc,i,yy);
}ReleaseDC(hwnd,hdc);}
VOID funcionseno(float pS[]){
int i;float fAngle ;
for (i=0;i<OUT_BUFFER_SIZE;i++){
pS[i]= (BYTE)((127+127 * sin(fAngle)));fAngle += 2 * PI * 1000 / SAMPLE_RATE;if (fAngle > 2*PI)
fAngle -= 2 * PI;
}}
VOID copiarbuffer(float entra[], float sale[]){
int i;
for (i=0;i<1024;i++){
sale[i]=entra[i];
74
}}
VOID ruidoblanco(float pB[]){
int i;for (i=0;i<1024;i++)
{pB[i]=(BYTE) rand()%255;
}}
VOID ondacuadrada(float pt[]){
int i;int k=0;int periodo=30;
for (i=0;i<OUT_BUFFER_SIZE;i++){
if (k==0)
pt[i]=0;else //__--__--__--__
pt[i]=127;
k=(k+1)%periodo;}
}
void fft(int N,float XR[],float X[]){
int i,j,k,M,N1,I1,I2, N2;int L=10;float C,S;float tempr,tempi;float WR[1024];float WI[1024];float XI[1024];
// Iniciarfor(i=0;i<=N-1;i++){
WR[i]=cos(2*pi*i/N);WI[i]=sin(2*pi*i/N);
XI[i]=0.0;
}// Calcular FFT.
N2=N;for(i=0;i<L;i++)
75
{N1=N2;N2=N2/2;I1=0;I2=N/N1;
for(j=0;j<N2;j++){C=WR[I1];S=WI[I1];I1=I1+I2;
for(k=j;k<N;k+=N1){
M=k+N2;
tempr=XR[k]-XR[M];XR[k]=XR[k]+XR[M];tempi=XI[k]-XI[M];XI[k]=XI[k]+XI[M];XR[M]=C*tempr-S*tempi;XI[M]=C*tempi+S*tempr;}}
}// Invertir el orden.
bitrev(N,XR,XI);// Calcular magnitud.
for(i=0;i<=N-1;i++){
X[i]=(sqrt(pow(XR[i],2)+pow(XI[i],2)));//X[i]=XR[i]+XI[i];
}
}
void modificarfft(int N,float T[],float R[]){
int i;for(i=0;i<=N-1;i++)
{
if (i >= 0 && i < 4 ) (R[i]=T[i]*(255-var1));if (i >= 4 && i < 8 ) (R[i]=T[i]*(255-var2));if (i >= 8 && i < 10 ) (R[i]=T[i]*(255-var3));if (i >= 10 && i < 20 ) (R[i]=T[i]*(255-var4));if (i >= 20 && i < 40 ) (R[i]=T[i]*(255-var5));if (i >= 40 && i < 80 ) (R[i]=T[i]*(255-var6));if (i >= 80 && i < 100) (R[i]=T[i]*(255-var7));if (i >= 100 && i < 200) (R[i]=T[i]*(255-var8));if (i >= 200 && i < 300) (R[i]=T[i]*(255-var9));
76
if (i >= 300 && i < 400) (R[i]=T[i]*(255-var10));if (i >= 400 && i < 500) (R[i]=T[i]*(255-var11));if (i >= 500 && i < 600) (R[i]=T[i]*(255-var12));if (i >= 600 && i < 700) (R[i]=T[i]*(255-var13));if (i >= 700 && i < 800) (R[i]=T[i]*(255-var14));if (i >= 800 && i < 850) (R[i]=T[i]*(255-var15));if (i >= 850 && i < 900) (R[i]=T[i]*(255-var16));if (i >= 900 && i < 950) (R[i]=T[i]*(255-var17));if (i >= 950 && i < 1000) (R[i]=T[i]*(255-var18));if (i >= 1000 && i < 1005) (R[i]=T[i]*(255-var19));if (i >= 1005 && i < 1015) (R[i]=T[i]*(255-var20));
}
}
void ifft(int N,float X2[],float X3[]){
int i,j,k,M,N1,I1,I2, N2;int L=10;float C2,S2;float tempr2,tempi2;float WR2[1024];float WI2[1024];float XI2[1024];float XR2[1024];
for(i=0;i<=N-1;i++){WR2[i]=cos(2*pi*i/N);WI2[i]=sin(2*pi*i/N);XR2[i]=X2[i];XI2[i]=0.0;
}
N2=N;for(i=0;i<L;i++){
N1=N2;N2=N2/2;I1=0;I2=N/N1;for(j=0;j<N2;j++){C2=WR2[I1];S2=WI2[I1];I1=I1+I2;for(k=j;k<N;k+=N1){
77
M=k+N2;
tempr2=XR2[k]-XR2[M];XR2[k]=XR2[k]+XR2[M];tempi2=XI2[k]-XI2[M];XI2[k]=XI2[k]+XI2[M];XR2[M]=C2*tempr2-S2*tempi2;XI2[M]=C2*tempi2+S2*tempr2;
}}
}
bitrev2(N,XR2,XI2);for(i=0;i<=N-1;i++){
X3[i]=(XR2[i]+XI2[i]);// Resultado de la FFT Inversa}
}
void bitrev(int N, float XR[1024], float XI[1024]){float temp;int i, j, k;j=0;for(i=0;i<N-1;i++){if(i<j){temp=XR[j];XR[j]=XR[i];XR[i]=temp;temp=XI[j];XI[j]=XI[i];XI[i]=temp;k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;}else{k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;
78
}}
}
void bitrev2(int N, float XR2[1024], float XI2[1024]){float temp2;int i, j, k;j=0;for(i=0;i<N-1;i++){if(i<j){temp2=XR2[j];XR2[j]=XR2[i];XR2[i]=temp2;temp2=XI2[j];XI2[j]=XI2[i];XI2[i]=temp2;k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;}else{k=N/2;while(k<=j){j=j-k;k=k/2;}j=j+k;}}}
79
Bibliografıa
[1] Gibilisco Stan, Diccionario Enciclopedico, Mc. Graw Hill, Vol. 1,2,3., 1995.
[2] Ceballos F. Javier, Visual C++, Aplicaciones para Win 32, 2a Edi-cion,Alfaomega, 2004. 717 pgs.
[3] Petzold Charles “Exploring Waveform Audio-Generating Sine Waves in Soft-ware”, PC Magazine, November 26, 1991, pp:505-510.
[4] Herrera Enrique, Comunicaciones 1, Senales, Modulacion y TransmisionLimusa, pp: 30-35, 2000.
[5] Bernal Jesus Reconocimiento de Voz y Fonetica Acustica, Alfaomega, pp: 169-171, 207, 1999.
[6] Hsu Hwei P, Analisis de Fourier, Prentice Hall,1998, 274 pgs.
[7] Boylestad Robert L, Electronica: Teorıa de Circuitos 6a Edicion, Prentice Hall,1997, 949 pgs .
[8] Petzold Charles, Programming Windows, 5a Edicion, Microsoft Press, 1999,1479pgs.
[9] Pena G. M “Captura de Multiples Eventos MIDI en tiempo de ejecucion”,Inedita. Mexico. Tesis presentada para aspirar al grado de Doctor en Ciencias deIngeniero en Comunicaciones y Electronica, Centro de Investigacion y Estudiosavanzados del IPN, 2005. 160 pgs.
[10] Moog Bob, “MIDI: Musical Instrument Digital Interface”, Journal of the AudioEngeering Society, may 1986, v. 34 No. 5. pp. 394-404.
[11] Sedgewick Robert, Algoritmos en C++, Addison-Wesley Iberoameri-cana,1995,726 pgs.
[12] Pappas Chris H., Visual C++ 6.00, Manual de Referencia Mc. Graw Hill,1999,945 pgs.
80
Φ
81