¡Bienvenido a Stratos!
#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <al.h>#include <alc.h>#include <alut.h>class cSound{private: char* rutaSonido; ALuint Buffer; // Buffers to hold sound data. ALuint Source; // Sources are points of emitting sound. ALfloat SourcePos[3]; // Position of the source sound. ALfloat SourceVel[3]; // Velocity of the source sound. ALfloat ListenerPos[3]; // Position of the Listener. ALfloat ListenerVel[3]; // Velocity of the Listener. ALfloat ListenerOri[6]; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. // Variables to load into. ALenum format; ALsizei size; ALvoid* data; ALsizei freq; ALboolean loop;public: cSound(char* ruta); ALboolean LoadALData(bool loadSources); void SetListenerValues(); void KillALData(); void LoadDefaultValues(void); void reloadData(); void play(); void stop(); void pause();};
#include "sound.h"cSound::cSound(char* ruta){ this->rutaSonido = ruta; LoadDefaultValues(); // Initialize OpenAL and clear the error bit. alutInit(NULL, 0); alGetError(); // Load the wav data. if (LoadALData(true) == AL_FALSE) printf("Error loading data."); SetListenerValues();}void cSound::play(){ alSourcePlay(Source);}void cSound::stop(){ alSourceStop(Source);}void cSound::pause(){ alSourcePause(Source);}/* * ALboolean LoadALData() * * This function will load our sample data from the disk using the Alut * utility and send the data into OpenAL as a buffer. A source is then * also created to play that buffer. */ALboolean cSound::LoadALData(bool loadSources){ // Load wav data into a buffer. alGenBuffers(1, &Buffer); if (alGetError() != AL_NO_ERROR) return AL_FALSE; alutLoadWAVFile(rutaSonido, &format, &data, &size, &freq, &loop); alBufferData(Buffer, format, data, size, freq); alutUnloadWAV(format, data, size, freq); // Bind the buffer with the source. alGenSources(1, &Source); if (alGetError() != AL_NO_ERROR) return AL_FALSE; alSourcei (Source, AL_BUFFER, Buffer ); alSourcef (Source, AL_PITCH, 1.0 ); alSourcef (Source, AL_GAIN, 1.0 ); alSourcefv(Source, AL_POSITION, SourcePos); alSourcefv(Source, AL_VELOCITY, SourceVel); alSourcei (Source, AL_LOOPING, loop ); // Do another error check and return. if (alGetError() == AL_NO_ERROR) return AL_TRUE; return AL_FALSE;}void cSound::reloadData(){ KillALData();}/* * void SetListenerValues() * * We already defined certain values for the Listener, but we need * to tell OpenAL to use that data. This function does just that. */void cSound::SetListenerValues(){ alListenerfv(AL_POSITION, ListenerPos); alListenerfv(AL_VELOCITY, ListenerVel); alListenerfv(AL_ORIENTATION, ListenerOri);}/* * void KillALData() * * We have allocated memory for our buffers and sources which needs * to be returned to the system. This function frees that memory. */void cSound::KillALData(){ alDeleteBuffers(1, &Buffer); alDeleteSources(1, &Source); free(&Buffer); alutExit();}void cSound::LoadDefaultValues(void){ SourcePos[0] = 0.0; // Position of the source sound. SourcePos[1] = 0.0; // Position of the source sound. SourcePos[2] = 0.0; // Position of the source sound. SourceVel[0] = 0.0; // Velocity of the source sound. SourceVel[1] = 0.0; // Velocity of the source sound. SourceVel[2] = 0.0; // Velocity of the source sound. ListenerPos[0] = 0.0; // Position of the Listener. ListenerPos[1] = 0.0; // Position of the Listener. ListenerPos[2] = 0.0; // Position of the Listener. ListenerVel[0] = 0.0; // Velocity of the Listener. ListenerVel[1] = 0.0; // Velocity of the Listener. ListenerVel[2] = 0.0; // Velocity of the Listener. ListenerOri[0] = 0.0; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. ListenerOri[1] = 0.0; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. ListenerOri[2] = -1.0; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. ListenerOri[3] = 0.0; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. ListenerOri[4] = 1.0; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'. ListenerOri[5] = 0.0 ; // Orientation of the Listener. (first 3 elements are "at", second 3 are "up") // Also note that these should be units of '1'.}
sonido[MAX_SONIDOS-1]->KillALData();sonido[MAX_SONIDOS-1]->LoadALData(false);sonido[MAX_SONIDOS-1]->play();code]
Audiere está tirado de usar pero tiene mil bugs (entre ellos que peta con multiprocesador), así que nos vamos a pasar a OpenAL. El problema es que tiene en nuestros juegos hay cerca de 300 sonidos y OpenAL permite reproducir muchos menos al mismo tiempo por temas de hardware.
He pensado en destruir y crear los sonidos según los necesite pero no encuentro una manera de hacerlo que no incremente la memoria cada vez.
Por cierto Prompt, ¿seguro que en ALSA/OSS hay aceleración por hardware? Yo estaba convencido de que fuera de Windows+DS3D o XFi/Audigy todo iba por software. Y en el Generic software device se pueden crear hasta 256 sources, o al menos así era con la última versión que probé. De todas maneras, yo creo que tantos sonidos simultáneos son del todo innecesarios, con 16-32 a la vez ya tienes suficiente. Más es ansia.