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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2011-08-07 15:54:58 +0400
committerJoerg Mueller <nexyon@gmail.com>2011-08-07 15:54:58 +0400
commit2d884fc035d403d43c7a18e3e61cd56ccdfbec2b (patch)
tree2548dcfbb52370618d1f255f57e65bcf1cbb49a4 /intern
parent4370099fb0bc1bdd21f78b14a91a1d8eb76e1bc1 (diff)
3D Audio GSoC:
* Pepper depends on ffmpeg 0.7.1 or higher now, windows and mac build systems set to ffmpeg-0.8 * Fixed orientation retrieval in OpenAL device code. * Added stopAll() method to AUD_IDevice (also for Python) and call it on BGE exit * Changed BGE to use audaspace via native C++ instead over the C API. * Made AUD_SequencerFactory and AUD_SequencerEntry thread safe. * Changed sound caching into a flag which fixes problems on file loading, especially with undo. * Removed unused parameter from sound_mute_scene_sound * Fixed bug: changing FPS didn't update the sequencer sound positions. * Fixed bug: Properties of sequencer strips weren't set correctly. * Minor warning fixes.
Diffstat (limited to 'intern')
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp24
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h9
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp22
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp1
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp6
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp10
-rw-r--r--intern/audaspace/intern/AUD_C-API.h8
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h5
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp4
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h1
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.cpp75
-rw-r--r--intern/audaspace/intern/AUD_SequencerEntry.h16
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp51
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.h15
-rw-r--r--intern/audaspace/intern/AUD_SequencerHandle.cpp5
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp4
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp13
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h1
19 files changed, 264 insertions, 8 deletions
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index 40fc8a55f03..d5b365fa62f 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -469,8 +469,7 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& ve
AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
{
- // AUD_XXX not implemented yet
- return AUD_Quaternion(0, 0, 0, 0);
+ return m_orientation;
}
bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
@@ -491,6 +490,8 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaterni
m_device->unlock();
+ m_orientation = orientation;
+
return true;
}
@@ -1284,6 +1285,21 @@ AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> fa
return play(factory->createReader(), keep);
}
+void AUD_OpenALDevice::stopAll()
+{
+ lock();
+ alcSuspendContext(m_context);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ alcProcessContext(m_context);
+ unlock();
+}
+
void AUD_OpenALDevice::lock()
{
pthread_mutex_lock(&m_mutex);
@@ -1454,8 +1470,7 @@ void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
{
- // AUD_XXX not implemented yet
- return AUD_Quaternion(0, 0, 0, 0);
+ return m_orientation;
}
void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
@@ -1474,6 +1489,7 @@ void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
direction[5] = 2 * (orientation.w() * orientation.x() +
orientation.y() * orientation.z());
alListenerfv(AL_ORIENTATION, direction);
+ m_orientation = orientation;
}
float AUD_OpenALDevice::getSpeedOfSound() const
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 3ba761bad5a..3e8b05d79e2 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -89,6 +89,9 @@ private:
/// Stop callback data.
void* m_stop_data;
+ /// Orientation.
+ AUD_Quaternion m_orientation;
+
/// Current status of the handle
AUD_Status m_status;
@@ -205,6 +208,11 @@ private:
AUD_Buffer m_buffer;
/**
+ * Orientation.
+ */
+ AUD_Quaternion m_orientation;
+
+ /**
* Starts the streaming thread.
*/
void start(bool join = true);
@@ -243,6 +251,7 @@ public:
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index 94e02576ccc..928c67c5196 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -2245,6 +2245,25 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
return (PyObject *)handle;
}
+PyDoc_STRVAR(M_aud_Device_stopAll_doc,
+ "stopAll()\n\n"
+ "Stops all playing and paused sounds.");
+
+static PyObject *
+Device_stopAll(Device *self)
+{
+ try
+ {
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->stopAll();
+ Py_RETURN_NONE;
+ }
+ catch(AUD_Exception& e)
+ {
+ PyErr_SetString(AUDError, e.str);
+ return NULL;
+ }
+}
+
PyDoc_STRVAR(M_aud_Device_lock_doc,
"lock()\n\n"
"Locks the device so that it's guaranteed, that no samples are "
@@ -2295,6 +2314,9 @@ static PyMethodDef Device_methods[] = {
{"play", (PyCFunction)Device_play, METH_VARARGS | METH_KEYWORDS,
M_aud_Device_play_doc
},
+ {"stopAll", (PyCFunction)Device_stopAll, METH_NOARGS,
+ M_aud_Device_stopAll_doc
+ },
{"lock", (PyCFunction)Device_lock, METH_NOARGS,
M_aud_Device_lock_doc
},
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index a7534dbed32..b980e1d98e0 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -39,6 +39,7 @@
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
+#include <libavformat/avio.h>
#include "ffmpeg_compat.h"
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
index f2b7acc5ea2..197671ee37a 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGWriter.cpp
@@ -40,6 +40,7 @@ extern "C" {
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavformat/avio.h>
+#include "ffmpeg_compat.h"
}
static const char* context_error = "AUD_FFMPEGWriter: Couldn't allocate context.";
@@ -127,7 +128,8 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
m_codecCtx->bit_rate = bitrate;
m_codecCtx->sample_rate = int(m_specs.rate);
m_codecCtx->channels = m_specs.channels;
- m_codecCtx->time_base = (AVRational){1, m_codecCtx->sample_rate};
+ m_codecCtx->time_base.num = 1;
+ m_codecCtx->time_base.den = m_codecCtx->sample_rate;
switch(m_specs.format)
{
@@ -180,7 +182,7 @@ AUD_FFMPEGWriter::AUD_FFMPEGWriter(std::string filename, AUD_DeviceSpecs specs,
try
{
- if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_WRONLY))
+ if(avio_open(&m_formatCtx->pb, filename.c_str(), AVIO_FLAG_WRITE))
AUD_THROW(AUD_ERROR_FILE, file_error);
avformat_write_header(m_formatCtx, NULL);
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 467ee736b7f..e5c966fdcae 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -1174,3 +1174,13 @@ const char* AUD_mixdown(AUD_Sound* sound, unsigned int start, unsigned int lengt
return e.str;
}
}
+
+AUD_Reference<AUD_IDevice> AUD_getDevice()
+{
+ return AUD_device;
+}
+
+AUD_I3DDevice* AUD_get3DDevice()
+{
+ return AUD_3ddevice;
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index abcbd215074..7689d1b06b5 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -528,6 +528,14 @@ extern AUD_Sound* AUD_getPythonSound(PyObject* sound);
#ifdef __cplusplus
}
+
+#include "AUD_Reference.h"
+class AUD_IDevice;
+class AUD_I3DDevice;
+
+AUD_Reference<AUD_IDevice> AUD_getDevice();
+
+AUD_I3DDevice* AUD_get3DDevice();
#endif
#endif //AUD_CAPI
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index 992e3347366..86d695ef764 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -84,6 +84,11 @@ public:
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
+ * Stops all playing sounds.
+ */
+ virtual void stopAll()=0;
+
+ /**
* Locks the device.
* Used to make sure that between lock and unlock, no buffers are read, so
* that it is possible to start, resume, pause, stop or seek several
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
index c1a9de7f724..7d652268af3 100644
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ b/intern/audaspace/intern/AUD_IFactory.h
@@ -34,7 +34,7 @@
#include "AUD_Space.h"
#include "AUD_Reference.h"
-class AUD_IReader;
+#include "AUD_IReader.h"
/**
* This class represents a type of sound source and saves the necessary values
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index dddb53fd00c..b7d658aafe6 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -139,6 +139,10 @@ AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> fact
return new AUD_NULLHandle();
}
+void AUD_NULLDevice::stopAll()
+{
+}
+
void AUD_NULLDevice::lock()
{
}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index 59ef200f934..5274d68ebf6 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -76,6 +76,7 @@ public:
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.cpp b/intern/audaspace/intern/AUD_SequencerEntry.cpp
index 54993befb41..c5112f9f3de 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.cpp
+++ b/intern/audaspace/intern/AUD_SequencerEntry.cpp
@@ -62,19 +62,48 @@ AUD_SequencerEntry::AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float
float f = 1;
m_volume.write(&f);
m_pitch.write(&f);
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&m_mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+}
+
+AUD_SequencerEntry::~AUD_SequencerEntry()
+{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void AUD_SequencerEntry::lock()
+{
+ pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_SequencerEntry::unlock()
+{
+ pthread_mutex_unlock(&m_mutex);
}
void AUD_SequencerEntry::setSound(AUD_Reference<AUD_IFactory> sound)
{
+ lock();
+
if(m_sound.get() != sound.get())
{
m_sound = sound;
m_sound_status++;
}
+
+ unlock();
}
void AUD_SequencerEntry::move(float begin, float end, float skip)
{
+ lock();
+
if(m_begin != begin || m_skip != skip || m_end != end)
{
m_begin = begin;
@@ -82,11 +111,17 @@ void AUD_SequencerEntry::move(float begin, float end, float skip)
m_end = end;
m_pos_status++;
}
+
+ unlock();
}
void AUD_SequencerEntry::mute(bool mute)
{
+ lock();
+
m_muted = mute;
+
+ unlock();
}
int AUD_SequencerEntry::getID() const
@@ -117,6 +152,8 @@ void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float dis
float distance_reference, float attenuation, float cone_angle_outer,
float cone_angle_inner, float cone_volume_outer)
{
+ lock();
+
if(volume_max != m_volume_max)
{
m_volume_max = volume_max;
@@ -164,6 +201,8 @@ void AUD_SequencerEntry::updateAll(float volume_max, float volume_min, float dis
m_cone_volume_outer = cone_volume_outer;
m_status++;
}
+
+ unlock();
}
bool AUD_SequencerEntry::isRelative()
@@ -173,11 +212,15 @@ bool AUD_SequencerEntry::isRelative()
void AUD_SequencerEntry::setRelative(bool relative)
{
+ lock();
+
if(m_relative != relative)
{
m_relative = relative;
m_status++;
}
+
+ unlock();
}
float AUD_SequencerEntry::getVolumeMaximum()
@@ -187,8 +230,12 @@ float AUD_SequencerEntry::getVolumeMaximum()
void AUD_SequencerEntry::setVolumeMaximum(float volume)
{
+ lock();
+
m_volume_max = volume;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getVolumeMinimum()
@@ -198,8 +245,12 @@ float AUD_SequencerEntry::getVolumeMinimum()
void AUD_SequencerEntry::setVolumeMinimum(float volume)
{
+ lock();
+
m_volume_min = volume;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getDistanceMaximum()
@@ -209,8 +260,12 @@ float AUD_SequencerEntry::getDistanceMaximum()
void AUD_SequencerEntry::setDistanceMaximum(float distance)
{
+ lock();
+
m_distance_max = distance;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getDistanceReference()
@@ -220,8 +275,12 @@ float AUD_SequencerEntry::getDistanceReference()
void AUD_SequencerEntry::setDistanceReference(float distance)
{
+ lock();
+
m_distance_reference = distance;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getAttenuation()
@@ -231,8 +290,12 @@ float AUD_SequencerEntry::getAttenuation()
void AUD_SequencerEntry::setAttenuation(float factor)
{
+ lock();
+
m_attenuation = factor;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getConeAngleOuter()
@@ -242,8 +305,12 @@ float AUD_SequencerEntry::getConeAngleOuter()
void AUD_SequencerEntry::setConeAngleOuter(float angle)
{
+ lock();
+
m_cone_angle_outer = angle;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getConeAngleInner()
@@ -253,8 +320,12 @@ float AUD_SequencerEntry::getConeAngleInner()
void AUD_SequencerEntry::setConeAngleInner(float angle)
{
+ lock();
+
m_cone_angle_inner = angle;
m_status++;
+
+ unlock();
}
float AUD_SequencerEntry::getConeVolumeOuter()
@@ -264,6 +335,10 @@ float AUD_SequencerEntry::getConeVolumeOuter()
void AUD_SequencerEntry::setConeVolumeOuter(float volume)
{
+ lock();
+
m_cone_volume_outer = volume;
m_status++;
+
+ unlock();
}
diff --git a/intern/audaspace/intern/AUD_SequencerEntry.h b/intern/audaspace/intern/AUD_SequencerEntry.h
index 5c68b4c7ab2..71e3f8b8908 100644
--- a/intern/audaspace/intern/AUD_SequencerEntry.h
+++ b/intern/audaspace/intern/AUD_SequencerEntry.h
@@ -36,6 +36,8 @@
#include "AUD_AnimateableProperty.h"
#include "AUD_IFactory.h"
+#include <pthread.h>
+
class AUD_SequencerEntry
{
friend class AUD_SequencerHandle;
@@ -60,6 +62,9 @@ private:
float m_cone_angle_inner;
float m_cone_volume_outer;
+ /// The mutex for locking.
+ pthread_mutex_t m_mutex;
+
AUD_AnimateableProperty m_volume;
AUD_AnimateableProperty m_panning;
AUD_AnimateableProperty m_pitch;
@@ -68,6 +73,17 @@ private:
public:
AUD_SequencerEntry(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip, int id);
+ virtual ~AUD_SequencerEntry();
+
+ /**
+ * Locks the entry.
+ */
+ void lock();
+
+ /**
+ * Unlocks the previously locked entry.
+ */
+ void unlock();
void setSound(AUD_Reference<AUD_IFactory> sound);
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
index dd856dc0701..7481717c286 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp
@@ -50,26 +50,57 @@ AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, float fps, bool mute
m_orientation.write(q.get());
float f = 1;
m_volume.write(&f);
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&m_mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
}
AUD_SequencerFactory::~AUD_SequencerFactory()
{
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void AUD_SequencerFactory::lock()
+{
+ pthread_mutex_lock(&m_mutex);
+}
+
+void AUD_SequencerFactory::unlock()
+{
+ pthread_mutex_unlock(&m_mutex);
}
void AUD_SequencerFactory::setSpecs(AUD_Specs specs)
{
+ lock();
+
m_specs = specs;
m_status++;
+
+ unlock();
}
void AUD_SequencerFactory::setFPS(float fps)
{
+ lock();
+
m_fps = fps;
+
+ unlock();
}
void AUD_SequencerFactory::mute(bool muted)
{
+ lock();
+
m_muted = muted;
+
+ unlock();
}
bool AUD_SequencerFactory::getMute() const
@@ -84,8 +115,12 @@ float AUD_SequencerFactory::getSpeedOfSound() const
void AUD_SequencerFactory::setSpeedOfSound(float speed)
{
+ lock();
+
m_speed_of_sound = speed;
m_status++;
+
+ unlock();
}
float AUD_SequencerFactory::getDopplerFactor() const
@@ -95,8 +130,12 @@ float AUD_SequencerFactory::getDopplerFactor() const
void AUD_SequencerFactory::setDopplerFactor(float factor)
{
+ lock();
+
m_doppler_factor = factor;
m_status++;
+
+ unlock();
}
AUD_DistanceModel AUD_SequencerFactory::getDistanceModel() const
@@ -106,8 +145,12 @@ AUD_DistanceModel AUD_SequencerFactory::getDistanceModel() const
void AUD_SequencerFactory::setDistanceModel(AUD_DistanceModel model)
{
+ lock();
+
m_distance_model = model;
m_status++;
+
+ unlock();
}
AUD_AnimateableProperty* AUD_SequencerFactory::getAnimProperty(AUD_AnimateablePropertyType type)
@@ -127,18 +170,26 @@ AUD_AnimateableProperty* AUD_SequencerFactory::getAnimProperty(AUD_AnimateablePr
AUD_Reference<AUD_SequencerEntry> AUD_SequencerFactory::add(AUD_Reference<AUD_IFactory> sound, float begin, float end, float skip)
{
+ lock();
+
AUD_Reference<AUD_SequencerEntry> entry = new AUD_SequencerEntry(sound, begin, end, skip, m_id++);
m_entries.push_front(entry);
m_entry_status++;
+ unlock();
+
return entry;
}
void AUD_SequencerFactory::remove(AUD_Reference<AUD_SequencerEntry> entry)
{
+ lock();
+
m_entries.remove(entry);
m_entry_status++;
+
+ unlock();
}
AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/intern/audaspace/intern/AUD_SequencerFactory.h
index 2ad7c18733b..434f23e4c0c 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/intern/audaspace/intern/AUD_SequencerFactory.h
@@ -36,10 +36,10 @@
#include "AUD_AnimateableProperty.h"
#include <list>
+#include <pthread.h>
class AUD_SequencerEntry;
-// AUD_XXX TODO: This class is not thread safe yet!
/**
* This factory creates a resampling reader that does simple linear resampling.
*/
@@ -68,6 +68,9 @@ private:
AUD_AnimateableProperty m_location;
AUD_AnimateableProperty m_orientation;
+ /// The mutex for locking.
+ pthread_mutex_t m_mutex;
+
// hide copy constructor and operator=
AUD_SequencerFactory(const AUD_SequencerFactory&);
AUD_SequencerFactory& operator=(const AUD_SequencerFactory&);
@@ -76,6 +79,16 @@ public:
AUD_SequencerFactory(AUD_Specs specs, float fps, bool muted);
~AUD_SequencerFactory();
+ /**
+ * Locks the factory.
+ */
+ void lock();
+
+ /**
+ * Unlocks the previously locked factory.
+ */
+ void unlock();
+
void setSpecs(AUD_Specs specs);
void setFPS(float fps);
diff --git a/intern/audaspace/intern/AUD_SequencerHandle.cpp b/intern/audaspace/intern/AUD_SequencerHandle.cpp
index 006dafe2026..978439d3174 100644
--- a/intern/audaspace/intern/AUD_SequencerHandle.cpp
+++ b/intern/audaspace/intern/AUD_SequencerHandle.cpp
@@ -70,6 +70,7 @@ void AUD_SequencerHandle::update(float position, float frame)
{
if(!m_handle.isNull())
{
+ m_entry->lock();
if(position >= m_entry->m_end && m_entry->m_end >= 0)
m_handle->pause();
else if(position >= m_entry->m_begin)
@@ -133,6 +134,7 @@ void AUD_SequencerHandle::update(float position, float frame)
if(m_entry->m_muted)
m_handle->setVolume(0);
+ m_entry->unlock();
}
}
@@ -140,9 +142,11 @@ void AUD_SequencerHandle::seek(float position)
{
if(!m_handle.isNull())
{
+ m_entry->lock();
if(position >= m_entry->m_end && m_entry->m_end >= 0)
{
m_handle->pause();
+ m_entry->unlock();
return;
}
@@ -155,5 +159,6 @@ void AUD_SequencerHandle::seek(float position)
m_handle->pause();
else
m_handle->resume();
+ m_entry->unlock();
}
}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
index e01da34651f..c404a88d4f7 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ b/intern/audaspace/intern/AUD_SequencerReader.cpp
@@ -75,6 +75,8 @@ AUD_Specs AUD_SequencerReader::getSpecs() const
void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
{
+ m_factory->lock();
+
if(m_factory->m_status != m_status)
{
m_device.changeSpecs(m_factory->m_specs);
@@ -179,6 +181,8 @@ void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
time += float(len) / float(specs.rate);
}
+ m_factory->unlock();
+
m_position += length;
eos = false;
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index bc041eb97e3..4ffb95ec2a1 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -838,6 +838,19 @@ AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory>
return play(factory->createReader(), keep);
}
+void AUD_SoftwareDevice::stopAll()
+{
+ lock();
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ unlock();
+}
+
void AUD_SoftwareDevice::lock()
{
pthread_mutex_lock(&m_mutex);
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index da317834d2c..d2e2bf634ac 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -287,6 +287,7 @@ public:
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
+ virtual void stopAll();
virtual void lock();
virtual void unlock();
virtual float getVolume() const;