Utils::Ticket<AudioWorld> AudioWorld::playSound(Handle::SfxHandle h, const Math::float3& position, bool relative, float maxDist) { #ifdef RE_USE_SOUND if (!m_Context) return Utils::Ticket<AudioWorld>(); alcMakeContextCurrent(m_Context); Sound& snd = m_Allocator.getElement(h); // Get a cached source object Source s = getFreeSource(); //LogInfo() << "play sound " << snd.sfx.file << " vol " << snd.sfx.vol; alSourcef(s.m_Handle, AL_PITCH, m_Engine.getGameClock().getGameEngineSpeedFactor()); alSourcef(s.m_Handle, AL_GAIN, snd.sfx.vol / 127.0f); alSource3f(s.m_Handle, AL_POSITION, position.x, position.y, position.z); alSource3f(s.m_Handle, AL_VELOCITY, 0, 0, 0); alSourcef(s.m_Handle, AL_MAX_DISTANCE, maxDist); // Relative for sources directly attached to the listener alSourcei(s.m_Handle, AL_SOURCE_RELATIVE, relative ? AL_TRUE : AL_FALSE); // TODO: proper looping would require slicing and queueing multiple buffers // and setting the source to loop when the non-looping buffer was played. // start and end don't seem to be used, thoug? alSourcei(s.m_Handle, AL_LOOPING, snd.sfx.loop ? AL_TRUE : AL_FALSE); alSourcei(s.m_Handle, AL_BUFFER, snd.m_Handle); ALenum error = alGetError(); if (error != AL_NO_ERROR) { static bool warned = false; if (!warned) { LogWarn() << "Could not attach buffer to source: " << AudioEngine::getErrorString(error); warned = true; } return Utils::Ticket<AudioWorld>(); } alSourcePlay(s.m_Handle); error = alGetError(); if (error != AL_NO_ERROR) { static bool warned = false; if (!warned) { LogWarn() << "Could not start source!" << AudioEngine::getErrorString(error); warned = true; } return Utils::Ticket<AudioWorld>(); } return s.soundTicket; #else return Utils::Ticket<AudioWorld>(); #endif }
void AudioDevice::play(const SoundBuffer& sound, double volume, double pitch) { RecursiveLock lock(mutex); if (auto source = getFreeSource()) { ALint state = 0; AL(alGetSourcei(*source, AL_SOURCE_STATE, &state)); CHECK(state == AL_INITIAL) << state; AL(alSourcei(*source, AL_BUFFER, sound.getBufferId())); AL(alSourcef(*source, AL_PITCH, pitch)); AL(alSourcef(*source, AL_GAIN, volume)); AL(alSourcePlay(*source)); } }