Page Menu
Home
Search
Configure Global Search
Log In
Files
F32972
audio_sleep2.patch
Public
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Authored By
Tom Edwards (artfunkel)
Nov 25 2013, 10:48 PM
Size
8 KB
Subscribers
None
audio_sleep2.patch
View Options
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 21a4255..7f9ad3c 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -90,6 +90,8 @@ set(SRC
intern/AUD_ConverterFunctions.h
intern/AUD_ConverterReader.cpp
intern/AUD_ConverterReader.h
+ intern/AUD_DeferredDevice.cpp
+ intern/AUD_DeferredDevice.h
intern/AUD_FileFactory.cpp
intern/AUD_FileFactory.h
intern/AUD_FileWriter.cpp
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 42fd87e..49841c3 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -43,6 +43,7 @@
#include <sstream>
#include "AUD_NULLDevice.h"
+#include "AUD_DeferredDevice.h"
#include "AUD_I3DDevice.h"
#include "AUD_I3DHandle.h"
#include "AUD_FileFactory.h"
@@ -138,12 +139,12 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
break;
#ifdef WITH_SDL
case AUD_SDL_DEVICE:
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_DeferredDevice([specs, buffersize]() { return new AUD_SDLDevice(specs, buffersize); }));
break;
#endif
#ifdef WITH_OPENAL
case AUD_OPENAL_DEVICE:
- dev = boost::shared_ptr<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
+ dev = boost::shared_ptr<AUD_IDevice>(new AUD_Deferred3DDevice([specs, buffersize]() { return new AUD_OpenALDevice(specs, buffersize); }));
break;
#endif
#ifdef WITH_JACK
diff --git a/intern/audaspace/intern/AUD_DeferredDevice.cpp b/intern/audaspace/intern/AUD_DeferredDevice.cpp
new file mode 100644
index 0000000..059fbe3
--- /dev/null
+++ b/intern/audaspace/intern/AUD_DeferredDevice.cpp
@@ -0,0 +1,127 @@
+#include "AUD_DeferredDevice.h"
+#include "AUD_MutexLock.h"
+
+using namespace boost;
+
+/**********************************************************************/
+/************************* AUD_DeferredDevice *************************/
+/**********************************************************************/
+
+AUD_DeferredDevice::AUD_DeferredDevice(std::function<AUD_IDevice* ()> creator)
+{
+ createInner = creator;
+ m_inner = nullptr;
+
+ pthread_attr_init(&m_threadAttr);
+ pthread_attr_setdetachstate(&m_threadAttr, PTHREAD_CREATE_JOINABLE);
+
+ getInner();
+}
+
+AUD_DeferredDevice::~AUD_DeferredDevice()
+{
+ delete m_inner;
+ pthread_join(m_thread, nullptr);
+ pthread_attr_destroy(&m_threadAttr);
+}
+
+shared_ptr<AUD_IHandle> AUD_DeferredDevice::registerHandle(shared_ptr<AUD_IHandle> handle)
+{
+ m_handles.push_back(weak_ptr<AUD_IHandle>(handle));
+ return handle;
+}
+
+void* AUD_DeferredDevice::runThread(void *dev_in)
+{
+ AUD_DeferredDevice *device = static_cast<AUD_DeferredDevice*>(dev_in);
+ char destroy = 0;
+ while (1)
+ {
+ detail::Sleep(100);
+ destroy++;
+ {
+ AUD_MutexLock lock(*device);
+ for (AUD_HandleIterator it = device->m_handles.begin(); it != device->m_handles.end(); it++)
+ {
+ while (it->expired())
+ it = device->m_handles.erase(it);
+
+ switch (it->lock()->getStatus())
+ {
+ case AUD_STATUS_PLAYING:
+ destroy = 0;
+ break;
+ }
+ if (destroy == 0) break;
+ }
+ }
+ if (destroy >= 2)
+ {
+ device->destroyInner();
+ return nullptr;
+ }
+ }
+}
+void AUD_DeferredDevice::destroyInner()
+{
+ if (!m_inner) return;
+
+ printf("DESTROY\n");
+ innerSpecs = m_inner->getSpecs();
+ innerVolume = m_inner->getVolume();
+ pthread_join(m_thread, nullptr);
+
+ // causes memory allocation crashes with Blender nowhere on the call stack!
+ /*for (AUD_HandleIterator it = m_handles.begin(); it != m_handles.end(); it++)
+ {
+ if (shared_ptr<AUD_IHandle> handle = it->lock())
+ handle.reset();
+ }*/
+
+ delete m_inner;
+ m_inner = nullptr;
+}
+
+AUD_IDevice *AUD_DeferredDevice::getInner()
+{
+ if (!m_inner)
+ {
+ m_inner = createInner();
+ assert(m_inner != nullptr);
+ pthread_create(&m_thread, &m_threadAttr, runThread, this);
+ }
+ return m_inner;
+}
+
+/***********************************************************************/
+/*********************** AUD_Deferred3DDevice **************************/
+/***********************************************************************/
+
+AUD_Deferred3DDevice::AUD_Deferred3DDevice(std::function<AUD_I3DDevice* ()> creator)
+: AUD_DeferredDevice([creator]() { return dynamic_cast<AUD_IDevice*>(creator()); })
+{
+ m_inner = nullptr;
+}
+
+AUD_I3DDevice *AUD_Deferred3DDevice::getInner()
+{
+ m_inner = dynamic_cast<AUD_I3DDevice*>(AUD_DeferredDevice::getInner());
+ return m_inner;
+}
+
+void AUD_Deferred3DDevice::destroyInner()
+{
+ if (!AUD_DeferredDevice::m_inner) return;
+
+ getInner(); // make sure *our* m_inner is assigned
+
+ innerListenerLocation = m_inner->getListenerLocation();
+ innerListenerVelocity = m_inner->getListenerVelocity();
+ innerListenerOrientation = m_inner->getListenerOrientation();
+ innerSpeedOfSound = m_inner->getSpeedOfSound();
+ innerDopplerFactor = m_inner->getDopplerFactor();
+ innerDistanceModel = m_inner->getDistanceModel();
+
+ AUD_DeferredDevice::destroyInner();
+ m_inner = nullptr;
+}
\ No newline at end of file
diff --git a/intern/audaspace/intern/AUD_DeferredDevice.h b/intern/audaspace/intern/AUD_DeferredDevice.h
new file mode 100644
index 0000000..4abb182
--- /dev/null
+++ b/intern/audaspace/intern/AUD_DeferredDevice.h
@@ -0,0 +1,92 @@
+#ifndef __AUD_DEFERREDDEVICE_H__
+#define __AUD_DEFERREDDEVICE_H__
+
+#include "AUD_IDevice.h"
+#include "AUD_I3DDevice.h"
+
+#include <list>
+#include <pthread.h>
+#include <boost/noncopyable.hpp>
+#include <boost/weak_ptr.hpp>
+
+// FIXME: AUD_IHandle objects created by inner devices are not aware of this layer, and occasionlly try to access destroyed devices.
+
+class AUD_DeferredDevice : public AUD_IDevice, private boost::noncopyable
+{
+private:
+
+ std::function<AUD_IDevice *()> createInner;
+
+ std::list<boost::weak_ptr<AUD_IHandle>> m_handles;
+ boost::shared_ptr<AUD_IHandle> registerHandle(boost::shared_ptr<AUD_IHandle> handle);
+
+ pthread_t m_thread;
+ pthread_attr_t m_threadAttr;
+ static void* runThread(void*);
+
+ AUD_DeviceSpecs innerSpecs;
+ float innerVolume;
+
+protected:
+ AUD_IDevice *m_inner;
+ AUD_IDevice *getInner();
+ virtual void destroyInner();
+ typedef std::list<boost::weak_ptr<AUD_IHandle> >::iterator AUD_HandleIterator;
+
+public:
+ AUD_DeferredDevice(std::function<AUD_IDevice* ()> creator);
+ ~AUD_DeferredDevice();
+
+ AUD_DeviceSpecs getSpecs() const { return m_inner ? m_inner->getSpecs() : innerSpecs; }
+
+ boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IReader> reader, bool keep = false) { return registerHandle(getInner()->play(reader, keep)); }
+ boost::shared_ptr<AUD_IHandle> play(boost::shared_ptr<AUD_IFactory> factory, bool keep = false) { return registerHandle(getInner()->play(factory, keep)); }
+
+ void stopAll() { getInner()->stopAll(); }
+
+ void lock() { getInner()->lock(); }
+ void unlock() { getInner()->unlock(); }
+
+ float getVolume() const { return m_inner ? m_inner->getVolume() : innerVolume; }
+ void setVolume(float volume) { return getInner()->setVolume(volume); }
+};
+
+class AUD_Deferred3DDevice : public AUD_DeferredDevice, public AUD_I3DDevice
+{
+private:
+ AUD_Vector3 innerListenerLocation;
+ AUD_Vector3 innerListenerVelocity;
+ AUD_Quaternion innerListenerOrientation;
+ float innerSpeedOfSound;
+ float innerDopplerFactor;
+ AUD_DistanceModel innerDistanceModel;
+
+protected:
+ AUD_I3DDevice *m_inner;
+
+ AUD_I3DDevice *getInner();
+ virtual void destroyInner();
+
+public:
+ AUD_Deferred3DDevice(std::function<AUD_I3DDevice* ()> creator);
+
+ AUD_Vector3 getListenerLocation() const { return m_inner ? m_inner->getListenerLocation() : innerListenerLocation; }
+ void setListenerLocation(const AUD_Vector3& location) { getInner()->setListenerLocation(location); }
+
+ AUD_Vector3 getListenerVelocity() const { return m_inner ? m_inner->getListenerVelocity() : innerListenerVelocity; }
+ void setListenerVelocity(const AUD_Vector3& velocity) { getInner()->setListenerVelocity(velocity); }
+
+ AUD_Quaternion getListenerOrientation() const { return m_inner ? m_inner->getListenerOrientation() : innerListenerOrientation; }
+ void setListenerOrientation(const AUD_Quaternion& orientation) { setListenerOrientation(orientation); }
+
+ float getSpeedOfSound() const { return m_inner ? m_inner->getSpeedOfSound() : innerSpeedOfSound; }
+ void setSpeedOfSound(float speed) { getInner()->setSpeedOfSound(speed); }
+
+ float getDopplerFactor() const { return m_inner ? m_inner->getDopplerFactor() : innerDopplerFactor; }
+ void setDopplerFactor(float factor) { getInner()->setDopplerFactor(factor); }
+
+ AUD_DistanceModel getDistanceModel() const { return m_inner ? m_inner->getDistanceModel() : innerDistanceModel; }
+ void setDistanceModel(AUD_DistanceModel model) { getInner()->setDistanceModel(model); }
+};
+
+#endif //__AUD_DEFERREDDEVICE_H__
\ No newline at end of file
File Metadata
Details
Mime Type
text/x-diff
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
ef/97/1479bcb68d26e015081957b6b090
Event Timeline
Log In to Comment