diff --git a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
index daf68b8e2..0c5a6f4e3 100644
--- a/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
+++ b/aegisub/build/aegisub_vs2008/aegisub_vs2008.vcproj
@@ -493,6 +493,14 @@
RelativePath="..\..\src\audio_provider_hd.h"
>
+
+
+
+
diff --git a/aegisub/src/Makefile b/aegisub/src/Makefile
index 47d2fde7b..4b4bf9dee 100644
--- a/aegisub/src/Makefile
+++ b/aegisub/src/Makefile
@@ -145,6 +145,7 @@ SRC += \
audio_provider.cpp \
audio_provider_convert.cpp \
audio_provider_hd.cpp \
+ audio_provider_lock.cpp \
audio_provider_pcm.cpp \
audio_provider_ram.cpp \
audio_renderer.cpp \
diff --git a/aegisub/src/audio_provider.cpp b/aegisub/src/audio_provider.cpp
index e1c45cc4d..7175fe439 100644
--- a/aegisub/src/audio_provider.cpp
+++ b/aegisub/src/audio_provider.cpp
@@ -50,6 +50,7 @@
#include "audio_provider_ffmpegsource.h"
#endif
#include "audio_provider_hd.h"
+#include "audio_provider_lock.h"
#include "audio_provider_pcm.h"
#include "audio_provider_ram.h"
#include "compat.h"
@@ -152,7 +153,7 @@ AudioProvider *AudioProviderFactory::GetProvider(wxString const& filename, int c
// Change provider to RAM/HD cache if needed
if (cache == -1) cache = OPT_GET("Audio/Cache/Type")->GetInt();
if (!cache || !needsCache) {
- return provider;
+ return new LockAudioProvider(provider);
}
DialogProgress progress(wxGetApp().frame, _("Load audio"));
diff --git a/aegisub/src/audio_provider_lock.cpp b/aegisub/src/audio_provider_lock.cpp
new file mode 100644
index 000000000..35e5e259d
--- /dev/null
+++ b/aegisub/src/audio_provider_lock.cpp
@@ -0,0 +1,36 @@
+// Copyright (c) 2012, Thomas Goyne
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+// $Id$
+
+/// @file audio_provider_lock.cpp
+/// @brief An audio provider adapter for un-threadsafe audio providers
+/// @ingroup audio_input
+
+#include "config.h"
+
+#include "audio_provider_lock.h"
+
+LockAudioProvider::LockAudioProvider(AudioProvider *source) : source(source) {
+ channels = source->GetChannels();
+ num_samples = source->GetNumSamples();
+ sample_rate = source->GetSampleRate();
+ bytes_per_sample = source->GetBytesPerSample();
+ float_samples = source->AreSamplesFloat();
+}
+
+void LockAudioProvider::GetAudio(void *buf, int64_t start, int64_t count) const {
+ wxMutexLocker lock(mutex);
+ source->GetAudio(buf, start, count);
+}
diff --git a/aegisub/src/audio_provider_lock.h b/aegisub/src/audio_provider_lock.h
new file mode 100644
index 000000000..e00db08d0
--- /dev/null
+++ b/aegisub/src/audio_provider_lock.h
@@ -0,0 +1,37 @@
+// Copyright (c) 2012, Thomas Goyne
+//
+// Permission to use, copy, modify, and distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+//
+// $Id$
+
+/// @file audio_provider_lock.h
+/// @brief An audio provider adapter for un-threadsafe audio providers
+/// @ingroup audio_input
+
+#include "include/aegisub/audio_provider.h"
+
+#include
+
+#ifndef AGI_PRE
+#include
+#endif
+
+class LockAudioProvider : public AudioProvider {
+ agi::scoped_ptr source;
+ mutable wxMutex mutex;
+
+public:
+ LockAudioProvider(AudioProvider *source);
+ void GetAudio(void *buf, int64_t start, int64_t count) const;
+ bool AreSamplesNativeEndian() const { return source->AreSamplesNativeEndian(); }
+};