/*********************************************************************************\ |SVE 3D Sound C File |Author: Sabarish Babu |Version: 1.1 |Date: 06/03/08 |Added: More functions to manipulate sound attributes, combined functions to make | interface cleaner, more error checking..... | | \*********************************************************************************/ #include "sve_al.h" ALvoid SVE_init3DSound(int* argc, char **argv) { alutInit(argc, argv); SVE_3DSound_State = malloc(sizeof(SVE_3DSound_State_Struct)); SVE_3DSound_State->SVE_3DListener = malloc(sizeof(SVE_3DListener_Struct)); if (SVE_3DSound_State == NULL) { printf("Error creating SVE 3D Sound State\n"); SVE_done(); } if (SVE_3DSound_State->SVE_3DListener == NULL) { printf("Error creating SVE 3D Listener\n"); SVE_done(); } SVE_3DSound_State->NUM_BUFFERS = 0; SVE_3DSound_State->NUM_SOURCES = 0; SVE_3DSound_State->sound_flag = TRUE; return; } /*set up the 3D sound buffers and initialize default values for listener and sounds*/ ALvoid SVE_set3DSoundBuffers() { ALint errorcode; ALuint j = 0; ALuint k = 0; ALsizei size,freq; ALenum format; ALvoid *data; ALboolean loop; /*listener intitialization*/ SVE_create3DListener(); alListenerfv(AL_POSITION,SVE_3DSound_State->SVE_3DListener->position); alListenerfv(AL_VELOCITY,SVE_3DSound_State->SVE_3DListener->velocity); alListenerfv(AL_ORIENTATION,SVE_3DSound_State->SVE_3DListener->orientation); alListenerf(AL_GAIN,SVE_3DSound_State->SVE_3DListener->gain); /*------------------------*/ /*make the buffers*/ alGenBuffers(SVE_3DSound_State->NUM_BUFFERS,SVE_3DSound_State->buffer); /*load the wav files into the buffers*/ for (j = 0; j < SVE_3DSound_State->NUM_BUFFERS; j++) { if (SVE_3DSound_State->SVE_3DSound_array[j] != NULL) { alutLoadWAVFile(SVE_3DSound_State->SVE_3DSound_array[j]->filename, &format,&data,&size,&freq,&loop); if (data == NULL ) printf("Error Loading %s\n",SVE_3DSound_State->SVE_3DSound_array[j]->filename); else printf("Loaded %s\n",SVE_3DSound_State->SVE_3DSound_array[j]->filename); alBufferData(SVE_3DSound_State->buffer[j],format,data,size,freq); alutUnloadWAV(format,data,size,freq); errorcode = alGetError(); } } /*assign to buffers to sources, and initialize sounds*/ alGenSources(SVE_3DSound_State->NUM_SOURCES,SVE_3DSound_State->source); for (j = 0; j < SVE_3DSound_State->NUM_SOURCES; j++) { if (SVE_3DSound_State->SVE_3DSound_array[j] != NULL) { alSourcei(SVE_3DSound_State->source[j],AL_BUFFER,SVE_3DSound_State->buffer[j]); } } /*assign position and looping attribute to each source*/ for (j = 0; j < SVE_3DSound_State->NUM_SOURCES; j++) { if (SVE_3DSound_State->SVE_3DSound_array[j] != NULL) { alSourcei(SVE_3DSound_State->source[j],AL_LOOPING,SVE_3DSound_State->SVE_3DSound_array[j]->islooping); alSourcefv(SVE_3DSound_State->source[j], AL_POSITION, SVE_3DSound_State->SVE_3DSound_array[j]->position); } } return; } /*initialize the listener structure*/ ALvoid SVE_create3DListener() { //initializes the listener position to 0,0,0 SVE_3DSound_State->SVE_3DListener->position[0] = 0.0f; //x SVE_3DSound_State->SVE_3DListener->position[1] = 0.0f; //y SVE_3DSound_State->SVE_3DListener->position[2] = 0.0f; //z //initializes the listener velocity to 0,0,0 SVE_3DSound_State->SVE_3DListener->velocity[0] = 0.0f; SVE_3DSound_State->SVE_3DListener->velocity[1] = 0.0f; SVE_3DSound_State->SVE_3DListener->velocity[2] = 0.0f; /*ORIENTATION*/ /*---------------------------------*/ /*at vector*/ SVE_3DSound_State->SVE_3DListener->orientation[0] = 0.0f; SVE_3DSound_State->SVE_3DListener->orientation[1] = 0.0f; SVE_3DSound_State->SVE_3DListener->orientation[2] = 1.0f; /*up vector*/ SVE_3DSound_State->SVE_3DListener->orientation[3] = 0.0f; SVE_3DSound_State->SVE_3DListener->orientation[4] = 1.0f; SVE_3DSound_State->SVE_3DListener->orientation[5] = 0.0f; /*----------------------------------*/ SVE_3DSound_State->SVE_3DListener->gain = 1.0f; if (SVE_3DSound_State->SVE_3DListener == NULL) printf("Error creating 3D Sound Listener Object...."); return; }/*SVE_create3DListener*/ /*set the position of the listener object*/ ALvoid SVE_set3DListenerPos(ALfloat x, ALfloat y, ALfloat z) { SVE_3DSound_State->SVE_3DListener->position[0] = x; SVE_3DSound_State->SVE_3DListener->position[1] = y; SVE_3DSound_State->SVE_3DListener->position[2] = z; alListenerfv(AL_POSITION,SVE_3DSound_State->SVE_3DListener->position); return; }/*SVE_set3DListenerPos*/ /*update the listener orientation*/ ALvoid SVE_set3DListenerOri(ALfloat atx, ALfloat aty, ALfloat atz, ALfloat topx, ALfloat topy, ALfloat topz) { SVE_3DSound_State->SVE_3DListener->orientation[0] = atx; SVE_3DSound_State->SVE_3DListener->orientation[1] = aty; SVE_3DSound_State->SVE_3DListener->orientation[2] = atz; SVE_3DSound_State->SVE_3DListener->orientation[3] = topx; SVE_3DSound_State->SVE_3DListener->orientation[4] = topy; SVE_3DSound_State->SVE_3DListener->orientation[5] = topz; alListenerfv(AL_ORIENTATION, SVE_3DSound_State->SVE_3DListener->orientation); return; }/*SVE_set3DListenerOri*/ /*updates the listener position and orientation with the user's position and orientation*/ ALvoid SVE_update3DListener(SVE_state state) { SVE_set3DListenerPos(state->originObject->position[3][0],state->originObject->position[3][1], state->originObject->position[3][2]); SVE_set3DListenerOri( -(state->currentView->viewingMatrix[0][2]), (state->currentView->viewingMatrix[1][2]), -(state->currentView->viewingMatrix[2][2]), 0.0f,1.0f, 0.0f); return; } /*SVE_update3DListener*/ /*initialize a sound structure with default values for a sound file*/ SVE_3DSound SVE_create3DSound(char* filename, ALboolean looping) { SVE_3DSound sound; static int i; if (SVE_3DSound_State->sound_flag == TRUE) { i = 0; SVE_3DSound_State->sound_flag = FALSE; SVE_3DSound_State->NUM_SOURCES = 0; SVE_3DSound_State->NUM_BUFFERS = 0; } sound = malloc(sizeof(SVE_3DSound_Struct)); sound->filename = filename; sound->islooping = looping; sound->source_num = SVE_3DSound_State->NUM_SOURCES; sound->buffer_num = SVE_3DSound_State->NUM_BUFFERS; SVE_3DSound_State->SVE_3DSound_array[i] = sound; SVE_3DSound_State->NUM_SOURCES++; SVE_3DSound_State->NUM_BUFFERS++; if (sound == NULL || SVE_3DSound_State->SVE_3DSound_array[i] == NULL) printf("Error creating 3D sound object %d", i); i++; return sound; }/*SVE_create3DSound*/ /*bind the sound to an object*/ ALvoid SVE_bind3DSoundToObject( SVE_object object, SVE_3DSound sound) { int i; for (i = 0; i < 3; i++) sound->position[i] = object->position[3][i]; sound->boundobject = object; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; return; }/*SVE_bind3DSoundToObject*/ /*set the position of a sound*/ ALvoid SVE_set3DSoundPos(ALfloat x, ALfloat y, ALfloat z, SVE_3DSound sound) { sound->position[0] = x; sound->position[1] = y; sound->position[2] = z; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcefv(SVE_3DSound_State->source[sound->source_num], AL_POSITION, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->position); return; }/*SVE_set3DSoundPos*/ /*set the gain for a specific sound*/ ALvoid SVE_set3DSoundGain(ALfloat x, SVE_3DSound sound) { sound->gain = x; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcef(SVE_3DSound_State->source[sound->source_num], AL_GAIN, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->gain); return; }/*SVE_set3DSoundGain*/ /*set the pitch for a specific sound*/ ALvoid SVE_set3DSoundPitch(ALfloat x, SVE_3DSound sound) { sound->pitch = x; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcef(SVE_3DSound_State->source[sound->source_num], AL_PITCH, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->pitch); return; }/*SVE_set3DSoundPitch*/ /*set the velocity for a specific sound*/ ALvoid SVE_set3DSoundVelocity(ALfloat x, ALfloat y, ALfloat z, SVE_3DSound sound) { float array[3]; array[0] = x; array[1] = y; array[2] = z; sound->velocity[0] = array[0]; sound->velocity[1] = array[1]; sound->velocity[2] = array[2]; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcefv(SVE_3DSound_State->source[sound->source_num], AL_VELOCITY, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->velocity); return; }/*SVE_set3DSoundVelocity*/ /*set the inner angle, outer angle, and outer angle gain for a specific sound*/ ALvoid SVE_set3DSoundAngles(ALfloat innerangle, ALfloat outerangle, ALfloat outergain, SVE_3DSound sound) { sound->cone_inner_angle = innerangle; sound->cone_outer_angle = outerangle; sound->cone_outer_gain = outergain; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcef(SVE_3DSound_State->source[sound->source_num], AL_CONE_OUTER_ANGLE, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->cone_outer_angle); alSourcef(SVE_3DSound_State->source[sound->source_num], AL_CONE_INNER_ANGLE, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->cone_inner_angle); alSourcef(SVE_3DSound_State->source[sound->source_num], AL_CONE_OUTER_GAIN, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->cone_outer_gain); return; }/*SVE_set3DSoundAngle*/ ALvoid SVE_set3DSoundDistances(ALfloat ref_distance, ALfloat max_distance, SVE_3DSound sound) { sound->ref_distance = ref_distance; sound->max_distance = max_distance; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcef(SVE_3DSound_State->source[sound->source_num], AL_MAX_DISTANCE, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->max_distance); alSourcef(SVE_3DSound_State->source[sound->source_num], AL_REFERENCE_DISTANCE, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->ref_distance); return; }/*SVE_set3dSoundDistances*/ ALvoid SVE_set3DSoundDistancesSab(ALfloat ref_distance, ALfloat max_distance, ALfloat rolloff_val, SVE_3DSound sound) { sound->ref_distance = ref_distance; sound->max_distance = max_distance; sound->rolloff = rolloff_val; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; //alSourcef(SVE_3DSound_State->source[sound->source_num], AL_MAX_DISTANCE, // SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->max_distance); //alSourcef(SVE_3DSound_State->source[sound->source_num], AL_REFERENCE_DISTANCE, // SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->ref_distance); alSourcef(SVE_3DSound_State->source[sound->source_num], AL_ROLLOFF_FACTOR, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->rolloff); return; }/*SVE_set3dSoundDistances*/ /*Set the relative source attribute for a specific sound*/ ALvoid SVE_makeRelativeSource(ALboolean ifrelative, SVE_3DSound sound) { sound->rel_source = ifrelative; SVE_3DSound_State->SVE_3DSound_array[sound->source_num] = sound; alSourcei(SVE_3DSound_State->source[sound->source_num], AL_SOURCE_RELATIVE, SVE_3DSound_State->SVE_3DSound_array[sound->source_num]->rel_source); }/*SVE_setRelativeSource*/ ALvoid SVE_close3DSound() { ALuint i; for (i = 0; i < SVE_3DSound_State->NUM_SOURCES; i++) free(SVE_3DSound_State->SVE_3DSound_array[i]); free(SVE_3DSound_State); alutExit(); } ALvoid SVE_3DSoundPlay(SVE_3DSound sound) { alSourcePlay(SVE_3DSound_State->source[sound->source_num]); } ALvoid SVE_3DSoundStop(SVE_3DSound sound) { alSourceStop(SVE_3DSound_State->source[sound->source_num]); } ALvoid SVE_3DPause(SVE_3DSound sound) { alSourcePause(SVE_3DSound_State->source[sound->source_num]); } BOOL SVE_check3DSoundPlaying(SVE_3DSound sound) { ALint isplaying; alGetSourcei(SVE_3DSound_State->source[sound->source_num], AL_SOURCE_STATE, &isplaying); if (isplaying == AL_PLAYING) return TRUE; else return FALSE; } /*Display any AL oriented error messages*/ void SVE_display3DSoundError() { int errorcode; errorcode = alGetError(); switch (errorcode) { case AL_INVALID_NAME: printf("SVE 3D Sound Error: Invalid name\n"); break; case AL_INVALID_ENUM: printf("SVE 3D Sound Error: Invalid enumeration value\n"); break; case AL_INVALID_VALUE: printf("SVE 3D Sound Error: Invalid filename or value\n"); break; case AL_INVALID_OPERATION: printf("SVE 3D Sound Error: Invalid operation or command\n"); break; case AL_OUT_OF_MEMORY: printf("SVE 3D Sound Error: Out of Memory\n"); break; } return; }/*DisplayALError*/