svn merge -r 30718:30912 https://svn.blender.org/svnroot/bf-blender/trunk/blender
authorJoerg Mueller <nexyon@gmail.com>
Fri, 30 Jul 2010 22:34:27 +0000 (22:34 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Fri, 30 Jul 2010 22:34:27 +0000 (22:34 +0000)
160 files changed:
intern/audaspace/CMakeLists.txt
intern/audaspace/FX/AUD_AccumulatorFactory.cpp
intern/audaspace/FX/AUD_AccumulatorFactory.h
intern/audaspace/FX/AUD_AccumulatorReader.cpp
intern/audaspace/FX/AUD_AccumulatorReader.h
intern/audaspace/FX/AUD_ButterworthFactory.cpp
intern/audaspace/FX/AUD_ButterworthFactory.h
intern/audaspace/FX/AUD_ButterworthReader.cpp
intern/audaspace/FX/AUD_ButterworthReader.h
intern/audaspace/FX/AUD_DelayFactory.cpp
intern/audaspace/FX/AUD_DelayFactory.h
intern/audaspace/FX/AUD_DelayReader.cpp
intern/audaspace/FX/AUD_DelayReader.h
intern/audaspace/FX/AUD_DoubleFactory.cpp [moved from intern/audaspace/intern/AUD_SourceCaps.h with 63% similarity]
intern/audaspace/FX/AUD_DoubleFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_DoubleReader.h
intern/audaspace/FX/AUD_EffectFactory.cpp
intern/audaspace/FX/AUD_EffectFactory.h
intern/audaspace/FX/AUD_EffectReader.cpp
intern/audaspace/FX/AUD_EffectReader.h
intern/audaspace/FX/AUD_EnvelopeFactory.cpp
intern/audaspace/FX/AUD_EnvelopeFactory.h
intern/audaspace/FX/AUD_EnvelopeReader.cpp
intern/audaspace/FX/AUD_EnvelopeReader.h
intern/audaspace/FX/AUD_FaderFactory.cpp
intern/audaspace/FX/AUD_FaderFactory.h
intern/audaspace/FX/AUD_FaderReader.cpp
intern/audaspace/FX/AUD_FaderReader.h
intern/audaspace/FX/AUD_HighpassFactory.cpp
intern/audaspace/FX/AUD_HighpassFactory.h
intern/audaspace/FX/AUD_HighpassReader.cpp
intern/audaspace/FX/AUD_HighpassReader.h
intern/audaspace/FX/AUD_LimiterFactory.cpp
intern/audaspace/FX/AUD_LimiterFactory.h
intern/audaspace/FX/AUD_LimiterReader.cpp
intern/audaspace/FX/AUD_LimiterReader.h
intern/audaspace/FX/AUD_LoopFactory.cpp
intern/audaspace/FX/AUD_LoopFactory.h
intern/audaspace/FX/AUD_LoopReader.cpp
intern/audaspace/FX/AUD_LoopReader.h
intern/audaspace/FX/AUD_LowpassFactory.cpp
intern/audaspace/FX/AUD_LowpassFactory.h
intern/audaspace/FX/AUD_LowpassReader.cpp
intern/audaspace/FX/AUD_LowpassReader.h
intern/audaspace/FX/AUD_PingPongFactory.cpp
intern/audaspace/FX/AUD_PingPongFactory.h
intern/audaspace/FX/AUD_PitchFactory.cpp
intern/audaspace/FX/AUD_PitchFactory.h
intern/audaspace/FX/AUD_PitchReader.cpp
intern/audaspace/FX/AUD_PitchReader.h
intern/audaspace/FX/AUD_RectifyFactory.cpp
intern/audaspace/FX/AUD_RectifyFactory.h
intern/audaspace/FX/AUD_RectifyReader.cpp
intern/audaspace/FX/AUD_RectifyReader.h
intern/audaspace/FX/AUD_ReverseFactory.cpp
intern/audaspace/FX/AUD_ReverseFactory.h
intern/audaspace/FX/AUD_ReverseReader.cpp
intern/audaspace/FX/AUD_ReverseReader.h
intern/audaspace/FX/AUD_SquareFactory.cpp
intern/audaspace/FX/AUD_SquareFactory.h
intern/audaspace/FX/AUD_SquareReader.cpp
intern/audaspace/FX/AUD_SquareReader.h
intern/audaspace/FX/AUD_SumFactory.cpp
intern/audaspace/FX/AUD_SumFactory.h
intern/audaspace/FX/AUD_SumReader.cpp
intern/audaspace/FX/AUD_SumReader.h
intern/audaspace/FX/AUD_SuperposeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_SuperposeReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_VolumeFactory.cpp
intern/audaspace/FX/AUD_VolumeFactory.h
intern/audaspace/FX/AUD_VolumeReader.cpp
intern/audaspace/FX/AUD_VolumeReader.h
intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
intern/audaspace/OpenAL/AUD_OpenALDevice.h
intern/audaspace/Python/AUD_PyAPI.cpp [new file with mode: 0644]
intern/audaspace/Python/AUD_PyAPI.h [new file with mode: 0644]
intern/audaspace/SConscript
intern/audaspace/SDL/AUD_SDLDevice.h
intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
intern/audaspace/SRC/AUD_SRCResampleFactory.h
intern/audaspace/SRC/AUD_SRCResampleReader.cpp
intern/audaspace/SRC/AUD_SRCResampleReader.h
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
intern/audaspace/fftw/AUD_BandPassReader.h
intern/audaspace/intern/AUD_3DMath.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Buffer.cpp
intern/audaspace/intern/AUD_Buffer.h
intern/audaspace/intern/AUD_BufferReader.cpp
intern/audaspace/intern/AUD_BufferReader.h
intern/audaspace/intern/AUD_C-API.cpp
intern/audaspace/intern/AUD_C-API.h
intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
intern/audaspace/intern/AUD_ChannelMapperFactory.h
intern/audaspace/intern/AUD_ChannelMapperReader.cpp
intern/audaspace/intern/AUD_ChannelMapperReader.h
intern/audaspace/intern/AUD_ConverterFactory.cpp
intern/audaspace/intern/AUD_ConverterFactory.h
intern/audaspace/intern/AUD_ConverterReader.cpp
intern/audaspace/intern/AUD_ConverterReader.h
intern/audaspace/intern/AUD_DefaultMixer.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_DefaultMixer.h [new file with mode: 0644]
intern/audaspace/intern/AUD_FileFactory.cpp
intern/audaspace/intern/AUD_FileFactory.h
intern/audaspace/intern/AUD_I3DDevice.h
intern/audaspace/intern/AUD_IDevice.h
intern/audaspace/intern/AUD_IFactory.h
intern/audaspace/intern/AUD_IReader.h
intern/audaspace/intern/AUD_LinearResampleFactory.cpp
intern/audaspace/intern/AUD_LinearResampleFactory.h
intern/audaspace/intern/AUD_LinearResampleReader.cpp
intern/audaspace/intern/AUD_LinearResampleReader.h
intern/audaspace/intern/AUD_Mixer.cpp
intern/audaspace/intern/AUD_Mixer.h
intern/audaspace/intern/AUD_MixerFactory.cpp
intern/audaspace/intern/AUD_MixerFactory.h
intern/audaspace/intern/AUD_NULLDevice.cpp
intern/audaspace/intern/AUD_NULLDevice.h
intern/audaspace/intern/AUD_ReadDevice.cpp
intern/audaspace/intern/AUD_ReadDevice.h
intern/audaspace/intern/AUD_Reference.h
intern/audaspace/intern/AUD_SequencerFactory.cpp
intern/audaspace/intern/AUD_SequencerFactory.h
intern/audaspace/intern/AUD_SequencerReader.cpp
intern/audaspace/intern/AUD_SequencerReader.h
intern/audaspace/intern/AUD_SinusFactory.cpp
intern/audaspace/intern/AUD_SinusFactory.h
intern/audaspace/intern/AUD_SinusReader.cpp
intern/audaspace/intern/AUD_SinusReader.h
intern/audaspace/intern/AUD_SoftwareDevice.cpp
intern/audaspace/intern/AUD_SoftwareDevice.h
intern/audaspace/intern/AUD_Space.h
intern/audaspace/intern/AUD_StreamBufferFactory.cpp
intern/audaspace/intern/AUD_StreamBufferFactory.h
intern/audaspace/jack/AUD_JackDevice.cpp
intern/audaspace/jack/AUD_JackDevice.h
intern/audaspace/sndfile/AUD_SndFileFactory.cpp
intern/audaspace/sndfile/AUD_SndFileFactory.h
intern/audaspace/sndfile/AUD_SndFileReader.cpp
intern/audaspace/sndfile/AUD_SndFileReader.h
source/blender/editors/mesh/editmesh_tools.c
source/blender/python/CMakeLists.txt
source/blender/python/SConscript
source/blender/python/doc/sphinx_doc_gen.py
source/blender/python/intern/bpy.c
source/blender/windowmanager/WM_api.h
source/blender/windowmanager/intern/wm_init_exit.c
source/blender/windowmanager/intern/wm_window.c
source/blender/windowmanager/wm_window.h
source/creator/creator.c
source/gameengine/BlenderRoutines/BL_KetsjiEmbedStart.cpp
source/gameengine/Ketsji/KX_KetsjiEngine.cpp
source/gameengine/Ketsji/KX_PythonInit.cpp
source/gameengine/Ketsji/KX_SoundActuator.cpp
source/gameengine/Ketsji/KX_SoundActuator.h

index 0965a467201172cbfe5930306c29a68d4ee494c8..c1d59dcd3e9c145e48cc8fd753fd96ee37758da8 100644 (file)
@@ -60,6 +60,12 @@ IF(WITH_FFTW3)
        ADD_DEFINITIONS(-DWITH_FFTW3)
 ENDIF(WITH_FFTW3)
 
-SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC})
+IF(WITH_PYTHON)
+       SET(INC ${INC} Python ${PYTHON_INC})
+       FILE(GLOB PYTHONSRC Python/*.cpp)
+       ADD_DEFINITIONS(-DWITH_PYTHON)
+ENDIF(WITH_PYTHON)
+
+SET(SRC ${SRC} ${FFMPEGSRC} ${SNDFILESRC} ${FFTW3SRC} ${SDLSRC} ${OPENALSRC} ${JACKSRC} ${PYTHONSRC})
 
 BLENDERLIB(bf_audaspace "${SRC}" "${INC}")
index 20709c57ee5ee7a2304f82a0b3fc1fe4bc22a9a5..6e9130d174bd0cdf2fa42d4c5ec1d2a41aacbb6f 100644 (file)
 AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
                                                                                           bool additive) :
                AUD_EffectFactory(factory),
-               m_additive(additive) {}
-
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(bool additive) :
-               AUD_EffectFactory(0),
-               m_additive(additive) {}
-
-AUD_IReader* AUD_AccumulatorFactory::createReader()
+               m_additive(additive)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_AccumulatorReader(reader, m_additive);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_AccumulatorFactory::createReader() const
+{
+       return new AUD_AccumulatorReader(getReader(), m_additive);
 }
index e475a19ccf62fee2710f2c25e15c3111c16cfd6e..2b90fa43bdfdbc659b4f3dd214f43e860fd57c2a 100644 (file)
@@ -37,7 +37,11 @@ private:
        /**
         * Whether the accumulator is additive.
         */
-       bool m_additive;
+       const bool m_additive;
+
+       // hide copy constructor and operator=
+       AUD_AccumulatorFactory(const AUD_AccumulatorFactory&);
+       AUD_AccumulatorFactory& operator=(const AUD_AccumulatorFactory&);
 
 public:
        /**
@@ -47,13 +51,7 @@ public:
         */
        AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
 
-       /**
-        * Creates a new accumulator factory.
-        * \param additive Whether the accumulator is additive.
-        */
-       AUD_AccumulatorFactory(bool additive = false);
-
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_ACCUMULATORFACTORY
index 67ab4157f9c824661bf564024106480be1fbce3a..a8964edcac78d84b979908395e26b67e1707c5b4 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_AccumulatorReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
 AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader,
                                                                                         bool additive) :
                AUD_EffectReader(reader),
-               m_additive(additive)
+               m_additive(additive),
+               m_sums(AUD_SAMPLE_SIZE(reader->getSpecs())),
+               m_prevs(AUD_SAMPLE_SIZE(reader->getSpecs()))
 {
-       AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
-       memset(m_sums->getBuffer(), 0, samplesize);
-
-       m_prevs = new AUD_Buffer(samplesize); AUD_NEW("buffer")
-       memset(m_prevs->getBuffer(), 0, samplesize);
-}
-
-AUD_AccumulatorReader::~AUD_AccumulatorReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-       delete m_sums; AUD_DELETE("buffer")
-       delete m_prevs; AUD_DELETE("buffer")
+       memset(m_sums.getBuffer(), 0, m_sums.getSize());
+       memset(m_prevs.getBuffer(), 0, m_prevs.getSize());
 }
 
 void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
@@ -59,16 +45,16 @@ void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
        sample_t* buf;
        sample_t* sums;
        sample_t* prevs;
-       sums = m_sums->getBuffer();
-       prevs = m_prevs->getBuffer();
+       sums = m_sums.getBuffer();
+       prevs = m_prevs.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 
        if(m_additive)
        {
@@ -87,7 +73,7 @@ void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
        {
                for(int channel = 0; channel < specs.channels; channel++)
                {
-                       for(int i = 0; i < length * specs.channels; i++)
+                       for(int i = 0; i < length; i++)
                        {
                                if(buf[i * CC] > prevs[channel])
                                        sums[channel] += buf[i * CC] - prevs[channel];
index 8ad1dda30f6b0bec4c660f547fd16a7679025d7f..68c1360731db48dd387956c75877a4b0b6e07a07 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_ACCUMULATORREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class represents an accumulator.
@@ -35,40 +35,38 @@ class AUD_Buffer;
 class AUD_AccumulatorReader : public AUD_EffectReader
 {
 private:
+       /**
+        * Whether the accumulator is additive.
+        */
+       const bool m_additive;
+
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The sums of the specific channels.
         */
-       AUD_Buffer *m_sums;
+       AUD_Buffer m_sums;
 
        /**
         * The previous results of the specific channels.
         */
-       AUD_Buffer *m_prevs;
+       AUD_Buffer m_prevs;
 
-       /**
-        * Whether the accumulator is additive.
-        */
-       bool m_additive;
+       // hide copy constructor and operator=
+       AUD_AccumulatorReader(const AUD_AccumulatorReader&);
+       AUD_AccumulatorReader& operator=(const AUD_AccumulatorReader&);
 
 public:
        /**
         * Creates a new accumulator reader.
         * \param reader The reader to read from.
         * \param additive Whether the accumulator is additive.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_AccumulatorReader(AUD_IReader* reader, bool additive);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_AccumulatorReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index fd0a53def7cfd603b273886f18d9e8c5474e3b27..1bb1d726a9831a845bbb0b801820100081721cba 100644 (file)
 AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
                                                                                           float frequency) :
                AUD_EffectFactory(factory),
-               m_frequency(frequency) {}
-
-AUD_ButterworthFactory::AUD_ButterworthFactory(float frequency) :
-               AUD_EffectFactory(0),
-               m_frequency(frequency) {}
-
-AUD_IReader* AUD_ButterworthFactory::createReader()
+               m_frequency(frequency)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_ButterworthReader(reader, m_frequency);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_ButterworthFactory::createReader() const
+{
+       return new AUD_ButterworthReader(getReader(), m_frequency);
 }
index 69169531d7070681fa662c644f94982fa3cb6d61..30b7a402c574ae20e3f08a2521edb43312ea7128 100644 (file)
@@ -37,7 +37,11 @@ private:
        /**
         * The attack value in seconds.
         */
-       float m_frequency;
+       const float m_frequency;
+
+       // hide copy constructor and operator=
+       AUD_ButterworthFactory(const AUD_ButterworthFactory&);
+       AUD_ButterworthFactory& operator=(const AUD_ButterworthFactory&);
 
 public:
        /**
@@ -47,13 +51,7 @@ public:
         */
        AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
 
-       /**
-        * Creates a new butterworth factory.
-        * \param frequency The cutoff frequency.
-        */
-       AUD_ButterworthFactory(float frequency);
-
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_BUTTERWORTHFACTORY
index 2129dfef7984c242f2bc31b872e24b36384a2a5d..cfe4205c7f883bd31df49c4e7b9547b10e1816c1 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_ButterworthReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 #include <cmath>
 
 AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
                                                                                         float frequency) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
+               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
+               m_position(0)
 {
        AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_outvalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
-       memset(m_outvalues->getBuffer(), 0, samplesize * 5);
-
-       m_invalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer")
-       memset(m_invalues->getBuffer(), 0, samplesize * 5);
-
-       m_position = 0;
+       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
+       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
 
        // calculate coefficients
        float omega = 2 * tan(frequency * M_PI / specs.rate);
@@ -74,31 +67,23 @@ AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
        m_coeff[1][2] = 6 * o4 / norm;
 }
 
-AUD_ButterworthReader::~AUD_ButterworthReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-
-       delete m_outvalues; AUD_DELETE("buffer")
-       delete m_invalues; AUD_DELETE("buffer");
-}
-
 void AUD_ButterworthReader::read(int & length, sample_t* & buffer)
 {
        sample_t* buf;
        sample_t* outvalues;
        sample_t* invalues;
 
-       outvalues = m_outvalues->getBuffer();
-       invalues = m_invalues->getBuffer();
+       outvalues = m_outvalues.getBuffer();
+       invalues = m_invalues.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
 
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
        int channels = specs.channels;
 
        for(int channel = 0; channel < channels; channel++)
index b1cbd4e3820c5291d320b3ceb1d5669ac2fee862..52cbb6425406b0a14c570095a1dc5fe69f062cf4 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_BUTTERWORTHREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class represents a butterworth filter.
@@ -38,17 +38,17 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The last out values buffer.
         */
-       AUD_Buffer *m_outvalues;
+       AUD_Buffer m_outvalues;
 
        /**
         * The last in values buffer.
         */
-       AUD_Buffer *m_invalues;
+       AUD_Buffer m_invalues;
 
        /**
         * The position for buffer cycling.
@@ -60,6 +60,10 @@ private:
         */
        float m_coeff[2][5];
 
+       // hide copy constructor and operator=
+       AUD_ButterworthReader(const AUD_ButterworthReader&);
+       AUD_ButterworthReader& operator=(const AUD_ButterworthReader&);
+
 public:
        /**
         * Creates a new butterworth reader.
@@ -68,15 +72,9 @@ public:
         * \param release The release value in seconds.
         * \param threshold The threshold value.
         * \param arthreshold The attack/release threshold value.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_ButterworthReader(AUD_IReader* reader, float frequency);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_ButterworthReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 25ce4faed4c93a74d030c6f5270b5096225af088..f98743d6fb74efcd18216cb25332aadfcfa8327d 100644 (file)
 
 AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
                AUD_EffectFactory(factory),
-               m_delay(delay) {}
-
-AUD_DelayFactory::AUD_DelayFactory(float delay) :
-               AUD_EffectFactory(0),
-               m_delay(delay) {}
-
-float AUD_DelayFactory::getDelay()
+               m_delay(delay)
 {
-       return m_delay;
 }
 
-void AUD_DelayFactory::setDelay(float delay)
+float AUD_DelayFactory::getDelay() const
 {
-       m_delay = delay;
+       return m_delay;
 }
 
-AUD_IReader* AUD_DelayFactory::createReader()
+AUD_IReader* AUD_DelayFactory::createReader() const
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_DelayReader(reader, m_delay); AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_DelayReader(getReader(), m_delay);
 }
index 5ad4b9ab99611185a7da0158b8fcdf9814b7ff3f..721262fb73f368e92490f9cd44869fe18d82c8b4 100644 (file)
@@ -37,7 +37,11 @@ private:
        /**
         * The delay in samples.
         */
-       float m_delay;
+       const float m_delay;
+
+       // hide copy constructor and operator=
+       AUD_DelayFactory(const AUD_DelayFactory&);
+       AUD_DelayFactory& operator=(const AUD_DelayFactory&);
 
 public:
        /**
@@ -45,26 +49,14 @@ public:
         * \param factory The input factory.
         * \param delay The desired delay in seconds.
         */
-       AUD_DelayFactory(AUD_IFactory* factory = 0, float delay = 0);
-
-       /**
-        * Creates a new delay factory.
-        * \param delay The desired delay in seconds.
-        */
-       AUD_DelayFactory(float delay);
+       AUD_DelayFactory(AUD_IFactory* factory, float delay = 0);
 
        /**
         * Returns the delay in seconds.
         */
-       float getDelay();
-
-       /**
-        * Sets the delay.
-        * \param delay The new delay value in seconds.
-        */
-       void setDelay(float delay);
+       float getDelay() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_DELAYFACTORY
index f2521f645aa9f8a8251a04b01bc50f327edb0f2a..e9f0c15b9b417922105ec2f111979bf3c9cc158f 100644 (file)
  */
 
 #include "AUD_DelayReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
 AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_delay(int(delay * reader->getSpecs().rate)),
+               m_remdelay(int(delay * reader->getSpecs().rate)),
+               m_empty(true)
 {
-       m_delay = (int)(delay * reader->getSpecs().rate);
-       m_remdelay = m_delay;
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_DelayReader::~AUD_DelayReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
 }
 
 void AUD_DelayReader::seek(int position)
 {
-       if(position < 0)
-               return;
-
        if(position < m_delay)
        {
                m_remdelay = m_delay - position;
@@ -58,18 +49,18 @@ void AUD_DelayReader::seek(int position)
        }
 }
 
-int AUD_DelayReader::getLength()
+int AUD_DelayReader::getLength() const
 {
        int len = m_reader->getLength();
        if(len < 0)
                return len;
-       return len+m_delay;
+       return len + m_delay;
 }
 
-int AUD_DelayReader::getPosition()
+int AUD_DelayReader::getPosition() const
 {
        if(m_remdelay > 0)
-               return m_delay-m_remdelay;
+               return m_delay - m_remdelay;
        return m_reader->getPosition() + m_delay;
 }
 
@@ -80,26 +71,41 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer)
                AUD_Specs specs = m_reader->getSpecs();
                int samplesize = AUD_SAMPLE_SIZE(specs);
 
-               if(m_buffer->getSize() < length * samplesize)
-                       m_buffer->resize(length * samplesize);
+               if(m_buffer.getSize() < length * samplesize)
+               {
+                       m_buffer.resize(length * samplesize);
+                       m_empty = false;
+               }
+
+               buffer = m_buffer.getBuffer();
 
                if(length > m_remdelay)
                {
-                       memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize);
+                       if(!m_empty)
+                               memset(buffer, 0, m_remdelay * samplesize);
+
                        int len = length - m_remdelay;
-                       m_reader->read(len, buffer);
-                       memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels,
-                                  buffer, len * samplesize);
+                       sample_t* buf;
+                       m_reader->read(len, buf);
+
+                       memcpy(buffer + m_remdelay * specs.channels,
+                                  buf, len * samplesize);
+
                        if(len < length-m_remdelay)
                                length = m_remdelay + len;
+
                        m_remdelay = 0;
+                       m_empty = false;
                }
                else
                {
-                       memset(m_buffer->getBuffer(), 0, length * samplesize);
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
                        m_remdelay -= length;
                }
-               buffer = m_buffer->getBuffer();
        }
        else
                m_reader->read(length, buffer);
