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
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2010-08-02 22:22:34 +0400
committerJoerg Mueller <nexyon@gmail.com>2010-08-02 22:22:34 +0400
commit86fc34b924e281ee9273c44c024434bdd6e3f7f2 (patch)
tree44b3a423eaa1643ca6ad3519249bf2c15586e472 /intern/audaspace
parentbce3a49e2e8fb9d344ca86769f5ffe0c7189024f (diff)
Audaspace:
* Added a stopCallback function that is called when the end of a sound is reached. * Fixed the scrubbing not working. * Minor SoundActuator cleanup.
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp35
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h1
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp27
-rw-r--r--intern/audaspace/intern/AUD_C-API.h8
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h14
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp5
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h1
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp37
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h50
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.cpp74
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.h71
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp23
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h1
13 files changed, 342 insertions, 5 deletions
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index 88e48ff20ba..f69a2e5d805 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -68,6 +68,12 @@ struct AUD_OpenALHandle : AUD_Handle
/// The loop count of the source.
int loopcount;
+
+ /// The stop callback.
+ stopCallback stop;
+
+ /// Stop callback data.
+ void* stop_data;
};
struct AUD_OpenALBufferedFactory
@@ -131,13 +137,9 @@ void AUD_OpenALDevice::updateStreams()
{
// for all sounds
- AUD_HandleIterator it = m_playingSounds->begin();
- while(it != m_playingSounds->end())
+ for(AUD_HandleIterator it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
{
sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
// is it a streamed sound?
if(!sound->isBuffered)
@@ -227,12 +229,21 @@ void AUD_OpenALDevice::updateStreams()
// if it really stopped
if(sound->data_end)
{
+ if(sound->stop)
+ sound->stop(sound->stop_data);
+
+ // increment the iterator to the next value,
+ // because the sound gets deleted in the list here.
+ ++it;
// pause or
if(sound->keep)
pause(sound);
// stop
else
stop(sound);
+ // decrement again, so that we get the next sound in the
+ // next loop run
+ --it;
}
// continue playing
else
@@ -1012,6 +1023,20 @@ bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
return result;
}
+bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
+{
+ lock();
+ bool result = isValid(handle);
+ if(result)
+ {
+ AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
+ h->stop = callback;
+ h->stop_data = data;
+ }
+ 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 37a5b886882..985954fc20b 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -160,6 +160,7 @@ public:
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);
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 5e0364c618c..b9926b85a48 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -60,6 +60,7 @@ bool g_pyinitialized = false;
#include "AUD_ReadDevice.h"
#include "AUD_IReader.h"
#include "AUD_SequencerFactory.h"
+#include "AUD_SilenceFactory.h"
#ifdef WITH_SDL
#include "AUD_SDLDevice.h"
@@ -845,6 +846,32 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
return result;
}
+static void pauseSound(AUD_Channel* handle)
+{
+ assert(AUD_device);
+
+ AUD_device->pause(handle);
+}
+
+AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
+{
+ assert(AUD_device);
+
+ AUD_SilenceFactory silence;
+ AUD_LimiterFactory limiter(&silence, 0, seconds);
+
+ try
+ {
+ AUD_Channel* channel = AUD_device->play(&limiter);
+ AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
+ return channel;
+ }
+ catch(AUD_Exception&)
+ {
+ return NULL;
+ }
+}
+
AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume)
{
/* AUD_XXX should be this: but AUD_createSequencer is called before the device
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index f73e658d5b1..de2d8465d18 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -463,6 +463,14 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
float sthreshold, int samplerate,
int* length);
+/**
+ * Pauses a playing sound after a specific amount of time.
+ * \param handle The handle to the sound.
+ * \param time The time in seconds.
+ * \return The silence handle.
+ */
+extern AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds);
+
extern AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume);
extern void AUD_destroySequencer(AUD_Sound* sequencer);
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index bb2d65cde74..d0925f6f647 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -34,6 +34,8 @@ struct AUD_Handle
{
};
+typedef void (*stopCallback)(void*);
+
/**
* This class represents an output device for sound sources.
* Output devices may be several backends such as plattform independand like
@@ -225,6 +227,18 @@ public:
* - 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_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index ec9e02ef28f..272e1e4b5b2 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -133,3 +133,8 @@ 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 c6261854803..a1ffdba201a 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -59,6 +59,7 @@ public:
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_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
new file mode 100644
index 00000000000..4e59d7486d5
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SilenceFactory.cpp
@@ -0,0 +1,37 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SilenceFactory.h"
+#include "AUD_SilenceReader.h"
+#include "AUD_Space.h"
+
+AUD_SilenceFactory::AUD_SilenceFactory()
+{
+}
+
+AUD_IReader* AUD_SilenceFactory::createReader() const
+{
+ return new AUD_SilenceReader();
+}
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.h b/intern/audaspace/intern/AUD_SilenceFactory.h
new file mode 100644
index 00000000000..bc8a5b92727
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SilenceFactory.h
@@ -0,0 +1,50 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SILENCEFACTORY
+#define AUD_SILENCEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory creates a reader that plays a sine tone.
+ */
+class AUD_SilenceFactory : public AUD_IFactory
+{
+private:
+ // hide copy constructor and operator=
+ AUD_SilenceFactory(const AUD_SilenceFactory&);
+ AUD_SilenceFactory& operator=(const AUD_SilenceFactory&);
+
+public:
+ /**
+ * Creates a new silence factory.
+ */
+ AUD_SilenceFactory();
+
+ virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_SILENCEFACTORY
diff --git a/intern/audaspace/intern/AUD_SilenceReader.cpp b/intern/audaspace/intern/AUD_SilenceReader.cpp
new file mode 100644
index 00000000000..5243286c5e4
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SilenceReader.cpp
@@ -0,0 +1,74 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#include "AUD_SilenceReader.h"
+
+#include <cstring>
+
+AUD_SilenceReader::AUD_SilenceReader() :
+ m_position(0)
+{
+}
+
+bool AUD_SilenceReader::isSeekable() const
+{
+ return true;
+}
+
+void AUD_SilenceReader::seek(int position)
+{
+ m_position = position;
+}
+
+int AUD_SilenceReader::getLength() const
+{
+ return -1;
+}
+
+int AUD_SilenceReader::getPosition() const
+{
+ return m_position;
+}
+
+AUD_Specs AUD_SilenceReader::getSpecs() const
+{
+ AUD_Specs specs;
+ specs.rate = AUD_RATE_44100;
+ specs.channels = AUD_CHANNELS_MONO;
+ return specs;
+}
+
+void AUD_SilenceReader::read(int & length, sample_t* & buffer)
+{
+ // resize if necessary
+ if(m_buffer.getSize() < length * sizeof(sample_t))
+ {
+ m_buffer.resize(length * sizeof(sample_t));
+ memset(m_buffer.getBuffer(), 0, m_buffer.getSize());
+ }
+
+ buffer = m_buffer.getBuffer();
+ m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_SilenceReader.h b/intern/audaspace/intern/AUD_SilenceReader.h
new file mode 100644
index 00000000000..a8b959b5309
--- /dev/null
+++ b/intern/audaspace/intern/AUD_SilenceReader.h
@@ -0,0 +1,71 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN LGPL LICENSE BLOCK *****
+ *
+ * Copyright 2009 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 Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 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 Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * ***** END LGPL LICENSE BLOCK *****
+ */
+
+#ifndef AUD_SILENCEREADER
+#define AUD_SILENCEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class is used for sine tone playback.
+ * The output format is in the 16 bit format and stereo, the sample rate can be
+ * specified.
+ * As the two channels both play the same the output could also be mono, but
+ * in most cases this will result in having to resample for output, so stereo
+ * sound is created directly.
+ */
+class AUD_SilenceReader : public AUD_IReader
+{
+private:
+ /**
+ * The current position in samples.
+ */
+ int m_position;
+
+ /**
+ * The playback buffer.
+ */
+ AUD_Buffer m_buffer;
+
+ // hide copy constructor and operator=
+ AUD_SilenceReader(const AUD_SilenceReader&);
+ AUD_SilenceReader& operator=(const AUD_SilenceReader&);
+
+public:
+ /**
+ * Creates a new reader.
+ */
+ AUD_SilenceReader();
+
+ virtual bool isSeekable() const;
+ virtual void seek(int position);
+ virtual int getLength() const;
+ virtual int getPosition() const;
+ virtual AUD_Specs getSpecs() const;
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_SILENCEREADER
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 1f063e636f1..757f31fc15d 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -45,6 +45,12 @@ struct AUD_SoftwareHandle : AUD_Handle
/// The loop count of the source.
int loopcount;
+
+ /// The stop callback.
+ stopCallback stop;
+
+ /// Stop callback data.
+ void* stop_data;
};
typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
@@ -151,6 +157,9 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
// in case the end of the sound is reached
if(pos < length)
{
+ if(sound->stop)
+ sound->stop(sound->stop_data);
+
if(sound->keep)
pause(sound);
else
@@ -488,3 +497,17 @@ bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int 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 c14b5356c6b..93b0f165c7a 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -132,6 +132,7 @@ public:
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