Mini Manual OpenAL

Anuncio
Mini Manual de OpenAL
Por Daniel Barrero (dbarrero@cable.net.co) - 22/4/2002
Basado en los excelentes tutoriales de: Jorge bernal Martinez (lordloki@users.berlios.de ,
http://worldspace.berlios.de/openal/index.html)
Introducción
Open AL es una interface de software para el hardware de sonido de manera analoga al modo como
OpenGL es una interface de software para el hardware grafico, esta interface consiste de una serie de
comandos para la manipulacion de ondas sonoras, incluyendo la posicion de las fuentes de sonidos
(emisores) asi como los receptores de audio.
La característica principal de esta libreria es su capacidad de proporcionarn un sonido 3D, es decir, el
sonido variara dependiendo de donde la ubicacion en el espacio del receptor, sus movimientos
respectivos, de los objetos que se encuentren definidos en la escena, etc. Dicho sonido también
dependerá de donde se encuentre la fuente de sonido, de su velocidad, de si se aleja o se acerca, y del
tipo de sala en la que nos encontremos.
Los principales conceptos que se utilizaran con mayor frecuencia:
Efecto Doppler : Este efecto es debido principalmente a la velocidad relativa de la fuente de sonido
(source) con respecto al observador (listener) y en menor medida a la velocidad del sonido en el medio
donde nos encontremos. Lo que produce dicho efecto es un cambio de intensidad que se manifiesta de
la forma siguiente--> cuando la fuente sonora se acerca al observador el sonido parece mas agudo y
cuando la fuente sonora se aleja del observador el sonido parece mas grave. Un ejemplo sencillo en el
que se nota dicho efecto es cuando llega un tren a la estación y cuando se aleja dicho tren de la
estación.
Nivel de intensidad : El decibelio (dB) es la unidad en la que medimos la intensidad de los sonidos.
El oído humano tiene una respuesta logarítmica a los estímulos o sonidos que le llegan por lo que la
formula para obtener la intensidad de dichos sonidos será :
dB = 10 * log ( I / Io)
, donde Io = intensidad de referencia
Debido a la respuesta logarítmica del oído respecto del sonido se tiene que el nivel de intensidad (en
dB) de dos o mas fuentes no va a ser igual a la suma de los niveles de intensidades de cada fuente, es
decir que por ejemplo dos fuentes de 10 dB de nivel de intensidad no es igual a una fuente de 20 dB
sino que es igual a una fuente de 13 dB. La suma de diversas fuentes sigue la siguiente formula:
Atenuación por la distancia : Debido al incremento de la separación del observador respecto de la
fuente de sonido se produce una disminución del nivel de intensidad de dicha fuente. Esto es debido a
que el nivel de intensidad de una fuente es proporcional a la potencia de dicha fuente e inversamente
proporcional al cuadrado de la distancia, es decir I = W / A donde W es la potencia en watios y A es el
area de la esfera que rodea ala fuente (ya que el sonido se propaga en todas las direcciones) y tiene un
valor de 4*PI*radio al cuadrado.
Por lo tanto sustituyendo en la formula de niveles de intensidad podemos obtener la atenuación o
ganancia de decibelios debido a la distancia:
Reverberación : Es cuando el sonido se refleja en todas las direcciones y con igual modulo y
probabilidad pudiendo llegar al observador una vez que ha terminado de emitirse dicho sonido.
Requerimientos:
Windows: Librerias OpenAL32.lib, Alut.lib, archivos de encabezados, libreria dinamica
OpenAL32.dll, estas se pueden obtener en modo binario o fuentes en : http://www.openal.org/home
Tutoriales en español se pueden encontrar en : http://worldspace.berlios.de/openal/index.html
Ejemplo de aplicacion OpenAL y OpenGL anotado :
El objetivo de este programa es definir 3 emisores de sonido localizados en ubicaciones diferentes en
el espacio, adicionalmente se define un receptor activo el cual se puede mover en el espacio
demostrando el cambio del sonido percibido de cada fuente a medida que este se desplaza.
/* Incluir librerias standard, OpenGL y OpenAL
#include <gl/glut.h>
#include "AL/alut.h"
#include <stdlib.h>
#include <stdio.h>
*/
/* definir numero de buffers y fuentes a utilizar (iguales en este caso)
#define NUM_BUFFERS 3
#define NUM_SOURCES 3
/* definir numero de ambientes de sonido */
#define NUM_ENVIRONMENTS 1
/* definir la posicion velocidad y orientacion del receptor */
ALfloat listenerPos[]={0.0,0.0,4.0};
ALfloat listenerVel[]={0.0,0.0,0.0};
Alfloat listenerOri[]={0.0,0.0,1.0, 0.0,1.0,0.0};
/* definir las posiciones, velocidaded y orientaciones de cada emisor */
ALfloat
ALfloat
ALfloat
ALfloat
ALfloat
ALfloat
source0Pos[]={
source0Vel[]={
source1Pos[]={
source1Vel[]={
source2Pos[]={
source2Vel[]={
-2.0, 0.0, 0.0};
0.0, 0.0, 0.0};
2.0, 0.0, 0.0};
0.0, 0.0, 0.0};
0.0, 0.0, -4.0};
0.0, 0.0, 0.0};
/* reservar buffers de sonido */
ALuint buffer[NUM_BUFFERS];
ALuint source[NUM_SOURCES];
ALuint environment[NUM_ENVIRONMENTS];
int GLwin ;
ALsizei size,freq;
ALenum format;
ALvoid *data;
int ch;
*/
void init(void)
{
glClearColor(0.0,0.0,0.0,1.0) ;
ALint
error;
/* definir repeticion del sonido en loop */
ALboolean loop=1;
/* asignar posicion, velocidad y orientacion al receptor */
alListenerfv(AL_POSITION,listenerPos);
alListenerfv(AL_VELOCITY,listenerVel);
alListenerfv(AL_ORIENTATION,listenerOri);
/* pedir a openAL la generacion de los buffers */
alGenBuffers(NUM_BUFFERS,buffer);
if ((error = alGetError()) != AL_NO_ERROR)
{
printf("- Error creating buffers !!\n");
exit(1);
}
/*cargar archivos de sonido y asignarlos a los emisores */
alutLoadWAVFile("c.wav",&format,&data,&size,&freq,&loop);
alBufferData(buffer[0],format,data,size,freq);
alutUnloadWAV(format,data,size,freq);
alutLoadWAVFile("b.wav",&format,&data,&size,&freq,&loop);
alBufferData(buffer[1],format,data,size,freq);
alutUnloadWAV(format,data,size,freq);
alutLoadWAVFile("a.wav",&format,&data,&size,&freq,&loop);
alBufferData(buffer[2],format,data,size,freq);
alutUnloadWAV(format,data,size,freq);
alGenSources(NUM_SOURCES,source);
if ((error = alGetError())!=AL_NO_ERROR)
{
printf("- Error creating sources !!\n");
exit(2);
}
/* definir parametros de control del sonido para cada emisor */
alSourcef(source[0],AL_PITCH,1.0f);
alSourcef(source[0],AL_GAIN,1.0f);
alSourcefv(source[0],AL_POSITION,source0Pos);
alSourcefv(source[0],AL_VELOCITY,source0Vel);
alSourcei(source[0],AL_BUFFER,buffer[0]);
alSourcei(source[0],AL_LOOPING,AL_TRUE);
alSourcef(source[1],AL_PITCH,1.0f);
alSourcef(source[1],AL_GAIN,1.0f);
alSourcefv(source[1],AL_POSITION,source1Pos);
alSourcefv(source[1],AL_VELOCITY,source1Vel);
alSourcei(source[1],AL_BUFFER,buffer[1]);
alSourcei(source[1],AL_LOOPING,AL_TRUE);
alSourcef(source[2],AL_PITCH,1.0f);
alSourcef(source[2],AL_GAIN,1.0f);
alSourcefv(source[2],AL_POSITION,source2Pos);
alSourcefv(source[2],AL_VELOCITY,source2Vel);
alSourcei(source[2],AL_BUFFER,buffer[2]);
alSourcei(source[2],AL_LOOPING,AL_TRUE);
}
void display(void)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT) ;
glPushMatrix() ;
glRotatef(20.0,1.0,1.0,0.0) ;
glPushMatrix() ;
glTranslatef(source0Pos[0],source0Pos[1],source0Pos[2]) ;
glColor3f(1.0,0.0,0.0) ;
glutWireCube(0.5) ;
glPopMatrix() ;
glPushMatrix() ;
glTranslatef(source2Pos[0],source2Pos[1],source2Pos[2]) ;
glColor3f(0.0,0.0,1.0) ;
glutWireCube(0.5) ;
glPopMatrix() ;
glPushMatrix() ;
glTranslatef(source1Pos[0],source0Pos[1],source0Pos[2]) ;
glColor3f(0.0,1.0,0.0) ;
glutWireCube(0.5) ;
glPopMatrix() ;
//the listener
glPushMatrix() ;
glTranslatef(listenerPos[0],listenerPos[1],listenerPos[2]) ;
glColor3f(1.0,1.0,1.0) ;
glutWireCube(0.5) ;
glPopMatrix() ;
glPopMatrix() ;
glutSwapBuffers() ;
}
void reshape(int w, int h) // the reshape function
{
glViewport(0,0,(GLsizei)w,(GLsizei)h) ;
glMatrixMode(GL_PROJECTION) ;
glLoadIdentity() ;
gluPerspective(60.0,(GLfloat)w/(GLfloat)h,1.0,30.0) ;
glMatrixMode(GL_MODELVIEW) ;
glLoadIdentity() ;
glTranslatef(0.0,0.0,-6.6) ;
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case '1':
/*activar emisor (loop infinito) */
alSourcePlay(source[0]);
break;
case '2':
alSourcePlay(source[1]);
break;
case '3':
alSourcePlay(source[2]);
break;
case '4':
/*desactivar emisor (parar loop de sonido) */
case
case
case
case
/* cambiar posicion
case
case
alSourceStop(source[0]);
break;
'5':
alSourceStop(source[1]);
break;
'6':
alSourceStop(source[2]);
break;
'a':
'A':
listenerPos[0] -= 0.1 ;
del receptor */
alListenerfv(AL_POSITION,listenerPos);
break ;
's':
'S':
case
case
case
case
case
listenerPos[0] += 0.1 ;
alListenerfv(AL_POSITION,listenerPos);
break ;
'q':
'Q':
listenerPos[2] -= 0.1 ;
alListenerfv(AL_POSITION,listenerPos);
break ;
'z':
'Z':
listenerPos[2] += 0.1 ;
alListenerfv(AL_POSITION,listenerPos);
break ;
27 :
alSourceStop(source[2]);
alSourceStop(source[1]);
alSourceStop(source[0]);
alutExit();
glutDestroyWindow(GLwin) ;
exit(0) ;
default:
break ;
}
glutPostRedisplay() ;
}
int main(int argc, char** argv) //finaly the main function
{
//initialise glut
glutInit(&argc, argv) ;
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH) ;
glutInitWindowSize(400,400) ;
//inicializar openAL
alutInit(&argc, argv) ;
GLwin = glutCreateWindow("OpenAL & OpenGL | www.dev-gallery.com") ;
init() ;
glutDisplayFunc(display) ;
glutKeyboardFunc(keyboard) ;
glutReshapeFunc(reshape) ;
glutMainLoop() ;
return 0;
}
Descargar