index 4662b455dfca8e907c84eae1f5de1751432511a8..121842b0c6b6792102fc967dc750b7f9dea4a63c 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_DELAYREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class reads another reader and changes it's delay.
@@ -38,35 +38,38 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The delay level.
         */
-       int m_delay;
+       const int m_delay;
 
        /**
         * The remaining delay for playback.
         */
        int m_remdelay;
 
+       /**
+        * Whether the buffer is currently filled with zeros.
+        */
+       bool m_empty;
+
+       // hide copy constructor and operator=
+       AUD_DelayReader(const AUD_DelayReader&);
+       AUD_DelayReader& operator=(const AUD_DelayReader&);
+
 public:
        /**
         * Creates a new delay reader.
         * \param reader The reader to read from.
         * \param delay The delay in seconds.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_DelayReader(AUD_IReader* reader, float delay);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_DelayReader();
-
        virtual void seek(int position);
-       virtual int getLength();
-       virtual int getPosition();
+       virtual int getLength() const;
+       virtual int getPosition() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
similarity index 63%
rename from intern/audaspace/intern/AUD_SourceCaps.h
rename to intern/audaspace/FX/AUD_DoubleFactory.cpp
index b1edd2b9b4e3cee99436170b612dd33beba8ecc9..9f625d0763f4413829e0ff32b756aa639f91cb9f 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_SOURCECAPS
-#define AUD_SOURCECAPS
+#include "AUD_DoubleFactory.h"
+#include "AUD_DoubleReader.h"
 
-#include "AUD_IDevice.h"
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2)
+{
+}
 
-/// The structure for source capabilities.
-typedef struct
+AUD_IReader* AUD_DoubleFactory::createReader() const
 {
-       /// The source to apply the capability on.
-       AUD_Handle* handle;
+       AUD_IReader* reader1 = m_factory1->createReader();
+       AUD_IReader* reader2;
 
-       /// The value for the capability.
-       float value;
-} AUD_SourceCaps;
+       try
+       {
+               reader2 = m_factory2->createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               throw;
+       }
 
-#endif //AUD_SOURCECAPS
+       return new AUD_DoubleReader(reader1, reader2);
+}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
new file mode 100644 (file)
index 0000000..f2e83b2
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $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_DOUBLEFACTORY
+#define AUD_DOUBLEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_DoubleFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+       // hide copy constructor and operator=
+       AUD_DoubleFactory(const AUD_DoubleFactory&);
+       AUD_DoubleFactory& operator=(const AUD_DoubleFactory&);
+
+public:
+       /**
+        * Creates a new double factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_DOUBLEFACTORY
index 1e51a094427e5b507cc525166eb9f6122880b408..6b39e01270fbaac465cc8def92eb55b50cfa17f4 100644 (file)
  */
 
 #include "AUD_DoubleReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
 AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
                                                                   AUD_IReader* reader2) :
-               m_reader1(reader1), m_reader2(reader2)
+               m_reader1(reader1), m_reader2(reader2), m_finished1(false)
 {
-       try
+       AUD_Specs s1, s2;
+       s1 = reader1->getSpecs();
+       s2 = reader2->getSpecs();
+       if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
        {
-               if(!reader1)
-                       AUD_THROW(AUD_ERROR_READER);
-
-               if(!reader2)
-                       AUD_THROW(AUD_ERROR_READER);
-
-               AUD_Specs s1, s2;
-               s1 = reader1->getSpecs();
-               s2 = reader2->getSpecs();
-               if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
-                       AUD_THROW(AUD_ERROR_READER);
-       }
-
-       catch(AUD_Exception)
-       {
-               if(reader1)
-               {
-                       delete reader1; AUD_DELETE("reader")
-               }
-               if(reader2)
-               {
-                       delete reader2; AUD_DELETE("reader")
-               }
-
-               throw;
+               delete reader1;
+               delete reader2;
+               AUD_THROW(AUD_ERROR_READER);
        }
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-       m_finished1 = false;
 }
 
 AUD_DoubleReader::~AUD_DoubleReader()
 {
-       delete m_reader1; AUD_DELETE("reader")
-       delete m_reader2; AUD_DELETE("reader")
-       delete m_buffer; AUD_DELETE("buffer")
+       delete m_reader1;
+       delete m_reader2;
 }
 
-bool AUD_DoubleReader::isSeekable()
+bool AUD_DoubleReader::isSeekable() const
 {
-       return false;
+       return m_reader1->isSeekable() && m_reader2->isSeekable();
 }
 
 void AUD_DoubleReader::seek(int position)
 {
-       int length1 = m_reader1->getLength();
+       m_reader1->seek(position);
 
-       if(position < 0)
-               position = 0;
+       int pos1 = m_reader1->getPosition();
 
-       if(position < length1)
-       {
-               m_reader1->seek(position);
-               m_reader2->seek(0);
-               m_finished1 = false;
-       }
+       if((m_finished1 = (pos1 < position)))
+               m_reader2->seek(position - pos1);
        else
-       {
-               m_reader2->seek(position-length1);
-               m_finished1 = true;
-       }
+               m_reader2->seek(0);
 }
 
-int AUD_DoubleReader::getLength()
+int AUD_DoubleReader::getLength() const
 {
        int len1 = m_reader1->getLength();
        int len2 = m_reader2->getLength();
@@ -106,49 +74,45 @@ int AUD_DoubleReader::getLength()
        return len1 + len2;
 }
 
-int AUD_DoubleReader::getPosition()
+int AUD_DoubleReader::getPosition() const
 {
        return m_reader1->getPosition() + m_reader2->getPosition();
 }
 
-AUD_Specs AUD_DoubleReader::getSpecs()
+AUD_Specs AUD_DoubleReader::getSpecs() const
 {
        return m_reader1->getSpecs();
 }
 
