OpenAL

De Wikipedia, la enciclopedia libre
Saltar a: navegación, búsqueda
OpenAL
Desarrollador
Loki Software
http://www.openal.org/
Información general
Última versión estable 2.1.0.0
Febrero de 2010
Género Interfaz de programación de aplicaciones
Sistema operativo Multiplataforma
Licencia LGPL hasta la versión v1.1, las posteriores propietarias
[editar datos en Wikidata ]

Open Audio Library es una API de audio multiplataforma desarrollada por Creative Labs para el renderizado eficiente de audio posicional y multicanal en tres dimensiones. Está ideada para su uso en videojuegos y el estilo y Microsoft Xbox y formato PCM, bien en 8 o 16 bits, en formato mono o estéreo. El motor de renderizado se encarga de todos los cálculos necesarios como la atenuación, doppler, etc.

Inicialización y cerrado de la librería[editar]

La librería puede (y debe) ser inicializada en el código para ser usada. Para ello, se deben escribir las líneas:

  // Inicializar dispositivos de audio.
  ALCdevice *device;
  ALCcontext *context;
 
  // Abrir e iniciar un dispositivo con las opciones por defecto.
  device = alcOpenDevice(NULL);
  if(!device)
  {
    // Gestionar error (salir...)
  }
 
  // Generar un contexto OpenAL.
  context = alcCreateContext(device, NULL);
  if(context == NULL || alcMakeContextCurrent(context) == ALC_FALSE)
  {
    // Limpiar dispositivo
    if(context != NULL)
      alcDestroyContext(context);
    alcCloseDevice(device);
 
    // Y gestionar error (salir...)
    // ...
  }
 
  // Selccionar un modelo de ganancia sobre la distancia de escucha (lineal acotado, en este caso).
  alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
 
  // ...

Y, en contraparte, se deben cerrar la libería una vez se ha terminado de usar:

  ALCdevice *device;  // Dispositivo.
  ALCcontext *context;    // Contexto.
 
  context = alcGetCurrentContext();
  if(context == NULL)
      return;
 
  device = alcGetContextsDevice(context);
 
  alcMakeContextCurrent(NULL); // Desactivar el contexto actual.
  alcDestroyContext(context);      // Destruir el contexto usado.
  alcCloseDevice(device);      // Cerrar el dispositivo de audio.

Conceptos principales[editar]

Para entender el correcto funcionamiento de la librería, se deben definir una serie de conceptos de gran importancia:

Buffer de sonido[editar]

