Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'intern/audaspace/OpenAL/AUD_OpenALDevice.cpp')
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1647
1 files changed, 0 insertions, 1647 deletions
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
deleted file mode 100644
index c0c77b6f917..00000000000
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ /dev/null
@@ -1,1647 +0,0 @@
-/*
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * Audaspace is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/OpenAL/AUD_OpenALDevice.cpp
- * \ingroup audopenal
- */
-
-
-#include "AUD_OpenALDevice.h"
-#include "AUD_IFactory.h"
-#include "AUD_IReader.h"
-#include "AUD_ConverterReader.h"
-#include "AUD_MutexLock.h"
-
-#include <cstring>
-#include <limits>
-
-#ifdef WIN32
-#include <windows.h>
-#else
-#include <unistd.h>
-#endif
-
-/*struct AUD_OpenALBufferedFactory
-{
- /// The factory.
- AUD_IFactory* factory;
-
- /// The OpenAL buffer.
- ALuint buffer;
-};*/
-
-//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
-
-
-/******************************************************************************/
-/*********************** AUD_OpenALHandle Handle Code *************************/
-/******************************************************************************/
-
-static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
- "generated.";
-static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
- "generated.";
-static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
- "queued to the source.";
-static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
- "filled with data.";
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PLAYING)
- {
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
- m_device->m_pausedSounds.push_back(This);
-
- alSourcePause(m_source);
-
- m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
-
- return true;
- }
- }
- }
- }
-
- return false;}
-
-AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
- m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
- m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
- m_device(device)
-{
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
-
- // OpenAL playback code
- alGenBuffers(CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
- try
- {
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
- int length;
- bool eos;
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- reader->read(length, eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
- }
-
- alGenSources(1, &m_source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &m_source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
- throw;
- }
- alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
-{
- return pause(false);
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
-{
- if(m_status)
- {
- AUD_MutexLock lock(*m_device);
-
- if(m_status == AUD_STATUS_PAUSED)
- {
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_pausedSounds.erase(it);
- m_device->m_playingSounds.push_back(This);
-
- m_device->start();
- m_status = AUD_STATUS_PLAYING;
-
- return true;
- }
- }
- }
- }
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_status = AUD_STATUS_INVALID;
-
- alDeleteSources(1, &m_source);
- if(!m_isBuffered)
- alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
-
- for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
- {
- if(it->get() == this)
- {
- boost::shared_ptr<AUD_OpenALHandle> This = *it;
-
- m_device->m_playingSounds.erase(it);
-
- return true;
- }
- }
-
- for(AUD_HandleIterator it = m_device->m_pausedSounds.begin(); it != m_device->m_pausedSounds.end(); it++)
- {
- if(it->get() == this)
- {
- m_device->m_pausedSounds.erase(it);
- return true;
- }
- }
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep()
-{
- if(m_status)
- return m_keep;
-
- return false;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_keep = keep;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- if(m_isBuffered)
- alSourcef(m_source, AL_SEC_OFFSET, position);
- else
- {
- m_reader->seek((int)(position * m_reader->getSpecs().rate));
- m_eos = false;
-
- ALint info;
-
- alGetSourcei(m_source, AL_SOURCE_STATE, &info);
-
- // we need to stop playing sounds as well to clear the buffers
- // this might cause clicks, but fixes a bug regarding position determination
- if(info == AL_PAUSED || info == AL_PLAYING)
- alSourceStop(m_source);
-
- alSourcei(m_source, AL_BUFFER, 0);
- m_current = 0;
-
- ALenum err;
- if((err = alGetError()) == AL_NO_ERROR)
- {
- int length;
- AUD_DeviceSpecs specs = m_device->m_specs;
- specs.specs = m_reader->getSpecs();
- m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- for(int i = 0; i < CYCLE_BUFFERS; i++)
- {
- length = m_device->m_buffersize;
- m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
-
- if(length == 0)
- {
- // AUD_XXX: TODO: don't fill all buffers and enqueue them later
- length = 1;
- memset(m_device->m_buffer.getBuffer(), 0, length * AUD_DEVICE_SAMPLE_SIZE(specs));
- }
-
- alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
- length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
-
- if(alGetError() != AL_NO_ERROR)
- break;
- }
-
- if(m_loopcount != 0)
- m_eos = false;
-
- alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
- }
-
- alSourceRewind(m_source);
- }
-
- if(m_status == AUD_STATUS_STOPPED)
- m_status = AUD_STATUS_PAUSED;
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return 0.0f;
-
- float position = 0.0f;
-
- alGetSourcef(m_source, AL_SEC_OFFSET, &position);
-
- if(!m_isBuffered)
- {
- int queued;
-
- // this usually always returns CYCLE_BUFFERS
- alGetSourcei(m_source, AL_BUFFERS_QUEUED, &queued);
-
- AUD_Specs specs = m_reader->getSpecs();
- position += (m_reader->getPosition() - m_device->m_buffersize *
- queued) / (float)specs.rate;
- }
-
- return position;
-}
-
-AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus()
-{
- return m_status;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_PITCH, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_PITCH, pitch);
-
- return true;
-}
-
-int AUD_OpenALDevice::AUD_OpenALHandle::getLoopCount()
-{
- if(!m_status)
- return 0;
- return m_loopcount;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
-{
- if(!m_status)
- return false;
-
- if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
- m_status = AUD_STATUS_PAUSED;
-
- m_loopcount = count;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- m_stop = callback;
- m_stop_data = data;
-
- return true;
-}
-
-/******************************************************************************/
-/********************* AUD_OpenALHandle 3DHandle Code *************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat p[3];
- alGetSourcefv(m_source, AL_POSITION, p);
-
- result = AUD_Vector3(p[0], p[1], p[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& location)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
-
- return true;
-}
-
-AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- ALfloat v[3];
- alGetSourcefv(m_source, AL_VELOCITY, v);
-
- result = AUD_Vector3(v[0], v[1], v[2]);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& velocity)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
-
- return true;
-}
-
-AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
-{
- return m_orientation;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
-{
- ALfloat direction[3];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcefv(m_source, AL_DIRECTION, direction);
-
- m_orientation = orientation;
-
- return true;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
-{
- int result;
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MIN_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MIN_GAIN, volume);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_MAX_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
-
- return true;
-}
-
-float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
-{
- float result = std::numeric_limits<float>::quiet_NaN();
-
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return result;
-
- alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
-
- return result;
-}
-
-bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
-{
- if(!m_status)
- return false;
-
- AUD_MutexLock lock(*m_device);
-
- if(!m_status)
- return false;
-
- alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
-
- return true;
-}
-
-/******************************************************************************/
-/**************************** Threading Code **********************************/
-/******************************************************************************/
-
-static void *AUD_openalRunThread(void *device)
-{
- AUD_OpenALDevice* dev = (AUD_OpenALDevice*)device;
- dev->updateStreams();
- return NULL;
-}
-
-void AUD_OpenALDevice::start(bool join)
-{
- AUD_MutexLock lock(*this);
-
- if(!m_playing)
- {
- if(join)
- pthread_join(m_thread, NULL);
-
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
-
- pthread_create(&m_thread, &attr, AUD_openalRunThread, this);
-
- pthread_attr_destroy(&attr);
-
- m_playing = true;
- }
-}
-
-void AUD_OpenALDevice::updateStreams()
-{
- boost::shared_ptr<AUD_OpenALHandle> sound;
-
- int length;
-
- ALint info;
- AUD_DeviceSpecs specs = m_specs;
- ALCenum cerr;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > stopSounds;
- std::list<boost::shared_ptr<AUD_OpenALHandle> > pauseSounds;
- AUD_HandleIterator it;
-
- while(1)
- {
- lock();
-
- alcSuspendContext(m_context);
- cerr = alcGetError(m_device);
- if(cerr == ALC_NO_ERROR)
- {
- // for all sounds
- for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
- {
- sound = *it;
-
- // is it a streamed sound?
- if(!sound->m_isBuffered)
- {
- // check for buffer refilling
- alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
-
- if(info)
- {
- specs.specs = sound->m_reader->getSpecs();
- m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
-
- // for all empty buffers
- while(info--)
- {
- // if there's still data to play back
- if(!sound->m_eos)
- {
- // read data
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
-
- // looping necessary?
- if(length == 0 && sound->m_loopcount)
- {
- if(sound->m_loopcount > 0)
- sound->m_loopcount--;
-
- sound->m_reader->seek(0);
-
- length = m_buffersize;
- sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
- }
-
- if(sound->m_loopcount != 0)
- sound->m_eos = false;
-
- // read nothing?
- if(length == 0)
- {
- break;
- }
-
- // unqueue buffer (warning: this might fail for slow early returning sources (none exist so far) if the buffer was not queued due to recent changes - has to be tested)
- alSourceUnqueueBuffers(sound->m_source, 1, &sound->m_buffers[sound->m_current]);
- ALenum err;
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // fill with new data
- alBufferData(sound->m_buffers[sound->m_current],
- sound->m_format,
- m_buffer.getBuffer(), length *
- AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
-
- if((err = alGetError()) != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- // and queue again
- alSourceQueueBuffers(sound->m_source, 1,
- &sound->m_buffers[sound->m_current]);
- if(alGetError() != AL_NO_ERROR)
- {
- sound->m_eos = true;
- break;
- }
-
- sound->m_current = (sound->m_current+1) %
- AUD_OpenALHandle::CYCLE_BUFFERS;
- }
- else
- break;
- }
- }
- }
-
- // check if the sound has been stopped
- alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
-
- if(info != AL_PLAYING)
- {
- // if it really stopped
- if(sound->m_eos && info != AL_INITIAL)
- {
- if(sound->m_stop)
- sound->m_stop(sound->m_stop_data);
-
- // pause or
- if(sound->m_keep)
- pauseSounds.push_back(sound);
- // stop
- else
- stopSounds.push_back(sound);
- }
- // continue playing
- else
- alSourcePlay(sound->m_source);
- }
- }
-
- for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- (*it)->pause(true);
-
- for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- (*it)->stop();
-
- pauseSounds.clear();
- stopSounds.clear();
-
- alcProcessContext(m_context);
- }
-
- // stop thread
- if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
- {
- m_playing = false;
- unlock();
- pthread_exit(NULL);
- }
-
- unlock();
-
-#ifdef WIN32
- Sleep(20);
-#else
- usleep(20000);
-#endif
- }
-}
-
-/******************************************************************************/
-/**************************** IDevice Code ************************************/
-/******************************************************************************/
-
-static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
-
-AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
-{
- // cannot determine how many channels or which format OpenAL uses, but
- // it at least is able to play 16 bit stereo audio
- specs.format = AUD_FORMAT_S16;
-
-#if 0
- if(alcIsExtensionPresent(NULL, "ALC_ENUMERATION_EXT") == AL_TRUE)
- {
- ALCchar* devices = const_cast<ALCchar*>(alcGetString(NULL, ALC_DEVICE_SPECIFIER));
- printf("OpenAL devices (standard is: %s):\n", alcGetString(NULL, ALC_DEFAULT_DEVICE_SPECIFIER));
-
- while(*devices)
- {
- printf("%s\n", devices);
- devices += strlen(devices) + 1;
- }
- }
-#endif
-
- m_device = alcOpenDevice(NULL);
-
- if(!m_device)
- AUD_THROW(AUD_ERROR_OPENAL, open_error);
-
- // at least try to set the frequency
- ALCint attribs[] = { ALC_FREQUENCY, (ALCint)specs.rate, 0 };
- ALCint* attributes = attribs;
- if(specs.rate == AUD_RATE_INVALID)
- attributes = NULL;
-
- m_context = alcCreateContext(m_device, attributes);
- alcMakeContextCurrent(m_context);
-
- alcGetIntegerv(m_device, ALC_FREQUENCY, 1, (ALCint*)&specs.rate);
-
- // check for specific formats and channel counts to be played back
- if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
- specs.format = AUD_FORMAT_FLOAT32;
-
- m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
-
- if((!m_useMC && specs.channels > AUD_CHANNELS_STEREO) ||
- specs.channels == AUD_CHANNELS_STEREO_LFE ||
- specs.channels == AUD_CHANNELS_SURROUND5)
- specs.channels = AUD_CHANNELS_STEREO;
-
- alGetError();
- alcGetError(m_device);
-
- m_specs = specs;
- m_buffersize = buffersize;
- m_playing = false;
-
-// m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
-
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
-
- pthread_mutex_init(&m_mutex, &attr);
-
- pthread_mutexattr_destroy(&attr);
-
- start(false);
-}
-
-AUD_OpenALDevice::~AUD_OpenALDevice()
-{
- lock();
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
-
- // delete all buffered factories
- /*while(!m_bufferedFactories->empty())
- {
- alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
- delete *m_bufferedFactories->begin();
- m_bufferedFactories->erase(m_bufferedFactories->begin());
- }*/
-
- alcProcessContext(m_context);
-
- // wait for the thread to stop
- unlock();
- pthread_join(m_thread, NULL);
-
- //delete m_bufferedFactories;
-
- // quit OpenAL
- alcMakeContextCurrent(NULL);
- alcDestroyContext(m_context);
- alcCloseDevice(m_device);
-
- pthread_mutex_destroy(&m_mutex);
-}
-
-AUD_DeviceSpecs AUD_OpenALDevice::getSpecs() const
-{
- return m_specs;
-}
-
-bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
-{
- bool valid = true;
- format = 0;
-
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = AL_FORMAT_MONO16;
- break;
- case AUD_CHANNELS_STEREO:
- format = AL_FORMAT_STEREO16;
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD16");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN16");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN16");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN16");
- break;
- }
- default:
- valid = false;
- }
- break;
- case AUD_FORMAT_FLOAT32:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = alGetEnumValue("AL_FORMAT_MONO_FLOAT32");
- break;
- case AUD_CHANNELS_STEREO:
- format = alGetEnumValue("AL_FORMAT_STEREO_FLOAT32");
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD32");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN32");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN32");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN32");
- break;
- }
- default:
- valid = false;
- }
- break;
- default:
- valid = false;
- }
-
- if(!format)
- valid = false;
-
- return valid;
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IReader> reader, bool keep)
-{
- AUD_Specs specs = reader->getSpecs();
-
- // check format
- if(specs.channels == AUD_CHANNELS_INVALID)
- return boost::shared_ptr<AUD_IHandle>();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = boost::shared_ptr<AUD_IReader>(new AUD_ConverterReader(reader, m_specs));
-
- ALenum format;
-
- if(!getFormat(format, specs))
- return boost::shared_ptr<AUD_IHandle>();
-
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle> sound;
-
- try
- {
- // create the handle
- sound = boost::shared_ptr<AUD_OpenALDevice::AUD_OpenALHandle>(new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep));
- }
- catch(AUD_Exception&)
- {
- alcProcessContext(m_context);
- throw;
- }
-
- alcProcessContext(m_context);
-
- // play sound
- m_playingSounds.push_back(sound);
-
- start();
-
- return boost::shared_ptr<AUD_IHandle>(sound);
-}
-
-boost::shared_ptr<AUD_IHandle> AUD_OpenALDevice::play(boost::shared_ptr<AUD_IFactory> factory, bool keep)
-{
- /* AUD_XXX disabled
- AUD_OpenALHandle* sound = NULL;
-
- lock();
-
- try
- {
- // check if it is a buffered factory
- for(AUD_BFIterator i = m_bufferedFactories->begin();
- i != m_bufferedFactories->end(); i++)
- {
- if((*i)->factory == factory)
- {
- // create the handle
- sound = new AUD_OpenALHandle;
- sound->keep = keep;
- sound->current = -1;
- sound->isBuffered = true;
- sound->eos = true;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
-
- alcSuspendContext(m_context);
-
- // OpenAL playback code
- try
- {
- alGenSources(1, &sound->source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourcei(sound->source, AL_BUFFER, (*i)->buffer);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &sound->source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- delete sound;
- alcProcessContext(m_context);
- throw;
- }
-
- // play sound
- m_playingSounds->push_back(sound);
-
- alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
- start();
-
- alcProcessContext(m_context);
- }
- }
- }
- catch(AUD_Exception&)
- {
- unlock();
- throw;
- }
-
- unlock();
-
- if(sound)
- return sound;*/
-
- return play(factory->createReader(), keep);
-}
-
-void AUD_OpenALDevice::stopAll()
-{
- AUD_MutexLock lock(*this);
-
- alcSuspendContext(m_context);
-
- while(!m_playingSounds.empty())
- m_playingSounds.front()->stop();
-
- while(!m_pausedSounds.empty())
- m_pausedSounds.front()->stop();
-
- alcProcessContext(m_context);
-}
-
-void AUD_OpenALDevice::lock()
-{
- pthread_mutex_lock(&m_mutex);
-}
-
-void AUD_OpenALDevice::unlock()
-{
- pthread_mutex_unlock(&m_mutex);
-}
-
-float AUD_OpenALDevice::getVolume() const
-{
- float result;
- alGetListenerf(AL_GAIN, &result);
- return result;
-}
-
-void AUD_OpenALDevice::setVolume(float volume)
-{
- alListenerf(AL_GAIN, volume);
-}
-
-/* AUD_XXX Temorary disabled
-
-bool AUD_OpenALDevice::bufferFactory(void *value)
-{
- bool result = false;
- AUD_IFactory* factory = (AUD_IFactory*) value;
-
- // load the factory into an OpenAL buffer
- if(factory)
- {
- // check if the factory is already buffered
- lock();
- for(AUD_BFIterator i = m_bufferedFactories->begin();
- i != m_bufferedFactories->end(); i++)
- {
- if((*i)->factory == factory)
- {
- result = true;
- break;
- }
- }
- unlock();
- if(result)
- return result;
-
- AUD_IReader* reader = factory->createReader();
-
- if(reader == NULL)
- return false;
-
- AUD_DeviceSpecs specs = m_specs;
- specs.specs = reader->getSpecs();
-
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- reader = new AUD_ConverterReader(reader, m_specs);
-
- ALenum format;
-
- if(!getFormat(format, specs.specs))
- {
- return false;
- }
-
- // load into a buffer
- lock();
- alcSuspendContext(m_context);
-
- AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
- bf->factory = factory;
-
- try
- {
- alGenBuffers(1, &bf->buffer);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL);
-
- try
- {
- sample_t* buf;
- int length = reader->getLength();
-
- reader->read(length, buf);
- alBufferData(bf->buffer, format, buf,
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL);
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(1, &bf->buffer);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- delete bf;
- alcProcessContext(m_context);
- unlock();
- return false;
- }
-
- m_bufferedFactories->push_back(bf);
-
- alcProcessContext(m_context);
- unlock();
- }
- else
- {
- // stop all playing and paused buffered sources
- lock();
- alcSuspendContext(m_context);
-
- AUD_OpenALHandle* sound;
- AUD_HandleIterator it = m_playingSounds->begin();
- while(it != m_playingSounds->end())
- {
- sound = *it;
- ++it;
-
- if(sound->isBuffered)
- stop(sound);
- }
- alcProcessContext(m_context);
-
- while(!m_bufferedFactories->empty())
- {
- alDeleteBuffers(1,
- &(*(m_bufferedFactories->begin()))->buffer);
- delete *m_bufferedFactories->begin();
- m_bufferedFactories->erase(m_bufferedFactories->begin());
- }
- unlock();
- }
-
- return true;
-}*/
-
-/******************************************************************************/
-/**************************** 3D Device Code **********************************/
-/******************************************************************************/
-
-AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
-{
- ALfloat p[3];
- alGetListenerfv(AL_POSITION, p);
- return AUD_Vector3(p[0], p[1], p[2]);
-}
-
-void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
-{
- alListenerfv(AL_POSITION, (ALfloat*)location.get());
-}
-
-AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
-{
- ALfloat v[3];
- alGetListenerfv(AL_VELOCITY, v);
- return AUD_Vector3(v[0], v[1], v[2]);
-}
-
-void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
-{
- alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
-}
-
-AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
-{
- return m_orientation;
-}
-
-void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
-{
- ALfloat direction[6];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
- direction[3] = 2 * (orientation.x() * orientation.y() -
- orientation.w() * orientation.z());
- direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
- orientation.z() * orientation.z());
- direction[5] = 2 * (orientation.w() * orientation.x() +
- orientation.y() * orientation.z());
- alListenerfv(AL_ORIENTATION, direction);
- m_orientation = orientation;
-}
-
-float AUD_OpenALDevice::getSpeedOfSound() const
-{
- return alGetFloat(AL_SPEED_OF_SOUND);
-}
-
-void AUD_OpenALDevice::setSpeedOfSound(float speed)
-{
- alSpeedOfSound(speed);
-}
-
-float AUD_OpenALDevice::getDopplerFactor() const
-{
- return alGetFloat(AL_DOPPLER_FACTOR);
-}
-
-void AUD_OpenALDevice::setDopplerFactor(float factor)
-{
- alDopplerFactor(factor);
-}
-
-AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
-{
- switch(alGetInteger(AL_DISTANCE_MODEL))
- {
- case AL_INVERSE_DISTANCE:
- return AUD_DISTANCE_MODEL_INVERSE;
- case AL_INVERSE_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
- case AL_LINEAR_DISTANCE:
- return AUD_DISTANCE_MODEL_LINEAR;
- case AL_LINEAR_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
- case AL_EXPONENT_DISTANCE:
- return AUD_DISTANCE_MODEL_EXPONENT;
- case AL_EXPONENT_DISTANCE_CLAMPED:
- return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
- default:
- return AUD_DISTANCE_MODEL_INVALID;
- }
-}
-
-void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
-{
- switch(model)
- {
- case AUD_DISTANCE_MODEL_INVERSE:
- alDistanceModel(AL_INVERSE_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
- alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
- break;
- case AUD_DISTANCE_MODEL_LINEAR:
- alDistanceModel(AL_LINEAR_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
- alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
- break;
- case AUD_DISTANCE_MODEL_EXPONENT:
- alDistanceModel(AL_EXPONENT_DISTANCE);
- break;
- case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
- alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
- break;
- default:
- alDistanceModel(AL_NONE);
- }
-}