-AUD_ReaderType AUD_DoubleReader::getType()
-{
-       if(m_reader1->getType() == AUD_TYPE_BUFFER &&
-          m_reader2->getType() == AUD_TYPE_BUFFER)
-               return AUD_TYPE_BUFFER;
-       return AUD_TYPE_STREAM;
-}
-
-bool AUD_DoubleReader::notify(AUD_Message &message)
-{
-       return m_reader1->notify(message) | m_reader2->notify(message);
-}
-
 void AUD_DoubleReader::read(int & length, sample_t* & buffer)
 {
        if(!m_finished1)
        {
                int len = length;
                m_reader1->read(len, buffer);
+
                if(len < length)
                {
                        AUD_Specs specs = m_reader1->getSpecs();
                        int samplesize = AUD_SAMPLE_SIZE(specs);
-                       if(m_buffer->getSize() < length * samplesize)
-                               m_buffer->resize(length * samplesize);
-                       memcpy(m_buffer->getBuffer(), buffer, len * samplesize);
+
+                       if(m_buffer.getSize() < length * samplesize)
+                               m_buffer.resize(length * samplesize);
+
+                       sample_t* buf = buffer;
+                       buffer = m_buffer.getBuffer();
+
+                       memcpy(buffer, buf, len * samplesize);
+
                        len = length - len;
                        length -= len;
-                       m_reader2->read(len, buffer);
-                       memcpy(m_buffer->getBuffer() + length * specs.channels, buffer,
+                       m_reader2->read(len, buf);
+
+                       memcpy(buffer + length * specs.channels, buf,
                                   len * samplesize);
+
                        length += len;
-                       buffer = m_buffer->getBuffer();
+
                        m_finished1 = true;
                }
        }
index d82b81ec0baa93b61afdd80567ec1f0ca5e95670..d80ba33dfe3af263b2774c52f22e53ec37734b99 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_DOUBLEREADER
 
 #include "AUD_IReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This reader plays two readers with the same specs sequently.
@@ -53,15 +53,18 @@ private:
        /**
         * The playback buffer for the intersecting part.
         */
-       AUD_Buffer* m_buffer;
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_DoubleReader(const AUD_DoubleReader&);
+       AUD_DoubleReader& operator=(const AUD_DoubleReader&);
 
 public:
        /**
         * Creates a new ping pong reader.
         * \param reader1 The first reader to read from.
         * \param reader2 The second reader to read from.
-        * \exception AUD_Exception Thrown if one of the reader specified is NULL
-        *             or the specs from the readers differ.
+        * \exception AUD_Exception Thrown if the specs from the readers differ.
         */
        AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
 
@@ -70,13 +73,11 @@ public:
         */
        virtual ~AUD_DoubleReader();
 
-       virtual bool isSeekable();
+       virtual bool isSeekable() const;
        virtual void seek(int position);
-       virtual int getLength();
-       virtual int getPosition();
-       virtual AUD_Specs getSpecs();
-       virtual AUD_ReaderType getType();
-       virtual bool notify(AUD_Message &message);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual AUD_Specs getSpecs() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 882499416b7cd49424ce723765b7469687fec444..eda4e4e04b2ea7c87340189645a5328ecbd66e3d 100644 (file)
 #include "AUD_EffectFactory.h"
 #include "AUD_IReader.h"
 
-AUD_IReader* AUD_EffectFactory::getReader()
-{
-       if(m_factory != 0)
-               return m_factory->createReader();
-
-       return 0;
-}
-
 AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
 {
        m_factory = factory;
 }
 
-void AUD_EffectFactory::setFactory(AUD_IFactory* factory)
+AUD_EffectFactory::~AUD_EffectFactory()
 {
-       m_factory = factory;
 }
 
-AUD_IFactory* AUD_EffectFactory::getFactory()
+AUD_IFactory* AUD_EffectFactory::getFactory() const
 {
        return m_factory;
 }
index 67259b9e6c3dffd0f9e636bcb633b39e918c1283..fd3746d0da3f5189f8f00b84c56aea4469ff1afb 100644 (file)
  */
 class AUD_EffectFactory : public AUD_IFactory
 {
+private:
+       // hide copy constructor and operator=
+       AUD_EffectFactory(const AUD_EffectFactory&);
+       AUD_EffectFactory& operator=(const AUD_EffectFactory&);
+
 protected:
        /**
         * If there is no reader it is created out of this factory.
@@ -44,9 +49,12 @@ protected:
         * Returns the reader created out of the factory.
         * This method can be used for the createReader function of the implementing
         * classes.
-        * \return The reader created out of the factory or NULL if there is none.
+        * \return The reader created out of the factory.
         */
-       AUD_IReader* getReader();
+       inline AUD_IReader* getReader() const
+       {
+               return m_factory->createReader();
+       }
 
 public:
        /**
@@ -58,19 +66,13 @@ public:
        /**
         * Destroys the factory.
         */
-       virtual ~AUD_EffectFactory() {}
-
-       /**
-        * Sets the input factory.
-        * \param factory The input factory.
-        */
-       void setFactory(AUD_IFactory* factory);
+       virtual ~AUD_EffectFactory();
 
        /**
         * Returns the saved factory.
         * \return The factory or NULL if there has no factory been saved.
         */
-       AUD_IFactory* getFactory();
+       AUD_IFactory* getFactory() const;
 };
 
 #endif //AUD_EFFECTFACTORY
index 47026b88440b3fabdac7c559961d433cf6ad111e..b54ca279088fe62718b2e82afa6349c2418e651d 100644 (file)
 
 AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
 {
-       if(!reader)
-               AUD_THROW(AUD_ERROR_READER);
        m_reader = reader;
 }
 
 AUD_EffectReader::~AUD_EffectReader()
 {
-       delete m_reader; AUD_DELETE("reader")
+       delete m_reader;
 }
 
-bool AUD_EffectReader::isSeekable()
+bool AUD_EffectReader::isSeekable() const
 {
        return m_reader->isSeekable();
 }
@@ -47,31 +45,21 @@ void AUD_EffectReader::seek(int position)
        m_reader->seek(position);
 }
 
-int AUD_EffectReader::getLength()
+int AUD_EffectReader::getLength() const
 {
        return m_reader->getLength();
 }
 
-int AUD_EffectReader::getPosition()
+int AUD_EffectReader::getPosition() const
 {
        return m_reader->getPosition();
 }
 
-AUD_Specs AUD_EffectReader::getSpecs()
+AUD_Specs AUD_EffectReader::getSpecs() const
 {
        return m_reader->getSpecs();
 }
 
-AUD_ReaderType AUD_EffectReader::getType()
-{
-       return m_reader->getType();
-}
-
-bool AUD_EffectReader::notify(AUD_Message &message)
-{
-       return m_reader->notify(message);
-}
-
 void AUD_EffectReader::read(int & length, sample_t* & buffer)
 {
        m_reader->read(length, buffer);
index f64bf34077ddd579398dd61b5bcd8f91d219674d..c447f79bc6ec8d39f8b7283352af5f233c561f1d 100644 (file)
  */
 class AUD_EffectReader : public AUD_IReader
 {
+private:
+       // hide copy constructor and operator=
+       AUD_EffectReader(const AUD_EffectReader&);
+       AUD_EffectReader& operator=(const AUD_EffectReader&);
+
 protected:
        /**
         * The reader to read from.
@@ -44,7 +49,6 @@ public:
        /**
         * Creates a new effect reader.
         * \param reader The reader to read from.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_EffectReader(AUD_IReader* reader);
 
@@ -53,13 +57,11 @@ public:
         */
        virtual ~AUD_EffectReader();
 
-       virtual bool isSeekable();
+       virtual bool isSeekable() const;
        virtual void seek(int position);
-       virtual int getLength();
-       virtual int getPosition();
-       virtual AUD_Specs getSpecs();
-       virtual AUD_ReaderType getType();
-       virtual bool notify(AUD_Message &message);
+       virtual int getLength() const;
+       virtual int getPosition() const;
+       virtual AUD_Specs getSpecs() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
index c3b2c3f24fe4b0867e7be421c5cca8d5804fc369..1c625067f1c59ff88520f063536cecb71bd2d8b9 100644 (file)
@@ -33,26 +33,12 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
                m_attack(attack),
                m_release(release),
                m_threshold(threshold),
-               m_arthreshold(arthreshold) {}
-
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(float attack, float release,
-                                                                                float threshold, float arthreshold) :
-               AUD_EffectFactory(0),
-               m_attack(attack),
-               m_release(release),
-               m_threshold(threshold),
-               m_arthreshold(arthreshold) {}
-
-AUD_IReader* AUD_EnvelopeFactory::createReader()
+               m_arthreshold(arthreshold)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_EnvelopeReader(reader, m_attack, m_release,
-                                                                               m_threshold, m_arthreshold);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_EnvelopeFactory::createReader() const
+{
+       return new AUD_EnvelopeReader(getReader(), m_attack, m_release, m_threshold,
+                                                                 m_arthreshold);
 }
index c79e5472e30609ab4f81aa8863d229d872090729..c31c6727d0370a827202ce1c9be65ab3ceb2c5f0 100644 (file)
@@ -37,22 +37,26 @@ private:
        /**
         * The attack value in seconds.
         */
-       float m_attack;
+       const float m_attack;
 
        /**
         * The release value in seconds.
         */
-       float m_release;
+       const float m_release;
 
        /**
         * The threshold value.
         */
-       float m_threshold;
+       const float m_threshold;
 
        /**
         * The attack/release threshold value.
         */
-       float m_arthreshold;
+       const float m_arthreshold;
+
+       // hide copy constructor and operator=
+       AUD_EnvelopeFactory(const AUD_EnvelopeFactory&);
+       AUD_EnvelopeFactory& operator=(const AUD_EnvelopeFactory&);
 
 public:
        /**
@@ -66,17 +70,7 @@ public:
        AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
                                                float threshold, float arthreshold);
 
-       /**
-        * Creates a new envelope factory.
-        * \param attack The attack value in seconds.
-        * \param release The release value in seconds.
-        * \param threshold The threshold value.
-        * \param arthreshold The attack/release threshold value.
-        */
-       AUD_EnvelopeFactory(float attack, float release, float threshold,
-                                               float arthreshold);
-
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_ENVELOPEFACTORY
index 71ccbfd6503d4f4dbe4882755a8e3fe7fa07b71a..ef64b6fa4eb4342f195e4a45e78b19f8a854271b 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_EnvelopeReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 #include <cmath>
@@ -33,40 +32,27 @@ AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
                                                                           float release, float threshold,
                                                                           float arthreshold) :
                AUD_EffectReader(reader),
-               m_threshold(threshold)
+               m_bAttack(pow(arthreshold, 1.0f/(reader->getSpecs().rate * attack))),
+               m_bRelease(pow(arthreshold, 1.0f/(reader->getSpecs().rate * release))),
+               m_threshold(threshold),
+               m_envelopes(AUD_SAMPLE_SIZE(reader->getSpecs()))
 {
-       AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_envelopes = new AUD_Buffer(samplesize);
-       AUD_NEW("buffer")
-       memset(m_envelopes->getBuffer(), 0, samplesize);
-
-       m_bAttack = pow(arthreshold, 1.0f/(specs.rate * attack));
-       m_bRelease = pow(arthreshold, 1.0f/(specs.rate * release));
-}
-
-AUD_EnvelopeReader::~AUD_EnvelopeReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-       delete m_envelopes; AUD_DELETE("buffer")
+       memset(m_envelopes.getBuffer(), 0, m_envelopes.getSize());
 }
 
 void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
 {
        sample_t* buf;
        sample_t* envelopes;
-       envelopes = m_envelopes->getBuffer();
+       envelopes = m_envelopes.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 
        sample_t value;
 
index ff9dd23d34cd224edd1e407b63d3146934bce07c..b452ee2119a18a60e7ee037b1554abaecde60d11 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_ENVELOPEREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class represents an envelope follower.
@@ -36,29 +36,33 @@ class AUD_EnvelopeReader : public AUD_EffectReader
 {
 private:
        /**
-        * The playback buffer.
+        * Attack b value.
         */
-       AUD_Buffer *m_buffer;
+       const float m_bAttack;
 
        /**
-        * The last envelopes buffer.
+        * Release b value.
         */
-       AUD_Buffer *m_envelopes;
+       const float m_bRelease;
 
        /**
-        * Attack b value.
+        * Threshold value.
         */
-       float m_bAttack;
+       const float m_threshold;
 
        /**
-        * Release b value.
+        * The playback buffer.
         */
-       float m_bRelease;
+       AUD_Buffer m_buffer;
 
        /**
-        * Threshold value.
+        * The last envelopes buffer.
         */
-       float m_threshold;
+       AUD_Buffer m_envelopes;
+
+       // hide copy constructor and operator=
+       AUD_EnvelopeReader(const AUD_EnvelopeReader&);
+       AUD_EnvelopeReader& operator=(const AUD_EnvelopeReader&);
 
 public:
        /**
@@ -68,16 +72,10 @@ public:
         * \param release The release value in seconds.
         * \param threshold The threshold value.
         * \param arthreshold The attack/release threshold value.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release,
                                           float threshold, float arthreshold);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_EnvelopeReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 4357e11bd4396d76dbdce211bcf3c44315a99f3a..bbe9319c928cf927215fee5ea8f6b51c151ea373 100644 (file)
@@ -31,54 +31,26 @@ AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
                AUD_EffectFactory(factory),
                m_type(type),
                m_start(start),
-               m_length(length) {}
-
-AUD_FaderFactory::AUD_FaderFactory(AUD_FadeType type,
-                                                                  float start, float length) :
-               AUD_EffectFactory(0),
-               m_type(type),
-               m_start(start),
-               m_length(length) {}
-
-AUD_FadeType AUD_FaderFactory::getType()
+               m_length(length)
 {
-       return m_type;
 }
 
-void AUD_FaderFactory::setType(AUD_FadeType type)
+AUD_FadeType AUD_FaderFactory::getType() const
 {
-       m_type = type;
+       return m_type;
 }
 
-float AUD_FaderFactory::getStart()
+float AUD_FaderFactory::getStart() const
 {
        return m_start;
 }
 
-void AUD_FaderFactory::setStart(float start)
-{
-       m_start = start;
-}
-
-float AUD_FaderFactory::getLength()
+float AUD_FaderFactory::getLength() const
 {
        return m_length;
 }
 
-void AUD_FaderFactory::setLength(float length)
+AUD_IReader* AUD_FaderFactory::createReader() const
 {
-       m_length = length;
-}
-
-AUD_IReader* AUD_FaderFactory::createReader()
-{
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_FaderReader(reader, m_type, m_start, m_length);
-               AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
 }
index 4999ccac8f1135ca9b7b21a672ee72efa1ffc8d8..af5d18538eae625fea7845ec752407a8261fe250 100644 (file)
@@ -39,17 +39,21 @@ private:
        /**
         * The fading type.
         */
-       AUD_FadeType m_type;
+       const AUD_FadeType m_type;
 
        /**
         * The fading start.
         */
-       float m_start;
+       const float m_start;
 
        /**
         * The fading length.
         */
-       float m_length;
+       const float m_length;
+
+       // hide copy constructor and operator=
+       AUD_FaderFactory(const AUD_FaderFactory&);
+       AUD_FaderFactory& operator=(const AUD_FaderFactory&);
 
 public:
        /**
@@ -59,53 +63,26 @@ public:
         * \param start The time where fading should start in seconds.
         * \param length How long fading should last in seconds.
         */
-       AUD_FaderFactory(AUD_IFactory* factory = 0,
+       AUD_FaderFactory(AUD_IFactory* factory,
                                          AUD_FadeType type = AUD_FADE_IN,
                                          float start = 0.0f, float length = 1.0f);
 
-       /**
-        * Creates a new fader factory.
-        * \param type The fading type.
-        * \param start The time where fading should start in seconds.
-        * \param length How long fading should last in seconds.
-        */
-       AUD_FaderFactory(AUD_FadeType type = AUD_FADE_IN,
-                                         float start = 0.0f, float length = 1.0f);
-
        /**
         * Returns the fading type.
         */
-       AUD_FadeType getType();
-
-       /**
-        * Sets the fading type.
-        * \param type The new fading type: AUD_FADE_IN or AUD_FADE_OUT.
-        */
-       void setType(AUD_FadeType type);
+       AUD_FadeType getType() const;
 
        /**
         * Returns the fading start.
         */
-       float getStart();
-
-       /**
-        * Sets the fading start.
-        * \param start The new fading start.
-        */
-       void setStart(float start);
+       float getStart() const;
 
        /**
         * Returns the fading length.
         */
-       float getLength();
-
-       /**
-        * Sets the fading length.
-        * \param start The new fading length.
-        */
-       void setLength(float length);
+       float getLength() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_FADERFACTORY
index 4e919fff323f86e60c10937933012292969d5671..2292fa06102f97b635a179c8c174712e6f22da6a 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_FaderReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
@@ -33,19 +32,9 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
                AUD_EffectReader(reader),
                m_type(type),
                m_start(start),
-               m_length(length)
+               m_length(length),
+               m_empty(true)
 {
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_FaderReader::~AUD_FaderReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-}
-
-bool AUD_FaderReader::notify(AUD_Message &message)
-{
-       return m_reader->notify(message);
 }
 
 void AUD_FaderReader::read(int & length, sample_t* & buffer)
@@ -56,28 +45,50 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
 
        m_reader->read(length, buffer);
 
-       if(m_buffer->getSize() < length * samplesize)
-               m_buffer->resize(length * samplesize);
-
        if((position + length) / (float)specs.rate <= m_start)
        {
                if(m_type != AUD_FADE_OUT)
                {
-                       buffer = m_buffer->getBuffer();
-                       memset(buffer, 0, length * samplesize);
+                       if(m_buffer.getSize() < length * samplesize)
+                       {
+                               m_buffer.resize(length * samplesize);
+                               m_empty = false;
+                       }
+
+                       buffer = m_buffer.getBuffer();
+
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
                }
        }
        else if(position / (float)specs.rate >= m_start+m_length)
        {
                if(m_type == AUD_FADE_OUT)
                {
-                       buffer = m_buffer->getBuffer();
-                       memset(buffer, 0, length * samplesize);
+                       if(m_buffer.getSize() < length * samplesize)
+                       {
+                               m_buffer.resize(length * samplesize);
+                               m_empty = false;
+                       }
+
+                       buffer = m_buffer.getBuffer();
+
+                       if(!m_empty)
+                       {
+                               memset(buffer, 0, length * samplesize);
+                               m_empty = true;
+                       }
                }
        }
        else
        {
-               sample_t* buf = m_buffer->getBuffer();
+               if(m_buffer.getSize() < length * samplesize)
+                       m_buffer.resize(length * samplesize);
+
+               sample_t* buf = m_buffer.getBuffer();
                float volume = 1.0f;
 
                for(int i = 0; i < length * specs.channels; i++)
@@ -98,5 +109,6 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
                }
 
                buffer = buf;
+               m_empty = false;
        }
 }
index a75ac6e7a47553da010ed79e9aa68d80a142a3a1..d9d685af956b605f53398b81cda127d2224a7714 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_FADERREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class fades another reader.
@@ -37,25 +37,34 @@ class AUD_Buffer;
 class AUD_FaderReader : public AUD_EffectReader
 {
 private:
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer *m_buffer;
-
        /**
         * The fading type.
         */
-       AUD_FadeType m_type;
+       const AUD_FadeType m_type;
 
        /**
         * The fading start.
         */
-       float m_start;
+       const float m_start;
 
        /**
         * The fading length.
         */
-       float m_length;
+       const float m_length;
+
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * Whether the buffer is empty.
+        */
+       bool m_empty;
+
+       // hide copy constructor and operator=
+       AUD_FaderReader(const AUD_FaderReader&);
+       AUD_FaderReader& operator=(const AUD_FaderReader&);
 
 public:
        /**
@@ -63,17 +72,10 @@ public:
         * \param type The fading type.
         * \param start The time where fading should start in seconds.
         * \param length How long fading should last in seconds.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
                                        float start,float length);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_FaderReader();
-
-       virtual bool notify(AUD_Message &message);
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 384d36beab729ddf5835c91d1bc1ea11f16a091f..1ab5237c8ffb29e8f36ca23c382ee75313e0d5b2 100644 (file)
@@ -30,22 +30,11 @@ AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
                                                                                 float Q) :
                AUD_EffectFactory(factory),
                m_frequency(frequency),
-               m_Q(Q) {}
-
-AUD_HighpassFactory::AUD_HighpassFactory(float frequency, float Q) :
-               AUD_EffectFactory(0),
-               m_frequency(frequency),
-               m_Q(Q) {}
-
-AUD_IReader* AUD_HighpassFactory::createReader()
+               m_Q(Q)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_HighpassReader(reader, m_frequency, m_Q);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_HighpassFactory::createReader() const
+{
+       return new AUD_HighpassReader(getReader(), m_frequency, m_Q);
 }
index 5e31053ed6c809677bee12cd6133faaf485eec15..1220157a776bf7d8d6cacbe49b8aac6f6efb4296 100644 (file)
@@ -37,12 +37,16 @@ private:
        /**
         * The attack value in seconds.
         */
-       float m_frequency;
+       const float m_frequency;
 
        /**
         * The Q factor.
         */
-       float m_Q;
+       const float m_Q;
+
+       // hide copy constructor and operator=
+       AUD_HighpassFactory(const AUD_HighpassFactory&);
+       AUD_HighpassFactory& operator=(const AUD_HighpassFactory&);
 
 public:
        /**
@@ -53,14 +57,7 @@ public:
         */
        AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
 
-       /**
-        * Creates a new highpass factory.
-        * \param frequency The cutoff frequency.
-        * \param Q The Q factor.
-        */
-       AUD_HighpassFactory(float frequency, float Q = 1.0f);
-
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_HIGHPASSFACTORY
index 36b1bb8082e8b2e3b684cb21d25b4e7fd0eaaf6c..904d6a95867f46d386fa876ac36c23bcb8a23f46 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_HighpassReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 #include <cmath>
 
 AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
                                                                           float Q) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
+               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
+               m_position(0)
 {
-       AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_outvalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
-       AUD_NEW("buffer")
-       memset(m_outvalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
+       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
+       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
 
-       m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
-       AUD_NEW("buffer")
-       memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
-
-       m_position = 0;
+       AUD_Specs specs = reader->getSpecs();
 
        // calculate coefficients
        float w0 = 2 * M_PI * frequency / specs.rate;
@@ -65,31 +57,23 @@ AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
        m_coeff[1][1] = (-1 - cos(w0)) / norm;
 }
 
-AUD_HighpassReader::~AUD_HighpassReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-
-       delete m_outvalues; AUD_DELETE("buffer")
-       delete m_invalues; AUD_DELETE("buffer");
-}
-
 void AUD_HighpassReader::read(int & length, sample_t* & buffer)
 {
        sample_t* buf;
        sample_t* outvalues;
        sample_t* invalues;
 
-       outvalues = m_outvalues->getBuffer();
-       invalues = m_invalues->getBuffer();
+       outvalues = m_outvalues.getBuffer();
+       invalues = m_invalues.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
 
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
        int channels = specs.channels;
 
        for(int channel = 0; channel < channels; channel++)
index dc28a62e45bd46fde0f7196b8925095efb4ee4bc..845e764ac9f0d5474c7ac8082411f1da08c6e2b2 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_HIGHPASSREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 #define AUD_HIGHPASS_ORDER 3
 
@@ -40,17 +40,17 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The last out values buffer.
         */
-       AUD_Buffer *m_outvalues;
+       AUD_Buffer m_outvalues;
 
        /**
         * The last in values buffer.
         */
-       AUD_Buffer *m_invalues;
+       AUD_Buffer m_invalues;
 
        /**
         * The position for buffer cycling.
@@ -62,21 +62,19 @@ private:
         */
        float m_coeff[2][AUD_HIGHPASS_ORDER];
 
+       // hide copy constructor and operator=
+       AUD_HighpassReader(const AUD_HighpassReader&);
+       AUD_HighpassReader& operator=(const AUD_HighpassReader&);
+
 public:
        /**
         * Creates a new highpass reader.
         * \param reader The reader to read from.
         * \param frequency The cutoff frequency.
         * \param Q The Q factor.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_HighpassReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 6f19575240a9ccf2e25eed4338f3b41f13f93fe8..75501afcec329d0f62421cbc627e23c93de3d3f8 100644 (file)
@@ -31,37 +31,21 @@ AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
                                                                           float start, float end) :
                AUD_EffectFactory(factory),
                m_start(start),
-               m_end(end) {}
-
-float AUD_LimiterFactory::getStart()
+               m_end(end)
 {
-       return m_start;
 }
 
-void AUD_LimiterFactory::setStart(float start)
+float AUD_LimiterFactory::getStart() const
 {
-       m_start = start;
+       return m_start;
 }
 
-float AUD_LimiterFactory::getEnd()
+float AUD_LimiterFactory::getEnd() const
 {
        return m_end;
 }
 
-void AUD_LimiterFactory::setEnd(float end)
-{
-       m_end = end;
-}
-
-AUD_IReader* AUD_LimiterFactory::createReader()
+AUD_IReader* AUD_LimiterFactory::createReader() const
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_LimiterReader(reader, m_start, m_end);
-               AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_LimiterReader(getReader(), m_start, m_end);
 }
index 588fea6eb4b3176c63fc0a1ed8d5d4db70ac568e..5d9491f60aaf7e00d477e35647cdf8d5102336bb 100644 (file)
@@ -37,12 +37,16 @@ private:
        /**
         * The start time.
         */
-       float m_start;
+       const float m_start;
 
        /**
         * The end time.
         */
-       float m_end;
+       const float m_end;
+
+       // hide copy constructor and operator=
+       AUD_LimiterFactory(const AUD_LimiterFactory&);
+       AUD_LimiterFactory& operator=(const AUD_LimiterFactory&);
 
 public:
        /**
@@ -52,33 +56,20 @@ public:
         * \param end The desired end time, a negative value signals that it should
         *            play to the end.
         */
-       AUD_LimiterFactory(AUD_IFactory* factory = 0,
+       AUD_LimiterFactory(AUD_IFactory* factory,
                                           float start = 0, float end = -1);
 
        /**
         * Returns the start time.
         */
-       float getStart();
-
-       /**
-        * Sets the start time.
-        * \param start The new start time.
-        */
-       void setStart(float start);
+       float getStart() const;
 
        /**
         * Returns the end time.
         */
-       float getEnd();
-
-       /**
-        * Sets the end time.
-        * \param end The new end time, a negative value signals that it should play
-        *            to the end.
-        */
-       void setEnd(float end);
+       float getEnd() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_LIMITERFACTORY
index 05882369001804c258c703a657c6ddb2a681ba55..dd7301213c938e7d855812bb6b03e44faed3286f 100644 (file)
 
 AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
                                                                         float start, float end) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_start(int(start * reader->getSpecs().rate)),
+               m_end(int(end * reader->getSpecs().rate))
 {
-       m_end = (int)(end * reader->getSpecs().rate);
-
-       if(start <= 0)
-               m_start = 0;
-       else
+       if(m_start > 0)
        {
-               m_start = (int)(start * reader->getSpecs().rate);
                if(m_reader->isSeekable())
                        m_reader->seek(m_start);
                else
                {
                        // skip first m_start samples by reading them
-                       int length;
+                       int length = AUD_DEFAULT_BUFFER_SIZE;
                        sample_t* buffer;
-                       for(int i = m_start;
-                               i >= AUD_DEFAULT_BUFFER_SIZE;
-                               i -= AUD_DEFAULT_BUFFER_SIZE)
+                       for(int len = m_start;
+                               length == AUD_DEFAULT_BUFFER_SIZE;
+                               len -= AUD_DEFAULT_BUFFER_SIZE)
                        {
-                               length = AUD_DEFAULT_BUFFER_SIZE;
+                               if(len < AUD_DEFAULT_BUFFER_SIZE)
+                                       length = len;
                                m_reader->read(length, buffer);
-                               length = i;
                        }
-                       m_reader->read(length, buffer);
                }
        }
 }
@@ -64,18 +60,18 @@ void AUD_LimiterReader::seek(int position)
        m_reader->seek(position + m_start);
 }
 
-int AUD_LimiterReader::getLength()
+int AUD_LimiterReader::getLength() const
 {
        int len = m_reader->getLength();
-       if(m_reader->getType() != AUD_TYPE_BUFFER || len < 0 ||
-          (len > m_end && m_end >= 0))
+       if(len < 0 || (len > m_end && m_end >= 0))
                len = m_end;
        return len - m_start;
 }
 
-int AUD_LimiterReader::getPosition()
+int AUD_LimiterReader::getPosition() const
 {
-       return m_reader->getPosition() - m_start;
+       int pos = m_reader->getPosition();
+       return AUD_MIN(pos, m_end) - m_start;
 }
 
 void AUD_LimiterReader::read(int & length, sample_t* & buffer)
@@ -83,7 +79,7 @@ void AUD_LimiterReader::read(int & length, sample_t* & buffer)
        if(m_end >= 0)
        {
                int position = m_reader->getPosition();
-               if(position+length > m_end)
+               if(position + length > m_end)
                        length = m_end - position;
                if(length < 0)
                {
index 9921f5ee1b0f580386556d71c7898801f9473c2e..59d6096dcba26f703850bcedfbc40bcb6674f685 100644 (file)
@@ -37,12 +37,16 @@ private:
        /**
         * The start sample: inclusive.
         */
-       int m_start;
+       const int m_start;
 
        /**
         * The end sample: exlusive.
         */
-       int m_end;
+       const int m_end;
+
+       // hide copy constructor and operator=
+       AUD_LimiterReader(const AUD_LimiterReader&);
+       AUD_LimiterReader& operator=(const AUD_LimiterReader&);
 
 public:
        /**
@@ -51,13 +55,12 @@ public:
         * \param start The desired start sample (inclusive).
         * \param end The desired end sample (exklusive), a negative value signals
         *            that it should play to the end.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
 
        virtual void seek(int position);
-       virtual int getLength();
-       virtual int getPosition();
+       virtual int getLength() const;
+       virtual int getPosition() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 90186f623ffd5a308b7512253ca83f090ad52b23..6805a8e4b426243daca32276e58e165b13483bf2 100644 (file)
 
 AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
                AUD_EffectFactory(factory),
-               m_loop(loop) {}
-
-AUD_LoopFactory::AUD_LoopFactory(int loop) :
-               AUD_EffectFactory(0),
-               m_loop(loop) {}
-
-int AUD_LoopFactory::getLoop()
+               m_loop(loop)
 {
-       return m_loop;
 }
 
-void AUD_LoopFactory::setLoop(int loop)
+int AUD_LoopFactory::getLoop() const
 {
-       m_loop = loop;
+       return m_loop;
 }
 
-AUD_IReader* AUD_LoopFactory::createReader()
+AUD_IReader* AUD_LoopFactory::createReader() const
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_LoopReader(reader, m_loop); AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_LoopReader(getReader(), m_loop);
 }
index c81d906b82e61b54e8351d39cb02370dce7c35d9..f9e358af52d555e6ce68db22b7185f0fc3d6297b 100644 (file)
@@ -38,7 +38,11 @@ private:
        /**
         * The loop count.
         */
-       int m_loop;
+       const int m_loop;
+
+       // hide copy constructor and operator=
+       AUD_LoopFactory(const AUD_LoopFactory&);
+       AUD_LoopFactory& operator=(const AUD_LoopFactory&);
 
 public:
        /**
@@ -47,28 +51,14 @@ public:
         * \param loop The desired loop count, negative values result in endless
         *        looping.
         */
-       AUD_LoopFactory(AUD_IFactory* factory = 0, int loop = -1);
-
-       /**
-        * Creates a new loop factory.
-        * \param loop The desired loop count, negative values result in endless
-        *        looping.
-        */
-       AUD_LoopFactory(int loop);
+       AUD_LoopFactory(AUD_IFactory* factory, int loop = -1);
 
        /**
         * Returns the loop count.
         */
-       int getLoop();
-
-       /**
-        * Sets the loop count.
-        * \param loop The desired loop count, negative values result in endless
-        *        looping.
-        */
-       void setLoop(int loop);
+       int getLoop() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_LOOPFACTORY
index 3bcd8c2f9d32e4484bc117b1569dd315dbeb0848..7521f914a5c3bf7f61abf0c98e4e387e1c0553ab 100644 (file)
 #include <cstring>
 
 AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
-               AUD_EffectReader(reader), m_loop(loop)
+               AUD_EffectReader(reader), m_count(loop), m_left(loop)
 {
-       m_samples = -1;
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
-AUD_LoopReader::~AUD_LoopReader()
+void AUD_LoopReader::seek(int position)
 {
-       delete m_buffer; AUD_DELETE("buffer")
+       int len = m_reader->getLength();
+       if(len < 0)
+               m_reader->seek(position);
+       else
+       {
+               if(m_count >= 0)
+               {
+                       m_left = m_count - (position / len);
+                       if(m_left < 0)
+                               m_left = 0;
+               }
+               m_reader->seek(position % len);
+       }
 }
 
-AUD_ReaderType AUD_LoopReader::getType()
+int AUD_LoopReader::getLength() const
 {
-       if(m_loop < 0)
-               return AUD_TYPE_STREAM;
-       return m_reader->getType();
+       if(m_count < 0)
+               return -1;
+       return m_reader->getLength() * m_count;
 }
 
-bool AUD_LoopReader::notify(AUD_Message &message)
+int AUD_LoopReader::getPosition() const
 {
-       if(message.type == AUD_MSG_LOOP)
-       {
-               m_loop = message.loopcount;
-               m_samples = message.time * m_reader->getSpecs().rate;
-
-               m_reader->notify(message);
-
-               return true;
-       }
-       return m_reader->notify(message);
+       return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
 }
 
 void AUD_LoopReader::read(int & length, sample_t* & buffer)
@@ -66,50 +67,44 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
        AUD_Specs specs = m_reader->getSpecs();
        int samplesize = AUD_SAMPLE_SIZE(specs);
 
-       if(m_samples >= 0)
-       {
-               if(length > m_samples)
-                       length = m_samples;
-               m_samples -= length;
-       }
-
        int len = length;
 
        m_reader->read(len, buffer);
 
-       if(len < length && m_loop != 0)
+       if(len < length && m_left)
        {
                int pos = 0;
 
-               if(m_buffer->getSize() < length * samplesize)
-                       m_buffer->resize(length * samplesize);
+               if(m_buffer.getSize() < length * samplesize)
+                       m_buffer.resize(length * samplesize);
+
+               sample_t* buf = m_buffer.getBuffer();
 
-               memcpy(m_buffer->getBuffer() + pos * specs.channels,
-                          buffer, len * samplesize);
+               memcpy(buf + pos * specs.channels, buffer, len * samplesize);
 
                pos += len;
 
-               while(pos < length && m_loop != 0)
+               while(pos < length && m_left)
                {
-                       if(m_loop > 0)
-                               m_loop--;
+                       if(m_left > 0)
+                               m_left--;
 
                        m_reader->seek(0);
 
                        len = length - pos;
                        m_reader->read(len, buffer);
+
                        // prevent endless loop
                        if(!len)
                                break;
 
-                       memcpy(m_buffer->getBuffer() + pos * specs.channels,
-                                  buffer, len * samplesize);
+                       memcpy(buf + pos * specs.channels, buffer, len * samplesize);
 
                        pos += len;
                }
 
                length = pos;
-               buffer = m_buffer->getBuffer();
+               buffer = buf;
        }
        else
                length = len;
index e61a49cb0db39c4c13c1a7c4c7dc259f9ae4e6b0..e0ed4cb6bf33f0f9ace7ee83f97f7ccdec8c3a1e 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_LOOPREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class reads another reader and loops it.
@@ -39,17 +39,21 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
-        * The left loop count.
+        * The loop count.
         */
-       int m_loop;
+       const int m_count;
 
        /**
-        * The left samples.
+        * The left loop count.
         */
-       int m_samples;
+       int m_left;
+
+       // hide copy constructor and operator=
+       AUD_LoopReader(const AUD_LoopReader&);
+       AUD_LoopReader& operator=(const AUD_LoopReader&);
 
 public:
        /**
@@ -57,17 +61,12 @@ public:
         * \param reader The reader to read from.
         * \param loop The desired loop count, negative values result in endless
         *        looping.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_LoopReader(AUD_IReader* reader, int loop);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_LoopReader();
-
-       virtual AUD_ReaderType getType();
-       virtual bool notify(AUD_Message &message);
+       virtual void seek(int position);
+       virtual int getLength() const;
+       virtual int getPosition() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 05dc5ff3994d0617031e0655b4d78f48b972c60d..dfef0f6f7c3aa1a3b4f8c756709f6e872ce67309 100644 (file)
@@ -30,22 +30,11 @@ AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
                                                                           float Q) :
                AUD_EffectFactory(factory),
                m_frequency(frequency),
-               m_Q(Q) {}
-
-AUD_LowpassFactory::AUD_LowpassFactory(float frequency, float Q) :
-               AUD_EffectFactory(0),
-               m_frequency(frequency),
-               m_Q(Q) {}
-
-AUD_IReader* AUD_LowpassFactory::createReader()
+               m_Q(Q)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_LowpassReader(reader, m_frequency, m_Q);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_LowpassFactory::createReader() const
+{
+       return new AUD_LowpassReader(getReader(), m_frequency, m_Q);
 }
index 8a419823de02edc1b2274996c26ead7a6b87faa8..61b76510a9e2e3f53b45643284f12b3780f289fc 100644 (file)
@@ -37,12 +37,16 @@ private:
        /**
         * The attack value in seconds.
         */
-       float m_frequency;
+       const float m_frequency;
 
        /**
         * The Q factor.
         */
-       float m_Q;
+       const float m_Q;
+
+       // hide copy constructor and operator=
+       AUD_LowpassFactory(const AUD_LowpassFactory&);
+       AUD_LowpassFactory& operator=(const AUD_LowpassFactory&);
 
 public:
        /**
@@ -53,14 +57,7 @@ public:
         */
        AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
 
-       /**
-        * Creates a new lowpass factory.
-        * \param frequency The cutoff frequency.
-        * \param Q The Q factor.
-        */
-       AUD_LowpassFactory(float frequency, float Q = 1.0f);
-
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_LOWPASSFACTORY
index 6dc0bf66a961d35bde0bd00ff27770f85a40ab8c..71b5de1234d1424b09a3fe23de3b167a51e1b157 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_LowpassReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 #include <cmath>
 
 AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
                                                                         float Q) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
+               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
+               m_position(0)
 {
-       AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_outvalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
-       AUD_NEW("buffer")
-       memset(m_outvalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
+       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
+       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
 
-       m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
-       AUD_NEW("buffer")
-       memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
-
-       m_position = 0;
+       AUD_Specs specs = reader->getSpecs();
 
        // calculate coefficients
        float w0 = 2 * M_PI * frequency / specs.rate;
@@ -65,31 +57,23 @@ AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
        m_coeff[1][1] = (1 - cos(w0)) / norm;
 }
 
-AUD_LowpassReader::~AUD_LowpassReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-
-       delete m_outvalues; AUD_DELETE("buffer")
-       delete m_invalues; AUD_DELETE("buffer");
-}
-
 void AUD_LowpassReader::read(int & length, sample_t* & buffer)
 {
        sample_t* buf;
        sample_t* outvalues;
        sample_t* invalues;
 
-       outvalues = m_outvalues->getBuffer();
-       invalues = m_invalues->getBuffer();
+       outvalues = m_outvalues.getBuffer();
+       invalues = m_invalues.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
 
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
        int channels = specs.channels;
 
        for(int channel = 0; channel < channels; channel++)
index a490ba52c1cfb05886386f7eaa55b6b45f6ab42e..66e4b91b78329c23eb1eea7ba5170316204c6051 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_LOWPASSREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 #define AUD_LOWPASS_ORDER 3
 
@@ -40,17 +40,17 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The last out values buffer.
         */
-       AUD_Buffer *m_outvalues;
+       AUD_Buffer m_outvalues;
 
        /**
         * The last in values buffer.
         */
-       AUD_Buffer *m_invalues;
+       AUD_Buffer m_invalues;
 
        /**
         * The position for buffer cycling.
@@ -62,21 +62,19 @@ private:
         */
        float m_coeff[2][AUD_LOWPASS_ORDER];
 
+       // hide copy constructor and operator=
+       AUD_LowpassReader(const AUD_LowpassReader&);
+       AUD_LowpassReader& operator=(const AUD_LowpassReader&);
+
 public:
        /**
         * Creates a new lowpass reader.
         * \param reader The reader to read from.
         * \param frequency The cutoff frequency.
         * \param Q The Q factor.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_LowpassReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 8b72afe05e72468c56036e02b5b6b9224155a77f..b3aaa9e80a45aaeb64321b1453d6c0247c29dd0e 100644 (file)
 #include "AUD_ReverseFactory.h"
 
 AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
-               AUD_EffectFactory(factory) {}
-
-AUD_IReader* AUD_PingPongFactory::createReader()
+               AUD_EffectFactory(factory)
 {
-       if(m_factory == 0)
-               return 0;
+}
 
-       AUD_IReader* reader = m_factory->createReader();
+AUD_IReader* AUD_PingPongFactory::createReader() const
+{
+       AUD_IReader* reader = getReader();
+       AUD_IReader* reader2;
+       AUD_ReverseFactory factory(m_factory);
 
-       if(reader != 0)
+       try
        {
-               AUD_IReader* reader2;
-               AUD_ReverseFactory factory(m_factory);
-
-               try
-               {
-                       reader2 = factory.createReader();
-               }
-               catch(AUD_Exception)
-               {
-                       reader2 = 0;
-               }
-
-               if(reader2 != 0)
-               {
-                       reader = new AUD_DoubleReader(reader, reader2);
-                       AUD_NEW("reader")
-               }
-               else
-               {
-                       delete reader; AUD_DELETE("reader")
-                       reader = 0;
-               }
+               reader2 = factory.createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader;
+               throw;
        }
 
-       return reader;
+       return new AUD_DoubleReader(reader, reader2);
 }
index b8854da550a85c1518bb06a865ddf0e7d9fe7b08..82aedca8f7f7825cf23f81295adbd426457701d6 100644 (file)
  */
 class AUD_PingPongFactory : public AUD_EffectFactory
 {
+private:
+       // hide copy constructor and operator=
+       AUD_PingPongFactory(const AUD_PingPongFactory&);
+       AUD_PingPongFactory& operator=(const AUD_PingPongFactory&);
+
 public:
        /**
         * Creates a new ping pong factory.
         * \param factory The input factory.
         */
-       AUD_PingPongFactory(AUD_IFactory* factory = 0);
-
-       /**
-        * Destroys the factory.
-        */
+       AUD_PingPongFactory(AUD_IFactory* factory);
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_PINGPONGFACTORY
index 5f814283c12a17b3c0a2d7dd82e2d063dc00403e..be285562db3711615c4e97c8166ff0e8afbd4d33 100644 (file)
 
 AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
                AUD_EffectFactory(factory),
-               m_pitch(pitch) {}
-
-AUD_PitchFactory::AUD_PitchFactory(float pitch) :
-               AUD_EffectFactory(0),
-               m_pitch(pitch) {}
-
-AUD_IReader* AUD_PitchFactory::createReader()
+               m_pitch(pitch)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_PitchReader(reader, m_pitch); AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_PitchFactory::createReader() const
+{
+       return new AUD_PitchReader(getReader(), m_pitch);
 }
index 96c4d0d7e9209832675b5596889b56d585c6969c..52b9b7d99e5ebfa44ddcee808d5d3e2c644fc742 100644 (file)
@@ -37,7 +37,11 @@ private:
        /**
         * The pitch.
         */
-       float m_pitch;
+       const float m_pitch;
+
+       // hide copy constructor and operator=
+       AUD_PitchFactory(const AUD_PitchFactory&);
+       AUD_PitchFactory& operator=(const AUD_PitchFactory&);
 
 public:
        /**
@@ -45,26 +49,9 @@ public:
         * \param factory The input factory.
         * \param pitch The desired pitch.
         */
-       AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0f);
-
-       /**
-        * Creates a new pitch factory.
-        * \param pitch The desired pitch.
-        */
-       AUD_PitchFactory(float pitch);
-
-       /**
-        * Returns the pitch.
-        */
-       float getPitch();
-
-       /**
-        * Sets the pitch.
-        * \param pitch The new pitch value. Should be between 0.0 and 1.0.
-        */
-       void setPitch(float pitch);
+       AUD_PitchFactory(AUD_IFactory* factory, float pitch);
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_PITCHFACTORY
index c53264e1350a72d22a55c96339ae39b92ef51d8b..19c3be31968eb8ef682bcc0b23837855410a08ef 100644 (file)
 #include "AUD_PitchReader.h"
 
 AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader), m_pitch(pitch)
 {
-       m_pitch = pitch;
 }
 
-AUD_Specs AUD_PitchReader::getSpecs()
+AUD_Specs AUD_PitchReader::getSpecs() const
 {
        AUD_Specs specs = m_reader->getSpecs();
        specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
index 440e9cc843c08e7dfe7ef8f97e7954d90ec39d0d..cc188cf0ee4a1fc28c6be3b6a86abdd426fe3478 100644 (file)
@@ -37,18 +37,21 @@ private:
        /**
         * The pitch level.
         */
-       float m_pitch;
+       const float m_pitch;
+
+       // hide copy constructor and operator=
+       AUD_PitchReader(const AUD_PitchReader&);
+       AUD_PitchReader& operator=(const AUD_PitchReader&);
 
 public:
        /**
         * Creates a new pitch reader.
         * \param reader The reader to read from.
         * \param pitch The size of the buffer.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_PitchReader(AUD_IReader* reader, float pitch);
 
-       virtual AUD_Specs getSpecs();
+       virtual AUD_Specs getSpecs() const;
 };
 
 #endif //AUD_PITCHREADER
index f97defd793b6dd8bb92f521aac69612b4f1379a7..52608c3177b6ab21c113e899ddae0af7af817cf0 100644 (file)
 #include "AUD_RectifyReader.h"
 
 AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
-               AUD_EffectFactory(factory) {}
-
-AUD_RectifyFactory::AUD_RectifyFactory() :
-               AUD_EffectFactory(0) {}
-
-AUD_IReader* AUD_RectifyFactory::createReader()
+               AUD_EffectFactory(factory)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_RectifyReader(reader); AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_RectifyFactory::createReader() const
+{
+       return new AUD_RectifyReader(getReader());
 }
index ed00620d3183e99dd8608de37c4566a4a482b278..d8b39e83fdfca7dba12090d4dddcef866a88c86f 100644 (file)
  */
 class AUD_RectifyFactory : public AUD_EffectFactory
 {
+private:
+       // hide copy constructor and operator=
+       AUD_RectifyFactory(const AUD_RectifyFactory&);
+       AUD_RectifyFactory& operator=(const AUD_RectifyFactory&);
+
 public:
        /**
         * Creates a new rectify factory.
         * \param factory The input factory.
         */
-       AUD_RectifyFactory(AUD_IFactory* factory = 0);
-
-       /**
-        * Creates a new rectify factory.
-        */
-       AUD_RectifyFactory();
+       AUD_RectifyFactory(AUD_IFactory* factory);
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_RECTIFYFACTORY
index 5d3ce80e811e58f6eaedc8d34860b8e05d6c7c66..c5bf73fac0316d27758434580254a84f4ee16ec3 100644 (file)
  */
 
 #include "AUD_RectifyReader.h"
-#include "AUD_Buffer.h"
 
 #include <cmath>
 
 AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
                AUD_EffectReader(reader)
 {
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_RectifyReader::~AUD_RectifyReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
 }
 
 void AUD_RectifyReader::read(int & length, sample_t* & buffer)
@@ -45,10 +38,10 @@ void AUD_RectifyReader::read(int & length, sample_t* & buffer)
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 
        for(int i = 0; i < length * specs.channels; i++)
                buffer[i] = fabs(buf[i]);
index afbe2e59cabc1cf466c60e2e18695e2e8dc0ec2e..498f18e50411b2c65ea37970bfd6d2992ec0e24f 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_RECTIFYREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class reads another reader and rectifies it.
@@ -38,21 +38,19 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_RectifyReader(const AUD_RectifyReader&);
+       AUD_RectifyReader& operator=(const AUD_RectifyReader&);
 
 public:
        /**
         * Creates a new rectify reader.
         * \param reader The reader to read from.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_RectifyReader(AUD_IReader* reader);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_RectifyReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 1242641c350928fded7f271ec4f6eac4b26cef00..1002e2de87eb0956305e9e9ad0d13570abfc65d0 100644 (file)
 #include "AUD_Space.h"
 
 AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
-               AUD_EffectFactory(factory) {}
-
-AUD_IReader* AUD_ReverseFactory::createReader()
+               AUD_EffectFactory(factory)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_ReverseReader(reader); AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_ReverseFactory::createReader() const
+{
+       return new AUD_ReverseReader(getReader());
 }
index 4b664c47281db5b5c7e54fdda1d1cf991b8f3c5e..a1995ee68f92c9ca616c4247eae20bf9b4b3bb72 100644 (file)
  */
 class AUD_ReverseFactory : public AUD_EffectFactory
 {
+private:
+       // hide copy constructor and operator=
+       AUD_ReverseFactory(const AUD_ReverseFactory&);
+       AUD_ReverseFactory& operator=(const AUD_ReverseFactory&);
+
 public:
        /**
         * Creates a new reverse factory.
         * \param factory The input factory.
         */
-       AUD_ReverseFactory(AUD_IFactory* factory = 0);
+       AUD_ReverseFactory(AUD_IFactory* factory);
 
-       /**
-        * Destroys the factory.
-        */
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_REVERSEFACTORY
index 82d6c70ce53fa48eafaabddf556286d01aad5cd8..a17a4a64a18ee701960bdb81a4d221e136f2b7f6 100644 (file)
  */
 
 #include "AUD_ReverseReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
 AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_length(reader->getLength()),
+               m_position(0)
 {
-       if(reader->getType() != AUD_TYPE_BUFFER)
+       if(m_length < 0 || !reader->isSeekable())
                AUD_THROW(AUD_ERROR_READER);
-
-       m_length = reader->getLength();
-       if(m_length < 0)
-               AUD_THROW(AUD_ERROR_READER);
-
-       m_position = 0;
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_ReverseReader::~AUD_ReverseReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
 }
 
 void AUD_ReverseReader::seek(int position)
@@ -52,12 +41,12 @@ void AUD_ReverseReader::seek(int position)
        m_position = position;
 }
 
-int AUD_ReverseReader::getLength()
+int AUD_ReverseReader::getLength() const
 {
        return m_length;
 }
 
-int AUD_ReverseReader::getPosition()
+int AUD_ReverseReader::getPosition() const
 {
        return m_position;
 }
@@ -66,7 +55,7 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
 {
        // first correct the length
        if(m_position + length > m_length)
-               length = m_length-m_position;
+               length = m_length - m_position;
 
        if(length <= 0)
        {
@@ -78,10 +67,10 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
        int samplesize = AUD_SAMPLE_SIZE(specs);
 
        // resize buffer if needed
-       if(m_buffer->getSize() < length * samplesize)
-               m_buffer->resize(length * samplesize);
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 
        sample_t* buf;
        int len = length;
@@ -105,5 +94,5 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
 
        m_position += length;
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 }
index 045d2ac5a8ec714c3e5179f14a31f968afbfc7c4..8eb960a5dee7bd89aa33ad051b66f64fcb27bb4f 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_REVERSEREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class reads another reader from back to front.
@@ -37,37 +37,36 @@ class AUD_ReverseReader : public AUD_EffectReader
 {
 private:
        /**
-        * The current position.
+        * The sample count.
         */
-       int m_position;
+       const int m_length;
 
        /**
-        * The sample count.
+        * The current position.
         */
-       int m_length;
+       int m_position;
 
        /**
         * The playback buffer.
         */
-       AUD_Buffer* m_buffer;
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_ReverseReader(const AUD_ReverseReader&);
+       AUD_ReverseReader& operator=(const AUD_ReverseReader&);
 
 public:
        /**
         * Creates a new reverse reader.
         * \param reader The reader to read from.
-        * \exception AUD_Exception Thrown if the reader specified is NULL or not
-        *            a buffer.
+        * \exception AUD_Exception Thrown if the reader specified has an
+        *            undeterminable/infinite length or is not seekable.
         */
        AUD_ReverseReader(AUD_IReader* reader);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_ReverseReader();
-
        virtual void seek(int position);
-       virtual int getLength();
-       virtual int getPosition();
+       virtual int getLength() const;
+       virtual int getPosition() const;
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 638acaa9a327a3c3403f853ee06516fa00d7fdee..b95c9d9bb0f95fa039008406f13722978e2109f0 100644 (file)
 
 AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
                AUD_EffectFactory(factory),
-               m_threshold(threshold) {}
-
-AUD_SquareFactory::AUD_SquareFactory(float threshold) :
-               AUD_EffectFactory(0),
-               m_threshold(threshold) {}
-
-float AUD_SquareFactory::getThreshold()
+               m_threshold(threshold)
 {
-       return m_threshold;
 }
 
-void AUD_SquareFactory::setThreshold(float threshold)
+float AUD_SquareFactory::getThreshold() const
 {
-       m_threshold = threshold;
+       return m_threshold;
 }
 
-AUD_IReader* AUD_SquareFactory::createReader()
+AUD_IReader* AUD_SquareFactory::createReader() const
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_SquareReader(reader, m_threshold); AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_SquareReader(getReader(), m_threshold);
 }
index dfbe5ae2887f9bc4e66d734afcd64d8d112b76d4..da87dc6f8889735b3ed9371df640b2d33df4ebe8 100644 (file)
@@ -37,7 +37,11 @@ private:
        /**
         * The threshold.
         */
-       float m_threshold;
+       const float m_threshold;
+
+       // hide copy constructor and operator=
+       AUD_SquareFactory(const AUD_SquareFactory&);
+       AUD_SquareFactory& operator=(const AUD_SquareFactory&);
 
 public:
        /**
@@ -45,26 +49,14 @@ public:
         * \param factory The input factory.
         * \param threshold The threshold.
         */
-       AUD_SquareFactory(AUD_IFactory* factory = 0, float threshold = 0.0f);
-
-       /**
-        * Creates a new square factory.
-        * \param threshold The threshold.
-        */
-       AUD_SquareFactory(float threshold);
+       AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f);
 
        /**
         * Returns the threshold.
         */
-       float getThreshold();
-
-       /**
-        * Sets the threshold.
-        * \param threshold The new threshold value. Should be between 0.0 and 1.0.
-        */
-       void setThreshold(float threshold);
+       float getThreshold() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_SQUAREFACTORY
index 2d4dc52fe27ec430fa989a7285cd60462c1edd8b..4bf0d87f99b6fcfd2e87ee6b8c06b0716b00459b 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_SquareReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
@@ -32,12 +31,6 @@ AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) :
                AUD_EffectReader(reader),
                m_threshold(threshold)
 {
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_SquareReader::~AUD_SquareReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
 }
 
 void AUD_SquareReader::read(int & length, sample_t* & buffer)
@@ -46,10 +39,11 @@ void AUD_SquareReader::read(int & length, sample_t* & buffer)
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
+
+       buffer = m_buffer.getBuffer();
 
        for(int i = 0; i < length * specs.channels; i++)
        {
index 63dda351445acd0f4996c670c099e38817b6b44f..d3a5331b0e8892e2f16607b4d66de4e80ddc61ff 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_SQUAREREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class changes another signal into a square signal.
@@ -38,27 +38,25 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The threshold level.
         */
-       float m_threshold;
+       const float m_threshold;
+
+       // hide copy constructor and operator=
+       AUD_SquareReader(const AUD_SquareReader&);
+       AUD_SquareReader& operator=(const AUD_SquareReader&);
 
 public:
        /**
         * Creates a new square reader.
         * \param reader The reader to read from.
         * \param threshold The size of the buffer.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_SquareReader(AUD_IReader* reader, float threshold);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_SquareReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
index f7990aab8a162ba2fa5ee8da9760e0cb23475ba6..96ad286bf5c8ffaddd7d700409d5a8f588f879d3 100644 (file)
 #include "AUD_SumReader.h"
 
 AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
-               AUD_EffectFactory(factory) {}
-
-AUD_IReader* AUD_SumFactory::createReader()
+               AUD_EffectFactory(factory)
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_SumReader(reader);
-               AUD_NEW("reader")
-       }
+}
 
-       return reader;
+AUD_IReader* AUD_SumFactory::createReader() const
+{
+       return new AUD_SumReader(getReader());
 }
index 5cb48e26b1042101c4436c742dc8deb2c2d9a14d..045a0a3a625c0fb1fd54620622e5f91e1d67dca3 100644 (file)
  */
 class AUD_SumFactory : public AUD_EffectFactory
 {
+private:
+       // hide copy constructor and operator=
+       AUD_SumFactory(const AUD_SumFactory&);
+       AUD_SumFactory& operator=(const AUD_SumFactory&);
+
 public:
        /**
         * Creates a new sum factory.
         * \param factory The input factory.
         */
-       AUD_SumFactory(AUD_IFactory* factory = 0);
+       AUD_SumFactory(AUD_IFactory* factory);
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_SUMFACTORY
index 08747790fc91b6b100543df934714fa7fde0f8c8..13f0e2271a6a61876b5a9e86d348f7214c711d0d 100644 (file)
  */
 
 #include "AUD_SumReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
 #define CC specs.channels + channel
 
 AUD_SumReader::AUD_SumReader(AUD_IReader* reader) :
-               AUD_EffectReader(reader)
+               AUD_EffectReader(reader),
+               m_sums(AUD_SAMPLE_SIZE(reader->getSpecs()))
 {
-       AUD_Specs specs = reader->getSpecs();
-       int samplesize = AUD_SAMPLE_SIZE(specs);
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-
-       m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer")
-       memset(m_sums->getBuffer(), 0, samplesize);
-}
-
-AUD_SumReader::~AUD_SumReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-       delete m_sums; AUD_DELETE("buffer")
+       memset(m_sums.getBuffer(), 0, m_sums.getSize());
 }
 
 void AUD_SumReader::read(int & length, sample_t* & buffer)
 {
        sample_t* buf;
        sample_t* sums;
-       sums = m_sums->getBuffer();
+       sums = m_sums.getBuffer();
 
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
+
+       buffer = m_buffer.getBuffer();
 
        for(int channel = 0; channel < specs.channels; channel++)
                for(int i = 0; i < length * specs.channels; i++)
index 76ccf2f863a0f82db799fdaad94f7eb8db3660ea..0bb470bac97c8f3c51f2323900cf596c1a6a55c2 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_SUMREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class represents an summer.
@@ -38,26 +38,24 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The sums of the specific channels.
         */
-       AUD_Buffer *m_sums;
+       AUD_Buffer m_sums;
+
+       // hide copy constructor and operator=
+       AUD_SumReader(const AUD_SumReader&);
+       AUD_SumReader& operator=(const AUD_SumReader&);
 
 public:
        /**
         * Creates a new sum reader.
         * \param reader The reader to read from.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_SumReader(AUD_IReader* reader);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_SumReader();
-
        virtual void read(int & length, sample_t* & buffer);
 };
 
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
new file mode 100644 (file)
index 0000000..6bfc112
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * $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_SuperposeFactory.h"
+#include "AUD_SuperposeReader.h"
+
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+               m_factory1(factory1), m_factory2(factory2)
+{
+}
+
+AUD_IReader* AUD_SuperposeFactory::createReader() const
+{
+       AUD_IReader* reader1 = m_factory1->createReader();
+       AUD_IReader* reader2;
+       try
+       {
+               reader2 = m_factory2->createReader();
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               throw;
+       }
+
+       return new AUD_SuperposeReader(reader1, reader2);
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
new file mode 100644 (file)
index 0000000..a7fde2c
--- /dev/null
@@ -0,0 +1,63 @@
+/*
+ * $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_SUPERPOSEFACTORY
+#define AUD_SUPERPOSEFACTORY
+
+#include "AUD_IFactory.h"
+
+/**
+ * This factory plays two other factories behind each other.
+ * \note Readers from the underlying factories must have the same sample rate and channel count.
+ */
+class AUD_SuperposeFactory : public AUD_IFactory
+{
+private:
+       /**
+        * First played factory.
+        */
+       AUD_IFactory* m_factory1;
+
+       /**
+        * Second played factory.
+        */
+       AUD_IFactory* m_factory2;
+
+       // hide copy constructor and operator=
+       AUD_SuperposeFactory(const AUD_SuperposeFactory&);
+       AUD_SuperposeFactory& operator=(const AUD_SuperposeFactory&);
+
+public:
+       /**
+        * Creates a new superpose factory.
+        * \param factory1 The first input factory.
+        * \param factory2 The second input factory.
+        */
+       AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+
+       virtual AUD_IReader* createReader() const;
+};
+
+#endif //AUD_SUPERPOSEFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
new file mode 100644 (file)
index 0000000..c24b01b
--- /dev/null
@@ -0,0 +1,112 @@
+/*
+ * $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_SuperposeReader.h"
+
+#include <cstring>
+
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+       m_reader1(reader1), m_reader2(reader2)
+{
+       try
+       {
+               AUD_Specs s1, s2;
+               s1 = reader1->getSpecs();
+               s2 = reader2->getSpecs();
+               if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
+                       AUD_THROW(AUD_ERROR_READER);
+       }
+       catch(AUD_Exception&)
+       {
+               delete reader1;
+               delete reader2;
+
+               throw;
+       }
+}
+
+AUD_SuperposeReader::~AUD_SuperposeReader()
+{
+       delete m_reader1;
+       delete m_reader2;
+}
+
+bool AUD_SuperposeReader::isSeekable() const
+{
+       return m_reader1->isSeekable() && m_reader2->isSeekable();
+}
+
+void AUD_SuperposeReader::seek(int position)
+{
+       m_reader1->seek(position);
+       m_reader2->seek(position);
+}
+
+int AUD_SuperposeReader::getLength() const
+{
+       int len1 = m_reader1->getLength();
+       int len2 = m_reader2->getLength();
+       if((len1 < 0) || (len2 < 0))
+               return -1;
+       return AUD_MIN(len1, len2);
+}
+
+int AUD_SuperposeReader::getPosition() const
+{
+       int pos1 = m_reader1->getPosition();
+       int pos2 = m_reader2->getPosition();
+       return AUD_MAX(pos1, pos2);
+}
+
+AUD_Specs AUD_SuperposeReader::getSpecs() const
+{
+       return m_reader1->getSpecs();
+}
+
+void AUD_SuperposeReader::read(int & length, sample_t* & buffer)
+{
+       AUD_Specs specs = m_reader1->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
+
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
+       buffer = m_buffer.getBuffer();
+
+       int len1 = length;
+       sample_t* buf;
+       m_reader1->read(len1, buf);
+       memcpy(buffer, buf, len1 * samplesize);
+
+       if(len1 < length)
+               memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
+
+       int len2 = length;
+       m_reader2->read(len2, buf);
+
+       for(int i = 0; i < len2 * specs.channels; i++)
+               buffer[i] += buf[i];
+
+       length = AUD_MAX(len1, len2);
+}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
new file mode 100644 (file)
index 0000000..eeceb9a
--- /dev/null
@@ -0,0 +1,79 @@
+/*
+ * $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_SUPERPOSEREADER
+#define AUD_SUPERPOSEREADER
+
+#include "AUD_IReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This reader plays two readers with the same specs sequently.
+ */
+class AUD_SuperposeReader : public AUD_IReader
+{
+private:
+       /**
+        * The first reader.
+        */
+       AUD_IReader* m_reader1;
+
+       /**
+        * The second reader.
+        */
+       AUD_IReader* m_reader2;
+
+       /**
+        * The playback buffer for the intersecting part.
+        */
+       AUD_Buffer m_buffer;
+
+       // hide copy constructor and operator=
+       AUD_SuperposeReader(const AUD_SuperposeReader&);
+       AUD_SuperposeReader& operator=(const AUD_SuperposeReader&);
+
+public:
+       /**
+        * Creates a new superpose reader.
+        * \param reader1 The first reader to read from.
+        * \param reader2 The second reader to read from.
+        * \exception AUD_Exception Thrown if the specs from the readers differ.
+        */
+       AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+
+       /**
+        * Destroys the reader.
+        */
+       virtual ~AUD_SuperposeReader();
+
+       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_SUPERPOSEREADER
index fbde608aa122c69f92d6d1772cd4d2a4c82cc3b3..9f0fd5821fd41bc028b1f3509a386f24c7a764d0 100644 (file)
 
 AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
                AUD_EffectFactory(factory),
-               m_volume(volume) {}
-
-AUD_VolumeFactory::AUD_VolumeFactory(float volume) :
-               AUD_EffectFactory(0),
-               m_volume(volume) {}
-
-float AUD_VolumeFactory::getVolume()
+               m_volume(volume)
 {
-       return m_volume;
 }
 
-void AUD_VolumeFactory::setVolume(float volume)
+float AUD_VolumeFactory::getVolume() const
 {
-       m_volume = volume;
+       return m_volume;
 }
 
-AUD_IReader* AUD_VolumeFactory::createReader()
+AUD_IReader* AUD_VolumeFactory::createReader() const
 {
-       AUD_IReader* reader = getReader();
-
-       if(reader != 0)
-       {
-               reader = new AUD_VolumeReader(reader, m_volume); AUD_NEW("reader")
-       }
-
-       return reader;
+       return new AUD_VolumeReader(getReader(), m_volume);
 }
index 09f91241b4705c483a508236e89b191ff89a0187..a086aab4640ab4e74e4ff9d4a1f710d7faa5c537 100644 (file)
@@ -39,7 +39,11 @@ private:
        /**
         * The volume.
         */
-       float m_volume;
+       const float m_volume;
+
+       // hide copy constructor and operator=
+       AUD_VolumeFactory(const AUD_VolumeFactory&);
+       AUD_VolumeFactory& operator=(const AUD_VolumeFactory&);
 
 public:
        /**
@@ -47,26 +51,14 @@ public:
         * \param factory The input factory.
         * \param volume The desired volume.
         */
-       AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0f);
-
-       /**
-        * Creates a new volume factory.
-        * \param volume The desired volume.
-        */
-       AUD_VolumeFactory(float volume);
+       AUD_VolumeFactory(AUD_IFactory* factory, float volume);
 
        /**
         * Returns the volume.
         */
-       float getVolume();
-
-       /**
-        * Sets the volume.
-        * \param volume The new volume value. Should be between 0.0 and 1.0.
-        */
-       void setVolume(float volume);
+       float getVolume() const;
 
-       virtual AUD_IReader* createReader();
+       virtual AUD_IReader* createReader() const;
 };
 
 #endif //AUD_VOLUMEFACTORY
index f094c1e4ea3bdbcf43a6362201acda28a1985562..7401b508b28596f0ea900d736f77accb12133438 100644 (file)
@@ -24,7 +24,6 @@
  */
 
 #include "AUD_VolumeReader.h"
-#include "AUD_Buffer.h"
 
 #include <cstring>
 
@@ -32,25 +31,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
                AUD_EffectReader(reader),
                m_volume(volume)
 {
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_VolumeReader::~AUD_VolumeReader()
-{
-       delete m_buffer; AUD_DELETE("buffer")
-}
-
-bool AUD_VolumeReader::notify(AUD_Message &message)
-{
-       if(message.type == AUD_MSG_VOLUME)
-       {
-               m_volume = message.volume;
-
-               m_reader->notify(message);
-
-               return true;
-       }
-       return m_reader->notify(message);
 }
 
 void AUD_VolumeReader::read(int & length, sample_t* & buffer)
@@ -59,10 +39,10 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer)
        AUD_Specs specs = m_reader->getSpecs();
 
        m_reader->read(length, buf);
-       if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs))
-               m_buffer->resize(length*AUD_SAMPLE_SIZE(specs));
+       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
+               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
 
-       buffer = m_buffer->getBuffer();
+       buffer = m_buffer.getBuffer();
 
        for(int i = 0; i < length * specs.channels; i++)
                buffer[i] = buf[i] * m_volume;
index 489f85b10f214d63d364b95eea0566b3ebde7b3d..0e96a27e2879223ee93775a110dec421fdb3ff3d 100644 (file)
@@ -27,7 +27,7 @@
 #define AUD_VOLUMEREADER
 
 #include "AUD_EffectReader.h"
-class AUD_Buffer;
+#include "AUD_Buffer.h"
 
 /**
  * This class reads another reader and changes it's volume.
@@ -38,28 +38,25 @@ private:
        /**
         * The playback buffer.
         */
-       AUD_Buffer *m_buffer;
+       AUD_Buffer m_buffer;
 
        /**
         * The volume level.
         */
-       float m_volume;
+       const float m_volume;
+
+       // hide copy constructor and operator=
+       AUD_VolumeReader(const AUD_VolumeReader&);
+       AUD_VolumeReader& operator=(const AUD_VolumeReader&);
 
 public:
        /**
         * Creates a new volume reader.
         * \param reader The reader to read from.
         * \param volume The size of the buffer.
-        * \exception AUD_Exception Thrown if the reader specified is NULL.
         */
        AUD_VolumeReader(AUD_IReader* reader, float volume);
 
-       /**
-        * Destroys the reader.
-        */
-       virtual ~AUD_VolumeReader();
-
-       virtual bool notify(AUD_Message &message);
        virtual void read(int & length, sample_t* & buffer);
 };
 
index 796764989ba22d58bae29b682d696a91a7694de0..6d1f9a5527b27e8d43247f76afd89e1477113629 100644 (file)
@@ -24,9 +24,9 @@
  */
 
 #include "AUD_OpenALDevice.h"
+#include "AUD_IFactory.h"
 #include "AUD_IReader.h"
-#include "AUD_ConverterFactory.h"
-#include "AUD_SourceCaps.h"
+#include "AUD_ConverterReader.h"
 
 #include <cstring>
 #include <limits>
@@ -302,12 +302,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
 
        // check for specific formats and channel counts to be played back
        if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
-       {
                specs.format = AUD_FORMAT_FLOAT32;
-               m_converter = NULL;
-       }
-       else
-               m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
 
        m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
 
@@ -317,10 +312,9 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
        m_buffersize = buffersize;
        m_playing = false;
 
-       m_playingSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
-       m_pausedSounds = new std::list<AUD_OpenALHandle*>(); AUD_NEW("list")
+       m_playingSounds = new std::list<AUD_OpenALHandle*>();
+       m_pausedSounds = new std::list<AUD_OpenALHandle*>();
        m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
-       AUD_NEW("list")
 
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
@@ -345,10 +339,10 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
                alDeleteSources(1, &sound->source);
                if(!sound->isBuffered)
                {
-                       delete sound->reader; AUD_DELETE("reader")
+                       delete sound->reader;
                        alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
                }
-               delete sound; AUD_DELETE("handle")
+               delete sound;
                m_playingSounds->erase(m_playingSounds->begin());
        }
 
@@ -359,10 +353,10 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
                alDeleteSources(1, &sound->source);
                if(!sound->isBuffered)
                {
-                       delete sound->reader; AUD_DELETE("reader")
+                       delete sound->reader;
                        alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
                }
-               delete sound; AUD_DELETE("handle")
+               delete sound;
                m_pausedSounds->erase(m_pausedSounds->begin());
        }
 
@@ -370,7 +364,7 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
        while(!m_bufferedFactories->empty())
        {
                alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
-               delete *m_bufferedFactories->begin(); AUD_DELETE("bufferedfactory");
+               delete *m_bufferedFactories->begin();
                m_bufferedFactories->erase(m_bufferedFactories->begin());
        }
 
@@ -385,22 +379,19 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
        else
                unlock();
 
-       delete m_playingSounds; AUD_DELETE("list")
-       delete m_pausedSounds; AUD_DELETE("list")
-       delete m_bufferedFactories; AUD_DELETE("list")
+       delete m_playingSounds;
+       delete m_pausedSounds;
+       delete m_bufferedFactories;
 
        // quit OpenAL
        alcMakeContextCurrent(NULL);
        alcDestroyContext(m_context);
        alcCloseDevice(m_device);
 
-       if(m_converter)
-               delete m_converter; AUD_DELETE("factory")
-
        pthread_mutex_destroy(&m_mutex);
 }
 
-AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
+AUD_DeviceSpecs AUD_OpenALDevice::getSpecs() const
 {
        return m_specs;
 }
@@ -511,7 +502,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                        if((*i)->factory == factory)
                        {
                                // create the handle
-                               sound = new AUD_OpenALHandle; AUD_NEW("handle")
+                               sound = new AUD_OpenALHandle;
                                sound->keep = keep;
                                sound->current = -1;
                                sound->isBuffered = true;
@@ -532,15 +523,15 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                                                if(alGetError() != AL_NO_ERROR)
                                                        AUD_THROW(AUD_ERROR_OPENAL);
                                        }
-                                       catch(AUD_Exception)
+                                       catch(AUD_Exception&)
                                        {
                                                alDeleteSources(1, &sound->source);
                                                throw;
                                        }
                                }
-                               catch(AUD_Exception)
+                               catch(AUD_Exception&)
                                {
-                                       delete sound; AUD_DELETE("handle")
+                                       delete sound;
                                        alcProcessContext(m_context);
                                        throw;
                                }
@@ -555,7 +546,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                        }
                }
        }
-       catch(AUD_Exception)
+       catch(AUD_Exception&)
        {
                unlock();
                throw;
@@ -577,14 +568,11 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        // check format
        bool valid = specs.channels != AUD_CHANNELS_INVALID;
 
-       if(m_converter)
-       {
-               m_converter->setReader(reader);
-               reader = m_converter->createReader();
-       }
+       if(m_specs.format != AUD_FORMAT_FLOAT32)
+               reader = new AUD_ConverterReader(reader, m_specs);
 
        // create the handle
-       sound = new AUD_OpenALHandle; AUD_NEW("handle")
+       sound = new AUD_OpenALHandle;
        sound->keep = keep;
        sound->reader = reader;
        sound->current = 0;
@@ -595,8 +583,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
 
        if(!valid)
        {
-               delete sound; AUD_DELETE("handle")
-               delete reader; AUD_DELETE("reader")
+               delete sound;
+               delete reader;
                return NULL;
        }
 
@@ -637,22 +625,22 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                                if(alGetError() != AL_NO_ERROR)
                                        AUD_THROW(AUD_ERROR_OPENAL);
                        }
