diff options
author | Joerg Mueller <nexyon@gmail.com> | 2010-07-31 14:03:08 +0400 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2010-07-31 14:03:08 +0400 |
commit | 5c9cf81cf98c99e52064b0cd45be3b2eaba9e40c (patch) | |
tree | 463240a84d34a3debf5bba9c326827fb436db703 /intern | |
parent | 61c9e46aad2cf679331341c7d38f10bec19203a9 (diff) |
Audaspace:
* Fixed some compiler warnings
* Implemented device looping
* Note: Scrubbing in the sequencer is broken atm
Diffstat (limited to 'intern')
-rw-r--r-- | intern/audaspace/OpenAL/AUD_OpenALDevice.cpp | 37 | ||||
-rw-r--r-- | intern/audaspace/OpenAL/AUD_OpenALDevice.h | 2 | ||||
-rw-r--r-- | intern/audaspace/Python/AUD_PyAPI.cpp | 23 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.cpp | 13 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_C-API.h | 3 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_IDevice.h | 18 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_NULLDevice.cpp | 10 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_NULLDevice.h | 2 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_SoftwareDevice.cpp | 145 | ||||
-rw-r--r-- | intern/audaspace/intern/AUD_SoftwareDevice.h | 7 |
10 files changed, 188 insertions, 72 deletions
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp index 6d1f9a5527b..88e48ff20ba 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp @@ -65,6 +65,9 @@ struct AUD_OpenALHandle : AUD_Handle /// Whether the stream doesn't return any more data. bool data_end; + + /// The loop count of the source. + int loopcount; }; struct AUD_OpenALBufferedFactory @@ -156,6 +159,18 @@ void AUD_OpenALDevice::updateStreams() length = m_buffersize; sound->reader->read(length, buffer); + // looping necessary? + if(length == 0 && sound->loopcount) + { + if(sound->loopcount > 0) + sound->loopcount--; + + sound->reader->seek(0); + + length = m_buffersize; + sound->reader->read(length, buffer); + } + // read nothing? if(length == 0) { @@ -507,6 +522,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) sound->current = -1; sound->isBuffered = true; sound->data_end = true; + sound->loopcount = 0; alcSuspendContext(m_context); @@ -578,6 +594,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep) sound->current = 0; sound->isBuffered = false; sound->data_end = false; + sound->loopcount = 0; valid &= getFormat(sound->format, specs.specs); @@ -975,6 +992,26 @@ bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch) return result; } +int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle) +{ + lock(); + int result = 0; + if(isValid(handle)) + result = ((AUD_OpenALHandle*)handle)->loopcount; + unlock(); + return result; +} + +bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count) +{ + lock(); + bool result = isValid(handle); + if(result) + ((AUD_OpenALHandle*)handle)->loopcount = count; + unlock(); + return result; +} + /* AUD_XXX Temorary disabled bool AUD_OpenALDevice::bufferFactory(void *value) diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h index cba031f25f9..37a5b886882 100644 --- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h +++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h @@ -158,6 +158,8 @@ public: 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 AUD_Vector3 getListenerLocation() const; virtual void setListenerLocation(const AUD_Vector3& location); diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp index 13617283a1e..dff7334e577 100644 --- a/intern/audaspace/Python/AUD_PyAPI.cpp +++ b/intern/audaspace/Python/AUD_PyAPI.cpp @@ -1228,8 +1228,7 @@ Handle_get_loop_count(Handle *self, void* nothing) try { - // AUD_XXX will come soon; return Py_BuildValue("f", device->device->getPitch(self->handle)); - AUD_THROW(AUD_ERROR_FACTORY); + return Py_BuildValue("i", device->device->getLoopCount(self->handle)); } catch(AUD_Exception&) { @@ -1250,14 +1249,8 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing) try { - /* AUD_XXX Doesn't work atm, will come back - AUD_Message message; - message.loopcount = loops; - message.type = AUD_MSG_LOOP; - if(device->device->sendMessage(self->handle, message)) - { + if(device->device->setLoopCount(self->handle, loops)) return 0; - }*/ } catch(AUD_Exception&) { @@ -1302,7 +1295,7 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing) float x, y, z; if(!PyArg_Parse(args, "(fff)", &x, &y, &z)) - return NULL; + return -1; Device* dev = (Device*)self->device; @@ -1361,7 +1354,7 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing) float x, y, z; if(!PyArg_Parse(args, "(fff)", &x, &y, &z)) - return NULL; + return -1; Device* dev = (Device*)self->device; @@ -1420,7 +1413,7 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing) float w, x, y, z; if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z)) - return NULL; + return -1; Device* dev = (Device*)self->device; @@ -2368,7 +2361,7 @@ Device_set_listener_location(Device *self, PyObject* args, void* nothing) float x, y, z; if(!PyArg_Parse(args, "(fff)", &x, &y, &z)) - return NULL; + return -1; try { @@ -2423,7 +2416,7 @@ Device_set_listener_velocity(Device *self, PyObject* args, void* nothing) float x, y, z; if(!PyArg_Parse(args, "(fff)", &x, &y, &z)) - return NULL; + return -1; try { @@ -2478,7 +2471,7 @@ Device_set_listener_orientation(Device *self, PyObject* args, void* nothing) float w, x, y, z; if(!PyArg_Parse(args, "(ffff)", &w, &x, &y, &z)) - return NULL; + return -1; try { diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp index 1f9e76c4535..5e0364c618c 100644 --- a/intern/audaspace/intern/AUD_C-API.cpp +++ b/intern/audaspace/intern/AUD_C-API.cpp @@ -344,24 +344,17 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound) } } -int AUD_setLoop(AUD_Channel* handle, int loops, float time) +int AUD_setLoop(AUD_Channel* handle, int loops) { if(handle) { - /* AUD_XXX Doesn't work atm, will come back - - AUD_Message message; - message.type = AUD_MSG_LOOP; - message.loopcount = loops; - message.time = time; - try { - return AUD_device->sendMessage(handle, message); + return AUD_device->setLoopCount(handle, loops); } catch(AUD_Exception&) { - }*/ + } } return false; } diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h index 6b7f7c1a2ea..f73e658d5b1 100644 --- a/intern/audaspace/intern/AUD_C-API.h +++ b/intern/audaspace/intern/AUD_C-API.h @@ -165,10 +165,9 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound); * Sets a remaining loop count of a looping sound that currently plays. * \param handle The playback handle. * \param loops The count of remaining loops, -1 for infinity. - * \param time The time after which playback should stop, -1 for infinity. * \return Whether the handle is valid. */ -extern int AUD_setLoop(AUD_Channel* handle, int loops, float time); +extern int AUD_setLoop(AUD_Channel* handle, int loops); /** * Rectifies a sound. diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h index 4170e274574..bb2d65cde74 100644 --- a/intern/audaspace/intern/AUD_IDevice.h +++ b/intern/audaspace/intern/AUD_IDevice.h @@ -207,6 +207,24 @@ public: * - 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; }; #endif //AUD_IDevice diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp index aea2bf4ba62..ec9e02ef28f 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.cpp +++ b/intern/audaspace/intern/AUD_NULLDevice.cpp @@ -123,3 +123,13 @@ 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; +} diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h index 0f070da0863..c6261854803 100644 --- a/intern/audaspace/intern/AUD_NULLDevice.h +++ b/intern/audaspace/intern/AUD_NULLDevice.h @@ -57,6 +57,8 @@ public: 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); }; #endif //AUD_NULLDEVICE diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp index 8ef34f6659b..1f063e636f1 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp +++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp @@ -42,14 +42,15 @@ struct AUD_SoftwareHandle : AUD_Handle /// The volume of the source. float volume; + + /// The loop count of the source. + int loopcount; }; typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator; void AUD_SoftwareDevice::create() { - m_playingSounds = new std::list<AUD_SoftwareHandle*>(); - m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); m_playback = false; m_volume = 1.0f; m_mixer = new AUD_DefaultMixer(m_specs); @@ -70,23 +71,25 @@ void AUD_SoftwareDevice::destroy() delete m_mixer; + AUD_SoftwareHandle* handle; + // delete all playing sounds - while(m_playingSounds->begin() != m_playingSounds->end()) + while(!m_playingSounds.empty()) { - delete (*(m_playingSounds->begin()))->reader; - delete *(m_playingSounds->begin()); - m_playingSounds->erase(m_playingSounds->begin()); + handle = m_playingSounds.front(); + m_playingSounds.pop_front(); + delete handle->reader; + delete handle; } - delete m_playingSounds; // delete all paused sounds - while(m_pausedSounds->begin() != m_pausedSounds->end()) + while(!m_pausedSounds.empty()) { - delete (*(m_pausedSounds->begin()))->reader; - delete *(m_pausedSounds->begin()); - m_pausedSounds->erase(m_pausedSounds->begin()); + handle = m_pausedSounds.front(); + m_pausedSounds.pop_front(); + delete handle->reader; + delete handle; } - delete m_pausedSounds; pthread_mutex_destroy(&m_mutex); } @@ -98,12 +101,16 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) { AUD_SoftwareHandle* sound; int len; + int pos; sample_t* buf; std::list<AUD_SoftwareHandle*> stopSounds; + std::list<AUD_Buffer*> tempBufs; + AUD_Buffer* tempbuf; + int samplesize = AUD_SAMPLE_SIZE(m_specs); // for all sounds - AUD_HandleIterator it = m_playingSounds->begin(); - while(it != m_playingSounds->end()) + AUD_HandleIterator it = m_playingSounds.begin(); + while(it != m_playingSounds.end()) { sound = *it; // increment the iterator to make sure it's valid, @@ -111,13 +118,38 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) ++it; // get the buffer from the source + pos = 0; len = length; sound->reader->read(len, buf); - m_mixer->add(buf, 0, len, sound->volume); + // in case of looping + while(pos + len < length && sound->loopcount) + { + tempbuf = new AUD_Buffer(len * samplesize); + memcpy(tempbuf->getBuffer(), buf, len * samplesize); + tempBufs.push_back(tempbuf); + m_mixer->add(tempbuf->getBuffer(), pos, len, sound->volume); + + pos += len; + + if(sound->loopcount > 0) + sound->loopcount--; + + sound->reader->seek(0); + + len = length - pos; + sound->reader->read(len, buf); + + // prevent endless loop + if(!len) + break; + } + + m_mixer->add(buf, pos, len, sound->volume); + pos += len; // in case the end of the sound is reached - if(len < length) + if(pos < length) { if(sound->keep) pause(sound); @@ -129,12 +161,20 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) // superpose m_mixer->superpose(buffer, length, m_volume); + // cleanup while(!stopSounds.empty()) { sound = stopSounds.front(); stopSounds.pop_front(); stop(sound); } + + while(!tempBufs.empty()) + { + tempbuf = tempBufs.front(); + tempBufs.pop_front(); + delete tempbuf; + } } unlock(); @@ -142,12 +182,12 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length) bool AUD_SoftwareDevice::isValid(AUD_Handle* handle) { - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) + 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++) + for(AUD_HandleIterator i = m_pausedSounds.begin(); + i != m_pausedSounds.end(); i++) if(*i == handle) return true; return false; @@ -170,16 +210,15 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep) if(reader == NULL) return NULL; - AUD_Specs rs = reader->getSpecs(); - // play sound AUD_SoftwareHandle* sound = new AUD_SoftwareHandle; sound->keep = keep; sound->reader = reader; sound->volume = 1.0f; + sound->loopcount = 0; lock(); - m_playingSounds->push_back(sound); + m_playingSounds.push_back(sound); if(!m_playback) playing(m_playback = true); @@ -195,14 +234,14 @@ bool AUD_SoftwareDevice::pause(AUD_Handle* handle) lock(); // only songs that are played can be paused - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) + 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()) + m_pausedSounds.push_back(*i); + m_playingSounds.erase(i); + if(m_playingSounds.empty()) playing(m_playback = false); result = true; break; @@ -221,13 +260,13 @@ bool AUD_SoftwareDevice::resume(AUD_Handle* handle) lock(); // only songs that are paused can be resumed - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + for(AUD_HandleIterator i = m_pausedSounds.begin(); + i != m_pausedSounds.end(); i++) { if(*i == handle) { - m_playingSounds->push_back(*i); - m_pausedSounds->erase(i); + m_playingSounds.push_back(*i); + m_pausedSounds.erase(i); if(!m_playback) playing(m_playback = true); result = true; @@ -246,15 +285,15 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle) lock(); - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) + for(AUD_HandleIterator i = m_playingSounds.begin(); + i != m_playingSounds.end(); i++) { if(*i == handle) { delete (*i)->reader; delete *i; - m_playingSounds->erase(i); - if(m_playingSounds->empty()) + m_playingSounds.erase(i); + if(m_playingSounds.empty()) playing(m_playback = false); result = true; break; @@ -262,14 +301,14 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle) } if(!result) { - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + for(AUD_HandleIterator i = m_pausedSounds.begin(); + i != m_pausedSounds.end(); i++) { if(*i == handle) { delete (*i)->reader; delete *i; - m_pausedSounds->erase(i); + m_pausedSounds.erase(i); result = true; break; } @@ -353,8 +392,8 @@ AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle) lock(); - for(AUD_HandleIterator i = m_playingSounds->begin(); - i != m_playingSounds->end(); i++) + for(AUD_HandleIterator i = m_playingSounds.begin(); + i != m_playingSounds.end(); i++) { if(*i == handle) { @@ -364,8 +403,8 @@ AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle) } if(status == AUD_STATUS_INVALID) { - for(AUD_HandleIterator i = m_pausedSounds->begin(); - i != m_pausedSounds->end(); i++) + for(AUD_HandleIterator i = m_pausedSounds.begin(); + i != m_pausedSounds.end(); i++) { if(*i == handle) { @@ -429,3 +468,23 @@ 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; +} diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h index cd819d638a9..c14b5356c6b 100644 --- a/intern/audaspace/intern/AUD_SoftwareDevice.h +++ b/intern/audaspace/intern/AUD_SoftwareDevice.h @@ -29,6 +29,7 @@ #include "AUD_IDevice.h" struct AUD_SoftwareHandle; class AUD_Mixer; +class AUD_Buffer; #include <list> #include <pthread.h> @@ -81,12 +82,12 @@ private: /** * The list of sounds that are currently playing. */ - std::list<AUD_SoftwareHandle*>* m_playingSounds; + std::list<AUD_SoftwareHandle*> m_playingSounds; /** * The list of sounds that are currently paused. */ - std::list<AUD_SoftwareHandle*>* m_pausedSounds; + std::list<AUD_SoftwareHandle*> m_pausedSounds; /** * Whether there is currently playback. @@ -129,6 +130,8 @@ public: 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); }; #endif //AUD_SOFTWAREDEVICE |