Está en la página 1de 221

UNIVERSIDAD NACIONAL DE EDUCACIN A DISTANCIA

ESCUELA TCNICA SUPERIOR DE INGENIERA INFORMTICA

Proyecto de Fin de Carrera de Ingeniero Informtico

Desarrollo de aplicaciones de audio en C++: un


enfoque prctico

Carlos Jimnez de Parga Bernal - Quirs


Dirigido por: D. Antonio Jimnez de Parga Bernal - Quirs
Supervisado por: D. Jos Luis Fernndez Marrn

Curso: 2010 - 2011 (21 de diciembre de 2010)

Desarrollo de aplicaciones de audio en C++: un enfoque prctico


Proyecto de Fin de Carrera de modalidad especfica

Realizado por: Carlos Jimnez de Parga Bernal - Quirs

Dirigido por: D. Antonio Jimnez de Parga Bernal - Quirs

Supervisado por: D. Jos Luis Fernndez Marrn

Tribunal calificador:
a

Presidente: D./D . .......................................................................................................................

Secretario: D./D . ........................................................................................................................

Vocal: D./D . ...............................................................................................................................

Fecha de lectura y defensa: ........................................................................................................


Calificacin................................................................................................................................

1. Resumen: Estudio sobre el panorama actual del desarrollo de aplicaciones de audio de alto
rendimiento en entornos multiplataforma escritos en lenguaje C++. Abordado desde la
perspectiva terica de los fundamentos fsicos del sonido, la tecnologa electrnica, los
sintetizadores musicales, software libre para el desarrollo de aplicaciones y enfoque terico y
prctico sobre los principios del tratamiento digital de seales.

2. Lista de palabras clave: Onda, Sonido, Fourier, Armnicos, Espectro, Instrumentos


musicales, Sintetizador, Teorema de Nyquist, Aliasing, Decibelios, Sntesis musical, DirectX,
DirectSound, COM, OpenAL, Buffer, MIDI, Sistema Exclusivo, Canal MIDI, Esquemtico MIDI,
DirectMusic, DirectMIDI, Formatos de sonido, Audiere, PCM, WAV, AIFF, MP3, XM, MOD,
Procesador Digital de Seal, FFT, Transormada Rpida de Fourier, Filtros, FIR, IIR,
Envolventes.

3. Traduccin del ttulo: Audio application development in C++: a practical approach

4. Traduccin del resumen: Study on currently available multi-platform libraries in C++ for
high-performance audio application development. Theoretical approach to the physics of sound,
audio synthesizer hardware, open-source software for audio applications and signal processing
principles.

5. Traduccin de las palabras clave: Waveform, Sound, Fourier, Armonics, Spectrum,


Musical instruments, Synthesizer, Nyquists theorem, Aliasing, Decibels, Music synthesis,
DirectX, DirectSound, OpenAL, Buffer, MIDI, Exclusive System, MIDI Channel, MIDI schematic,
DirectMusic, DirectMIDI, Sound formats, Audiere, PCM, WAV, AIFF, MP3, XM, MOD, Digital
Signal Processor, FFT, Fast Fourier Transform, Filters, FIR, IIR, Envelopes.

6. ndice

1. Resumen...........................................................................................................................

2. Lista de palabras clave.....................................................................................................

3. Traduccin del ttulo.........................................................................................................

4. Traduccin del resumen...................................................................................................

5. Traduccin de las palabras clave.....................................................................................

6. ndice................................................................................................................................

7. Listas de figuras...............................................................................................................

8. Cuerpo..............................................................................................................................

8.1 Captulo 1...................................................................................................................

8.1.1

Contexto........................................................................................................

8.1.2

Trabajos anteriores........................................................................................

8.1.3

Aportaciones y conclusiones.........................................................................

8.2 Captulo 2...................................................................................................................

10

8.2.1

Contexto........................................................................................................

10

8.2.2

Validacin mediante un prototipo..................................................................

11

8.2.3

Trabajos anteriores........................................................................................ 12

8.2.4

Aportaciones y conclusiones.........................................................................

12

8.3 Captulo 3...................................................................................................................

12

8.3.1

Contexto........................................................................................................

12

8.3.2

Validacin mediante un prototipo..................................................................

13

8.3.3

Trabajos anteriores........................................................................................ 13

8.3.4

Aportaciones y conclusiones.........................................................................

13

8.4 Captulo 4...................................................................................................................

14

8.4.1

Contexto......................................................................................................... 14

8.4.2

Trabajos anteriores........................................................................................ 15

8.4.3

Aportaciones y conclusiones.........................................................................

15

8.5 Captulo 5...................................................................................................................

16

8.5.1

Contexto......................................................................................................... 16

8.5.2

Desarrollo del subproyecto DirectMIDI..........................................................

17

8.5.3

Trabajos anteriores........................................................................................ 18

8.5.4

Aportaciones y conclusiones.........................................................................

18

8.6 Captulo 6...................................................................................................................

18

8.6.1

Contexto........................................................................................................

18

8.6.2

Validacin mediante un prototipo..................................................................

19

8.6.3

Aportaciones y conclusiones.........................................................................

20

8.7 Captulo 7...................................................................................................................

20

8.7.1

Contexto........................................................................................................

20

8.7.2

Validacin mediante un prototipo..................................................................

22

8.7.3

Trabajos anteriores........................................................................................ 22

8.7.4

Aportaciones y conclusiones.........................................................................

22

9. Listado de referencias y Bibliografa.................................................................................

23

10. Listado de siglas, abreviaturas y acrnimos.....................................................................

28

11. Anexos.............................................................................................................................

29

7. Listas de figuras
Figura 8.1 Umbrales de tolerancia al sonido......................................................................

Figura 8.2 Formas de onda bsicas...................................................................................

Figura 8.3 Envolvente de volumen.....................................................................................

Figura 8.4 Muestreo de seal.............................................................................................

Figura 8.5 Arquitectura bsica de DirectX..........................................................................

10

Figura 8.6 Ciclo de vida en cascada..................................................................................

11

Figura 8.7 Logotipo de MIDI...............................................................................................

14

Figura 8.8 Logotipo del proyecto DirectMIDI......................................................................

17

8. Cuerpo
8.1 Captulo 1

8.1.1 Contexto
En este captulo se abordan varios conceptos de la teora bsica del sonido. Se
comienza introduciendo al lector en los conceptos de generacin de la onda y
cmo sta es transmitida por el espacio. Para explicar estos conceptos se
exponen diversos ejemplos ilustrativos. Posteriormente, se aborda en el
captulo los tipos de onda que se dan en la naturaleza.
Otro aspecto que se aborda en este captulo son los conceptos de las
magnitudes de la onda: periodo, longitud de onda, frecuencia y amplitud,
aspectos stos fundamentales en la fsica de la onda. Tan importante como los
conceptos de magnitudes es la ecuacin matemtica que describe la onda, de
la cual se realiza un desarrollo terico.
A continuacin se explica uno de los conceptos fundamentales que sern de
gran utilidad para poder seguir el tratado y que son de importancia relevante en
el captulo 7 de Tratamiento Digital de Seales. Estos son la representacin de
la seal en el dominio del tiempo y en el dominio de la frecuencia. Dentro de
este apartado tambin se realiza una introduccin al concepto de espectro.
Se explica tambin en este captulo el Teorema de Fourier que demuestra que
cualquier funcin peridica continua, con un nmero finito de mximos y
mnimos, puede desarrollarse en una serie trigonomtrica uniformemente
convergente, llamada serie de Fourier.
Las conceptos de ondas armnicas y el ruido con sus respectivas
representaciones en el dominio y en la frecuencia son un tema tambin tratado
en este captulo.
Posteriormente se pasa a introducir la teora de la propagacin del sonido a
travs de diferentes medios fsicos y sus caractersticas. Se describen las
velocidades que alcanza el sonido en el agua, la madera y el acero.

En el tercer apartado del primer punto del captulo se menciona, sin llegar a lo
exhaustivo, el funcionamiento del odo humano, sus principales rganos
componentes y cmo se relacionan estos con el cerebro para producir la
sensacin acstica. Por tanto, se explican cada una de estas partes que son: el
odo externo, el odo medio y el odo interno. Como ejemplo ilustrativo se
expone un diagrama de bloques que relaciona cada parte del odo con un
sistema digital de audio.
Dentro de este apartado se definen a grandes rasgos las principales cualidades
del sonido que son: intensidad, tono, timbre y duracin.
Es conocido por todos el rango de frecuencias que abarca el espectro audible,
esto es, un rango que va desde los 20 a los 20000 Hz. Como ejemplo prctico
se representa mediante una tabla los diferentes rangos de frecuencia de las
diferentes octavas musicales.
Se incluye en este apartado un grfico con los umbrales de la tolerancia
humana de los sonidos en decibelios; como se muestra en la siguiente figura:

Figura 8.1 Umbrales de tolerancia al sonido


Por tanto, y para detallar ms este apartado se ha querido aadir una tabla con
los diferentes niveles de presin sonora.

Dentro de un nuevo apartado se explica los conceptos tericos de la


generacin del sonido analgico y digital. Para explicar la idea de generacin
de sonido analgico se ha hecho alusin a los tres tipos bsicos de
instrumentos: de percusin, de viento y de cuerda. Ya dentro de este mismo
apartado se explica la teora de la sntesis analgica de audio y la electrnica
que lo hace posible. Los componentes electrnicos fundamentales para la
generacin analgica son:
Oscilador: es un circuito electrnico capaz de generar una onda peridica a una
determinada frecuencia. Por ejemplo estos dos tipos de onda:

Figura 8.2 Formas de onda bsicas


Generador de envolvente: es un circuito que genera una seal que permite
controlar un parmetro dentro de un sistema de sntesis. La seal envolvente
se suele usar para modular la amplitud de la seal armnica, y de esta manera
simular las variaciones de amplitud de un instrumento de cuerda. Otros tipos de
envolvente se utilizan para modular el tono o pitch de la seal.

Figura 8.3 Envolvente de volumen


Amplificador de ganancia controlada: es un sistema que utilizan los
sintetizadores analgicos cuya ganancia puede ser controlada por una tensin
auxiliar.

Filtro: es un circuito selectivo en frecuencia que deja pasar unas mientras


atena otras. Este componente es fundamental para la sntesis analgica. Los
tipos bsicos son: paso-bajo, paso-alto, paso-banda y elimina-banda.
Tan importante como la sntesis analgica es la sntesis digital, por eso se hace
un repaso en este apartado a las tcnicas que comenzaron a desarrollarse a
finales del siglo XX para la generacin digital de sonido. En este captulo se
explican:
La sntesis aditiva: Consistente en generar un sonido peridico, ms complejo,
resultante de la suma de ondas sinusoidales ms elementales de frecuencia
mltiplo de una frecuencia base.
Modulacin de frecuencia o sntesis FM: Una de las formas de poder realizar
sntesis de sonido es por medio de la modulacin, que consiste en variar la
frecuencia de la seal portadora en funcin de la seal moduladora, generando
una seal modulada.
Sntesis por tabla de onda: Consiste en reproducir pequeos fragmentos de
sonidos digitalizados y almacenados en memoria escaldolos segn la nota
deseada.
En el ltimo apartado de este captulo se abordan los conceptos de
representacin del sonido. Dentro del mismo se explica en detalle el concepto
de Conversin analgico / digital, para lo cual es necesario entender el
Teorema de Nyquist, que indica que para muestrear una seal es necesario
hacerlo al menos al doble de la frecuencia mxima de la seal analgica de
entrada. En el siguiente grfico se muestra una seal analgica muestreada
para su representacin digital:

Figura 8.4 Muestreo de seal

Dentro de este apartado se explica, igualmente, el proceso de conversin de


una seal analgica en otra digital, de relevante importancia para el tratamiento
digital de seales. Junto con el concepto de muestreo, se explican tambin los
conceptos de cuantizacin y codificacin.
Antes de abordar el siguiente tema se hace un breve apunte sobre las formas
de representacin del sonido muestreado que son: PCM, PAM y PDM.
No se podra terminar este apartado sobre la conversin analgico-digital sin
explicar el concepto de aliasing, que es un efecto que puede ocurrir durante la
conversin y que se produce cuando la seal que se muestra tiene
componentes de frecuencia por encima de fs/2 o frecuencia de Nyquist.
Por ltimo, para concluir el captulo se explica el concepto de conversin
digital-analgica.

8.1.2 Trabajos anteriores


Algunos trabajos anteriores que versan sobre los temas previamente expuestos
son: John G. Proakis & Dimitris G. Manolakis Tratamiento Digital de Seales,
libros de Fsica de preuniversitario y Tcnicas de Grabacin modernas de la
editorial Omega.

8.1.3 Aportaciones y conclusiones


En este captulo se ha pretendido dar a conocer al lector las nociones bsicas
de teora del sonido, sin nimo de ser demasiado terico ni demasiado bsico;
tratando de abordar los conceptos complejos de una manera sencilla y
entendible para el lector y/o estudiante.

8.2 Captulo 2

8.2.1 Contexto
Este captulo se centra principalmente en la programacin en DirectX con
Visual C++ para la generacin de audio con DirectSound.
El captulo comienza con una introduccin a la filosofa de DirectX, desarrollada
principalmente para los juegos en plataformas Windows que siempre han
necesitado de altas prestaciones. Se explica conjuntamente la arquitectura de
DirectX que es esencialmente una arquitectura software por capas, como se
muestra en la figura 8.5:

DirectX

HAL

HEL

Hardware

Figura 8.5 Arquitectura bsica de DirectX


Posteriormente se describen los componentes del paquete SDK de DirectX,
para pasar finalmente a una breve introduccin a la filosofa COM (Component
Object Model Modelo de Objetos Componentes), que junto a DCOM
conforma uno de los pilares fundamentales de la arquitectura de componentes
de Windows.
Despus de la breve introduccin a COM se entra definitivamente, y ya en
profundidad, en la programacin en DirectSound. Se explica al lector los
fundamentos de la arquitectura DirectSound para posteriormente desarrollar los
distintos formatos de sonido soportados por la librera. Para explicar los
fundamentos de programacin en DirectSound se ha procedido a desglosar los
contenidos en las siguientes partes:

10

Creacin del objeto DirectSound

Establecimiento del nivel cooperativo

Creacin del buffer primario

Introduccin a los buffers secundarios

Pasos para crear los buffers secundarios

Archivos de sonido

Descripcin del buffer

Creacin del buffer secundario

Liberacin de las interfaces COM

Por ltimo, y debido al inters por el sonido en tres dimensiones se explica


cmo hacer que la aplicacin soporte buffers en 3D.

8.2.2 Validacin mediante un prototipo


Para aportar un ejemplo de aplicacin en DirectX / DirectSound, se ha
desarrollado una aplicacin en el entorno Visual C++ 2005, en modo consola,
llamada dsound.exe que se podr encontrar en el directorio de binarios del CDROM del proyecto. Para escribir esta aplicacin Win32 se ha utilizado un
esquema de ciclo de vida en cascada, puesto que los requisitos de los usuarios
estn bastante claros y la tecnologa es madura:

Figura 8.6 Ciclo de vida en cascada

11

8.2.3 Trabajos anteriores


Existen otros trabajos anteriores sobre la programacin de DirectSound,
especialmente en la Web, pero fundamentalmente el libro de referencia para la
programacin en DirectX / DirectSound es el publicado por la editorial de
Microsoft: a fondo DirectX.

8.2.4 Aportaciones y conclusiones


Se ha procurado explicar los conceptos complejos de la arquitectura COM sin
entrar en demasiado detalle, pues es un tema complicado para desarrolladores
que estn acostumbrados a ser clientes invocadores de tales objetos. Se ha
pretendido, sobre todo, dar una visin de la potencia y el alcance mundial que
DirectSound ha tenido durante su larga historia hasta el DirectX10. En las
versiones actuales de DirectX an se soportan las APIs de DirectSound con
las antiguas interfaces; no obstante se ha creado una nueva arquitectura para
sistemas de 64 bits y nuevas funciones de la API que han dejado un poco
desplazadas a las antiguas de DirectSound.

8.3 Captulo 3

8.3.1 Contexto
En este captulo se aborda la programacin en la librera OpenAL. Esta librera
es una versin multiplataforma de DirectSound de la compaa Creative Labs.
Para iniciar el captulo se introduce al lector en la arquitectura de OpenAL,
mucho ms sencilla y directa que la de su homlogo DirectX.
Una vez explicado el funcionamiento de la arquitectura, se comienza a exponer
al lector los fundamentos bsicos para la programacin en OpenAL. Para ello
se ha dividido el apartado en las siguientes secciones a fin de seguir una
metodologa ms pedaggica. Los apartados sobre la programacin OpenAL
son los siguientes:


Inicializacin

12

Trabajo con buffers

Reproduccin de sonido

Posicionamiento 3D

Salida de la aplicacin

Gestin de errores

Por ltimo se comentan las principales ventajas de OpenAL como librera


multiplataforma

de

alto

rendimiento

y muy utilizada

actualmente

en

videojuegos, junto con la ventaja adicional de que no es necesario la


instalacin de ningn plug-in para su ejecucin. Adems de esto, se comenta
tambin que su programacin y su diseo es mucho ms verstil que el de
DirectSound.

8.3.2 Validacin mediante un prototipo


Se ha desarrollado una aplicacin con Visual C++ 2010 sobre Win32 y
OpenAL, en modo consola, para demostrar las utilidades de esta API, as como
ilustrar al lector con un ejemplo compuesto de varias fases de cmo escribir
una aplicacin con los elementos bsicos de OpenAL.
La aplicacin de demostracin se puede encontrar en el CD-ROM del proyecto
en la carpeta de binarios, con el nombre openal.exe.
Por ltimo comentar que se ha utilizado un esquema de ciclo de vida en
cascada como el que se ilustra en la figura 8.6.

8.3.3 Trabajos anteriores


No hay constancia de otros trabajos en castellano sobre la librera de OpenAL.
Para el desarrollo del proyecto se han utilizado los manuales oficiales que
estn publicados en la pgina principal de Creative Labs.

8.3.4 Aportaciones y conclusiones


Se ha explicado al lector la programacin en OpenAL de una forma
metodolgica y pedaggica que sea fcilmente comprensible, de esta forma,

13

se han evitado construir aplicaciones complejas con interfaces grficas de


usuario para no desviar la atencin del lector hacia aspectos diferentes de la
API de audio.

8.4 Captulo 4

8.4.1 Contexto
En este captulo sobre tecnologa MIDI se exponen todos los aspectos tericos
sobre la interfaz para la interconexin de instrumentos musicales digitales.
En el principio del captulo se presenta al lector en una breve historia de MIDI,
as como el origen y la concepcin de este sistema innovador que sigue
perdurando en la actualidad.

Figura 8.7 Logotipo de MIDI


Posteriormente se explican algunos conceptos de la utilizacin de la tecnologa
y los entornos ms usuales donde suele aplicarse.
Como seccin de inters para lectores especializados en diseo electrnico se
explica con detalle todo el hardware en torno al sistema MIDI. Para ello se
ilustran detalles sobre los conectores, cables MIDI, pines, y esquemticos. Se
exponen de esta forma las ideas bsicas de los diferentes puertos MIDI: MIDI
in, MIDI out y MIDI thru.
Adems de la configuracin explicada anteriormente se comentan los
diferentes modos de interconexin de sistemas, por medio de USB, FireWire y
conexiones de red mLAN.
No poda faltar en un captulo sobre MIDI informacin sobre los diferentes
mensajes que componen la especificacin mantenida por la MMA. Por tanto se
comenta de manera detallada este significado de los campos de los diferentes

14

mensajes midi. Para ello se explican los fundamentos de los canales MIDI y los
mensajes de canal: note on, note off, poly aftertouch, channel aftertouch, etc.
Adems de los mensajes de canal se explican los mensajes de sistema
exclusivo, necesarios para controlar los dispositivos y que permiten el uso de
un lenguaje ajeno al protocolo musical, y que al ser propietario de cada sistema
se requiere saber su especificacin segn cada fabricante.
Para entender esta terminologa se explican en el captulo los fundamentos de
transmisin y recepcin SYX.
Al finalizar el captulo se explican los fundamentos del tiempo MIDI y su
sincronizacin.

8.4.2 Trabajos anteriores


Hay mucha bibliografa y referencias en la Web tanto en ingls como en
castellano, debido a la repercusin y popularidad del tema. Principalmente, se
ha recurrido a fuentes en Internet, especialmente a la Web de la MMA y una
pgina

Web

bastante

afamada

entre

los

desarrolladores

llamada

peculiarmente: MIDI Technical Fanatic's Brainwashing Center

8.4.3 Aportaciones y conclusiones


Se ha pretendido en este captulo introducir al lector en los fundamentos y la
terminologa MIDI. Se ha intentado ser breve en los conceptos menos
relevantes y ms exhaustivo en los conceptos orientados a la programacin de
sistemas en esta tecnologa. El enfoque principalmente terico de este captulo
ha servido como puente para introducir al lector en el siguiente captulo que
versar sobre programacin MIDI con la librera LGPL DirectMIDI.

15

8.5 Captulo 5

8.5.1 Contexto
Una vez explicados los conceptos bsicos sobre MIDI se introduce al lector en
los fundamentos de programacin de estos sistemas. Para entender los
entresijos tcnicos de la programacin en MIDI se ha centrado el captulo en la
librera de software libre DirectMIDI. Esta librera est basada en DirectX y
actualmente se encuentra disponible para sistemas Windows de 32 bits. Este
1

software utiliza una licencia GNU LGPL que, segn Richard Stallman , es un
mtodo para licenciar software de tal forma que su uso y modificacin
permanezcan siempre libres y queden en la comunidad, permitiendo su uso
libremente por otros desarrolladores sin coste alguno.
Para comenzar la explicacin sobre el uso de la librera se introduce
primeramente al lector en los fundamentos de las interfaces COM ms
importantes de DirectMusic que permitirn la implementacin de las
funcionalidades.
Despus se explica cmo obtener el software del repositorio de software libre
2

SourceForge .
Posteriormente se ilustra mediante grficos la arquitectura de objetos que
constituyen la librera y sus objetivos dentro del sistema de clases.
Para mostrar el uso de la librera en C++ se han seguido los siguientes pasos
en la metodologa:


Configuracin del entorno de desarrollo

Creacin de las primeras lneas de cdigo

Preparacin de la captura de msica

Inicializacin de objetos

Comienzo de la captura de msica

Aumento del lmite de instrumentos

es un programador estadounidense y figura relevante del movimiento por el software libre en


el mundo. Ver proyecto GNU.
2
http://www.sourceforge.net

16

DLS de alto nivel

DLS de bajo nivel

Terminacin la aplicacin

Por ltimo se explica cmo manejar excepciones para el tratamiento de errores


de la librera.

8.5.2 Desarrollo del subproyecto DirectMIDI


3

El proyecto DirectMIDI se comenz en septiembre de 2002 con la idea de


incluirlo en un futuro proyecto de fin de carrera universitario. Inicialmente se
orient a su publicacin en la revista electrnica para programadores en
4

plataformas Windows CodeProject en la que obtuvo una gran aceptacin y


valoracin. Posteriormente se licenci como software libre y se public en el
repositorio SourceForge.
El proyecto ha sido desarrollado en Visual C++ .NET 7.1 utilizando la API
Win32 y DirectX. Para su desarrollo se ha utilizado un esquema de ciclo de
vida en espiral, puesto que es un proyecto complejo, novedoso y los cambios
en los requisitos son frecuentes.
Se puede encontrar una copia de la librera en el directorio de fuentes del
captulo y un ejemplo de programacin en el directorio de binarios, llamado
Example_mid.exe. Para ejecutar este programa es necesario tener un
ordenador con un puerto de entrada MIDI.

Figura 8.8 Logotipo del proyecto DirectMIDI

3
4

Pgina Web del proyecto: http://directmidi.sourceforge.net


http://www.codeproject.com

17

8.5.3 Trabajos anteriores


Existe un libro sobre programacin MIDI en Windows que ha sido un referente
en toda la dcada llamado: Maximum MIDI music applications in C++.

8.5.4 Aportaciones y conclusiones


Las aportaciones de este captulo tienen una doble vertiente: por un lado se ha
intentado explicar lo ms cmodamente posible la programacin con la librera
de manera que sea amigable y entretenida para el programador de
aplicaciones musicales; por otro lado, se ha de tener en cuenta que el
desarrollo de la librera DirectMIDI, que transcurri entre los aos 2002 a 2004,
fue orientado a obtener una librera MIDI con resultados eficientes y que
pudiera ser utilizada en el campo profesional y de investigacin. Una de las
caractersticas que se resaltaron de la librera fue la baja latencia del timer MIDI
que usa DierectMusic y que permite aplicaciones con un mejor rendimiento.
Actualmente la librera se encuentra en estado beta y disponible desde DirectX
9. Se pretender publicar en breve una versin para plataformas de 64 bits.

8.6 Captulo 6

8.6.1 Contexto
En este captulo se aborda el tema fundamental para el programador de
aplicaciones de audio, que es el problema de aadir capacidades de
reproduccin y manipulacin de ficheros de audio conocidos.
Para comenzar, se introduce una seccin sobre el estado actual de las libreras
de reproduccin de audio. Posteriormente se presenta al lector la librera de
5

software libre Audiere , un potente software en varias plataformas que permite


la reproduccin de diversos formatos de audio: Ogg Vorbis, MP3, WAV, MOD,
XM.

http://audiere.sourceforge.net/

18

La librera, que est implementada y orientada a la programacin en C++,


accede al hardware de audio de varias plataformas con diferentes tecnologas:
DirectSound y WinMM en Windows y OSS en Linux.
Para iniciar al lector en la programacin en Audiere se comienza explicando los
fundamentos de la API, as como la jerarqua de clases que componen el
sistema. Por tanto para llegar a reproducir un fichero de audio son necesarios
los siguientes pasos que se explican en el captulo:

La clase AudioDevice

La clase OutputStream

Reproduccin y efectos

Por ltimo se explica cmo acceder al buffer PCM para obtener las muestras.
En este caso se ilustra un ejemplo que invierte un fichero de msica MP3.
Para finalizar el captulo se describen las caractersticas de los principales
formatos de audio. Los formatos que se explican en este captulo son:


WAV

AIFF

MPEG:MP3

General Midi MID

XM / MOD

8.6.2 Validacin mediante un prototipo


En este captulo se han desarrollado dos prototipos de prueba para ilustrar los
ejemplos explicados. El primero de ellos llamado audiere.exe demuestra las
capacidades de la librera usando las funciones play, setPan (para cambiar el
balance), SetPitchShift (para cambiar la frecuencia de reproduccin de las
muestras) y stop.
La segunda aplicacin desarrollada se llama invert.exe cuya finalidad es leer un
fichero de audio y reescribir las muestras al revs (en backward).

19

Para desarrollar estos proyectos se ha seguido un ciclo de vida en cascada


puesto que la tecnologa es madura y los requisitos son conocidos desde el
principio.

8.6.3 Aportaciones y conclusiones


La idea fundamental de este captulo es iniciar al programador de aplicaciones
de audio en el uso de libreras de cdigo fuente abierto y software libre para su
inclusin en sus programas. Con la librera que se expone en el captulo se
pretende facilitar en gran medida el desarrollo de aplicaciones para reproducir
archivos de audio que de lo contrario conllevaran un perodo de desarrollo muy
largo y un aumento del coste.
Otro aspecto que se ha intentado exponer son los diferentes formatos de audio
existentes en la actualidad y que estn ms extendidos en el mundo del
desarrollo de software de audio digital.

8.7 Captulo 7

8.7.1 Contexto
El captulo final del tratado se orienta a los fundamentos del Tratamiento Digital
de Seal. Este tema es transcendente por su amplia difusin en el entorno
acadmico y profesional y porque su repercusin en el desarrollo de
aplicaciones tanto de imagen como de audio ha sido muy importante en estos
ltimos aos.
El captulo comienza explicando los aspectos ms relevantes de la historia del
tratamiento digital de seales y sus mbitos de aplicacin. Posteriormente, se
comienza a introducir al lector en los algoritmos bsicos utilizados en el audio
que se clasifican en lineales y no lineales. A continuacin se pasa a explicar los
fundamentos de los dos tipos de filtros existentes: los filtros IIR y FIR, que son
los acrnimos de Infinite Impulse Response y Finite Impulse Response
respectivamente. Para explicar estos conceptos se detallan con grficos sus

20

principales estructuras y se presentan sus ecuaciones. Dentro del apartado de


algoritmos se explica tambin en qu consiste la tcnica de envolvente de
volumen, as como el retardo y los efectos basados en el mismo: coros, eco,
reverberacin, phaser y flanger.
Posteriormente, y dentro del apartado de algoritmos, se explican los
fundamentos de la tcnica de Compresin del rango dinmico.
Una de las herramientas ms utilizadas actualmente en los proyectos de audio
es la Transformada Rpida de Fourier o FFT, la cual se explica detalladamente
a lo largo del captulo.
Para finalizar, se introduce al lector en la programacin C++ de aplicaciones de
TDS utilizando la librera gratuita para fines educacionales Mitov. En concreto
se explica detalladamente al lector cmo se desarrolla una aplicacin en Visual
C++ con esta librera desde cero.
Para conseguir este propsito se utilizar la librera GUI MFC (Microsoft
Foundation Classes), que tiene la ventaja de ser una API primitiva y no
necesitar ninguna versin de sistema operativo Windows avanzado, ni tan
siquiera la instalacin de .NET.
En primer lugar se explica al lector cmo utilizar las libreras SignalLab y
AudioLab para generar una forma de onda bsica por pantalla y poder
reproducir un fichero WAV.
Despus de explicar estos conceptos se presenta un ejemplo de aplicacin
real de uso de la librera para el anlisis de seales de audio. Para conseguir
este propsito se explica al lector el diagrama de bloques que usar la
aplicacin, as como el cdigo fuente necesario para instanciar los objetos
Mitov que requiere la aplicacin.
El ejemplo que se propone es una aplicacin C++ para el anlisis de una forma
de onda en formato WAV, aplicacin de filtros paso banda, paso bajo y paso
alto y ecualizacin de 10 bandas. Por ltimo la salida de la seal se visualizar
en tres tipos de presentacin diferentes: espectrograma (waterfall), dominio del
tiempo y dominio de la frecuencia (FFT).

21

8.7.2 Validacin mediante un prototipo


Como se ha mencionado en el apartado anterior, se ha desarrollado una
aplicacin en Visual C++ que refleja la tendencia actual del uso de las tcnicas
fundamentales del Tratamiento Digital de Seal.
Para desarrollar la aplicacin propuesta se ha servido de la librera gratuita
para fines no comerciales Mitov.
Para la ingeniera del proyecto se ha utilizado un ciclo de vida en cascada
(figura 8.6), puesto que los requisitos fueron indicados por el Director y eran
claros desde el principio.
La aplicacin se puede encontrar en el CD-ROM del proyecto dentro del
directorio de binarios con el nombre tds.exe.

8.7.3 Trabajos anteriores


Se han escrito muchos tratados sobre el Tratamiento Digital de Seal, aunque
la mayor parte de la bibliografa se encuentra en lengua inglesa. En la Web hay
multitud de referencias sobre este tema tanto desde el punto de vista
comercial, acadmico como de aficionado. No obstante, el principal libro de
referencia anteriormente escrito y utilizado por la mayora de la Universidades
es el de John G. Proakis & Dimitris G. Manolakis Tratamiento Digital de
Seales.

8.7.4 Aportaciones y conclusiones


La idea de este captulo es introducir al lector en los conceptos de Tratamiento
de Seales, con el nimo de hacer una lectura amena de un tema
eminentemente complejo. Aunque este captulo es de dificultosa lectura se ha
intentado centrase en el aspecto ms pragmtico del mismo, huyendo de un
riguroso formalismo matemtico y centrndose en los aspectos que conciernen
a las aplicaciones informticas de sonido en la actualidad.

22

9. Listado de referencias y Bibliografa

9.1 Captulo 1

Libros

1. [Alonso et al] Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y


Vdeo, Ra-ma, 2002.

2. [Candel et al] Fsica COU, Anaya, 1990.

3. [Cuenca et al] Tecnologa Bsica del Sonido I, Paraninfo, 2006.

4. [Miles et al] Tcnicas de Grabacin modernas, Omega, 2007.

5. [Snchez] Apuntes Redes 3 IT Informtica de Sistemas, 1997.

La Web

6. http://www.mrfizzix.com/instruments/

7. http://www.ehu.es/acustica/espanol/fisiologia1/siaues/siaues.html

8. [Herrera] http://sam.atlantes.org/

9. [Wikipedia] http://es.wikipedia.org/wiki/Cualidades_del_sonido

10. [Wikipedia] http://es.wikipedia.org/wiki/O%C3%ADdo

11. [Wikipedia] http://es.wikipedia.org/wiki/Octava

23

12. [Wikipedia] http://en.wikipedia.org/wiki/Frequency_modulation_synthesis

13. [Wikipedia]
http://es.wikipedia.org/wiki/S%C3%ADntesis_mediante_tabla_de_ondas

9.2 Captulo 2

Libros

14. [Bradley et al] A fondo DirectX, Microsoft Press, 1998.

15. [Colouris et al] Sistemas Distribuidos: conceptos y diseo, Pearson, 2001.

16. [Gordon] Programacin COM y COM+ , Anaya Multimedia, 2000.

La Web

17. [Gimeno]
http://usuarios.multimania.es/andromeda_studios/paginas/tutoriales/articulo02.
htm

18. [MSDN] http://msdn2.microsoft.com/es-es/default.aspx

9.3 Captulo 3

Manuales

19. [Creative Labs] OpenAL Programmer's Guide - OpenAL Versions 1.0 and 1.1

24

La Web

20. [Wikipedia] http://en.wikipedia.org/wiki/OpenAL

9.4 Captulo 4

Libros

21. [Alonso et al] Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y


Vdeo, Ra-ma, 2002.

22. [Miles et al] Tcnicas de Grabacin modernas, Omega, 2007.

La Web

23. [MIDI Manufacturers Association] http://www.midi.org/

24. http://home.roadrunner.com/~jgglatt/

25. [Wikipedia] http://es.wikipedia.org/wiki/MIDI

9.5 Captulo 5

La Web

26. [Jimnez de Parga] http://directmidi.sourceforge.net/

27. [MSDN] http://msdn2.microsoft.com/es-es/default.aspx

25

9.6 Captulo 6

Libros

28. [Alonso et al] Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y


Vdeo, Ra-ma, 2002.

La Web

29. [Arribas]
http://www.lpi.tel.uva.es/~nacho/docencia/ing_ond_1/trabajos_01_02/formatos_audi
o_digital/html/midiformat.htm

30. [Austin et al] http://audiere.sourceforge.net/documentation.php

31. [MSDN] http://msdn2.microsoft.com/es-es/default.aspx

32. [Wikipedia] http://es.wikipedia.org/wiki/Waveform_Audio_Format

33. [Wikipedia] http://es.wikipedia.org/wiki/AIFF

34. [Wikipedia] http://es.wikipedia.org/wiki/MP3

35. [Wikipedia] http://es.wikipedia.org/wiki/General_MIDI

36. [Wikipedia] http://en.wikipedia.org/wiki/MOD_(file_format)

37. [Wikipedia] http://en.wikipedia.org/wiki/XM_(file_format)

26

9.7 Captulo 7

Libros

38. [Schildt] Programacin con MFC 6.0, Osborne McGraw-Hill, 1999.

La Web

39. [MSDN] http://msdn2.microsoft.com/es-es/default.aspx

40. [Mitov documentation] http://www.mitov.com

41. [Wikipedia] http://en.wikipedia.org/wiki/Digital_audio_editor

42. [Wikipedia] http://en.wikipedia.org/wiki/Sound_effect

43. [Wikipedia] http://paws.kettering.edu/~drussell/demos.html

44. [Wikipedia] http://en.wikipedia.org/wiki/CooleyTukey_FFT_algorithm

45. [Wikipedia] http://en.wikipedia.org/wiki/Butterfly_diagram

27

10. Listado de siglas, abreviaturas y acrnimos

Hz: Hertzios

VCA: Voltaje Controlled Amplifier (Amplificador controlador por tensin)

FM: Frequency Modulation (Modulacin de frecuencia)

FFT: Fast Fourier Transform

IIR: Infinite Impulse Response (Respuesta infinita al impulso)

FIR: Finite Impulse Response (Respuesta finita al impulso)

PCM: Pulse Code Modulation (Modulacin por pulsos codificados)

PAM: Pulse Amplitude Modulation (Modulacin por amplitud de pulsos)

PDM: Pulse Density Modulation (Modulacin de seal por densidad de


impulsos)

SDK: Software Development Kit

COM: Component Object Model (Modelo de objetos componentes)

DCOM: Modelo de objetos componentes distribuidos

CD-ROM: Compact Disk Read-Only Memory

API: Application Programming Interface (Interfaz de programacin de


aplicaciones)

MIDI: Musical Instrument Digital Interface (Interfaz digital de instrumentos


musicales)

mLAN: Music Local Area Network

LGPL: Lesser General Public License

GNU: GNU no es Unix

DLS: Downloadable Sounds

MP3: Mpeg I audio layer III

WAV: Waveform audio file format

OSS: Open Sound System

AIFF: Audio Interchange File Format

MID: General MIDI format

MOD: Amiga music Module file

28

XM: Extended Module

GUI: Graphical User Interface

11. Anexos
A continuacin se adjunta el tratado terico correspondiente al proyecto de fin de carrera.

Esta obra est bajo una licencia Reconocimiento 3.0 Espaa de Creative Commons.
Para ver una copia de esta licencia, visite http://creativecommons.org/licenses/by-sa/3.0/es/
o envie una carta a Creative Commons, 171 Second Street, Suite 300, San Francisco,
California 94105, USA.

29

Desarrollo de
Aplicaciones de
Audio en C++
Un enfoque prctico
Carlos Jimnez de Parga Bernal - Quirs

A mis padres Antonio y Carolina, por comprenderme y


acompaarme estos 12 aos que he dedicado al estudio de esta
ciencia con tan gran potencial creativo como es la Informtica.

En recuerdo de las personas que nos dejaron en el camino,


especialmente a mi to Pepe y mi abuelo Juan, el cual me ense
a apreciar la msica.

Prefacio
Es evidente el auge en capacidad de cmputo de los sistemas con
microprocesador en la actualidad. En un breve perodo de tiempo, hemos
pasado de procesadores de 8 bits con una capacidad computacional baja, a
procesadores de 64 bits con un alta frecuencia de reloj y gran capacidad de
clculo. As mismo, y paralelamente a este desarrollo en microprocesadores
para ordenadores personales, ha surgido una industria de fabricacin de
dispositivos externos que permiten realizar tareas de E/S impensables hace
veinte aos, en especial, los dispositivos de procesamiento de sonido como son:
tarjetas de audio, DSPs (procesadores digitales de seal) y mdulos hardware
de sntesis de sonido, basados en los ltimos avances de la electrnica de fsica
acstica, software y multiprocesadores.
El sonido digital se ha convertido en objeto de estudio y forma parte de
nuestra cultura de hoy en da. Como ejemplos caben destacar: la msica, donde
ya no es difcil escuchar temas o composiciones donde se inserte un sonido
digital, los videojuegos, donde las ltimas tecnologas se abren paso para
producir efectos ms realistas que introducen al jugador en una atmsfera de
gran verosimilitud, el cine, con efectos acsticos en tres dimensiones que
realzan las escenas, y un amplio rango de investigaciones que van desde la
compresin de audio y reconocimiento de voz, hasta la Inteligencia Artificial.
En lo que respecta a la programacin de sonido profesional en
computadores personales, especialmente en Windows, Linux y Mac OS, se han
desarrollado componentes software accesibles a travs del API del sistema
operativo, que permiten acceder a funciones de bajo nivel de manejo de puertos
MIDI y realizar E/S de formas de onda PCM a travs de los canales de audio de
las tarjetas; abstrayendo la complejidad de la programacin del hardware.
Estas APIs son esenciales para comprender el modelo de programacin de
aplicaciones de audio profesionales, donde la latencia debe ser lo ms baja
posible y poder conseguir as las mximas garantas de rendimiento y
fiabilidad.
Tan importante como conocer el software de abstraccin de las
funcionalidades bsicas de una tarjeta, es la teora elemental del sonido, como
son: su comportamiento fsico, sus parmetros, conversin A/D y D/A, la
percepcin humana de las vibraciones acsticas en el espacio y los teoremas
fundamentales de fsica.
Es lgico que en un mundo donde la seal de sonido es computable y
analizable, sea posible realizar un tratamiento digital de seal para poder
manipularla, filtrarla, mezclarla y conseguir efectos en tiempo real sobre las
muestras capturadas por algn dispositivo externo. Esto, por lo tanto, es un
tema trascendental a nivel actual y profesional.

iii

ndice

Dedicatoria....................................................................................................................
Prefacio.........................................................................................................................
ndice............................................................................................................................

i
iii
v

PARTE I: Conceptos preliminares...........................................................................


1. Teora del sonido..........................................................................................
1.1 Fsica de la onda...................................................................................
1.1.1 El concepto de onda..................................................................
1.1.2 Magnitudes de la onda..............................................................
1.1.3 Ecuacin matemtica de la onda...............................................
1.2 El sonido como forma de onda.............................................................
1.2.1 Dominio del tiempo y frecuencia..............................................
1.2.2 Teorema de Fourier...................................................................
1.2.3 Ondas armnicas y ruido...........................................................
1.2.4 Propagacin del sonido.............................................................
1.3 Percepcin humana del sonido.............................................................
1.3.1 Funcionamiento del odo...........................................................
1.3.2 Cualidades del sonido...............................................................
1.3.3 Espectro audible e intensidad sonora (Decibelios)...................
1.4 Generacin de sonido analgico y digital.............................................
1.4.1 Instrumentos musicales convencionales...................................
1.4.2 Sntesis analgica......................................................................
1.4.3 Tcnicas de sntesis digital........................................................
1.5 Representacin del sonido....................................................................
1.5.1 Conversin Analgico / Digital...................................................
1.5.1.1 Teorema de Nyquist...................................................
1.5.1.2 Proceso de conversin................................................
1.5.1.3 El problema del aliasing.............................................
1.5.2 Conversin Digital / Analgico...................................................
Bibliografa y referencias...........................................................................

1
3
3
3
4
6
8
8
10
12
13
15
15
17
18
20
20
23
29
34
34
34
34
37
38
40

PARTE II: Programacin..........................................................................................


2. DirectX y la API DirectSound......................................................................
2.1 Qu es DirectX?..................................................................................
2.1.1 Introduccin..............................................................................
2.1.2 Filosofa de DirectX..................................................................
2.1.3 Arquitectura de DirectX............................................................
2.1.4 Componentes de DirectX..........................................................
2.1.5 Programacin en DirectX..........................................................
2.1.6 Tecnologa COM.......................................................................
2.2 Programacin en DirectSound..............................................................
2.2.1 Introduccin..............................................................................
2.2.2 Arquitectura de DirectSound.....................................................
2.2.3 Formato de sonido soportado por DirectSound........................
2.2.4 Creacin del objeto DirectSound..............................................

43
45
45
45
46
46
47
47
48
52
52
52
53
54

2.2.5 Establecer el nivel cooperativo.................................................


2.2.6 Crear el buffer primario............................................................
2.2.7 Introduccin a los buffers secundarios......................................
2.2.8 Pasos para crear los buffers secundarios..................................
2.2.9 Archivos de sonido...................................................................
2.2.10 Describir el buffer....................................................................
2.2.11 Creacin del buffer secundario................................................
2.2.12 Sonido en tres dimensiones......................................................
2.2.13 Bloqueo del buffer....................................................................
2.2.14 Reproducir y posicionar el buffer en 3D..................................
2.2.15 Liberar las interfaces................................................................
Bibliografa y referencias.................................................................................

55
56
57
57
58
58
59
60
61
63
64
65

3. OpenAL...........................................................................................................
3.1 Introduccin a OpenAL........................................................................
3.2 Arquitectura de OpenAL......................................................................
3.3 Programacin con OpenAL..................................................................
3.3.1 Inicializacin.............................................................................
3.3.2 Trabajar con buffers..................................................................
3.3.3 Reproducir sonido.....................................................................
3.3.4 Posicionamiento 3D..................................................................
3.3.5 Salida de la aplicacin...............................................................
3.3.6 Gestin de errores.....................................................................
3.4 Ventajas de OpenAL............................................................................
Bibliografa y referencias.................................................................................

67
67
67
69
69
71
73
74
76
77
77
78

PARTE III: MIDI.......................................................................................................


4. Introduccin al MIDI..................................................................................
4.1 Qu es MIDI?......................................................................................
4.1.1 Un poco de historia...................................................................
4.1.2 Conceptos bsicos.....................................................................
4.1.3 Electrnica MIDI......................................................................
4.1.3.1 Interconexin de sistemas...........................................
4.1.3.2 Esquemticos...............................................................
4.2 Especificacin MIDI.............................................................................
4.2.1 Introduccin..............................................................................
4.2.2 Canales MIDI............................................................................
4.3 Mensajes MIDI.....................................................................................
4.3.1 Mensajes de canal.....................................................................
4.3.2 Mensajes de sistema..................................................................
4.3.3 Mensajes de sistema exclusivo..................................................
4.3.4 Mensajes de modo....................................................................
4.3.5 Mensajes de tiempo real...........................................................
4.4 Sincronizacin y tiempo MIDI.............................................................
Bibliografa y referencias...........................................................................

79
81
81
81
82
84
84
87
88
88
88
90
90
93
94
95
96
98
99

5. Programacin MIDI....................................................................................
5.1 Introduccin..........................................................................................
5.2 La API DirectMusic de DirectX...........................................................
5.2.1 Caractersticas principales........................................................

101
101
102
102

vi

5.2.2 Principales interfaces COM......................................................


5.3 Desarrollando aplicaciones con la librera DirectMIDI........................
5.3.1 Introduccin..............................................................................
5.3.2 Esquema de la arquitectura DirectMIDI...................................
5.3.3 Comenzando la aplicacin........................................................
5.3.3.1 Primer paso: configurar el entorno de desarrollo........
5.3.3.2 Segundo paso: las primeras lneas de cdigo..............
5.3.3.3 Tercer paso: preparando la captura de msica............
5.3.3.4 Cuarto paso: inicializando objetos..............................
5.3.3.5 Quinto paso: comenzar la captura de msica..............
5.3.3.6 Sexto paso: aumentando el lmite de instrumentos.....
5.3.3.7 Sptimo paso: terminar la aplicacin..........................
5.3.4 Manejo de excepciones.............................................................
Bibliografa y referencias...........................................................................

103
104
104
106
107
107
107
108
109
111
112
118
119
120

PARTE IV: Reproduccin de formatos de sonido..................................................


6. Reproduccin de formatos de sonido..........................................................
6.1 Introduccin..........................................................................................
6.2 La librera Audiere................................................................................
6.2.1 Introduccin..............................................................................
6.2.2 Clase AudioDevice...................................................................
6.2.3 Clase OutputStream..................................................................
6.2.4 Reproduccin y efectos.............................................................
6.2.5 Acceso a los datos PCM de un buffer.......................................
6.3 Formatos de sonido conocidos..............................................................
6.3.1 Formato WAV..........................................................................
6.3.2 Formato AIFF...........................................................................
6.3.3 Formatos MPEG: MP3.............................................................
6.3.4 Formato General MIDI.............................................................
6.3.5 Formato MOD / XM.................................................................
Bibliografa y referencias..........................................................................

121
123
123
124
124
126
127
128
129
133
133
133
134
136
141
143

PARTE V: Tratamiento Digital de Seal.................................................................


7. Tratamiento Digital de Seal......................................................................
7.1 Procesado digital de seal aplicado al audio........................................
7.2 Algoritmos bsicos para audio..............................................................
7.2.1 Filtros........................................................................................
7.2.2 Envolvente de volumen............................................................
7.2.3 Retardo......................................................................................
7.2.4 Compresin...............................................................................
7.3 Transformada rpida de Fourier (FFT).................................................
7.4 Libreras C++........................................................................................
7.4.1 Modelos de libreras..................................................................
7.4.2 Mitov.........................................................................................
7.4.3 Principales libreras de Mitov...................................................
7.4.4 Conceptos bsicos de las libreras SignalLab y AudioLab.......
7.5 Desarrollo de una aplicacin de procesado de seal.............................
7.5.1 Diagrama de bloques................................................................
7.5.2 Declaracin de objetos de librera............................................
7.5.3 Inicializacin e interconexin de objetos..................................

145
147
147
148
148
150
150
152
153
158
158
158
158
159
163
163
164
165

vii

7.5.4 Comportamiento de los filtros y el ecualizador........................ 167


7.5.5 Aspecto final de la aplicacin................................................... 170
Bibliografa y referencias............................................................................................. 171

APNDICE.................................................................................................................
A1. Mensajes de la especificacin MIDI 1.0.................................................
A2. Lista de mensajes de controladores MIDI 1.0.......................................
A3. Lista de instrumentos GM1 (General MIDI 1.0)..................................
A4. Tabla de frecuencias de notas musicales en Hertzios...........................

viii

173
173
176
179
181

Parte I

Conceptos preliminares

C A P T U L O 1 Teora del sonido

Teora del sonido

1.1 Fsica de la onda


En nuestro entorno fsico habitual estamos expuestos a perturbaciones ondulatorias
transmitidas por distintos medios: lquidos, slidos, gases o incluso el vaco. La
naturaleza de la perturbacin es diferente segn el medio, y tambin la manera de
percibirla.
Un ejemplo cotidiano es el de la luz que nos viene del sol a travs del espacio en
forma de radiacin electromagntica.
En la figura 1.1 se muestra otro ejemplo de propagacin de una onda cuando
sacudimos el extremo de una cuerda, la perturbacin producida viaja por ella alcanzado
todos sus puntos.

Figura 1.1 Ejemplo de onda mecnica


1.1.1 El concepto de onda
En los ejemplos anteriores se puede apreciar una caracterstica comn: una
perturbacin generada en un punto de inicio que se propaga en el espacio hasta alcanzar
otro punto.
En estas situaciones anteriores ha sido necesario aportar energa, por lo tanto al generar
la perturbacin se transmite energa.

C A P T U L O 1 Teora del sonido


As pues, podemos definir una onda como el fenmeno de transmisin de una
perturbacin de alguna propiedad de un medio en el espacio transportando energa. El
medio en el que se transmite puede ser de diferente naturaleza: aire, agua o un trozo de
metal, por ejemplo. Es de tener en cuenta que este transporte de energa por el medio
nunca va acompaado de transporte de materia.
Dentro de los tipos de onda y dependiendo del tipo de clasificacin que apliquemos
podemos considerar los siguientes:

Ondas materiales: en este tipo de ondas la perturbacin se produce en un medio


elstico (aire, agua, metal) y se transmiten gracias a la elasticidad del medio, es
por ello que la velocidad de propagacin dependa de sus caractersticas elsticas.
En esta clasificacin cabe destacar los ejemplos anteriormente citados de la onda
producida al tirar una piedra al agua y la cuerda.

Ondas electromagnticas: Son un caso especial de ondas, en las que no es


necesario un medio material, sino que pueden transmitirse por el vaco. Las
ondas electromagnticas estn producidas por las oscilaciones de un campo
elctrico en relacin con un campo magntico asociado. Dentro de este
arquetipo podemos encuadrar los ejemplos de las ondas de radio, las de TV, o
las de un router Wi-Fi.

Figura 1.2 Otro ejemplo de onda, al tirar un objeto al agua


1.1.2 Magnitudes de la onda
Una vez vistos los ejemplos de ondas ms caractersticos de nuestro entorno
cotidiano y explicado su concepto, es hora de definir las magnitudes que caracterizan
los tipos de ondas vistos previamente. Las magnitudes principales que describen una
onda son las siguientes:

Periodo: Es el tiempo que transcurre entre dos pulsos sucesivos de la onda, se


representa con la letra T y se mide en segundos.

Longitud de onda: Se define como la distancia entre dos pulsos sucesivos en un


medio determinado. La longitud de onda depende de la velocidad de

C A P T U L O 1 Teora del sonido


propagacin de la perturbacin en el medio. Se escribe con la letra griega
(lambda) y se representa en metros.

Frecuencia: Esta magnitud es fundamental en el estudio de las ondas y tambin


est relacionada con el periodo, puesto que se define como la inversa del mismo.
Para hacernos una idea que resulte fcil, podemos entenderla como el nmero de
oscilaciones que se producen en un segundo. Su medida es el Hertzio (Hz o s-1),
en honor al fsico alemn Heinrich Rudolf Hertz, aunque tambin se emplean
mltiplos como el Kilohertzio (KHz) y el Megahertzio(MHz). Se expresa con la
frmula:

f =

1
T

Amplitud: Se considera como la distancia mxima que separa un punto de la


posicin de equilibrio. (La distancia superior o inferior a la lnea central de la
forma de onda de la figura 1.3). Cuanto ms grande sea la distancia o
desplazamiento de esa lnea central, ms intenso ser el nivel de la seal
elctrica, la variacin de presin o el desplazamiento fsico dentro del medio.

Amplitud

Amplitud (A)

Amplitud (A)

Tiempo

Periodo (T)

Figura 1.3 Parmetros de una onda senoidal

C A P T U L O 1 Teora del sonido


1.1.3 Ecuacin matemtica de la onda
El movimiento ondulatorio supone la transmisin de una perturbacin de un
punto a otro sin transporte neto de materia. Por lo tanto, y como el objetivo es conocer
dicho movimiento (slo queda satisfecho cuando en cada momento se pueda conocer la
perturbacin que afecta a cada punto del medio por el que se propaga), cmo
podramos establecer una ecuacin matemtica que defina el valor de dicha
perturbacin en funcin del tiempo?
Tomando como ejemplo el caso de la cuerda y suponiendo que la propagacin
de la onda armnica es a una determinada velocidad (v) y que se mueve en direccin
positiva del eje X como se muestra en la figura 1.4:
y

Figura 1.4 Pulso inicial


Transcurrido un tiempo t, el pulso habr recorrido una distancia:
d=vt
Quedando en la siguiente posicin:
y
d

Figura 1.5 Desplazamiento del pulso

Por lo tanto, si la funcin:

C A P T U L O 1 Teora del sonido


y = f(x)
representa el pulso inicial, la funcin
y = f(x d)
representar el pulso d, ya que la forma de la curva no vara. Se puede observar que para
valores de x incrementados cierto valor d se obtiene el mismo resultado en la funcin.
Sustituyendo d por su valor, resulta la funcin:
y = f(x- vt)
que corresponde a una onda que se propaga con velocidad v hacia la derecha a lo largo
del eje X.
Si se considera un tren de ondas armnico propagndose por la cuerda, la
ecuacin que describe la posicin de cada punto de la cuerda en el instante inicial es de
la siguiente forma:
y = A sen kx

siendo A y k constantes.
Si admitimos que a medida que transcurre el tiempo el tren de ondas se propaga con
velocidad v hacia la derecha sin deformarse, la ecuacin que describe el movimiento es
de la siguiente forma:
y(x,t) = A sen k(x vt)

Figura 1.6 Onda inicial y propagada


Al trmino k(x-vt) se le denomina fase. En ocasiones hay que aadir a esta frmula la
constante , que recibe el nombre de fase inicial. De ese modo,

C A P T U L O 1 Teora del sonido


y(x,t) = A sen[k(x vt) + ]
sera entonces la ecuacin que encierra toda la informacin acerca del movimiento
ondulatorio.

1.2 El sonido como forma de onda


El sonido es por tanto un fenmeno fsico y como se ha visto anteriormente, es
un movimiento ondulatorio en un medio elstico que generalmente es el aire, debido a
cambios rpidos de presin generados por el movimiento vibratorio en el medio.
Podramos, entonces, clasificar el sonido como un tipo de onda que produce cierta
sensacin en el odo como consecuencia del movimiento ondulatorio en el aire, agua u
otros medios.
1.2.1 Dominio del tiempo y frecuencia
Una seal puede verse como la variacin en el tiempo de una cantidad tal como
voltaje o corriente. Como ejemplo consideramos la seal de voltaje sinusoidal dada por:
v(t) = V cos (2Ft + )
V es el voltaje de pico, F es la frecuencia y es la fase relativa. Estos parmetros se
indican en la figura 1.7. La onda es peridica con periodo T = 1/F, ya que:
v(t) = v(t + T)

V(t)

V
Amplitud (A)

Tiempo

T = 1/F

Figura 1.7 Onda senoidal en el dominio del tiempo


Esta descripcin se denomina representacin de la seal en el dominio del
tiempo: la seal se ve como una funcin del tiempo. Esta es la forma ms comn de

C A P T U L O 1 Teora del sonido


representar las seales y de observarlas en las aplicaciones de edicin de sonido
comunes.

Sin embargo, existe otra manera de representacin de una seal. Consideremos la forma
de onda de la figura 1.7. Esta seal sinusoidal viene descrita por la amplitud V, la
frecuencia F y la fase . Estos tres parmetros junto con el conocimiento de que la seal
es sinusoidal son suficientes para dibujar la forma de onda del voltaje; la tripleta (V, F,
) especifica completamente la seal. Si consideramos despreciable la fase, es decir,
=0, trataremos entonces con la amplitud V y la frecuencia F; ahora el par (V,F)
especifica completamente la seal. En esta interpretacin F y V pueden tomar cualquier
valor positivo y la seal puede representarse grficamente como muestra la figura 1.8.

(V,F)

Componente espectral

F = 1/T

Figura 1.8 Representacin espectral de una onda senoidal


Esta es la representacin en el dominio de la frecuencia. Con este punto de vista,
una seal cosenoidal viene representada por una flecha vertical localizada en algn
punto F del eje de frecuencias, y la altura de la flecha corresponde a la amplitud V.
La representacin en el dominio de la frecuencia es muy til, ya que las seales
ms complejas pueden ser consideradas como una superposicin (suma) de
componentes sinusoidales con diferentes amplitudes, frecuencias y fases. Para las
seales armnicas las frecuencias estn relacionadas por nmeros enteros. Si T es el
perodo, entonces se dice que la forma de onda tiene una frecuencia fundamental de 1/T.
La siguiente frecuencia ms cercana contenida en la forma de onda es 2/T, denominada
segundo armnico, y despus viene el tercer armnico a la frecuencia 3/T, y as
sucesivamente. Generalmente los distintos armnicos tienen amplitudes y fases
diferentes. Para obtener una apreciacin general del contenido en armnicos de una
forma de onda compleja, es conveniente representar la seal grficamente en el dominio
de la frecuencia, como se ilustra en la figura 1.9.

C A P T U L O 1 Teora del sonido

f
0

1/T

2/T

3/T

4/T

Figura 1.9 Representacin de las componentes espectrales de una onda armnica


La altura de las flechas representa la fuerza de los distintos armnicos. Esta
representacin en el dominio de la frecuencia se denomina frecuentemente espectro de
la seal; los distintos componentes en frecuencia que los constituyen se denominan
componentes espectrales o lneas espectrales.
1.2.2 Teorema de Fourier
Gracias al teorema de Fourier, desarrollado por el matemtico francs Fourier
(1807-1822) y completado por el matemtico alemn Dirichlet (1829), es posible
demostrar que toda funcin peridica continua, con un nmero finito de mximos y
mnimos en cualquier perodo, puede desarrollarse en una nica serie trigonomtrica
uniformemente convergente a dicha funcin, llamada serie de Fourier.
Supongamos que una seal peridica se puede representar como:
x(t) = A0 + A1cos(2(t/T) + 1) + A2cos(2(t/T) + 2) + + Ancos(2(t/T) + n)
o ms concisamente como:

x(t ) = A0 + An cos[2 (nt / T ) + n ]


n =1

Esto se conoce como la representacin mediante series de Fourier de x(t). Ntese


la relacin con la representacin en el dominio de la frecuencia: Las amplitudes An dan
las alturas de las distintas lneas espectrales.
Una representacin alternativa se obtiene a partir de la relacin trigonomtrica cos(A
+B), podemos entonces representar x(t) de la siguiente forma:

n =1

n =1

x(t ) = A0 + an cos(2nt / T ) + bnsen(2nt / T )


donde an = Ancos(n) y bn = -An sen(n).

10

C A P T U L O 1 Teora del sonido


Otra representacin hace uso de la relacin:
cos A =

e ja + e ja
2

donde, definiendo C0 = A0, x(t) puede expresarse en trminos de una nica serie sobre
todos los nmeros enteros:

x(t ) =

Cne ( j 2 / T )

n =

los trminos an y bn reciben el nombre de coeficientes de Fourier y pueden obtenerse


evaluando las integrales:

a0 =

1T
x(t )dt
T0

an =

2 T
x(t ) cos(2nt / T )dt
T 0

bn =

2 T
x(t ) sen(2nt / T )dt
T 0

que se obtienen extrapolando lo sumatorios, es decir usando el concepto de integral


definida, como suma de infinitos diferenciales de funcin entre dos lmites que
representan un intervalo.
El coeficiente a0 corresponde al valor medio de la funcin en el perodo T.

11

C A P T U L O 1 Teora del sonido


1.2.3 Ondas armnicas y ruido
Desde el punto de vista subjetivo, los sonidos que percibimos se pueden dividir
en dos grandes grupos: sonidos armnicos y ruidos o sonidos no armnicos.
Las ondas armnicas se caracterizan por tener componentes que se repiten
peridicamente y que dan lugar a una serie de rayas espectrales en la transformada de
Fourier, conocidas como armnicos. Este es el tipo de sonido que se genera como
consecuencia de la vibracin de un material elstico a la frecuencia de resonancia. Este
sera el caso del sonido de una cuerda de piano.
El ruido en cambio no tiene componentes armnicas y por tanto da lugar a una
transformada de Fourier con componentes en todas las frecuencias. Segn la
distribucin de amplitud de estas componentes se puede hablar de ruido blanco y ruido
coloreado. El ruido blanco tiene igual amplitud en todas las frecuencias, mientras que el
ruido coloreado tiene mayor peso de unas frecuencias que de otras. Este es el tipo de
sonido que se genera como consecuencia de una interaccin mecnica a una velocidad
superior de la caracterstica del medio, lo cual da lugar a una onda de choque. Este sera
del caso del sonido de percusin.

12

C A P T U L O 1 Teora del sonido

Figura 1.10 Ondas armnicas y ruido con sus respectivas transformadas


1.2.4 Propagacin del sonido
El efecto que producen la vibracin de las partculas desplazadas como forma de
onda en el aire y que percibe el odo es lo que denominamos sonido. Como
mencionamos antes, el sonido es una onda mecnica, y aunque se puede propagar por
otros medios, es necesario que se convierta en una perturbacin acstica para poder ser
percibida por el odo. Como ejemplo ilustrativo, imagine el lector los primeros modelos
de telfono en el que se conectaban dos vasos de plstico por medio de una cuerda
tensa. Al comenzar a hablar uno de los interlocutores, el sonido se transforma en una
vibracin mecnica y consigue hacer vibrar el envase situado en el extremo opuesto.
El sonido se propaga por los diferentes medios de forma longitudinal, es decir, el
movimiento de las partculas ocurre en la direccin misma en la que la onda se propaga.
Si estudiamos el caso de la propagacin del sonido en el aire, ste se transmite como
una onda de presin debido a la compresin y expansin de las partculas de oxgeno.
Un ejemplo de este fenmeno podemos verlo ilustrado en la figura 1.11.

13

C A P T U L O 1 Teora del sonido

Figura 1.11 Propagacin de una onda sonora


No debe confundirse la propagacin del sonido con la propagacin de una
perturbacin mecnica que da lugar a una seal acstica. Esto ocurre en medios
diferentes al aire. As pues, cuando por ejemplo golpeamos un metal alargado que
produce sonido en un extremo y en el otro es la transformacin acstica de la vibracin
mecnica, aqu es importante saber que no se transmite el sonido por el metal, sino que
es una perturbacin mecnica a travs del metal.
Como vimos en el apartado 1.1.1, tanto si se trata de una onda material, como si
sta es electromagntica, la perturbacin se propaga de un punto a otro del espacio con
una velocidad que depende de las caractersticas del medio. En ambos casos se produce
un transporte de energa.
La velocidad del sonido depende de las caractersticas del medio fsico en las
que se transmite la propagacin. La velocidad del sonido es mayor en elementos slidos
que en elementos lquidos, y en los lquidos mayor que en los gaseosos. La velocidad
del sonido depende de la siguiente frmula:

v=

Siendo B el factor de compresin del medio y la densidad.


En general la velocidad del sonido depender de la densidad del material y su
elasticidad. As, la velocidad de propagacin de la onda es menor cuanto mayor es la
densidad, por ello, la velocidad en el agua es menor que en la madera, como podemos
ver en la tabla 1.1. No obstante, tambin influira aqu el factor de compresin, que
explicara entonces por qu la velocidad de una onda es mayor en el acero que en el
agua, a pesar de tener mayor densidad.
Material
Velocidad
Agua (20 C)
1.482 m/s
Madera
3.900 m/s
Acero Inoxidable
5790 m/s
Tabla 1.1 Velocidad de propagacin del sonido en diferentes medios

14

C A P T U L O 1 Teora del sonido


La velocidad del sonido en el aire (a una temperatura de 20) es de 344 m/s. Existe
una ecuacin propuesta por Newton y posteriormente modificada por Laplace que nos
permite obtener la velocidad del sonido en el aire teniendo en cuenta la variable de la
temperatura:

V =

331.3
t
1+
273.15

1.3 Percepcin humana del sonido


El sonido no sera una realidad si no fuera por la capacidad de captacin por los
sentidos del ser humano, en este caso el rgano encargado de transformar las
vibraciones sonoras en el medio en respuestas nerviosas interpretables por el cerebro es
el odo. Este ser el objeto de estudio del presente apartado.
1.3.1 Funcionamiento del odo
Una de las funciones principales del odo es convertir las ondas sonoras en
vibraciones que estimulen las clulas nerviosas, para ello el odo tiene tres partes
claramente identificadas. Estas partes estn interconectadas y son el odo externo, el
medio y el interno. Cada parte tiene funciones especficas dentro de la secuencia de
procesamiento del sonido.

Figura 1.12 Anatoma del odo humano

15

C A P T U L O 1 Teora del sonido


Empecemos con cada una de estas partes:

Odo externo: Es la parte ms externa e incluye las siguientes partes:


o Pabelln auricular: Es la parte exterior del odo, es un cartlago plano y
elstico que tiene forma del extremo de una trompeta y est cubierta de
piel gruesa. Las partes principales del pabelln auricular son: el hlix que
es el borde exterior, el antihlix que es la eminencia central del pabelln
que termina en una elevacin llamada anttrago o parte central, en la
parte inferior.
o Conducto auditivo externo: Es una especie de tubo que mide unos 2,5 cm
de longitud situado en el hueso temporal; est compuesto por folculos
pilosos, glndulas sebceas que producen cerumen y glndulas de ovillo
que son las responsables de dar el color a la cera.

o Membrana timpnica: Esta membrana vibra cuando es golpeada por


ondas sonoras transmitidas por el aire y es la responsable de convertir las
mismas en impulsos nerviosos que llegan al cerebro.
Odo medio:
o Trompa de Eustaquio: Conecta el odo medio con la faringe e iguala la
presin entre las dos bandas de la membrana timpnica.
o Martillo, Yunque y Estribo: Se encargan de transmitir al odo interno las
vibraciones sonoras que llegan por el aire. Transforman las ondas
sonoras en vibraciones mecnicas. Las vibraciones captadas por la
membrana timpnica hacen que se mueva el martillo, que desplaza al
yunque y al estribo, que es el hueso conectado a la membrana oval,
recibiendo las vibraciones aumentadas en 5 dB.

o Ventana oval: Es la responsable de convertir los estmulos recibidos por


los huesos anteriores del medio areo a un medio lquido
Odo interno:
o Cclea: Tambin llamado caracol. Como su mismo nombre indica, tiene
forma de tubo espiral. Se encuentra lleno de lquido y posee la membrana
de Reissner y la membrana basilar, donde reside el rgano de Corti,
formado por clulas ciliadas que vibran a determinadas frecuencias.
o Canales semicirculares: Son tres tubos de forma semicircular, uno de
ellos se encuentra en posicin horizontal y los otros dos en posicin
vertical.
o Nervios auditivos: Son los responsables de transmitir la informacin
sonora al cerebro.

En la figura 1.13 puede observarse la relacin de las funciones del odo con un
procesamiento computerizado del mismo:

16

C A P T U L O 1 Teora del sonido

Odo externo

Odo medio

Odo interno

Pabelln auricular +
Conducto auditivo +
Membrana timpnica

Martillo +
Yunque +
Estribo

Vestbulo+
Cclea

Preamplificador
procesador

Micrfono de
alta calidad

Analizador de frecuencias

Figura 1.13 Modelo equivalente del odo humano

1.3.2 Cualidades del sonido


En apartados anteriores hemos visto los parmetros del sonido desde el punto de
vista fsico. Sin embargo, desde el punto de vista de la percepcin auditiva, hay otros
parmetros que resultan relevantes:

Intensidad: Se define como la energa por unidad de rea. Normalmente es la


medida de la intensidad del sonido en el aire en la posicin donde se encuentra
el oyente. El odo humano responde de manera logartmica a la intensidad del
sonido y se suele medir en decibelios, concepto que se estudiar en la siguiente
seccin. La unidad bsica son los vatios/m2 o vatios/ cm2.

Tono: Es la respuesta del odo a la frecuencia del sonido. Con el tono se percibe
si los sonidos son graves, agudos o medios. La mayora de los sonidos que
escuchamos estn compuestos de varias frecuencias, por tanto, el tono que se
percibe depende de la frecuencia dominante.

Timbre: Se determina principalmente por el contenido armnico o las


caractersticas dinmicas del sonido como son: el vibrato, la componente de
ataque etc. El timbre permite distinguir sonidos, como por ejemplo, diferenciar
una misma nota producida por dos instrumentos musicales diferentes.

Duracin: Es la duracin de la vibracin del sonido.

17

C A P T U L O 1 Teora del sonido


1.3.3 Espectro audible e intensidad sonora (Decibelios)
El espectro audible del ser humano se encuentra en el rango de frecuencias desde
los 20 a los 20000 Hertzios (Hz). Los sonidos por debajo de los 20 Hz se les denomina
infrasonidos o subsnicos, y respectivamente, a los que tienen una frecuencia superior a
los 20000 Hz se les llama ultrasnicos.
A las frecuencias se las puede clasificar segn su tonalidad, por lo tanto, a
mayor frecuencia mayor tonalidad. As existen tonos graves, medios y altos. Los
sonidos graves caen dentro del rango de 20 a 300 Hz, los medios de 300 a 2000 Hz y los
agudos de 2000 a 20000Hz.
En cuestin de frecuencia el odo tambin funciona en escala logartmica, y esta
es la base de la armona musical. Dos notas musicales se consideran armnicas cuando
la frecuencia de una es un mltiplo de la otra. Una octava es el intervalo entre dos notas
cuya frecuencia fundamental tiene una relacin de dos a uno. Dentro de una octava hay
siete notas bsicas, siendo la octava nota del doble de frecuencia que la primera, de ah
su nombre. El odo nos hace percibir como equiespaciadas las notas dentro de una
octava, a pesar de que la distancia en frecuencia es diferente segn la octava que se
considere.
El espectro audible se puede subdividir en octavas. En la siguiente tabla se
puede observar una relacin entre el nmero de octava y su frecuencia:
1 octava
16 32 Hz
2 octava
32 - 64 Hz
3 octava
64- 125 Hz
4 octava
125 250 hz
5 octava
250 500 Hz
6 octava
500 1000 Hz
7 octava
1000 2000 Hz
8 octava
2000 4000 Hz
9 octava
4000 8000 Hz
10 octava
8000 16000 Hz
11 octava
16000 32000 Hz
Tabla 1.2 Rango de frecuencias de las octavas musicales
La primera y la ltima octava son prcticamente inaudibles.
Tambin la capacidad vocal se puede medir en octavas, siendo el rango medio
de una persona de 3 octavas.
Respecto a la intensidad sonora, depende de la amplitud de oscilacin, de la
potencia de la fuente y de la forma en que ha sido transmitida, es decir, el medio fsico.
La intensidad sonora se mide en decibelios (dB), que es la unidad utilizada para
medir el nivel presin sonora (SPL). El trmino decibelio significa 1/10 de un belio,
unidad de medida de transmisin telefnica que recibi el nombre gracias a Alexander
Graham Bell, inventor del telfono.

18

C A P T U L O 1 Teora del sonido


La sensacin sonora de intensidad se agudiza para sonidos dbiles, y su
sensibilidad disminuye para sonidos fuertes, es decir, los decibelios siguen una relacin
exponencial, que es la que tiene el odo humano.

En la figura 1.14 se presentan los umbrales de la tolerancia de los sonidos en


decibelios:

Figura 1.14 Sensibilidad del odo humano


La referencia de los 0 dB SPL es el umbral de audicin, que es la menor cantidad de
sonido en el aire perceptible por el odo humano emitida a 1000 Hz.
En la siguiente ecuacin se muestra la relacin del valor del nivel de intensidad sonora:
I
Nivel = 10log
Iref
que, por lo tanto, se puede expresar de la siguiente forma:
P
Nivel = 10log

Pr ef
Como la referencia es 2 10 -5 Pa, resulta que los decibelios SPL valen medidos en Pa:
P
NivelSPL = 20log
-5
2 10

19

C A P T U L O 1 Teora del sonido


En la siguiente tabla se muestra una correlacin de distintos niveles de SPL de presin
sonora con sonidos del medio:
Decibelios
Caso real
Despegue de un avin
120
Umbral de dolor
110
Martillo neumtico
90
Interior de una oficina
60
Conversacin normal
50
Habitacin en silencio
40
Al aire libre en silencio
20
Umbral inferior de audicin
0
Tabla 1.3 Niveles sonoros de diversos eventos

1.4 Generacin de sonido analgico y digital


El sonido es resultado de vibraciones producidas en alguna fuente de tipo
material (como un piano) o una fuente electrnica (como un sintetizador o una guitarra
elctrica).
Ambas son diferentes en la forma de generacin de la forma de onda, pero an as,
comparten caractersticas comunes que comentaremos a continuacin.
1.4.1 Instrumentos musicales convencionales
En este apartado tratamos los instrumentos fabricados con materiales como la
madera o el metal. Vamos a tratar la fsica de los instrumentos de percusin, los de
viento y los de cuerda como ejemplos ms significativos.

Instrumentos de percusin:
El ejemplo ms caracterstico es el tambor. La peculiaridad principal de este
instrumento es que el sonido se genera golpeando un mazo o baquetas contra una
membrana, llamada comnmente parche, que cubre la abertura de una caja de
resonancia generalmente cilndrica.
Los instrumentos de percusin se basan principalmente en la vibracin y en la
resonancia. Cuando se golpea la membrana se produce una deformacin de la misma
que genera una vibracin del aire que hay dentro del mismo. El cuerpo del tambor
empieza a resonar, junto con la membrana, produciendo un sonido alto y grave
procedente de su estructura.
La frecuencia de resonancia de la caja del tambor se define segn la ecuacin:

20

C A P T U L O 1 Teora del sonido

0.764 F

f =
D

1/ 2

donde F es la tensin de la membrana por unidad de circunferencia en N/m (newtons


por metro), D es el dimetro de la membrana y es la densidad de rea de la membrana
medida en kg/m2.
Para los xilofones, marimbas u otros instrumentos que incorporen platos
vibrantes, se usa la siguiente ecuacin para obtener la frecuencia de resonancia:

f =

1.03kv
L2

donde L es la longitud de la barra, v es la velocidad del sonido en el objeto y k es una


constante que depende del objeto.

Instrumentos de viento:
Los instrumentos de viento generan sonido por medio de vibraciones producidas
en el interior de tubos. Los cambios de frecuencia del sonido se producen como
consecuencia de acortar o alargar la longitud de los tubos, cerrando y abriendo pequeos
orificios creados en los mismos. Existen tres categoras de instrumentos de viento, en
atencin al material constructivo y a la forma de generar la vibracin: metal (ej.
trompeta), madera (ej. flauta) y rganos.
La ecuacin para determinar la longitud de onda en un instrumento de viento
donde el tubo est abierto por ambos extremos es:

2L
n

donde n 1 y L es la longitud del tubo.

y la ecuacin para un instrumento de viento abierto por slo por un extremo es:

4L
(2n + 1)

donde n 0 y L es la longitud del tubo.

21

C A P T U L O 1 Teora del sonido


Instrumentos de cuerda:
Los instrumentos de cuerda generan el sonido por vibracin de una cuerda
tensada, que resuena en una caja de resonancia. Estos instrumentos estn construidos de
diferentes materiales para producir diferentes tonalidades.
En todos los instrumentos de cuerda, la cuerda est fijada en los extremos del
instrumento y es golpeada, frotada o pinzada para producir una onda sonora que es
amplificada posteriormente en el cuerpo del instrumento. De la forma de actuar sobre la
cuerda se deriva la clasificacin de estos instrumentos: de cuerda frotada (ej. violn), de
cuerda pulsada (ej. guitarra) o de cuerda percutida (ej. piano).
A continuacin se deduce la frecuencia de vibracin de una cuerda tensada. La
velocidad de una onda viajando por una cuerda vibrando, y la tensin de la cuerda estn
relacionados por la siguiente ecuacin:
v = f

v=
m

1/ 2

= f

donde T es la tensin en Newtons, m es la masa de la cuerda y L la longitud de la


misma. Por lo tanto:
1/ 2


L
f =

Esta frecuencia es conocida como la frecuencia fundamental y tiene una longitud


de onda igual a dos veces la longitud de la cuerda, debido a esto los nodos o puntos cero
de desplazamiento de la onda son los finales de la cuerda del instrumento (figura 1.15).
Debido a esto incluira longitudes de onda que son iguales a la longitud de la cuerda,
(primer armnico), 2/3 de la longitud de la cuerda (segundo armnico), 2/4 de la
longitud de la cuerda (tercer armnico), y as sucesivamente. Es importante conocer que
el sonido de un instrumento de cuerda ser diferente atendiendo al cuerpo del
instrumento que har que resuene a diferentes frecuencias.

22

C A P T U L O 1 Teora del sonido

Figura 1.15 Vibracin de una cuerda


1.4.2 Sntesis analgica
En esta forma de sntesis entendemos la generacin de sonido sin electrnica
digital, conectando varios mdulos en cascada para obtener el sonido final. El elemento
principal en un sintetizador, ya sea analgico o digital, es el oscilador, que es un
sistema que genera una onda peridica con una determinada forma (cuadrada,
sinusoidal, triangular, diente de sierra, etc.).
Se puede clasificar los tipos de sntesis analgica en los siguientes tipos:

Sntesis aditiva: Consiste en generar el sonido mediante sucesivos


enriquecimientos del espectro de la onda, es decir, se van aadiendo armnicos
hasta conseguir la forma de onda deseada.
Sntesis sustractiva: Se parte de una forma de onda muy rica en armnicos, por
ejemplo del resultado de una sntesis no lineal, y desde ah vamos eliminando
armnicos hasta quedarnos con una forma de onda ms bsica y adecuada a
nuestras necesidades.
Sntesis por modulacin de amplitud (AM): Consiste en utilizar una seal
portadora a una determinada frecuencia e ir modulando su amplitud mediante
otra seal, por lo general, mltiplo de la primera. La forma de onda resultante se
le denomina seal moduladora. Por ende, se consiguen formas de ondas con
diferentes timbres partiendo de formas de onda ms primitivas.
Sntesis por modulacin en anillo (RM): En este caso se trata de una modulacin
en amplitud, pero se multiplica la seal portadora por la moduladora, generando
de esta forma sonidos ms peculiares que los de sntesis por modulacin de
amplitud (AM).

Las tcnicas citadas anteriormente se las califica de tcnicas de sntesis lineal,


pues existe una relacin lineal entre el espectro de las frecuencias iniciales
(moduladora y portadora, por ejemplo) y el espectro de salida.
La sntesis analgica est basada en mdulos, todo en sntesis analgica es
modular.
En la figura 1.16 tenemos el diagrama de bloques de un sintetizador analgico:

23

C A P T U L O 1 Teora del sonido

Figura 1.16 Diagrama de bloques de un sintetizador analgico

A continuacin se describen con ms detenimiento cada una de sus partes:


Oscilador
Un oscilador es un circuito electrnico capaz de generar una forma de onda
peridica a una determinada frecuencia. Existen osciladores controlados por tensin
(cuya frecuencia de oscilacin es controlada por el voltaje de un circuito) y osciladores
digitales (que son generados de por circuitera digital). En este caso nos centraremos en
los primeros.
Las formas de onda ms utilizadas en msica electrnica han sido las cuadradas y las de
diente de sierra, como se ve en la siguiente figura:

Figura 1.17 Onda de diente de sierra (izquierda) y onda cuadrada (derecha)


Tambin se utilizan otros tipos de onda como la triangular y la onda de ruido
(onda que no posee tonalidad, es aleatoria, no posee periodo y se le denomina ruido
blanco).
Las ondas triangulares son apropiadas para generar timbres parecidos a los instrumentos
de viento, mientras que la aleatoria es ms apropiada para los instrumentos de
percusin.

Figura 1.18 Onda triangular (izquierda) y aleatoria (derecha)

Para crear un generador de onda triangular con circuitera analgica se utiliza el


circuito que se describe en la figura 1.19. El condensador C se carga mediante una
fuente de corriente constante, con lo cual la tensin en sus terminales crece linealmente.
24

C A P T U L O 1 Teora del sonido


Dicha tensin se aplica a un amplificador operacional que funciona como comparador.
Cuando la tensin del condensador supera la tensin de referencia Vref el comparador
activa el transistor, el cual descarga el condensador y el ciclo vuelve a empezar. Si la
seal triangular se aplica a un segundo comparador con una tensin de referencia
variable, se consigue una onda de ancho de pulso variable (PWM).
En la siguiente figura podemos ver una implementacin analgica para un oscilador de
diente de sierra y cuadrada:

Figura 1.19 Generador de formas de onda bsicas (diente de sierra y cuadrada)

Generadores de envolvente
Un generador de envolvente es un circuito que genera una seal que permite
controlar un parmetro dentro de un sistema de sntesis. La seal envolvente se suele
usar para modular la amplitud de la seal armnica, y de esta manera simular las
variaciones de amplitud de un instrumento de cuerda. Otros tipos de envolvente se
utilizan para modular el tono o pitch de la seal.
Normalmente, los generadores de envolvente, son del tipo ADSR (Attack, decay,
sustain, release) o traducido al espaol (ataque, decaimiento, sostenido, liberacin)
como se puede ver en la siguiente figura:

25

C A P T U L O 1 Teora del sonido

Figura 1.20 Diagrama de una envolvente de volumen


En la siguiente figura se puede ver un circuito utilizado para generador de
envolvente tipo ADSR

Figura 1.21 Esquema elctrico de un generador de envolvente de volumen

Amplificador
Los amplificadores que utilizan los sistemas analgicos son del tipo VCA o
amplificadores controlados por tensin que tienen la peculiaridad que su ganancia puede
ser controlada por un voltaje adicional. El VCA es el complemento indispensable para
producir una envolvente de amplitud.
Para implementar un VCA se suelen usar amplificadores operacionales de
transconductancia, aunque tambin se puede implementar con componentes discretos.
En la siguiente figura se observa la circuitera para implementar un VCA.

26

C A P T U L O 1 Teora del sonido

Figura 1.22 Amplificador de amplitud controlada


Filtro
Los filtros son elementos indispensables en la sntesis analgica; aunque estos
conceptos se tratarn ms en profundidad en el captulo 7.
Hay varios tipos de filtro como veremos a continuacin:

Filtro paso-bajo

Filtro paso-banda
Figura 1.23 Tipos de filtro

Filtro paso-alto

Filtro elimina-banda

27

C A P T U L O 1 Teora del sonido


El filtro ms utilizado en cuestin es el paso-bajo, pues es el ms fcil de
implementar. Tiene dos caractersticas fundamentales: la frecuencia de corte y la
pendiente de filtrado. Algunas implementaciones de filtro paso-bajo incorporan un filtro
resonante para mejorar la pendiente de corte, un cuyo caso hay un parmetro ms que
controlar.
La frecuencia de corte debe ser ajustable mediante un voltaje de control, la de
resonancia tambin, aunque en este esquema no se vara con un voltaje sino con una
resistencia, mientras que la pendiente de filtrado viene determinada por el nmero de
polos del circuito. Valores tpicos para la pendiente
2 polos: 12 dB/octava
3 polos: 18 dB/octava
4 polos: 24 dB/octava
5 polos: 30 dB/octava

Vemos que los decibelios/octava se van incrementando de 6 en 6 a partir de 12


dB/octava: cada polo introduce un incremento de 6 dB/octava en la pendiente. A mayor
pendiente, ms selectivo es el filtro.
Valores comunes para filtros es de 12 dB/octava (2 polos) y 24 dB/octava (4 polos).
Respecto a la implementacin del circuito se puede decir que la configuracin se
le denomina Filtro de Estado Variable (State Variable Filter) ya que permite la
configuracin independiente tanto de la frecuencia de corte como de la resonancia o
factor de amortiguamiento.

Figura 1.24 Esquema elctrico de un filtro sintonizable


La frecuencia de corte se controla mediante un voltaje, mientras que la resonancia se
controla con un simple potencimetro.

28

C A P T U L O 1 Teora del sonido


1.4.3 Tcnicas de sntesis digital
Dentro de la sntesis digital consideramos la generacin de sonido utilizando un
sistema electrnico digital, que puede ser un circuito dedicado o un sistema procesador
controlado por software. Hay que destacar que muchas de las tcnicas utilizadas en la
sntesis analgica son utilizadas tambin en la sntesis digital.
La sntesis digital tiene varias ventajas sobre la analgica:

Se puede reutilizar el mismo circuito para varios sonidos, simplemente


cambiando la configuracin.
Es menos sensible al ruido acoplado, porque todo el procesamiento es digital.
Se pueden hacer filtros y efectos difciles de fabricar en circuitera analgica.

A continuacin destacamos las tcnicas ms comunes de sntesis digital:


Sntesis aditiva
Como vimos en la seccin anterior, la sntesis aditiva consiste en generar un
sonido peridico ms complejo resultante de la suma de ondas sinusoidales ms
elementales de frecuencia mltiplo de una frecuencia base.
Para obtener una forma de onda rica, son necesarios muchos armnicos.
Actualmente esto es fcilmente realizable va software, pero en los inicios plasmarlo
con circuitera digital (hardware) requera un gran nmero de osciladores y sumadores y
por lo tanto, encareca en exceso el sistema.
En la siguiente figura se puede observar un ejemplo tpico de sntesis aditiva
digital por medio de la suma de dos formas de onda bsicas:

Figura 1.25 Sntesis aditiva de formas de onda


La onda resultante mantiene la frecuencia del componente ms grave, pero con el timbre
alterado.
29

C A P T U L O 1 Teora del sonido


Modulacin de frecuencia (FM)
Una de las formas de poder realizar sntesis de sonido es por medio de la
modulacin, que consiste en variar un parmetro de la seal portadora con respecto a la
seal moduladora, generando una seal modulada. Para la sntesis FM se hace oscilar la
frecuencia de la onda portadora. Para esta sntesis slo se utilizan de dos a seis
osciladores, mientras que en la sntesis aditiva se requiere un oscilador para cada onda.
Por ende, la sntesis FM es ms rica en calidad que la sntesis aditiva, ya que puede
generar ondas complejas que contengan mltiples frecuencias con tan slo dos
osciladores.
La historia de este modelo de sntesis tiene su origen en el famoso compositor John
Chowning y en el sintetizador DX7 fabricado por la casa Yamaha:

Figura 1.26 Sintetizador Yamaha DX7


Yamaha compr los derechos del algoritmo de sntesis FM para construir su modelo de
sintetizador que puede apreciarse en la imagen anterior.
En el funcionamiento de la sntesis FM, la distribucin de los armnicos de una
onda sinusoidal simple modulada por otra seal sinusoidal puede ser representada con
las funciones de Bessel.
La sntesis FM es una forma de sntesis no lineal. Comienza con un oscilador
generando una onda portadora con la frecuencia Fc y otra con una seal moduladora,
con una frecuencia Fm que se aplica para cambiar o modular la frecuencia de la
portadora.
Si la amplitud del modulador es 0, la frecuencia de salida de la seal portadora
es simplemente Fc. De otra forma, la amplitud de la seal moduladora causa que la seal
de la portadora oscile por encima o por debajo de Fc. En otras palabras, cuanto ms
fuerte es la seal moduladora, ms cambia la frecuencia de la portadora. Como ejemplo
ilustrativo, supongamos que Fc es 1000 Hz. Si la amplitud de la modulacin es 100 Hz
se consigue que la seal de la portadora oscile entre 900 Hz y 1100 Hz, esto es, 100 Hz
en cada direccin. Esto es lo que se conoce como desviacin.
A la misma vez, la frecuencia de la seal moduladora causa bandas laterales
(side bands) que aparecen en frecuencias por encima y por debajo de la frecuencia
portadora. Por lo tanto, para cada componente de frecuencia en la seal moduladora,
aparece una banda lateral superior por encima de Fc y una banda inferior por debajo de
Fc. Una seal compleja moduladora (conteniendo ms armnicos que una seal

30

C A P T U L O 1 Teora del sonido


sinusoidal) crear bandas laterales correspondientes a cada una de sus componentes
sinusoidales.
La desviacin es responsable de la distribucin espectral de potencia de la seal
de salida. Cuando la desviacin es cero, toda la potencia se concentra en la frecuencia
portadora. A medida que aumenta la desviacin la potencia se reparte entre las
frecuencias que rodean a la portadora.
La relacin entre la desviacin y la frecuencia moduladora se denomina ndice
de modulacin (I = d / fm). Esta relacin controla la riqueza espectral del sonido. Si se
acta simultneamente sobre la profundidad de modulacin y sobre el espectro de la
seal moduladora se consigue una gran riqueza armnica en la seal modulada. Esta es
la potencia de la sntesis FM.

=1

=5

=25
Figura 1.27 Representacin temporal de una seal modulada en FM, en funcin del
ndice de modulacin.

Puede consultarse ms informacin sobre el algoritmo FM en la siguiente URL:


http://the-all.org/tx81z/fm_overview.html
y
http://www.rfcafe.com/references/electrical/frequency-modulation.htm

31

C A P T U L O 1 Teora del sonido


Sntesis por tabla de ondas
Este es el sistema utilizado por la mayora de los sintetizadores digitales
modernos. Parten de pequeos fragmentos de sonidos digitalizados y almacenados en
memoria. Esta sntesis tambin llamada de tabla de ondas o Wavetable se utiliza cuando
no recurre directamente a un muestreo del sonido a emitir. Un sintetizador General
MIDI (GM) deber contener suficientes fragmentos para representar los 128
instrumentos y los 59 sonidos de percusin.
Las tcnicas de sntesis por tabla de onda ms utilizadas son las siguientes:

Generacin en bucle: es la tcnica ms primitiva y se basa en la repeticin


(looping) de muestras de sonido pregrabadas para producir una seal original.
Para ello se dividen y almacenan las dos partes de la mayora de los sonidos
producidos por instrumentos: la seccin de ataque que se reproduce entera y
la de sostenimiento que se reproduce en bucle cada vez con menor intensidad
siguiendo un patrn preestablecido. Finalmente el sonido se completa con una
seccin de liberacin donde se termina de bajar la amplitud hasta 0 de manera
ms rpida imitando el desvanecimiento natural del sonido.
Este sistema tiene cierta complejidad si se intentan utilizar efectos como coro o
reverberacin. Por otro lado, es necesario un tratamiento adicional de la seal
para mejorar la relacin seal/ruido o preparar la seal para su edicin.

32

Desplazamiento de tonos: con esta tcnica se puede lograr que a partir de una
muestra de sonido que representa una nota determinada se puedan generar otras
notas del mismo instrumento. Para conseguir esto se aplican diferentes filtros a
la seal original que junto con un aumento o reduccin de la frecuencia de
reproduccin de la seal da lugar a la nueva nota. Este sistema es ms fcil de
implementar por software y es el que utilizan muchos VST (Instrumentos
Virtuales Digitales) comerciales, como el de la figura 1.28.

Interpolacin: esta tcnica intenta eliminar el problema de almacenamiento en


memoria, reduciendo la memoria destinada al muestreo de sonidos. En este caso
los sonidos pueden estar grabados a una frecuencia relativamente baja. De esta
forma cuando la seal sea enviada al conversor D/A (digital-analgico) el
sintetizador puede encontrarse con que debe enviarle posiciones de memoria
que son decimales (como, por ejemplo, enviarle la posicin 4,5 de la memoria).
Este problema se resuelve mediante la interpolacin de los valores adyacentes.
Con este mtodo se puede reconstruir mejor la seal original y aumentar
considerablemente la calidad del sonido.

Diezmado: es el efecto contrario a la interpolacin. La seal es muestreada a


varias veces por encima de la frecuencia necesaria para poder afinar mucho
mejor los problemas de cambio de tono al editar la misma o realizar bucles con
ella. El nico problema de este mtodo es el excesivo espacio de memoria que
requiere.

C A P T U L O 1 Teora del sonido


Los sintetizadores actuales tienen una memoria ROM de hasta 64MB para el
almacenamiento de muestras y las tarjetas de sonidos 4 y 8MB respectivamente. En el
caso de los sintetizadores hay ciertas garantas de que la calidad del sonido ser
aceptablemente buena.

Figura 1.28 Software VST con sntesis de tabla de ondas con desplazamiento de tonos.

33

C A P T U L O 1 Teora del sonido

1.5 Representacin del sonido


1.5.1 Conversin analgico / digital
Debe de ser posible representar el sonido que se encuentra en el ambiente o
procedente de lneas de entrada (line-in) en un formato numrico inteligible para el ser
humano y sobre todo procesable por computadora, de esta manera, es posible capturar
sonido del medio con micrfonos y transformar inicialmente esas vibraciones en el aire
en impulsos electromagnticos (seal analgica) y finalmente, a travs de un proceso
electrnico de conversin, obtener una seal o secuencia de informacin digital
procesable por software. A continuacin tratamos el proceso de conversin de analgico
a digital.
1.5.1.1 Teorema de Nyquist
Para obtener muestras de una seal de entrada analgica se utiliza el teorema de
Nyquist-Shannon, el cual postula que la frecuencia de muestreo debe ser dos veces
superior a la frecuencia mxima de la seal a muestrear.
Frecuencia muestreo = 2 x Frecuencia mxima seal analgica de entrada
En la siguiente figura se puede observar el proceso de muestreo:

Figura 1.29 Seal analgica muestreada


En la prctica se suele elegir una frecuencia de muestreo ligeramente superior a
la frecuencia mxima de la seal analgica. As por ejemplo, si queremos representar
una seal con una frecuencia 20000 Hz con calidad de CD tendremos que capturar la
seal con una frecuencia de muestreo de 44100 Hz o 44,1 Khz.

1.5.1.2 Proceso de conversin


Para poder realizar la conversin analgico digital se hace preciso la utilizacin
de un tipo de circuito especial llamado ADC (Analog-to-Digital Converter o Conversor
Analgico Digital). Dicho circuito realiza los siguientes procesos:
Muestreo de la seal analgica:
El primer paso para convertir una seal analgica en digital es muestrearla
(sampling), es decir, tomar valores sucesivos de la amplitud de la seal a intervalos
regulares de tiempo. Con este proceso la seal continua pasa a ser discreta en el tiempo,
si bien no en amplitud. Como hemos explicado anteriormente estas muestras son

34

C A P T U L O 1 Teora del sonido


tomadas con una frecuencia determinada a la que se denomina frecuencia de muestreo y
por lo tanto a mayor frecuencia de muestreo mayor calidad y fidelidad tendr la seal
digital resultante.
Durante el proceso de muestreo se asignan valores numricos equivalentes a la tensin
la amplitud de la seal, con la finalidad de realizar a continuacin el proceso de
cuantizacin.

Voltios

8
7
6
5
4
3
2
1
0
Tiempo

Figura 1.30 Principio bsico del muestreo


Cuanto mayor sea el nmero de muestras tomadas, mayor ser tambin el ancho
de banda necesario para transmitir una seal digital, requiriendo tambin un espacio
mucho mayor para almacenarla en un CD o un DVD.
Cuantizacin:
Posteriormente al proceso de muestreo se realiza el proceso de cuantizacin de
la seal analgica de entrada.
Para conseguir este propsito, los valores continuos de seal se convierten en una
secuencia de valores numricos decimales discretos que corresponden a los diferentes
niveles de voltaje de la seal de entrada.

Voltios

8
7
6
5
4
3
2
1
0
Tiempo

Figura 1.31 Cuantizacin de amplitud

35

C A P T U L O 1 Teora del sonido


Codificacin
La codificacin permite asignarle valores numricos binarios equivalentes a los
valores de tensiones o voltajes que conforman la seal elctrica analgica original,
como puede verse en la siguiente figura:

Voltios

8
7
6
5
4
3
2
1
0

Tiempo
001 010 001 011 010 100 101 100 101 011

Figura 1.32 Codificacin de las muestras (PCM)


En el proceso de codificacin es importante saber cuntos bits asignamos a esos
valores de amplitud de la seal muestreada y cuantificada. As si utilizamos valores de n
bits para representar la seal podremos codificar un total 2n 1 valores de amplitud
diferentes. Por ejemplo, en un byte (8 bits) podemos representar un total de 28 1 = 256
-1 valores diferentes de amplitud, el problema es que la calidad del sonido no ser tan
aceptable. Por esto, en la mayora de las aplicaciones reales se utiliza un tamao de
palabra de 16 bits, pudiendo por lo tanto representar un total de 216 1 = 65536 1
valores diferentes, obteniendo una seal resultante de mayor calidad. En la siguiente
tabla se muestra una relacin de formatos de frecuencias de muestreo y bits para
representar los formatos de sonido ms conocidos:
Tipo formato
Frecuencia muestreo
Resolucin
Calidad CD
44100Hz
16bits
Calidad Radio
22Khz
8bits
Calidad telfono
11Khz
8bits
Tabla 1.4 Niveles de muestreo segn la calidad y ancho de banda
Dentro del proceso de codificacin podemos considerar diferentes tipos de formato,
entre ellos destacan:
PCM
El formato PCM (en ingls Pulse Code Modulation) es un formato o
procedimiento de modulacin para transformar la seal analgica muestreada y
cuantificada en una formato de bits. Este formato es ampliamente utilizado, as podemos
verlo aplicado a los telfonos digitales, el audio digital en ordenadores (ampliamente
tratado en este estudio) y el formato Red Book de los CD de audio.

36

C A P T U L O 1 Teora del sonido


PAM
El formato PAM o modulacin por amplitud de pulsos (Pulse AmplitudModulation) es la ms sencilla de las modulaciones digitales. Consiste en cambiar la
amplitud de la seal (de frecuencia fija) en funcin del smbolo a transmitir.
Dichas amplitudes pueden ser reales o complejas. Si representamos las
amplitudes en el plano complejo tenemos lo que se llaman constelaciones de seal. En
funcin del nmero de smbolos o amplitudes posibles se llama a la modulacin NPAM. As podemos tener 2PAM, 4PAM, 260PAM. De la correcta eleccin de los
puntos de la constelacin (amplitudes) depende la inmunidad a ruido (distancia entre
puntos).

Figura 1.33 Diferentes formatos de codificacin

1.5.1.3 El problema del aliasing


Un riesgo que puede existir durante la conversin analgico-digital es el
aliasing, que se produce cuando la seal que se muestrea tiene componentes de
frecuencia por encima de fs/2 o frecuencia de Nyquist.
Para evitar este problema se utiliza un filtro paso-bajo, que elimina todas las frecuencias
que estn por encima de fs/2. En la prctica como los filtros no son perfectos hay que
intentar que la frecuencia de Nyquist est un poco por encima de la mxima frecuencia
que se desea muestrear.
La consecuencia del aliasing es que las frecuencias que estn por encima de la
frecuencia de Nyquist aparecen desplazadas en frecuencia dentro del espectro
muestreado, como se muestra en la figura 1.34.

37

C A P T U L O 1 Teora del sonido

Figura 1.34 Efecto del aliasing

1.5.2 Conversin digital / analgico


El objeto de este tipo de convertidor es transformar una seal discreta en tiempo
y frecuencia en una seal continua, en otras palabras, convertir una secuencia de
cdigos binarios en una seal elctrica analgica.
Como se vio en la seccin anterior, la representacin espectral de una seal
muestreada es un conjunto de rplicas del espectro de la seal original, que se repiten en
mltiplos de la frecuencia de muestreo. Al convertir la seal del dominio digital al
analgico, estas rplicas aparecern a menos que se disponga un filtro paso bajo a la
salida del conversor D/A. Este filtro paso bajo es necesariamente analgico y puede
resultar caro y complicado si la frecuencia mxima de la seal est muy cerca de la
frecuencia de Nyquist.
Sin embargo existen tcnicas digitales que simplifican la reconstruccin de la
seal y el diseo de dicho filtro, a cambio de una mayor complejidad en la parte digital.
La tcnica ms comnmente utilizada en los conversores D/A de audio y vdeo
es el oversampling. Esta tcnica consiste en aumentar la frecuencia de muestreo de la
seal, manteniendo intacta la representacin espectral. Como consecuencia, la
frecuencia mxima de la seal se aleja de la frecuencia de Nyquist, permitiendo el uso
de filtros analgicos ms sencillos.
Para aumentar la frecuencia de muestreo de la seal se ha de interpolar con
muestras de valor cero. Un filtro interpolador digital transforma estas muestras nulas en
valores intermedios entre las muestras originales.
A pesar del aumento de complejidad en el dominio digital, el resultado merece la
pena desde un punto de vista prctico, pues el rea de silicio ocupada por el filtro digital
es mucho menor que el espacio de un filtro analgico de orden elevado, con la ventaja

38

C A P T U L O 1 Teora del sonido


adicional de que el filtrado digital no est sujeto a las tolerancias de los componentes
analgicos.
filtro analgico
banda imagen

fs/2

fs

interpolacin

t
filtrado digital

filtro analgico
banda imagen

fs/2

fs

Figura 1.35 Comparacin entre la conversin D/A bsica (arriba) y la conversin con
oversampling (abajo)
El desarrollo del oversampling ha evolucionado paralelamente al de los
convertidores D/A sigma-delta, tambin conocidos como one bit stream. Estos
convertidores no reconstruyen la seal analgica desde cero para cada muestra, sino que
suman o restan la diferencia necesaria para que la seal alcance el nivel deseado. Esta
diferencia se muestrea con un nico bit de resolucin, de ah el nombre one bit stream.
Esta simplificacin se compensa con una mayor frecuencia de muestreo, pues
para poder reproducir grandes variaciones de la seal en saltos de 1 LSB se requiere que
su valor se actualice mucho ms rpido que la frecuencia original de muestreo. Sin
embargo las etapas analgicas del convertidor D/A son ms sencillas, lo cual reduce su
consumo.

39

C A P T U L O 1 Teora del sonido

Bibliografa y referencias
Libros
Fsica COU A.Candel, J.Satoca, J.B. Soler, F.Tejerina, J.J. Tent. Editorial Anaya,
1990.
Apuntes Redes 3 IT Informtica de Sistemas Universidad de Murcia, 1997.
Tcnicas de Grabacin modernas David Miles Huber, Robert E. Runstein, 6 edicin.
Editorial Omega, 2007.
Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y Vdeo Manuel-Alonso
Castro Gil, Antonio Colmenar Santos, Pablo Losada de Dios, Juan Peire Arroba.
Editorial Ra-ma, 2002.
Tecnologa Bsica del Sonido I Ignasi Cuenca David, Eduard Gmez Juan. Editorial
Paraninfo, 2006.
La Web
Wikipedia:
Concepto de sonido:
http://es.wikipedia.org/wiki/Cualidades_del_sonido
Funcionamiento del odo:
http://es.wikipedia.org/wiki/O%C3%ADdo
Otros URL:
The Physic of Instruments
http://www.mrfizzix.com/instruments/
Sistema auditivo humano:
http://www.ehu.es/acustica/espanol/fisiologia1/siaues/siaues.html
Sntesis analgica musical:
http://sam.atlantes.org/ Avelino Herrera Morales
Tcnicas de sntesis digital:
http://en.wikipedia.org/wiki/Frequency_modulation_synthesis
http://es.wikipedia.org/wiki/S%C3%ADntesis_mediante_tabla_de_ondas
40

C A P T U L O 1 Teora del sonido

http://es.wikipedia.org/wiki/Octava
http://www.analog.com/en/content/0,2886,761%255F795%255F91588%255F0,00.html

Lista de figuras obtenidas de Internet


Figura 1.10
Figura 1.28

http://www.virtins.com
http://www.renoise.com/

41

Parte II

Programacin

C A P T U L O 2 DirectX y la API DirectSound

DirectX y la API DirectSound

2.1 Qu es DirectX?
2.1.1 Introduccin
En los inicios del desarrollo de aplicaciones multimedia en Windows era muy difcil
poder escribir cdigo eficiente que pudiera controlar con xito los efectos de vdeo y
audio en este sistema operativo. Aunque el objetivo de Windows era aislar al
programador del hardware, lo cual era origen de numerosas dificultades de operatividad
en sistemas MS-DOS, sin embargo este aislamiento no gust al principio a los
desarrolladores multimedia pues seguan con el hbito de trabajar directamente con el
hardware para poder as sacar el mximo rendimiento a las aplicaciones.
Paulatinamente, fueron aceptndose las dificultades que implicaba programar
aplicaciones en MS-DOS: falta de uniformidad en la plataforma, imposibilidad para
manejar una gama amplia de dispositivos hardware de entrada/salida multimedia,
dificultad para acceder al conocimiento especfico de cada arquitectura, hardware y
recursos software, sistema operativo mono-usurario y mono-tarea, etc.
DirectX ha permitido abrir la puerta a las funciones de Windows (sin pedir al
programador que sacrifique el rendimiento) y poder abstraer de esta manera la
complejidad del acceso al hardware. El objetivo de los creadores de DirectX era hacer la
plataforma Windows un entorno atractivo para programar aplicaciones multimedia. As,
desde la aparicin de esta tecnologa han surgido juegos con movimientos suaves,
animaciones cristalinas y sonido de alta calidad.
Los desarrolladores consiguieron una nueva plataforma muy rica, de gran rendimiento y
con gran operatividad; y los fabricantes de hardware dispondran de un mercado ms
amplio para sus productos. Se haba conseguido al fin la independencia del dispositivo
que facilita el desarrollo de aplicaciones multimedia a gran escala.
DirectX consta de unas libreras en cdigo binario que abstraen las funciones de acceso
al hardware y al mismo tiempo consigue un alto rendimiento. Se distribuye como un
programa que se instala junto a las libreras del sistema y se proporciona adicionalmente
y dirigido a profesionales del sector del desarrollo multimedia un SDK (Software
Development Kit) que incluye las libreras estticas y cdigo fuente para poder crear
aplicaciones DirectX. La versin actual de DirectX es la 11 que est disponible
solamente para Windows Vista y Windows 7.

45

C A P T U L O 2 DirectX y la API DirectSound


2.1.2 Filosofa de DirectX
Los diseadores de DirectX se plantearon los siguientes objetivos:

Rapidez
Disminuir la latencia
Ser humilde

Rapidez: Este es el objetivo ms importante de todos. En primer lugar DirectX debe


ser muy rpido y por lo tanto se debe utilizar la asistencia hardware en todo momento y
slo en casos de su ausencia utilizar la emulacin por software.
Disminuir la latencia: El sistema operativo Windows permite la abstraccin de casi
todas las funciones. Normalmente, dicha abstraccin representa un beneficio que libera
al creador de software de los detalles especficos del entorno sobre el que se ejecuta la
aplicacin. Pero tambin, puede implicar un retardo al solicitar un servicio. Este retardo
se le denomina latencia y debe ser disminuida al mximo.
Ser humilde: Al desarrollar un librera software se intenta transmitir una idea
personal de cmo hacer las cosas, no obstante, los estndares pueden facilitar las cosas
considerablemente. El objetivo del diseo de DirectX es que fuera ampliamente
aceptado y no irrumpir en las partes ms importantes del diseo de la aplicacin o en el
proceso de ingeniera del software.
2.1.3 Arquitectura de DirectX
La arquitectura est basada en un equipo de controladores: dos controladores, la
capa de abstraccin del hardware (HAL) y la capa de emulacin de hardware (HEL)
colaboran para ejecutar las peticiones de servicio realizadas por DirectX. Cuando se
crea un objeto DirectX para un determinado dispositivo, DirectX consulta el hardware
para una determinada posibilidad (por ejemplo, un coprocesador grfico que puede
realizar operaciones de escalado) y ste utilizar el hardware que proporcione dicha
funcin. Cuando no haya asistencia de hardware se recurrir a la capa HEL.
En la figura 2.1 puede verse dicha distribucin:

DirectX

HAL

HEL

Hardware

Figura 2.1 Arquitectura HAL/HEL de DirectX

46

C A P T U L O 2 DirectX y la API DirectSound


2.1.4 Componentes de DirectX
Los diferentes componentes de DirectX se ofrecen al programador a travs de
diferentes APIs (Application program interface). La versin 9 de DirectX (utilizada en
este estudio) consta de los siguientes componentes:

DirectDraw: permite la animacin suave de sprites y grficos usando


intercambio de pginas de vdeo, acceso a coprocesadores grficos
especializados (GPUs) y administracin de memoria de vdeo. Sirve de base
para otros componentes como Direct3D y DirectShow.

Direct3D: proporciona funciones 3D en tiempo real utilizando el hardware de la


GPU.

DirectSound: tratado en este captulo. Proporciona sonido estreo y 3D con


mezcla de sonido por hardware as como administracin de la memoria de la
tarjeta de sonido.

DirectMusic: proporciona funciones de alto nivel para manejar funciones MIDI


con baja latencia y una mayor abstraccin de los objetos de sonido. Este
componente utiliza las funciones de DirectSound.

DirectShow: facilita el desarrollo de aplicaciones de vdeo con uso de filtros y


codecs de compresin de audio y vdeo.

DirectPlay: incluye servicios transparentes de mensajera independientes del


medio para crear juegos en red local (LAN) e Internet, de forma que puedan
cooperar diferentes jugadores.

DirectInput: proporciona entrada de baja latencia desde una amplia variedad de


dispositivos de entrada y permite el funcionamiento de dispositivos de salida,
incluyendo perifricos activos de juego (joysticks, volantes, etc) .

2.1.5 Programacin en DirectX


Para programar en DirectX podemos utilizar cualquier lenguaje existente en
plataforma Windows: Visual Basic, C# y Visual C++. En este estudio abordaremos el
desarrollo de aplicaciones en DirectSound utilizando este ltimo.
Para el correcto funcionamiento de las aplicaciones en DirectX es fundamental conocer
a fondo la API de Windows (API Win32), es decir, es necesario para el programador
tener conocimientos consistentes sobre los entresijos de la programacin en este sistema
operativo comercial. En caso de que el lector no posea estos conocimientos, se le remite
a la lectura del libro de Programacin para Windows 95 de Charles Petzold.
Es fundamental para poder programar con DirectX tener una ligera nocin sobre la
tecnologa COM (Modelo de objetos componentes) ya que es la base de la filosofa
DirectX y, como consecuencia, ser explicado en el siguiente apartado.

47

C A P T U L O 2 DirectX y la API DirectSound


2.1.6 Tecnologa COM
La tecnologa COM es ampliamente utilizada en Windows, de hecho, es un estndar
creado por Microsoft, que junto con el middleware DCOM forma la base para la
tecnologa de objetos distribuidos.
COM es un modelo binario que puede ser utilizado independientemente de los lenguajes
de programacin que puedan soportarlo. CORBA y Java RMI son otros de los modelos
que compiten con COM.
Un componente es un objeto que incluye unas caractersticas mnimas, para que puedan
ser utilizados tanto en un programa como en la etapa de diseo del mismo. Los
componentes COM pueden utilizarse en mltiples lenguajes, de ah que estn ms
extendidos. Adems, las distintas partes del propio sistema operativo estn realizadas
con COM. La dificultad de esta tecnologa estriba en la complejidad para su desarrollo.
El origen de COM est en Microsoft, en sus primeros sistemas operativos, pues
encontraron el problema de insertar grficos de unas aplicaciones en otras. En 1991
desarrollaron un protocolo mediante el cual en un documento podran insertarse objetos
mantenidos por programas distintos en los que se estaba editando. El protocolo se
llamaba OLE 1.0 y se basaba en el paso de mensajes y el uso de memoria global
compartida. El resultado fue realmente malo, no slo por la fragilidad del sistema (con
la cada de una de las aplicaciones caa el sistema), sino por la complejidad de la
realizacin de componentes para los programadores.
La siguiente versin de OLE (llamada COM) se rescribi desde cero por Microsoft y
DEC en un principio. Al final DEC abandon el proyecto y Microsoft continu con l.
Las nuevas versiones que realiz Microsoft ampliaron el modelo para poder usar los
componentes desde distintos ordenadores ( DCOM o Distributed COM ).
El objetivo de la tecnologa COM es utilizar la programacin orientada a objetos
que posteriormente se encontrarn a nivel de programas binarios y que por lo tanto, para
poder usarlos no es necesario tener su cdigo fuente, lo que fomenta la transparencia y
la abstraccin.
Se pueden utilizar las libreras de enlace dinmico o DLLs para albergar estos
componentes.
La caracterstica de un objeto COM es que puede ejecutarse fuera del mbito de un
proceso, es decir, puede estar en ejecucin en otros procesos de la misma mquina o de
otra mquina diferente.
El modelo COM sigue la arquitectura cliente/servidor. El objeto COM en s es el
servidor, y es usado por un programa que hace de cliente. Existen varias formas de
realizar la comunicacin. Podemos encontrar un componente COM como parte de un
ejecutable, o en una DLL o incluso en otra mquina (DCOM).
Los servidores COM pueden ser escritos en variedad de lenguajes y en sistemas
operativos distintos, mientras que, por ejemplo, los objetos escritos en C++ son siempre
para C++.
Es normal que un servidor tenga varios objetos COM, aunque se presenta un problema a
la hora de identificar qu componente se quiere usar cuando reside en un lugar distinto
al cliente. La forma de conseguir la unicidad del objeto COM es con una secuencia de
128 bits que lo identifique unvocamente y que la probabilidad de conflicto sea
prcticamente nula. Esta secuencia se llama GUID (Identificador nico global). Los
GUIDs utilizados para identificar objetos COM se denominan CLSID (Identificador de
clase).

48

C A P T U L O 2 DirectX y la API DirectSound


La programacin en COM est bsicamente orientada a objetos. Pero en este punto
es necesario definir la nocin de Interfaz. As, para COM una interfaz es un conjunto de
declaraciones de funciones que puede o no implementar un objeto. La definicin de
Interfaz es: conjunto de funciones que se ponen a disposicin del pblico. Suelen tener
relacin entre s. Las interfaces tambin tienen un GUID (denominado IID, o
identificador de interfaz ). Un mismo objeto implementa normalmente varias interfaces.
En la siguiente figura se puede observar un ejemplo de objeto COM.
CLSID_IObjeto1

Objeto1
Interfaz1

Interfaz2

- metodo1

- metodo1

- metodo2

- metodo2

- metodo3

- metodo3

IID_IInterfaz1

IID_IInterfaz2

Figura 2.2 Objeto COM

Uno de los componentes principales de modelo COM son las interfaces, que,
aunque este concepto no existe en programacin C++, s existe en otros lenguajes como
Java. Las interfaces en C++ se implementan como clases abstractas. Toda interfaz en
COM deriva de la interfaz IUnknown. Por lo tanto, una interfaz es una clase que
contiene un conjunto de punteros a funciones que se encuentran en la tabla de mtodos
virtuales VMT que genera el compilador.
El cliente de un objeto COM no acceder directamente al objeto, sino que lo har a
travs de sus interfaces. Lo nico que poseer el cliente ser un puntero a la interfaz que
implementar los mtodos que llevan a cabo la lgica de negocio.
Interfaz IUnknown: Como se ha mencionado anteriormente todas las interfaces
derivan de IUnknown. Si nos fijamos en el grfico 2.3, podemos observar que para
acceder al resto de las interfaces se entra por la interfaz de arriba:

49

C A P T U L O 2 DirectX y la API DirectSound

IUnknown

Interfaz 2
Objeto COM
Interfaz 3
Figura 2.3

Se utiliza un lenguaje independiente de otros lenguajes de programacin y de la


plataforma llamado IDL (Interface Definition Language) para definir las interfaces y sus
argumentos. A partir de este lenguaje sera posible obtener las declaraciones en distintos
lenguajes de programacin para que puedan ser usadas. Por consiguiente, la interfaz
IUnknown quedara representada en IDL de la siguiente manera:
[ local, object
huid(00000000-0000-0000-C000-000000000046)
pointer_default(unique)
]
interface IUnknown
{
HRESULT QueryInterface (
[in]REFIID riid,
[out,iid_is(riid)] void **ppvObject);
ULONG AddRef();
ULONG Release();
}

En la definicin de la intefaz IUnknown podemos apreciar tres mtodos especiales:


1. QueryInterface(): Este mtodo se utiliza para la invocacin de interfaces, es
decir, el objeto COM se puede ver como una caja negra que encapsula un
conjunto de interfaces y mtodos. Para acceder a la implementacin de una
determinada interfaz recurriremos a la utilizacin de este mtodo, que nos
devolver un puntero a dicha interfaz. Su funcionamiento es siempre similar: el
primero es el IID que el identificador de interfaz que se quiere invocar, y el
segundo parmetro un doble puntero void a esa interfaz. Por ejemplo:

50

C A P T U L O 2 DirectX y la API DirectSound


CoCreateInstante(CLSID_Objeto1, NULL, CLSCTX_ALL,
IID_IUnknown, (void **)&Interfaz1);
Interfaz1->QueryInterface(IID_Interfaz2, (void **)
&Interfaz2);
2. AddRef() y Release(): Permiten controlar el ciclo de vida del objeto COM,
incrementando o disminuyendo el contador de referencias a dicho objeto, de
forma que cuando el contador de referencias llegue a cero se liberar el objeto de
la memoria.

51

C A P T U L O 2 DirectX y la API DirectSound

2.2 Programacin en DirectSound1


2.2.1 Introduccin
DirectSound proporciona las dos caractersticas requeridas por los desarrolladores
de aplicaciones de sonido profesionales: velocidad y control. Entre sus caractersticas
principales destacan:

Uso automtico de aceleracin por hardware cuando se encuentra disponible.


Mezcla ilimitada de sonidos.
Reproduccin de baja latencia.
Efectos de sonido con posicionamiento 3D fcilmente integrables en
aplicaciones Direct3D u OpenGL.
Conversin automtica de los formatos de onda de entrada (incluso de varios
formatos) para que concuerden con el formato de salida.
Acceso a las funcionalidades de la tarjeta de sonido sin acceder al hardware, a
travs de la API.

2.2.2 Arquitectura de DirectSound


La estructura de base de la arquitectura DirectSound reside en la utilizacin de
buffers secundarios de sonido, que representan un nico sonido, ya sea esttico (sonidos
cortos fcilmente almacenables en bloques de memoria) o canalizados (los datos de
audio se transfieren en bloques al dispositivo de salida).
Un aspecto fundamental en la programacin en DirectSound es que el tipo de datos de
forma de onda almacenados en los buffers ser, en todo caso, formato PCM.
Apoyndose en los buffers primarios, DirectSound mezcla los sonidos almacenados en
sus respectivos buffers secundarios a alta velocidad. Adems realiza otras operaciones
adicionales como conversiones de formato (por ejemplo, cambios de frecuencia de
muestreo de 44 a 22 kHz) y aplicacin de efectos especiales, como posicionamiento 3D
del sonido o efectos de Echo, Delay o Chorus. Finalmente, desde el buffer primario los
datos se envan al dispositivo de salida.
DirectSound coloca de manera automtica tantos buffers como le es posible en la
memoria del hardware siempre que buffers y funciones de mezcla estn disponibles por
hardware. Si no, DirectSound mezcla por software los buffers que residen en la
memoria y los canaliza hacia el mezclador por hardware junto con los sonidos
procedentes de los buffers por hardware. El proceso se ilustra en la figura 2.4:

En este captulo se utilizar el compilador Microsoft Visual C++ 2005.

52

C A P T U L O 2 DirectX y la API DirectSound


Buffers por software
Mezclador por software

Buffer primario
Dispositivo
Buffers por hardware (si
disponibles)

Mezclador por hardware (si


disponible)

Figura 2.4 Arquitectura DirectSound

2.2.3 Formato de sonido soportado por DirectSound


El formato de sonido de una forma de onda en DirectSound debe tener las siguientes
caractersticas:

El nmero de canales (1 = mono, 2 = estreo, etc.)


La frecuencia de muestreo (en Hertzios). El formato depende de la frecuencia y
del nmero de canales, por lo que para el sonido estreo habr el doble de
muestras por cada segundo de sonido. Las muestras de sonido estreo estn
intercaladas, yendo en primer lugar el canal izquierdo. Las frecuencias de
muestreo que admite el hardware de los PC son 11.025, 22.050 y 22.100 Hz.
La resolucin de la muestra en nmero de bits: 8 16.
El tag de formato, que identifica cmo deben interpretarse los datos de las
muestras. En DirectSound deben ajustarse al tag WAVE_FORMAT_PCM.

La informacin del formato se contiene en


WAVEFORMATEX, que tiene la siguiente composicin:
Campo
WORD wFormatTag
WORD nChannels
DWORD nSamplesPerSec
DWORD nAvgBytesPerSec
WORD nBlockAlign

una

estructura

de

tipo

Descripcin
Tipo de formato. Debe ser
WAVE_FORMAT_PCM
Nmero de canales 1(mono), 2 (estreo)
Frecuencia de muestreo(en hertzios):
Normalmente 11.025, 22.050, 44.100
Velocidad media de transferencia
(nSamplesPerSec * nBlockAlign)
Bytes por muestra (nChannels *
nBitsPerSample / 8)

53

C A P T U L O 2 DirectX y la API DirectSound


WORD wBitsPerSample
WORD cbSize

Nmero de bits por muestra (8 16)


Nmero de bytes de informacin
adicional: para propsito del usuario.
Siempre es 0
Tabla 2.1

2.2.4 Creacin del objeto DirectSound


Para la creacin del objeto DirectSound podemos
DirectSoundCreate que se describe en la siguiente tabla:
Parmetro
LPGUID lpGUID
LPDIRECTSOUND *ppDS
LPUNKNOWN pUnkOuter

utilizar

la funcin

Descripcin
Puntero al GUID del dispositivo, o NULL
para el dispositivo por defecto
Direccin del puntero que se iniciar
mediante la llamada
Debe ser NULL
Tabla 2.2

No obstante, antes de crear el objeto DirectSound se precisa iniciar la librera de


COM mediante la llamada a la funcin Win32 CoInitialize(NULL):
#include "stdafx.h"
#include
#include
#include
#include
#include
#include
#include

<windows.h>
<mmsystem.h>
<dsound.h>
<SDKsound.h>
<math.h>
<string>
<sstream>

#include "directsound.h"
int _tmain(int argc, _TCHAR* argv[])
{
// Inicializa COM
CoInitialize(NULL);
IDirectSound8* pDS = NULL;
HRESULT
hr;
const LPCWSTR tituloVentana = (LPCWSTR) L"Directsound - Captulo
2";
SetConsoleTitle(tituloVentana);
// Crea IDirectSound a partir del dispositivo primario
if( FAILED( hr = DirectSoundCreate8( NULL, &pDS, NULL ) ) )
printf("Error al crear DirectSound (codigo numero=%d)\n",hr);

54

C A P T U L O 2 DirectX y la API DirectSound


En las primeras lneas se incluyen los ficheros cabecera bsicos para poder acceder a
las definiciones de las funciones y clases.
Despus del punto de entrada main(), iniciamos COM y establecemos un ttulo para
la ventana de consola de aplicacin Win32. Finalmente se invoca una referencia a la
interfaz COM IDirectSound8 con el dispositivo de sonido por defecto.
Para manejar informacin sobre errores en DirectX se utiliza con frecuencia una
variable del tipo HRESULT que contiene un cdigo de estado con respecto a la llamada
a la funcin COM, que puede luego verificarse con las macros FAILED (para detectar
algn error en la llamada) y SUCCEEDED (la funcin devolvi S_OK y funcion
correctamente).
2.2.5 Establecer el nivel cooperativo
Posteriormente a la creacin del objeto DirectSound necesitamos establecer el nivel
cooperativo mediante la llamada SetCooperativeLevel. Esta funcin tiene el efecto de
asociar DirectSound a una ventana y determinar cmo su aplicacin va a compartir con
otros el dispositivo de sonido.
El prototipo de la funcin es:
HRESULT IDirectSound::SetCooperativeLevel(HWND hwnd, DWORD dwLevel)
El primer parmetro es un handle de ventana y si todas las ventanas hijas de la
aplicacin derivan de la misma ventana principal, se debera pasar el handle de la
ventana de nivel superior a dichos mtodos. El segundo parmetro permite fijar el valor
del nivel cooperativo como se muestra en la tabla 2.3 en orden ascendente de prioridad:
dwLevel
DDSCL_NORMAL

Ventajas
Mejor cooperacin con
otras aplicaciones.

DDSCL_PRIORITY

Permite modificar el
formato primario.

DDSCL_EXCLUSIVE

Garantiza el uso exclusivo


del dispositivo, por lo que
las aplicaciones de fondo
permanecen mudas.
DDSCL_WRITEPRIMARY Garantiza el acceso al
buffer primario para
realizar una mezcla
personalizada.

Desventajas
No se puede modificar el
formato primario, por lo
que se est restringiendo al
formato de salida por
defecto de DirectSound.
Podra terminar
modificando la salida de
otra aplicacin.
Podra no ser apropiado
silenciar todas las
aplicaciones de fondo.
Requiere un controlador de
DirectSound; no se pueden
reproducir buffers
secundarios; las
aplicaciones restantes
pierden sus buffers.

Tabla 2.3

55

C A P T U L O 2 DirectX y la API DirectSound


Casi todas las aplicaciones utilizan un nivel cooperativo DDSCL_NORMAL o
DDSCL_PRIORITY. El nivel DDSCL_WRITEPRIMARY slo es necesario para
aplicaciones altamente especializadas que necesitan realizar sus propias operaciones de
mezclado.
En el fragmento de cdigo del ejemplo se muestra el funcionamiento de esta funcin:
// Establece el nivel cooperativo de DirectSound
if (FAILED( hr = pDS>SetCooperativeLevel(FindWindow(NULL,tituloVentana),DSSCL_PRIORITY) )
)
printf("Error en la funcion SetCooperativeLevel (codigo
numero %d)\n", hr );

2.2.6 Crear el buffer primario


Por defecto el buffer primario tiene una frecuencia de 22.050 Hz, 2 canales y 8 bits
por muestra. En el buffer primario es donde se mezclan todos los sonidos, con
independencia de sus formatos antes de reproducirse.
En el ejemplo se ha establecido un formato primario de 16 bits, estreo y 44.100 Hz;
obviamente, DirectSound canalizar los datos al buffer primario con ms rapidez si no
tiene que convertirlos.
Es significativo advertir que DirectSound est optimizado para trabajar con muestras
de 16 bits, y no se produce prdida alguna de rendimiento por cambiar el formato del
buffer primario a uno de 16 bits.
En el cdigo del ejemplo siguiente se muestra cmo obtener un buffer primario:
// Crea el buffer primario
LPDIRECTSOUNDBUFFER pDSBPrimary = NULL;
// Obtiene el buffer primario
DSBUFFERDESC dsbd;
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize
= sizeof(DSBUFFERDESC);
dsbd.dwFlags
= DSBCAPS_PRIMARYBUFFER ;
dsbd.dwBufferBytes = 0;
dsbd.lpwfxFormat
= NULL;
if( FAILED( hr = pDS->CreateSoundBuffer( &dsbd, &pDSBPrimary, NULL
) ) )
printf("Error al crear el buffer primario (codigo error =
%d)", hr );
// Establece el formato del buffer primario
WAVEFORMATEX wfx;
ZeroMemory( &wfx, sizeof(WAVEFORMATEX) );
wfx.wFormatTag
= (WORD) WAVE_FORMAT_PCM;
wfx.nChannels
= 2;
wfx.nSamplesPerSec = 44100;
wfx.wBitsPerSample = 16;
wfx.nBlockAlign
= (WORD) (wfx.wBitsPerSample / 8 *
wfx.nChannels);
wfx.nAvgBytesPerSec = (DWORD) (wfx.nSamplesPerSec *
wfx.nBlockAlign);

56

C A P T U L O 2 DirectX y la API DirectSound


if( FAILED( hr = pDSBPrimary->SetFormat(&wfx) ) )
printf("Error al poner formato al buffer primario (codigo
error =%d)", hr );

2.2.7 Introduccin a los buffers secundarios


El objeto bsico del sonido es el buffer y se representa mediante la interfaz
IDirectSoundBuffer. Los buffers secundarios son circulares. Si un buffer se est
reproduciendo de manera continua, tan pronto como DirectSound llega al final vuelve
de nuevo al principio. Si se estn canalizando datos hacia el buffer, es responsabilidad
del programador enlazar los datos de esta forma.
DirectSound mantiene un par de punteros por cada buffer de sonido: la posicin actual
de reproduccin y la posicin actual de escritura. La ms necesaria es la posicin actual
de reproduccin, o cursor de reproduccin, que es el desplazamiento del siguiente byte
de datos que se va a enviar al mezclador. Respecto a la posicin actual de escritura,
DirectSound no est escribiendo en dicha posicin y, en muchos casos, ni siquiera lo
hace la aplicacin. Lo que en realidad representa la posicin de escritura es el primer
punto del buffer, ms all de la posicin de reproduccin, en el que es seguro escribir.
Los diferentes tipos de buffers secundarios se dividen en estticos y canalizados. Un
buffer secundario esttico es aquel que se usar para un nico sonido corto que se
emplee con frecuencia. Un buffer canalizado est destinado a un sonido que no cabra
en un buffer de un tamao razonable y del que se debe copiar una parte determinada a
medida que se reproduce. La nica diferencia entre estos dos tipos de buffers estriba en
la optimizacin. Se pueden canalizar datos hacia un buffer esttico o usar un buffer
canalizado para un sonido esttico, pero ninguno de ellos funcionara a la perfeccin.
Por lo tanto, mediante el uso de las constantes de la API: DSBCAPS_STATIC,
DSBCAPS_LOCHARDWARE y DSBCASP_LOCSOFTWARE se pueden definir las
diferentes combinaciones de tipos de buffers.
2.2.8 Pasos para crear los buffers secundarios
Los pasos implicados en la creacin de buffers secundarios son los siguientes:
1. Iniciar una estructura del tipo WAVEFORMATEX que describa el formato del
sonido.
2. Iniciar una estructura del tipo DSBUFFERDESC con los parmetros del buffer,
incluyendo un puntero a su estructura WAVEFORMATEX.
3. Llamar al mtodo CreateSoundBuffer para crear el buffer.
4. Bloquear el buffer, entero o slo una parte.
5. Copiar datos al buffer(normalmente provenientes de un fichero de audio o
generados con una funcin matemtica).
6. Desbloquear el buffer.
7. Fijar la posicin de reproduccin.
8. Reproducir el buffer.
9. Si se trata de un buffer canalizado, repetir los pasos 4, 5 y 6.

57

C A P T U L O 2 DirectX y la API DirectSound


2.2.9 Archivos de sonido
Para trabajar con sonidos en DirectSound es necesario recurrir a alguna fuente de
sonido almacenado en formato PCM en memoria secundaria. Este es el caso de los
ficheros WAV (originarios de Microsoft) y muy utilizados en Windows. Estos archivos
estn en formato RIFF (Resource Interchange File Format), formato que almacena
cabeceras y datos en bloques de longitud variable que siempre comienzan con un cdigo
de cuatro letras, por ejemplo: wave o data. Los archivos de onda incluyen un bloque
fmt que se corresponde con una estructura del tipo WAVEFORMATEX. El bloque
data, dando por su puesto que el formato es PCM, es tan slo una coleccin de
muestra de 8 16 bits.
En el ejemplo que se incluye con el estudio se ha recurrido a la clase CWaveFile
definida en el fichero del SDK de DirectX como SDKSound.cpp y SDKSound.h que
deben de incluirse en el proyecto para poder trabajar con ficheros WAV.
2.2.10 Describir el buffer
Para describir el buffer se utiliza la estructura DSBUFFERDESC que
inicializaremos con algunos de los siguientes flags:
Flag
DBSCAPS_CTRL3D

Notas
Se utiliza para posicionamiento en 3D del
sonido, si y slo si se crea una interfaz
IDirectSound3DBuffer. No puede
combinarse con DSBCAPS_CTRLPAN
DSBCAPS_CTRLALL
Establece todos los controles
DSBCAPS_CTRLDEFAULT
Establece controles por defecto
DSBCAPS_CTRLFREQUENCY
Cambia la frecuencia de reproduccin
DSBCAPS_CTRLPAN
Cambia el pan (balance)
DSBCAPS_POSITIONNOTIFY
Informa o notifica sobre el
posicionamiento
DSBCAPS_CTRLVOLUME
El buffer va a sufrir cambios de volumen
DSBCAPS_LOCHARDWARE
Buffer canalizado por hardware
DSBCAPS_LOCSOFTWARE
Buffer canalizado por software
DSBCAPS_STATIC
Buffer esttico
DSBCAPS_PRIMARYBUFFER
El buffer es primario
DSBCAPS_MUTE3DATMAXDISTANCE Hace que los buffers 3D sean ms
eficientes reduciendo el nmero de
clculos necesarios.
Tabla 2.4

58

C A P T U L O 2 DirectX y la API DirectSound


2.2.11 Creacin del buffer secundario
Para crear el buffer secundario utilizaremos el mtodo:
HRESULT IDirectSound::CreateSoundBuffer
Con los siguientes parmetros:
Parmetro
LPCDBUFFERDESC lpcDSBufferDesc
LPLDIRECTSOUNDBUFFER
lplpDirectSoundBuffer
IUnknown FAR *pUnkOuter

Descripcin
Puntero a la estructura de descripcin del
buffer.
Recibe el puntero a la interfaz
Debe ser NULL

Tabla 2.5
A continuacin se muestra el cdigo que lo hace posible:
/ Crea un buffer secundario con sonido
LPDIRECTSOUNDBUFFER*
LPDIRECTSOUND3DBUFFER*
DWORD
CWaveFile*
const int

apDSBuffer
apDS3DBuffer
dwDSBufferSize
pWaveFile
NUM_BUFFERS

=
=
=
=
=

NULL;
NULL;
NULL;
NULL;
3;

// Arrays de buffers secundarios y 3D respectivamente


apDSBuffer
= new LPDIRECTSOUNDBUFFER[NUM_BUFFERS];
apDS3DBuffer = new LPDIRECTSOUND3DBUFFER[NUM_BUFFERS];
if( apDSBuffer == NULL )
printf("Falta memoria para buffers secundarios");
if( apDS3DBuffer == NULL )
printf("Falta memoria para buffers 3D");

for(int i = 0;i<NUM_BUFFERS; i++ )


{
pWaveFile = new CWaveFile();
if( pWaveFile == NULL )
printf("Falta memoria para objeto CWaveFile");
std::wstring fichero,indice;
std::wostringstream iss;
iss << i+1;
fichero = L"..\\media\\sonido" + iss.str() + L".wav";
// Abre fichero WAV/PCM para leer cabecera
pWaveFile->Open((LPWSTR)fichero.c_str(), NULL,
WAVEFILE_READ );
if( pWaveFile->GetSize() == 0 ) // Fichero inexistente o
vaco
printf("Error al leer fichero WAV");

59

C A P T U L O 2 DirectX y la API DirectSound


// El buffer secundario debe tener el mismo tamao que el
fichero WAV
dwDSBufferSize = pWaveFile->GetSize();
// Crea el buffer secundario con las propiedades deseadas
ZeroMemory( &dsbd, sizeof(DSBUFFERDESC) );
dsbd.dwSize
= sizeof(DSBUFFERDESC);
dsbd.dwFlags
= DSBCAPS_STATIC |
DSBCAPS_CTRLFREQUENCY |DSBCAPS_CTRLVOLUME | DSBCAPS_CTRL3D;
dsbd.dwBufferBytes
= dwDSBufferSize;
dsbd.guid3DAlgorithm = GUID_NULL;
dsbd.lpwfxFormat
= pWaveFile->m_pwfx;
// Crea el buffer secundario DirectSound
if (FAILED(hr = pDS->CreateSoundBuffer( &dsbd,
&apDSBuffer[i], NULL )))
printf("Error al crear buffer secundario (codigo
error =%d)", hr );

2.2.12 Sonido en tres dimensiones


Una de las posibilidades de DirectSound es el posicionamiento 3D en tiempo real
del sonido. ste coloca los sonidos en el espacio siguiendo el mismo sistema de
coordenadas que usa Direct3D y OpenGL. Para poder adaptar una aplicacin
DirectSound a DirectSound 3D es tan sencillo como aadir las dos siguientes interfaces:

IDirectSound3DBuffer: controla las propiedades 3D de fuentes de sonido


individuales, es decir, buffer secundarios.
IDirectSound3DListener: se emplea para colocar un oyente virtual y para
manipular las propiedades generales del entorno del sonido 3D.

DirectSound puede proporcionar el efecto sonoro de la posicin y el movimiento de


una fuente acstica de las siguientes formas:

Atenuando la amplitud dependiendo de la distancia que haya desde la fuente del


sonido hasta el oyente.
Atenuando la amplitud en uno u otro lado, o realizando un desplazamiento, para
indicar la orientacin hacia la izquierda o la derecha de la fuente de sonido.
Truncando un sonido que se encuentre justo delante del oyente, de acuerdo con
la orientacin de sus odos y el efecto de bloqueo de sonido de su cabeza.
Aplicando un breve retardo a la reproduccin del sonido en un lado o en otro
para reflejar la mayor distancia recorrida por las ondas sonoras originadas en el
lado opuesto de la cabeza. (A este efecto se le denomina ITD, lo que significa
retardo interaural o diferencia de tiempo interaural).
Incrementando o disminuyendo la frecuencia de una fuente de sonido para crear
un efecto Doppler, simulando el efecto de fuentes sonoras que se mueven.

Las coordenadas que utiliza DirectSound 3D son las cartesianas X, Y y Z. Las


posiciones se miden desde el origen de coordenadas (0.0, 0.0, 0.0). Para representar las
coordenadas 3D se utiliza el tipo de datos D3DVALUE. En Direct3D, una diferencia de

60

C A P T U L O 2 DirectX y la API DirectSound


1.0 entre dos puntos situados a lo largo de un vector no se corresponde con una
determinada distancia del mundo real; es responsabilidad del diseador establecer una
escala. Por defecto, 1.0 equivale a 1 metro. Por lo tanto, un buffer con una posicin (2.0, 0.0, 8.0) estar situado un metro a la izquierda y 8 metros por delante de la posicin
por defecto del oyente.
Para obtener una interfaz IDirectSound3D, es necesario invocarla a travs de la interfaz
IDirectSoundBuffer con el mtodo COM QueryInterface.
De esta forma quedara el cdigo:
// Obtiene interfaces 3D
if (FAILED(hr = apDSBuffer[i]->QueryInterface(
IID_IDirectSound3DBuffer, (VOID**) &apDS3DBuffer[i])))
printf("Error al obtener buffer 3D (codigo error
=%d)", hr );

y obtiene tres buffers 3D.


A partir de aqu es necesario fijar las propiedades del buffer 3D; para ello se utiliza
la estructura DS3DBUFFER donde se asignarn los flags que describen las
caractersticas del buffer. En esta estructura se puede definir cundo un sonido debe
situarse en el espacio de forma relativa al oyente o de manera absoluta, dependiendo del
modo del buffer.
Los siguientes flags representan los tres modelos mediante los que se puede configurar
un buffer 3D:

DS3DMODE_HEARDRELATIVE: el buffer se coloca en una posicin relativa


a la del oyente. Es el modo que se usar en el ejemplo.
DS3DMODE_NORMAL: el buffer se coloca de forma relativa al espacio y no
se desplaza a medida que lo hace el oyente. La mayora de los sonidos 3D
funcionan con este mtodo; sta es la configuracin por defecto.
DS3DMODE_DISABLE: esta configuracin se puede utilizar para ahorrar
tiempo de CPU al desactivar el proceso 3D de un buffer de sonido.

// Propiedades del buffer 3D


DS3DBUFFER ds3db;
ZeroMemory(&ds3db,sizeof(DS3DBUFFER));
ds3db.dwSize = sizeof(DS3DBUFFER);
apDS3DBuffer[i]->GetAllParameters( &ds3db);
ds3db.dwMode = DS3DMODE_HEADRELATIVE;
apDS3DBuffer[i]->SetAllParameters(&ds3db, DS3D_IMMEDIATE );

2.2.13 Bloqueo del buffer


Ya se ha visto cmo se crea el buffer secundario y se establecen sus propiedades. A
continuacin se explicar cmo bloquearlo antes de desplazar datos desde el archivo de
sonido al buffer. De esta forma nos aseguramos de que el buffer permanece en una
situacin estable y al mismo tiempo, se obtiene su direccin de memoria. En la tabla 2.6
se muestran los parmetros del mtodo Lock.
61

C A P T U L O 2 DirectX y la API DirectSound

Parmetro
DWORD dwWriteCursor
DWORD dwWriteBytes
DWORD lplpvAudioPtr1
LPDWORD lpdwAudioBytes1
LPVOID lplpAudioPtr2
LPDWORD lpdwAudioBytes2

DWORD dwFlags

Descripcin
Desplazamiento a la zona en la que
comenzar la parte bloqueada.
Nmero de bytes a bloquear.
Recibe la direccin de inicio de bloqueo.
Recibe el tamao de bloqueo, o la primera
porcin si el bloqueo es circular.
Recibe la direccin de la segunda porcin
del bloqueo; si no lo es, recibe NULL.
Recibe el nmero de bytes de la segunda
porcin del bloqueo si ste es circular; si
no lo es, recibe 0.
DSBLOCK_FROMWRITECURSOR o
DSBLOCK_ENTIREBUFFER
Tabla 2.6

En el fragmento de cdigo siguiente se muestra el ejemplo del bloqueo del buffer antes
de la reproduccin.
VOID*
pDSLockedBuffer
= NULL; // Puntero a la memoria bloqueada
DWORD
dwDSLockedBufferSize = 0;
// Tamao de la zona bloqueada
DWORD
dwWavDataRead
= 0;
// Cantidad de datos del fichero
WAV a leer
// Bloquea el buffer
if( FAILED( hr = apDSBuffer[i]->Lock( 0,dwDSBufferSize,
&pDSLockedBuffer,&dwDSLockedBufferSize,
NULL, NULL, 0L ) ) )
printf("Error de bloqueo del buffer (codigo
error=%d)", hr );
// Empieza a leer desde el inicio del fichero
pWaveFile->ResetFile();
if( FAILED( hr = pWaveFile->Read( (BYTE*) pDSLockedBuffer,
dwDSLockedBufferSize,&dwWavDataRead ) ) )
printf("Error leyendo el fichero de audio (codigo error=
%d)", hr );

Por ltimo, es necesario desbloquear el buffer. En la tabla 2.7 se muestran los


parmetros del mtodo Unlock.
Parmetro
LPVOID lpvAudioPtr1
DWORD dwAudioBytes1
LPVOID lpvAudioPtr2

DWORD dwAudioBytes2

62

Descripcin
Direccin de inicio del bloqueo.
Nmero de bytes en la primera porcin
del bloqueo.
Direccin de inicio del buffer si se
produjo desbordamiento del buffer, si no
es as, NULL.
Nmero de bytes en la parte del buffer que

C A P T U L O 2 DirectX y la API DirectSound


produjo el desbordamiento.
Tabla 2.7
if ( FAILED( apDSBuffer[i]->Unlock( pDSLockedBuffer,
dwDSLockedBufferSize, NULL, 0 ) ) )
printf("Error al desbloquear buffer (codigo error
=%d)", hr );
SAFE_DELETE( pWaveFile ) // Libera el objeto CWaveFile
}

2.2.14 Reproducir y posicionar el buffer en 3D


Reproducir el buffer consiste en fijar la posicin actual de reproduccin al principio
del buffer y llamar al mtodo Play. En la tabla 2.8 se muestran sus parmetros:
HRESULT IDirectSoundBuffer::Play
Parmetros
DWORD dwReserved1
DWORD dwReserved2
DWORD dwFlags

Descripcin
Debe ser 0.
Debe ser 0.
0 o DBSPLAY_LOOPING.
Tabla 2.8

case '1':
if (FAILED (hr = apDSBuffer[0]->Play( 0, 0, 0)))
printf("Error al reproducir buffer 1 (codigo error =%d)",
hr );
break;

Es indispensable controlar la gestin de una prdida del buffer. Si el error que


devuelve Play es DSERR_BUFFERLOST es porque un buffer mediante hardware
puede perder su espacio de memoria debido a que otra aplicacin tome el control de
dicho buffer. Cuando esto sucede todas las llamadas a Lock o Play que se realicen sobre
dicho buffer generarn un error hasta que la aplicacin recupere el espacio de memoria
del buffer mediante una llamada al mtodo Restore.
Por ltimo, si deseamos posicionar el buffer en 3D es necesario llamar al mtodo:
IDirectSoundBuffer3D::SetPosition
al cual se debe pasar la posicin 3D en formato D3DVALUE de las coordenadas x,y,z
y una constante que debe ser:

DS3D_DEFERRED: Los parmetros no se hacen efectivos hasta que no se


llama al mtodo: IDirectSound3DListener8::CommitDeferredSettings.
DS3D_INMEDIATE: Los parmetros son aplicados inmediatamente.

En el siguiente ejemplo podemos ver una aplicacin de posicionamiento 3D:

63

C A P T U L O 2 DirectX y la API DirectSound


case '4':
for( double alfa=0.0; alfa < circulo ; alfa += 0.1 )
{
D3DVALUE x = D3DVALUE(distancia*cos(alfa));
D3DVALUE y = D3DVALUE(distancia*sin(alfa));
if ( FAILED( hr = apDS3DBuffer[0]>SetPosition(x,y,0,DS3D_IMMEDIATE) ) )
printf("Error al posicionar 3D (codigo error =%d)",
hr );
Sleep(100);
}
break;

2.2.15 Liberar las interfaces


En ltimo lugar, una vez acabado el procesamiento de sonido y con vistas a salir de
la aplicacin es necesario liberar las referencias a las interfaces COM. Para ello se debe
llamar a la macro definida en directsound.h como SAFE_RELEASE. En el siguiente
fragmento de cdigo podemos ver su utilizacin:
// Libera interfaces y arrays
SAFE_RELEASE(pDSBPrimary);
SAFE_RELEASE(apDSBuffer[0]);
SAFE_RELEASE(apDSBuffer[1]);
SAFE_RELEASE(apDSBuffer[2]);
SAFE_RELEASE(apDS3DBuffer[0]);
SAFE_RELEASE(apDS3DBuffer[1]);
SAFE_RELEASE(apDS3DBuffer[2]);
SAFE_RELEASE(pDS);
SAFE_DELETE(apDSBuffer);
SAFE_DELETE(apDS3DBuffer);

64

C A P T U L O 2 DirectX y la API DirectSound

Bibliografa y referencias
Libros
A fondo DirectX Bradley Bargen, Peter Donnelly. Microsoft Press, 1998.
Programacin COM y COM+ Alan Gordon . Anaya Multimedia, 2001.
Sistemas Distribuidos: conceptos y diseo Colouris, Dolimore, Kindberg. Pearson
Addison Wesley, 2001
La Web
MSDN (Microsoft Developer Network):
http://msdn2.microsoft.com/es-es/default.aspx
Francisco ngel Gimeno Domnech Andrmeda Studios
http://usuarios.multimania.es/andromeda_studios/paginas/tutoriales/articulo02.htm

65

C A P T U L O 3 OpenAL

OpenAL

3.1 Introduccin a OpenAL


OpenAL son las siglas de Open Audio Library, una librera de cdigo fuente abierto
con una API multiplataforma. El diseo fue pensado para un alto rendimiento en el
posicionamiento 3D multi-canal y se distribuye como librera adicional que se instala en
los directorios del sistema. El estilo de OpenAL es muy parecido al de su semejante
OpenGL, por lo que existen diversas analogas en la convencin de llamadas a las
funciones.
La historia de OpenAL se remonta a la compaa de software Loki cuando
intentaban poder realizar de una forma fcil la traslacin de cdigo de juegos
programados en Windows sobre Linux. El proyecto fue distribuido con licencia pblica
como software libre y mantenido por esta comunidad. Ms tarde fue la compaa de
Creative Labs la que continu el mantenimiento del proyecto, con apoyo de Apple y la
comunidad de software libre.

Figura 3.1 Logotipo de OpenAL

3.2 Arquitectura de OpenAL


La arquitectura de OpenAL se basa en la Arquitecture Review Board o ARB que es
el modelo usado por OpenGL.
La estructura bsica consta de 3 elementos principales: objetos source, buffers y
listeners. Un objeto source contiene un puntero a un buffer, la velocidad, la posicin, la
direccin y la intensidad del sonido. Un objeto listener contiene la posicin, la
velocidad, la direccin y la ganancia global aplicada a todos los sonidos. As mismo, los
buffers son los responsables de albergar formas de onda de audio con codificacin
PCM, con resolucin de 8 16 bits y formato monoaural o estreo. El motor de
renderizado lleva a cabo todos los clculos necesarios para obtener la atenuacin de
distancia, efecto Doppler, etc.
El resultado neto de una aplicacin desarrollada con esta arquitectura es que el usuario
final aprecia que el sonido es muy natural y que el posicionamiento 3D est
perfectamente acompasado con el movimiento por un escenario virtual. Desde la

67

C A P T U L O 3 OpenAL
perspectiva del programador de aplicaciones requiere de muy poco tiempo de
codificacin y de mantenimiento para cumplir los requisitos.
De la misma forma que OpenGL, OpenAL consta de dos secciones de la API: el ncleo
basado en las llamadas a las funciones y la API ALC que es usada para manejar
contextos de renderizacin, uso de recursos y bloqueo multiplataforma. Adems,
imitando a su predecesor, OpenAL incluye una librera de alto nivel para
programadores, llamada ALUT, con convenciones de llamadas muy parecidas a la
GLUT de OpenGL cuyo cometido es simplificar algunas tareas complicadas como es la
lectura de un fichero WAV.

Dispositivo n1

Listener

Contexto n1

Source 1

Source 2

Source 3

Source 4

Buffer 1

Buffer 2

Buffer 3

Buffer 4

Figura 3.2 Arquitectura de OpenAL


Con el objetivo de proveer funcionalidad de cara al futuro, OpenAL utiliza un
mecanismo de extensiones por el cual los fabricantes pueden incluir sus propias
extensiones en distribuciones de OpenAL, con el propsito de exponer funciones
adicionales en su hardware propietario. Las extensiones siguen la base ARB
(Arquitecture Review Board), asegurando que va a existir retrocompatibilidad con las
extensiones anteriores. Las extensiones ARB pueden ser agregadas al ncleo de la API
tras un cierto perodo de tiempo.
Entre las plataformas en las que se encuentra implementado OpenAL destacan las
siguientes:

68

Mac OSX
GNU/Linux
BSD
Solaris
IRIX

C A P T U L O 3 OpenAL

Windows PC
XBox 360

3.3 Programacin con OpenAL1


3.3.1 Inicializacin
El primer paso para inicializar OpenAL es abrir el dispositivo. Una vez abierto con
xito, procederemos abrir un contexto sobre dicho dispositivo. A partir de entonces es
cuando los objetos fundamentales de OpenAL pueden ser manejados. La funcin para
abrir el dispositivo es la que se muestra a continuacin:
alcOpenDevice
Parmetros
conts ALCchar *devicename

Descripcin
Un string describiendo el dispositivo
Tabla 3.1

Si el string que contiene el nombre del dispositivo es null, se obtendr el dispositivo


por defecto. En caso de que el dispositivo no pueda ser abierto o se produzca un error
devolver la constante literal null.
Despus de iniciar el dispositivo es necesario crear el contexto, y para esto
llamamos a la funcin:
alcCreateContext
Parmetros
ALCdevice *device
ALCint *attrlist

Descripcin
Puntero al dispositivo
Atributos:
ALC_FREQUENCY
ALC_MONO_SOURCES
ALC_REFRESH
ALC_STEREO_SOURCES
ALC_SYNC
Tabla 3.2

La funcin devolver un puntero al nuevo contexto o null si ocurre algn error.


Una vez creado el contexto, procederemos a informar al sistema sobre cul va a ser
el contexto con el que se activar la aplicacin, para lo que se requiere llamar a la
siguiente funcin:

En este captulo utilizaremos el compilador Microsoft Visual C++ .NET 2010 que es el ms avanzado
en Windows 64 bits hasta la fecha de publicacin de este tratado.

69

C A P T U L O 3 OpenAL
alcMakeContextCurrent
Parmetros
ALContext *context

Descripcin
Puntero al contexto
Tabla 3.3
En caso de error, la funcin devolver la constante booleana ALC_FALSE, y en caso de
xito devolver ALC_TRUE.
Con estas llamadas tan simples podemos activar un dispositivo y un contexto de
renderizacin para reproducir buffers de sonidos y activar sources y listeners.
Por ltimo, dentro de la seccin de inicializacin, existe la posibilidad de indagar en
OpenAL la presencia de extensiones hardware, mediante la llamada a la funcin:
alIsExtensionPresent

Parmetros
ALCdevice *device
const ALCchar *extname

Descripcin
Puntero al dispositivo del cual interesa
averiguar extensin
Cadena indicando la extensin
Tabla 3.4

A continuacin se muestra el cdigo del ejemplo que consigue dichas tareas:


#include
#include
#include
#include
#include

<conio.h>
<windows.h>
<math.h>
<string>
<sstream>

#include "al.h"
#include "alc.h"
#include "AL/alut.h"

const int NUM_BUFFERS = 4;


const int NUM_SOURCES = 4;
void _tmain(int argc, _TCHAR* argv[])
{
ALCdevice* Device;
ALCcontext* Context;
ALenum
error;
// Inicializacin
Device = alcOpenDevice(NULL); // Selecciona el dispositivo por
defecto
if (Device)
alcMakeContextCurrent(Context =
alcCreateContext(Device,NULL));
// Comprueba que existe la extensin EAX 2.0
ALboolean bEAX = alIsExtensionPresent("EAX2.0");
if (bEAX) printf("EAX2.0 presente en el sistema...\n");
alGetError(); // Limpia el cdigo de error

70

C A P T U L O 3 OpenAL
3.3.2 Trabajar con buffers
Depus de iniciar la aplicacin es preciso generar el primer elemento bsico de la
arquitectura de OpenAL: el buffer. Con este objeto podremos almacenar formas de
ondas provenientes de ficheros WAV y reproducirlas ms tarde.
La funcin que lleva a cabo este cometido es:
alGenBuffers
Parmetros

Descripcin
ALsizei n
Nmero de buffers a generar
ALuint *buffers
Puntero a un array de valores ALuint que
almacenar el nombre de los nuevos
buffers.
Tabla 3.5
Una vez creado el buffer es posible almacenar en l datos en formato PCM
provenientes de un fichero WAV. Para realizar esta operacin se utiliza una funcin de
alto nivel definida en la librera externa alut.h que permite leer ficheros en formato
WAV.
alutLoadWAVFile
Parmetros
ALbyte* strFile
ALenum* format
ALvoid *data
ALsizei *size
ALsizei *freq
ALboolean *loop

Descripcin
Nombre del fichero
Formato del fichero
Datos en PCM
Tamao del fichero
Frecuencia de sampleo
Bucle de reproduccin del fichero
Tabla 3.6

Por ltimo, y una vez ledos los datos PCM en un array, se proceder a copiarlos
dentro del objeto buffer con la siguiente funcin:
alBufferData
Parmetros
ALuint buffer
ALenum format

const ALvoid *data


ALsizei size
ALsizei freq

Descripcin
Nombre del buffer a llenar con datos
Puede ser uno de los siguientes:
AL_FORMAT_MONO8
AL_FORMAT_MONO16
AL_FORMAT_STEREO8
AL_FORMAT_STEREO16
Puntero a los datos de audio
El tamao de los datos en bytes
Frecuencia de muestreo
Tabla 3.7

71

C A P T U L O 3 OpenAL
Esta funcin tambin puede leer datos en formatos diferentes a PCM si se utilizan
las extensiones apropiadas.
Con todo esto, el cdigo necesario para implementar la generacin y carga de datos en
el buffer es como se muestra en el siguiente ejemplo:
// Genera los buffers
ALuint
buffer[NUM_BUFFERS];
alGenBuffers(NUM_BUFFERS, buffer);
printf("Generando buffers...\n");
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alGenBuffers :", error);
terminaAplicacion();
return;
}
// Carga los ficheros WAV
ALsizei size,freq;
ALenum format;
ALvoid *data;
ALboolean loop;
printf("Leyendo ficheros de audio...\n");
for(int i = 0; i < NUM_BUFFERS; i++)
{
std::string fichero,indice;
std::ostringstream iss;
iss << i+1;
fichero = "..\\media\\sonido" + iss.str() + ".wav";
alutLoadWAVFile((ALbyte*)fichero.c_str(), &format, &data,
&size, &freq, &loop);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alutLoadWAVFile: %d", error);
// Delete Buffers
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
// Copia a los respectivos buffers los datos
printf("Copiando a buffer...\n");
alBufferData(buffer[i],format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alBufferData buffer 0 : %d", error);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
// Descarga el fichero WAV
alutUnloadWAV(format,data,size,freq);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alutUnloadWAV : %d", error);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
}

72

C A P T U L O 3 OpenAL
3.3.3 Reproducir sonido
Como es habitual en toda aplicacin de sonido, debe exisitir algn objeto que
controle la reproduccin de audio. En OpenAL tenemos el objeto source que permite
llevar a cabo esta operacin:
alGenSources
Parmetros
ALsizei n
ALuint *sources

Descripcin
Nmero de sources a generar
Puntero a un array de valores ALuint con
los nombres de los sources
Tabla 3.8

Con el fin de reproducir el sonido debemos adjuntar los buffers, creados en la seccin
anterior, a los sources mediante la llamada a la siguiente funcin:
alSourcei
Parmetros
ALuint source
ALenum param

ALint value

Descripcin
Nombre del source al que hay que
establecer los atributos
Uno de los siguientes atributos:
AL_SOURCE_RELATIVE
AL_CONE_INNER_ANGLE
AL_CONE_OUTER_ANGLE
AL_LOOPING
AL_BUFFER
AL_SOURCE_STATE
Valor a establecer
Tabla 3.9

En el siguiente fragmento de cdigo se ilustra la manera de llevarlo a cabo:


// Genera las fuentes
ALuint
source[NUM_SOURCES];
alGenSources(NUM_SOURCES,source);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alGenSources 1 : %d", error);
alDeleteSources(NUM_SOURCES, source);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
// Adjunta los buffers a las fuentes
for(int i=0;i < NUM_SOURCES; i++)
{
alSourcei(source[i], AL_BUFFER, buffer[i]);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alSourcei AL_BUFFER 0 : %d", error);

73

C A P T U L O 3 OpenAL
alDeleteSources(NUM_SOURCES, source);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
}

Ahora ya es posible reproducir un source mediante la funcin:


alSourcePlay
Parmetros

Descripcin
El nombre de la fuente a reproducir
Tabla 3.10

ALuint source

while( condicion )
{
switch( _getch() )
{
// Reproduce buffer 1
case '1':
alSourcePlay(source[0]);

Con estas funciones adicionales es posible tambin:

Detener el sonido
alSourceStop(source[0]);

Rebobinar
alSourceRewind(source[0]);

o pausarlo
alSourcePause(source[0]);

3.3.4 Posicionamiento 3D
Esta es una de las caractersticas ms avanzadas de OpenAL, ya que permimte
utilizar diferentes configuraciones para manipular el sonido en tres dimensiones. Uno de
los elementos fundamentales para el posicionamiento 3D es el listener, que se podra
asemejar a los odos del sujeto que se encuentra sumergido en el espacio virtual.
Normalmente, los listeners suelen establecerse en la posicin de la cmara, de manera
que sensacin acstica concuerde con la percepcin visual. As mismo, es posible
aplicar un gran nmero de parmetros sobre el listener para controlar la orientacin,
posicin y la velocidad. Este objeto debe ser nico en la aplicacin, lgicamente, ya que
el sonido procesado mediante el mismo es luego dirigido a los canales estreo de los
altavoces.

74

C A P T U L O 3 OpenAL
Respecto al posicionamiento 3D de un sonido en OpenAL es posible llevarlo a cabo
llamando a la siguiente funcin:
alSourcefv
Parmetros
ALuint source
ALenum param

ALfloat *values

Descripcin
Source al que hay que establecer los
atributos
Atributo a establecer. Puede ser uno de los
siguientes:
AL_POSITION
AL_VELOCITY
AL_DIRECTION
Un puntero a un array de valores a
establecer
Tabla 3.11

En este caso se utilizar un vector de 3 elementos para almacenar las


componentes X,Y y Z de la posicin, velocidad o direccin del sonido 3D, como se
muestra en el ejemplo programado:
ALfloat source4Pos[3]; // Almacena la posicion del buffer 4

Por ltimo, para realizar el posiconamiento 3D del sonido utilizaremos el siguiente


cdigo:
for(float alfa=0.0f; alfa < circulo ; alfa += 0.1f )
{
ALfloat x = distancia*cos(alfa);
ALfloat y = distancia*sin(alfa);
source4Pos[0] = x;
source4Pos[1] = y;
source4Pos[2] = 0.0f;
alSourcefv(source[3], AL_POSITION, source4Pos);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("Error al posicionar 3D buffer4 :", error);
alDeleteSources(NUM_SOURCES, source);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();
return;
}
Sleep(100);
}
alSourcei(source[3], AL_LOOPING, AL_FALSE);

75

C A P T U L O 3 OpenAL

Figura 3.3 Descripcin del efecto de giro de 360 creado sobre el oyente en el ejemplo
anterior

3.3.5 Salida de la aplicacin


Para terminar la aplicacin de forma controlada necesitamos obtener un puntero al
contexto actual, obtener el dispositivo activado dentro de l y posteriormente establecer
el contexto actual como null, destruir el contexto y cerrar el dispositivo. A continuacin
se muestra la secuencia del cdigo que lo realiza:
// Termina la aplicacin
// Libera el contexto y el dispositivo
void terminaAplicacion()
{
ALCcontext* Context
= alcGetCurrentContext();
ALCdevice* Device
= alcGetContextsDevice(Context);
alcMakeContextCurrent(NULL);
alcDestroyContext(Context);
alcCloseDevice(Device);
alutExit();
}

Tambin es importante liberar los buffers y los sources creados para manejar audio.
Las funciones alDeleteBuffers y alDeleteSources son las responsables de destruir los
objetos buffer y source que se hayan creado durante la ejecucin de la aplicacin. De
esta manera se liberar el espacio de memoria utilizado para dicho propsito en el
sistema. El siguiente fragmento de cdigo ha sido utilizado en el ejemplo para liberar
los objetos sources y buffers en el momento de romper el flujo de control para salir de la
aplicacin:
alDeleteSources(NUM_SOURCES, source);
alDeleteBuffers(NUM_BUFFERS, buffer);
terminaAplicacion();

76

C A P T U L O 3 OpenAL
Ya slo faltara, por ltimo, salir de la aplicacin OpenAL mediante a la llamada:
aluExit()
3.3.6 Gestin de errores
Cuando se produce una situacin anmala en la llamada a cualquier funcin de
OpenAL se genera un estado de error en la librera que informa con un cdigo el tipo de
error que se ha producido. Evidentemente, este tipo de gestin de errores se realiza
mediante consulta utilizando la funcin:
ALenum alGetError(ALvoid)

La consiguiente llamada a la funcin producir que se elimine el estado de error de la


memoria.
El uso de esta funcin puede verse en el siguiente ejemplo:
ALuint
buffer[NUM_BUFFERS];
alGenBuffers(NUM_BUFFERS, buffer);
printf("Generando buffers...\n");
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("alGenBuffers :", error);
terminaAplicacion();
return;
}

3.4 Ventajas de OpenAL


La primera gran ventaja de OpenAL con respecto a otras libreras de audio como
DirectSound es la portabilidad. Se puede utilizar en gran cantidad de plataformas, desde
Windows hasta Linux, con lo que los desarrolladores tienen un gran abanico de sistemas
que pueden cubrir utilizando el mismo cdigo sin necesidad de cambiar nada. Las
razones son estratgicas a la hora de abordar aplicaciones multiplataforma, cada vez
ms de moda y que repercute en aspectos tales como la Ingeniera de Software
(reutilizacin de cdigo, diseo, pruebas, mantenimiento, evaluacin, etc.) as como
econmicas.
La segunda gran ventaja es la simplicidad de la arquitectura y del cdigo. No es
necesario tecnologa de programacin compleja, como es el caso de COM en DirectX,
no hay que complicar lo evidente con funciones adicionales como es el caso de la
prdida del buffer en DirectSound. La arquitectura es fcilmente comprensible: las
entidades utilizadas son las bsicas de cualquier aplicacin de sonido.
La ltimas grandes ventajas son la eficiencia y las prestaciones. OpenAL
proporciona una baja latencia y un rendimiento ptimo de CPU a la hora de mezclar
varios buffers de sonido y realizar clculos de posicionamiento 3D espacial con muchas
fuentes de sonido.

77

C A P T U L O 3 OpenAL
Como conclusin se puede destacar que OpenAL se presenta como una gran alternativa
a otras libreras de sonido por sus mltiples ventajas a la hora del desarrollo de software
de audio.

Bibliografa y referencias
referencias
Manuales
OpenAL Programmer's Guide - OpenAL Versions 1.0 and 1.1
La Web
Wikipedia:
http://en.wikipedia.org/wiki/OpenAL

78

Parte III

MIDI

C A P T U L O 4 Introduccin a MIDI

Introduccin a MIDI

4.1 Qu es MIDI?
4.1.1 Un poco de historia
Al comienzo del desarrollo de la tecnologa musical, todos los sintetizadores
eran monofnicos, es decir, slo eran capaces de reproducir una sola nota al mismo
tiempo.
A finales de la dcada de los 70 hizo su aparicin el sintetizador digital y trajo consigo
el problema de la incompatibilidad entre sistemas de fabricados por cada compaa. De
este modo se hizo necesario la creacin de un lenguaje comn que abstrajera las
caractersticas tcnicas de cada marca y permitiera la comunicacin entre sistemas.
En 1982 , Dave Smith, de la empresa Sequential, propuso poner de acuerdo a las
grandes compaas para crear un protocolo de comunicacin entre sistemas que fuera
respetado por el convenio o norma. El fundamento de su idea era poder interconectar los
instrumentos digitales para hacer sonar a ms de un aparato a la vez, creando as un
efecto de polifona musical.
El estndar MIDI fue propuesto inicialmente en un documento dirigido a la
Audio Engineering Scoiety. La primera especificacin MIDI se public en agosto de
1983.
El primer sintetizador capaz de soportar la especificacin fue el Prophet 600 de
Sequential (figura 4.1). En 1996 todos los instrumentos que ostentaban el logotipo
respetaban el estndar.
MIDI es el acrnimo de Interfaz Digital de Instrumentos Musicales, y
actualmente el estndar es ampliamente utilizado en la industrial musical; aunque es
tambin muy utilizado en otros muchos sistemas, no slo instrumentos musicales. As,
por ejemplo, podemos encontrar la tecnologa MIDI implementada en sistemas para
controlar la secuencia de luces de un espectculo en directo o controlar aparatos de
edicin de sonido, entre otras muchas aplicaciones.

81

C A P T U L O 4 Introduccin a MIDI

Figura 4.1 Prophet 600 de Sequential


4.1.2 Conceptos bsicos
La informacin MIDI define diversos tipos de datos como nmeros que pueden
corresponder a notas particulares, nmeros de programas de sonidos o valores de
controladores. Gracias a esta simplicidad, los datos pueden ser interpretados de diversas
maneras y utilizados con fines diferentes a la msica. El protocolo incluye
especificaciones complementarias de hardware y software. As, es posible la
interconexin de una gran nmero heterogneo de sistemas software y hardware, tal
como se muestra en la figura 4.2.
Permite, por ejemplo, reproducir y componer msica en el formato MIDI. Los
archivos almacenados en disco se caracterizan por su calidad de muestreo y su poco
espacio en bytes requerido. Un fichero de una cancin puede oscilar entorno a los 17
Kilobytes. Aunque este estndar de fichero no es comnmente utilizado en Internet.

Figura 4.2 Interconexin de sistemas MIDI

82

C A P T U L O 4 Introduccin a MIDI
Cabe aclarar que MIDI no transmite seales de audio, sino datos de eventos y
mensajes controladores que se pueden interpretar de manera arbitraria, de acuerdo con
la programacin del dispositivo que los recibe. Es decir, MIDI es una especie de
partitura que contiene las instrucciones en valores numricos, o ms especficamente
en binario, sobre cundo generar cada nota de sonido y las caractersticas que debe
tener; posteriormente el sistema MIDI transformar en msica las secuencia de
instrucciones.
Los aparatos MIDI se pueden clasificar en tres grandes categoras:


Controladores: generan los mensajes MIDI (activacin de nota, desactivacin


de nota). El controlador ms familiar para los msicos tiene forma de teclado de
piano, que es el ms utilizado; aunque tambin se puede encontrar en guitarras
elctricas, rganos de tubos, clarinetes, incuso gaitas.

Figura 4.3 Controlador MIDI




Unidades generadoras de sonido: tambin conocidas como mdulos de sonido.


Suelen ser unidades centrales de procesamiento de audio que reciben datos
MIDI y generan sonido.

Figura 4.4 Mdulo MIDI




Secuenciadores: son sistemas software o hardware dedicados a reproducir un


fichero con especificacin General MIDI 1.0 (GM1) o General MIDI 2.0 (GM2).

Figura 4.5 Secuenciador MIDI


83

C A P T U L O 4 Introduccin a MIDI
4.1.3 Electrnica MIDI
4.1.3.1 Interconexin de sistemas
MIDI no ha sido indiferente a los nuevos avances en sistemas de comunicacin
electrnica de datos. As, las nuevas tecnologas en comunicaciones han abierto un gran
abanico de posibilidades al estndar, del cual se ha dejado influenciar.
El sistema MIDI utiliza un total de 16 canales que se pueden comunicar entre aparatos o
instrumentos a travs de cada cable. Los tipos de conexin actuales son los siguientes:
Conectores y cables MIDI:
El MIDI comunica de manera digital los datos de una interpretacin musical a
travs de un cable estndar MIDI como una serie de mensajes que se transmiten a una
velocidad de 31,25 kbaudios (bits/segundo).

Figura 4.6 Cable MIDI


El sistema de funcionamiento es tipo simplex, es decir, slo puede transmitir
seales en un sentido. La direccin que toman las seales es siempre desde un
dispositivo maestro hacia un dispositivo esclavo. El primero genera la informacin y el
segundo la recibe.
Un cable estndar MIDI consiste en un cable mutipolar trenzado blindado
terminado en un conector DIN de cinco pines. Los pines 4 y 5 se utilizan para conducir
los datos y el pin 2 para conectar el blindaje del cable a la toma de tierra. Los pines 1 y
3 no se utilizan actualmente, pero estn reservados para futuros propsitos. El cable
trenzado y el blindaje metlico se utilizan para reducir las interferencias
electromagnticas del exterior.
La especificacin del cable MIDI obliga a una longitud mxima del cable de 15
metros para evitar la degradacin de seal y la interferencia externa; aunque las
longitudes tpicas son de 1,3 y 6 metros de largo. En la figura 4.6 pueden apreciarse los
conectores MIDI estndar.
En los sistemas MIDI se utilizan tres tipos de puerto:

84

C A P T U L O 4 Introduccin a MIDI

MIDI in: es la entrada de datos al dispositivo.


MIDI out: salida de datos hacia otro dispositivo.
MIDI thru: Puente de datos. Transmite una copia exacta de los datos que llegan
por MIDI in a otro instrumento o aparato MIDI que contina la cadena de datos
MIDI conectada.

Figura 4.7: Puertos MIDI


Algunos dispositivos no tiene puerto thru, por lo que deben emularlo por software.
Slo hay dos formas de conectar un sistema MIDI a otro. Son las siguientes:

Conectar el MIDI out al MIDI in del otro sistema.


Conectar el puerto MIDI thru de un sistema al puerto MIDI in del otro sistema.

Una forma tpica de conectar dispositivos MIDI es un una red margarita o daisy
chain. Este mtodo transmite MIDI de un aparato al siguiente puenteando los datos
recibidos por MIDI in de un aparato, directamente a otro aparato por MIDI thru, donde
la cadena contina en el siguiente aparato. En la figura 4.8 se muestra un ejemplo de
esta disposicin.

Figura 4.8: Conexin en margarita (daisy chain)


Esta conexin permite al dispositivo 1 conectarse al dispositivo 2, que repite los
datos hacia el dispositivo 3 y as sucesivamente.

85

C A P T U L O 4 Introduccin a MIDI
Conexiones USB y FireWire:
Actualmente los sistemas MIDI pueden conectarse tambin a travs de
conectores USB del tipo 1 y 2 y el protocolo IEEE (FireWare). Gracias a estos
dispositivos de alta velocidad es posible conectar, respetando el protocolo MIDI 1.0,
aparatos de diferentes compaas. La ventaja de estos conectores es la facilidad de
auto-deteccin del dispositivo, la rpida y cmoda conexin.
Conexiones de red mLAN:
Este innovador sistema fue creado por Yamaha y resolva el problema de la
innecesaria parafernalia de cables para la conexin MIDI. Este sistema permite que el
audio multicanal y los datos sean transferidos a travs del cable estndar IEEE FireWare
1394.
mLAN, soporta un total de 100 canales de datos de audio digital y hasta 256 puertos
MIDI, es decir, un total de 16 x 256 conexiones o canales en tiempo real. Adems tiene
la posibilidad de comunicacin fullduplex a velocidades de 100, 200 400 Mbps.
Las ventajes principales de este sistema son la velocidad de conexin, el ancho de banda
para audio y canales MIDI, y la fcil conexin automtica entre sistemas MIDI sin
necesidad de configuracin.

Figura 4.9 Sistema mLAN

86

C A P T U L O 4 Introduccin a MIDI
4.1.3.2 Esquemticos
En esta seccin se ilustra los esquemticos electrnicos para configurar las
conexiones IN, OUT y THRU a la circuitera MIDI basada en un integrado UART para
comunicacin serie.

Figura 4.10 Esquemtico MIDI


Como puede observarse en la figura 4.10, MIDI es un interfaz serie asncrono.
La frecuencia de baudios es 31.25 Kbaudios (+/- 1%). Hay 1 bit de comienzo, 8 bits de
datos y 1 bit de parada (en total 10 bits), lo cual hace un periodo de 320 microsegundos
por byte serie.
La intensidad de corriente en el bucle del circuito MIDI es de 5mA. Para evitar
daos en el aparato en caso de una diferencia de tensin excesiva con el transmisor, la
entrada est optoaislada. Los optoacopladores Sharp PC-900 y HP6N138 garantizan una
respuesta binaria bien diferenciada para evitar errores de datos. Los flancos de subida y
bajada de los optoacopladores deben estar por debajo de 2 microsegundos.
La transmisin MIDI-thru podra no ser realizada correctamente debido al
tiempo de retardo (causado por el tiempo de respuesta del optoacoplador) entre los
flancos de subida y bajada de la onda cuadrada. Estos errores de temporizacin tendern
a incrementarse de forma progresiva cuantos ms dispositivos estn conectados en
estructura de margarita (daisy-chain) a otros conectores MIDI-thru. Por lo tanto, esto
limita el nmero de dispositivos que pueden encadenarse en esta distribucin.

87

C A P T U L O 4 Introduccin a MIDI

4.2 Especificacin MIDI


4.2.1 Introduccin
De acuerdo a la especificacin MIDI, los mensajes estn compuestos de varios bytes
que se transmiten en serie y contienen un conjunto de instrucciones o de datos de
control a uno o a varios sistemas. Los dos bytes fundamentales del sistema MIDI son:

Byte de estado.
Byte de datos.

El byte de estado se utiliza para indicar el tipo de mensaje y el canal dentro del
sistema al que va dirigido. En los bytes de datos se codifican en binario los valores
numricos que indican los parmetros para ese canal. Por ejemplo: la nota pulsada y la
velocidad de pulsacin. Figura 4.11.
Para identificarlo, el MSB (bit ms significativo) del byte de estado es siempre 1, en
contrapartida, el MSB del byte de datos siempre empieza en 0.
Byte de estado
N de estado/canal
(1001 0100)
(note on/canal 5)

Byte de datos 1
N de nota
(0100 0000)
(64)

Byte de datos 2
Velocidad de pulsacin
(0101 1001)
(89)

Figura 4.11 Mensaje MIDI


4.2.2 Canales MIDI
Con el uso de canales MIDI, un mensaje generado por un sistema puede dirigirse
a otro sistema por medio de la identificacin de canales. Esto se consigue utilizando
cuatro bits dentro del byte de estado. Como son cuatro bits en el campo de estado,
tenemos un total de 24 = 16 canales MIDI direccionables. Con el uso de canales
podemos asignar un instrumento a cada canal y enviarlo a travs del sistema.
En la figura 4.12, puede verse esta situacin representada dentro del crculo en rojo.
Tenemos dos dispositivos: el GPO Studio 2 y la tarjeta SB Creative Live, en los cuales
hemos asignados dos instrumentos de percusin sobre el mismo canal: Tambourine y
Splash Cymbal 2 que sonarn simultneamente cuando reciban datos sobre el canal 10,
aunque estn en aparatos diferentes.

88

C A P T U L O 4 Introduccin a MIDI

Figura 4.12 Asignacin a canales


Utilizando como ejemplo la figura 4.12 se podra crear una composicin corta
utilizando un sintetizador como estacin de trabajo conectado a un secuenciador (un
software capaz de grabar, editar y reproducir datos MIDI), un mdulo de sonido y un
sampler. De esta manera es posible que el ordenador enve mensajes MIDI al mdulo de
sonido, al sintetizador o al sampler, controlando por medio de cada canal los
instrumentos en cada dispositivo antes mencionado.

89

C A P T U L O 4 Introduccin a MIDI

4.3 Mensajes MIDI


En el apndice A1 puede consultarse la tabla resumida de los diferentes tipos de
mensajes MIDI. A continuacin se detallan ampliamente cada uno de estos tipos.
4.3.1 Mensajes de canal
Son utilizados para transmitir datos de interpretacin en tiempo real, puesto que son
generados cuando un instrumento MIDI es tocado en directo. Los mensajes de canal
contienen un nmero de canal en su byte de estado. A continuacin se explican los siete
tipos de mensajes:


Note on: indica que una nota particular debera ser reproducida. Esencialmente,
significa que la nota comienza a sonar, aunque algunos patches podran tener un
periodo de ataque VCA largo que necesite aumentar lentamente el sonido. En
cualquier caso, este mensaje indica que una nota particular comienza a sonar (al
menos que la velocidad de pulsacin de la nota sea 0). Si el dipositivo el
multitmbrico, cada nota se reproduce en un canal diferente.
El rango del byte de estado abarca los valores hexadecimales 0x90 a 0x9F. El
primer byte de datos contiene el nmero de la nota. Hay 128 posibles notas en
un sistema MIDI, numeradas del 0 al 127. El valor 60 corresponde a la nota DO
central del teclado. El segundo byte de datos es la velocidad, tambin en el rango
[0,127]. Indica con qu fuerza se ha pulsado la tecla. Con frecuencia la
velocidad se usa para adaptar el tiempo de ataque del VCA.
Un mensaje MIDI con la velocidad 0 es considerado como un mensaje de Note
off.

Note off: indica que una nota en concreto ha sido finalizada. Esto significa que
la nota debe de parar la reproduccin, aunque algunos patches podran tener un
tiempo de liberacin (release time) que necesite disminuir lentamente el sonido.
Algunas veces, el pedal de sostenimiento puede estar presionado, en ese caso la
liberacin de la nota es pospuesta hasta que se levante el pedal. En cualquier
evento, este mensaje puede causar que el VCA se posicione dentro de la etapa de
liberacin, o si el pedal est presionado, indica que una nota debera ser liberada
cuando el pedal de sostenimiento est desactivado. En un dispositivo
multitmbrico cada note off debera activarse por cada canal.
El mensaje contiene un byte de estado con el rango de valores: 0x80 a 0x8F,
mientras que el primer byte de datos contiene la tecla a liberar y el segundo byte
la velocidad en la que se ha dejado levantar la tecla.

90

Aftertouch: cuando una determinada nota est reproducindose puede serle


aplicada una presin. Muchos instrumentos MIDI tiene electrnica sensible a la
presin que pueden detectar cmo de fuerte presiona un msico la tecla. El
msico puede variar esta presin, incluso cuando contina presionando la tecla.
El mensaje de aftertouch expresa la cantidad de presin en un determinado
punto de una tecla. Puesto que el msico pude variar continuamente la presin,
los dispositivos que generan aftertouch normalmente envan varios mensajes

C A P T U L O 4 Introduccin a MIDI
durante el proceso. Una vez recibido el mensaje, muchos dispositivos lo usan
para variar el VCA de la nota y/o el nivel de sostenido de la envolvente VCF, o
la cantidad a ser aplicada al control LFO.
El byte de estado est comprendido en el rango de valores: 0xA0 a 0xAF.
El primer byte de datos es el nmero de nota a aplicar la presin. El segundo
byte de datos es la cantidad de presin, en un rango discreto de [0,127] valores.


Channel preassure: este mensaje expresa la cantidad general (media) de


presin en las teclas en un determinado punto. Al igual que en el mensaje de
aftertouch, los msicos pueden variar continuamente la presin, generndose
mltiples mensajes de este tipo. El comportamiento al recibir el mensaje de este
efecto es el mismo que en el aftertouch. Pero, cul es la diferencia entre el
mensaje de aftertouch y channel presassure? La diferencia principal recae en
que el mensaje aftertouch es para teclas individuales, es decir, un mensaje
aftertouch solamente afecta a la nota cuyo nmero est en el mensaje. Cada tecla
que se presiona genera su propio mensaje aftertouch. Si presionamos una tecla
ms fuerte que otra, esa tecla sola generar mensajes aftertouch con valores ms
altos que la otra tecla. El resultado neto es que algunos efectos se aplicarn a una
tecla ms que a otra. En contrapartida, el mensaje channel preassure es enviado
para el teclado entero. As, si presionamos una tecla ms fuerte que otra, el
sintetizador promediar la diferencia entre las dos presiones, y luego
simplemente produce el efecto de presionar las dos teclas con la misma presin
exacta. Un sistema MIDI usa normalmente uno de los dos efectos
separadamente.
Muchos controladores MIDI no generan aftertouch ya que requiere un sensor de
presin individual por cada tecla, y esto encarece el diseo y el producto. Por
esta razn, algunos dispositivos slo implementan el mensaje de channel
preassure.

Program change: se utiliza para cambiar un programa determinado1. La


mayora de los mdulos de sonido tienen una gran variedad de instrumentos.
Cada uno de estos instrumentos est contenido en un programa. As, cambiando
el programa cambia el instrumento que suena cuando una nota es presionada.
Obviamente, los mensajes MIDI pueden cambiar el programa. En MIDI hay un
total de 128 posibles programas, numerados en el rango [0,127] (vase apndice
A3). Si el dispositivo es multitmbrico, normalmente puede reproducir 16 partes
a la vez en cada canal.
Existen algunos sistemas MIDI que no tienen instrumentos, por ejemplo, una
unidad de Reverb. En este caso se utiliza para seleccionar el Preset a utilizar.
Otro ejemplo sera el de una caja de ritmos, en el que el mensaje se utilizara
para seleccionar un determinado patrn rtmico.
En este mensaje el byte de estado comprende los valores del 0xC0 al 0xCF,
mientas que slo transporta un byte de datos, que contiene el programa a
establecer.

Alguna terminologa se refiere al programa como patch, intrumento, preset, etc.

91

C A P T U L O 4 Introduccin a MIDI


Control change: establece un valor de controlador concreto. Un controlador es


cualquier botn, slider, switch etc. que normalmente implementa alguna funcin
ms que reproducir o detener notas. Hay un total de 128 posibles controladores
en un dispositivo MIDI y estn numerados en el rango discreto [0,127] (vase
apndice A2). Alguno de estos nmeros de controlador estn asignados a un
control hardware particular en el dispositivo MIDI. Por ejemplo, el controlador 1
es asignado a la rueda de modulacin o mudulation wheel. Otros nmeros de
controlador son libremente asignados para ser arbitrariamente interpretados por
el sistema. Por ejemplo, una caja de ritmos podra tener un control slider para
manejar el Tempo el cual asigna libremente valores arbitrarios. Cuando la caja
de ritmos recibe un mensaje de controlador con ese nmero de controlador ya
puede ajustar el Tempo. Hay que recalcar en este apartado que un dispositivo
MIDI no necesita el controlador fsico para responder a los mensajes de
controladores.
El byte de estado del mensaje de cambio de control cae en el rango: 0xB0 a
0xBF, y el primer byte de datos es el nmero de controlador en el rango [0,127].
El segundo byte especifica el valor a establecer para el controlador determinado.

Pitch Wheel: denominado tambin rueda de modulacin. Este mensaje es usado


para desplazar la altura tonal de un nota. La rueda de modulacin es medida por
el dcimo cuarto bit. El valor central es 0x2000.
Respecto al byte de estado, est dentro del rango 0xE0 a 0xEF, mientras que los
dos byte de datos deberan combinarse para formar un valor de 14 bits. Los bits
0 a 6 del segundo byte son realmente los bits del 7 al 13 del valor de 14 bits. De
esta forma tendramos el siguiente procedimiento en C++ para realizar la
combinacin:
unsigned short CombineBytes(unsigned char First, unsigned char
Second)
{
unsigned short _14bit;
_14bit = (unsigned short)Second;
_14bit <<= 7;
_14bit |= (unsigned short)First;
return(_14bit);
}

92

C A P T U L O 4 Introduccin a MIDI
4.3.2 Mensajes de sistema
Estos mensajes son transmitidos globalmente a cada dispositivo dentro de la red
MIDI, puesto que no se utiliza en ellos el nmero de canal. Cualquier dispositivo
responder a los mensajes del sistema independientemente del canal. A continuacin se
enumeran los diferentes mensajes de sistema MIDI:


System exclusive: sirve para comunicar con el dispositivo informacin


independiente del protocolo MIDI. En la seccin siguiente (4.3.3) se examinar
este mensaje con ms detenimiento.

Song Position Pointer: algunos dispositivo maestros que controlan la secuencia


de reproduccin envan este mensaje para forzar a un dispositivo esclavo a poner
en la cola una cierta posicin de la secuencia. Este mensaje no comienza
inmediatamente la reproduccin, simplemente pone al dispositivo preparado
para la reproduccin en una particular posicin en la secuencia.
El byte de estado tiene el valor 0xF2 y los bytes de datos, al igual que en el caso
de la rueda de modulacin, tienen que ser combinados en un valor de 14 bits. El
valor de 14 bits es el MIDI Beat en el que comenzar la secuencia. Se asume que
la secuencia comienza en el MIDI Beat 0. Cada MIDI Beat utiliza 6 pulsos
MIDI. Es decir, cada MIDI Beat es un deciseisavo de nota.
Ejemplo: Si el valor del Song Position Pointer es 8, el secuenciador debera
poner en la cola al tercer cuarto de nota de la secuencia:
8 MIDI Beats x 6 pulsos de reloj MIDI por Beat = 48 pulsos MIDI
ya que hay 24 pulsos en de nota.

Song select: los dispositivos maestros MIDI envan este mensaje para comenzar
el playback de una cancin.
El byte de estado es 0xF3, y el byte de datos es una valor comprendido entre 0 y
127 que indica el nmero de secuencia o cancin.

Tune request: mensaje que tambin se traduce como peticin de tono. Este
mensaje se utiliza para solicitar al dispositivo un cambio de calibracin tonal.
Con frecuencia se implementa en mdulos de sonido con circuitos osciladores
analgicos.
El byte de estado es el valor 0xF6 y no contiene byte de datos.

End of system exclusive: indica el final de un mensaje de sistema exclusivo.

93

C A P T U L O 4 Introduccin a MIDI
4.3.3 Mensajes de sistema exclusivo
Estos mensajes permiten a los fabricantes y programadores de sistemas MIDI
comunicar informacin especfica para la configuracin del dispositivo.
El principal uso del mensaje es para enviar una gran cantidad de datos en formato no
estructurado MIDI, como volcados de la memoria de patches, datos del secuenciador o
datos de formas de onda. Por ejemplo, un mensaje SysEx podra se utilizado para
establecer el nivel de retroalimentacin para un operador en un sintetizador de
modelado fsico de Roland .
El formato de transmisin de un mensaje de sistema exclusivo (figura 4.13),
como se define en el estndar MIDI, incluye un byte de estado (arranque) de sistema
exclusivo (0xF0) y un byte de parada EOX (0xF7).
0xF0 0x43 0x25 ... ... ... ... ... ... 0xF7

Figura 4.13 Estructura de mensaje de sistema exclusivo


El byte ms importante despus del 0xF0 (SOX) debera ser el identificador de
fabricante, as, por ejemplo para la marca Korg tendramos el byte 0x42 y para la
empresa Kurzweil el byte 0x07.

A continuacin se muestran algunos ejemplos de utilizacin de los mensajes de


sistema exclusivo:

Transmisin de datos de sonido (patches) entre sintetizadores con tabla de


ondas.
Copia de seguridad de los sonidos actuales almacenados en la EPROM del
sintetizador. Este proceso se lleva a cabo haciendo un volcado (dump) de los
datos del sintetizador a un ordenador para ser almacenados en un disco u otro
tipo de memoria secundaria.
Obtencin de sonidos de la Web. Internet permite acceder a un gran banco de
muestras de sonido (patches) de sistema exclusivo. Tan slo es necesario
descargar el fichero en formato .syx compatible con el modelo de sintetizador y
proceder a su envo desde el ordenador a travs de un puerto MIDI.
Control y edicin MIDI en tiempo real basada en sistema exclusivo. Los editores
de sonido proporcionados por los fabricantes del dispositivo permiten alterar y
enviar cambios de los parmetros digitales a la configuracin del sistema. As,
es posible cambiar las variables del sonido, la secuenciacin, los osciladores,
etc. En la imagen 4.14 puede verse un editor de sonidos para el sintetizador
Korg X5D.

Es necesario recalcar que los datos de sistema exclusivo tomados de la red o de


disco suelen codificarse utilizando varios estilos de formato de archivo de sistema
exclusivo (no hay por lo tanto estandarizacin). Debido a esto, los volcados de
memoria se codifican utilizando utilidades software de sistema exclusivo estndar,
fcilmente disponibles para Mac o PC (figura 4.14).
Tambin es posible encontrar datos de sistema exclusivo en ficheros MIDI estndar.
Este sistema almacena los datos en una pista o track del archivo MIDI.

94

C A P T U L O 4 Introduccin a MIDI

Figura 4.14 Editor de sonidos para envo por sistema exclusivo


4.3.4 Mensajes de modo
Este tipo de mensajes se utilizan para enviar al dispositivo receptor parmetros de
configuracin MIDI para recibir los mensajes de canal. Como se ver a continuacin, el
modo 3 es el ms utilizado, ya que es el ms potente, en detrimento del uso actual de los
otros modos.

Modo 1 omni on/poly: Es el ms simple de todos. Con este mensaje si un


dispositivo enva un mensaje (note on) por el canal 7 y otro por el canal 10, el
receptor en modo Omni ignorar los canales por los que lleguen, reproduciendo
las dos notas a la vez. Omni on indica que no se consideran los canales y Poly
que puede reproducir ms de una nota a la vez.
Modo 2 omni on/mono: Es idntico al modo 1, excepto que slo permite una
nota a la misma vez.
Modo 3 omni off/poly: Es el modo ms potente de los cuatro y el ms
comnmente usado. Omni off indica que s considera los canales en que recibe,
por lo tanto, selecciona lo que reproduce. Poly indica que es posible reproducir
ms de una nota a la vez.
Modo 4 omni off/mono: Este modo es bsicamente una versin monofnica del
modo 3. Esta variante slo permite una nota a la vez en cada canal.

95

C A P T U L O 4 Introduccin a MIDI
4.3.5 Mensajes de tiempo real
Los mensajes de tiempo real, que consisten en un solo byte de estado, estn
comprendidos en el rango [0xF8,0xFF]. Estos mensajes estn principalmente
relacionados con la temporizacin y sincronizacin. MIDI permite que los mensajes de
tiempo real sean enviados en cualquier momento, incluso intercalados con otros
mensajes MIDI. Por ejemplo, un mensaje en tiempo real podra ser enviado entre los
dos bytes de datos de un mensaje note on. Un dispositivo debera siempre estar
preparado para manejar cada situacin; procesando el byte de tiempo real, y
subsiguientemente continuar procesando el mensaje anteriormente interrumpido.
A continuacin se enumeran los mensajes de tiempo real utilizados en MIDI:


MIDI Clock: algunos dispositivos maestros que controlan la reproduccin de la


secuencia envan este mensaje para mantener al dispositivo esclavo en sincrona
con el maestro. Un mensaje de tiempo MIDI se enva a intervalos regulares
(basados en el Tempo del maestro) para realizar esta tarea.
El mensaje de reloj de tiempo contiene el byte de estado 0xF8, mientras que no
contiene ningn byte de datos.
En la seccin 4.4 comentaremos con ms detalle los aspectos relacionados con el
reloj y la sincronizacin MIDI.

MIDI Tick: como en el caso anterior, algunos dispositivos maestros envan este
mensaje para mantener las sincrona con el receptor. Este mensaje es enviado a
intervalos regulares de uno cada 10 ms.
El byte de estado contiene el valor 0xF9 y no tiene datos.

MIDI Start: indica al dispositivo esclavo que debe comenzar la reproduccin de


una secuencia o una cancin. Comienza siempre en el MIDI Beat 0.
El byte de estado es 0xFA y no contiene datos.

MIDI Stop: es el opuesto al anterior. Indica al dispositivo esclavo que detenga


la secuencia o la cancin.
El byte de estado es 0xFC y no tiene datos.

MIDI Continue: para continuar la reproduccin de la secuencia o cancin por


donde se haba detenido anteriormente, o puesto en cola con el mensaje Song
Position Pointer.
El byte de estado es 0xFB y no contiene datos.

Reset: Reinicia el dispositivo a la configuracin por defecto como si se hubiera


encendido de nuevo.
El byte de estado es 0xFF y no tiene bytes de datos.

96

C A P T U L O 4 Introduccin a MIDI


Active Sense: Este mensaje se enva cada 300 ms si no ha habido actividad en el


bus MIDI. Esto permite indicar a los dispositivos que hay una buena conexin
entre ellos.
El byte de estado es 0xFE y tampoco contiene datos.
En la figura 4.15 puede verse el algoritmo del mensaje Active Sense. Se asume
que los dispositivos tienen un timer hardware que se incrementa cada
milisegundo. Una variable llamada timeout se utiliza para incrementar los
milisegundos transcurridos. Otra variable llamada flag se activa cuando el
dispositivo recibe un mensaje homnimo de otros dispositivo, y
consecuentemente espera a recibir ms mensajes Active Sense de ese
dispositivo.

In t e r r u p c i n
d e l t im e r

Interru pci n
d e recepci n
M ID I

F la g = 0

R ecib e
d atos

F la g = 1
In c r e m e n t a
t im e o u t

Inicia la
variable d e
tim eou t

S A L ID A

t im e o u t < = 3 0 0 m s

no 0xF E

?
t im e o u t > 3 0 0 m s

0xFE
Establece
el flag

S AL ID A

a algu na o tra
o peracin

D e s a c t iv a
t o d a s la s
n o ta s

S A L ID A

In ic ia e l
f la g

S A L ID A

Figura 4.15 Algoritmo Active Sense

97

C A P T U L O 4 Introduccin a MIDI

4.4 Sincronizacin y tiempo MIDI


Hay 24 pulsos MIDI en cada cuarto de nota (un cuarto de nota equivale a una
negra), 12 pulsos MIDI en un octavo de nota, 6 pulsos en un dieciseisavo, etc. Por lo
tanto, cuando un dispositivo esclavo cuenta 24 pulsos de reloj MIDI, sabe que ha
transcurrido de nota. Obviamente, la frecuencia a la que el reloj maestro se
incrementa depende del Tempo. Por ejemplo, para un tempo de 120 BPM, es decir, 120
cuartos de nota en cada minuto, el maestro enva un pulso cada 20833 microsegundos.
Sabiendo que hay 106 microsegundos en un segundo y que un minuto contiene 60 x 106
microsegundos. En un tempo de 120 BPM, hay 120 cuartos de nota por minuto. Como
hay 24 pulsos MIDI en un cuarto de nota, en consecuencia, debera haber 24 x 120
pulsos MIDI por minuto. Por lo tanto, cada pulso MIDI es enviado a una frecuencia de
60 x 106 / (24 x 120) microsegundos.
El cdigo de tiempo MIDI o MIDI time code (MTC) incorpora el formato de
tiempo absoluto: horas, minutos, segundos y cuadros, al flujo de datos MIDI. Es uno de
los ms recientes cdigos de tiempo utilizados en MIDI.
Con el mensaje Song Position Pointer se pueden sincronizar las secuencias o canciones
entre dispositivos MIDI con suficiente exactitud, aunque surgen problemas cuando hay
que sincronizarlos, por ejemplo, con grabadoras de vdeo o procesadores de sonido. El
cdigo de tiempo utilizado internacionalmente para estos aparatos es el SMPTE que es
el acrnimo de Society of Motion Pictures & Television Engineers y utiliza, al igual que
MTC el tiempo absoluto. El formato SMPTE es muy eficaz y permite sincronizar con
mucha eficacia aparatos muy heterogneos. Es posible convertir el formato MTC a
SMPTE y al contrario.

Figura 4.16 Secuenciador MIDI Rosegarden


98

C A P T U L O 4 Introduccin a MIDI

Bibliografa y referencias
Libros
Tcnicas de Grabacin modernas David Miles Huber, Robert E. Runstein, 6 edicin.
Editorial Omega, 2007.
Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y Vdeo Manuel-Alonso
Castro Gil, Antonio Colmenar Santos, Pablo Losada de Dios, Juan Peire Arroba.
Editorial Ra-ma, 2002.
La Web
MIDI Manufacturers Association:
http://www.midi.org/
MIDI specification:
http://home.roadrunner.com/~jgglatt/
Wikipedia:
http://es.wikipedia.org/wiki/MIDI

Lista de figuras obtenidas de Internet


http://www.amazona.de/media/articles/article_images/article_697/1_prop
het600.jpg
Figura 4.2 http://www.nopianonoproblem.com/files/other/MIDI_SetupOptions_Larg
e.jpg
Figura 4.3 http://www.etcetera.co.uk/products/images/EMU300big.jpg
Figura 4.4 http://www.generalmanual.com/img/0902/roland-jv-2080-synthesizermodule.jpg
Figura 4.8 http://www.fortunecity.com/emachines/e11/86/graphics/midi/MIDI5.gif
Figura 4.9 http://www.savedbytechnology.com/2003/yamaha_my16-mlan.jpg
Figura 4.14 Software del sintetizador Korg X5D
http://www.les-stooges.org/pascal/midiswing/index.php
Portada
Figura 4.1

99

C A P T U L O 5 Programacin MIDI

Programacin MIDI

5.1 Introduccin
Una vez examinados los conceptos bsicos sobre la tecnologa MIDI es momento de
programar el sistema para modificar en tiempo real eventos y mensajes. De esta forma,
es posible realizar aplicaciones que se ajusten a las demandas actuales de edicin de
msica, as como programas de control de dispositivos a travs de mensajes MIDI.
La programacin MIDI se ha vuelto fundamental en la programacin de sistemas, pues
se utiliza en un amplio rango de aplicaciones, desde investigacin hasta videojuegos.
Actualmente se hace necesaria alguna herramienta que permita a los ingenieros y
programadores desarrollar software musical y de acceso a las funciones bsicas de los
dispositivos MIDI. De esta manera, se consigue una abstraccin del software de bajo
nivel, proveyendo una arquitectura orientada a objetos y estratificada que permita el
diseo de software robusto y complejo compuesto por una gran cantidad de
componentes.
En los principios de los aos 90, desarrollar una aplicacin de acceso a MIDI sobre
una plataforma de 16 bits como era Atari (muy utilizado en la industria en aquella
poca), supona desarrollar una aplicacin basada en una ingeniera de software no
orientada a objetos, pero estructurada y modular, implementada en un lenguaje como C
donde el acceso al hardware MIDI del computador se haca a travs de funciones de
envi de bytes a puertos, y en su extremo, programando directamente en ensamblador.
Posteriormente, con la aparicin de los sistemas operativos modernos de 16 y 32 bits
como Windows, Linux y Mac/OS, han provisto una API (Interfaz de Programacin de
Aplicaciones) al servicio de los programadores que, adems de abstraer la complejidad
del acceso al hardware (manejado por las capas de E/S y la mquina virtual del sistema
operativo) proporciona un conjunto de servicios para acceder a todas las funciones que
MIDI posee. La ventaja de este enfoque moderno permite desarrollar software MIDI
que funcionar con cualquier fabricante de hardware sin la necesidad de modificar el
cdigo fuente del programa.
Actualmente en Windows existe la posibilidad de desarrollar aplicaciones MIDI
utilizando dos APIs diferentes: la Windows Multmedia API y la API DirectMusic de
DirectX. En este estudio nos centraremos en esta ltima.
Otras libreras MIDI de alto nivel profesionales para C++ existentes en Internet son:

CLAM: C++ library for audio music. Desarrollada en la Universidad Pompeu


Fabra de Barcelona por el Grupo de Tecnologa Musical.
The Synthesis Toolkit in C++: Desarrollado por la Universidad de Standford.
Maximum MIDI music applications in C++. Libro sobre MIDI que contiene una
librera sobre la API Windows Multimedia.
DirectMIDI: Librera de software libre que se explicar en este captulo.

101

C A P T U L O 5 Programacin MIDI

5.2 La API DirectMusic de DirectX


Como se explic en el captulo 2, DirectMusic es un componente ms de la librera
de alto rendimiento para multimedia DirectX, junto con DirectSound y DirectShow.
DirectMusic permite que los efectos de sonido y la msica sean compuestos y
reproducidos con un control flexibe e interactivo.
Arquitectnicamente, DirectMusic es un conjunto de objetos de alto nivel, construidos
sobre DirectSound que permite la reproduccin de sonido y msica sin la necesidad de
utilizar las funciones de bajo nivel de DirectSound. DirectMusic trabaja con datos de
msica basados en mensajes. La msica puede ser sintetizada va hardware directamente
con los puertos que proporciona el fabricante o con el Sintetizador software de
Microsoft.
La historia de la API de DirectMusic se remonta al ao 1996 cuando fue lanzado por
primera vez como un componente ActiveX, llamado Iteractive Music Architecture
(IMA). Fue introducido inicialmente como parte de la versin 6.1 de DirectX en febrero
de 1999 e incluido en todos los sistemas operativos Windows 98 segunda edicin.
5.2.1 Caractersticas principales
DirectMusic provee un sistema completo para la implementacin de soundtracks
(pistas) utilizando las ventajas de la aceleracin hardware, sonidos descargables
(downloadable sounds) y los Objetos Media DirectX (DMOs), posicionamiento
avanzado de efectos en 3D, entre otras muchas ms caractersticas.
En DirectMusic, la msica es generada en tiempo real y no de forma esttica,
proporcionado funcionalidades para la reproduccin con variaciones y responder a
eventos flexibles de programas va MIDI. Entre las caractersticas avanzadas caben
destacar:

102

Carga y reproduccin de sonidos desde ficheros o recursos MIDI, WAV y


ficheros propietarios.
Monitorizacin del tiempo de los eventos musicales con alta precisin. Permite
adems la captura del tiempo de los datos MIDI en el momento de su recepcin
utilizando un reloj de referencia del sistema de alta resolucin.
Permite que la msica y los efectos sean rpidos y dinmicamente cambiados en
tiempo real en respuesta a eventos del usuario. En este aspecto, resuelve los
problemas de rendimiento de la API Multimedia bsica de Windows(funcin
midiout).
Reproduce mltiples fuentes de sonido a la vez.
Enva eventos de tempo, cambios de programa (patch) y otros eventos MIDI de
forma programada.
Utilizacin de los sonidos descargables (Downloadable sounds), un estndar de
La Asociacin de Fabricantes MIDI (MMA), permitiendo a los desarrolladores
la salida de datos de audio de tabla de ondas sobre hardware de audio no
equipado con sntesis de tabla de ondas.
En los ordenadores sin un hardware sintetizador de tabla de ondas, el
Sintetizador Software de Microsoft permite emular un hardware de tabla de
ondas, consiguiendo que las aplicaciones tengan un resultado homogneo en
todos los sistemas.
Posicionamiento del sonido en un espacio tridimensional.

C A P T U L O 5 Programacin MIDI

Posibilidad de aplicar efectos de sonidos como Chorus, Reverb, Delay, Flanger,


Echo, Distortion, Gargle, etc.
Uso de ms de 16 canales MIDI. Por medio de la utilizacin de los objetos
performance es posible reproducir hasta 216 65536 canales MIDI.
Con la utilizacin de los audiopaths los efectos de espacializacin pueden ser
aplicados individualmente a cada sonido.
Captura de datos MIDI, permitiendo la redireccin del flujo de un puerto de
entrada a otro de salida.

5.2.2 Principales interfaces COM


Como pudimos ver en el captulo 2, DirectX est basado en tecnologa COM
(Modelo de objetos componentes) que se describi detalladamente en la seccin 2.1.6.
DirectMusic est compuesto de varias interfaces COM que abstraen la funcionalidad de
las aplicaciones musicales MIDI. Las principales interfaces son las siguientes:

IDirectMusic8: provee mtodos para manejar buffers, puertos y el reloj


maestro. Slo debera haber una instancia de esta interfaz por aplicacin.

IReferenceClock: esta interfaz estndar proporciona acceso al reloj maestro que


es un timer hardware en modo kernel con una alta resolucin y es usado para
sincronizar todo el playback de audio en el sistema. El mtodo
IReferenceClock::GetTime devuelve el tiempo como un entero de 64 bits
(definido como un tipo REFERENCE_TIME) en incrementos de 100s o
nanosegundos.

IDirectMusicPort8: proporciona acceso al objeto DirectMusicPort, que


representa un dispositivo que recibe y enva datos MIDI, por ejemplo, el puerto
de entrada de un MPU-401, el puerto de salida de un MPU-401 o el sintetizador
software de Microsoft.

IDirectMusicThru8: permite la redireccin de mensajes de un puerto de


entrada a otros puertos de salida. El mtodo IDirectMusicThru8::ThruChannel
es utilizado para establecer o romper la conexin thru desde un canal de entrada
en un puerto MIDI a otro canal de salida de otro puerto MIDI.

IDirectMusicBuffer8: representa un buffer que contiene datos (normalmente


en forma de mensajes MIDI) para ser secuenciados por un puerto. El buffer
contiene una pequea cantidad de datos(normalmente menos de 200ms). Este
buffer es creado con al menos 32 bytes de datos MIDI estndar.

IDirectMusicLoader8: se usa para la carga de objetos DirectMusic tales como


segmentos, ficheros MIDI, ficheros WAV y DLS.

IDirectMusicCollection8: maneja un conjunto de instrumentos de un fichero


DLS y contiene mtodos para descargarlos a un puerto de un sintetizador.

103

C A P T U L O 5 Programacin MIDI

IDirectMusicIntrument8: esta interfaz representa un instrumento individual de


una coleccin DLS que es descargado posteriormente a un sintetizador usando el
mtodo IDirectMusicPort8::DownloadInstrument.

IDirectMusicDownloadedInstrument8: es usada para identificar un


instrumento descargado en un sintetizador. El puntero a la interfaz es usado ms
tarde para liberar el instrumento de la memoria del sintetizador a travs de una
llamada al mtodo IDirectMusicPort8::UnloadInstrument.

IDirectMusicPortDownload8: permite a una aplicacin comunicarse


directamente con un puerto que soporte descarga DLS para descargar bloques de
memoria directamente al puerto.

IDirectMusicDownload8: representa un bloque contiguo de memoria utilizado


para la descarga a un puerto DLS.

5.3 Desarrollando aplicaciones con la librera DirectMIDI


5.3.1 Introduccin
La librera DirectMIDI es una coleccin de clases C++ basadas en DirectMusic con
la intencin de mejorar el desarrollo software bajo la tecnologa de audio y MIDI. La
capa software est diseada con una precisa orientacin a objetos para facilitar la
construccin de aplicaciones e integracin en la arquitectura. El framework
proporciona, adems, un sistema de prevencin de errores y su facilidad de uso hace que
DirectMIDI sea la herramienta ideal para desarrolladores que estn buscando una
librera de audio y MIDI estable, amigable, segura y en el estado del arte.
El proyecto se encuentra en fase beta aunque hay una versin estable desde la 2.3.
Desde la versin 2.1 se considera adems software libre, liberada bajo los trminos de
GNU(General Public License) y publicada como artculo en la revista electrnica sobre
programacin CodeProject.
El diseador y programador de la librera es el autor de este proyecto, que dedic dos
aos a su desarrollo y evaluacin ntegros.
Actualmente se puede acceder a los ficheros fuente desde el repositorio de software
libre de SourceForge, en la URL: http://directmidi.sourceforge.net

104

C A P T U L O 5 Programacin MIDI

Figura 5.1 Pgina principal de la librera DirectMIDI

Figura 5.2 Aplicacin de muestra de la librera DirectMIDI

105

C A P T U L O 5 Programacin MIDI
5.3.2 Esquema de la arquitectura DirectMIDI
El ncleo principal de la librera est basado en sus diez clases relacionadas que
definen los diferentes objetos involucrados en una aplicacin basada en MIDI y que
encapsulan el cdigo para llevarlo a cabo.
El siguiente diagrama de colaboracin muestra los objetos creados por una aplicacin
que usa DirectMIDI:
Exceptions

CMasterClock

CInputPort

CReceiver

CDirectMusic

CDLSLoader

CCollection1..i

COutputPort

CInstrument1..j

Initialize
DownLoad / UnLoad

DirectMusic
main
objects

MIDI ports

External MIDI - Synthesizer with


SysEx Events DLS support

CDMusicException

CSampleInstrument
1..n

Exception
handling

Figura 5.3 Diagrama de colaboracin de objetos


Como podemos observar, hay un objeto del tipo CDirectMusic que encapsula la
inicializacin COM de una aplicacin Win32. Este objeto es el responsable de iniciar
los objetos que representan los puertos MIDI que se dividen en dos categoras: puertos
de entrada para mensajes de entrada MIDI tales como mensajes de sistema exclusivo o
mensajes MIDI 1.0 y puerto de salida MIDI para enviar mensajes en formato sistema
exclusivo o MIDI 1.0. Hay un objeto adicional llamado CMasterClock que proporciona
una enumeracin y seleccin de un timer hardware como reloj maestro.
Hay otros tres objetos relacionados con el objeto COutputPort directa e indirectamente,
este es el caso del objeto CDLSLoader que es el responsable de cargar ficheros DLS
para almacenarlos en un objeto CCollection. Este objeto representa un conjunto de
instrumentos en formato DLS 1.0 2.0 y permite extraer sus instrumentos a mejores
contenedores para ellos, llamados objetos CInstrument. Estos son los responsables de
mantener una instancia de un objeto particular para un mejor control y organizacin.
Una vez se hayan seleccionado todos los instrumentos de la colecciones, se puede
proceder a descargarlos a un programa MIDI especfico en un sintetizador para
reproducirlos.
Adems del objeto CInstrument, hay otro objeto similar proporcionado por la librera
DirectMIDI que permite almacenar formas de onda en formato WAV o en formato
PCM generadas de forma programtica. Este objeto, llamado CSampleInstrument,

106

C A P T U L O 5 Programacin MIDI
proporciona funciones de ayuda para ajustar envolventes, LFOs (Osciladores de baja
frecuencia) y regiones (zonas activas del teclado) antes de descargarlos al puerto de
salida.
Finalmente, el objeto CDMusicException maneja todas las excepciones producidas en la
aplicacin y muestra informacin detallada sobre el problema que gener el error.
5.3.3 Comenzando la aplicacin
5.3.3.1 Primer paso: Configurar el entorno de desarrollo
Es posible comenzar la aplicacin en muchos tipos diferentes de proyectos con
Visual Studio y la librera DirectMIDI, tales como una aplicacin MFC, Win32 bsica o
Win32 en modo consola1.
Para poder compilar una aplicacin DirectMIDI necesitamos aadir al proyecto los
siguientes ficheros cabecera: CDirectMidi.h, CDirectBase.h y CMidiPart.h. Por ltimo
es necesario aadir tambin al proyecto todos los ficheros .cpp que aparecen dentro del
directorio directmidi.
Tambin se requiere tener instalada una versin actualizada del SDK de DirectX, en
este caso se ha utilizado la versin 9.0c. Finalmente necesitamos aadir al IDE de
Visual C++ las rutas de las dependencias (.lib) y ficheros cabecera (.h) del SDK de
DirectX, que normalmente se encuentran localizados en los directorios lib que incluye
el paquete de instalacin.
5.3.3.2 Segundo paso: Las primeras lneas de cdigo
El compilador debera saber cual es el cdigo externo que se est utilizando en el
fichero .cpp actual de trabajo. Por ello se debe utilizar la directiva #include para indicar
al compilador qu otros recursos fuente son necesarios para la compilacin. Las
cabeceras (includes) requeridas se muestran en el siguiente cdigo:
// Cabeceras ANSI I/0
#include <conio.h>
#include <iostream>
#include <math.h>

// La librera DirectMIDI
#include ".\\DirectMidi\\CDirectMidi.h"

// Inclusin de
#pragma comment
#pragma comment
#pragma comment
#pragma comment

la libreras necesaria en lnea


(lib,"dxguid.lib") // Definiciones GUID
(lib,"winmm.lib")
(lib,"dsound.lib")
(lib,"dxerr9.lib")

using namespace std;


using namespace directmidi;
// Tamao mximo para los datos de System Exclusivo

Preferiblemente se utilizar el IDE Microsoft Visual C++ .NET 7.1.

107

C A P T U L O 5 Programacin MIDI
const int SYSTEM_EXCLUSIVE_MEM = 48000;
// Define PI
const double PI = 3.1415926;

La directiva #pragma comment indica al linkador que cree un fichero obj con las
libreras necesarias. Las ltimas lneas de cdigo indicadas anteriormente contienen
constantes simblicas necesarias para el ejemplo.
5.3.3.3 Tercer paso: preparando la captura de msica
La clase CInputPort es la responsable de manejar eventos de entrada MIDI. Estos
eventos MIDI son capturados por un thread que invoca a dos mtodos virtuales puros
sobrecargados de la clase CReceiver; dependiendo del tipo de dato MIDI llegado al
puerto. Estos dos diferentes tipos de datos pueden ser: datos MIDI no estructurados (en
forma de Sistema Exclusivo) y datos MIDI estructurados (mensajes MIDI Standard
1.0).
Para sobrecargar estas funciones virtuales puras, es necesario derivar una clase de
CReceiver como se muestra en el siguiente fragmento de cdigo:
// Clase heredada de CReceiver
class CDMReceiver:public CReceiver
{
public:
// Funciones sobrecargadas
void RecvMidiMsg(REFERENCE_TIME rt,DWORD dwChannel,DWORD
dwBytesRead,BYTE *lpBuffer);
void RecvMidiMsg(REFERENCE_TIME rt,DWORD dwChannel,DWORD dwMsg);
};

Una vez realizada esta operacin, podemos implementar parte del cdigo de
procesamiento de eventos:
// Funcin sobrecargada para la captura de datos en Sistema Exclusivo
void CDMReceiver::RecvMidiMsg(REFERENCE_TIME lprt,DWORD
dwChannel,DWORD dwBytesRead,BYTE *lpBuffer)
{
DWORD dwBytecount;
// Imprime el buffer recibido
for (dwBytecount = 0;dwBytecount < dwBytesRead;dwBytecount++)
{
cout.width(2);
cout.precision(2);
cout.fill('0');
cout << hex <<static_cast<int>(lpBuffer[dwBytecount])<< "
";
if ((dwBytecount % 20) == 0) cout << endl;
if (lpBuffer[dwBytecount] == END_SYS_EX)
cout << "\nMemoria del sistema volcada" << endl;

108

C A P T U L O 5 Programacin MIDI

}
}

// Funcin sobrecargada para la captura de datos MIDI estructurados


void CDMReceiver::RecvMidiMsg(REFERENCE_TIME lprt,DWORD
dwChannel,DWORD dwMsg)
{
unsigned char Command,Channel,Note,Velocity;
// Extrae parmetros MIDI del mensaje
CInputPort::DecodeMidiMsg(dwMsg,&Command,&Channel,&Note,&Velocit
y);
if (Command == NOTE_ON) //Channel #0 Note-On
{
cout << " Received on channel " <<
static_cast<int>(Channel) <<
" Note " << static_cast<int>(Note) << " with velocity " <<
static_cast<int>(Velocity) << endl;
}
}

La primera funcin lee los datos del buffer en formato Sistema Exclusivo, imprime
los valores en base numrica hexadecimal y detecta cundo el sintetizador alcanza el
final del volcado de datos (el byte 0xF7 de fin de datos exclusivos). Es importante saber
que no todos los datos SysEx son recibidos en una nica llamada RecvMidiMsg, se
pueden producir mltiples llamadas consecutivas a esta funcin miembro.
La segunda funcin sobregcargada gestiona mensajes estndar MIDI, tales como
note on o cambio de programa, en formato de doble palabra. Si se necesita parsear el
mensaje en partes se debe usar el mtodo esttico CInputPort::DecodeMidiMsg para
extraer cada byte componente MIDI.
5.3.3.4 Cuarto paso: inicilizando objetos
En este paso se declaran los principales objetos que sern usados a lo largo de la
aplicacin. Son lo siguientes:
int main(int argc, char* argv[])
{
CDirectMusic CDMusic;
CInputPort
CInPort;
CDMReceiver Receiver;
COutputPort COutPort;
CDLSLoader
CLoader;
CCollection CCollectionA,CCollectionB;
CInstrument CInstrument1,CInstrument2;
CSampleInstrument CSample1,CSample2;

La primera lnea declara un objeto del tipo CDirectMusic que es el responsable de


instanciar e inicilizar DirectMusic y ser el ltimo objeto en ser destruido. El siguiente
objeto es CInputPort que maneja los puertos de entrada. El tercero es el objeto

109

C A P T U L O 5 Programacin MIDI
CDMReceiver que es una clase derivada de CReciever y que implementa las funciones
sobrecargadas vistas en el aparatado anterior. El objeto COutputPort es el responsable
de enviar datos al dispositivo y de descargar datos en el puerto. Los ltimos objetos
gestionan los sonidos descargables que sern comentados en el siguiente paso.
Ahora es posible comenzar a llamar a los mtodos y activar todo el sistema MIDI. A
continuacin se explica como conseguir este propsito:
try
{
// Inicializa DirectMusic
CDMusic.Initialize();
// Inicializa los puertos dado un objeto gestor de DirectMusic
COutPort.Initialize(CDMusic);
CInPort.Initialize(CDMusic);

El siguiente fragmento de cdigo muestra cmo activar los puertos de entrada y salida:
// Etructura de informacin para el puerto
INFOPORT PortInfo;
DWORD dwPortCount = 0;
//Seleccin del sintetizador software
do
COutPort.GetPortInfo(++dwPortCount,&PortInfo);
while (!(PortInfo.dwFlags & DMUS_PC_SOFTWARESYNTH));
COutPort.SetPortParams(0,0,1,SET_REVERB | SET_CHORUS,44100);
COutPort.ActivatePort(&PortInfo,32);
// Activacin del puerto de salida a partir de la estructura de
informacin
cout << "\nPuerto de salida seleccionado: " <<
PortInfo.szPortDescription << endl;
// Activacin del puerto de entrada, selecciona el primero (por
defecto)
CInPort.GetPortInfo(1,&PortInfo);
CInPort.ActivatePort(&PortInfo,SYSTEM_EXCLUSIVE_MEM);
// Activa el objeto receptor
CInPort.SetReceiver(Receiver);

Las primeras lneas enumeran todos los puertos de salida y seleccionan el primer
sintetizador software existente en el sistema, dado un nmero desde 1 hasta el valor de
COutputPort::GetNumPorts en el primer parmetro de COutputPort::GetPortInfo.

110

C A P T U L O 5 Programacin MIDI
Antes de llamar a COutputPort::ActivatePort necesitamos llamar al mtodo
COutputPort::SetPortParams para indicar el tipo de caractersticas que se necesitan en
el puerto de salida (si se pasa el valor cero como parmetro, se asumir la configuracin
por defecto para ese parmetro). Posteriormente se llamar a la funcin
COutputPort::ActivatePort pasando un puntero a una estructura INFOPORT para
activar el puerto de salida, usando los parmetros del nmero de grupo de canales y una
frecuencia de muestreo pasada en la llamada a COutputPort::SetPortParams. El
parmetro de canal de grupo es el nmero de grupos de canales MIDI para ser utilizados
en el puerto software, cada grupo de canal es un conjunto de 16 canales MIDI.
Uno de los parmetros configurables ms importantes en el mtodo
COutputPort::SetPortParams es el parmetro de la frecuencia de muestreo, que es la
frecuencia en Hertzios que se necesita para establecer la calidad del sonido en el puerto
de salida. En este caso se asumen 44100 Hz como frecuencia de muestreo.
En las ltimas tres lneas se selecciona el puerto de entrada MIDI para la captura de
mensajes, realizando operaciones similares. En este caso no se lleva a cabo ninguna
enumeracin, se limita a seleccionar el primer puerto de entrada por defecto. Es
importante advertir que hay un segundo parmetro en el mtodo
CInputPort::ActivatePort que indica el tamao de memoria mximo reservado para
albergar datos en formato de sistema exclusivo. En este caso slo se reservan 46.8
Kilobytes. Si se deja este parmetro opcional, el valor por defecto ser 32 bytes,
suficiente espacio para recibir datos MIDI estructurados estndar.
Finalmente, se establece un objeto receiver por medio de una llamada al mtodo
CInputPort::SetReceiver. Si cerramos la llave de sentencia principal y se ejecuta la
aplicacin se obtendr la siguiente salida:

Figura 5.4
5.3.3.5 Quinto paso: comenzar la captura de msica
Capturar datos musicales desde un teclado externo es muy simple tan pronto como
se haya inicializado el puerto de entrada. Si reservamos espacio para recibir datos en
sistema exclusivo en la llamada a CInputPort::ActivatePort, ahora la aplicacin estar
preparada para manejar todos los eventos de entrada generados por un teclado
controlador o un sintetizador. El siguiente cdigo explica como realizar la captura:
//Activa la recepcin de mensajes de entrada
CInPort.ActivateNotification();
cout << "Notificacion activada" << endl;
// Redirige mensajes del canal global 0 al canal de destino
global 0
CInPort.SetThru(0,0,0,COutPort);

Como podemos observar, la primera lnea de cdigo activa la notificacin de todos


los mensajes de entrada MIDI usando un manejador de eventos que invoca a su
respectiva funcin miembro virtual ya sobrecargada en la primera parte de la aplicacin.

111

C A P T U L O 5 Programacin MIDI
Otra caracterstica de DirectMIDI es la redireccin. Usando la redireccin (MIDI thru)
se pueden pasar mensajes MIDI desde un puerto de entrada activado a otro puerto de
salida especificando un canal de grupo y el canal global de origen y de destino donde
los mensajes sern redireccionados.
La siguiente salida muestra un volcado de datos en sistema exclusivo y una captura de
datos MIDI estndar estructurados:

Figura 5.5
5.3.3.6 Sexto paso: aumentando el lmite de instrumentos
DirectMIDI soporta la carga de mltiples sonidos almacenados en ficheros DLS
(Downloadable sound files). Esta tecnologa es el estndar de los fabricantes MIDI para
un formato de fuentes de sonido en el estado del arte de la tecnologa multimedia. El
actual formato DLS2 especifica todas las definiciones de los instrumentos: muestras,
LFOs, filtros paso bajo, bucles y generadores de evolvente que sern descargados y
renderizados en un puerto que soporte estos requisitos.
DirectMIDI soporta dos tipos de operaciones DLS: DLS de alto nivel y DLS de bajo
nivel. Ambas prestaciones se comentan a continuacin.
El DLS de alto nivel es la forma de manejar instrumentos de formas de onda que
pueden ser almacenados en formatos DLS 1.0 y DLS 2.0. Estos ficheros pueden ser
creados por una aplicacin como DirectMusic Producer que permite configurar
visualmente un amplio rango de parmetros antes mencionados. El DLS de bajo nivel
permite descarga directa de bytes de datos en formato DLS 1.0 a un puerto sintetizador,
proporcionando parmetros de articulacin y regiones para el instrumento antes de la
decarga.
DLS de alto nivel:
Utilizar ficheros DLS (.dls) en una aplicacin DirectMIDI resulta flexible y sencillo.
Para este propsito debemos declarar un objeto del tipo CDLSLoader con el fin de
realizar la carga y la descarga de ficheros a la librera. Adems de este objeto, es
necesario declarar otro objeto del tipo CCollection que es un contenedor que permite
albergar objetos del tipo Cinstrument, que son la instancia ltima de mantener una
referencia al instrumento DLS. El cdigo mostrado a continuacin explica como llevar a
cabo esta tarea:
// Inicializa el objeto loader
CLoader.Initialize();
// Carga el primer fichero DLS
CLoader.LoadDLS(_T(".\\media\\sample.dls"),CCollectionA);
// Carga la coleccin GM/GS por defecto del sintetizador software

112

C A P T U L O 5 Programacin MIDI
CLoader.LoadDLS(NULL,CCollectionB);

// Estructura de informacin de un instrumento


INSTRUMENTINFO InstInfo;
DWORD dwInstIndex = 0;
// Enumera los instrumentos en la coleccin B
while (CCollectionB.EnumInstrument(dwInstIndex++,&InstInfo) == S_OK)
{
cout << "Nombre del instrumento: " << InstInfo.szInstName
<< endl;
cout << "Patch en coleccion: " <<
InstInfo.dwPatchInCollection << endl;
cout << "----------------------------------------" << endl;
}

// Obtiene el instrumento con ndice 214 de la coleccin B


CCollectionB.GetInstrument(CInstrument1,214);
// Lo asigna al programa MIDI 0
CInstrument1.SetPatch(0);
cout << "\nInstrumento seleccionado: " << CInstrument1.m_strInstName
<< endl;
cout << "Patch en la coleccion fuente " <<
CInstrument1.m_dwPatchInCollection <<
" al programa destino MIDI: " <<
CInstrument1.m_dwPatchInMidi << endl;
// Obtien el instrumento con indice 0 de la coleccion A
CCollectionA.GetInstrument(CInstrument2,0);
// Lo asigna al programa MIDI 1
CInstrument2.SetPatch(1);
cout << "\nInstrumento seleccionado: " << CInstrument2.m_strInstName
<< endl;
cout << "Patch en la coleccion fuente " <<
CInstrument2.m_dwPatchInCollection <<
" al programa destino MIDI: " <<
CInstrument2.m_dwPatchInMidi << endl;
// Establece el rango de notas
CInstrument1.SetNoteRange(0,127);
CInstrument2.SetNoteRange(0,127);
// Descarga los instrumentos a los puertos de salida
COutPort.DownloadInstrument(CInstrument1);
COutPort.DownloadInstrument(CInstrument2);

113

C A P T U L O 5 Programacin MIDI
cout << "Tocando el instrumento 1:" << CInstrument1.m_strInstName <<
endl;
cout << "Presione una tecla para reproducir el segundo instrumento..."
<< endl;
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(PATCH_CHANGE,0,0,0),0)
;
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(NOTE_ON,0,40,127),0);
getch();
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(NOTE_OFF,0,40,0),0);
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(PATCH_CHANGE,0,1,0),0)
;
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(NOTE_ON,0,60,127),0);
cout << "Tocando el instrumento 2:" << CInstrument2.m_strInstName <<
endl;
getch();
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(NOTE_OFF,0,60,0),0);

La primera lnea inicializa el objeto Loader que llama internamente a la funcin


Win32 CoCreateInstance e instancia el objeto COM en el espacio del proceso. Una vez
iniciado el objeto COM IDirectMusicLoader podemos proceder a la carga del fichero
DLS usando el mtodo CDLSLoader::LoadDLS, que toma una cadena de texto
terminada en null representando un fichero, y una referencia a un objeto CCollection de
destino donde los instrumentos definidos en el fichero sern almacenados en memoria.
Cuando la cadena de texto proporcionada es null, DirectMIDI cargar el el conjunto
estndar GM/GS definido en la EPROM del sintetizador.
Para averiguar qu instrumentos residen en el objeto CCollection debemos llamar al
mtodo CCollectionEnumInstrument que toma una variable contador indicando el
ndice deseado del instrumento en la coleccin y un puntero a una estructura
INSTRUMENTINFO que recibir la informacin del instrumento en cuestin, es decir,
el nombre del instrumento y el patch en la coleccin.
Es posible tambin obtener una referencia particular a un instrumento llamando a la
funcin sobrecargada CCollection::GetInstrument y proporcionando una referencia a un
objeto CInstrument con el ndice en la coleccin. Este mtodo inciar las propiedades
del objeto CInstrument con los datos del instrumento.
El mtodo CInstrument::SetNoteRange activa la regin del teclado que debe responder
a un evento note-on. Finalmente, es necesario proporcionar un programa MIDI destino
para el instrumento en el sintetizador, llamando a la funcin miembro
COutputPort::DownloadInstrument y pasando una referencia al objeto CInstrument.

114

C A P T U L O 5 Programacin MIDI
La siguiente imagen muestra la salida del programa que se ha comentado previamente:

Figura 5.6
DLS de bajo nivel:
DirectMIDI 2.3 permite a una aplicacin comunicarse directamente con un puerto
que soporta descarga DLS. Hay dos alternativas para descargar datos al puerto: la
primera es cargar un fichero de forma de onda PCM en formato WAV que contenga los
datos de la muestra, y la segunda es generar la forma de onda en memoria usando
funciones matemticas. En el primer caso, es necesario cargar el fichero WAV mediante
el mtodo esttico CDLSLoader::LoadWaveFile y proporcionar los siguientes tres
parmetros: un puntero a una cadena terminada en null con la ruta del fichero en disco,
una referencia a un objeto CSampleInstrument y un flag indicando el acceso deseado al
fichero. Si el flag es la constante DM_LOAD_FROM_FILE, el fichero es siempre ledo
de disco cuando sea necesario; esto es til para ficheros muy grandes. Si el flag es
DM_USE_MEMORY, el fichero permanece almacenado en memoria dinmica
aumentando la velocidad de acceso.
Respecto a la segunda alternativa antes comentada, puede ser utilizada mediante
el mtodo CSampleInstrument::SetWaveForm, pasando un puntero a un buffer de bytes
y proporcionando una estructura WAVEFORMATEX conteniendo el formato de la
forma de onda. La forma de onda, tanto si se ha ledo de un fichero WAV como si se ha
generado matemticamente, debemos almacenarla en un objeto CSampleInstrument.
El cdigo a continuacin explica estas caractersticas:
// Carga el fichero WAV
CDLSLoader::LoadWaveFile(_T(".\\media\\starbreeze.wav"),CSample1,DM_US
E_MEMORY);
// Lo asigna a un patch
CSample1.SetPatch(2);
// Establece un loop contnuo
CSample1.SetLoop(TRUE);
// Establece parmetros WAV adicionales
CSample1.SetWaveParams(0,0,68,F_WSMP_NO_TRUNCATION);
REGION region;
ARTICPARAMS articparams;

115

C A P T U L O 5 Programacin MIDI
// Inicializa estructuras
ZeroMemory(&region,sizeof(REGION));
ZeroMemory(&articparams,sizeof(ARTICPARAMS));

// Establece los parmetros de regin


region.RangeKey.usHigh = 127;
region.RangeKey.usLow = 0;
region.RangeVelocity.usHigh = 127;
// Ajusta LFO
articparams.LFO.tcDelay = TimeCents(10.0);
articparams.LFO.pcFrequency = PitchCents(5.0);
// Establece el envolvente de Pitch
articparams.PitchEG.tcAttack
articparams.PitchEG.tcDecay
articparams.PitchEG.ptSustain
articparams.PitchEG.tcRelease

=
=
=
=

TimeCents(0.0);
TimeCents(0.0);
PercentUnits(0.0);
TimeCents(0.0);

// Establece la envolvente de volumen


articparams.VolEG.tcAttack
articparams.VolEG.tcDecay
articparams.VolEG.ptSustain
articparams.VolEG.tcRelease

=
=
=
=

TimeCents(1.275);
TimeCents(0.0);
PercentUnits(100.0);
TimeCents(10.157);

// Establece los parmetros de instrumentos


CSample1.SetRegion(&region);
CSample1.SetArticulationParams(&articparams);
// Reserva memoria para los sampes
COutPort.AllocateMemory(CSample1);
// Descarga el instrumento al puerto
COutPort.DownloadInstrument(CSample1);
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(PATCH_CHANGE,0,2,0),0)
;
cout << "Preparado para reproducir el fichero WAV" << endl;
getch();
// Asigna patch 3
CSample2.SetPatch(3);
// Establece parmetros adicionales
CSample2.SetWaveParams(0,0,68,F_WSMP_NO_TRUNCATION);

116

C A P T U L O 5 Programacin MIDI
// Establece los parmetros de los instrumentos
CSample2.SetLoop(TRUE);
CSample2.SetRegion(&region);
CSample2.SetArticulationParams(&articparams);
// Genera los datos de la forma de onda
// Muestras por segundo
DWORD nSamplesPerSec = 44100;
// La duracin de la muestra
double nTimeSec = 1.5;
// Numero de muestras
DWORD nSamples = static_cast<DWORD>(nTimeSec * nSamplesPerSec);
// Frecuencia digital de la forma de onda
double Frequency = 1000.0/nSamplesPerSec;
// Reserva memoria para la forma de onda
WORD *pRawData = new WORD[nSamples];
// Genera la forma de onda
for(DWORD ni = 0;ni < nSamples;ni++)
pRawData[ni]
=
static_cast<WORD>(30000*sin(2.0*PI*Frequency*ni) +
5000*sin(6.0*PI*Frequency*ni) +
1000*sin(10.0*PI*Frequency*ni));
// Formato de la forma de onda
WAVEFORMATEX pwfex = {WAVE_FORMAT_PCM,1,44100,44100,2,16,0};
// Establece el formato de la forma de onda
CSample2.SetWaveForm((BYTE*)pRawData,&pwfex,nSamples*2);
// Reserva memoria para la interfaz
COutPort.AllocateMemory(CSample2);
//Descarga instruemento al puerto
COutPort.DownloadInstrument(CSample2);
COutPort.SendMidiMsg(COutputPort::EncodeMidiMsg(PATCH_CHANGE,0,3,0),0)
;

La imagen 5.7 muestra la forma de onda generada en el ejemplo anterior:

117

C A P T U L O 5 Programacin MIDI

Figura 5.7
5.3.3.7 Sptimo paso: terminar la aplicacin
El ltimo paso de esta secuencia es cerrar la aplicacin de una forma apropiada y
limpia. Un ejemplo de esta funcin de limpieza y terminacin de notificaciones puede
verse en el cdigo siguiente:
// Finaliza la aplicaicn
// Rompe la redireccin
CInPort.BreakThru(0,0,0);
// Finaliza la notificacin
CInPort.TerminateNotification();
cout << "\n\nNotificacion terminada" << endl;
cout << "Descargando instrumentos" << endl;
// Descarga las colecciones del objeto Loader
CLoader.UnloadCollection(CCollectionA);
CLoader.UnloadCollection(CCollectionB);
// Descarga los instrumentos del puerto
cout << "Unloading instruments" << endl;
COutPort.UnloadInstrument(CInstrument1);
COutPort.UnloadInstrument(CInstrument2);
// Descarga las muestras de los puertos
COutPort.UnloadInstrument(CSample1);
COutPort.UnloadInstrument(CSample2);
// Libera la memoria reservada
COutPort.DeallocateMemory(CSample1);
COutPort.DeallocateMemory(CSample2);
delete [] pRawData;
cout << "Aplicacin terminada...OK" << endl;

118

C A P T U L O 5 Programacin MIDI

getch();
}
catch (CDMusicException& DMExcp)
{
cout << "\n" << DMExcp.GetErrorDescription() << "\n" << endl;
getch();
}
return 0;
}

Si se activ la notificacin en el puerto de entrada MIDI para recibir mensajes de


entrada MIDI, es responsabilidad del programador llamar al mtodo
CInputPort::TerminateNotification para finalizar la recepcin de eventos por este
puerto. Tambin es necesario llamar al mtodo CInputPort::BreakThru si se estableci
un conexin Thru entre dos puertos. Es importante liberar la memoria reservada por las
colecciones de instrumentos. Para conseguir esto, debemos llamar al mtodo
CDLSLoader::UnloadCollection y liberar la interfaces DirectMusic internas llamando a
COutputPort::DeallocateMemory. Esta operacin hay que repetirla con los
instrumentos descargados en el sintetizador mediante la llamada al mtodo
COutputPort::UnloadInstrument.
Aunque la librera DirectMIDI liberar la memoria automticamente, mediante el
sistema de recoleccin de basura implementado en los destructores de las clases, es
importante que el programador tambin se ocupe de estas cuestiones.
5.3.4 Manejo de excepciones
DirectMIDI contiene la clase CDMusicException que maneja todas las posibles
situaciones anmalas que ocurren durante la ejecucin de la aplicacin, permitiendo
liberar al programador de comprobar constantemente los valores de retorno de las
funciones DirectX mediante la macro FAILED.
Bsicamente el objeto provee tres importantes propiedades para informar sobre el error
que son: m_hrCode que informa sobre el valor HRESULT de COM en DirectX,
m_strMethod que proporciona la descripcin del mtodo donde la llamada a la funcin
fall, y por ltimo, m_nLine que devuelve el nmero de lnea del cdigo fuente del
mdulo donde se produjo el error.
Adems de estas tres propiedades, hay un mtodo adicional para facilitar la
descripcin textual del error del mtodo, CDMusicException::GetErrorDescription que
retorna una cadena LPCTSTR conteniendo una descripcin detallada del error una vez
que la excepcin a sido capturada.
Para terminar, en la siguiente imagen se muestra un ejemplo que informa de un
error durante la ejecucin:

Figura 5.8 Informacin de una excepcin

119

C A P T U L O 5 Programacin MIDI

Bibliografa y referencias
La Web
DirectMIDI wrapper class library
http://directmidi.sourceforge.net/
MSDN
http://msdn2.microsoft.com/es-es/default.aspx

120

Parte IV

Reproduccin de
formatos de sonido

C A P T U L O 6 Reproduccin de formatos de sonido

Reproduccin de formatos
de sonido

6.1 Introduccin
Para desarrollar aplicaciones profesionales y complejas se hace necesario el uso
de abstraccin y modularidad de las funciones de bajo nivel ya vistas en los captulos 2
y 3 de la parte 2. Evidentemente, si requerimos implementar funcionalidades como
mezclar gran cantidad de sonidos o reproducir ficheros de audio conocidos como el
formato mp3, ogg, MIDI, WAV, etc. se nos presenta el problema de necesitar
encapsular y abstraer la complejidad de las funciones COM de DirectX o de la cantidad
de funciones de OpenAL, puesto que si se implementa en la misma capa que la lgica
de negocio de nuestra aplicacin, el resultado ser desastroso. En el caso de desarrollar
una aplicacin de reproduccin de ficheros mp3, sera muy confuso tener que mezclar el
cdigo de procesamiento y decodificacin MPEG con las funciones de DirectSound.
Esto tambin sera aplicable a un videojuego, donde el cdigo y los objetos que
gestionan el motor del juego no podran entremezclarse con cdigo de bajo nivel para
reproducir un efecto o poner una msica de fondo.
La solucin en este caso tendra dos alternativas:
1. Desarrollar por nuestra cuenta una capa software donde se implementara el
cdigo de acceso a los dispositivos de audio(DirectSound, OpenAL), y,
adicionalmente otra capa superior a sta donde se implementara la lgica ms
cercana al usuario como: reproduccin de formatos de sonido conocidos y
objetos de alto nivel para gestionar streams, sonidos cortos, mezclas, efectos,
etc. o
2. Utilizar una librera de software de terceros donde ya se nos provea de estas
funcionalidades antes descritas. La ventaja de este enfoque es la eficiencia de la
reutilizacin y el ahorro del tiempo de desarrollo, puesto que esta parte puede
ser subcontratada a terceras personas. La desventaja, sin embargo, de este
enfoque es el coste de la adquisicin de la licencia para la distribucin al
pblico.
Afortunadamente, en el entorno del software libre existen soluciones muy
aceptables y eficientes que resuelven este problema.
En este captulo se explicar la utilizacin de una librera GNU de software
libre para resolver todos los problemas de una aplicacin de audio profesional.
Esta librera se llama Audiere que se explicar a continuacin.

123

C A P T U L O 6 Reproduccin de formatos de sonido

6.2 La librera Audiere


6.2.1 Introduccin
Audiere es una librera software de audio con una API de alto nivel desarrollada
por Chad Austin (jefe de desarrollo), Matt Campbell, Jacky Chong, Theo Reed, Richard
SCAF y Ben Scoot como contribuidores.
Entre las caractersticas ms relevantes caben destacar:

API fcil e intuitiva.


Permite la reproduccin de audio en streaming y almacenado dinmicamente en
buffers.
Efectos de cambio de volumen, pan y velocidad de reproduccin.
Posibilidad de generacin de formas de onda bsicas como ruido blanco y ondas
cuadradas.
Enumeracin en tiempo de ejecucin de dispositivos de audio y formatos de
ficheros de audio soportados.
Manejo de ficheros por streams.
Portabilidad a lenguajes como Python, Delphi, Java y XPCOM (JavaScript en
Mozilla).

Los formatos de audio que soporta son:

Ogg Vorbis (OGG).


MP3 (MPEG Layer-3)
FLAC
WAV descomprimido
AIFF
MOD, S3M, XM e IT.

Las tecnologas software de salida de audio que soporta Audiere son:

DirectSound
WinMM (Windows Multimedia API)
OSS en Linux y Cygwin
SGI AL en IRIX

Audiere es cdigo fuente abierto y publicado bajo la licencia LGPL. Esto significa
que es posible usar esta librera en productos comerciales siempre y cuando no se
modifique el cdigo fuente. En el caso de modificar el cdigo fuente y liberar una nueva
librera, sta debe ser publicada bajo los trminos de LGPL tambin.
Audiere es una librera portable que ha sido testeada en sistemas como Windows,
Linux i386, Cygwin e IRIX con al menos tres grandes compiladores. La arquitectura de
Audiere es independiente de la codificacin big-endian y little-endian.

124

C A P T U L O 6 Reproduccin de formatos de sonido


La librera puede descargarse del repositorio de software libre SourceForge en la
URL: http://audiere.sourceforge.net/home.php y en la seccin download podemos
descargar la librera completa cuya ltima versin es la 1.9.4.
Una vez instalada la librera podemos acceder al programa de prueba en el
directorio audiere-1.9.4-win32\bin y ejecutar la aplicacin wxPlayer.exe. Veremos una
interfaz de usuario como la siguiente:

Figura 6.1 Aplicacin de ejemplo de la librera


Donde podremos ejecutar las funcionalidades bsicas de la librera. En el
ejemplo de la imagen 6.1 se estn reproduciendo dos ficheros mp3 mezclados en tiempo
real: uno en modo stream y otro en un buffer. Lgicamente el fichero mp3 cargado en
forma de stream requiere menos tiempo de carga y memoria que el almacenado en el
buffer puesto que lo reproduce bajo demanda en tiempo de ejecucin.

125

C A P T U L O 6 Reproduccin de formatos de sonido


6.2.2 Clase AudioDevice
Comenzaremos a programar una aplicacin real de audio con la librera Audiere
importando en primer lugar la cabecera audiere.h, como se muestra en el cdigo
siguiente:
include
#include
#include
#include

<windows.h>
<conio.h>
<iostream>
"audiere.h"

using namespace audiere;


using namespace std;
int main(int argc, char* argv[])
{
// Crea el dispositivo defecto para salida de audio
AudioDevicePtr device(OpenDevice());
if (!device) {
cout << "Error al crear dispositivo" << endl;
return 1;
}

Como podemos observar en el cdigo anterior, adems de incluir la cabecera


audiere.h y usar su espacio de nombres(namespace), se ha creado el objeto AudioDevice
que maneja la gestin del dispositivo de audio de salida.
La funcin OpenDevice permite inicilializar la librera, detectar y abrir el dispositivo de
sonido por defecto. La clase AudioDevice deriva de la clase RefCounted como se ilustra
en la siguiente figura:

Figura 6.2
Esta clase base (RefCounted) permite contar referencias de instancias de la clase,
as cuando el contador de referencias llega a cero se libera completamente la memoria
que ocupaba el objeto AudioDevice.
El objeto AudioDevice representa un dispositivo en el sistema que es capaz de abrir y
mezclar varias fuentes de sonido. En Windows, DirectSound sera un ejemplo de un
dispositivo.

126

C A P T U L O 6 Reproduccin de formatos de sonido


6.2.3 Clase OutputStream
La clase OutputStream representa una conexin a un dispositivo de audio. De
esta forma mltiples streams de salida son mezclados por un dispositivo de salida para
producir una forma de onda final que es lo que el usuario oye.
Cada objeto OutputStream puede ser reproducido o detenido independientemente de
otros objetos OutputStream. Adems se les puede establecer parmetros como volumen,
pan y efectos tambin de forma independiente.

Figura 6.3
Como en el caso anterior, esta clase tambin hereda de la clase RefCounted para la
gestin de memoria.
Sus mtodos pblicos disponibles al desarrollador son los que a continuacin se
muestran:
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual
virtual

void
void
bool
void
void
bool
void
float
void
float
void
float
bool
int
void
int

play ()=0
stop ()=0
isPlaying ()=0
reset ()=0
setRepeat (bool repeat)=0
getRepeat ()=0
setVolume (float volume)=0
getVolume ()=0
setPan (float pan)=0
getPan ()=0
setPitchShift (float shift)=0
getPitchShift ()=0
isSeekable ()=0
getLength ()=0
setPosition (int position)=0
getPosition ()=0

Como podemos apreciar, este objeto contiene los mtodos principales para
manejar las funcionalidades bsicas de un sonido: cambiar el volumen, pan, reproducir,
pausar, obtener la posicin de la secuencia, cambiar la frecuencia de reproduccin, etc.
Si a continuacin requerimos cargar un fichero en un objeto OutputStream para
su reproduccin tendremos que recurrir a la funcin global OpenSound que detectar
automticamente el tipo de formato y lo cargar en el objeto como stream o buffer
segn se le indique en el ltimo parmetro mediante los flags true o false.
En el cdigo siguiente se muestra esta situacin:

127

C A P T U L O 6 Reproduccin de formatos de sonido


// Carga el fichero de sonido 3
OutputStreamPtr sound3(OpenSound(device, "..\\media\\sonido3.wav",
false));
if (!sound3) {
cout << "Error al cargar sonido3" << endl;
return 1;
}

// Carga la msica
OutputStreamPtr stream(OpenSound(device, "..\\media\\OMD Electricity.mp3", true));
if (!stream) {
cout << "Error al cargar musica" << endl;
return 1;
}

6.2.4 Reproduccin y efectos


Por ltimo, una vez que se hayan cargado los ficheros en los objetos
OutputStream, tan slo queda ahora reproducir el sonido y aplicar efectos como pan,
volumen y cambio de la velocidad de reproduccin.
Como se vio en la lista de mtodos pblicos de la clase OutputStream, tenemos todas las
funciones necesarias para llevarlo a cabo, mediante, por ejemplo, el mtodo play,
setPan, setVolume, setRepeat, etc.
En el cdigo que se muestra en la siguientes lneas podemos apreciar el uso de estos
mtodos:
while( condicion )
{
switch( _getch() )
{
// Reproduce buffer 1
case '1':
sound1->play();
break;
// Reproduce buffer 2
case '2':
sound2->play();
break;
// Reproduce buffer 3
case '3':
sound3->play();
break;
// Reproduce musica
case '4':
stream->play();
break;
// Efecto pan de la musica
case '5':
for(float i= -1.0;i < 1.0;i+=0.1)
{
stream->setPan(i); // Izquierda->Derecha
Sleep(100);
}

128

C A P T U L O 6 Reproduccin de formatos de sonido


for(float i= 1.0;i > -1.0;i-=0.1)
{
stream->setPan(i); // Derecha->Izquierda
Sleep(100);
}
stream->setPan(0); // Centro
break;
// Frecuencia de reproduccion a 2x
case '6':
stream->setPitchShift(2.0);
break;
// Frecuencia de reproduccion a 0.5x
case '7':
stream->setPitchShift(0.5);
break;
// Frecuencia de reproduccion
case '8':
stream->setPitchShift(1.0);
break;
// Pausa musica
case '9':
stream->stop();
break;
// Fin de la aplicacion
case '0':
condicion = false;
}
}

Es fcil realizar estas operaciones. Como puede intuirse, todos los sonidos que
se reproducen con el mtodo play se mezclan sobre el mismo dispositivo, permitiendo
utilizar un nmero indeterminado de fuentes de sonido. Esto puede ser til para un
videojuego donde varios efectos de sonido se deben mezclar con una banda sonora de
fondo. El mtodo setPan toma valores desde -1.0 (balance a canal izquierdo) a 1.0
(balance a canal derecho), estando en el 0.0 el balance central. Por ltimo, el mtodo
setPitchShift cosigue cambiar la velocidad de reproduccin con valores de 2.0
(reproduce a doble velocidad), 0.5 (reproduce a la mitad de la velocidad) y 1.0
(reproduce normal).
Es de destacar que esta librera tiene una plitica de gestin de memoria muy
avanzada y automtica por lo que puede terminarse la apliacacin sin necesidad de
liberar los recursos manualmente.
6.2.5 Acceso a los datos PCM de un buffer
Uno de los aspectos ms importantes de una librera de audio es poder acceder a
los datos de audio PCM contenidos en un buffer de sonido. Para poder realizar esta
operacin con Audiere es necesario cargar el sonido en un objeto SampleSurce que
adems de ser la fuente para datos PCM permite posicionar el sonido. En la siguiente
imagen se muestra la estructura de esta clase:

129

C A P T U L O 6 Reproduccin de formatos de sonido

Figura 6.4
Previo a la obtencin de los datos PCM necesitamos utilizar la clase
SampleBuffer que es un contenedor de muestras de sonido de slo lectura que permite
abrir streams de muestras e iterar sobre ellos. Este objeto es usado en la situacin donde
un sonido muy largo se carga una sola vez en memoria y se redirige en stream varias
veces hacia el dispositivo. Para obtener el objeto que hemos mencionado anteriormente
llamaremos a la funcin global CreateSampleBuffer.
En la siguiente imagen se muestra la estructura de esta clase estndar:

Figura 6.5
Por lo tanto el cdigo para llevar esto a cabo es el siguiente:
#include
#include
#include
#include

<windows.h>
<conio.h>
<iostream>
"audiere.h"

using namespace audiere;


using namespace std;
int main(int argc, char* argv[])
{
AudioDevicePtr device(OpenDevice());
if (!device) {
cout << "Error abriendo dispositivo" << endl;
return 1;
}
// Cargamos el fichero de sonido mp3 en un objeto SampleSource
SampleSourcePtr sampleSource = OpenSampleSource("..\\media\\OMD
- Electricity.mp3");
if (!sampleSource)
{
cout << "Error al cargar fichero" << endl;
return 1;
}
// Se obtiene un buffer de datos a partir del objeto
SampleSource

130

C A P T U L O 6 Reproduccin de formatos de sonido


SampleBufferPtr sampleBuffer1 =
CreateSampleBuffer(sampleSource);
if (!sampleBuffer1)
{
cout << "Error al crear objeto sampleBuffer" << endl;
return 1;
}

Con las funciones miembro getFormat y getLength podemos obtener


informacin del formato de la forma de onda y la longitud en frames.
Con el objetivo de reservar memoria dinmica para albergar los datos de la forma de
onda se hace preciso calcular el tamao de la muestra en bytes. Para ello se recurrir a la
siguiente funcin:
Tamao buffer(bytes) = nmero de canales nmero de frames bits por muestra
Finalmente se recurre a la funcin miembro SampleBuffer::getSamples para
obtener un puntero a los bytes de la muestra.
Con todo esto se puede ya reservar memoria y almacenar los datos PCM en ella
mediante el siguiente cdigo de ejemplo:
int channel_count,sample_rate,frame_count;
SampleFormat sample_format;
// Se obtienen los datos de formato del buffer de audio
sampleBuffer1->getFormat(channel_count,sample_rate,sample_format);
// Se obtiene el nmero de frames
frame_count = sampleBuffer1->getLength();
// Se calcula el tamao de muestra en bytes
DWORD sampleSize = channel_count * frame_count *
GetSampleSize(sample_format);
cout << "El tamano de la muestra a invertir es: " << sampleSize << "
bytes" << endl;
// Puntero al array dinmico donde almacenar los datos
WORD *pRawData = new WORD[sampleSize / 2];
// Volcado de datos al array
CopyMemory(pRawData,sampleBuffer1->getSamples(),sampleSize);

El cdigo que se muestra a continuacin es un ejemplo de inversin de una


forma de onda, en este caso de una cancin, para reproducir en reverse o backward. Con
esta finalidad se ha creado un array auxiliar en memoria dinmica donde se realizar el
proceso de inversin, que como se muestra en la figura siguiente, consiste en
intercambiar el orden de los ltimos bytes para ser los primeros en el array de forma
invertida. El motor reproducir la muestra palabra por palabra, ya que el formato es de
16 bits por muestra.

131

C A P T U L O 6 Reproduccin de formatos de sonido


Array origen en bytes
1

10 11 12 13 14 15 16 17 18 19 20

Array destino en bytes


19 20 17 18 15 16 13 14 11 12

10

Figura 6.6
As, por lo tanto, el algoritmo que lleva a cabo esta inversin es el siguiente:
// Array auxiliar para la inversin
WORD *pRawAux = new WORD[sampleSize / 2];
// Indice al penltimo byte de datos
int t = sampleSize / 2 - 1;
// Proceso de inversin
for(int i = 0;i < sampleSize / 2;i++)
{
pRawAux[i] = pRawData[t];
t--;
}

Ya slo falta crear un nuevo objeto SampleBuffer a partir del nuevo array con los
datos invertidos y de ah obtener un objeto SampleSource mediante el mtodo
SampleBuffer::openStream. Por ltimo se pasa este objeto a la funcin global ya
comentada, OpenSound, y se provee un puntero al objeto SampleBuffer que contiene la
muestra invertida. Esta funcin nos devolver definitivamente un puntero a un objeto
OutputStream cuyo destino final es poder ser reproducido.
El cdigo que se muestra a continuacin ilustra estas operaciones:
// Crear un nuevo objeto SampleBuffer para albergar datos
SampleBufferPtr sampleBuffer2 =
CreateSampleBuffer(pRawAux,frame_count,channel_count,sample_rate,sampl
e_format);
if (!sampleBuffer2)
{
cout << "Error al crear objeto SampleBuffer" << endl;
return 1;
}
// Se obtiene un puntero al objeto SampleSource
SampleSourcePtr sampleSource2 = sampleBuffer2->openStream();
// Se libera la memoria de los arrays de datos
delete [] pRawData;
delete [] pRawAux;
// Se crea un objeto de salido de sonido stream
OutputStreamPtr sound2(OpenSound(device,sampleSource2,false));
if (!sound2)
{
cout << "Error al crear el objeto OutputStream" << endl;
return 1;

132

C A P T U L O 6 Reproduccin de formatos de sonido


}
// Finalmente se reproducen los datos invertidos
cout << "Reproduciendo sonido invertido. Pulse una tecla para
finalizar..." << endl;
sound2->play();
_getch();
return 0;
}

6.3 Formatos de sonido conocidos


6.3.1 Formato WAV
El formato WAV o WAVE cuyo nombre proviene de waveform audio file
format, es un formato de audio sin compresin desarrollado por Microsoft e IBM. Este
formato admite los modos mono y estreo a diversos bits y velocidades de muestreo. Se
encuentra normalmente en los sistemas PC con la extensin .wav y es el principal de los
sistemas operativos Windows.
El formato WAV deriva del formato RIFF (Resource Interchange File Format)
y es relativamente parecido al los formatos AIFF e IFF utilizados en sistemas Mac OS.
Una de las ventajas que proporciona el formato es que puede soportar cualquier
tipo de cdec; aunque principalmente se utiliza con el formato PCM sin comprimir.
Una de las limitaciones de WAV es que slo se puede grabar un archivo de hasta 4
gigabytes, debido a una limitacin en la cabecera del fichero donde se indica la longitud
del mismo con un nmero de 32 bits.
La estructura de este fichero es muy simple, con una cabecera compuesta por 4
parmetros: duracin temporal, frecuencia de muestreo, resolucin y grabacin mono o
estreo.
6.3.2 Formato AIFF
Este formato de audio fue desarrollado por Apple en 1998 y est basado en el
formato IFF. Es le acrnimo de Apple Interchange File Format y es uno de los formatos
de sonido ms compatibles.
Los datos de audio en estndar AIFF no estn comprimidos, almacenndose los datos en
big-endian y codificacin PCM. Este formato tiene una variante con compresin que se
le denomina AIFF-C o AIFC, con soporte para una gran variedad de cdecs.
El estndar AIFF es uno de los formatos lderes, junto a WAV, usados a nivel
profesional para aplicaciones de audio, ya que, a diferencia del formato MP3, est
comprimido sin ninguna prdida lo que facilita un rpido procesamiento de seal en
detrimento del aumento de espacio en memoria secundaria.
Una de las ventajas de este estndar es poder dar soporte a bucles en notas
musicales para su uso en samplers.
El formato se puede encontrar con extensiones .aiff o .aif, y para las variantes
comprimidas con extensin .aifc, aunque las anteriores tambin admiten compresin.

133

C A P T U L O 6 Reproduccin de formatos de sonido


6.3.3 Formatos MPEG: MP3
El formato MPEG-1 Audio Layer III o MPEG-2 Audio Leyer III, ms
comnmente conocido MP3, es un formato de compresin de audio digital patentado
que usa un algoritmo con prdida para obtener tamaos de ficheros relativamente
pequeos.
MP3 fue desarrollado por el Moving Picture Experts Group (MPEG) que es una
organizacin encargada de desarrollar normativas para compresin de vdeo y audio
digital. MP3 forma parte del estndar MPEG-1 y del posterior y ms extendido MPEG2. El estndar est recogido en las normativas ISO/IEC 11172-3 e ISO/IEC 13818-3.
Estos tipos de ficheros que suelen encontrarse en ordenadores personales y
reproductores de audio, tiene la extensin .mp3.
Historia
Este formato fue desarrollado principalmente por Karlheinz BrandenBurg,
director de tecnologas del Instituto Fraunhofer IIS. Las primeras patentes fueron
registradas en 1986 y varias ms en 1991. Pero no fue hasta julio de 1995 cuando
Brandenburg us por primera vez la extensin .mp3 para los archivos de su ordenador.
A partir de esta fecha el formato MP3 se convirti en muy popular y fue el
sistema utilizado para streaming de audio y compresin de alta calidad, aunque en los
equipos de alta fidelidad era patente la prdida de calidad acstica. Con un fichero MP3
con una compresin de 128kbits/s se consegua un tamao unas 11 veces menor que su
homnimo en CD.
Con el boom de Internet a principios del milenio el formato tuvo una gran
difusin, ya que hizo posible el intercambio de ficheros musicales. De todos es sabido el
problema actual con las copias piratas y la violacin de los derechos de autor derivadas
del desarrollo de software P2P. Actualmente MP3 goza de un gran xito y su utilizacin
est siendo cada vez ms frecuente.
Especificaciones tcnicas
El sistema de codificacin MP3 utiliza un algoritmo con prdidas. Sin embargo,
las prdidas corresponden a frecuencias que el odo humano no puede captar. El
algoritmo elimina toda la informacin que no se necesita. Para ello utiliza un sistema
denominado codificacin de subbandas, proceso el cual la seal se descompone en
subbandas a travs del banco de filtros hbrido. Las subbandas obtenidas, se comparan
con el original mediante un modelo psicoacstico que discrimina las bandas que no son
importantes. Por ltimo las subbandas son cuantizadas y codificadas y el resultado final
se comprime con un algoritmo tipo Huffman LZW.
En la capa III de MPEG-1, se encuentra el llamado banco de filtros hbrido. Esta
mejora de la resolucin frecuencial empeora la resolucin temporal introduciendo
problemas de pre-eco que son predichos y corregidos.
Este sistema utilizado en la capa III es el llamado banco de filtros hbrido
polifase/MDCT. Se encarga de realizar el mapeado de la seal en el dominio del tiempo

134

C A P T U L O 6 Reproduccin de formatos de sonido


al de la frecuencia tanto para el codificador como para los filtros de reconstruccin del
decodificador. Las muestras de salida del banco estn cuantizadas y proporcionan una
resolucin en frecuencia variable, 6x32 o 18x32 subbandas, ajustndose mucho mejor a
las bandas crticas de las diferentes frecuencias.
La capa III tiene tres modos de bloque de funcionamiento: dos modos donde las 32
salidas del banco de filtros pueden pasar a travs de las ventanas y las transformadas
MDCT y un modo de bloque mixto donde las dos bandas de frecuencia ms baja usan
bloques largos y las 30 bandas superiores usan bloques cortos. Para la capa III de
MPEG-1 se especifican cuatro tipos de ventana:
1.
2.
3.
4.

Normal
Transicin de ventana larga a corta (Start)
3 ventanas cortas (Short)
Transicin de ventana corta a larga (Stop)

La compresin de basa en la reduccin del margen dinmico irrelevante, es decir, en


la incapacidad del sistema auditivo para detectar los errores de cuantizacin en
condiciones de enmascaramiento. Este estndar divide la seal en bandas de frecuencia
que se aproximan a las bandas crticas, y luego cuantifica cada subbanda en funcin del
umbral de deteccin del ruido dentro de esa banda. El modelo psicoacstico es una
modificacin del empleado en esquema II, y utiliza un mtodo denominado prediccin
polinmica. Analiza la seal de audio y calcula la cantidad de ruido que se puede
introducir en funcin de la frecuencia, es decir, calcula la cantidad de
enmascaramiento o umbral de enmascaramiento en funcin de la frecuencia.
El codificador utiliza esta informacin para decidir la mejor manera de gastar los
bits disponibles. El estndar provee dos modelos piscoacsticos el I y el II. El modelo I
es mucho menos complejo que el II y simplifica considerablemente los clculos.
Las pruebas acsticas, realizadas con personas con odo muy agudo, se han utilizado
para comprobar si la codificacin es suficientemente buena. En la tabla 6.1 pueden
observarse las diferentes caractersticas de distintas fuentes de sonido.

Capa
1
2
3

Compresin
4:1
6:1 a 8:1
10:1 a 12:1

Transferencia
384 kbits/s
256 a 192 kbits/s
128 a 112 kbits/s

Tabla 6.1 Caractersticas de las distintas fuentes de sonido

135

C A P T U L O 6 Reproduccin de formatos de sonido


En la tabla 6.2 se muestra las caractersticas de distintas fuentes de sonido.
Calidad
Telfono
Radio AM
Radio FM
CD
DAT

Muestreo
8 Khz
11,025 Khz
22,050 Khz
44,1 Khz
48 Khz

Resolucin
8
8
16
16
16

Modo
Mono
Mono
Estreo
Estreo
Estreo

Tasa transferencia
64 kbps
88 kbps
705,6 kbps
1441,2 kbps
1536 kbps

Tabla 6.2 Caractersticas de distintas fuentes de sonido


As por ejemplo para el odo no experimentado, con 128 kbps o hasta 192 kbps
es aceptable. En personas que escuchan mucha msica o que tienen experiencia en la
parte auditiva, desde 192 a 256 kbps debe ser recomendable. En la msica que circula
por Internet las tasas suelen ser de 128 y 192 kbps.
Para la codificacin y la cuantizacin la solucin que propone el estndar en cuanto
a la reparticin de bits o ruido, se hace en un ciclo de iteracin que consiste en un ciclo
interno y otro externo:


Ciclo interno: realiza la cuantizacin no-uniforme de acuerdo con el sistema de


punto flotante. El ciclo escoge un determinado intervalo de cuantizacin y, a los
datos cuantizados, se les aplica codificacin Huffman en el siguiente bloque. El
ciclo termina cuando los valores cuantizados que han sido codificados con
Huffman usan menor o igual nmero de bits que la mxima cantidad de bits
permitida.

Ciclo externo: este ciclo se encarga de verificar si el factor de escala para cada
subbanda tiene ms distorsin de la permitida (ruido en la seal codificada),
comparando cada banda del factor de escala con los datos previamente
calculados en el anlisis psicoacstico.

Por ltimo falta empaquetar los datos. Para ello se toman muestras cuantificadas del
banco de filtros, junto a los datos de asignacin de bits/ruido y almacena el audio
codificado y datos adicionales en tramas. Cada trama contiene hasta 1152 muestras de
audio y est formada por un encabezado, junto con un chequeo de deteccin de errores
CRC y datos auxiliares.

6.3.4 Formato General MIDI


General MIDI conocido con el acrnimo GM exige que todos los instrumentos
sean compatibles con el mismo estndar GM.
El estndar especifica qu sonidos se crean con el ordenador y cmo van a ser
enviados al procesador para que emita los sonidos, por tanto es la especificacin GM la
que define el formato MIDI en una tarjeta de sonido.

136

C A P T U L O 6 Reproduccin de formatos de sonido


Los ficheros GM contienen las partituras de las composiciones musicales en
formato MIDI. La extensin con la que se encuentra el formato suele es .mid, aunque
existe una variante llamada .kar que contiene la lrica de las canciones para ser
interpretadas por sistemas de karaoke.
El conjunto GM consta de un total de 128 instrumentos clasificados por tipos
como se muestra en el apndice A3. Sin embargo, para la especificacin GM2 se
definen un total de 256 instrumentos y 9 kits de batera GS (General Sound).
Estos ficheros ocupan muy poco espacio fsico y las composiciones suelen ser
reproducidas a 16 bits a 44,1 kHz en estreo y efectos. Para reproducir un fichero MIDI
no requiere los recursos que necesita un fichero de audio convencional, como por
ejemplo un MP3 o un XM. La MMA (Asociacin Internacional de fabricantes MIDI)
public una normativa en cuanto a la estandarizacin de los archivos MIDI o SMF que
consisten en la siguiente estructura:

Cabecera:
id
tamano
formato

deltatime

Identificador que contiene los caracteres MThh


Tamao de la longitud del fichero sin contar id ni
tamano
0 Pista nica
1 Multipista, sncrono (todas las pistas se ejecutan
simultneamente)
2 Multipista asncrono (las pistas se ejecutan de
manera secuencial)
Nmero de intervalos contenidos en de nota.
Especifica tiempo de reproduccin.

Si quisiramos definir una estructura en C++ para albergar estos datos


podramos recurrir a una clase estndar como la del siguiente ejemplo:
class MIDIhdr{
private:
char id[4];
long tamano;
unsigned formato;
unsigned numero_pistas;
unsigned deltatime;
public:
void setid(const char *id);
char *getid();
etc.
};

137

C A P T U L O 6 Reproduccin de formatos de sonido




Segmentos de pista:

Cada segmento de pista est compuesto por una cabecera, seguida de una
serie de eventos MIDI. Entre estos eventos se encuentran los comandos, que son
los datos enviados y recibidos por los puertos MIDI.
Cadena de cuatro caracteres que identifica la cabecera del
track. Es MTrk.
Indica el tamao de la pista sin indicar la cabecera, es
decir, el nmero de comandos que contiene.

id
tamano

En C++ podemos implementar simplemente con la clase estndar:


class Miditrk {
private:
char
long
public:
void
char
etc.

id[4];
tamano;
setid(const char *id);
*getid();

};

Notas musicales:

En MIDI estn comprendidas con un numero decimal positivo entre 0 y 127.


Son las siguientes:
Octava
0
1
2
3
4
5
6
7
8
9
10


Do
0
12
24
36
48
60
72
84
96
108
120

Do#
1
13
25
37
49
61
73
85
97
109
121

Re
2
14
26
38
50
62
74
86
98
110
122

Re#
3
15
27
39
51
63
75
87
99
111
123

Mi
4
16
28
40
52
64
76
88
100
112
124

Fa
5
17
29
41
53
65
77
89
101
113
125

Fa#
6
18
30
42
54
66
78
90
102
114
126

Sol
7
19
31
43
55
67
79
91
103
115
127

Sol#
8
20
32
44
56
68
80
92
104
116

La
9
21
33
45
57
69
81
93
105
117

La#
10
22
34
46
58
70
82
94
106
118

Si
11
23
35
47
59
71
83
95
107
119

Valores de longitud variable:

La finalidad de utilizar comandos con datos de longitud variable es


representar un amplio rango de valores evitando que valores pequeos ocupen
ms espacio fsico de lo necesitado.
Estos valores se forman como una secuencia de bytes, del que slo cuentan los
siete bits menos significativos. El MSB debe ser siempre 1 si quedan ms bytes
para representar el valor y 0 para el ltimo byte.

138

C A P T U L O 6 Reproduccin de formatos de sonido




Eventos:

Estn formados por los comandos de voz y los comandos de modo. Los
primeros constan de un byte de estado seguido de datos dependientes del byte de
estado. Para los 16 posibles canales de GM-1 se utilizan los 4 bits ms bajos del
byte de estado. As, por ejemplo, para indicar que una nota ha sido pulsada o
liberada se utilizara los siguientes bytes de estado:
Byte de estado
0x8....

Significado
Liberacin de nota

0x9....

Pulsacin de nota

Datos
1 byte de nota + 1 byte de
velocidad pulsacin
1 byte de nota + 1 byte de
velocidad pulsacin

Los comandos de modo constan slo de un byte que indica el estado pero no
requieren ningn canal determinado. El comando ms utilizado tiene como
funcin silenciar las notas en todos los canales.


Mensajes de sistema exclusivo:

Como se coment en el captulo 4, los mensajes de sistema exclusivo son


datos no estructurados proporcionados por cada fabricante de sistema MIDI que
tienen una nomenclatura determinada.
Los mensajes de sistema exclusivo tienen el siguiente formato de arranque:
0xF0 + longitud + mensaje no estructurado
Se pueden enviar desde un solo bloque hasta varios. Para el envo de un
mensaje de mltiples bloques se hace necesario indicar el final del stream
indicndolo con el byte 0xF7.


Eventos META:

Los eventos Meta no se consideran mensajes MIDI sino otro tipo de


informacin que se asocia al fichero. Para desarrollar un componente de lectura
de un fichero MIDI no es necesario conocer todos los eventos Meta. Por su
extensin se ha eludido indicar en esta seccin los diferentes eventos. Si el lector
est interesado en conocer los diferentes eventos, se le anima a consultar el sitio
Web de la MMA.
Para reproducir un fichero MIDI en Audiere es necesario en primer lugar utilizar
un nuevo tipo de dispositivo, llamado MIDIDevice que gestiona el objeto de control
del puerto MIDI. En segundo lugar, para abrir el puerto MIDI se invocar a la
funcin OpenMIDIDevice con el parmetro NULL, puesto que actualmente no se
encuentra implementado en esta librera la eleccin de otros tipos de puertos.
Debido a esto, slo ser posible seleccionar un puerto MIDI por defecto. En
ltimo lugar y con el fin de reproducir el fichero MIDI, se recurrir al objeto
MIDIStream que albergar el contenido del archivo previamente ledo y almacenado

139

C A P T U L O 6 Reproduccin de formatos de sonido


con el mtodo MIDIDevice::openStream, pasndole como parmetro un cadena con
la identificacin del archivo.
En la siguientes lneas de cdigo podemos apreciar la utilizacin de estas clases.

// Dispositivo MIDI
MIDIDevicePtr midi(OpenMIDIDevice(NULL));
if (!midi) {
cout << "Error al crear dispositivo MIDI" << endl;
return 1;
}
MIDIStreamPtr midStream(midi->openStream("../media/SONG_001.mid"));
if (!midStream) {
cout << "Error al cargar fichero MIDI" << endl;
return 1;
}

Por ltimo invocaremos al mtodo MIDIStream::play para reproducir el contenido del


fichero MIDI, como se muestra en el ejemplo:
// Reproduce fichero MIDI
case 'x':
midStream->play();
break;

140

C A P T U L O 6 Reproduccin de formatos de sonido


6.3.5 Formato MOD / XM
El formato MOD tiene su origen en los ordenadores Amiga donde los programas
de edicin musical, llamados trackers, solan almacenarlos en ficheros con extensin
.mod.
La primera versin del formato fue creado por Karsten Obarski para su uso en el
editor Ultimate Soundtracker; tracker publicado para el ordenador Amiga en 1987.
Desde entonces, el formato ha sido soportado por cientos de reproductores de audio y
docenas de trackers.
En las primeras versiones del formato MOD se utilizaban slo 4 canales para la
reproduccin simultnea, correspondiendo a las capacidades del chipset de audio
original de Amiga, y un lmite de 15 instrumentos.
El formato fue diseado para ser directamente reproducido en el Amiga sin
procesamiento adicional por hardware. Por ejemplo, las muestras de sonido eran
almacenadas en formato PCM de 8 bits de resolucin que se enviaban posteriormente al
DAC del sistema de audio. Tampoco los datos de las patterns u hojas de notas
estaban empaquetados. La gran innovacin de este sistema era el poco uso de CPU que
requera para la reproduccin de ficheros de audio. Esto fue utilizado para reproducir
msica de fondo en los videojuegos de la poca.
El fichero MOD tuvo su mximo auge en la llamada Demoscene (movimiento
cultural para el arte infogrfico en tiempo real) donde dos demosceners, llamados
Mahoney y Kaktus, desarrollaron un papel relevante en el diseo del formato.
Consideraciones tcnicas:
Un pattern es normalmente representado en una interfaz de usuario como una
tabla con una columna por canal, as si tenemos 4 columnas; una para cada canal, cada
columna tiene un total de 64 filas o rows.
Una celda en la tabla pude causar un cambio en el canal cuando el tiempo de la
fila (row) se ha alcanzado. Por ejemplo:





Comienzo de la reproduccin de una nueva nota, a un determinado volumen


y efectos.
Cambiar el volumen o efecto especial de la nota.
Cambiar el flujo del pattern (saltar a una determinada posicin dentro del
pattern o hacer un loop en el mismo).
Etc.

Respecto al Timing, el mnimo tiempo per frame es 0.02 segundos, o un retrazo


vertical (intervalo VSync), ya que el software original usaba la sincronizacin VSync del
monitor at 50 Hz para sistemas PAL 60 Hz para sistemas NTSC.
La frecuencia a la que un pattern es reproducido est definida por la
configuracin de velocidad. Cada fila o row en el pattern dura un retrazo vertical
(0.02 segundos). La configuracin de velocidad vara entonces entre 1 a 255. Con este

141

C A P T U L O 6 Reproduccin de formatos de sonido


factor se consigue que el tempo de la meloda o cancin se reproduzca ms deprisa o
ms lentamente.
En versiones posteriores del formato, el retrazo vertical fue reemplazado con un
periodo de tiempo ajustable en el rango [0.01,0.078] segundos. Lamentablemente,
algunas de las funcionalidades antiguas fallaron, puesto que el nuevo comando de
establecimiento de la velocidad tena un cdigo idntico al antiguo. Por ende, los
valores entre [1, 31] eran interpretados como configuraciones antiguas, pero los dems
valores fueron considerados modificaciones al perodo de tiempo ajustable. Como
consecuencia, los valores comprendidos entre [32, 255] usados en algunas ficheros
fallaban en las nuevas versiones de los trackers.
Formato XM:
Una variante del formato MOD que surgi posteriormente a su desarrollo fue el
formato XM, acrnimo de extended module, e introducido por los demosceners que
desarrollaron el secuenciador Fast Tracker 2. Su extensin es .xm.
Entre las caractersticas tcnicas introducidas por este formato, caben destacar:
instrumentos multi-muestra con efectos de volumen, envolventes de panning y
compresin de patterns. Tambin aument el nmero de canales y de comandos
utilizados por el antiguo fichero MOD, aadi soporte para muestra PCM de 16 bits y
ofreci una tabla de frecuencias alternativas para portamentos.
El formato XM se utiliza actualmente en muchas composiciones para ordenador, sobre
todo en demos y videojuegos.

Figura 6.6 Imagen del mtico editor de MOD / XM FastTracker II

142

C A P T U L O 6 Reproduccin de formatos de sonido

Bibliografa y referencias
Libros
Diseo y desarrollo Multimedia, Sistemas, Imagen, Sonido y Vdeo Manuel-Alonso
Castro Gil, Antonio Colmenar Santos, Pablo Losada de Dios, Juan Peire Arroba.
Editorial Ra-ma, 2002.
La Web
Wikipedia:
WAV
http://es.wikipedia.org/wiki/Waveform_Audio_Format
AIFF
http://es.wikipedia.org/wiki/AIFF
MP3
http://es.wikipedia.org/wiki/MP3
GM
http://es.wikipedia.org/wiki/General_MIDI
MOD
http://en.wikipedia.org/wiki/MOD_(file_format)
XM
http://en.wikipedia.org/wiki/XM_(file_format)
GM
http://www.lpi.tel.uva.es/~nacho/docencia/ing_ond_1/trabajos_01_02/formatos_audio_
digital/html/midiformat.htm Juan Ignacio Arribas
Audiere documentation:
http://audiere.sourceforge.net/documentation.php
MSDN
http://msdn2.microsoft.com/es-es/default.aspx

143

Parte V

Tratamiento Digital de
Seal

C A P T U L O 7 Tratamiento Digital de Seal

Tratamiento Digital de Seal

7.1 Procesado digital de seal aplicado al audio


El procesado digital de seal ha supuesto un gran avance en el campo del audio,
aunque su desarrollo ha sido relativamente lento por la gran cantidad de potencia de
clculo que se requiere.
La primera aplicacin comercial del procesado digital data de principios de los 80 en los
reproductores de CD, que incorporaban filtros FIR para mejorar la reconstruccin de la
seal analgica. En esta poca todava resultaba demasiado caro cualquier otro tipo de
procesado digital, de manera que los soportes digitales convivan con amplificadores y
ecualizadores analgicos. Incluso en los estudios de grabacin se empleaba una amplia
variedad de equipos analgicos por la escasez de equipos y aplicaciones capaces de
procesar el audio digital.
A principios de los 90 hizo su aparicin el DSP (Digital Signal Processor), un
procesador especializado para operaciones matemticas en serie sobre grandes
cantidades de datos. El DSP permiti llevar a la prctica toda la teora de procesado
digital que hasta entonces slo poda ser probada en simulaciones, pero no en tiempo
real. Adems el DSP era programable, lo cual permita cambiar sobre la marcha el tipo
de procesado que se haca sobre el audio. Hasta entonces la nica manera econmica de
disponer de un procesado digital era mediante circuitos programados sobre hardware,
como era el caso de los reproductores de CD.
Al principio el DSP era caro, ya que deba tener suficiente potencia para realizar por
software lo que otros circuitos hacan por hardware. Durante algunos aos el procesado
digital de audio dependa de costosas tarjetas DSP que se aadan a los ordenadores para
realizar los clculos que eran demasiado pesados para el procesador. Estas tarjetas eran
adems propietarias, de manera que el hardware y la aplicacin estaban estrechamente
relacionados.
A mediados de los 90 comenzaron a aparecer procesadores de uso general con
extensiones multimedia, es decir, con un DSP integrado. Progresivamente el juego de
instrucciones multimedia se fue popularizando e integrndose en las aplicaciones, y
comenzaron a aparecer los primeros programas de procesado de audio para todos los
pblicos.
La consagracin del procesado digital como norma general para el audio se produjo con
la popularizacin del formato MP3. La capa III de MPEG es una especificacin para la
compresin de audio por transformada, que en lugar de almacenar la onda de audio en el
tiempo se almacena su transformada en frecuencia, con ciertos recortes para reducir la
tasa binaria. A partir de este momento el procesado digital salt de los ordenadores a los
dispositivos porttiles, resultando cada vez ms barato y ms eficiente.

147

C A P T U L O 7 Tratamiento Digital de Seal

7.2 Algoritmos bsicos para audio


En esta seccin se comentarn algunos algoritmos bsicos en el procesado de audio.
Existen muchos ms efectos, pero casi todos se basan en combinaciones de los que aqu
se mencionan.
Los efectos de audio se pueden clasificar en dos grupos bsicos:

Lineales: el audio resultante es una combinacin de las muestras presentes o


pasadas del audio inicial multiplicadas por coeficientes que son independientes
de la amplitud. Esto no significa que los coeficientes tengan que ser constantes,
sino que en un instante de tiempo dado se cumplan las propiedades de aditividad
y homogeneidad respecto de la seal de entrada. En esta categora se encuadran
el filtrado, la ecualizacin, el mezclado, el retardo y la envolvente.

No lineales: el audio resultante depende del audio inicial con una relacin que
no es una constante, sino una funcin del mismo. En esta categora se encuadran
la compresin o expansin del rango dinmico, la distorsin y el recorte
(clipping).

Como veremos a continuacin, muchos de los efectos que simulan procesos del
mundo real estn modificados en alguno de sus parmetros por funciones que varan
con el tiempo.

7.2.1 Filtros
Un filtro es un procesado de sonido que tiene como resultado la reduccin o
amplificacin de la seal en alguna banda de frecuencia. El filtrado se consigue
mediante la suma de la seal original con diversas muestras retardadas y multiplicadas
por ciertos coeficientes.
Existen dos categora bsicas para la realizacin de filtros digitales:
IIR (Infinite Impulse Response), o filtro recursivo: en este tipo de filtro la
seal de salida depende de la seal de entrada con diversos retardos y de la seal
de salida retardada, todas ellas multiplicadas por ciertos coeficientes. Al
depender la seal de salida de las muestras retardadas de la misma, se produce
un bucle de realimentacin que mantiene la seal activa de manera infinita. En la
prctica, los coeficientes y la cuantizacin de los datos hacen que la seal
realimentada acabe extinguindose. Tambin es posible que la seal de salida
oscile o se amplifique, pero estos no son efectos deseables en un filtro. Un filtro
IIR responde a la frmula general:
y[n] = b0x[n] + b1x[n-1] + b2x[n-2] + ... a1y[n-1] a2y[n-2] ...

148

FIR (Finite Impulse Response), o filtro no recursivo: En este tipo de filtro la


seal de salida depende nicamente de las muestras de la seal original con
diversos retardos y multiplicadas por ciertos coeficientes. Por tanto, una vez
extinguida la seal de entrada, la seal de salida desaparecer una vez
transcurrido el retardo del filtro. Una caracterstica del filtro FIR es que la

C A P T U L O 7 Tratamiento Digital de Seal


respuesta impulsional se corresponde con los valores de los coeficientes del
filtro, lo cual simplifica bastante la programacin de una respuesta en frecuencia
determinada. Un filtro FIR responde a la frmula general:
y[n] = b0x[n] + b1x[n-1] + b2x[n-2] + ...
Para ambas categoras existen varias formas de construir el filtro segn cmo se
desee optimizar el hardware asociado. Los elementos de diseo bsicos son el retardo
(que es un registro), el multiplicador y el sumador. La estructura del filtro es muy
importante para optimizar el uso de recursos y la precisin de las operaciones. Para una
funcin de transferencia dada, existen diversas implementaciones posibles. Las
estructuras bsicas son:

Forma directa I: esta estructura requiere el doble de celdas de retardo que el


orden del filtro.

Figura 7.1

Forma directa II o cannica: esta estructura requiere el mismo nmero de


celdas de retardo que el orden del filtro.

Figura 7.2
En el caso de un filtro FIR, la seccin de coeficientes ai no existira. Dicha seccin
representa la parte recursiva del filtro, y es responsable de los polos de la funcin de
149

C A P T U L O 7 Tratamiento Digital de Seal


transferencia. La seccin de coeficientes bi representa los ceros de la funcin de
transferencia. En la cercana de los polos, la funcin de transferencia aumenta mucho de
valor, pudiendo causar problemas de desbordamiento en los sumadores. En la cercana
de los ceros, la funcin de transferencia se acerca a cero, pudiendo causar problemas de
cuantizacin. Es por ello que la eleccin de la estructura del filtro debe hacerse
cuidadosamente segn la funcin que se desee implementar.
La ventaja de los filtros FIR es que se pueden realizar estructuras muy largas puesto
que la seal no se amplifica durante el camino. No obstante, para lograr una respuesta
abrupta se puede requerir una gran cantidad de etapas. Los coeficientes del filtro FIR
equivalen a las muestras de la respuesta impulsional, o dicho de otra manera, a la
transformada inversa de su respuesta en frecuencia, lo cual simplifica su realizacin.
Los filtros IIR pueden presentar grandes resonancias a lo largo de la estructura. En
consecuencia, se suele recurrir a encadenar filtros IIR de orden bajo para asegurar que la
seal no diverja demasiado. El diseo del filtro IIR es ms complejo, ya que hay que
combinar ceros y polos para lograr la respuesta deseada. Una manera tpica de disear
filtros IIR es usando las funciones de transferencia de filtros analgicos como
referencia.
7.2.2 Envolvente de volumen
Una envolvente de volumen es una modulacin de la amplitud de la seal de forma
variable en el tiempo. Equivale a multiplicar el valor de cada muestra por el valor de la
funcin envolvente en el correspondiente instante de tiempo.
Las envolventes se emplean de manera sistemtica en la sntesis de sonido para generar
sonidos ms reales.
A continuacin se describen algunos tipos de envolventes:

Fundido (fade): el fundido se suele utilizar al inicio de una pieza musical (fadein) o al final (fade-out) para lograr una transicin suave de la msica al silencio
y viceversa. En estos casos se aplica una envolvente exponencial para que,
combinada con la respuesta del odo al volumen, el oyente tenga una impresin
lineal.
Trmolo: el trmolo se utiliza para simular instrumentos musicales en la sntesis
de sonido, y suele ser una envolvente sinusoidal de frecuencia inferior a la
audible.
Envolvente de nota musical: modula la amplitud de la nota en 4 fases: ataque,
decaimiento, sostenido y liberacin. Simula los distintos estados de vibracin
por los que pasa un instrumento musical durante la generacin de una nota. En el
caso de un instrumento de cuerda hay 4 fases, pero en otros puede haber menos.

7.2.3 Retardo
El retardo consiste en generar una copia retrasada del sonido original con el objeto
de mezclarla con ste. La seal retardada se manipula y se mezcla con el sonido original
para generar el efecto deseado.
El retardo es importante en muchos efectos musicales, entre ellos los filtros, pero
tambin otros ms exticos como el flanger y phaser.

150

C A P T U L O 7 Tratamiento Digital de Seal


Hay varios tipos de efectos que se basan en el retardo de la seal:

Coros: consiste en mezclar una o ms versiones retardadas del sonido con el


audio original. El retardo debe ser superior a 5 ms para ser percibido por el
oyente y para evitar la interferencia destructiva con la onda original. Las
versiones retardadas se pueden manipular para que se diferencien mejor del
sonido original. El efecto resultante se asemeja a un coro de voces o
instrumentos interpretando una misma pieza musical.
Eco: consiste en mezclar una o ms versiones retardadas del sonido con el audio
original. El retardo debe ser superior a 50 ms para producir este efecto. Se
pueden aadir rplicas con distintos retardos para simular mltiples reflexiones
del sonido en la distancia.
Reverberacin: se suele distinguir el eco de la reverberacin por el nmero de
rplicas y el retardo entre las mismas. El eco tiene pocas rplicas que son
distinguibles en el tiempo por el oyente. En cambio, la reverberacin est
compuesta de muchas rplicas que llegan en un intervalo reducido de tiempo (<1
ms). La reverberacin representa mejor el efecto que se produce al propagarse el
sonido en un recinto cerrado. Para simular el efecto de la absorcin del sonido
por los materiales las rplicas deben estar afectadas por una envolvente de
volumen. El tiempo que tarda en extinguirse el eco viene dado por la ecuacin
de Sabine:

T=

V
c Sa

T: tiempo hasta que el eco se atena 60 dB (s)


c: velocidad del sonido en el aire (340 m/s)
V: volumen del recinto (m3)
S: superficie del recinto (suelo, techo y paredes) (m2)
a: coeficiente de absorcin de los materiales

Figura 7.3. Nivel sonoro para un recinto con paredes desnudas (rojo) y el mismo
recinto con moqueta (negro).
Phaser: consiste en mezclar el sonido original con una versin del mismo con
desfase constante, es decir, una copia exacta donde todas las frecuencias han
sufrido el mismo desfase. No se trata de un simple retardo temporal, sino de un
filtrado de fase lineal. El resultado es un sonido de aspecto sinttico,
especialmente cuando se usa sobre voces.
Flanger: consiste en mezclar la seal original con una versin que tiene un
retardo variable controlado por otra seal. El resultado de mezclar una seal con
otra versin retardada es que se produce un filtrado en peine debido a la

151

C A P T U L O 7 Tratamiento Digital de Seal


interferencia destructiva en frecuencias equiespaciadas, por lo que el espectro
resultante presenta picos y valles que van cambiando de posicin segn la seal
moduladora. Para que se aprecie la variacin espectral, el sonido original debe
ser rico en armnicos, de manera que siempre quede algo de seal despus del
filtrado en peine.
7.2.4 Compresin
La compresin es un efecto no lineal que reduce el rango dinmico de una seal de
audio, es decir, disminuye la diferencia entre la amplitud mxima y la mnima. Este
efecto se consigue aplicando una funcin para la que la relacin entre el valor de salida
y el de entrada sea menor cuanto mayor sea la amplitud del segundo. Este efecto se
utiliza mucho en produccin para acomodar sonidos tenues e intensos sobre un registro
con rango dinmico limitado sin que se pierdan los primeros ni se saturen los segundos.
Este efecto se usara para convertir una grabacin de una con 20 bits a un formato CD
de 16 bits.
En la siguiente figura podemos observar la relacin entre el nivel de entrada de la
seal de audio, el nivel de salida, y la reduccin de ganancia como consecuencia de la
compresin.

Figura 7.4. Funcin de transferencia de un compresor de rango dinmico.

152

C A P T U L O 7 Tratamiento Digital de Seal

7.3 Transformada rpida de Fourier (FFT)


Comenzaremos explicando la forma analtica de la transformada de Fourier de una
seal discreta en el tiempo (muestreada), tambin conocida como DTFT (Discrete Time
Fourier Transform). Existen numerosas analogas entre la transformada de una seal
continua y una discreta, aunque tambin hay diferencias esenciales que a continuacin
describiremos.
La transformada de Fourier para una seal discreta x[n] se define como:
X() =

n =

x[n]e

jn

n =

Donde x[n] es una seal discreta infinita en el tiempo y X() es una funcin
continua que se repite peridicamente con un intervalo 2. Comnmente se utiliza el
intervalo [-, ] para referirse al rango de frecuencia de la seal discreta. Obsrvese que
el rango de frecuencia es adimensional, es decir, no est referido a ninguna unidad de
medida de frecuencia ya que la seal muestreada en el tiempo tambin es adimensional,
pues al muestrearla se convierte en una sucesin de valores sin escala temporal. Por
tanto, se habla de como la frecuencia normalizada en radianes, aunque tambin se
puede sustituir por 2f, en cuyo caso la frecuencia normalizada representa la relacin
f/fs (fs = frecuencia de muestreo) y su intervalo es de [-0.5, 0.5].
Esta periodicidad es la principal diferencia con la transformada continua de Fourier,
que existe de - a . En este punto es donde debemos enlazar con el captulo 1 de
muestreo de seal. La frecuencia representa la frecuencia de Nyquist de la seal
discreta. Recurdese que el espectro de una seal muestreada se repite peridicamente y
que toda componente frecuencial que se encuentre por encima de la frecuencia de
Nyquist aparece alienada como una frecuencia dentro del rango permitido (figura 7.5).
La explicacin de este efecto de aliasing la tenemos en la propia definicin de la
transformada.
En Tratamiento Digital de Seal la notacin, e-jn tambin se puede representar
como cos(n) + jsen(n), donde j es la unidad imaginaria, tambin representada como
i.

Figura 7.5. Muestreo de una seal y alisasing.

153

C A P T U L O 7 Tratamiento Digital de Seal


Si x[n] es una seal real, como es habitualmente el caso en el muestreo de audio, la
transformada X() es una funcin donde la parte negativa es la conjugada de la parte
positiva, es decir X*(-) = X(). Si tenemos en cuenta que la transformada se puede
representar en trminos de amplitud y fase, una seal real producira una transformada
cuyo mdulo es simtrico respecto a cero mientras que la fase tiene signo distinto a un
lado y otro del cero. Por este motivo, en muchos casos tan slo se representa la
magnitud de la transformada entre 0 y .
En un sistema de procesado de seal las seales en el tiempo no son infinitas y
tampoco se puede representar numricamente una transformada que es una funcin
continua. Para este caso existe una nueva aproximacin de la transformada que es la
transformada discreta de Fourier o DFT (Discrete Fourier Transform) donde tanto la
seal en el tiempo como la seal transformada son discretas y limitadas en el tiempo.
La transformada discreta de Fourier de una seal discreta x[n] sobre un nmero de
muestras N se define como:
N 1

X[k ] = x[n]e

2 kn
N

n =0

La transformada discreta es una aproximacin de la transformada continua bajo


ciertas condiciones. Si la seal temporal que se analiza es un ciclo exacto de una seal
peridica entonces la transformada discreta es una versin muestreada de la
transformada continua. Sin embargo, esto no es normalmente as en la seales de audio
muestreadas, y por tanto la transformada de una porcin de audio dar como resultado
una aproximacin de su contenido en frecuencia con ciertos artefactos. Estos artefactos
son consecuencia del enventanado.
Si tomamos una porcin de una seal senoidal muestreada y calculamos su
transformada, muy probablemente lo que veremos no ser una raya a la frecuencia
normalizada de la senoidal, sino un lbulo principal ms o menos ancho acompaado de
varios lbulos laterales de amplitud decreciente a ambos lados del primero, como se
muestra en la figura 7.6. Lo que ha ocurrido es que transformada se ha convolucionado
con transformada de la funcin rectangular, que es la mscara que hemos utilizado
para seleccionar un fragmento de la seal senoidal, que por definicin es infinita. Tan
slo si el fragmento seleccionado se corresponde exactamente a un ciclo de la seal
senoidal la transformada discreta de una seal finita coincidir completamente con la
transformada continua de una seal infinita.

154

C A P T U L O 7 Tratamiento Digital de Seal

Figura 7.6. Transformada discreta de una porcin de seal sinusoidal.


Esta mscara utilizada para seleccionar una porcin de la seal temporal se
denomina ventana, y la forma de la misma determina la resolucin con la cual se podrn
distinguir las componentes espectrales de la seal temporal. Hay muchos tipos de
ventanas segn se quiera mejorar la resolucin espectral o el rango dinmico del
espectro. Las ventanas ms comunes para mejorar la resolucin espectral (para
distinguir mejor las componentes espectrales) son las de von Hann, Hamming,
Blackman y coseno alzado. Las ventanas ms comunes para mejorar el rango dinmico
de la transformada son las de Blackman. A diferencia de la ventana rectangular, todas
estas ventanas
El uso de una ventana es importante cuando se realiza la transformada de una seal
de audio al vuelo, ya que se debe seleccionar una porcin de audio suficientemente
larga para representar todas las componentes espectrales pero suficientemente corta para
generar una carga computacional asequible y un refresco del espectro razonable.
El aspecto computacional es importante, ya que la transformada exige un gran
nmero de sumas, multiplicaciones y operaciones trigonomtricas que requieren
bsquedas en tablas. Para reducir esta carga computacional est la transformada rpida
de Fourier or FFT (Fast Fourier Transform) que explota ciertas propiedades de la
transformada para reducir el nmero de operaciones. As, mientras que la DFT requiere
N2 multiplicaciones complejas, algoritmos como el de Cooley-Tukey requieren tan slo
(N/2) log2 N. La restriccin de este algoritmo es que slo puede hacerse sobre un
nmero de muestras que sea potencia de 2, aunque existen otros algoritmos para
descomponer muestras de tamao arbitrario en secciones donde se pueden aplicar los
algoritmos rpidos.
El algoritmo de mariposa o de Cooley-Tukey consiste en calcular la FFT como
combinacin de otras FFTs de la mitad de longitud (figura 7.7), prosiguiendo
recursivamente hasta llegar a la transformada elemental de 2 muestras (figura 7.8). Esta
transformada de dos muestras se calcula de forma muy simple como sumas y restas de
las muestras de entrada. Al combinar las FFTs se utilizan unos multiplicadores que
corresponden a valores de la exponencial e-jn evaluada en posiciones fijas.

155

C A P T U L O 7 Tratamiento Digital de Seal

Figura 7.7. Descomposicin de la transformada en transformadas menores mediante


diezmado y operaciones en mariposa.

Figura 7.8. FFT bsica de 2 puntos, tambin conocida como operacin mariposa.
La esencia del algoritmo Cooley-Tukey es separar la FFT en muestras pares e
impares, de manera que el sumatorio inicial
N 1

X[k ] = x[n]e

2 kn
N

n =0

se transforma en
X[k ] =

N / 2 1

x[2n]e

2 k ( 2 n )
N

N / 2 1

n =0

x[2n + 1]e

2 k ( 2 n +1)
N

n =0

Donde el primer sumatorio corresponde a las muestras pares y el segundo a las


impares. Si extraemos el trmino e
reescribirse como:
X[k ] =

N / 2 1

x[2n]e

2 k
N

2 k ( 2 n )
N

del segundo sumatorio, la expresin puede

+e

2 k N / 2 1
N

x[2n + 1]e

n =0

2 k ( 2 n )
N

n =0

Obsrvese que la primera parte es sencillamente la DFT de las muestras pares,


mientras que la segunda parte es la DFT de las muestras impares multiplicada por un
coeficiente. Es decir:
j

2 k
N

X[k ] = DFT(pares) + e
DFT(impares)
Dicho coeficiente se denomina factor de alternancia y habitualmente se representa
como WNk . Si la transformada tuviera slo dos muestras (N=2), dicho trmino valdra 1

156

C A P T U L O 7 Tratamiento Digital de Seal


para k=0 y 1 para k=1. En consecuencia se reduce enormemente el nmero de
operaciones con nmeros complejos a cambio de una mayor complejidad en los cruces
de muestras mediante operaciones en mariposa, lo cual no es un problema para un
algoritmo recursivo.
Un problema adicional cuando se calcula una DFT al vuelo para representar
dinmicamente el espectrograma de un sonido es que al tomar bloques consecutivos de
muestras existen discontinuidades que pueden causar grandes diferencias en el espectro
resultante. Una forma de evitar este problema es tomar secciones de audio solapadas y
aplicar un enventanado, de manera que el espectro resultante refleje mejor las
variaciones del contenido musical. Este mtodo se conoce como Transformada de
Fourier a Corto Plazo (Discrete-Time STFT). Esta transformada se parece a la DFT pero
se incluye un trmino de enventanado w[n].
N 1

X[k , m] = w[n m] x[n]e

2 kn
N

n =0

157

C A P T U L O 7 Tratamiento Digital de Seal

7.4 Libreras C++


7.4.1 Modelos de libreras
Comenzaremos esta seccin de programacin introduciendo los elementos software
bsicos que implementarn los conceptos previamente explicados.
En el desarrollo de aplicaciones en C++ para Tratamiento Digital de seal se pueden
utilizar las libreras industriales de las compaas Intel o AMD, o en su caso las libreras
de cdigo fuente abierto Spuc, que es el acrnimo de Signal Processing Using C++
A DSP Library.
Puesto que algunas libreras enunciadas anteriormente son comerciales o
excesivamente complejas, en este apartado proponemos una librera para Visual C++
que simplifica en gran medida el desarrollo de aplicaciones de Tratamiento Digital de
Seales. Esta librera es de la compaa Mitov, que ofrece una serie de componentes en
varios lenguajes dentro de la plataforma Win32 y .NET para el desarrollo de
aplicaciones de manejo de seal de alto rendimiento.
7.4.2 Mitov
El software de Mitov est especializado en el desarrollo de procesado rpido de
seal para audio y video. Las libreras estn orientadas a su utilizacin en plataformas
Windows bajo los compiladores de Delphi, Borland C++ Builder, Visual C++ con MFC
y .NET.
En el presente captulo se va a explicar cmo utilizar los componentes bsicos de la
librera dentro del entorno de desarrollo de Microsoft Visual C++.1
El paquete software podemos localizarlo a travs de la URL http://www.mitov.com.
Una vez descargado, se puede leer en la documentacin de la licencia que el
producto software es de pago para aplicaciones con salida comercial, mientras que las
aplicaciones utilizadas con fines educativos no implican el pago de ninguna cantidad.
7.4.3 Principales libreras de Mitov
Los principales componentes incluidos en la suite de la compaa Mitov son los
que a continuacin se enumeran:

VideoLab: es un conjunto de objetos para la captura, reproduccin, procesado,


manipulaciones geomtricas, mezclado, anlisis y visualizacin. Ofrece, entre
otras posibilidades, manipulaciones rpidas y complejas de video.
AudioLab: permite la captura, reproduccin, procesado, mezclado, anlisis y
visualizacin de audio. Generalmente utiliza como formato de entrada la
extensin WAV.
SignalLab: conjunto de componentes para el procesamiento rpido de seal
(DSP). Contiene objetos para la visualizacin de la seal por medio de
osciloscopios.
VisionLab: es una coleccin de objetos orientados a la visin bsica por
computador. El componente permite el desarrollo de aplicaciones de deteccin

Se compilar con el IDE Microsoft Visual C++ 2005 8.0

158

C A P T U L O 7 Tratamiento Digital de Seal

de movimiento para la industria de la seguridad. Incluye algoritmos para la


deteccin de contornos, rostros y objetos.
PlotLab: componente para el desarrollo de aplicaciones que requieren el uso de
grficas y representacin estadstica de datos.

stas son a grandes rasgos los principales componentes o libreras de la suite


del software de Mitov. Las libreras concernientes a este captulo sern AudioLab y
SignalLab, para la reproduccin de audio y el tratamiento digital de seales
respectivamente.

7.4.4 Conceptos bsicos de las libreras SingalLab y AudioLab


Como se ha comentado anteriormente, la librera SignalLab permite la manipulacin
de seal por medio de varios objetos fundamentales. Gracias a ellos es posible
programar aplicaciones de seal en Visual C++ con apoyo de las libreras de MFC
(Microsoft Foundation Classes).
Comenzaremos explicando esta primera librera bsica. Con el fin de desarrollar una
aplicacin con SingalLab o AudioLab es imprescindible, en primera instancia, crear un
proyecto del tipo MFC, aplicacin de dilogo, en un entorno de desarrollo de Microsoft.
La peculiaridad de los objetos de visualizacin de grficas (Scopes), es que se requiere
enlazar el identificador de un componente tipo Label, sobre una aplicacin basada en un
cuadro de Dilogo, con un objeto del tipo CTSLScope. De esta manera se obtendra el
siguiente cdigo que se muestra en el ejemplo:
// SignalGeneratorDlg.h : fichero cabecera
//
#pragma once
#include "afxwin.h"
#include <CSLScope.h> // Ficheros cabecera de la librera
#include <CSLSignalGen.h>
// CSignalGeneratorDlg dialog
class CSignalGeneratorDlg : public CDialog
{
// Construccin
public:
CSignalGeneratorDlg(CWnd* pParent = NULL); // Constructor
// estndar
// Datos del dilogo
enum { IDD = IDD_SIGNALGENERATOR_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
// para intercambio de datos dinmico
// Implementacin
protected:
CTSLScope SLScope; // Objeto para visualizacin
CTSLSginalGen SLSignalGen; // Objeto para generacin de seal

159

C A P T U L O 7 Tratamiento Digital de Seal


protected:
HICON m_hIcon;

Finalmente, se requiere enlazar el handler de ventana del control Label con el


objeto SLScope, dentro del mtodo ::OnInitDialog() de punto de entrada de la
aplicacin, tal como se muestra en el siguiente fragmento de cdigo fuente:
VCL_InitControls( m_hWnd );
SLScope.Open( m_Scope.m_hWnd ); // Aqu enlazamos el handler
SLSignalGen.OutputPin.Connect( SLScope.InputPins[ 0 ] );
VCL_Loaded();
return TRUE; // return TRUE unless you set the focus to a
control
}

El resultado se ilustra en la siguiente figura:

Figura 7.9 Generacin de una forma de onda bsica


Como se puede observar, con muy pocas lneas de cdigo hemos conseguido una
pequea y bsica aplicacin que genera una seal elemental sinusoidal y la representa
en un osciloscopio virtual.
Otra cuestin clave es la interconectividad entre los objetos de seal, es decir, entre
el objeto de generacin de seal bsica y el objeto del osciloscopio. Para conseguir este
propsito se recurre a las propiedades de los objetos OutputPin e InputPin, que son las
responsables de conectar la salida de generacin de onda con la entrada del
osciloscopio. De esta manera, y como se explica en el cdigo fuente se lleva a cabo de
la siguiente forma:
SLSignalGen.OutputPin.Connect( SLScope.InputPins[ 0 ] );

160

C A P T U L O 7 Tratamiento Digital de Seal

Figura 7.10 Diagrama de interconexin entre los objetos


Con esto conseguimos conectar la salida del generador de seal con una de las
entradas del osciloscopio, puesto que es posible conectar varias entradas para la
visualizacin de seal, con slo cambiar el ndice del array de la propiedad, en el modo
que se muestra en el siguiente fragmento de cdigo:
SLSignalGen1.OutputPin.Connect( SLScope.InputPins[ 0 ] );
SLSignalGen2.OutputPin.Connect( SLScope.InputPins[ 1 ] );
SLSignalGen3.OutputPin.Connect( SLScope.InputPins[ 2 ] );
.
.
.

Explicaremos ahora el funcionamiento trivial del componente AudioLab. Es


importante saber que son imprescindibles dos objetos bsicos para la lectura de un
fichero de sonido y la salida de audio por el altavoz del sistema. Etos son
CTALWavePlayer y CTALAudioOut respectivamente.
El primero de ellos permite la lectura de un fichero en formato WAV que
posteriormente ser redirigirlo a un objeto de SignalLab o al propio objeto de salida de
audio. El funcionamiento de estos objetos es muy simple y sigue la misma filosofa que
se ha explicado en el ejemplo de la generacin de una seal de sonido bsica. En este
caso, la interconexin para la lectura de un fichero y su reproduccin por uno de los
canales de salida de audio del sistema, se realizara de la siguiente manera que se
muestra a continuacin:
{
// Construccin
public:
CAudioPlayerDlg(CWnd* pParent = NULL); // Constructor
estndar
// Datos del dilogo
enum { IDD = IDD_AUDIOPLAYER_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV
// para intercambio dinmico de datos
// Implementacin
protected:
CTALWavePlayer ALWavePlayer; // Objeto reproductor de sonido
CTALAudioOut ALAudioOut; // Objeto de salida de audio
protected:
HICON m_hIcon;
// Funciones miembro
virtual BOOL OnInitDialog();

161

C A P T U L O 7 Tratamiento Digital de Seal


afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
};

Como podemos observar, en primer lugar se declaran los objetos CTALWavePlayer


y CTALAudioOut.
Por ltimo se interconectan en uno de los mtodos de la aplicacin basada en
dilogos; pero en este caso en concreto, se utiliza el mtodo OnInitDialog como punto
de entrada a la aplicacin. En el cdigo que se muestra a continuacin podemos apreciar
el funcionamiento de los respectivos objetos de AudioLab:

BOOL CAudioPlayerDlg::OnInitDialog()
{
CDialog::OnInitDialog();
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING,
IDM_ABOUTBOX,
strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE); // Establece icono grande
SetIcon(m_hIcon, FALSE); //Establece icono pequeo
// Lectura del fichero WAV
ALWavePlayer.FileName = "C:\\Program Files\\LabPacks\\Visual
C++\\Demos\\AVIFiles\\Demo.wav";
// Redireccin al canal de salida de audio
ALWavePlayer.OutputPin.Connect( ALAudioOut.InputPin );
VCL_Loaded(); // Inicio de los controles Mitov
return TRUE;
}

Obviamente, en la primera lnea en negrita indicamos el fichero de sonido WAV2


que necesitamos leer, y por ltimo, interconectamos la salida del objeto reproductor con
la entrada del objeto de salida de audio en el sistema.

En este tratado nicamente se utilizar el formato WAV por su calidad; aunque es posible utilizar otros
formatos en Mitov como WMA.

162

C A P T U L O 7 Tratamiento Digital de Seal


En la siguiente figura se ilustra dicha interconexin:

Figura 7.11 Diagrama de conexin entre los objetos


Para concluir y con el fin de que funcionen correctamente todas las libreras dentro
de la aplicacin Visual C++ no debemos olvidar llamar a la funcin VCL_Loaded() que
se responsabilizar de iniciar y arrancar todo el sistema de objetos SignalLab y
AudioLab.

7.5 Desarrollo de una aplicacin de procesado de seal


7.5.1 Diagrama de bloques
El propsito de este apartado es explicar cmo se desarrolla una aplicacin completa
de procesado digital de audio en un entorno conocido como es Visual C++.
Con el fin de exponer un ejemplo prctico del mundo real, se ha pretendido
implementar un programa que realiza varias operaciones elementales con un objetivo
obviamente instructivo de tratamiento de seal.
La aplicacin consiste en una ventana de dilogo que importa un fichero en formato
WAV y realiza cuatro operaciones bsicas interconectadas de seal: filtrado paso bajo,
filtrado paso banda, filtrado paso alto y ecualizacin de diez bandas. La salida de esta
secuencia ser conectada a su vez, a tres osciloscopios. Estos osciloscopios son:
representacin tiempo frecuencia, onda y espectro FFT. En la imagen que se muestra
debajo de esta lneas podemos apreciar la interconexin en el diagrama de bloques:
Tiempo
frecuencia

in

out

Reproductor

ON / OFF

in

Filtro paso
bajo

out

ON / OFF

in

Filtro paso
banda

out

ON / OFF

in

out

Filtro paso alto

in

Onda

in

Espectro
(FFT)

in

Altavoz del
sistema

out

in

Ecualizador

ON / OFF

Figura 7.12 Diagrama de bloques de la aplicacin

163

C A P T U L O 7 Tratamiento Digital de Seal


7.5.2 Declaracin de objetos de librera
Para comenzar a implementar la aplicacin, es requisito imprescindible declarar los
objetos que se van a utilizar a lo largo de la aplicacin de ejemplo. Con este fin, hemos
de utilizar los siguientes objetos que se declararn inicialmente en el fichero de cabecera
de la clase del dilogo principal:
// tdsDlg.h : Fichero cabecera
//
#pragma once
// Incluye cabeceras de los ficheros de librera
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include

<CSLScope.h>
<CALWavePlayer.h>
<CALAudioOut.h>
<CALSpectrum.h>
<CSLWaterfall.h>
<CALLowPass.h>
<CALBandPass.h>
<CALHighPass.h>
<CALGraphicEqualizer.h>
<CSLFourier.h>
"afxwin.h"
"afxcmn.h"

// CtdsDlg dialog
class CtdsDlg : public CDialog
{
// Construccin
public:
CtdsDlg(CWnd* pParent = NULL);

// Constructor estndar

// Datos del dilogo


enum { IDD = IDD_TDS_DIALOG };
protected:
virtual void DoDataExchange(CDataExchange* pDX);
// para intercambio dinmico de datos

// DDX/DDV

// Implementacin
protected:
CTSLWaterfall SLScope; // Scope Waterfall
CTSLScope SLScope2;
// Scope en tiempo
CTSLScope SLScope3;
// Scope para Fourier
// Objetos de SignalLab y AudioLab
CTSLFourier SLFourier;
// Objeto
CTALLowPass SLLowPass;
// Objeto
CTALBandPass SLBandPass; // Objeto
CTALHighPass SLHighPass; // Objeto
CTALGraphicEqualizer SLEqualizer;
CTALWavePlayer ALWavePlayer;
CTALAudioOut ALAudioOut; // Objeto
CTALSpectrum ALSpectrum; // Objeto

164

que realiza FFT


filtro paso bajo
filtro paso banda
filtro paso alto
// Objeto ecualizador
// Objeto reproductor
salida de audio
espectro

C A P T U L O 7 Tratamiento Digital de Seal


Como podemos observar se declararn los objetos dentro de la clase que hereda
de CDialog en la parte protected de la misma.

7.5.3 Inicializacin e interconexin de objetos


Con la idea de poder comenzar la aplicacin con unos valores iniciales por defecto,
llamaremos a los constructores y mtodos de inicializacin de los objetos que se han
declarado en la seccin anterior. En el siguiente fragmento de cdigo podemos observar
la inicializacin tanto de los objetos de librera, como de los controles GUI de la
aplicacin visual. Para conseguir esto sobrecargamos el mtodo OnInitDialog de MFC
donde comenzamos a iniciar objetos:
// Manejador de mensaje OnInitDialog
BOOL CtdsDlg::OnInitDialog()
{
CDialog::OnInitDialog();

ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);


ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
CString strAboutMenu;
strAboutMenu.LoadString(IDS_ABOUTBOX);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX,
strAboutMenu);
}
}
SetIcon(m_hIcon, TRUE);
SetIcon(m_hIcon, FALSE);

// Establece icono grande


// Establece icono pequeo

VCL_InitControls(m_hWnd); // Inicia librera


SLScope.Open(m_Scope.m_hWnd); // Conecta scopes con handlers de
controles
SLScope2.Open(m_Scope2.m_hWnd);
SLScope3.Open(m_Scope3.m_hWnd);
SLScope3.Visible = false; // Fourier no es visible al principio
// Cambia ttulos de los scopes
SLScope.Title.Text = "Tiempo frecuencia";
SLScope2.Title.Text = "Onda";
SLScope3.Title.Text = "Espectro (FFT)";
// Conecta el Wave player con el filtro paso bajo
ALWavePlayer.OutputPin.Connect(SLLowPass.InputPin);
// Desactiva filtros

165

C A P T U L O 7 Tratamiento Digital de Seal


SLLowPass.Enabled
SLBandPass.Enabled
SLHighPass.Enabled
SLEqualizer.Enabled

=
=
=
=

false;
false;
false;
false;

// Inicia frecuencias de los filtros


SLLowPass.Frequency = 5000;
SLBandPass.FreqHigh = 11000;
SLBandPass.FreqLow
= 9000;
SLHighPass.Frequency = 5000;
SLEqualizer.Channels.Add(10);
// Establece coeficientes y frecuencias en el ecualizador
SLEqualizer.Channels[0].Coefficient = 1.0;
SLEqualizer.Channels[0].Frequency
= 31.25;
SLEqualizer.Channels[1].Coefficient = 1.0;
SLEqualizer.Channels[1].Frequency
= 62.5;
SLEqualizer.Channels[2].Coefficient = 1.0;
SLEqualizer.Channels[2].Frequency
= 125.0;
SLEqualizer.Channels[3].Coefficient = 1.0;
SLEqualizer.Channels[3].Frequency
= 250.0;
SLEqualizer.Channels[4].Coefficient = 1.0;
SLEqualizer.Channels[4].Frequency
= 500.0;
SLEqualizer.Channels[5].Coefficient = 1.0;
SLEqualizer.Channels[5].Frequency
= 1000.0;
SLEqualizer.Channels[6].Coefficient = 1.0;
SLEqualizer.Channels[6].Frequency
= 2000.0;
SLEqualizer.Channels[7].Coefficient = 1.0;
SLEqualizer.Channels[7].Frequency
= 4000.0;
SLEqualizer.Channels[8].Coefficient = 1.0;
SLEqualizer.Channels[8].Frequency
= 8000.0;
SLEqualizer.Channels[9].Coefficient = 1.0;
SLEqualizer.Channels[9].Frequency
= 16000.0;

SLScope3.Channels.Clear();
SLScope3.Channels.Add();
// Conecta filtro paso bajo con filtro paso banda
SLLowPass.OutputPin.Connect(SLBandPass.InputPin);
// Conecta filtro paso banda con filtro paso alto
SLBandPass.OutputPin.Connect(SLHighPass.InputPin);
// Conecta filtro paso alto con ecualizador
SLHighPass.OutputPin.Connect(SLEqualizer.InputPin);

166

C A P T U L O 7 Tratamiento Digital de Seal


// Conecta ecualizador con scopes
SLEqualizer.OutputPin.Connect(SLFourier.InputPin);
SLFourier.SpectrumOutputPin.Connect(SLScope3.InputPins[0]);
SLEqualizer.OutputPin.Connect(ALAudioOut.InputPin);
SLEqualizer.OutputPin.Connect(SLScope2.InputPins[0]);
SLEqualizer.OutputPin.Connect(ALSpectrum.InputPin);
ALSpectrum.OutputPins[0].Connect(SLScope.InputPin );
// Inicia controles de librera
VCL_Loaded();
IniciaSliders();
IniciaVariables();
setIconos();
SLScope.Levels.Axis.Autoscale = false;
return TRUE;
control
}

// return TRUE

unless you set the focus to a

En las primeras lneas se detalla cmo interconectar los controles Label con los
objetos CTSLScopes a travs de sus handlers de ventana. A continuacin se conecta el
reproductor de audio con el objeto filtro paso bajo.
Para comenzar la aplicacin de una manera clara y comprensible se ha preferido
desactivar por defecto los objetos de los filtros y el ecualizador, de esta manera se
puede observar en el cdigo cmo se establece a false las propiedades Enable de dichos
objetos. A continuacin se inician las frecuencias de corte de los filtros, as como los
coeficientes y frecuencias del ecualizador. Como ltima accin, se procede a
inerconectar los objetos de procesado de seal tal como se ilustr en el digrama de
bloques de la figura 7.12
7.5.4 Comportamiento de los filtros y el ecualizador
La ltima parte de la aplicacin es implementar el comportamiento de los filtros y el
ecualizador. Para implementar los filtros, se ha capturado el mensaje Win32 de
desplazamiento de sliders horizontales con el fin de calcular sus propiedades bsicas, de
esta manera tenemos el siguiente cdigo del mtodo sobrecargado:
// Manejador de mensajes de los sliders horizontales
afx_msg void CtdsDlg::OnHScroll(UINT SBCode,UINT nPos,CScrollBar *SB)
{
// Mensaje del slider paso bajo
if (SB==(CScrollBar *)&m_SliderBajo)
SLLowPass.Frequency = m_SliderBajo.GetPos();
// Mensaje del slider paso banda
else if ((SB==(CScrollBar *)&m_SliderFreqBanda) ||
(SB==(CScrollBar *)&m_SliderAnchoBanda))
{

167

C A P T U L O 7 Tratamiento Digital de Seal


double freqlow = (m_SliderFreqBanda.GetPos() m_SliderAnchoBanda.GetPos())/2;
if (freqlow < 20.0) freqlow = 20.0;
SLBandPass.FreqLow = freqlow;
double freqhigh = (m_SliderFreqBanda.GetPos() +
m_SliderAnchoBanda.GetPos())/2;
if (freqhigh > 20000.0) freqhigh = 20000.0;
SLBandPass.FreqHigh = freqhigh;
// Mensaje del slider paso alto
} else if (SB==(CScrollBar *)&m_SliderFreqAlto)
{
SLHighPass.Frequency = m_SliderFreqAlto.GetPos();
}
}

Como se aprecia en el cdigo, tanto para el objeto filtro paso bajo como el filtro
paso alto, nos hemos limitado a aplicar la frecuencia de corte a partir de los valores del
slider. De esta manera el filtro paso bajo obtiene unos valores comprendidos entre los
30Hz y los 10 KHz, y el el filtro paso alto unos valores comprendidos entre 30 Hz y los
15 Khz para sus sliders. Sin embargo, para el filtro paso banda se le ha aplicado la
siguiente ecuacin que expresa las frecuencias de corte:
Frecuenciaalta = frecuenciacentral +

anchobanda
2

Frecuenciabaja = frecuenciacentral

anchobanda
2

Ya slo resta implementar el comportamiento de ecualizador. Para este propsito se


ha capturado el mensaje de movimiento vertical de los sliders, puesto que en sistemas
hardware reales tpicamente se disean en esta posicin y por este motivo se han elegido
controles GUI que lo imiten. En el siguiente fragmento de cdigo que se expone a
continuacin se puede observar cmo se obtienen los valores de los coeficientes para el
ecualizador:
// Manejador de mensajes de los sliders verticales (ecualizador)
afx_msg void CtdsDlg::OnVScroll(UINT SBCode,UINT nPos,CScrollBar *SB)
{

if (SB==(CScrollBar *)&m_Slider1)
SLEqualizer.Channels[0].Coefficient
m_Slider1.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider2)
SLEqualizer.Channels[1].Coefficient
m_Slider2.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider3)
SLEqualizer.Channels[2].Coefficient
m_Slider3.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider4)
SLEqualizer.Channels[3].Coefficient
m_Slider4.GetPos()) / 100.0;

168

= (200.0 -

= (200.0 -

= (200.0 -

= (200.0 -

C A P T U L O 7 Tratamiento Digital de Seal


else if (SB==(CScrollBar *)&m_Slider5)
SLEqualizer.Channels[4].Coefficient
m_Slider5.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider6)
SLEqualizer.Channels[5].Coefficient
m_Slider6.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider7)
SLEqualizer.Channels[6].Coefficient
m_Slider7.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider8)
SLEqualizer.Channels[7].Coefficient
m_Slider8.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider9)
SLEqualizer.Channels[8].Coefficient
m_Slider9.GetPos()) / 100.0;
else if (SB==(CScrollBar *)&m_Slider10)
SLEqualizer.Channels[9].Coefficient
m_Slider10.GetPos()) / 100.0;
}

= (200.0 -

= (200.0 -

= (200.0 -

= (200.0 -

= (200.0 -

= (200.0 -

De esta forma se calculan los coeficientes para cada canal del ecualizador con la
siguiente ecuacin:
Coeficientecanal =

200 decibeliosbanda
100

169

C A P T U L O 7 Tratamiento Digital de Seal


7.5.5 Aspecto final de la aplicacin
Una vez escrito el cdigo explicado anteriormente y ejecutada la aplicacin
obtendremos la siguiente interfaz de usuario:

Figura 7.13 GUI de la aplicacin de ejemplo


En la parte izquierda podemos ver el osciloscopio para la respuesta en tiempo
frecuencia, como una representacin en vista de planta de la distribucin de las
frecuencias y sus amplitudes, mientras que en la parte derecha se visualiza la
representacin FFT de la misma seal donde se aprecia claramente en qu rango del
espectro se aglutinan las principales frecuencias.
Adems de la visualizacin de estos controles grficos, se permite la posibilidad de
aplicar un efecto de filtro paso bajo, cuyo objetivo es atenuar las frecuencias altas,
mientras que el filtro paso alto atena las frecuencias bajas. El filtro paso banda se
encarga de concentrar las frecuencias de la seal en una parte del espectro, por medio
del control Frecuencia, mientras que el control Ancho es el responsable de ampliar o
reducir el rango de frecuencias filtradas dentro del espectro.
Por ltimo, el ecualizador es el responsable de aumentar o disminuir la
intensidad en amplitud de las bandas de frecuencia seleccionadas. Si arrancamos la
aplicacin y activamos el objeto ecualizador podemos apreciar bien cmo se cambia la
intensidad de las diferentes bandas al tiempo que movemos verticalmente los sliders.

170

C A P T U L O 7 Tratamiento Digital de Seal

Bibliografa y referencias
referencias
Libros
Programacin con MFC 6.0 Herbert Schildt. Editorial Osborne McGraw-Hill, 1999.
La Web
Mitov documentation
http://www.mitov.com
MSDN
http://msdn2.microsoft.com/es-es/default.aspx
Wikipedia:
Efectos de audio:
http://en.wikipedia.org/wiki/Digital_audio_editor
http://en.wikipedia.org/wiki/Sound_effect
http://paws.kettering.edu/~drussell/demos.html
FFT:
http://en.wikipedia.org/wiki/CooleyTukey_FFT_algorithm
http://en.wikipedia.org/wiki/Butterfly_diagram

171

APNDICE

Apndice

A1. Mensajes de la especificacin MIDI 1.0


Byte estado
D7----D0

Byte(s) datos
D7----D0

Descripcin
Mensajes de canal

1000cccc

0nnnnnnn
0vvvvvvv

1001cccc

0nnnnnnn
0vvvvvvv

1010cccc

0nnnnnnn
0vvvvvvv

1011cccc

0nnnnnnn
0vvvvvvv

1100cccc

0ppppppp

1101nnnn

0ccccccc

1110nnnn

0lllllll
0mmmmmmm

Evento note-off.
Este evento es enviado cuando finaliza la nota.
(nnnnnnn) es el nmero de la nota.
(vvvvvvv) es la velocidad.
Evento note-on.
Este mensaje se enva cuando comienza una nota
(nnnnnnn) es el nmero de la nota.
Presin sobre la tecla (Aftertouch).
Este mensaje se enva para informar de la velocidad
de presin sobre la tecla.
(nnnnnnn) nmero de la nota.
(vvvvvvv) velocidad.
Cambio de control.
Este mensaje es enviado cuando se cambia un valor
de controlador.
Vase apndice A2.
(ccccccc) nmero de controlador.
(vvvvvvv) nuevo valor.
Cambio de programa
Indica un cambio de programa
(ppppppp) es el nuevo nmero de programa.
Presin del canal (After-touch).
Este mensaje es enviado cuando la presin del canal
cambia. Algunos teclados no soportan esta
caracterstica.
(ccccccc) es el nmero de canal.
Cambio de la rueda de modulacin.
Este mensaje es enviado para indicar un cambio en
la rueda de modulacin. La rueda de modulacin es
medido por el dcimo cuarto bit. El valor central es
2000H.
(llllll) son los 7 bits menos significativos.
(mmmmmm) son los 7 bits ms significativos.

173

APNDICE

1011nnnn

Mensajes de modo de canal


0ccccccc
Mensajes de modo de canal
0vvvvvvv
Es el mismo cdigo que el Cambio de
control(arriba), pero implementa un Modo de
control usando unos nmeros de controlador
reservados. Los nmeros son:
Control Local
Cuando el Control Local est off, todos los
dispositivos de un canal dado respondern
solamente a los datos recibidos sobre MIDI.
c = 122, v = 0: Control Local Off
c = 122, v = 127: Control Local On
Todas las notas desactivadas
Cuando llega este mensaje todos los osciladores se
desactivan.
c = 123, v = 0: Todas las notas Off
c = 124, v = 0: Modo Omni Off

11110000

11110001
11110010

11110011

11110100
11110101
11110110
11110111
174

c = 125, v = 0: Modo Omni On


c = 126, v = M: Modo mono On (Poly Off) donde
M es el nmero de canales
(Omni Off) o 0 (Omni On)
c = 127, v = 0: Modo Poly On (Mono Off)
(Note: Estos cuatro mensajes tambin causan todas
las notas desactivadas)
Mensajes de Sistema
0iiiiiii
Sistema exclusivo.
0ddddddd
Estos mensajes son especficos del dispositivo e
..
independientes del protocolo MIDI. Los bits (iiiiiii)
..
es la indentificacin de ID del fabricante.
0ddddddd
Si el dispositivo reconoce el ID lee los siguientes
11110111
mensajes (ddddddd). En otro caso el mensaje ser
ignorado. (Nota: Los mensajes de tiempo-real
solamente pueden ser entrelazados con los de
Sistema Exclusivo)
No definido
0lllllll
Puntero a la posicin de la cancin.
0mmmmmmm
Es un registro interno de 14 bits que almacena el
nmero de pulsos MIDI.
0sssssss
Seleccin de secuecia.
La seleccin de la cancin especifica que secuencia
o cancin debe ser reproducida..
No definido
No definido
Peticin de tono.
Fin de sistema exclusivo

APNDICE

11111000

11111001
11111010

11111011
11111100
11111101
11111110

11111111

Mensajes de tiempo-real
Reloj de tiempo.
Oscila 24 veces por cuarto de nota cuando la
sincronizacin es requerida.
No definido
Comienzo
Comienza la reproduccin de la secuencia. (Este
mensaje vendr seguido de mensajes de tiempo del
reloj).
Continua.
Continua en el punto donde la secuencia par.
Stop
Para la secuencia actual
No definido
Activa Sensing. El uso de este mensaje es opcional.
Cuando es inicialmente enviado, el receptor
esperar recibir otro mensaje Active Sensing cada
300ms (mximo), o ser asumido que la conexin
ha sido terminada. En la terminacin, el receptor
desactivar todas las voces y volver al modo
normal de operacin (Sensing no activo)
Reset.
Reinicia todos los receptores en el sistema al estado
activado. Este mensaje debera ser usado con
cuidado y preferiblemente bajo control manual.
Particularmente, no debera ser enviado con el
sistema encendido.

175

APNDICE
A2. Lista de mensajes de controladores MIDI 1.0
0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

176

Bank select
Modulation wheel
Breath control
Indefinido
Foot controller
Portamento time
Data Entry
Channel Volume
Balance
Indefinido
Pan
Expression Controller
Effect control 1
Effect control 2
Indefinido
Indefinido
General Purpose Controller
General Purpose Controller
General Purpose Controller
General Purpose Controller
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Bank Select
Modulation wheel
Breath control
Indefinido
Foot controller
Portamento time
Data entry
Channel Volume
Balance
Indefinido
Pan
Expression Controller
Effect control 1
Effect control 2
Indefinido
Indefinido
General Purpose Controller
General Purpose Controller
General Purpose Controller
General Purpose Controller
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido

#1
#2
#3
#4

#1
#2
#3
#4

APNDICE
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115

Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Damper pedal on/off (Sustain)
Portamento on/off
Sustenuto on/off
Soft pedal on/off
Legato Footswitch
Hold 2
Sound Controller 1 (Sound Variation)
Sound Controller 2 (Timbre)
Sound Controller 3 (Release Time)
Sound Controller 4 (Attack Time)
Sound Controller 5 (Brightness)
Sound Controller 6
Sound Controller 7
Sound Controller 8
Sound Controller 9
Sound Controller 10
General Purpose Controller #5
General Purpose Controller #6
General Purpose Controller #7
General Purpose Controller #8
Portamento Control
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Effects 1 Depth
Effects 2 Depth
Effects 3 Depth
Effects 4 Depth
Effects 5 Depth
Data entry +1
Data entry -1
Non-Registered Parameter Number LSB
Non-Registered Parameter Number MSB
Registered Parameter Number LSB
Registered Parameter Number MSB
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido
Indefinido

177

APNDICE
116
117
118
119
120
121
122
123
124
125
126
127

178

Indefinido
Indefinido
Indefinido
Indefinido
All Sound Off
Reset All Controllers
Local control on/off
All notes off
Omni mode off (+ all notes off)
Omni mode on (+ all notes off)
Poly mode on/off (+ all notes off)
Poly mode on (incl mono=off +all notes off)

APNDICE
A3. Lista de instrumentos GM (General MIDI)

00 - Piano de cola
acstico
01 - Piano
acstico
brillante
02 - Piano de cola
elctrico
03 - Piano de
cantina
04 - Piano Rhodes
05 - Piano con
"chorus"
06 - Clavicordio
07 - Clavinet
08 - Celesta
09 - Carilln
10 - Caja de
msica
11 - Vibrfono
12 - Marimba
13 - Xilfono
14 - Campanas
tubulares
15 - Salterio
16 - rgano
Hammond
17 - rgano
percusivo
18 - rgano de
rock
19 - rgano de
iglesia
20 - Armonio
21 - Acorden
22 - Armnica
23 - Bandonen
24 - Guitarra
espaola
25 - Guitarra
acstica
26 - Guitarra
elctrica
(jazz)
27 - Guitarra
elctrica
(limpia)
28 - Guitarra
elctrica

32 - Bajo acstico
33 - Bajo elctrico
pulsado
34 - Bajo elctrico
punteado
35 - Bajo sin
trastes
36 - Bajo
golpeado 1
37 - Bajo
golpeado 2
38 - Bajo
sintetizado 1
39 - Bajo
sintetizado 2
40 - Violn
41 - Viola
42 - Violoncello
43 - Contrabajo
44 - Cuerdas con
trmolo
45 - Cuerdas con
pizzicato
46 - Arpa
47 - Timbales
48 - Conjunto de
cuerda 1
49 - Conjunto de
cuerda 2
50 - Cuerdas
sintetizadas
1
51 - Cuerdas
sintetizadas
2
52 - Coro Aahs
53 - Voz Oohs
54 - Voz
sintetizada
55 - xito de
orquesta
56 - Trompeta
57 - Trombn
58 - Tuba
59 - Trompeta con
sordina
60 - Corno
francs

64 - Saxo soprano
65 - Saxo alto
66 - Saxo tenor
67 - Saxo bartono
68 - Oboe
69 - Corno ingls
70 - Fagot
71 - Clarinete
72 - Flautn
73 - Flauta
74 - Flauta dulce
75 - Flauta de pan
76 - Cuello de
botella
77 - Shakuhachi
(flauta
japonesa)
78 - Silbato
79 - Ocarina
80 - Meloda 1
(onda
cuadrada)
81 - Meloda 2
(diente de
sierra)
82 - Meloda 3
(rgano de
vapor)
83 - Meloda 4
(siseo
rgano)
84 - Meloda 5
(charanga)
85 - Meloda 6
(voz)
86 - Meloda 7
(quintas)
87 - Meloda 8
(bajo y
melodas)
88 - Fondo 1
(nueva era)
89 - Fondo 2
(clido)
90 - Fondo 3
(polisintetiz
ador)
91 - Fondo 4

96 - Efecto 1
(lluvia)
97 - Efecto 2
(banda
sonora)
98 - Efecto 3
(cristales)
99 - Efecto 4
(atmsfera)
100 Efecto 5
(brillo)
101 Efecto 6
(duendes)
102 Efecto 7
(ecos)
103 Efecto 8
(ciencia
ficcin)
104 Sitar
105 Banjo
106 Shamisen
107 Koto
108 Kalimba
109 Gaita
110 Violn celta
111 Shanai
112 Campanillas
113 Agog
114 Cajas
metlicas
115 Caja de
madera
116 Caja Taiko
117 Timbal
meldico
118 Caja
sintetizada
119 Platillo
invertido
120 Trasteo de
guitarra
121 Sonido de
respiracin
122 Playa
123 Piada de
pjaro
124 Timbre de
telfono

179

APNDICE
(apagada)
29 - Guitarra
saturada
(overdrive)
30 - Guitarra
distorsionad
a
31 - Armnicos
de guitarra

180

(trompa)
61 - Seccin de
metal
62 - Metales
sintetizados
1
63 - Metales
sintetizados
2

(coro)
92 - Fondo 5 (de
arco)
93 - Fondo 6
(metlico)
94 - Fondo 7
(celestial)
95 - Fondo 8
(escobillas)

125 Helicptero
126 Aplauso
127 Disparo de
fusil

APNDICE
A4. Tabla de frecuencias de notas musicales en Hertzios
Do 1: 65,406
Do# 1: 69,296
Re 1: 73,416
Re# 1: 77,782
Mi 1: 82,407
Fa 1: 87,307
Fa# 1: 92,499
Sol 1: 97,999
Sol#1: 103,826
La 1: 110
La# 1: 116,541
Si 1: 123,471

Do 2: 130,813
Do# 2: 138,591
Re 2: 146,832
Re# 2: 155,563
Mi 2: 164,814
Fa 2: 174,614
Fa# 2: 184,997
Sol 2: 195,998
Sol#2: 207,652
La 2: 220
La# 2: 233,082
Si 2: 246,942

Do 3: 261,626
Do# 3: 277,183
Re 3: 293,665
Re# 3: 311,127
Mi 3: 329,628
Fa 3: 349,228
Fa# 3: 369,994
Sol 3: 391,995
Sol#3: 415,305
La 3: 440
La# 3: 466,164
Si 3: 493,883

Do 4: 523,251
Do# 4: 554,365
Re 4: 587,33
Re# 4: 622,254
Mi 4: 659,255
Fa 4: 698,456
Fa# 4: 739,989
Sol 4: 783,991
Sol#4: 830,609
La 4: 880
La# 4: 932,328
Si 4: 987,767

Do 5: 1046,502
Do# 5: 1108,731
Re 5: 1174,659
Re# 5: 1244,508
Mi 5: 1318,51
Fa 5: 1396,913
Fa# 5: 1479,978
Sol 5: 1567,982
Sol#5: 1661,219
La 5: 1760
La# 5: 1864,655
Si 5: 1975,533

Do 6: 2093,005
Do# 6: 2217,461
Re 6: 2349,318
Re# 6: 2489,016
Mi 6: 2637,02
Fa 6: 2793,826
Fa# 6: 2959,955
Sol 6: 3135,963
Sol#6: 3322,438
La 6: 3520
La# 6: 3729,31
Si 6: 3951,066

Do 7: 4186,009
Do# 7: 4434,922
Re 7: 4698,636
Re# 7: 4978,032
Mi 7: 5274,041
Fa 7: 5587,652
Fa# 7: 5919,911
Sol 7: 6271,927
Sol#7: 6644,875
La 7: 7040
La# 7: 7458,62
Si 7: 7902,133

Do 8: 8372,018
Do# 8: 8869,844
Re 8: 9397,273
Re# 8: 9956,063
Mi 8: 10548,082
Fa 8: 11175,303
Fa# 8: 11839,822
Sol 8: 12543,854
Sol#8: 13289,75
La 8: 14080
La# 8: 14917,24
Si 8: 15804,266

181

También podría gustarte