-                       catch(AUD_Exception)
+                       catch(AUD_Exception&)
                        {
                                alDeleteSources(1, &sound->source);
                                throw;
                        }
                }
-               catch(AUD_Exception)
+               catch(AUD_Exception&)
                {
                        alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
                        throw;
                }
        }
-       catch(AUD_Exception)
+       catch(AUD_Exception&)
        {
-               delete sound; AUD_DELETE("handle")
-               delete reader; AUD_DELETE("reader")
+               delete sound;
+               delete reader;
                alcProcessContext(m_context);
                unlock();
                throw;
@@ -737,10 +725,10 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
                        alDeleteSources(1, &sound->source);
                        if(!sound->isBuffered)
                        {
-                               delete sound->reader; AUD_DELETE("reader")
+                               delete sound->reader;
                                alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
                        }
-                       delete *i; AUD_DELETE("handle")
+                       delete *i;
                        m_playingSounds->erase(i);
                        result = true;
                        break;
@@ -757,10 +745,10 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
                                alDeleteSources(1, &sound->source);
                                if(!sound->isBuffered)
                                {
-                                       delete sound->reader; AUD_DELETE("reader")
+                                       delete sound->reader;
                                        alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
                                }
-                               delete *i; AUD_DELETE("handle")
+                               delete *i;
                                m_pausedSounds->erase(i);
                                result = true;
                                break;
@@ -773,43 +761,31 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
        return result;
 }
 
-bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
+bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
 {
        bool result = false;
 
        lock();
 
        if(isValid(handle))
-       {
-               ((AUD_OpenALHandle*)handle)->keep = keep;
-               result = true;
-       }
+               result = ((AUD_OpenALHandle*)handle)->keep;
 
        unlock();
 
        return result;
 }
 
-bool AUD_OpenALDevice::sendMessage(AUD_Handle* handle, AUD_Message &message)
+bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
 {
        bool result = false;
 
        lock();
 
-       if(handle == 0)
+       if(isValid(handle))
        {
-               for(AUD_HandleIterator i = m_playingSounds->begin();
-                       i != m_playingSounds->end(); i++)
-                       if(!(*i)->isBuffered)
-                               result |= (*i)->reader->notify(message);
-               for(AUD_HandleIterator i = m_pausedSounds->begin();
-                       i != m_pausedSounds->end(); i++)
-                       if(!(*i)->isBuffered)
-                               result |= (*i)->reader->notify(message);
+               ((AUD_OpenALHandle*)handle)->keep = keep;
+               result = true;
        }
-       else if(isValid(handle))
-               if(!((AUD_OpenALHandle*)handle)->isBuffered)
-                       result = ((AUD_OpenALHandle*)handle)->reader->notify(message);
 
        unlock();
 
@@ -947,440 +923,623 @@ void AUD_OpenALDevice::unlock()
        pthread_mutex_unlock(&m_mutex);
 }
 
-/******************************************************************************/
-/**************************** Capabilities Code *******************************/
-/******************************************************************************/
+float AUD_OpenALDevice::getVolume() const
+{
+       float result;
+       alGetListenerf(AL_GAIN, &result);
+       return result;
+}
+
+void AUD_OpenALDevice::setVolume(float volume)
+{
+       alListenerf(AL_GAIN, volume);
+}
+
+float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
+{
+       lock();
+       float result = std::numeric_limits<float>::quiet_NaN();
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
+       unlock();
+       return result;
+}
 
-bool AUD_OpenALDevice::checkCapability(int capability)
+bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
 {
-       return capability == AUD_CAPS_3D_DEVICE ||
-                  capability == AUD_CAPS_VOLUME ||
-                  capability == AUD_CAPS_SOURCE_VOLUME ||
-                  capability == AUD_CAPS_SOURCE_PITCH ||
-                  capability == AUD_CAPS_BUFFERED_FACTORY;
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
+       unlock();
+       return result;
 }
 
-bool AUD_OpenALDevice::setCapability(int capability, void *value)
+float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
+{
+       lock();
+       float result = std::numeric_limits<float>::quiet_NaN();
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
+{
+       lock();
+       bool result = isValid(handle);
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
+       unlock();
+       return result;
+}
+
+/* AUD_XXX Temorary disabled
+
+bool AUD_OpenALDevice::bufferFactory(void *value)
 {
        bool result = false;
-       switch(capability)
+       AUD_IFactory* factory = (AUD_IFactory*) value;
+
+       // load the factory into an OpenAL buffer
+       if(factory)
        {
-       case AUD_CAPS_VOLUME:
-               alListenerf(AL_GAIN, *((float*)value));
-               return true;
-       case AUD_CAPS_SOURCE_VOLUME:
+               // check if the factory is already buffered
+               lock();
+               for(AUD_BFIterator i = m_bufferedFactories->begin();
+                       i != m_bufferedFactories->end(); i++)
                {
-                       AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
-                       lock();
-                       if(isValid(caps->handle))
+                       if((*i)->factory == factory)
                        {
-                               alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
-                                                 AL_GAIN, caps->value);
                                result = true;
+                               break;
                        }
-                       unlock();
                }
-               break;
-       case AUD_CAPS_SOURCE_PITCH:
+               unlock();
+               if(result)
+                       return result;
+
+               AUD_IReader* reader = factory->createReader();
+
+               if(reader == NULL)
+                       return false;
+
+               AUD_DeviceSpecs specs = m_specs;
+               specs.specs = reader->getSpecs();
+
+               if(m_specs.format != AUD_FORMAT_FLOAT32)
+                       reader = new AUD_ConverterReader(reader, m_specs);
+
+               ALenum format;
+
+               if(!getFormat(format, specs.specs))
                {
-                       AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
-                       lock();
-                       if(isValid(caps->handle))
-                       {
-                               alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
-                                                 AL_PITCH, caps->value);
-                               result = true;
-                       }
-                       unlock();
+                       delete reader;
+                       return false;
                }
-               break;
-       case AUD_CAPS_BUFFERED_FACTORY:
+
+               // load into a buffer
+               lock();
+               alcSuspendContext(m_context);
+
+               AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
+               bf->factory = factory;
+
+               try
                {
-                       AUD_IFactory* factory = (AUD_IFactory*) value;
+                       alGenBuffers(1, &bf->buffer);
+                       if(alGetError() != AL_NO_ERROR)
+                               AUD_THROW(AUD_ERROR_OPENAL);
 
-                       // load the factory into an OpenAL buffer
-                       if(factory)
+                       try
                        {
-                               // check if the factory is already buffered
-                               lock();
-                               for(AUD_BFIterator i = m_bufferedFactories->begin();
-                                       i != m_bufferedFactories->end(); i++)
-                               {
-                                       if((*i)->factory == factory)
-                                       {
-                                               result = true;
-                                               break;
-                                       }
-                               }
-                               unlock();
-                               if(result)
-                                       return result;
+                               sample_t* buf;
+                               int length = reader->getLength();
 
-                               AUD_IReader* reader = factory->createReader();
+                               reader->read(length, buf);
+                               alBufferData(bf->buffer, format, buf,
+                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                        specs.rate);
+                               if(alGetError() != AL_NO_ERROR)
+                                       AUD_THROW(AUD_ERROR_OPENAL);
+                       }
+                       catch(AUD_Exception&)
+                       {
+                               alDeleteBuffers(1, &bf->buffer);
+                               throw;
+                       }
+               }
+               catch(AUD_Exception&)
+               {
+                       delete bf;
+                       delete reader;
+                       alcProcessContext(m_context);
+                       unlock();
+                       return false;
+               }
 
-                               if(reader == NULL)
-                                       return false;
+               m_bufferedFactories->push_back(bf);
 
-                               AUD_DeviceSpecs specs = m_specs;
-                               specs.specs = reader->getSpecs();
+               alcProcessContext(m_context);
+               unlock();
+       }
+       else
+       {
+               // stop all playing and paused buffered sources
+               lock();
+               alcSuspendContext(m_context);
 
-                               // determine format
-                               bool valid = reader->getType() == AUD_TYPE_BUFFER;
+               AUD_OpenALHandle* sound;
+               AUD_HandleIterator it = m_playingSounds->begin();
+               while(it != m_playingSounds->end())
+               {
+                       sound = *it;
+                       ++it;
 
-                               if(valid)
-                               {
-                                       if(m_converter)
-                                       {
-                                               m_converter->setReader(reader);
-                                               reader = m_converter->createReader();
-                                       }
-                               }
+                       if(sound->isBuffered)
+                               stop(sound);
+               }
+               alcProcessContext(m_context);
 
-                               ALenum format;
+               while(!m_bufferedFactories->empty())
+               {
+                       alDeleteBuffers(1,
+                                                       &(*(m_bufferedFactories->begin()))->buffer);
+                       delete *m_bufferedFactories->begin();
+                       m_bufferedFactories->erase(m_bufferedFactories->begin());
+               }
+               unlock();
+       }
 
-                               if(valid)
-                                       valid = getFormat(format, specs.specs);
+       return true;
+}*/
 
-                               if(!valid)
-                               {
-                                       delete reader; AUD_DELETE("reader")
-                                       return false;
-                               }
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
 
-                               // load into a buffer
-                               lock();
-                               alcSuspendContext(m_context);
+AUD_Vector3 AUD_OpenALDevice::getListenerLocation() const
+{
+       ALfloat p[3];
+       alGetListenerfv(AL_POSITION, p);
+       return AUD_Vector3(p[0], p[1], p[2]);
+}
 
-                               AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
-                               AUD_NEW("bufferedfactory");
-                               bf->factory = factory;
+void AUD_OpenALDevice::setListenerLocation(const AUD_Vector3& location)
+{
+       alListenerfv(AL_POSITION, (ALfloat*)location.get());
+}
 
-                               try
-                               {
-                                       alGenBuffers(1, &bf->buffer);
-                                       if(alGetError() != AL_NO_ERROR)
-                                               AUD_THROW(AUD_ERROR_OPENAL);
+AUD_Vector3 AUD_OpenALDevice::getListenerVelocity() const
+{
+       ALfloat v[3];
+       alGetListenerfv(AL_VELOCITY, v);
+       return AUD_Vector3(v[0], v[1], v[2]);
+}
 
-                                       try
-                                       {
-                                               sample_t* buf;
-                                               int length = reader->getLength();
+void AUD_OpenALDevice::setListenerVelocity(const AUD_Vector3& velocity)
+{
+       alListenerfv(AL_VELOCITY, (ALfloat*)velocity.get());
+}
 
-                                               reader->read(length, buf);
-                                               alBufferData(bf->buffer, format, buf,
-                                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
-                                                                        specs.rate);
-                                               if(alGetError() != AL_NO_ERROR)
-                                                       AUD_THROW(AUD_ERROR_OPENAL);
-                                       }
-                                       catch(AUD_Exception)
-                                       {
-                                               alDeleteBuffers(1, &bf->buffer);
-                                               throw;
-                                       }
-                               }
-                               catch(AUD_Exception)
-                               {
-                                       delete bf; AUD_DELETE("bufferedfactory")
-                                       delete reader; AUD_DELETE("reader")
-                                       alcProcessContext(m_context);
-                                       unlock();
-                                       return false;
-                               }
+AUD_Quaternion AUD_OpenALDevice::getListenerOrientation() const
+{
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
+}
 
-                               m_bufferedFactories->push_back(bf);
+void AUD_OpenALDevice::setListenerOrientation(const AUD_Quaternion& orientation)
+{
+       ALfloat direction[6];
+       direction[0] = -2 * (orientation.w() * orientation.y() +
+                                                orientation.x() * orientation.z());
+       direction[1] = 2 * (orientation.x() * orientation.w() -
+                                               orientation.z() * orientation.y());
+       direction[2] = 2 * (orientation.x() * orientation.x() +
+                                               orientation.y() * orientation.y()) - 1;
+       direction[3] = 2 * (orientation.x() * orientation.y() -
+                                               orientation.w() * orientation.z());
+       direction[4] = 1 - 2 * (orientation.x() * orientation.x() +
+                                                       orientation.z() * orientation.z());
+       direction[5] = 2 * (orientation.w() * orientation.x() +
+                                               orientation.y() * orientation.z());
+       alListenerfv(AL_ORIENTATION, direction);
+}
 
-                               alcProcessContext(m_context);
-                               unlock();
-                       }
-                       else
-                       {
-                               // stop all playing and paused buffered sources
-                               lock();
-                               alcSuspendContext(m_context);
+float AUD_OpenALDevice::getSpeedOfSound() const
+{
+       return alGetFloat(AL_SPEED_OF_SOUND);
+}
 
-                               AUD_OpenALHandle* sound;
-                               AUD_HandleIterator it = m_playingSounds->begin();
-                               while(it != m_playingSounds->end())
-                               {
-                                       sound = *it;
-                                       ++it;
+void AUD_OpenALDevice::setSpeedOfSound(float speed)
+{
+       alSpeedOfSound(speed);
+}
 
-                                       if(sound->isBuffered)
-                                               stop(sound);
-                               }
-                               alcProcessContext(m_context);
+float AUD_OpenALDevice::getDopplerFactor() const
+{
+       return alGetFloat(AL_DOPPLER_FACTOR);
+}
 
-                               while(!m_bufferedFactories->empty())
-                               {
-                                       alDeleteBuffers(1,
-                                                                       &(*(m_bufferedFactories->begin()))->buffer);
-                                       delete *m_bufferedFactories->begin();
-                                       AUD_DELETE("bufferedfactory");
-                                       m_bufferedFactories->erase(m_bufferedFactories->begin());
-                               }
-                               unlock();
-                       }
+void AUD_OpenALDevice::setDopplerFactor(float factor)
+{
+       alDopplerFactor(factor);
+}
 
-                       return true;
-               }
-               break;
+AUD_DistanceModel AUD_OpenALDevice::getDistanceModel() const
+{
+       switch(alGetInteger(AL_DISTANCE_MODEL))
+       {
+       case AL_INVERSE_DISTANCE:
+               return AUD_DISTANCE_MODEL_INVERSE;
+       case AL_INVERSE_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
+       case AL_LINEAR_DISTANCE:
+               return AUD_DISTANCE_MODEL_LINEAR;
+       case AL_LINEAR_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
+       case AL_EXPONENT_DISTANCE:
+               return AUD_DISTANCE_MODEL_EXPONENT;
+       case AL_EXPONENT_DISTANCE_CLAMPED:
+               return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
+       default:
+               return AUD_DISTANCE_MODEL_INVALID;
        }
-       return result;
 }
 
