diff -r f589230fa21b -r 59dbd31e9953 misc/libopenalbridge/commands.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/misc/libopenalbridge/commands.c Thu Jun 17 20:30:39 2010 +0200 @@ -0,0 +1,224 @@ +/* + * commands.c + * Hedgewars + * + * Created by Vittorio on 13/06/10. + * Copyright 2010 __MyCompanyName__. All rights reserved. + * + */ + +#include "commands.h" +#include "wrappers.h" + +ALfloat old_gain; +extern ALuint *Sources; +extern ALuint cache_size, cache_index, sources_number; +extern ALboolean instances_number; +extern al_sound_t *the_sounds; + +void openal_pausesound (uint32_t index) { + if (openal_ready() == AL_TRUE && index < cache_size) + alSourcePause(Sources[the_sounds[index].source_index]); +} + + +void openal_stopsound (uint32_t index) { + if (openal_ready() == AL_TRUE && index < cache_size) + alSourceStop(Sources[the_sounds[index].source_index]); +} + + +void openal_playsound (unsigned int index) { + ALboolean needsSource = AL_TRUE; + ALfloat SourcePosition[] = { 0.0, 0.0, 0.0 }; + ALfloat SourceVelocity[] = { 0.0, 0.0, 0.0 }; + ALint state; + int i, j; + + if (openal_ready() == AL_TRUE && index < cache_size) { + // check if sound has already a source + if (the_sounds[index].source_index != -1) { + // it has a source, check it's not playing + alGetSourcei(Sources[the_sounds[index].source_index], AL_SOURCE_STATE, &state); + if (state != AL_PLAYING && state != AL_PAUSED) { + // it is not being played, so we can use it safely + needsSource = AL_FALSE; + } + // else it is being played, so we have to allocate a new source for this buffer + } + + if (needsSource) { +#ifdef DEBUG + fprintf(stderr,"(Bridge Debug) - looking for a source for sound %d\n", index); +#endif + for (i = 0; i < sources_number; i++) { + // let's iterate on Sources until we find a source that is not playing + alGetSourcei(Sources[i], AL_SOURCE_STATE, &state); + if (state != AL_PLAYING && state != AL_PAUSED) { + // let's iterate on the_sounds until we find the sound using that source + for (j = 0; j < cache_size; j++) { + if (the_sounds[j].source_index == i) { + the_sounds[j].source_index = -1; + break; + } + } + // here we know that no-one is using that source so we can use it + break; + } + } + + if (i == sources_number) { + // this means all sources are busy + } + + // set source properties that it will use when it's in playback + alSourcei (Sources[i], AL_BUFFER, the_sounds[index].buffer); + alSourcef (Sources[i], AL_PITCH, 1.0f); + alSourcef (Sources[i], AL_GAIN, 1.0f); + alSourcefv(Sources[i], AL_POSITION, SourcePosition); + alSourcefv(Sources[i], AL_VELOCITY, SourceVelocity); + alSourcei (Sources[i], AL_LOOPING, 0); + + if (AL_NO_ERROR != alGetError()) { + fprintf(stderr,"(Bridge ERROR) - failed to set Source properties\n"); + return; + } + the_sounds[index].source_index = i; + } + + alSourcePlay(Sources[the_sounds[index].source_index]); + + if (AL_NO_ERROR != alGetError()) { + fprintf(stderr,"(Bridge Warning) - failed to play sound %d\n", index); + return; + } + + the_sounds[index].stats++; + } +} + +void openal_toggleloop (uint32_t index) { + ALint loop; + + if (openal_ready() == AL_TRUE && index < cache_size) { + alGetSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, &loop); + alSourcei (Sources[the_sounds[index].source_index], AL_LOOPING, !((uint8_t) loop) & 0x00000001); + } +} + + +void openal_setvolume (uint32_t index, float gain) { + if (openal_ready() == AL_TRUE && index < cache_size) + alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, gain); +} + + +void openal_setglobalvolume (float gain) { + if (openal_ready() == AL_TRUE) + alListenerf (AL_GAIN, gain); +} + +void openal_togglemute () { + ALfloat gain; + + if (openal_ready() == AL_TRUE) { + alGetListenerf (AL_GAIN, &gain); + if (gain > 0) { + old_gain = gain; + gain = 0; + } else + gain = old_gain; + + alListenerf (AL_GAIN, gain); + } +} + +// Fade in or out by calling a helper thread +void openal_fade (uint32_t index, uint16_t quantity, al_fade_t direction) { +#ifndef _WIN32 + pthread_t thread; +#else + HANDLE Thread; +#endif + fade_t *fade; + + if (openal_ready() == AL_TRUE && index < cache_size) { + fade = (fade_t*) Malloc(sizeof(fade_t)); + fade->index = index; + fade->quantity = quantity; + fade->type = direction; + +#ifndef _WIN32 + pthread_create(&thread, NULL, (void *)helper_fade, (void *)fade); + pthread_detach(thread); +#else + Thread = (HANDLE) _beginthread((void *)helper_fade, 0, (void *)fade); +#endif + } +} + +void openal_setposition (uint32_t index, float x, float y, float z) { + if (openal_ready() == AL_TRUE && index < cache_size) + alSource3f(Sources[the_sounds[index].source_index], AL_POSITION, x, y, z);; +} + +void helper_fade(void *tmp) { + ALfloat gain; + ALfloat target_gain; + fade_t *fade; + uint32_t index; + uint16_t quantity; + al_fade_t type; + + fade = tmp; + index = fade->index; + quantity = fade->quantity; + type = fade->type; + free (fade); + + if (type == AL_FADE_IN) { +#ifdef DEBUG + fprintf(stderr,"(Bridge Info) - Fade-in in progress [index %d quantity %d]", index, quantity); +#endif + + // save the volume desired after the fade + alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain); + if (target_gain > 1.0f || target_gain <= 0.0f) + target_gain = 1.0f; + + for (gain = 0.0f ; gain <= target_gain; gain += (float) quantity/10000) { +#ifdef TRACE + fprintf(stderr,"(Bridge Debug) - Fade-in set gain to %f\n", gain); +#endif + alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain); + usleep(10000); + } + } else { + alGetSourcef(Sources[the_sounds[index].source_index], AL_GAIN, &target_gain); + + for (gain = target_gain; gain >= 0.00f; gain -= (float) quantity/10000) { +#ifdef TRACE + fprintf(stderr,"(Bridge Debug) - Fade-out set gain to %f\n", gain); +#endif + alSourcef(Sources[the_sounds[index].source_index], AL_GAIN, gain); + usleep(10000); + } + + if (AL_NO_ERROR != alGetError()) + fprintf(stderr,"(Bridge Warning) - Failed to set fade-out effect\n"); + + // stop that sound and reset its volume + alSourceStop (Sources[the_sounds[index].source_index]); + alSourcef (Sources[the_sounds[index].source_index], AL_GAIN, target_gain); + } + + if (AL_NO_ERROR != alGetError()) + fprintf(stderr,"(Bridge Warning) - Failed to set fade effect\n"); + +#ifndef _WIN32 + pthread_exit(NULL); +#else + _endthread(); +#endif +} +