From 044887b5a4b1df57fce408f29f59bce1d7fa0085 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Tue, 21 Jun 2011 20:21:43 +0000 Subject: 3D Audio GSoC: - Created Handle classes - Changed Reference counting completely - Fixing some streaming bugs - Completely disabled OpenAL Buffered Factories (they were unused anyway) --- intern/audaspace/CMakeLists.txt | 3 + intern/audaspace/FX/AUD_DoubleReader.cpp | 2 + intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 1654 ++++++++++------------ intern/audaspace/OpenAL/AUD_OpenALDevice.h | 154 +- intern/audaspace/Python/AUD_PyAPI.cpp | 255 ++-- intern/audaspace/Python/AUD_PyAPI.h | 7 +- intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp | 2 +- intern/audaspace/intern/AUD_BufferReader.cpp | 2 + intern/audaspace/intern/AUD_C-API.cpp | 212 +-- intern/audaspace/intern/AUD_C-API.h | 13 +- intern/audaspace/intern/AUD_I3DDevice.h | 196 --- intern/audaspace/intern/AUD_I3DHandle.h | 213 +++ intern/audaspace/intern/AUD_IDevice.h | 155 +- intern/audaspace/intern/AUD_IHandle.h | 181 +++ intern/audaspace/intern/AUD_NULLDevice.cpp | 80 +- intern/audaspace/intern/AUD_NULLDevice.h | 19 +- intern/audaspace/intern/AUD_Reference.h | 113 +- intern/audaspace/intern/AUD_ReferenceHandler.cpp | 33 + intern/audaspace/intern/AUD_SequencerFactory.cpp | 2 +- intern/audaspace/intern/AUD_SoftwareDevice.cpp | 535 +++---- intern/audaspace/intern/AUD_SoftwareDevice.h | 82 +- 21 files changed, 1875 insertions(+), 2038 deletions(-) create mode 100644 intern/audaspace/intern/AUD_I3DHandle.h create mode 100644 intern/audaspace/intern/AUD_IHandle.h create mode 100644 intern/audaspace/intern/AUD_ReferenceHandler.cpp (limited to 'intern/audaspace') diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt index ab88c9ecabd..9c75cd67e6a 100644 --- a/intern/audaspace/CMakeLists.txt +++ b/intern/audaspace/CMakeLists.txt @@ -87,8 +87,10 @@ set(SRC intern/AUD_FileFactory.cpp intern/AUD_FileFactory.h intern/AUD_I3DDevice.h + intern/AUD_I3DHandle.h intern/AUD_IDevice.h intern/AUD_IFactory.h + intern/AUD_IHandle.h intern/AUD_IReader.h intern/AUD_LinearResampleFactory.cpp intern/AUD_LinearResampleFactory.h @@ -104,6 +106,7 @@ set(SRC intern/AUD_ReadDevice.cpp intern/AUD_ReadDevice.h intern/AUD_Reference.h + intern/AUD_ReferenceHandler.cpp intern/AUD_ResampleFactory.h intern/AUD_SequencerFactory.cpp intern/AUD_SequencerFactory.h diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 5d9ebbd6187..2c39d193f67 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -91,6 +91,8 @@ AUD_Specs AUD_DoubleReader::getSpecs() const void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer) { + eos = false; + if(!m_finished1) { int len = length; diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 465ad5b5ae6..f24d3aef4e2 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -43,56 +43,723 @@ #include #endif -#define AUD_OPENAL_CYCLE_BUFFERS 3 +/*struct AUD_OpenALBufferedFactory +{ + /// The factory. + AUD_IFactory* factory; + + /// The OpenAL buffer. + ALuint buffer; +};*/ + +typedef std::list >::iterator AUD_HandleIterator; +//typedef std::list::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."; -/// Saves the data for playback. -struct AUD_OpenALHandle : AUD_Handle +AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference 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) { - /// Whether it's a buffered or a streamed source. - bool isBuffered; + AUD_DeviceSpecs specs = m_device->m_specs; + specs.specs = m_reader->getSpecs(); - /// The reader source. - AUD_Reference reader; + // OpenAL playback code + alGenBuffers(CYCLE_BUFFERS, m_buffers); + if(alGetError() != AL_NO_ERROR) + AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error); - /// Whether to keep the source if end of it is reached. - bool keep; + try + { + m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs)); + int length; + bool eos; - /// OpenAL sample format. - ALenum format; + for(int i = 0; i < CYCLE_BUFFERS; i++) + { + length = m_device->m_buffersize; + reader->read(length, eos, m_device->m_buffer.getBuffer()); + 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); + } - /// OpenAL source. - ALuint source; + alGenSources(1, &m_source); + if(alGetError() != AL_NO_ERROR) + AUD_THROW(AUD_ERROR_OPENAL, gensource_error); - /// OpenAL buffers. - ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS]; + 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() +{ + if(m_status) + { + m_device->lock(); - /// The first buffer to be read next. - int current; + if(m_status == AUD_STATUS_PLAYING) + { + m_device->m_playingSounds.remove(this); + m_device->m_pausedSounds.push_back(this); - /// Whether the stream doesn't return any more data. - bool eos; + alSourcePause(m_source); - /// The loop count of the source. - int loopcount; + m_status = AUD_STATUS_PAUSED; + m_device->unlock(); - /// The stop callback. - stopCallback stop; + return true; + } - /// Stop callback data. - void* stop_data; -}; + m_device->unlock(); + } -struct AUD_OpenALBufferedFactory + return false; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::resume() { - /// The factory. - AUD_IFactory* factory; + if(m_status) + { + m_device->lock(); + + if(m_status == AUD_STATUS_PAUSED) + { + m_device->m_pausedSounds.remove(this); + m_device->m_playingSounds.push_back(this); + + m_device->start(); + m_status = AUD_STATUS_PLAYING; + m_device->unlock(); + return true; + } + + m_device->unlock(); + } + + return false; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::stop() +{ + if(!m_status) + return false; + + m_device->lock(); + + if(m_status == AUD_STATUS_PLAYING) + m_device->m_playingSounds.remove(this); + else + m_device->m_pausedSounds.remove(this); + + m_device->unlock(); + + alDeleteSources(1, &m_source); + if(!m_isBuffered) + alDeleteBuffers(CYCLE_BUFFERS, m_buffers); + + m_status = AUD_STATUS_INVALID; + return true; +} + +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; + + m_device->lock(); + + m_keep = keep; + + m_device->unlock(); + + return true; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position) +{ + if(!m_status) + return false; + + m_device->lock(); + + 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); + + if(info != AL_PLAYING) + { + if(info == AL_PAUSED) + 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()); + 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); + } + } + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getPosition() +{ + if(!m_status) + return 0.0f; + + m_device->lock(); + + float position = 0.0f; + + alGetSourcef(m_source, AL_SEC_OFFSET, &position); + + if(!m_isBuffered) + { + AUD_Specs specs = m_reader->getSpecs(); + position += (m_reader->getPosition() - m_device->m_buffersize * + CYCLE_BUFFERS) / (float)specs.rate; + } + + m_device->unlock(); + + return position; +} + +AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus() +{ + return m_status; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getVolume() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_GAIN, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_GAIN, volume); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getPitch() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_PITCH, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_PITCH, pitch); + + m_device->unlock(); + + 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; + m_loopcount = count; + return true; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data) +{ + if(!m_status) + return false; + + m_device->lock(); + + m_stop = callback; + m_stop_data = data; + + m_device->unlock(); + + 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 result; + + m_device->lock(); + + ALfloat p[3]; + alGetSourcefv(m_source, AL_POSITION, p); + + m_device->unlock(); + + 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; + + m_device->lock(); + + alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get()); + + m_device->unlock(); + + return true; +} + +AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity() +{ + AUD_Vector3 result = AUD_Vector3(0, 0, 0); + + if(!m_status) + return result; + + m_device->lock(); + + ALfloat v[3]; + alGetSourcefv(m_source, AL_VELOCITY, v); + + m_device->unlock(); + + 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; + + m_device->lock(); + + alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get()); + + m_device->unlock(); + + return true; +} + +AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation() +{ + // AUD_XXX not implemented yet + return AUD_Quaternion(0, 0, 0, 0); +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation) +{ + if(!m_status) + return false; + + 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; + m_device->lock(); + + alSourcefv(m_source, AL_DIRECTION, direction); + + m_device->unlock(); + + return true; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative() +{ + int result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcei(m_source, AL_SOURCE_RELATIVE, relative); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_MAX_GAIN, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_MAX_GAIN, volume); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_MIN_GAIN, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_MIN_GAIN, volume); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_MAX_DISTANCE, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_MAX_DISTANCE, distance); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_REFERENCE_DISTANCE, distance); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_ROLLOFF_FACTOR, factor); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle) +{ + if(!m_status) + return false; + + m_device->lock(); + + alSourcef(m_source, AL_CONE_INNER_ANGLE, angle); + + m_device->unlock(); + + return true; +} + +float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter() +{ + float result = std::numeric_limits::quiet_NaN(); + + if(!m_status) + return result; + + m_device->lock(); + + alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result); + + m_device->unlock(); + + return result; +} + +bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume) +{ + if(!m_status) + return false; + + m_device->lock(); - /// The OpenAL buffer. - ALuint buffer; -}; + alSourcef(m_source, AL_CONE_OUTER_GAIN, volume); -typedef std::list::iterator AUD_HandleIterator; -typedef std::list::iterator AUD_BFIterator; + m_device->unlock(); + + return true; +} /******************************************************************************/ /**************************** Threading Code **********************************/ @@ -127,15 +794,15 @@ void AUD_OpenALDevice::start() void AUD_OpenALDevice::updateStreams() { - AUD_OpenALHandle* sound; + AUD_Reference sound; int length; ALint info; AUD_DeviceSpecs specs = m_specs; ALCenum cerr; - std::list stopSounds; - std::list pauseSounds; + std::list > stopSounds; + std::list > pauseSounds; AUD_HandleIterator it; while(1) @@ -147,45 +814,45 @@ void AUD_OpenALDevice::updateStreams() if(cerr == ALC_NO_ERROR) { // for all sounds - for(it = m_playingSounds->begin(); it != m_playingSounds->end(); it++) + for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++) { sound = *it; // is it a streamed sound? - if(!sound->isBuffered) + if(!sound->m_isBuffered) { // check for buffer refilling - alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info); + alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info); if(info) { - specs.specs = sound->reader->getSpecs(); + 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->eos) + if(!sound->m_eos) { // read data length = m_buffersize; - sound->reader->read(length, sound->eos, m_buffer.getBuffer()); + sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer()); // looping necessary? - if(length == 0 && sound->loopcount) + if(length == 0 && sound->m_loopcount) { - if(sound->loopcount > 0) - sound->loopcount--; + if(sound->m_loopcount > 0) + sound->m_loopcount--; - sound->reader->seek(0); + sound->m_reader->seek(0); length = m_buffersize; - sound->reader->read(length, sound->eos, m_buffer.getBuffer()); + sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer()); } - if(sound->loopcount != 0) - sound->eos = false; + if(sound->m_loopcount != 0) + sound->m_eos = false; // read nothing? if(length == 0) @@ -194,39 +861,39 @@ void AUD_OpenALDevice::updateStreams() } // unqueue buffer - alSourceUnqueueBuffers(sound->source, 1, - &sound->buffers[sound->current]); + alSourceUnqueueBuffers(sound->m_source, 1, + &sound->m_buffers[sound->m_current]); ALenum err; if((err = alGetError()) != AL_NO_ERROR) { - sound->eos = true; + sound->m_eos = true; break; } // fill with new data - alBufferData(sound->buffers[sound->current], - sound->format, + 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->eos = true; + sound->m_eos = true; break; } // and queue again - alSourceQueueBuffers(sound->source, 1, - &sound->buffers[sound->current]); + alSourceQueueBuffers(sound->m_source, 1, + &sound->m_buffers[sound->m_current]); if(alGetError() != AL_NO_ERROR) { - sound->eos = true; + sound->m_eos = true; break; } - sound->current = (sound->current+1) % - AUD_OPENAL_CYCLE_BUFFERS; + sound->m_current = (sound->m_current+1) % + AUD_OpenALHandle::CYCLE_BUFFERS; } else break; @@ -235,18 +902,18 @@ void AUD_OpenALDevice::updateStreams() } // check if the sound has been stopped - alGetSourcei(sound->source, AL_SOURCE_STATE, &info); + alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info); if(info != AL_PLAYING) { // if it really stopped - if(sound->eos) + if(sound->m_eos) { - if(sound->stop) - sound->stop(sound->stop_data); + if(sound->m_stop) + sound->m_stop(sound->m_stop_data); // pause or - if(sound->keep) + if(sound->m_keep) pauseSounds.push_back(sound); // stop else @@ -254,15 +921,15 @@ void AUD_OpenALDevice::updateStreams() } // continue playing else - alSourcePlay(sound->source); + alSourcePlay(sound->m_source); } } for(it = pauseSounds.begin(); it != pauseSounds.end(); it++) - pause(*it); + (*it)->pause(); for(it = stopSounds.begin(); it != stopSounds.end(); it++) - stop(*it); + (*it)->stop(); pauseSounds.clear(); stopSounds.clear(); @@ -271,7 +938,7 @@ void AUD_OpenALDevice::updateStreams() } // stop thread - if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR)) + if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR)) { unlock(); m_playing = false; @@ -292,19 +959,6 @@ void AUD_OpenALDevice::updateStreams() /**************************** IDevice Code ************************************/ /******************************************************************************/ -bool AUD_OpenALDevice::isValid(AUD_Handle* handle) -{ - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) - if(*i == handle) - return true; - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) - if(*i == handle) - return true; - return false; -} - static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened."; AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize) @@ -357,9 +1011,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize) m_buffersize = buffersize; m_playing = false; - m_playingSounds = new std::list(); - m_pausedSounds = new std::list(); - m_bufferedFactories = new std::list(); +// m_bufferedFactories = new std::list(); pthread_mutexattr_t attr; pthread_mutexattr_init(&attr); @@ -372,44 +1024,23 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize) AUD_OpenALDevice::~AUD_OpenALDevice() { - AUD_OpenALHandle* sound; - lock(); alcSuspendContext(m_context); - // delete all playing sounds - while(!m_playingSounds->empty()) - { - sound = *(m_playingSounds->begin()); - alDeleteSources(1, &sound->source); - if(!sound->isBuffered) - { - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - } - delete sound; - m_playingSounds->erase(m_playingSounds->begin()); - } + while(!m_playingSounds.empty()) + m_playingSounds.front()->stop(); + + while(!m_pausedSounds.empty()) + m_pausedSounds.front()->stop(); - // delete all paused sounds - while(!m_pausedSounds->empty()) - { - sound = *(m_pausedSounds->begin()); - alDeleteSources(1, &sound->source); - if(!sound->isBuffered) - { - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - } - delete sound; - m_pausedSounds->erase(m_pausedSounds->begin()); - } // delete all buffered factories - while(!m_bufferedFactories->empty()) + /*while(!m_bufferedFactories->empty()) { alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer); delete *m_bufferedFactories->begin(); m_bufferedFactories->erase(m_bufferedFactories->begin()); - } + }*/ alcProcessContext(m_context); @@ -422,9 +1053,7 @@ AUD_OpenALDevice::~AUD_OpenALDevice() else unlock(); - delete m_playingSounds; - delete m_pausedSounds; - delete m_bufferedFactories; + //delete m_bufferedFactories; // quit OpenAL alcMakeContextCurrent(NULL); @@ -530,116 +1159,52 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs) return valid; } -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."; - -AUD_Handle* AUD_OpenALDevice::play(AUD_Reference reader, bool keep) +AUD_Reference AUD_OpenALDevice::play(AUD_Reference reader, bool keep) { - AUD_OpenALHandle* sound = NULL; - - AUD_DeviceSpecs specs = m_specs; - specs.specs = reader->getSpecs(); + AUD_Specs specs = reader->getSpecs(); // check format - bool valid = specs.channels != AUD_CHANNELS_INVALID; + if(specs.channels == AUD_CHANNELS_INVALID) + return NULL; if(m_specs.format != AUD_FORMAT_FLOAT32) reader = new AUD_ConverterReader(reader, m_specs); - // create the handle - sound = new AUD_OpenALHandle; - sound->keep = keep; - sound->reader = reader; - sound->current = 0; - sound->isBuffered = false; - sound->loopcount = 0; - sound->stop = NULL; - sound->stop_data = NULL; - - valid &= getFormat(sound->format, specs.specs); + ALenum format; - if(!valid) - { - delete sound; + if(!getFormat(format, specs)) return NULL; - } lock(); alcSuspendContext(m_context); - // OpenAL playback code + AUD_Reference sound; + try { - alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error); - - try - { - m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs)); - int length; - - for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++) - { - length = m_buffersize; - reader->read(length,sound->eos, m_buffer.getBuffer()); - alBufferData(sound->buffers[i], sound->format, 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, &sound->source); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL, gensource_error); - - try - { - alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS, - sound->buffers); - if(alGetError() != AL_NO_ERROR) - AUD_THROW(AUD_ERROR_OPENAL, queue_error); - } - catch(AUD_Exception&) - { - alDeleteSources(1, &sound->source); - throw; - } - } - catch(AUD_Exception&) - { - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - throw; - } + // create the handle + sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep); } catch(AUD_Exception&) { - delete sound; alcProcessContext(m_context); unlock(); throw; } + alcProcessContext(m_context); + // play sound - m_playingSounds->push_back(sound); - alSourcei(sound->source, AL_SOURCE_RELATIVE, 1); + m_playingSounds.push_back(sound); start(); - alcProcessContext(m_context); unlock(); - return sound; + return AUD_Reference(sound); } -AUD_Handle* AUD_OpenALDevice::play(AUD_Reference factory, bool keep) +AUD_Reference AUD_OpenALDevice::play(AUD_Reference factory, bool keep) { /* AUD_XXX disabled AUD_OpenALHandle* sound = NULL; @@ -702,373 +1267,40 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_Reference factory, bool kee } } } - catch(AUD_Exception&) - { - unlock(); - throw; - } - - unlock(); - - if(sound) - return sound;*/ - - return play(factory->createReader(), keep); -} - -bool AUD_OpenALDevice::pause(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - // only songs that are played can be paused - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) - { - if(*i == handle) - { - m_pausedSounds->push_back(*i); - alSourcePause((*i)->source); - m_playingSounds->erase(i); - result = true; - break; - } - } - - unlock(); - - return result; -} - -bool AUD_OpenALDevice::resume(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - // only songs that are paused can be resumed - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) - { - if(*i == handle) - { - m_playingSounds->push_back(*i); - start(); - m_pausedSounds->erase(i); - result = true; - break; - } - } - - unlock(); - - return result; -} - -bool AUD_OpenALDevice::stop(AUD_Handle* handle) -{ - AUD_OpenALHandle* sound; - - bool result = false; - - lock(); - - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) - { - if(*i == handle) - { - sound = *i; - alDeleteSources(1, &sound->source); - if(!sound->isBuffered) - { - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - } - delete *i; - m_playingSounds->erase(i); - result = true; - break; - } - } - if(!result) - { - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) - { - if(*i == handle) - { - sound = *i; - alDeleteSources(1, &sound->source); - if(!sound->isBuffered) - { - alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers); - } - delete *i; - m_pausedSounds->erase(i); - result = true; - break; - } - } - } - - unlock(); - - return result; -} - -bool AUD_OpenALDevice::getKeep(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - if(isValid(handle)) - result = ((AUD_OpenALHandle*)handle)->keep; - - unlock(); - - return result; -} - -bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep) -{ - bool result = false; - - lock(); - - if(isValid(handle)) - { - ((AUD_OpenALHandle*)handle)->keep = keep; - result = true; - } - - unlock(); - - return result; -} - -bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position) -{ - bool result = false; - - lock(); - - if(isValid(handle)) - { - AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle; - if(alhandle->isBuffered) - alSourcef(alhandle->source, AL_SEC_OFFSET, position); - else - { - alhandle->reader->seek((int)(position * - alhandle->reader->getSpecs().rate)); - alhandle->eos = false; - - ALint info; - - alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info); - - if(info != AL_PLAYING) - { - if(info == AL_PAUSED) - alSourceStop(alhandle->source); - - alSourcei(alhandle->source, AL_BUFFER, 0); - alhandle->current = 0; - - ALenum err; - if((err = alGetError()) == AL_NO_ERROR) - { - int length; - AUD_DeviceSpecs specs = m_specs; - specs.specs = alhandle->reader->getSpecs(); - m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs)); - - for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++) - { - length = m_buffersize; - alhandle->reader->read(length, alhandle->eos, m_buffer.getBuffer()); - alBufferData(alhandle->buffers[i], alhandle->format, - m_buffer.getBuffer(), - length * AUD_DEVICE_SAMPLE_SIZE(specs), - specs.rate); - - if(alGetError() != AL_NO_ERROR) - break; - } - - if(alhandle->loopcount != 0) - alhandle->eos = false; - - alSourceQueueBuffers(alhandle->source, - AUD_OPENAL_CYCLE_BUFFERS, - alhandle->buffers); - } - - alSourceRewind(alhandle->source); - } - } - result = true; - } - - unlock(); - return result; -} - -float AUD_OpenALDevice::getPosition(AUD_Handle* handle) -{ - float position = 0.0f; - - lock(); - - if(isValid(handle)) - { - AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle; - alGetSourcef(h->source, AL_SEC_OFFSET, &position); - if(!h->isBuffered) - { - AUD_Specs specs = h->reader->getSpecs(); - position += (h->reader->getPosition() - m_buffersize * - AUD_OPENAL_CYCLE_BUFFERS) / - (float)specs.rate; - } - } - - unlock(); - return position; -} - -AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle) -{ - AUD_Status status = AUD_STATUS_INVALID; - - lock(); - - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) - { - if(*i == handle) - { - status = AUD_STATUS_PLAYING; - break; - } - } - if(status == AUD_STATUS_INVALID) - { - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) - { - if(*i == handle) - { - status = AUD_STATUS_PAUSED; - break; - } - } - } - - unlock(); - - return status; -} - -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); -} + catch(AUD_Exception&) + { + unlock(); + throw; + } -float AUD_OpenALDevice::getVolume(AUD_Handle* handle) -{ - lock(); - float result = std::numeric_limits::quiet_NaN(); - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result); unlock(); - return result; -} -bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume) -{ - lock(); - bool result = isValid(handle); - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume); - unlock(); - return result; -} + if(sound) + return sound;*/ -float AUD_OpenALDevice::getPitch(AUD_Handle* handle) -{ - lock(); - float result = std::numeric_limits::quiet_NaN(); - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result); - unlock(); - return result; + return play(factory->createReader(), keep); } -bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch) +void AUD_OpenALDevice::lock() { - lock(); - bool result = isValid(handle); - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch); - unlock(); - return result; + pthread_mutex_lock(&m_mutex); } -int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle) +void AUD_OpenALDevice::unlock() { - lock(); - int result = 0; - if(isValid(handle)) - result = ((AUD_OpenALHandle*)handle)->loopcount; - unlock(); - return result; + pthread_mutex_unlock(&m_mutex); } -bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count) +float AUD_OpenALDevice::getVolume() const { - lock(); - bool result = isValid(handle); - if(result) - { - ((AUD_OpenALHandle*)handle)->loopcount = count; - ((AUD_OpenALHandle*)handle)->eos = false; - } - unlock(); + float result; + alGetListenerf(AL_GAIN, &result); return result; } -bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data) +void AUD_OpenALDevice::setVolume(float volume) { - lock(); - bool result = isValid(handle); - if(result) - { - AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle; - h->stop = callback; - h->stop_data = data; - } - unlock(); - return result; + alListenerf(AL_GAIN, volume); } /* AUD_XXX Temorary disabled @@ -1308,333 +1540,3 @@ void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model) alDistanceModel(AL_NONE); } } - -AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle) -{ - AUD_Vector3 result = AUD_Vector3(0, 0, 0); - ALfloat p[3]; - lock(); - - if(isValid(handle)) - { - alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p); - result = AUD_Vector3(p[0], p[1], p[2]); - } - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, - (ALfloat*)location.get()); - - unlock(); - return result; -} - -AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle) -{ - AUD_Vector3 result = AUD_Vector3(0, 0, 0); - ALfloat v[3]; - lock(); - - if(isValid(handle)) - { - alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v); - result = AUD_Vector3(v[0], v[1], v[2]); - } - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, - (ALfloat*)velocity.get()); - - unlock(); - return result; -} - -AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle) -{ - // AUD_XXX not implemented yet - return AUD_Quaternion(0, 0, 0, 0); -} - -bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation) -{ - lock(); - bool result = isValid(handle); - - if(result) - { - 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; - alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION, - direction); - } - - unlock(); - return result; -} - -bool AUD_OpenALDevice::isRelative(AUD_Handle* handle) -{ - int result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE, - relative); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume) -{ - lock(); - bool result = isValid(handle); - - if(result) - - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN, - volume); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN, - volume); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE, - distance); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE, - distance); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR, - factor); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE, - angle); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE, - angle); - - unlock(); - return result; -} - -float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle) -{ - float result = std::numeric_limits::quiet_NaN();; - - lock(); - - if(isValid(handle)) - alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN, - &result); - - unlock(); - return result; -} - -bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume) -{ - lock(); - bool result = isValid(handle); - - if(result) - alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN, - volume); - - unlock(); - return result; -} diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h index d5db5989fe7..6bf04a36329 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h @@ -33,10 +33,11 @@ #define AUD_OPENALDEVICE #include "AUD_IDevice.h" +#include "AUD_IHandle.h" #include "AUD_I3DDevice.h" +#include "AUD_I3DHandle.h" #include "AUD_Buffer.h" -struct AUD_OpenALHandle; -struct AUD_OpenALBufferedFactory; +//struct AUD_OpenALBufferedFactory; #include #include @@ -49,6 +50,99 @@ struct AUD_OpenALBufferedFactory; class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice { private: + /// Saves the data for playback. + class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle + { + public: + static const int CYCLE_BUFFERS = 3; + + /// Whether it's a buffered or a streamed source. + bool m_isBuffered; + + /// The reader source. + AUD_Reference m_reader; + + /// Whether to keep the source if end of it is reached. + bool m_keep; + + /// OpenAL sample format. + ALenum m_format; + + /// OpenAL source. + ALuint m_source; + + /// OpenAL buffers. + ALuint m_buffers[CYCLE_BUFFERS]; + + /// The first buffer to be read next. + int m_current; + + /// Whether the stream doesn't return any more data. + bool m_eos; + + /// The loop count of the source. + int m_loopcount; + + /// The stop callback. + stopCallback m_stop; + + /// Stop callback data. + void* m_stop_data; + + /// Current status of the handle + AUD_Status m_status; + + /// Own device. + AUD_OpenALDevice* m_device; + + public: + + AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference reader, bool keep); + + virtual ~AUD_OpenALHandle() {} + virtual bool pause(); + virtual bool resume(); + virtual bool stop(); + virtual bool getKeep(); + virtual bool setKeep(bool keep); + virtual bool seek(float position); + virtual float getPosition(); + virtual AUD_Status getStatus(); + virtual float getVolume(); + virtual bool setVolume(float volume); + virtual float getPitch(); + virtual bool setPitch(float pitch); + virtual int getLoopCount(); + virtual bool setLoopCount(int count); + virtual bool setStopCallback(stopCallback callback = 0, void* data = 0); + + virtual AUD_Vector3 getSourceLocation(); + virtual bool setSourceLocation(const AUD_Vector3& location); + virtual AUD_Vector3 getSourceVelocity(); + virtual bool setSourceVelocity(const AUD_Vector3& velocity); + virtual AUD_Quaternion getSourceOrientation(); + virtual bool setSourceOrientation(const AUD_Quaternion& orientation); + virtual bool isRelative(); + virtual bool setRelative(bool relative); + virtual float getVolumeMaximum(); + virtual bool setVolumeMaximum(float volume); + virtual float getVolumeMinimum(); + virtual bool setVolumeMinimum(float volume); + virtual float getDistanceMaximum(); + virtual bool setDistanceMaximum(float distance); + virtual float getDistanceReference(); + virtual bool setDistanceReference(float distance); + virtual float getAttenuation(); + virtual bool setAttenuation(float factor); + virtual float getConeAngleOuter(); + virtual bool setConeAngleOuter(float angle); + virtual float getConeAngleInner(); + virtual bool setConeAngleInner(float angle); + virtual float getConeVolumeOuter(); + virtual bool setConeVolumeOuter(float volume); + }; + + /** * The OpenAL device handle. */ @@ -72,17 +166,17 @@ private: /** * The list of sounds that are currently playing. */ - std::list* m_playingSounds; + std::list > m_playingSounds; /** * The list of sounds that are currently paused. */ - std::list* m_pausedSounds; + std::list > m_pausedSounds; /** * The list of buffered factories. */ - std::list* m_bufferedFactories; + //std::list* m_bufferedFactories; /** * The mutex for locking. @@ -114,13 +208,6 @@ private: */ void start(); - /** - * Checks if a handle is valid. - * \param handle The handle to check. - * \return Whether the handle is valid. - */ - bool isValid(AUD_Handle* handle); - /** * Gets the format according to the specs. * \param format The variable to put the format into. @@ -153,27 +240,12 @@ public: virtual ~AUD_OpenALDevice(); virtual AUD_DeviceSpecs getSpecs() const; - virtual AUD_Handle* play(AUD_Reference reader, bool keep = false); - virtual AUD_Handle* play(AUD_Reference factory, bool keep = false); - virtual bool pause(AUD_Handle* handle); - virtual bool resume(AUD_Handle* handle); - virtual bool stop(AUD_Handle* handle); - virtual bool getKeep(AUD_Handle* handle); - virtual bool setKeep(AUD_Handle* handle, bool keep); - virtual bool seek(AUD_Handle* handle, float position); - virtual float getPosition(AUD_Handle* handle); - virtual AUD_Status getStatus(AUD_Handle* handle); + virtual AUD_Reference play(AUD_Reference reader, bool keep = false); + virtual AUD_Reference play(AUD_Reference factory, bool keep = false); virtual void lock(); virtual void unlock(); virtual float getVolume() const; virtual void setVolume(float volume); - virtual float getVolume(AUD_Handle* handle); - virtual bool setVolume(AUD_Handle* handle, float volume); - virtual float getPitch(AUD_Handle* handle); - virtual bool setPitch(AUD_Handle* handle, float pitch); - virtual int getLoopCount(AUD_Handle* handle); - virtual bool setLoopCount(AUD_Handle* handle, int count); - virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL); virtual AUD_Vector3 getListenerLocation() const; virtual void setListenerLocation(const AUD_Vector3& location); @@ -187,30 +259,6 @@ public: virtual void setDopplerFactor(float factor); virtual AUD_DistanceModel getDistanceModel() const; virtual void setDistanceModel(AUD_DistanceModel model); - virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle); - virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location); - virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle); - virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity); - virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle); - virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation); - virtual bool isRelative(AUD_Handle* handle); - virtual bool setRelative(AUD_Handle* handle, bool relative); - virtual float getVolumeMaximum(AUD_Handle* handle); - virtual bool setVolumeMaximum(AUD_Handle* handle, float volume); - virtual float getVolumeMinimum(AUD_Handle* handle); - virtual bool setVolumeMinimum(AUD_Handle* handle, float volume); - virtual float getDistanceMaximum(AUD_Handle* handle); - virtual bool setDistanceMaximum(AUD_Handle* handle, float distance); - virtual float getDistanceReference(AUD_Handle* handle); - virtual bool setDistanceReference(AUD_Handle* handle, float distance); - virtual float getAttenuation(AUD_Handle* handle); - virtual bool setAttenuation(AUD_Handle* handle, float factor); - virtual float getConeAngleOuter(AUD_Handle* handle); - virtual bool setConeAngleOuter(AUD_Handle* handle, float angle); - virtual float getConeAngleInner(AUD_Handle* handle); - virtual bool setConeAngleInner(AUD_Handle* handle, float angle); - virtual float getConeVolumeOuter(AUD_Handle* handle); - virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume); }; #endif //AUD_OPENALDEVICE diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp index b6e336eb329..2a4cee4dd0e 100644 --- a/intern/audaspace/Python/AUD_PyAPI.cpp +++ b/intern/audaspace/Python/AUD_PyAPI.cpp @@ -33,6 +33,7 @@ #include "structmember.h" #include "AUD_I3DDevice.h" +#include "AUD_I3DHandle.h" #include "AUD_NULLDevice.h" #include "AUD_DelayFactory.h" #include "AUD_DoubleFactory.h" @@ -1033,7 +1034,8 @@ static PyTypeObject FactoryType = { static void Handle_dealloc(Handle* self) { - Py_XDECREF(self->device); + if(self->handle) + delete reinterpret_cast*>(self->handle); Py_TYPE(self)->tp_free((PyObject*)self); } @@ -1046,11 +1048,9 @@ PyDoc_STRVAR(M_aud_Handle_pause_doc, static PyObject * Handle_pause(Handle *self) { - Device* device = (Device*)self->device; - try { - return PyBool_FromLong((long)(*reinterpret_cast*>(device->device))->pause(self->handle)); + return PyBool_FromLong((long)(*reinterpret_cast*>(self->handle))->pause()); } catch(AUD_Exception& e) { @@ -1068,11 +1068,9 @@ PyDoc_STRVAR(M_aud_Handle_resume_doc, static PyObject * Handle_resume(Handle *self) { - Device* device = (Device*)self->device; - try { - return PyBool_FromLong((long)(*reinterpret_cast*>(device->device))->resume(self->handle)); + return PyBool_FromLong((long)(*reinterpret_cast*>(self->handle))->resume()); } catch(AUD_Exception& e) { @@ -1091,11 +1089,9 @@ PyDoc_STRVAR(M_aud_Handle_stop_doc, static PyObject * Handle_stop(Handle *self) { - Device* device = (Device*)self->device; - try { - return PyBool_FromLong((long)(*reinterpret_cast*>(device->device))->stop(self->handle)); + return PyBool_FromLong((long)(*reinterpret_cast*>(self->handle))->stop()); } catch(AUD_Exception& e) { @@ -1123,11 +1119,9 @@ PyDoc_STRVAR(M_aud_Handle_position_doc, static PyObject * Handle_get_position(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return Py_BuildValue("f", (*reinterpret_cast*>(device->device))->getPosition(self->handle)); + return Py_BuildValue("f", (*reinterpret_cast*>(self->handle))->getPosition()); } catch(AUD_Exception& e) { @@ -1144,11 +1138,9 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:position", &position)) return -1; - Device* device = (Device*)self->device; - try { - if((*reinterpret_cast*>(device->device))->seek(self->handle, position)) + if((*reinterpret_cast*>(self->handle))->seek(position)) return 0; PyErr_SetString(AUDError, "Couldn't seek the sound!"); } @@ -1172,11 +1164,9 @@ PyDoc_STRVAR(M_aud_Handle_keep_doc, static PyObject * Handle_get_keep(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return PyBool_FromLong((long)(*reinterpret_cast*>(device->device))->getKeep(self->handle)); + return PyBool_FromLong((long)(*reinterpret_cast*>(self->handle))->getKeep()); } catch(AUD_Exception& e) { @@ -1195,11 +1185,10 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing) } bool keep = args == Py_True; - Device* device = (Device*)self->device; try { - if((*reinterpret_cast*>(device->device))->setKeep(self->handle, keep)) + if((*reinterpret_cast*>(self->handle))->setKeep(keep)) return 0; PyErr_SetString(AUDError, "Couldn't set keep of the sound!"); } @@ -1217,11 +1206,9 @@ PyDoc_STRVAR(M_aud_Handle_status_doc, static PyObject * Handle_get_status(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return PyBool_FromLong((long)(*reinterpret_cast*>(device->device))->getStatus(self->handle)); + return PyBool_FromLong((long)(*reinterpret_cast*>(self->handle))->getStatus()); } catch(AUD_Exception& e) { @@ -1236,11 +1223,9 @@ PyDoc_STRVAR(M_aud_Handle_volume_doc, static PyObject * Handle_get_volume(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return Py_BuildValue("f", (*reinterpret_cast*>(device->device))->getVolume(self->handle)); + return Py_BuildValue("f", (*reinterpret_cast*>(self->handle))->getVolume()); } catch(AUD_Exception& e) { @@ -1257,11 +1242,9 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:volume", &volume)) return -1; - Device* device = (Device*)self->device; - try { - if((*reinterpret_cast*>(device->device))->setVolume(self->handle, volume)) + if((*reinterpret_cast*>(self->handle))->setVolume(volume)) return 0; PyErr_SetString(AUDError, "Couldn't set the sound volume!"); } @@ -1279,11 +1262,9 @@ PyDoc_STRVAR(M_aud_Handle_pitch_doc, static PyObject * Handle_get_pitch(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return Py_BuildValue("f", (*reinterpret_cast*>(device->device))->getPitch(self->handle)); + return Py_BuildValue("f", (*reinterpret_cast*>(self->handle))->getPitch()); } catch(AUD_Exception& e) { @@ -1300,11 +1281,9 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:pitch", &pitch)) return -1; - Device* device = (Device*)self->device; - try { - if((*reinterpret_cast*>(device->device))->setPitch(self->handle, pitch)) + if((*reinterpret_cast*>(self->handle))->setPitch(pitch)) return 0; PyErr_SetString(AUDError, "Couldn't set the sound pitch!"); } @@ -1322,11 +1301,9 @@ PyDoc_STRVAR(M_aud_Handle_loop_count_doc, static PyObject * Handle_get_loop_count(Handle *self, void* nothing) { - Device* device = (Device*)self->device; - try { - return Py_BuildValue("i", (*reinterpret_cast*>(device->device))->getLoopCount(self->handle)); + return Py_BuildValue("i", (*reinterpret_cast*>(self->handle))->getLoopCount()); } catch(AUD_Exception& e) { @@ -1343,11 +1320,9 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "i:loop_count", &loops)) return -1; - Device* device = (Device*)self->device; - try { - if((*reinterpret_cast*>(device->device))->setLoopCount(self->handle, loops)) + if((*reinterpret_cast*>(self->handle))->setLoopCount(loops)) return 0; PyErr_SetString(AUDError, "Couldn't set the loop count!"); } @@ -1365,14 +1340,12 @@ PyDoc_STRVAR(M_aud_Handle_location_doc, static PyObject * Handle_get_location(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - AUD_Vector3 v = device->getSourceLocation(self->handle); + AUD_Vector3 v = handle->getSourceLocation(); return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); } else @@ -1396,15 +1369,13 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "(fff):location", &x, &y, &z)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { AUD_Vector3 location(x, y, z); - if(device->setSourceLocation(self->handle, location)) + if(handle->setSourceLocation(location)) return 0; PyErr_SetString(AUDError, "Location couldn't be set!"); } @@ -1425,14 +1396,12 @@ PyDoc_STRVAR(M_aud_Handle_velocity_doc, static PyObject * Handle_get_velocity(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - AUD_Vector3 v = device->getSourceVelocity(self->handle); + AUD_Vector3 v = handle->getSourceVelocity(); return Py_BuildValue("(fff)", v.x(), v.y(), v.z()); } else @@ -1456,15 +1425,13 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { AUD_Vector3 velocity(x, y, z); - if(device->setSourceVelocity(self->handle, velocity)) + if(handle->setSourceVelocity(velocity)) return 0; PyErr_SetString(AUDError, "Couldn't set the velocity!"); } @@ -1485,14 +1452,12 @@ PyDoc_STRVAR(M_aud_Handle_orientation_doc, static PyObject * Handle_get_orientation(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - AUD_Quaternion o = device->getSourceOrientation(self->handle); + AUD_Quaternion o = handle->getSourceOrientation(); return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z()); } else @@ -1516,15 +1481,13 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { AUD_Quaternion orientation(w, x, y, z); - if(device->setSourceOrientation(self->handle, orientation)) + if(handle->setSourceOrientation(orientation)) return 0; PyErr_SetString(AUDError, "Couldn't set the orientation!"); } @@ -1545,14 +1508,12 @@ PyDoc_STRVAR(M_aud_Handle_relative_doc, static PyObject * Handle_get_relative(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return PyBool_FromLong((long)device->isRelative(self->handle)); + return PyBool_FromLong((long)handle->isRelative()); } else { @@ -1577,14 +1538,13 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing) } bool relative = (args == Py_True); - Device* dev = (Device*)self->device; try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setRelative(self->handle, relative)) + if(handle->setRelative(relative)) return 0; PyErr_SetString(AUDError, "Couldn't set the relativeness!"); } @@ -1606,14 +1566,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc, static PyObject * Handle_get_volume_minimum(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getVolumeMinimum(self->handle)); + return Py_BuildValue("f", handle->getVolumeMinimum()); } else { @@ -1636,14 +1594,12 @@ Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:volume_minimum", &volume)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setVolumeMinimum(self->handle, volume)) + if(handle->setVolumeMinimum(volume)) return 0; PyErr_SetString(AUDError, "Couldn't set the minimum volume!"); } @@ -1665,14 +1621,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc, static PyObject * Handle_get_volume_maximum(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getVolumeMaximum(self->handle)); + return Py_BuildValue("f", handle->getVolumeMaximum()); } else { @@ -1695,14 +1649,12 @@ Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:volume_maximum", &volume)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setVolumeMaximum(self->handle, volume)) + if(handle->setVolumeMaximum(volume)) return 0; PyErr_SetString(AUDError, "Couldn't set the maximum volume!"); } @@ -1725,14 +1677,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_reference_doc, static PyObject * Handle_get_distance_reference(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getDistanceReference(self->handle)); + return Py_BuildValue("f", handle->getDistanceReference()); } else { @@ -1755,14 +1705,12 @@ Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:distance_reference", &distance)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setDistanceReference(self->handle, distance)) + if(handle->setDistanceReference(distance)) return 0; PyErr_SetString(AUDError, "Couldn't set the reference distance!"); } @@ -1785,14 +1733,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc, static PyObject * Handle_get_distance_maximum(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getDistanceMaximum(self->handle)); + return Py_BuildValue("f", handle->getDistanceMaximum()); } else { @@ -1815,14 +1761,12 @@ Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:distance_maximum", &distance)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setDistanceMaximum(self->handle, distance)) + if(handle->setDistanceMaximum(distance)) return 0; PyErr_SetString(AUDError, "Couldn't set the maximum distance!"); } @@ -1845,14 +1789,12 @@ PyDoc_STRVAR(M_aud_Handle_attenuation_doc, static PyObject * Handle_get_attenuation(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getAttenuation(self->handle)); + return Py_BuildValue("f", handle->getAttenuation()); } else { @@ -1875,14 +1817,12 @@ Handle_set_attenuation(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:attenuation", &factor)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setAttenuation(self->handle, factor)) + if(handle->setAttenuation(factor)) return 0; PyErr_SetString(AUDError, "Couldn't set the attenuation!"); } @@ -1910,14 +1850,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc, static PyObject * Handle_get_cone_angle_inner(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getConeAngleInner(self->handle)); + return Py_BuildValue("f", handle->getConeAngleInner()); } else { @@ -1940,14 +1878,12 @@ Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:cone_angle_inner", &angle)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setConeAngleInner(self->handle, angle)) + if(handle->setConeAngleInner(angle)) return 0; PyErr_SetString(AUDError, "Couldn't set the cone inner angle!"); } @@ -1969,14 +1905,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc, static PyObject * Handle_get_cone_angle_outer(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getConeAngleOuter(self->handle)); + return Py_BuildValue("f", handle->getConeAngleOuter()); } else { @@ -1999,14 +1933,12 @@ Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:cone_angle_outer", &angle)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setConeAngleOuter(self->handle, angle)) + if(handle->setConeAngleOuter(angle)) return 0; PyErr_SetString(AUDError, "Couldn't set the cone outer angle!"); } @@ -2028,14 +1960,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc, static PyObject * Handle_get_cone_volume_outer(Handle *self, void* nothing) { - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - return Py_BuildValue("f", device->getConeVolumeOuter(self->handle)); + return Py_BuildValue("f", handle->getConeVolumeOuter()); } else { @@ -2058,14 +1988,12 @@ Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing) if(!PyArg_Parse(args, "f:cone_volume_outer", &volume)) return -1; - Device* dev = (Device*)self->device; - try { - AUD_I3DDevice* device = dynamic_cast(reinterpret_cast*>(dev->device)->get()); - if(device) + AUD_I3DHandle* handle = dynamic_cast(reinterpret_cast*>(self->handle)->get()); + if(handle) { - if(device->setConeVolumeOuter(self->handle, volume)) + if(handle->setConeVolumeOuter(volume)) return 0; PyErr_SetString(AUDError, "Couldn't set the cone outer volume!"); } @@ -2302,12 +2230,9 @@ Device_play(Device *self, PyObject *args, PyObject *kwds) handle = (Handle*)HandleType.tp_alloc(&HandleType, 0); if(handle != NULL) { - handle->device = (PyObject*)self; - Py_INCREF(self); - try { - handle->handle = (*reinterpret_cast*>(self->device))->play(*reinterpret_cast*>(sound->factory), keep); + handle->handle = new AUD_Reference((*reinterpret_cast*>(self->device))->play(*reinterpret_cast*>(sound->factory), keep)); } catch(AUD_Exception& e) { diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h index 822aec06976..e234ad4dded 100644 --- a/intern/audaspace/Python/AUD_PyAPI.h +++ b/intern/audaspace/Python/AUD_PyAPI.h @@ -36,15 +36,15 @@ #ifdef __cplusplus extern "C" { -struct AUD_Handle; #else typedef void AUD_IFactory; typedef void AUD_IDevice; -typedef void AUD_Handle; +typedef void AUD_IHandle; #endif typedef void AUD_Reference_AUD_IFactory; typedef void AUD_Reference_AUD_IDevice; +typedef void AUD_Reference_AUD_IHandle; typedef struct { PyObject_HEAD @@ -54,8 +54,7 @@ typedef struct { typedef struct { PyObject_HEAD - AUD_Handle* handle; - PyObject* device; + AUD_Reference_AUD_IHandle* handle; } Handle; typedef struct { diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp index 852b93d24a8..b7690d55383 100644 --- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp +++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp @@ -432,7 +432,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer) pkgbuf_pos-data_size); } - if(eos = (left > 0)) + if((eos = (left > 0))) length -= left; m_position += length; diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp index 3ab226558ac..99a99069378 100644 --- a/intern/audaspace/intern/AUD_BufferReader.cpp +++ b/intern/audaspace/intern/AUD_BufferReader.cpp @@ -68,6 +68,8 @@ AUD_Specs AUD_BufferReader::getSpecs() const void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer) { + eos = false; + int sample_size = AUD_SAMPLE_SIZE(m_specs); sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels; diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 0b2e782925c..fc693be12d5 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -45,6 +45,7 @@ #include "AUD_NULLDevice.h" #include "AUD_I3DDevice.h" +#include "AUD_I3DHandle.h" #include "AUD_FileFactory.h" #include "AUD_StreamBufferFactory.h" #include "AUD_DelayFactory.h" @@ -89,7 +90,7 @@ extern "C" { typedef AUD_Reference AUD_Sound; typedef AUD_Reference AUD_Device; -typedef AUD_Handle AUD_Channel; +typedef AUD_Reference AUD_Channel; typedef AUD_Reference AUD_SEntry; #define AUD_CAPI_IMPLEMENTATION @@ -375,16 +376,16 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound) int AUD_setLoop(AUD_Channel* handle, int loops) { - if(handle) + assert(handle); + + try + { + return (*handle)->setLoopCount(loops); + } + catch(AUD_Exception&) { - try - { - return AUD_device->setLoopCount(handle, loops); - } - catch(AUD_Exception&) - { - } } + return false; } @@ -413,49 +414,58 @@ AUD_Channel* AUD_play(AUD_Sound* sound, int keep) assert(sound); try { - return AUD_device->play(*sound, keep); + AUD_Channel channel = AUD_device->play(*sound, keep); + if(!channel.isNull()) + return new AUD_Channel(channel); } catch(AUD_Exception&) { - return NULL; } + return NULL; } int AUD_pause(AUD_Channel* handle) { - return AUD_device->pause(handle); + assert(handle); + return (*handle)->pause(); } int AUD_resume(AUD_Channel* handle) { - return AUD_device->resume(handle); + assert(handle); + return (*handle)->resume(); } int AUD_stop(AUD_Channel* handle) { - if(!AUD_device.isNull()) - return AUD_device->stop(handle); - return false; + assert(handle); + int result = (*handle)->stop(); + delete handle; + return result; } int AUD_setKeep(AUD_Channel* handle, int keep) { - return AUD_device->setKeep(handle, keep); + assert(handle); + return (*handle)->setKeep(keep); } int AUD_seek(AUD_Channel* handle, float seekTo) { - return AUD_device->seek(handle, seekTo); + assert(handle); + return (*handle)->seek(seekTo); } float AUD_getPosition(AUD_Channel* handle) { - return AUD_device->getPosition(handle); + assert(handle); + return (*handle)->getPosition(); } AUD_Status AUD_getStatus(AUD_Channel* handle) { - return AUD_device->getStatus(handle); + assert(handle); + return (*handle)->getStatus(); } int AUD_setListenerLocation(const float* location) @@ -529,10 +539,13 @@ int AUD_setDistanceModel(AUD_DistanceModel model) int AUD_setSourceLocation(AUD_Channel* handle, const float* location) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { AUD_Vector3 v(location[0], location[1], location[2]); - return AUD_3ddevice->setSourceLocation(handle, v); + return h->setSourceLocation(v); } return false; @@ -540,10 +553,13 @@ int AUD_setSourceLocation(AUD_Channel* handle, const float* location) int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { AUD_Vector3 v(velocity[0], velocity[1], velocity[2]); - return AUD_3ddevice->setSourceVelocity(handle, v); + return h->setSourceVelocity(v); } return false; @@ -551,10 +567,13 @@ int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity) int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]); - return AUD_3ddevice->setSourceOrientation(handle, q); + return h->setSourceOrientation(q); } return false; @@ -562,9 +581,12 @@ int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation) int AUD_setRelative(AUD_Channel* handle, int relative) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setRelative(handle, relative); + return h->setRelative(relative); } return false; @@ -572,9 +594,12 @@ int AUD_setRelative(AUD_Channel* handle, int relative) int AUD_setVolumeMaximum(AUD_Channel* handle, float volume) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setVolumeMaximum(handle, volume); + return h->setVolumeMaximum(volume); } return false; @@ -582,9 +607,12 @@ int AUD_setVolumeMaximum(AUD_Channel* handle, float volume) int AUD_setVolumeMinimum(AUD_Channel* handle, float volume) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setVolumeMinimum(handle, volume); + return h->setVolumeMinimum(volume); } return false; @@ -592,9 +620,12 @@ int AUD_setVolumeMinimum(AUD_Channel* handle, float volume) int AUD_setDistanceMaximum(AUD_Channel* handle, float distance) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setDistanceMaximum(handle, distance); + return h->setDistanceMaximum(distance); } return false; @@ -602,9 +633,12 @@ int AUD_setDistanceMaximum(AUD_Channel* handle, float distance) int AUD_setDistanceReference(AUD_Channel* handle, float distance) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setDistanceReference(handle, distance); + return h->setDistanceReference(distance); } return false; @@ -612,9 +646,12 @@ int AUD_setDistanceReference(AUD_Channel* handle, float distance) int AUD_setAttenuation(AUD_Channel* handle, float factor) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setAttenuation(handle, factor); + return h->setAttenuation(factor); } return false; @@ -622,9 +659,12 @@ int AUD_setAttenuation(AUD_Channel* handle, float factor) int AUD_setConeAngleOuter(AUD_Channel* handle, float angle) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setConeAngleOuter(handle, angle); + return h->setConeAngleOuter(angle); } return false; @@ -632,9 +672,12 @@ int AUD_setConeAngleOuter(AUD_Channel* handle, float angle) int AUD_setConeAngleInner(AUD_Channel* handle, float angle) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setConeAngleInner(handle, angle); + return h->setConeAngleInner(angle); } return false; @@ -642,9 +685,12 @@ int AUD_setConeAngleInner(AUD_Channel* handle, float angle) int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume) { - if(AUD_3ddevice) + assert(handle); + AUD_Reference h(*handle); + + if(!h.isNull()) { - return AUD_3ddevice->setConeVolumeOuter(handle, volume); + return h->setConeVolumeOuter(volume); } return false; @@ -652,27 +698,23 @@ int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume) int AUD_setSoundVolume(AUD_Channel* handle, float volume) { - if(handle) + assert(handle); + try { - try - { - return AUD_device->setVolume(handle, volume); - } - catch(AUD_Exception&) {} + return (*handle)->setVolume(volume); } + catch(AUD_Exception&) {} return false; } int AUD_setSoundPitch(AUD_Channel* handle, float pitch) { - if(handle) + assert(handle); + try { - try - { - return AUD_device->setPitch(handle, pitch); - } - catch(AUD_Exception&) {} + return (*handle)->setPitch(pitch); } + catch(AUD_Exception&) {} return false; } @@ -695,14 +737,17 @@ AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek) try { - AUD_Channel* handle = (*device)->play(*sound); - (*device)->seek(handle, seek); - return handle; + AUD_Channel channel = (*device)->play(*sound); + if(!channel.isNull()) + { + channel->seek(seek); + return new AUD_Channel(channel); + } } catch(AUD_Exception&) { - return NULL; } + return NULL; } int AUD_setDeviceVolume(AUD_Device* device, float volume) @@ -719,22 +764,6 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume) return false; } -int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle, - float volume) -{ - if(handle) - { - assert(device); - - try - { - return (*device)->setVolume(handle, volume); - } - catch(AUD_Exception&) {} - } - return false; -} - int AUD_readDevice(AUD_Device* device, data_t* buffer, int length) { assert(device); @@ -821,7 +850,8 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high, static void pauseSound(AUD_Channel* handle) { - AUD_device->pause(handle); + assert(handle); + (*handle)->pause(); } AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds) @@ -829,16 +859,25 @@ AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds) AUD_Reference silence = new AUD_SilenceFactory; AUD_Reference limiter = new AUD_LimiterFactory(silence, 0, seconds); + AUD_device->lock(); + try { - AUD_Channel* channel = AUD_device->play(limiter); - AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle); - return channel; + AUD_Channel channel = AUD_device->play(limiter); + if(!channel.isNull()) + { + channel->setStopCallback((stopCallback)pauseSound, handle); + AUD_device->unlock(); + return new AUD_Channel(channel); + } } catch(AUD_Exception&) { - return NULL; } + + AUD_device->unlock(); + + return NULL; } AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume) @@ -966,7 +1005,8 @@ void AUD_seekSequencer(AUD_Channel* handle, float time) else #endif { - AUD_device->seek(handle, time); + assert(handle); + (*handle)->seek(time); } } @@ -979,7 +1019,8 @@ float AUD_getSequencerPosition(AUD_Channel* handle) else #endif { - return AUD_device->getPosition(handle); + assert(handle); + return (*handle)->getPosition(); } } @@ -1006,3 +1047,8 @@ AUD_Sound* AUD_copy(AUD_Sound* sound) { return new AUD_Reference(*sound); } + +void AUD_freeChannel(AUD_Channel* channel) +{ + delete channel; +} diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 3fdb9e7bca3..945faa50070 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -417,17 +417,6 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume); */ extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek); -/** - * Sets the volume of a played back sound of a read device. - * \param device The read device. - * \param handle The handle to the sound. - * \param volume The new volume, must be between 0.0 and 1.0. - * \return Whether the action succeeded. - */ -extern int AUD_setDeviceSoundVolume(AUD_Device* device, - AUD_Channel* handle, - float volume); - /** * Reads the next samples into the supplied buffer. * \param device The read device. @@ -498,6 +487,8 @@ extern int AUD_doesPlayback(void); extern AUD_Sound* AUD_copy(AUD_Sound* sound); +extern void AUD_freeChannel(AUD_Channel* channel); + #ifdef WITH_PYTHON extern PyObject* AUD_getPythonFactory(AUD_Sound* sound); diff --git a/intern/audaspace/intern/AUD_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h index df341dbb319..036f7b1fa94 100644 --- a/intern/audaspace/intern/AUD_I3DDevice.h +++ b/intern/audaspace/intern/AUD_I3DDevice.h @@ -35,8 +35,6 @@ #include "AUD_Space.h" #include "AUD_3DMath.h" -struct AUD_Handle; - /** * This class represents an output device for 3D sound. */ @@ -121,200 +119,6 @@ public: * \param model distance model. */ virtual void setDistanceModel(AUD_DistanceModel model)=0; - - - - /** - * Retrieves the location of a source. - * \param handle The handle of the source. - * \return The location. - */ - virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle)=0; - - /** - * Sets the location of a source. - * \param handle The handle of the source. - * \param location The new location. - * \return Whether the action succeeded. - */ - virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)=0; - - /** - * Retrieves the velocity of a source. - * \param handle The handle of the source. - * \return The velocity. - */ - virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle)=0; - - /** - * Sets the velocity of a source. - * \param handle The handle of the source. - * \param velocity The new velocity. - * \return Whether the action succeeded. - */ - virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)=0; - - /** - * Retrieves the orientation of a source. - * \param handle The handle of the source. - * \return The orientation as quaternion. - */ - virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle)=0; - - /** - * Sets the orientation of a source. - * \param handle The handle of the source. - * \param orientation The new orientation as quaternion. - * \return Whether the action succeeded. - */ - virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)=0; - - - /** - * Checks whether the source location, velocity and orientation are relative - * to the listener. - * \param handle The handle of the source. - * \return Whether the source is relative. - */ - virtual bool isRelative(AUD_Handle* handle)=0; - - /** - * Sets whether the source location, velocity and orientation are relative - * to the listener. - * \param handle The handle of the source. - * \param relative Whether the source is relative. - * \return Whether the action succeeded. - */ - virtual bool setRelative(AUD_Handle* handle, bool relative)=0; - - /** - * Retrieves the maximum volume of a source. - * \param handle The handle of the source. - * \return The maximum volume. - */ - virtual float getVolumeMaximum(AUD_Handle* handle)=0; - - /** - * Sets the maximum volume of a source. - * \param handle The handle of the source. - * \param volume The new maximum volume. - * \return Whether the action succeeded. - */ - virtual bool setVolumeMaximum(AUD_Handle* handle, float volume)=0; - - /** - * Retrieves the minimum volume of a source. - * \param handle The handle of the source. - * \return The minimum volume. - */ - virtual float getVolumeMinimum(AUD_Handle* handle)=0; - - /** - * Sets the minimum volume of a source. - * \param handle The handle of the source. - * \param volume The new minimum volume. - * \return Whether the action succeeded. - */ - virtual bool setVolumeMinimum(AUD_Handle* handle, float volume)=0; - - /** - * Retrieves the maximum distance of a source. - * If a source is further away from the reader than this distance, the - * volume will automatically be set to 0. - * \param handle The handle of the source. - * \return The maximum distance. - */ - virtual float getDistanceMaximum(AUD_Handle* handle)=0; - - /** - * Sets the maximum distance of a source. - * If a source is further away from the reader than this distance, the - * volume will automatically be set to 0. - * \param handle The handle of the source. - * \param distance The new maximum distance. - * \return Whether the action succeeded. - */ - virtual bool setDistanceMaximum(AUD_Handle* handle, float distance)=0; - - /** - * Retrieves the reference distance of a source. - * \param handle The handle of the source. - * \return The reference distance. - */ - virtual float getDistanceReference(AUD_Handle* handle)=0; - - /** - * Sets the reference distance of a source. - * \param handle The handle of the source. - * \param distance The new reference distance. - * \return Whether the action succeeded. - */ - virtual bool setDistanceReference(AUD_Handle* handle, float distance)=0; - - /** - * Retrieves the attenuation of a source. - * \param handle The handle of the source. - * \return The attenuation. - */ - virtual float getAttenuation(AUD_Handle* handle)=0; - - /** - * Sets the attenuation of a source. - * This value is used for distance calculation. - * \param handle The handle of the source. - * \param factor The new attenuation. - * \return Whether the action succeeded. - */ - virtual bool setAttenuation(AUD_Handle* handle, float factor)=0; - - /** - * Retrieves the outer angle of the cone of a source. - * \param handle The handle of the source. - * \return The outer angle of the cone. - */ - virtual float getConeAngleOuter(AUD_Handle* handle)=0; - - /** - * Sets the outer angle of the cone of a source. - * \param handle The handle of the source. - * \param angle The new outer angle of the cone. - * \return Whether the action succeeded. - */ - virtual bool setConeAngleOuter(AUD_Handle* handle, float angle)=0; - - /** - * Retrieves the inner angle of the cone of a source. - * \param handle The handle of the source. - * \return The inner angle of the cone. - */ - virtual float getConeAngleInner(AUD_Handle* handle)=0; - - /** - * Sets the inner angle of the cone of a source. - * \param handle The handle of the source. - * \param angle The new inner angle of the cone. - * \return Whether the action succeeded. - */ - virtual bool setConeAngleInner(AUD_Handle* handle, float angle)=0; - - /** - * Retrieves the outer volume of the cone of a source. - * The volume between inner and outer angle is interpolated between inner - * volume and this value. - * \param handle The handle of the source. - * \return The outer volume of the cone. - */ - virtual float getConeVolumeOuter(AUD_Handle* handle)=0; - - /** - * Sets the outer volume of the cone of a source. - * The volume between inner and outer angle is interpolated between inner - * volume and this value. - * \param handle The handle of the source. - * \param volume The new outer volume of the cone. - * \return Whether the action succeeded. - */ - virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume)=0; }; #endif //AUD_I3DDEVICE diff --git a/intern/audaspace/intern/AUD_I3DHandle.h b/intern/audaspace/intern/AUD_I3DHandle.h new file mode 100644 index 00000000000..259c702bf86 --- /dev/null +++ b/intern/audaspace/intern/AUD_I3DHandle.h @@ -0,0 +1,213 @@ +/* + * $Id$ + * + * ***** 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/intern/AUD_I3DHandle.h + * \ingroup audaspaceintern + */ + + +#ifndef AUD_I3DHANDLE +#define AUD_I3DHANDLE + +#include "AUD_Space.h" +#include "AUD_3DMath.h" + +/** + * This class represents an output device for 3D sound. + */ +class AUD_I3DHandle +{ +public: + /** + * Retrieves the location of a source. + * \return The location. + */ + virtual AUD_Vector3 getSourceLocation()=0; + + /** + * Sets the location of a source. + * \param location The new location. + * \return Whether the action succeeded. + */ + virtual bool setSourceLocation(const AUD_Vector3& location)=0; + + /** + * Retrieves the velocity of a source. + * \return The velocity. + */ + virtual AUD_Vector3 getSourceVelocity()=0; + + /** + * Sets the velocity of a source. + * \param velocity The new velocity. + * \return Whether the action succeeded. + */ + virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0; + + /** + * Retrieves the orientation of a source. + * \return The orientation as quaternion. + */ + virtual AUD_Quaternion getSourceOrientation()=0; + + /** + * Sets the orientation of a source. + * \param orientation The new orientation as quaternion. + * \return Whether the action succeeded. + */ + virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0; + + + /** + * Checks whether the source location, velocity and orientation are relative + * to the listener. + * \return Whether the source is relative. + */ + virtual bool isRelative()=0; + + /** + * Sets whether the source location, velocity and orientation are relative + * to the listener. + * \param relative Whether the source is relative. + * \return Whether the action succeeded. + */ + virtual bool setRelative(bool relative)=0; + + /** + * Retrieves the maximum volume of a source. + * \return The maximum volume. + */ + virtual float getVolumeMaximum()=0; + + /** + * Sets the maximum volume of a source. + * \param volume The new maximum volume. + * \return Whether the action succeeded. + */ + virtual bool setVolumeMaximum(float volume)=0; + + /** + * Retrieves the minimum volume of a source. + * \return The minimum volume. + */ + virtual float getVolumeMinimum()=0; + + /** + * Sets the minimum volume of a source. + * \param volume The new minimum volume. + * \return Whether the action succeeded. + */ + virtual bool setVolumeMinimum(float volume)=0; + + /** + * Retrieves the maximum distance of a source. + * If a source is further away from the reader than this distance, the + * volume will automatically be set to 0. + * \return The maximum distance. + */ + virtual float getDistanceMaximum()=0; + + /** + * Sets the maximum distance of a source. + * If a source is further away from the reader than this distance, the + * volume will automatically be set to 0. + * \param distance The new maximum distance. + * \return Whether the action succeeded. + */ + virtual bool setDistanceMaximum(float distance)=0; + + /** + * Retrieves the reference distance of a source. + * \return The reference distance. + */ + virtual float getDistanceReference()=0; + + /** + * Sets the reference distance of a source. + * \param distance The new reference distance. + * \return Whether the action succeeded. + */ + virtual bool setDistanceReference(float distance)=0; + + /** + * Retrieves the attenuation of a source. + * \return The attenuation. + */ + virtual float getAttenuation()=0; + + /** + * Sets the attenuation of a source. + * This value is used for distance calculation. + * \param factor The new attenuation. + * \return Whether the action succeeded. + */ + virtual bool setAttenuation(float factor)=0; + + /** + * Retrieves the outer angle of the cone of a source. + * \return The outer angle of the cone. + */ + virtual float getConeAngleOuter()=0; + + /** + * Sets the outer angle of the cone of a source. + * \param angle The new outer angle of the cone. + * \return Whether the action succeeded. + */ + virtual bool setConeAngleOuter(float angle)=0; + + /** + * Retrieves the inner angle of the cone of a source. + * \return The inner angle of the cone. + */ + virtual float getConeAngleInner()=0; + + /** + * Sets the inner angle of the cone of a source. + * \param angle The new inner angle of the cone. + * \return Whether the action succeeded. + */ + virtual bool setConeAngleInner(float angle)=0; + + /** + * Retrieves the outer volume of the cone of a source. + * The volume between inner and outer angle is interpolated between inner + * volume and this value. + * \return The outer volume of the cone. + */ + virtual float getConeVolumeOuter()=0; + + /** + * Sets the outer volume of the cone of a source. + * The volume between inner and outer angle is interpolated between inner + * volume and this value. + * \param volume The new outer volume of the cone. + * \return Whether the action succeeded. + */ + virtual bool setConeVolumeOuter(float volume)=0; +}; + +#endif //AUD_I3DHANDLE diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h index 88c9aa5e8d9..992e3347366 100644 --- a/intern/audaspace/intern/AUD_IDevice.h +++ b/intern/audaspace/intern/AUD_IDevice.h @@ -36,13 +36,7 @@ #include "AUD_Reference.h" class AUD_IFactory; class AUD_IReader; - -/// Handle structure, for inherition. -struct AUD_Handle -{ -}; - -typedef void (*stopCallback)(void*); +class AUD_IHandle; /** * This class represents an output device for sound sources. @@ -75,7 +69,7 @@ public: * \exception AUD_Exception Thrown if there's an unexpected (from the * device side) error during creation of the reader. */ - virtual AUD_Handle* play(AUD_Reference reader, bool keep = false)=0; + virtual AUD_Reference play(AUD_Reference reader, bool keep = false)=0; /** * Plays a sound source. @@ -87,87 +81,7 @@ public: * \exception AUD_Exception Thrown if there's an unexpected (from the * device side) error during creation of the reader. */ - virtual AUD_Handle* play(AUD_Reference factory, bool keep = false)=0; - - /** - * Pauses a played back sound. - * \param handle The handle returned by the play function. - * \return - * - true if the sound has been paused. - * - false if the sound isn't playing back or the handle is invalid. - */ - virtual bool pause(AUD_Handle* handle)=0; - - /** - * Resumes a paused sound. - * \param handle The handle returned by the play function. - * \return - * - true if the sound has been resumed. - * - false if the sound isn't paused or the handle is invalid. - */ - virtual bool resume(AUD_Handle* handle)=0; - - /** - * Stops a played back or paused sound. The handle is definitely invalid - * afterwards. - * \param handle The handle returned by the play function. - * \return - * - true if the sound has been stopped. - * - false if the handle is invalid. - */ - virtual bool stop(AUD_Handle* handle)=0; - - /** - * Gets the behaviour of the device for a played back sound when the sound - * doesn't return any more samples. - * \param handle The handle returned by the play function. - * \return - * - true if the source will be paused when it's end is reached - * - false if the handle won't kept or is invalid. - */ - virtual bool getKeep(AUD_Handle* handle)=0; - - /** - * Sets the behaviour of the device for a played back sound when the sound - * doesn't return any more samples. - * \param handle The handle returned by the play function. - * \param keep True when the source should be paused and not deleted. - * \return - * - true if the behaviour has been changed. - * - false if the handle is invalid. - */ - virtual bool setKeep(AUD_Handle* handle, bool keep)=0; - - /** - * Seeks in a played back sound. - * \param handle The handle returned by the play function. - * \param position The new position from where to play back, in seconds. - * \return - * - true if the handle is valid. - * - false if the handle is invalid. - * \warning Whether the seek works or not depends on the sound source. - */ - virtual bool seek(AUD_Handle* handle, float position)=0; - - /** - * Retrieves the current playback position of a sound. - * \param handle The handle returned by the play function. - * \return The playback position in seconds, or 0.0 if the handle is - * invalid. - */ - virtual float getPosition(AUD_Handle* handle)=0; - - /** - * Returns the status of a played back sound. - * \param handle The handle returned by the play function. - * \return - * - AUD_STATUS_INVALID if the sound has stopped or the handle is - *. invalid - * - AUD_STATUS_PLAYING if the sound is currently played back. - * - AUD_STATUS_PAUSED if the sound is currently paused. - * \see AUD_Status - */ - virtual AUD_Status getStatus(AUD_Handle* handle)=0; + virtual AUD_Reference play(AUD_Reference factory, bool keep = false)=0; /** * Locks the device. @@ -196,69 +110,6 @@ public: * \param volume The overall device volume. */ virtual void setVolume(float volume)=0; - - /** - * Retrieves the volume of a playing sound. - * \param handle The sound handle. - * \return The volume. - */ - virtual float getVolume(AUD_Handle* handle)=0; - - /** - * Sets the volume of a playing sound. - * \param handle The sound handle. - * \param volume The volume. - * \return - * - true if the handle is valid. - * - false if the handle is invalid. - */ - virtual bool setVolume(AUD_Handle* handle, float volume)=0; - - /** - * Retrieves the pitch of a playing sound. - * \return The pitch. - */ - virtual float getPitch(AUD_Handle* handle)=0; - - /** - * Sets the pitch of a playing sound. - * \param handle The sound handle. - * \param pitch The pitch. - * \return - * - true if the handle is valid. - * - false if the handle is invalid. - */ - virtual bool setPitch(AUD_Handle* handle, float pitch)=0; - - /** - * Retrieves the loop count of a playing sound. - * A negative value indicates infinity. - * \return The remaining loop count. - */ - virtual int getLoopCount(AUD_Handle* handle)=0; - - /** - * Sets the loop count of a playing sound. - * A negative value indicates infinity. - * \param handle The sound handle. - * \param count The new loop count. - * \return - * - true if the handle is valid. - * - false if the handle is invalid. - */ - virtual bool setLoopCount(AUD_Handle* handle, int count)=0; - - /** - * Sets the callback function that's called when the end of a playing sound - * is reached. - * \param handle The sound handle. - * \param callback The callback function. - * \param data The data that should be passed to the callback function. - * \return - * - true if the handle is valid. - * - false if the handle is invalid. - */ - virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0)=0; }; #endif //AUD_IDevice diff --git a/intern/audaspace/intern/AUD_IHandle.h b/intern/audaspace/intern/AUD_IHandle.h new file mode 100644 index 00000000000..51d8e0ca2e5 --- /dev/null +++ b/intern/audaspace/intern/AUD_IHandle.h @@ -0,0 +1,181 @@ +/* + * $Id$ + * + * ***** 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/intern/AUD_IHandle.h + * \ingroup audaspaceintern + */ + +#ifndef AUD_IHANDLE +#define AUD_IHANDLE + +//#include "AUD_Space.h" +//#include "AUD_Reference.h" + +typedef void (*stopCallback)(void*); + +/** + * This class represents a playback handles for specific devices. + */ +class AUD_IHandle +{ +public: + /** + * Destroys the device. + */ + virtual ~AUD_IHandle() {} + + /** + * Pauses a played back sound. + * \return + * - true if the sound has been paused. + * - false if the sound isn't playing back or the handle is invalid. + */ + virtual bool pause()=0; + + /** + * Resumes a paused sound. + * \return + * - true if the sound has been resumed. + * - false if the sound isn't paused or the handle is invalid. + */ + virtual bool resume()=0; + + /** + * Stops a played back or paused sound. The handle is definitely invalid + * afterwards. + * \return + * - true if the sound has been stopped. + * - false if the handle is invalid. + */ + virtual bool stop()=0; + + /** + * Gets the behaviour of the device for a played back sound when the sound + * doesn't return any more samples. + * \return + * - true if the source will be paused when it's end is reached + * - false if the handle won't kept or is invalid. + */ + virtual bool getKeep()=0; + + /** + * Sets the behaviour of the device for a played back sound when the sound + * doesn't return any more samples. + * \param keep True when the source should be paused and not deleted. + * \return + * - true if the behaviour has been changed. + * - false if the handle is invalid. + */ + virtual bool setKeep(bool keep)=0; + + /** + * Seeks in a played back sound. + * \param position The new position from where to play back, in seconds. + * \return + * - true if the handle is valid. + * - false if the handle is invalid. + * \warning Whether the seek works or not depends on the sound source. + */ + virtual bool seek(float position)=0; + + /** + * Retrieves the current playback position of a sound. + * \return The playback position in seconds, or 0.0 if the handle is + * invalid. + */ + virtual float getPosition()=0; + + /** + * Returns the status of a played back sound. + * \return + * - AUD_STATUS_INVALID if the sound has stopped or the handle is + *. invalid + * - AUD_STATUS_PLAYING if the sound is currently played back. + * - AUD_STATUS_PAUSED if the sound is currently paused. + * \see AUD_Status + */ + virtual AUD_Status getStatus()=0; + + /** + * Retrieves the volume of a playing sound. + * \return The volume. + */ + virtual float getVolume()=0; + + /** + * Sets the volume of a playing sound. + * \param volume The volume. + * \return + * - true if the handle is valid. + * - false if the handle is invalid. + */ + virtual bool setVolume(float volume)=0; + + /** + * Retrieves the pitch of a playing sound. + * \return The pitch. + */ + virtual float getPitch()=0; + + /** + * Sets the pitch of a playing sound. + * \param pitch The pitch. + * \return + * - true if the handle is valid. + * - false if the handle is invalid. + */ + virtual bool setPitch(float pitch)=0; + + /** + * Retrieves the loop count of a playing sound. + * A negative value indicates infinity. + * \return The remaining loop count. + */ + virtual int getLoopCount()=0; + + /** + * Sets the loop count of a playing sound. + * A negative value indicates infinity. + * \param count The new loop count. + * \return + * - true if the handle is valid. + * - false if the handle is invalid. + */ + virtual bool setLoopCount(int count)=0; + + /** + * Sets the callback function that's called when the end of a playing sound + * is reached. + * \param callback The callback function. + * \param data The data that should be passed to the callback function. + * \return + * - true if the handle is valid. + * - false if the handle is invalid. + */ + virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0; +}; + +#endif //AUD_IHandle diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp index 09fc4835978..6cb13111a43 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.cpp +++ b/intern/audaspace/intern/AUD_NULLDevice.cpp @@ -34,6 +34,7 @@ #include "AUD_NULLDevice.h" #include "AUD_IReader.h" #include "AUD_IFactory.h" +#include "AUD_IHandle.h" AUD_NULLDevice::AUD_NULLDevice() { @@ -48,56 +49,16 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const return specs; } -AUD_Handle* AUD_NULLDevice::play(AUD_Reference reader, bool keep) +AUD_Reference AUD_NULLDevice::play(AUD_Reference reader, bool keep) { return 0; } -AUD_Handle* AUD_NULLDevice::play(AUD_Reference factory, bool keep) +AUD_Reference AUD_NULLDevice::play(AUD_Reference factory, bool keep) { return 0; } -bool AUD_NULLDevice::pause(AUD_Handle* handle) -{ - return false; -} - -bool AUD_NULLDevice::resume(AUD_Handle* handle) -{ - return false; -} - -bool AUD_NULLDevice::stop(AUD_Handle* handle) -{ - return false; -} - -bool AUD_NULLDevice::getKeep(AUD_Handle* handle) -{ - return false; -} - -bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep) -{ - return false; -} - -bool AUD_NULLDevice::seek(AUD_Handle* handle, float position) -{ - return false; -} - -float AUD_NULLDevice::getPosition(AUD_Handle* handle) -{ - return std::numeric_limits::quiet_NaN(); -} - -AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle) -{ - return AUD_STATUS_INVALID; -} - void AUD_NULLDevice::lock() { } @@ -114,38 +75,3 @@ float AUD_NULLDevice::getVolume() const void AUD_NULLDevice::setVolume(float volume) { } - -float AUD_NULLDevice::getVolume(AUD_Handle* handle) -{ - return std::numeric_limits::quiet_NaN(); -} - -bool AUD_NULLDevice::setVolume(AUD_Handle* handle, float volume) -{ - return false; -} - -float AUD_NULLDevice::getPitch(AUD_Handle* handle) -{ - return std::numeric_limits::quiet_NaN(); -} - -bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch) -{ - return false; -} - -int AUD_NULLDevice::getLoopCount(AUD_Handle* handle) -{ - return 0; -} - -bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count) -{ - return false; -} - -bool AUD_NULLDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data) -{ - return false; -} diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h index 6a10267bbe0..69ca5b74f3b 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.h +++ b/intern/audaspace/intern/AUD_NULLDevice.h @@ -47,27 +47,12 @@ public: AUD_NULLDevice(); virtual AUD_DeviceSpecs getSpecs() const; - virtual AUD_Handle* play(AUD_Reference reader, bool keep = false); - virtual AUD_Handle* play(AUD_Reference factory, bool keep = false); - virtual bool pause(AUD_Handle* handle); - virtual bool resume(AUD_Handle* handle); - virtual bool stop(AUD_Handle* handle); - virtual bool getKeep(AUD_Handle* handle); - virtual bool setKeep(AUD_Handle* handle, bool keep); - virtual bool seek(AUD_Handle* handle, float position); - virtual float getPosition(AUD_Handle* handle); - virtual AUD_Status getStatus(AUD_Handle* handle); + virtual AUD_Reference play(AUD_Reference reader, bool keep = false); + virtual AUD_Reference play(AUD_Reference factory, bool keep = false); virtual void lock(); virtual void unlock(); virtual float getVolume() const; virtual void setVolume(float volume); - virtual float getVolume(AUD_Handle* handle); - virtual bool setVolume(AUD_Handle* handle, float volume); - virtual float getPitch(AUD_Handle* handle); - virtual bool setPitch(AUD_Handle* handle, float pitch); - virtual int getLoopCount(AUD_Handle* handle); - virtual bool setLoopCount(AUD_Handle* handle, int count); - virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0); }; #endif //AUD_NULLDEVICE diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h index 22abb29bdbb..4cc5c51d24d 100644 --- a/intern/audaspace/intern/AUD_Reference.h +++ b/intern/audaspace/intern/AUD_Reference.h @@ -28,10 +28,41 @@ * \ingroup audaspaceintern */ - #ifndef AUD_REFERENCE #define AUD_REFERENCE +#include + +class AUD_ReferenceHandler +{ +private: + static std::map m_references; + +public: + static inline void incref(void* reference) + { + std::map::iterator result = m_references.find(reference); + if(result != m_references.end()) + { + m_references[reference]++; + } + else + { + m_references[reference] = 1; + } + } + + static inline bool decref(void* reference) + { + if(!--m_references[reference]) + { + m_references.erase(reference); + return true; + } + return false; + } +}; + template /** * This class provides reference counting functionality. @@ -41,8 +72,7 @@ class AUD_Reference private: /// The reference. T* m_reference; - /// The reference counter. - int* m_refcount; + void* m_original; public: /** * Creates a new reference counter. @@ -50,9 +80,8 @@ public: */ AUD_Reference(T* reference = 0) { - m_reference = reference; - m_refcount = new int; - *m_refcount = 1; + m_original = m_reference = reference; + AUD_ReferenceHandler::incref(reference); } /** @@ -61,9 +90,16 @@ public: */ AUD_Reference(const AUD_Reference& ref) { - m_reference = ref.m_reference; - m_refcount = ref.m_refcount; - (*m_refcount)++; + m_original = m_reference = ref.m_reference; + AUD_ReferenceHandler::incref(m_reference); + } + + template + explicit AUD_Reference(const AUD_Reference& ref) + { + m_original = ref.get(); + m_reference = dynamic_cast(ref.get()); + AUD_ReferenceHandler::incref(m_original); } /** @@ -72,12 +108,8 @@ public: */ ~AUD_Reference() { - (*m_refcount)--; - if(*m_refcount == 0) - { + if(AUD_ReferenceHandler::decref(m_original)) delete m_reference; - delete m_refcount; - } } /** @@ -89,16 +121,12 @@ public: if(&ref == this) return *this; - (*m_refcount)--; - if(*m_refcount == 0) - { + if(AUD_ReferenceHandler::decref(m_original)) delete m_reference; - delete m_refcount; - } + m_original = ref.m_original; m_reference = ref.m_reference; - m_refcount = ref.m_refcount; - (*m_refcount)++; + AUD_ReferenceHandler::incref(m_original); return *this; } @@ -106,7 +134,7 @@ public: /** * Returns whether the reference is NULL. */ - bool isNull() const + inline bool isNull() const { return m_reference == 0; } @@ -114,15 +142,20 @@ public: /** * Returns the reference. */ - T* get() const + inline T* get() const { return m_reference; } + inline void* getOriginal() const + { + return m_original; + } + /** * Returns the reference. */ - T& operator*() const + inline T& operator*() const { return *m_reference; } @@ -130,44 +163,22 @@ public: /** * Returns the reference. */ - T* operator->() const + inline T* operator->() const { return m_reference; } - - template - explicit AUD_Reference(U* reference, int* refcount) - { - m_reference = dynamic_cast(reference); - if(m_reference) - { - m_refcount = refcount; - (*m_refcount)++; - } - else - { - m_refcount = new int; - *m_refcount = 1; - } - } - - template - AUD_Reference convert() - { - return AUD_Reference(m_reference, m_refcount); - } }; template -bool operator==(const AUD_Reference& a, const AUD_Reference& b) +inline bool operator==(const AUD_Reference& a, const AUD_Reference& b) { - return a.get() == b.get(); + return a.getOriginal() == b.getOriginal(); } template -bool operator!=(const AUD_Reference& a, const AUD_Reference& b) +inline bool operator!=(const AUD_Reference& a, const AUD_Reference& b) { - return a.get() == b.get(); + return a.getOriginal() != b.getOriginal(); } #endif // AUD_REFERENCE diff --git a/intern/audaspace/intern/AUD_ReferenceHandler.cpp b/intern/audaspace/intern/AUD_ReferenceHandler.cpp new file mode 100644 index 00000000000..cfc3c9441a8 --- /dev/null +++ b/intern/audaspace/intern/AUD_ReferenceHandler.cpp @@ -0,0 +1,33 @@ +/* + * $Id$ + * + * ***** 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/intern/AUD_Reference.cpp + * \ingroup audaspaceintern + */ + +#include "AUD_Reference.h" + +std::map AUD_ReferenceHandler::m_references; diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp index 47d5243c04e..1787dea0ebb 100644 --- a/intern/audaspace/intern/AUD_SequencerFactory.cpp +++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp @@ -108,7 +108,7 @@ AUD_Reference AUD_SequencerFactory::createReader() m_volume); m_readers.push_front(reader); - return reader.convert(); + return AUD_Reference(reader); } void AUD_SequencerFactory::removeReader(AUD_Reference reader) diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index f522772fc61..8ca735e9ad9 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -37,29 +37,202 @@ #include #include -/// Saves the data for playback. -struct AUD_SoftwareHandle : AUD_Handle +typedef std::list >::iterator AUD_HandleIterator; + +AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference reader, bool keep) : + m_reader(reader), m_keep(keep), m_volume(1.0f), m_loopcount(0), + m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device) +{ +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause() +{ + if(m_status) + { + m_device->lock(); + + if(m_status == AUD_STATUS_PLAYING) + { + m_device->m_playingSounds.remove(this); + m_device->m_pausedSounds.push_back(this); + + if(m_device->m_playingSounds.empty()) + m_device->playing(m_device->m_playback = false); + m_status = AUD_STATUS_PAUSED; + m_device->unlock(); + + return true; + } + + m_device->unlock(); + } + + return false; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume() +{ + if(m_status) + { + m_device->lock(); + + if(m_status == AUD_STATUS_PAUSED) + { + m_device->m_pausedSounds.remove(this); + m_device->m_playingSounds.push_back(this); + + if(!m_device->m_playback) + m_device->playing(m_device->m_playback = true); + m_status = AUD_STATUS_PLAYING; + m_device->unlock(); + return true; + } + + m_device->unlock(); + } + + return false; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop() +{ + if(!m_status) + return false; + + m_device->lock(); + + if(m_status == AUD_STATUS_PLAYING) + { + m_device->m_playingSounds.remove(this); + + if(m_device->m_playingSounds.empty()) + m_device->playing(m_device->m_playback = false); + } + else + m_device->m_pausedSounds.remove(this); + + m_device->unlock(); + m_status = AUD_STATUS_INVALID; + return true; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep() +{ + if(m_status) + return m_keep; + + return false; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep) +{ + if(!m_status) + return false; + + m_device->lock(); + + m_keep = keep; + + m_device->unlock(); + + return true; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position) { - /// The reader source. - AUD_Reference reader; + if(!m_status) + return false; + + m_device->lock(); + + m_reader->seek((int)(position * m_reader->getSpecs().rate)); + + m_device->unlock(); + + return true; +} + +float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition() +{ + if(!m_status) + return 0.0f; + + m_device->lock(); + + float position = m_reader->getPosition() / (float)m_device->m_specs.rate; + + m_device->unlock(); + + return position; +} + +AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus() +{ + return m_status; +} + +float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume() +{ + return m_volume; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume) +{ + if(!m_status) + return false; + m_volume = volume; + return true; +} + +float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch() +{ + return std::numeric_limits::quiet_NaN(); +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch) +{ + return false; +} + +int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount() +{ + if(!m_status) + return 0; + return m_loopcount; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count) +{ + if(!m_status) + return false; + m_loopcount = count; + return true; +} + +bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data) +{ + if(!m_status) + return false; + + m_device->lock(); + + m_stop = callback; + m_stop_data = data; + + m_device->unlock(); + + return true; +} + + + + - /// Whether to keep the source if end of it is reached. - bool keep; - /// The volume of the source. - float volume; - /// The loop count of the source. - int loopcount; - /// The stop callback. - stopCallback stop; - /// Stop callback data. - void* stop_data; -}; -typedef std::list::iterator AUD_HandleIterator; void AUD_SoftwareDevice::create() { @@ -81,23 +254,11 @@ void AUD_SoftwareDevice::destroy() if(m_playback) playing(m_playback = false); - AUD_SoftwareHandle* handle; - - // delete all playing sounds while(!m_playingSounds.empty()) - { - handle = m_playingSounds.front(); - m_playingSounds.pop_front(); - delete handle; - } + m_playingSounds.front()->stop(); - // delete all paused sounds while(!m_pausedSounds.empty()) - { - handle = m_pausedSounds.front(); - m_pausedSounds.pop_front(); - delete handle; - } + m_pausedSounds.front()->stop(); pthread_mutex_destroy(&m_mutex); } @@ -109,11 +270,11 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) lock(); { - AUD_SoftwareHandle* sound; + AUD_Reference sound; int len; int pos; bool eos; - std::list stopSounds; + std::list > stopSounds; sample_t* buf = m_buffer.getBuffer(); m_mixer->clear(length); @@ -131,39 +292,38 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) pos = 0; len = length; - sound->reader->read(len, eos, buf); + sound->m_reader->read(len, eos, buf); // in case of looping - while(pos + len < length && sound->loopcount && eos) + while(pos + len < length && sound->m_loopcount && eos) { - m_mixer->mix(buf, pos, len, sound->volume); + m_mixer->mix(buf, pos, len, sound->m_volume); pos += len; - if(sound->loopcount > 0) - sound->loopcount--; + if(sound->m_loopcount > 0) + sound->m_loopcount--; - sound->reader->seek(0); + sound->m_reader->seek(0); len = length - pos; - sound->reader->read(len, eos, buf); + sound->m_reader->read(len, eos, buf); // prevent endless loop if(!len) break; } - m_mixer->mix(buf, pos, len, sound->volume); - pos += len; + m_mixer->mix(buf, pos, len, sound->m_volume); // in case the end of the sound is reached - if(eos && !sound->loopcount) + if(eos && !sound->m_loopcount) { - if(sound->stop) - sound->stop(sound->stop_data); + if(sound->m_stop) + sound->m_stop(sound->m_stop_data); - if(sound->keep) - pause(sound); + if(sound->m_keep) + sound->pause(); else stopSounds.push_back(sound); } @@ -177,32 +337,19 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) { sound = stopSounds.front(); stopSounds.pop_front(); - stop(sound); + sound->stop(); } } unlock(); } -bool AUD_SoftwareDevice::isValid(AUD_Handle* handle) -{ - for(AUD_HandleIterator i = m_playingSounds.begin(); - i != m_playingSounds.end(); i++) - if(*i == handle) - return true; - for(AUD_HandleIterator i = m_pausedSounds.begin(); - i != m_pausedSounds.end(); i++) - if(*i == handle) - return true; - return false; -} - AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const { return m_specs; } -AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference reader, bool keep) +AUD_Reference AUD_SoftwareDevice::play(AUD_Reference reader, bool keep) { // prepare the reader reader = m_mixer->prepare(reader); @@ -210,13 +357,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference reader, bool kee return NULL; // play sound - AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; - sound->keep = keep; - sound->reader = reader; - sound->volume = 1.0f; - sound->loopcount = 0; - sound->stop = NULL; - sound->stop_data = NULL; + AUD_Reference sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, keep); lock(); m_playingSounds.push_back(sound); @@ -225,204 +366,14 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference reader, bool kee playing(m_playback = true); unlock(); - return sound; + return AUD_Reference(sound); } -AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference factory, bool keep) +AUD_Reference AUD_SoftwareDevice::play(AUD_Reference factory, bool keep) { return play(factory->createReader(), keep); } -bool AUD_SoftwareDevice::pause(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - // only songs that are played can be paused - for(AUD_HandleIterator i = m_playingSounds.begin(); - i != m_playingSounds.end(); i++) - { - if(*i == handle) - { - m_pausedSounds.push_back(*i); - m_playingSounds.erase(i); - if(m_playingSounds.empty()) - playing(m_playback = false); - result = true; - break; - } - } - - unlock(); - - return result; -} - -bool AUD_SoftwareDevice::resume(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - // only songs that are paused can be resumed - for(AUD_HandleIterator i = m_pausedSounds.begin(); - i != m_pausedSounds.end(); i++) - { - if(*i == handle) - { - m_playingSounds.push_back(*i); - m_pausedSounds.erase(i); - if(!m_playback) - playing(m_playback = true); - result = true; - break; - } - } - - unlock(); - - return result; -} - -bool AUD_SoftwareDevice::stop(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - for(AUD_HandleIterator i = m_playingSounds.begin(); - i != m_playingSounds.end(); i++) - { - if(*i == handle) - { - delete *i; - m_playingSounds.erase(i); - if(m_playingSounds.empty()) - playing(m_playback = false); - result = true; - break; - } - } - if(!result) - { - for(AUD_HandleIterator i = m_pausedSounds.begin(); - i != m_pausedSounds.end(); i++) - { - if(*i == handle) - { - delete *i; - m_pausedSounds.erase(i); - result = true; - break; - } - } - } - - unlock(); - - return result; -} - -bool AUD_SoftwareDevice::getKeep(AUD_Handle* handle) -{ - bool result = false; - - lock(); - - if(isValid(handle)) - result = ((AUD_SoftwareHandle*)handle)->keep; - - unlock(); - - return result; -} - -bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep) -{ - bool result = false; - - lock(); - - if(isValid(handle)) - { - ((AUD_SoftwareHandle*)handle)->keep = keep; - result = true; - } - - unlock(); - - return result; -} - -bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position) -{ - lock(); - - bool result = false; - - if(isValid(handle)) - { - AUD_Reference reader = ((AUD_SoftwareHandle*)handle)->reader; - reader->seek((int)(position * reader->getSpecs().rate)); - result = true; - } - - unlock(); - - return result; -} - -float AUD_SoftwareDevice::getPosition(AUD_Handle* handle) -{ - lock(); - - float position = 0.0f; - - if(isValid(handle)) - { - AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle; - position = h->reader->getPosition() / (float)m_specs.rate; - } - - unlock(); - - return position; -} - -AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle) -{ - AUD_Status status = AUD_STATUS_INVALID; - - lock(); - - for(AUD_HandleIterator i = m_playingSounds.begin(); - i != m_playingSounds.end(); i++) - { - if(*i == handle) - { - status = AUD_STATUS_PLAYING; - break; - } - } - if(status == AUD_STATUS_INVALID) - { - for(AUD_HandleIterator i = m_pausedSounds.begin(); - i != m_pausedSounds.end(); i++) - { - if(*i == handle) - { - status = AUD_STATUS_PAUSED; - break; - } - } - } - - unlock(); - - return status; -} - void AUD_SoftwareDevice::lock() { pthread_mutex_lock(&m_mutex); @@ -442,67 +393,3 @@ void AUD_SoftwareDevice::setVolume(float volume) { m_volume = volume; } - -float AUD_SoftwareDevice::getVolume(AUD_Handle* handle) -{ - lock(); - float result = std::numeric_limits::quiet_NaN(); - if(isValid(handle)) - result = ((AUD_SoftwareHandle*)handle)->volume; - unlock(); - return result; -} - -bool AUD_SoftwareDevice::setVolume(AUD_Handle* handle, float volume) -{ - lock(); - bool result = isValid(handle); - if(result) - ((AUD_SoftwareHandle*)handle)->volume = volume; - unlock(); - return result; -} - -float AUD_SoftwareDevice::getPitch(AUD_Handle* handle) -{ - return std::numeric_limits::quiet_NaN(); -} - -bool AUD_SoftwareDevice::setPitch(AUD_Handle* handle, float pitch) -{ - return false; -} - -int AUD_SoftwareDevice::getLoopCount(AUD_Handle* handle) -{ - lock(); - int result = 0; - if(isValid(handle)) - result = ((AUD_SoftwareHandle*)handle)->loopcount; - unlock(); - return result; -} - -bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int count) -{ - lock(); - bool result = isValid(handle); - if(result) - ((AUD_SoftwareHandle*)handle)->loopcount = count; - unlock(); - return result; -} - -bool AUD_SoftwareDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data) -{ - lock(); - bool result = isValid(handle); - if(result) - { - AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle; - h->stop = callback; - h->stop_data = data; - } - unlock(); - return result; -} diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h index 6518afe6737..45df48d12be 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.h +++ b/intern/audaspace/intern/AUD_SoftwareDevice.h @@ -33,9 +33,9 @@ #define AUD_SOFTWAREDEVICE #include "AUD_IDevice.h" +#include "AUD_IHandle.h" #include "AUD_Mixer.h" #include "AUD_Buffer.h" -struct AUD_SoftwareHandle; #include #include @@ -51,6 +51,56 @@ struct AUD_SoftwareHandle; class AUD_SoftwareDevice : public AUD_IDevice { protected: + /// Saves the data for playback. + class AUD_SoftwareHandle : public AUD_IHandle + { + public: + /// The reader source. + AUD_Reference m_reader; + + /// Whether to keep the source if end of it is reached. + bool m_keep; + + /// The volume of the source. + float m_volume; + + /// The loop count of the source. + int m_loopcount; + + /// The stop callback. + stopCallback m_stop; + + /// Stop callback data. + void* m_stop_data; + + /// Current status of the handle + AUD_Status m_status; + + /// Own device. + AUD_SoftwareDevice* m_device; + + public: + + AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference reader, bool keep); + + virtual ~AUD_SoftwareHandle() {} + virtual bool pause(); + virtual bool resume(); + virtual bool stop(); + virtual bool getKeep(); + virtual bool setKeep(bool keep); + virtual bool seek(float position); + virtual float getPosition(); + virtual AUD_Status getStatus(); + virtual float getVolume(); + virtual bool setVolume(float volume); + virtual float getPitch(); + virtual bool setPitch(float pitch); + virtual int getLoopCount(); + virtual bool setLoopCount(int count); + virtual bool setStopCallback(stopCallback callback = 0, void* data = 0); + }; + /** * The specification of the device. */ @@ -93,12 +143,12 @@ private: /** * The list of sounds that are currently playing. */ - std::list m_playingSounds; + std::list > m_playingSounds; /** * The list of sounds that are currently paused. */ - std::list m_pausedSounds; + std::list > m_pausedSounds; /** * Whether there is currently playback. @@ -115,36 +165,14 @@ private: */ float m_volume; - /** - * Checks if a handle is valid. - * \param handle The handle to check. - * \return Whether the handle is valid. - */ - bool isValid(AUD_Handle* handle); - public: virtual AUD_DeviceSpecs getSpecs() const; - virtual AUD_Handle* play(AUD_Reference reader, bool keep = false); - virtual AUD_Handle* play(AUD_Reference factory, bool keep = false); - virtual bool pause(AUD_Handle* handle); - virtual bool resume(AUD_Handle* handle); - virtual bool stop(AUD_Handle* handle); - virtual bool getKeep(AUD_Handle* handle); - virtual bool setKeep(AUD_Handle* handle, bool keep); - virtual bool seek(AUD_Handle* handle, float position); - virtual float getPosition(AUD_Handle* handle); - virtual AUD_Status getStatus(AUD_Handle* handle); + virtual AUD_Reference play(AUD_Reference reader, bool keep = false); + virtual AUD_Reference play(AUD_Reference factory, bool keep = false); virtual void lock(); virtual void unlock(); virtual float getVolume() const; virtual void setVolume(float volume); - virtual float getVolume(AUD_Handle* handle); - virtual bool setVolume(AUD_Handle* handle, float volume); - virtual float getPitch(AUD_Handle* handle); - virtual bool setPitch(AUD_Handle* handle, float pitch); - virtual int getLoopCount(AUD_Handle* handle); - virtual bool setLoopCount(AUD_Handle* handle, int count); - virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL); }; #endif //AUD_SOFTWAREDEVICE -- cgit v1.2.3