-bool AUD_OpenALDevice::getCapability(int capability, void *value)
+void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
 {
-       bool result = false;
-
-       switch(capability)
+       switch(model)
        {
-       case AUD_CAPS_VOLUME:
-               alGetListenerf(AL_GAIN, (float*)value);
-               return true;
-       case AUD_CAPS_SOURCE_VOLUME:
-               {
-                       AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
-                       lock();
-                       if(isValid(caps->handle))
-                       {
-                               alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
-                                                 AL_GAIN, &caps->value);
-                               result = true;
-                       }
-                       unlock();
-               }
+       case AUD_DISTANCE_MODEL_INVERSE:
+               alDistanceModel(AL_INVERSE_DISTANCE);
                break;
-       case AUD_CAPS_SOURCE_PITCH:
-               {
-                       AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
-                       lock();
-                       if(isValid(caps->handle))
-                       {
-                               alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
-                                                 AL_PITCH, &caps->value);
-                               result = true;
-                       }
-                       unlock();
-               }
+       case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
+               alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR:
+               alDistanceModel(AL_LINEAR_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
+               alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
                break;
+       case AUD_DISTANCE_MODEL_EXPONENT:
+               alDistanceModel(AL_EXPONENT_DISTANCE);
+               break;
+       case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
+               alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
+               break;
+       default:
+               alDistanceModel(AL_NONE);
+       }
+}
+
+AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
+{
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+       ALfloat p[3];
+       lock();
+
+       if(isValid(handle))
+       {
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
+               result = AUD_Vector3(p[0], p[1], p[2]);
        }
 
+       unlock();
        return result;
 }
 
-/******************************************************************************/
-/**************************** 3D Device Code **********************************/
-/******************************************************************************/
+bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
+                                  (ALfloat*)location.get());
 
-AUD_Handle* AUD_OpenALDevice::play3D(AUD_IFactory* factory, bool keep)
+       unlock();
+       return result;
+}
+
+AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
 {
-       AUD_OpenALHandle* handle = (AUD_OpenALHandle*)play(factory, keep);
-       if(handle)
-               alSourcei(handle->source, AL_SOURCE_RELATIVE, 0);
-       return handle;
+       AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+       ALfloat v[3];
+       lock();
+
+       if(isValid(handle))
+       {
+               alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
+               result = AUD_Vector3(v[0], v[1], v[2]);
+       }
+
+       unlock();
+       return result;
 }
 
-bool AUD_OpenALDevice::updateListener(AUD_3DData &data)
+bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
 {
-       alListenerfv(AL_POSITION, (ALfloat*)data.position);
-       alListenerfv(AL_VELOCITY, (ALfloat*)data.velocity);
-       alListenerfv(AL_ORIENTATION, (ALfloat*)&(data.orientation[3]));
+       lock();
+       bool result = isValid(handle);
 
-       return true;
+       if(result)
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
+                                  (ALfloat*)velocity.get());
+
+       unlock();
+       return result;
 }
 
-bool AUD_OpenALDevice::setSetting(AUD_3DSetting setting, float value)
+AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
 {
-       switch(setting)
-       {
-       case AUD_3DS_DISTANCE_MODEL:
-               if(value == AUD_DISTANCE_MODEL_NONE)
-                       alDistanceModel(AL_NONE);
-               else if(value == AUD_DISTANCE_MODEL_INVERSE)
-                       alDistanceModel(AL_INVERSE_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_INVERSE_CLAMPED)
-                       alDistanceModel(AL_INVERSE_DISTANCE_CLAMPED);
-               else if(value == AUD_DISTANCE_MODEL_LINEAR)
-                       alDistanceModel(AL_LINEAR_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_LINEAR_CLAMPED)
-                       alDistanceModel(AL_LINEAR_DISTANCE_CLAMPED);
-               else if(value == AUD_DISTANCE_MODEL_EXPONENT)
-                       alDistanceModel(AL_EXPONENT_DISTANCE);
-               else if(value == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
-                       alDistanceModel(AL_EXPONENT_DISTANCE_CLAMPED);
-               else
-                       return false;
-               return true;
-       case AUD_3DS_DOPPLER_FACTOR:
-               alDopplerFactor(value);
-               return true;
-       case AUD_3DS_SPEED_OF_SOUND:
-               alSpeedOfSound(value);
-               return true;
-       default:
-               return false;
-       }
+       // AUD_XXX not implemented yet
+       return AUD_Quaternion(0, 0, 0, 0);
 }
 
-float AUD_OpenALDevice::getSetting(AUD_3DSetting setting)
+bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
 {
-       switch(setting)
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
        {
-       case AUD_3DS_DISTANCE_MODEL:
-               switch(alGetInteger(AL_DISTANCE_MODEL))
-               {
-                       case AL_NONE:
-                               return AUD_DISTANCE_MODEL_NONE;
-                       case AL_INVERSE_DISTANCE:
-                               return AUD_DISTANCE_MODEL_INVERSE;
-                       case AL_INVERSE_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
-                       case AL_LINEAR_DISTANCE:
-                               return AUD_DISTANCE_MODEL_LINEAR;
-                       case AL_LINEAR_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_LINEAR_CLAMPED;
-                       case AL_EXPONENT_DISTANCE:
-                               return AUD_DISTANCE_MODEL_EXPONENT;
-                       case AL_EXPONENT_DISTANCE_CLAMPED:
-                               return AUD_DISTANCE_MODEL_EXPONENT_CLAMPED;
-               }
-       case AUD_3DS_DOPPLER_FACTOR:
-               return alGetFloat(AL_DOPPLER_FACTOR);
-       case AUD_3DS_SPEED_OF_SOUND:
-               return alGetFloat(AL_SPEED_OF_SOUND);
-       default:
-               return std::numeric_limits<float>::quiet_NaN();
+               ALfloat direction[3];
+               direction[0] = -2 * (orientation.w() * orientation.y() +
+                                                        orientation.x() * orientation.z());
+               direction[1] = 2 * (orientation.x() * orientation.w() -
+                                                       orientation.z() * orientation.y());
+               direction[2] = 2 * (orientation.x() * orientation.x() +
+                                                       orientation.y() * orientation.y()) - 1;
+               alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
+                                  direction);
        }
+
+       unlock();
+       return result;
 }
 
-bool AUD_OpenALDevice::updateSource(AUD_Handle* handle, AUD_3DData &data)
+bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
 {
-       bool result = false;
+       int result = std::numeric_limits<float>::quiet_NaN();;
 
        lock();
 
        if(isValid(handle))
-       {
-               int source = ((AUD_OpenALHandle*)handle)->source;
-               alSourcefv(source, AL_POSITION, (ALfloat*)data.position);
-               alSourcefv(source, AL_VELOCITY, (ALfloat*)data.velocity);
-               alSourcefv(source, AL_DIRECTION, (ALfloat*)&(data.orientation[3]));
-               result = true;
-       }
+               alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
+                                 relative);
 
        unlock();
+       return result;
+}
 
+float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
+                                        &result);
+
+       unlock();
        return result;
 }
 
-bool AUD_OpenALDevice::setSourceSetting(AUD_Handle* handle,
-                                                                               AUD_3DSourceSetting setting,
-                                                                               float value)
+bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
 {
        lock();
+       bool result = isValid(handle);
 
-       bool result = false;
+       if(result)
+
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
+                                 volume);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
 
        if(isValid(handle))
-       {
-               int source = ((AUD_OpenALHandle*)handle)->source;
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
+                                        &result);
 
-               switch(setting)
-               {
-               case AUD_3DSS_CONE_INNER_ANGLE:
-                       alSourcef(source, AL_CONE_INNER_ANGLE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_CONE_OUTER_ANGLE:
-                       alSourcef(source, AL_CONE_OUTER_ANGLE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_CONE_OUTER_GAIN:
-                       alSourcef(source, AL_CONE_OUTER_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_IS_RELATIVE:
-                       alSourcei(source, AL_SOURCE_RELATIVE, value > 0.0f);
-                       result = true;
-                       break;
-               case AUD_3DSS_MAX_DISTANCE:
-                       alSourcef(source, AL_MAX_DISTANCE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_MAX_GAIN:
-                       alSourcef(source, AL_MAX_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_MIN_GAIN:
-                       alSourcef(source, AL_MIN_GAIN, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_REFERENCE_DISTANCE:
-                       alSourcef(source, AL_REFERENCE_DISTANCE, value);
-                       result = true;
-                       break;
-               case AUD_3DSS_ROLLOFF_FACTOR:
-                       alSourcef(source, AL_ROLLOFF_FACTOR, value);
-                       result = true;
-                       break;
-               default:
-                       break;
-               }
-       }
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
+                                 volume);
 
        unlock();
        return result;
 }
 
-float AUD_OpenALDevice::getSourceSetting(AUD_Handle* handle,
-                                                                                AUD_3DSourceSetting setting)
+float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
 {
        float result = std::numeric_limits<float>::quiet_NaN();;
 
        lock();
 
        if(isValid(handle))
-       {
-               int source = ((AUD_OpenALHandle*)handle)->source;
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
+                                        &result);
 
-               switch(setting)
-               {
-               case AUD_3DSS_CONE_INNER_ANGLE:
-                       alGetSourcef(source, AL_CONE_INNER_ANGLE, &result);
-                       break;
-               case AUD_3DSS_CONE_OUTER_ANGLE:
-                       alGetSourcef(source, AL_CONE_OUTER_ANGLE, &result);
-                       break;
-               case AUD_3DSS_CONE_OUTER_GAIN:
-                       alGetSourcef(source, AL_CONE_OUTER_GAIN, &result);
-                       break;
-               case AUD_3DSS_IS_RELATIVE:
-                       {
-                               ALint i;
-                               alGetSourcei(source, AL_SOURCE_RELATIVE, &i);
-                               result = i ? 1.0f : 0.0f;
-                               break;
-                       }
-               case AUD_3DSS_MAX_DISTANCE:
-                       alGetSourcef(source, AL_MAX_DISTANCE, &result);
-                       break;
-               case AUD_3DSS_MAX_GAIN:
-                       alGetSourcef(source, AL_MAX_GAIN, &result);
-                       break;
-               case AUD_3DSS_MIN_GAIN:
-                       alGetSourcef(source, AL_MIN_GAIN, &result);
-                       break;
-               case AUD_3DSS_REFERENCE_DISTANCE:
-                       alGetSourcef(source, AL_REFERENCE_DISTANCE, &result);
-                       break;
-               case AUD_3DSS_ROLLOFF_FACTOR:
-                       alGetSourcef(source, AL_ROLLOFF_FACTOR, &result);
-                       break;
-               default:
-                       break;
-               }
-       }
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
+                                 distance);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
+                                 distance);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
+                                 factor);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
+                                 angle);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
+                                 angle);
+
+       unlock();
+       return result;
+}
+
+float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
+{
+       float result = std::numeric_limits<float>::quiet_NaN();;
+
+       lock();
+
+       if(isValid(handle))
+               alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
+                                        &result);
+
+       unlock();
+       return result;
+}
+
+bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
+{
+       lock();
+       bool result = isValid(handle);
+
+       if(result)
+               alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
+                                 volume);
 
        unlock();
        return result;
index cb8c83ab810e247e5bfdf972d543a9e997bfc9aa..cba031f25f96a8f1dd3a296d9779cb23391d9244 100644 (file)
@@ -30,7 +30,6 @@
 #include "AUD_I3DDevice.h"
 struct AUD_OpenALHandle;
 struct AUD_OpenALBufferedFactory;
-class AUD_ConverterFactory;
 
 #include <AL/al.h>
 #include <AL/alc.h>
@@ -63,11 +62,6 @@ private:
         */
        bool m_useMC;
 
-       /**
-       * The converter factory for readers with wrong input format.
-       */
-       AUD_ConverterFactory* m_converter;
-
        /**
         * The list of sounds that are currently playing.
         */
@@ -123,6 +117,10 @@ private:
         */
        bool getFormat(ALenum &format, AUD_Specs specs);
 