Un buffer de sonido es un espacio en memoria (generalmente, en la memoria principal del ordenador, o en la memoria de la tarjeta de sonido usado para almacenar los bytes que representan un sonido almacenado en la computadora. Generalmente, se trata de una codificación de un sonido determinado, usando una codificación digital.

Por ejemplo, se puede definir un buffer en OpenAL de la siguiente manera:

  // Cargar sonido codificado en el buffer de bytes (char*) "ound" con alguna librería (SDL_mixer, por ejemplo).
  Mix_Chunk *sound = Mix_LoadWAV("sonido.wav"); // SDL2_mixer
  if(!sound) {
    // Gestionar el error (salir ...)
  }
 
  ALuint buffer_id = 0; // Identificador de un buffer a cargar en OpenAL.
 
  alGenBuffer(1, &buffer_id); // Generar un buffer y almacenar su identificador en "buffer_id" (entero").
  ALenum error = alGetError(); // Comprobación de errores.
  if(error == AL_ERROR) {
    // Gestionar el error (salir ...)
  }
 
  // Cargar el sonido almacenado en "sound" (usando bytes y tamaño), 
  // con formato MONO de 16 bits, con una frecuencia de 44100 kHz.
  alBufferData(buffer_id, AL_FORMAT_MONO16, sound->abuf, sound->alen, 44100);
 
  // Liberar la estructura de datos, pues ya se ha cargado en OpenAL
  Mix_FreeChunk(sound); // SDL2_mixer

Sources[editar]

Un source u origen (traducido literalmente) es lo que se conoce como un emisor de sonido. Se caracteriza por encapsular a un sonido (reproducirlo), tener una posición 3D en el mundo, una velocidad, un volumen, una frecuencia, etc. Es una de las estructuras más importantes de OpenAL, puesto que permite la recepción de sonidos con efectos de sonido, como el efecto Doppler.

Como detalle importante, un emisor 3D sólo podrá emitir de manera correcta sonidos del tipo [MONO], con un único canal de reproducción.

Por ejemplo, para el caso anterior, se puede generar un código para definir un emisor:

  // Generar un recurso a partir del buffer generado anteriormente
  ALuint source_id = 0;
  alGenSource(1, &source_id); // Generar un emisor
 
  // Asociar el buffer al emisor
  alSourcei(source_id, AL_BUFFER, buffer_id);
 
  float velocity[]    = {2.f, 3.f, 0.f},     // Velocidad X = 2.0, Y = 3.0, Z = 0.0
        position[]    = {0.5f, -10.f, 3.f},  // Posición X = 0.5, Y = -10.0, Z = 3.0
        direction[]   = {1.0, 1.0, 0.0};     // Dirección X = 1.0, Y = 1.0, Z = 0.0 (hacia el frente, 45º hacia arriba)
 
  alSourcefv(source_id, AL_POSITION, position);   // Cambiar posición del emisor.
  alSourcefv(source_id, AL_VELOCITY, velocity);   // Cambiar velocidad del emisor.
  alSourcefv(source_id, AL_DIRECTION, direction); // Cambiar dirección de emisión.
 
  alSourcei(source_id, AL_LOOPING, true); //  Activar "loop" o bucle de reproducción.
 
  alSourcef(source_id, AL_PITCH, 1.0); // Cambiar la altura a 1.0 // Por defecto.
  alSourcef(source_id, AL_GAIN, 0.5); // Reducir la amplitud, ganancia o volumen a la mitad.
 
  alSourcef(source_id, AL_MAX_DISTANCE, 200);        // Cambiar la distancia máxima de escucha a 200 unidades.
  alSourcef(source_id, AL_REFERENCE_DISTANCE, 100);  // Cambiar distancia mínima de escucha máxima a 100 unidades.
 
  alSourcei(source_id, AL_LOOPING, loop);
 
  // ...

Los atributos de un sonido pueden cambiarse en cualquier momento mientras se está reproduciendo, y el sonido se verá afectado por dichos cambios.

Para operar con la reproducción de sonidos, basta con llamar a alguna de las funciones siguientes:

alSourceRewind(source_id); // Rebobinar.
alSourcePlay(source_id);   // Reproducir o reanudar.
alSourcePause(source_id);  // Pausar la reproducción.
alSourceStop(source_id);   // Parar la reproducción.

Todo emisor generado, cuando deje de usarse, deberá ser liberado con la función alDeleteSources(num_emisores, puntero a vector de ids)

Listener[editar]

En todo sistema de comunicación debe haber un emisor (source), un canal (simulación de aire, en este caso) y, por supuesto, un receptor. En el caso de OpenAL, el receptor u oyente es denominado listener.

Al igual que un emisor, un receptor tiene una serie de características principales, sea una posición, una dirección, una velocidad y una ganancia. Por desgracia, OpenAL sólo acepta un receptor o listener por contexto OpenAL. En caso de querer reproducir un sonido desde diversos oyentes, será necesario crear un contexto por cada oyente, y cambiarlo de manera dinámica.

Por ejemplo, un oyente se define de la siguiente manera:

  float velocity[]       = {2.f, 3.f, 0.f},     // Velocidad X = 2.0, Y = 3.0, Z = 0.0
        position[]       = {0.5f, -10.f, 3.f},  // Posición X = 0.5, Y = -10.0, Z = 3.0
        direction[][3]   = { 
                             {1.f, 0.f, 0.f}, // Vector "forward".
                             {0.f, 1.f, 0.f}  // Vector "up".
                           };     // Mirando al frente, y el receptor está orientado correctamente (vector up hacia arriba, (0,1,0) )
 
alListenerfv(AL_POSITION, position);      // Cambiar posición.
alListenerfv(AL_VELOCITY, velocity);      // Cambiar velocidad.
alListenerfv(AL_ORIENTATION, *direction);  // Cambiar orientación.
// La ganancia se especifica con AL_GAIN, al igual que en los emisores.

Al igual que con los emisores o sources, los cambios realizados sobre los distintos parámetros de un oyente se verán reflejados en cuanto a la escucha del sonido, en tiempo real.

Queues o colas para streaming[editar]

OpenAL permite la creación de Queues o colas para introducir sonidos y reproducirlos de manera continuada, como si de un streaming se tratase.

Funcionamiento de colas OpenAL

Puede ser de gran utilidad cuando el sonido a reproducir es demasiado grande (supongamos, 2 horas de grabación en HD), por lo que no será posible guardar el fichero completo en un buffer, y reproducirlo tal cual. Por ello, es necesario particionar el sonido original, e ir reproduciendo cada fragmento, y liberar aquellos ya reproducidos.

Además, cabe recalcar que se trata de una cola de buffers, y no de sources o emisores. Cada fragmento extraído del sonido original se irá reproduciendo de manera ordenada según su posición en la cola, y bajo las características establecidas (posición, ganancia...) para el emisor al que se le ha asignado la cola.

También se puede utilizar la librería y estas colas para captar sonido con un dispositivo de entrada (micrófono...) y reproducirlo de manera continuada, siendo cada fragmento una pequeña cantidad de audio grabado.

Juegos que utilizan OpenAL[editar]

Enlaces[editar]