/* audio/audio.cc This file is part of the Osirion project and is distributed under the terms of the GNU General Public License version 2 */ #include "audio/audio.h" #include "audio/buffers.h" #include "audio/pcm.h" #include "audio/sources.h" #include "sys/sys.h" namespace audio { ALCdevice *audio_device = 0; ALCcontext *audio_context = 0; bool audio_initialized = false; bool initialized() { return audio_initialized; } void init() { con_print << "^BInitializing audio..." << std::endl; audio_initialized = false; // open the default audio device audio_device = alcOpenDevice(0); if (!audio_device) { con_warn << "Could not initialize audio!" << std::endl; return; } // create the audio context audio_context = alcCreateContext(audio_device , 0); if (!audio_context) { alcCloseDevice(audio_device); audio_device = 0; con_warn << "Could not create audio context!" << std::endl; return; } alcMakeContextCurrent(audio_context); con_debug << " device ^B" << alcGetString(audio_device, ALC_DEFAULT_DEVICE_SPECIFIER) << std::endl; // clear errors alGetError(); Buffers::init(); Sources::init(); audio_initialized = true; // the "no sound" sound load("ui/nosnd"); // console sound load("ui/console"); } void reset() { if (audio_initialized) { con_print << "^BResetting audio..." << std::endl; Sources::shutdown(); Buffers::shutdown(); } if (!audio_initialized) { init(); } else { Buffers::init(); Sources::init(); load("ui/nosnd"); load("ui/console"); } } void load(const char *name) { if (!audio_initialized) return; Buffers::load(std::string(name)); } void shutdown() { con_print << "^BShutting down audio..." << std::endl; if (audio_initialized) { Sources::shutdown(); Buffers::shutdown(); } if (audio_context) { alcMakeContextCurrent(0); alcDestroyContext(audio_context); audio_context = 0; } if (audio_device) { alcCloseDevice(audio_device); audio_device = 0; } audio_initialized = false; } size_t play(const char *name) { if (!audio_initialized) return 0; size_t buffer_index = Buffers::load(std::string(name)); for (size_t i = 0; i < MAXUISOURCES; i++) { ALint srcstate = 0; ALuint source = Sources::source(i); alGetSourcei(source , AL_SOURCE_STATE , &srcstate); if (srcstate != AL_PLAYING) { Buffers::bind(source, buffer_index); alSourcef(source, AL_PITCH, 1.0); alSourcef(source, AL_GAIN, 1.0); alSourcei(source, AL_SOURCE_RELATIVE, AL_TRUE); ALfloat location[] = {0.0f, 0.0f, 0.0f}; alSourcefv(source, AL_POSITION, location); alSourceRewind(source); alSourcePlay(source); return buffer_index; } } return 0; } size_t play(size_t source_index, size_t buffer_index, float pitch, float gain) { if (!audio_initialized || !buffer_index) return 0; ALuint source = Sources::source(source_index); ALint srcstate = 0; alGetSourcei(source , AL_SOURCE_STATE , &srcstate); if (srcstate == AL_PLAYING) { alSourceStop(source); } Buffers::bind(source, buffer_index); alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE); alSourcef(source, AL_PITCH, pitch); alSourcef(source, AL_GAIN, gain); alSourcei(source, AL_LOOPING, AL_FALSE); alSourceRewind(source); alSourcePlay(source); return buffer_index; } size_t loop(size_t source_index, size_t buffer_index, float pitch, float gain) { if (!audio_initialized || !buffer_index) return 0; ALuint source = Sources::source(source_index); ALint srcstate = 0; alGetSourcei(source , AL_SOURCE_STATE , &srcstate); if (srcstate == AL_PLAYING) { alSourceStop(source); } Buffers::bind(source, buffer_index); //alSourcef(source, AL_REFERENCE_DISTANCE, 2.0f); // might be the cause of cracks in the sound alSourcei(source, AL_SOURCE_RELATIVE, AL_FALSE); alSourcef(source, AL_PITCH, pitch); alSourcef(source, AL_GAIN, gain); alSourcei(source, AL_LOOPING, AL_TRUE); alSourceRewind(source); alSourcePlay(source); return buffer_index; } size_t stop(size_t source_index) { if (!audio_initialized) return 0; ALuint source = Sources::source(source_index); ALint srcstate = 0; alGetSourcei(source , AL_SOURCE_STATE , &srcstate); if (srcstate == AL_PLAYING) { alSourceStop(source); } return source_index; } size_t loop(size_t source_index, const char *name, float pitch, float gain) { if (!audio_initialized) return 0; size_t buffer_index = Buffers::load(std::string(name)); if (buffer_index) loop(source_index, buffer_index, pitch, gain); return buffer_index; } void update_listener(math::Vector3f const &location, math::Axis const &axis, math::Vector3f const & velocity, float gain) { if (!audio_initialized) return; alListenerfv(AL_POSITION, location.ptr()); ALfloat orientation[6]; for (size_t i = 0; i < 3; i++) { orientation[i] = axis.forward()[i]; orientation[i+3] = axis.up()[i]; } alListenerfv(AL_ORIENTATION, orientation); alListenerf(AL_GAIN, gain); alListenerfv(AL_VELOCITY, velocity.ptr()); } void update_source(size_t source_index, math::Vector3f const & location, math::Vector3f const & velocity, float pitch, float gain) { if (!audio_initialized) return; ALuint source = Sources::source(source_index); alSourcefv(source, AL_POSITION, location.ptr()); alSourcefv(source, AL_VELOCITY, velocity.ptr()); alSourcef(source, AL_PITCH, pitch); alSourcef(source, AL_GAIN, gain); } bool is_playing(const size_t source_index) { if (!audio_initialized) return false; ALuint source = Sources::source(source_index); ALint srcstate = 0; alGetSourcei(source , AL_SOURCE_STATE , &srcstate); return (srcstate == AL_PLAYING); } }