+       // hide copy constructor and operator=
+       AUD_OpenALDevice(const AUD_OpenALDevice&);
+       AUD_OpenALDevice& operator=(const AUD_OpenALDevice&);
+
 public:
        /**
         * Opens the OpenAL audio device for playback.
@@ -142,31 +140,61 @@ public:
 
        virtual ~AUD_OpenALDevice();
 
-       virtual AUD_DeviceSpecs getSpecs();
+       virtual AUD_DeviceSpecs getSpecs() const;
        virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
        virtual bool pause(AUD_Handle* handle);
        virtual bool resume(AUD_Handle* handle);
        virtual bool stop(AUD_Handle* handle);
+       virtual bool getKeep(AUD_Handle* handle);
        virtual bool setKeep(AUD_Handle* handle, bool keep);
-       virtual bool sendMessage(AUD_Handle* handle, AUD_Message &message);
        virtual bool seek(AUD_Handle* handle, float position);
        virtual float getPosition(AUD_Handle* handle);
        virtual AUD_Status getStatus(AUD_Handle* handle);
        virtual void lock();
        virtual void unlock();
-       virtual bool checkCapability(int capability);
-       virtual bool setCapability(int capability, void *value);
-       virtual bool getCapability(int capability, void *value);
-
-       virtual AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false);
-       virtual bool updateListener(AUD_3DData &data);
-       virtual bool setSetting(AUD_3DSetting setting, float value);
-       virtual float getSetting(AUD_3DSetting setting);
-       virtual bool updateSource(AUD_Handle* handle, AUD_3DData &data);
-       virtual bool setSourceSetting(AUD_Handle* handle,
-                                                                 AUD_3DSourceSetting setting, float value);
-       virtual float getSourceSetting(AUD_Handle* handle,
-                                                                  AUD_3DSourceSetting setting);
+       virtual float getVolume() const;
+       virtual void setVolume(float volume);
+       virtual float getVolume(AUD_Handle* handle);
+       virtual bool setVolume(AUD_Handle* handle, float volume);
+       virtual float getPitch(AUD_Handle* handle);
+       virtual bool setPitch(AUD_Handle* handle, float pitch);
+
+       virtual AUD_Vector3 getListenerLocation() const;
+       virtual void setListenerLocation(const AUD_Vector3& location);
+       virtual AUD_Vector3 getListenerVelocity() const;
+       virtual void setListenerVelocity(const AUD_Vector3& velocity);
+       virtual AUD_Quaternion getListenerOrientation() const;
+       virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+       virtual float getSpeedOfSound() const;
+       virtual void setSpeedOfSound(float speed);
+       virtual float getDopplerFactor() const;
+       virtual void setDopplerFactor(float factor);
+       virtual AUD_DistanceModel getDistanceModel() const;
+       virtual void setDistanceModel(AUD_DistanceModel model);
+       virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
+       virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
+       virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
+       virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
+       virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
+       virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
+       virtual bool isRelative(AUD_Handle* handle);
+       virtual bool setRelative(AUD_Handle* handle, bool relative);
+       virtual float getVolumeMaximum(AUD_Handle* handle);
+       virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
+       virtual float getVolumeMinimum(AUD_Handle* handle);
+       virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
+       virtual float getDistanceMaximum(AUD_Handle* handle);
+       virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
+       virtual float getDistanceReference(AUD_Handle* handle);
+       virtual bool setDistanceReference(AUD_Handle* handle, float distance);
+       virtual float getAttenuation(AUD_Handle* handle);
+       virtual bool setAttenuation(AUD_Handle* handle, float factor);
+       virtual float getConeAngleOuter(AUD_Handle* handle);
+       virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
+       virtual float getConeAngleInner(AUD_Handle* handle);
+       virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
+       virtual float getConeVolumeOuter(AUD_Handle* handle);
+       virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
 };
 
 #endif //AUD_OPENALDEVICE
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
new file mode 100644 (file)
index 0000000..1361728
--- /dev/null
@@ -0,0 +1,2966 @@
+/*
+ * $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_PyAPI.h"
+#include "structmember.h"
+
+#include "AUD_I3DDevice.h"
+#include "AUD_NULLDevice.h"
+#include "AUD_DelayFactory.h"
+#include "AUD_DoubleFactory.h"
+#include "AUD_FaderFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_LimiterFactory.h"
+#include "AUD_LoopFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_PingPongFactory.h"
+#include "AUD_PitchFactory.h"
+#include "AUD_ReverseFactory.h"
+#include "AUD_SinusFactory.h"
+#include "AUD_FileFactory.h"
+#include "AUD_SquareFactory.h"
+#include "AUD_StreamBufferFactory.h"
+#include "AUD_SuperposeFactory.h"
+#include "AUD_VolumeFactory.h"
+
+#ifdef WITH_SDL
+#include "AUD_SDLDevice.h"
+#endif
+
+#ifdef WITH_OPENAL
+#include "AUD_OpenALDevice.h"
+#endif
+
+#ifdef WITH_JACK
+#include "AUD_JackDevice.h"
+#endif
+
+#include <cstdlib>
+#include <unistd.h>
+
+// ====================================================================
+
+#define PY_MODULE_ADD_CONSTANT(module, name) PyModule_AddIntConstant(module, #name, name)
+
+// ====================================================================
+
+static PyObject* AUDError;
+
+// ====================================================================
+
+static void
+Sound_dealloc(Sound* self)
+{
+       if(self->factory)
+               delete self->factory;
+       Py_XDECREF(self->child_list);
+       Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+static PyObject *
+Sound_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
+{
+       Sound *self;
+
+       self = (Sound*)type->tp_alloc(type, 0);
+       if(self != NULL)
+       {
+               static const char *kwlist[] = {"filename", NULL};
+               const char* filename = NULL;
+
+               if(!PyArg_ParseTupleAndKeywords(args, kwds, "|s", const_cast<char**>(kwlist), &filename))
+               {
+                       Py_DECREF(self);
+                       return NULL;
+               }
+               else if(filename == NULL)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, "Missing filename parameter!");
+                       return NULL;
+               }
+
+               try
+               {
+                       self->factory = new AUD_FileFactory(filename);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, "Filefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+PyDoc_STRVAR(M_aud_Sound_sine_doc,
+                        "sine(frequency[, rate])\n\n"
+                        "Creates a sine sound wave.\n\n"
+                        ":arg frequency: The frequency of the sine wave in Hz.\n"
+                        ":type frequency: float\n"
+                        ":arg rate: The sampling rate in Hz.\n"
+                        ":type rate: int\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_sine(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_file_doc,
+                        "file(filename)\n\n"
+                        "Creates a sound object of a sound file.\n\n"
+                        ":arg filename: Path of the file.\n"
+                        ":type filename: string\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_file(PyObject* nothing, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
+                        "lowpass(frequency)\n\n"
+                        "Creates a low quality lowpass filter.\n\n"
+                        ":arg frequency: The cut off trequency of the lowpass.\n"
+                        ":type frequency: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_lowpass(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_delay_doc,
+                        "delay(time)\n\n"
+                        "Delays a sound by playing silence before the sound starts.\n\n"
+                        ":arg time: How many seconds of silence should be added before the sound.\n"
+                        ":type time: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_delay(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_join_doc,
+                        "join(sound)\n\n"
+                        "Plays two sounds in sequence.\n\n"
+                        ":arg sound: The sound to play second.\n"
+                        ":type sound: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The two sounds have to have the same specifications "
+                        "(channels and samplerate).");
+
+static PyObject *
+Sound_join(Sound* self, PyObject* object);
+
+PyDoc_STRVAR(M_aud_Sound_highpass_doc,
+                        "highpass(frequency)\n\n"
+                        "Creates a low quality highpass filter.\n\n"
+                        ":arg frequency: The cut off trequency of the highpass.\n"
+                        ":type frequency: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_highpass(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_limit_doc,
+                        "limit(start, end)\n\n"
+                        "Limits a sound within a specific start and end time.\n\n"
+                        ":arg start: Start time in seconds.\n"
+                        ":type start: float\n"
+                        ":arg end: End time in seconds.\n"
+                        ":type end: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_limit(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_pitch_doc,
+                        "pitch(factor)\n\n"
+                        "Changes the pitch of a sound with a specific factor.\n\n"
+                        ":arg factor: The factor to change the pitch with.\n"
+                        ":type factor: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: This is done by changing the sample rate of the "
+                        "underlying sound, which has to be an integer, so the factor "
+                        "value rounded and the factor may not be 100 % accurate.");
+
+static PyObject *
+Sound_pitch(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_volume_doc,
+                        "volume(volume)\n\n"
+                        "Changes the volume of a sound.\n\n"
+                        ":arg volume: The new volume..\n"
+                        ":type volume: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: Should be in the range [0, 1] to avoid clipping.\n\n"
+                        ".. note:: This is a filter function, you might consider using "
+                        "aud.Handle.pitch instead.");
+
+static PyObject *
+Sound_volume(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_fadein_doc,
+                        "fadein(start, length)\n\n"
+                        "Fades a sound in.\n\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type start: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type length: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: This is a filter function, you might consider using "
+                        "aud.Handle.volume instead.");
+
+static PyObject *
+Sound_fadein(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_fadeout_doc,
+                        "fadeout(start, length)\n\n"
+                        "Fades a sound out.\n\n"
+                        ":arg start: Time in seconds when the fading should start.\n"
+                        ":type start: float\n"
+                        ":arg length: Time in seconds how long the fading should last.\n"
+                        ":type length: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_fadeout(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_loop_doc,
+                        "loop(count)\n\n"
+                        "Loops a sound.\n\n"
+                        ":arg count: How often the sound should be looped. "
+                        "Negative values mean endlessly.\n"
+                        ":type count: integer\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_loop(Sound* self, PyObject* args);
+
+PyDoc_STRVAR(M_aud_Sound_mix_doc,
+                        "mix(sound)\n\n"
+                        "Mixes two sounds.\n\n"
+                        ":arg sound: The sound to mix over the other.\n"
+                        ":type sound: aud.Sound\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The two sounds have to have the same specifications "
+                        "(channels and samplerate).");
+
+static PyObject *
+Sound_mix(Sound* self, PyObject* object);
+
+PyDoc_STRVAR(M_aud_Sound_pingpong_doc,
+                        "pingpong()\n\n"
+                        "Plays a sound forward and then backward.\n\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The sound has to be buffered to be played reverse.");
+
+static PyObject *
+Sound_pingpong(Sound* self);
+
+PyDoc_STRVAR(M_aud_Sound_reverse_doc,
+                        "reverse()\n\n"
+                        "Plays a sound reversed.\n\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: The sound has to be buffered to be played reverse.");
+
+static PyObject *
+Sound_reverse(Sound* self);
+
+PyDoc_STRVAR(M_aud_Sound_buffer_doc,
+                        "buffer()\n\n"
+                        "Buffers a sound into RAM.\n\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound\n\n"
+                        ".. note:: Raw PCM data needs a lot of space, only buffer short sounds.");
+
+static PyObject *
+Sound_buffer(Sound* self);
+
+PyDoc_STRVAR(M_aud_Sound_square_doc,
+                        "squre([threshold = 0])\n\n"
+                        "Makes a square wave out of an audio wave.\n\n"
+                        ":arg threshold: Threshold value over which an amplitude counts non-zero.\n"
+                        ":type threshold: float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_square(Sound* self, PyObject* args);
+
+static PyMethodDef Sound_methods[] = {
+       {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_sine_doc
+       },
+       {"file", (PyCFunction)Sound_file, METH_VARARGS | METH_STATIC,
+        M_aud_Sound_file_doc
+       },
+       {"lowpass", (PyCFunction)Sound_lowpass, METH_VARARGS,
+        M_aud_Sound_lowpass_doc
+       },
+       {"delay", (PyCFunction)Sound_delay, METH_VARARGS,
+        M_aud_Sound_delay_doc
+       },
+       {"join", (PyCFunction)Sound_join, METH_O,
+        M_aud_Sound_join_doc
+       },
+       {"highpass", (PyCFunction)Sound_highpass, METH_VARARGS,
+        M_aud_Sound_highpass_doc
+       },
+       {"limit", (PyCFunction)Sound_limit, METH_VARARGS,
+        M_aud_Sound_limit_doc
+       },
+       {"pitch", (PyCFunction)Sound_pitch, METH_VARARGS,
+        M_aud_Sound_pitch_doc
+       },
+       {"volume", (PyCFunction)Sound_volume, METH_VARARGS,
+        M_aud_Sound_volume_doc
+       },
+       {"fadein", (PyCFunction)Sound_fadein, METH_VARARGS,
+        M_aud_Sound_fadein_doc
+       },
+       {"fadeout", (PyCFunction)Sound_fadeout, METH_VARARGS,
+        M_aud_Sound_fadeout_doc
+       },
+       {"loop", (PyCFunction)Sound_loop, METH_VARARGS,
+        M_aud_Sound_loop_doc
+       },
+       {"mix", (PyCFunction)Sound_mix, METH_O,
+        M_aud_Sound_mix_doc
+       },
+       {"pingpong", (PyCFunction)Sound_pingpong, METH_NOARGS,
+        M_aud_Sound_pingpong_doc
+       },
+       {"reverse", (PyCFunction)Sound_reverse, METH_NOARGS,
+        M_aud_Sound_reverse_doc
+       },
+       {"buffer", (PyCFunction)Sound_buffer, METH_NOARGS,
+        M_aud_Sound_buffer_doc
+       },
+       {"square", (PyCFunction)Sound_square, METH_VARARGS,
+        M_aud_Sound_square_doc
+       },
+       {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Sound_doc,
+                        "Sound objects are immutable and represent a sound that can be "
+                        "played simultaneously multiple times.");
+
+static PyTypeObject SoundType = {
+       PyVarObject_HEAD_INIT(NULL, 0)
+       "aud.Sound",               /* tp_name */
+       sizeof(Sound),             /* tp_basicsize */
+       0,                         /* tp_itemsize */
+       (destructor)Sound_dealloc, /* tp_dealloc */
+       0,                         /* tp_print */
+       0,                         /* tp_getattr */
+       0,                         /* tp_setattr */
+       0,                         /* tp_reserved */
+       0,                         /* tp_repr */
+       0,                         /* tp_as_number */
+       0,                         /* tp_as_sequence */
+       0,                         /* tp_as_mapping */
+       0,                         /* tp_hash  */
+       0,                         /* tp_call */
+       0,                         /* tp_str */
+       0,                         /* tp_getattro */
+       0,                         /* tp_setattro */
+       0,                         /* tp_as_buffer */
+       Py_TPFLAGS_DEFAULT,        /* tp_flags */
+       M_aud_Sound_doc,           /* tp_doc */
+       0,                                 /* tp_traverse */
+       0,                                 /* tp_clear */
+       0,                                 /* tp_richcompare */
+       0,                                 /* tp_weaklistoffset */
+       0,                                 /* tp_iter */
+       0,                                 /* tp_iternext */
+       Sound_methods,             /* tp_methods */
+       0,                         /* tp_members */
+       0,                         /* tp_getset */
+       0,                         /* tp_base */
+       0,                         /* tp_dict */
+       0,                         /* tp_descr_get */
+       0,                         /* tp_descr_set */
+       0,                         /* tp_dictoffset */
+       0,                         /* tp_init */
+       0,                         /* tp_alloc */
+       Sound_new,                 /* tp_new */
+};
+
+static PyObject *
+Sound_sine(PyObject* nothing, PyObject* args)
+{
+       float frequency;
+       int rate = 44100;
+
+       if(!PyArg_ParseTuple(args, "f|i", &frequency, &rate))
+               return NULL;
+
+       Sound *self;
+
+       self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+       if(self != NULL)
+       {
+               try
+               {
+                       self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, "Sinusfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+static PyObject *
+Sound_file(PyObject* nothing, PyObject* args)
+{
+       const char* filename = NULL;
+
+       if(!PyArg_ParseTuple(args, "s", &filename))
+               return NULL;
+
+       Sound *self;
+
+       self = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+       if(self != NULL)
+       {
+               try
+               {
+                       self->factory = new AUD_FileFactory(filename);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(self);
+                       PyErr_SetString(AUDError, "Filefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)self;
+}
+
+static PyObject *
+Sound_lowpass(Sound* self, PyObject* args)
+{
+       float frequency;
+
+       if(!PyArg_ParseTuple(args, "f", &frequency))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LowpassFactory(self->factory, frequency, 0.9);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Lowpassfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_delay(Sound* self, PyObject* args)
+{
+       float delay;
+
+       if(!PyArg_ParseTuple(args, "f", &delay))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_DelayFactory(self->factory, delay);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Delayfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_join(Sound* self, PyObject* object)
+{
+       if(!PyObject_TypeCheck(object, &SoundType))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object has to be of type aud.Sound!");
+               return NULL;
+       }
+
+       Sound *parent;
+       Sound *child = (Sound*)object;
+
+       parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+       if(parent != NULL)
+       {
+               parent->child_list = Py_BuildValue("(OO)", self, object);
+
+               try
+               {
+                       parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Doublefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_highpass(Sound* self, PyObject* args)
+{
+       float frequency;
+
+       if(!PyArg_ParseTuple(args, "f", &frequency))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_HighpassFactory(self->factory, frequency, 0.9);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Highpassfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_limit(Sound* self, PyObject* args)
+{
+       float start, end;
+
+       if(!PyArg_ParseTuple(args, "ff", &start, &end))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LimiterFactory(self->factory, start, end);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Limiterfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_pitch(Sound* self, PyObject* args)
+{
+       float factor;
+
+       if(!PyArg_ParseTuple(args, "f", &factor))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_PitchFactory(self->factory, factor);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Pitchfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_volume(Sound* self, PyObject* args)
+{
+       float volume;
+
+       if(!PyArg_ParseTuple(args, "f", &volume))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_VolumeFactory(self->factory, volume);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Volumefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_fadein(Sound* self, PyObject* args)
+{
+       float start, length;
+
+       if(!PyArg_ParseTuple(args, "ff", &start, &length))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_fadeout(Sound* self, PyObject* args)
+{
+       float start, length;
+
+       if(!PyArg_ParseTuple(args, "ff", &start, &length))
+               return NULL;
+
+       if(!PyObject_TypeCheck(self, &SoundType))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+               return NULL;
+       }
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Faderfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_loop(Sound* self, PyObject* args)
+{
+       int loop;
+
+       if(!PyArg_ParseTuple(args, "i", &loop))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_LoopFactory(self->factory, loop);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Loopfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_mix(Sound* self, PyObject* object)
+{
+       if(!PyObject_TypeCheck(object, &SoundType))
+       {
+               PyErr_SetString(PyExc_TypeError, "Object is not of type aud.Sound!");
+               return NULL;
+       }
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+       Sound *child = (Sound*)object;
+
+       if(parent != NULL)
+       {
+               parent->child_list = Py_BuildValue("(OO)", self, object);
+
+               try
+               {
+                       parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Superposefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_pingpong(Sound* self)
+{
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_PingPongFactory(self->factory);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Pingpongfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_reverse(Sound* self)
+{
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_ReverseFactory(self->factory);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Reversefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_buffer(Sound* self)
+{
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               try
+               {
+                       parent->factory = new AUD_StreamBufferFactory(self->factory);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Bufferfactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+static PyObject *
+Sound_square(Sound* self, PyObject* args)
+{
+       float threshold = 0;
+
+       if(!PyArg_ParseTuple(args, "|f", &threshold))
+               return NULL;
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_SquareFactory(self->factory, threshold);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "Squarefactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
+// ========== Handle ==================================================
+
+static void
+Handle_dealloc(Handle* self)
+{
+       Py_XDECREF(self->device);
+       Py_TYPE(self)->tp_free((PyObject*)self);
+}
+
+PyDoc_STRVAR(M_aud_Handle_pause_doc,
+                        "pause()\n\n"
+                        "Pauses playback.\n\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_pause(Handle *self)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->pause(self->handle))
+               {
+                       Py_RETURN_TRUE;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't pause the sound!");
+               return NULL;
+       }
+
+       Py_RETURN_FALSE;
+}
+
+PyDoc_STRVAR(M_aud_Handle_resume_doc,
+                        "resume()\n\n"
+                        "Resumes playback.\n\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_resume(Handle *self)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->resume(self->handle))
+               {
+                       Py_RETURN_TRUE;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't resume the sound!");
+               return NULL;
+       }
+
+       Py_RETURN_FALSE;
+}
+
+PyDoc_STRVAR(M_aud_Handle_stop_doc,
+                        "stop()\n\n"
+                        "Stops playback.\n\n"
+                        ":return: Whether the action succeeded.\n"
+                        ":rtype: boolean");
+
+static PyObject *
+Handle_stop(Handle *self)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->stop(self->handle))
+               {
+                       Py_RETURN_TRUE;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't stop the sound!");
+               return NULL;
+       }
+
+       Py_RETURN_FALSE;
+}
+
+static PyMethodDef Handle_methods[] = {
+       {"pause", (PyCFunction)Handle_pause, METH_NOARGS,
+        M_aud_Handle_pause_doc
+       },
+       {"resume", (PyCFunction)Handle_resume, METH_NOARGS,
+        M_aud_Handle_resume_doc
+       },
+       {"stop", (PyCFunction)Handle_stop, METH_NOARGS,
+        M_aud_Handle_stop_doc
+       },
+       {NULL}  /* Sentinel */
+};
+
+PyDoc_STRVAR(M_aud_Handle_position_doc,
+                        "The playback position of the sound.");
+
+static PyObject *
+Handle_get_position(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               return Py_BuildValue("f", device->device->getPosition(self->handle));
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the position of the sound!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_position(Handle *self, PyObject* args, void* nothing)
+{
+       float position;
+
+       if(!PyArg_Parse(args, "f", &position))
+               return -1;
+
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->seek(self->handle, position))
+                       return 0;
+       }
+       catch(AUD_Exception&)
+       {
+       }
+
+       PyErr_SetString(AUDError, "Couldn't seek the sound!");
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_keep_doc,
+                        "Whether the sound should be kept paused in the device when its end is reached.");
+
+static PyObject *
+Handle_get_keep(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->getKeep(self->handle))
+               {
+                       Py_RETURN_TRUE;
+               }
+               else
+               {
+                       Py_RETURN_FALSE;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_keep(Handle *self, PyObject* args, void* nothing)
+{
+       if(!PyBool_Check(args))
+       {
+               PyErr_SetString(PyExc_TypeError, "keep is not a boolean!");
+               return -1;
+       }
+
+       bool keep = args == Py_True;
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->setKeep(self->handle, keep))
+                       return 0;
+       }
+       catch(AUD_Exception&)
+       {
+       }
+
+       PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_status_doc,
+                        "Whether the sound is playing, paused or stopped.");
+
+static PyObject *
+Handle_get_status(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               return Py_BuildValue("i", device->device->getStatus(self->handle));
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
+               return NULL;
+       }
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_doc,
+                        "The volume of the sound.");
+
+static PyObject *
+Handle_get_volume(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               return Py_BuildValue("f", device->device->getVolume(self->handle));
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't get the sound volume!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_volume(Handle *self, PyObject* args, void* nothing)
+{
+       float volume;
+
+       if(!PyArg_Parse(args, "f", &volume))
+               return -1;
+
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->setVolume(self->handle, volume))
+                       return 0;
+       }
+       catch(AUD_Exception&)
+       {
+       }
+
+       PyErr_SetString(AUDError, "Couldn't set the sound volume!");
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_pitch_doc,
+                        "The pitch of the sound.");
+
+static PyObject *
+Handle_get_pitch(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               return Py_BuildValue("f", device->device->getPitch(self->handle));
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't get the sound pitch!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
+{
+       float pitch;
+
+       if(!PyArg_Parse(args, "f", &pitch))
+               return -1;
+
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               if(device->device->setPitch(self->handle, pitch))
+                       return 0;
+       }
+       catch(AUD_Exception&)
+       {
+       }
+
+       PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
+                        "The (remaining) loop count of the sound. A negative value indicates infinity.");
+
+static PyObject *
+Handle_get_loop_count(Handle *self, void* nothing)
+{
+       Device* device = (Device*)self->device;
+
+       try
+       {
+               // AUD_XXX will come soon; return Py_BuildValue("f", device->device->getPitch(self->handle));
+               AUD_THROW(AUD_ERROR_FACTORY);
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't get the loop count!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
+{
+       int loops;
+
+       if(!PyArg_Parse(args, "i", &loops))
+               return -1;
+
+       Device* device = (Device*)self->device;
+
+       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))
+               {
+                       return 0;
+               }*/
+       }
+       catch(AUD_Exception&)
+       {
+       }
+
+       PyErr_SetString(AUDError, "Couldn't set the loop count!");
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_location_doc,
+                        "The source's location in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_location(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getSourceLocation(self->handle);
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the location!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_location(Handle *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 location(x, y, z);
+                       device->setSourceLocation(self->handle, location);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the location!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_velocity_doc,
+                        "The source's velocity in 3D space, a 3D tuple of floats.");
+
+static PyObject *
+Handle_get_velocity(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 v = device->getSourceVelocity(self->handle);
+                       return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the velocity!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
+{
+       float x, y, z;
+
+       if(!PyArg_Parse(args, "(fff)", &x, &y, &z))
+               return NULL;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Vector3 velocity(x, y, z);
+                       device->setSourceVelocity(self->handle, velocity);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the velocity!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_orientation_doc,
+                        "The source's orientation in 3D space as quaternion, a 4 float tuple.");
+
+static PyObject *
+Handle_get_orientation(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Quaternion o = device->getSourceOrientation(self->handle);
+                       return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the orientation!");
+       }
+
+       return NULL;
+}
+
+static int
+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;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       AUD_Quaternion orientation(w, x, y, z);
+                       device->setSourceOrientation(self->handle, orientation);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the orientation!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_relative_doc,
+                        "Whether the source's location, velocity and orientation is relative or absolute to the listener.");
+
+static PyObject *
+Handle_get_relative(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       if(device->isRelative(self->handle))
+                       {
+                               Py_RETURN_TRUE;
+                       }
+                       else
+                       {
+                               Py_RETURN_FALSE;
+                       }
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
+       }
+
+       return NULL;
+}
+
+static int
+Handle_set_relative(Handle *self, PyObject* args, void* nothing)
+{
+       if(!PyBool_Check(args))
+       {
+               PyErr_SetString(PyExc_TypeError, "Value is not a boolean!");
+               return -1;
+       }
+
+       bool relative = (args == Py_True);
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       device->setRelative(self->handle, relative);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the status!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
+                        "The minimum volume of the source.");
+
+static PyObject *
+Handle_get_volume_minimum(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+                       return NULL;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the minimum volume of the sound!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
+{
+       float volume;
+
+       if(!PyArg_Parse(args, "f", &volume))
+               return -1;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       device->setVolumeMinimum(self->handle, volume);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the minimum source volume!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
+                        "The maximum volume of the source.");
+
+static PyObject *
+Handle_get_volume_maximum(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
+               }
+               else
+               {
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+                       return NULL;
+               }
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't retrieve the maximum volume of the sound!");
+               return NULL;
+       }
+}
+
+static int
+Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
+{
+       float volume;
+
+       if(!PyArg_Parse(args, "f", &volume))
+               return -1;
+
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
+               if(device)
+               {
+                       device->setVolumeMaximum(self->handle, volume);
+                       return 0;
+               }
+               else
+                       PyErr_SetString(AUDError, "Device is not a 3D device!");
+       }
+       catch(AUD_Exception&)
+       {
+               PyErr_SetString(AUDError, "Couldn't set the maximum source volume!");
+       }
+
+       return -1;
+}
+
+PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
+                        "The reference distance of the source.");
+
+static PyObject *
+Handle_get_distance_reference(Handle *self, void* nothing)
+{
+       Device* dev = (Device*)self->device;
+
+       try
+       {
+               AUD_I3DDevice* device = dynamic_ca