/* 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; void init() { con_print << "^BInitializing audio..." << std::endl; // 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); // clear errors alGetError(); Buffers::init(); Sources::init(); //con_debug << " audio device ^B" << alcGetString(audio_device, ALC_DEFAULT_DEVICE_SPECIFIER) << std::endl; // the "no sound" sound load("ui/nosnd"); // console sound load("ui/console"); } void reset() { con_print << "^BInitializing audio..." << std::endl; Sources::shutdown(); Buffers::shutdown(); Buffers::init(); Sources::init(); load("ui/nosnd"); load("ui/console"); } void load (const char *name) { Buffers::load(std::string(name)); } void shutdown() { con_print << "^BShutting down audio..." << std::endl; Sources::shutdown(); Buffers::shutdown(); if (audio_context) { alcMakeContextCurrent(0); alcDestroyContext(audio_context); audio_context = 0; } if (audio_device) { alcCloseDevice(audio_device); audio_device = 0; } } size_t play(const char *name) { if (!audio_context) 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_context || !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_context || !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 loop(size_t source_index, const char *name, float pitch, float gain) { if (!audio_context) 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) { if (!audio_context) 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); //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_context) 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); } }