Huge new year audio commit!
authorJoerg Mueller <nexyon@gmail.com>
Fri, 1 Jan 2010 05:09:30 +0000 (05:09 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Fri, 1 Jan 2010 05:09:30 +0000 (05:09 +0000)
* Refactored the whole audaspace library to use float as sample format over all readers.
* Added new Readers like the linear resampler, envelope, lowpass, highpass and butterworth.
* Note: The butterworth filter isn't working correctly, some bug in there... Maybe also true for the envelope.
* Added a sound to f-curve operator that behaves mostly like the soundtracker script of technoestupido.

86 files changed:
intern/audaspace/FX/AUD_ButterworthFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_DelayReader.cpp
intern/audaspace/FX/AUD_DoubleReader.cpp
intern/audaspace/FX/AUD_EnvelopeFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_FaderReader.cpp
intern/audaspace/FX/AUD_FaderReader.h
intern/audaspace/FX/AUD_HighpassFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_HighpassFactory.h [moved from intern/audaspace/SDL/AUD_SDLMixer.h with 51% similarity]
intern/audaspace/FX/AUD_HighpassReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_HighpassReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LoopReader.cpp
intern/audaspace/FX/AUD_LowpassFactory.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LowpassFactory.h [new file with mode: 0644]
intern/audaspace/FX/AUD_LowpassReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_LowpassReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_RectifyReader.cpp
intern/audaspace/FX/AUD_RectifyReader.h
intern/audaspace/FX/AUD_ReverseReader.cpp
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/SDL/AUD_SDLDevice.cpp
intern/audaspace/SDL/AUD_SDLDevice.h
intern/audaspace/SDL/AUD_SDLMixer.cpp [deleted file]
intern/audaspace/SDL/AUD_SDLMixerReader.cpp [deleted file]
intern/audaspace/SDL/AUD_SDLMixerReader.h [deleted file]
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_FFMPEGReader.cpp
intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
intern/audaspace/fftw/AUD_BandPassFactory.cpp
intern/audaspace/fftw/AUD_BandPassReader.cpp
intern/audaspace/intern/AUD_Buffer.cpp
intern/audaspace/intern/AUD_Buffer.h
intern/audaspace/intern/AUD_BufferReader.cpp
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_ConverterFactory.cpp
intern/audaspace/intern/AUD_ConverterFactory.h
intern/audaspace/intern/AUD_ConverterFunctions.cpp
intern/audaspace/intern/AUD_ConverterFunctions.h
intern/audaspace/intern/AUD_ConverterReader.cpp
intern/audaspace/intern/AUD_ConverterReader.h
intern/audaspace/intern/AUD_FloatMixer.h [deleted file]
intern/audaspace/intern/AUD_IDevice.h
intern/audaspace/intern/AUD_LinearResampleFactory.cpp [moved from intern/audaspace/SDL/AUD_SDLMixerFactory.cpp with 53% similarity]
intern/audaspace/intern/AUD_LinearResampleFactory.h [moved from intern/audaspace/SDL/AUD_SDLMixerFactory.h with 65% similarity]
intern/audaspace/intern/AUD_LinearResampleReader.cpp [new file with mode: 0644]
intern/audaspace/intern/AUD_LinearResampleReader.h [new file with mode: 0644]
intern/audaspace/intern/AUD_Mixer.cpp [moved from intern/audaspace/intern/AUD_FloatMixer.cpp with 75% similarity]
intern/audaspace/intern/AUD_Mixer.h [moved from intern/audaspace/intern/AUD_IMixer.h with 56% similarity]
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_SinusReader.cpp
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/jack/AUD_JackDevice.cpp
intern/audaspace/jack/AUD_JackDevice.h
intern/audaspace/sndfile/AUD_SndFileReader.cpp
intern/audaspace/sndfile/AUD_SndFileReader.h
source/blender/blenkernel/BKE_sound.h
source/blender/blenkernel/intern/sequencer.c
source/blender/blenkernel/intern/sound.c
source/blender/blenkernel/intern/writeffmpeg.c
source/blender/editors/sound/sound_ops.c
source/blender/editors/space_graph/graph_edit.c
source/blender/editors/space_graph/graph_intern.h
source/blender/editors/space_graph/graph_ops.c

diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
new file mode 100644 (file)
index 0000000..fd0a53d
--- /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_ButterworthFactory.h"
+#include "AUD_ButterworthReader.h"
+
+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()
+{
+       AUD_IReader* reader = getReader();
+
+       if(reader != 0)
+       {
+               reader = new AUD_ButterworthReader(reader, m_frequency);
+               AUD_NEW("reader")
+       }
+
+       return reader;
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
new file mode 100644 (file)
index 0000000..6916953
--- /dev/null
@@ -0,0 +1,59 @@
+/*
+ * $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_BUTTERWORTHFACTORY
+#define AUD_BUTTERWORTHFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a butterworth filter reader.
+ */
+class AUD_ButterworthFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       float m_frequency;
+
+public:
+       /**
+        * Creates a new butterworth factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        */
+       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();
+};
+
+#endif //AUD_BUTTERWORTHFACTORY
diff --git a/intern/audaspace/FX/AUD_ButterworthReader.cpp b/intern/audaspace/FX/AUD_ButterworthReader.cpp
new file mode 100644 (file)
index 0000000..adcae87
--- /dev/null
@@ -0,0 +1,120 @@
+/*
+ * $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_ButterworthReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
+#define CC channels + channel
+
+AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
+                                                                                        float frequency) :
+               AUD_EffectReader(reader)
+{
+       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;
+
+       // calculate coefficients
+       float omega = 2 * tan(frequency * M_PI / specs.rate);
+       float o2 = omega * omega;
+       float o4 = o2 * o2;
+       float x1 = o2 + 2 * BWPB41 * omega + 4;
+       float x2 = o2 + 2 * BWPB42 * omega + 4;
+       float y1 = o2 - 2 * BWPB41 * omega + 4;
+       float y2 = o2 - 2 * BWPB42 * omega + 4;
+       float o228 = 2 * o2 - 8;
+       float norm = x1 * x2;
+       m_coeff[0][0] = 0;
+       m_coeff[0][1] = (x1 + x2) * o228 / norm;
+       m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm;
+       m_coeff[0][3] = (y1 + y2) * o228 / norm;
+       m_coeff[0][4] = y1 * y2 / norm;
+       m_coeff[1][4] = m_coeff[1][0] = o4 / norm;
+       m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm;
+       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();
+
+       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();
+       int channels = specs.channels;
+
+       for(int channel = 0; channel < channels; channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       invalues[m_position * CC] = buf[i * CC];
+                       outvalues[m_position * CC] = 0;
+
+                       for(int j = 0; j < 4; j++)
+                       {
+                               outvalues[m_position * CC] += m_coeff[1][j] *
+                                                                       invalues[((m_position + j) % 5) * CC] -
+                                                                       m_coeff[0][j] *
+                                                                       outvalues[((m_position + j) % 5) * CC];
+                       }
+
+                       buffer[i * CC] = outvalues[m_position * CC];
+
+                       m_position = (m_position + 4) % 5;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_ButterworthReader.h b/intern/audaspace/FX/AUD_ButterworthReader.h
new file mode 100644 (file)
index 0000000..b1cbd4e
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $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_BUTTERWORTHREADER
+#define AUD_BUTTERWORTHREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents a butterworth filter.
+ */
+class AUD_ButterworthReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer *m_buffer;
+
+       /**
+        * The last out values buffer.
+        */
+       AUD_Buffer *m_outvalues;
+
+       /**
+        * The last in values buffer.
+        */
+       AUD_Buffer *m_invalues;
+
+       /**
+        * The position for buffer cycling.
+        */
+       int m_position;
+
+       /**
+        * Filter coefficients.
+        */
+       float m_coeff[2][5];
+
+public:
+       /**
+        * Creates a new butterworth reader.
+        * \param reader The reader to read from.
+        * \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.
+        * \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);
+};
+
+#endif //AUD_BUTTERWORTHREADER
index 38d3b893b5cb9cf67843882e1ba83b9f38693d3d..f2521f645aa9f8a8251a04b01bc50f327edb0f2a 100644 (file)
@@ -77,31 +77,26 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer)
 {
        if(m_remdelay > 0)
        {
-               int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+               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);
 
                if(length > m_remdelay)
                {
-                       if(getSpecs().format == AUD_FORMAT_U8)
-                               memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize);
-                       else
-                               memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize);
+                       memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize);
                        int len = length - m_remdelay;
                        m_reader->read(len, buffer);
-                       memcpy(m_buffer->getBuffer()+m_remdelay*samplesize,
-                                  buffer, len*samplesize);
+                       memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels,
+                                  buffer, len * samplesize);
                        if(len < length-m_remdelay)
                                length = m_remdelay + len;
                        m_remdelay = 0;
                }
                else
                {
-                       if(getSpecs().format == AUD_FORMAT_U8)
-                               memset(m_buffer->getBuffer(), 0x80, length*samplesize);
-                       else
-                               memset(m_buffer->getBuffer(), 0, length*samplesize);
+                       memset(m_buffer->getBuffer(), 0, length * samplesize);
                        m_remdelay -= length;
                }
                buffer = m_buffer->getBuffer();
index 8d3afbf2f1df2a8609620676ef78defad9bba885..1e51a094427e5b507cc525166eb9f6122880b408 100644 (file)
@@ -137,15 +137,16 @@ void AUD_DoubleReader::read(int & length, sample_t* & buffer)
                m_reader1->read(len, buffer);
                if(len < length)
                {
-                       int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs());
+                       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);
+                       memcpy(m_buffer->getBuffer(), buffer, len * samplesize);
                        len = length - len;
                        length -= len;
                        m_reader2->read(len, buffer);
-                       memcpy(m_buffer->getBuffer() + length*samplesize,
-                                  buffer, len*samplesize);
+                       memcpy(m_buffer->getBuffer() + length * specs.channels, buffer,
+                                  len * samplesize);
                        length += len;
                        buffer = m_buffer->getBuffer();
                        m_finished1 = true;
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
new file mode 100644 (file)
index 0000000..c3b2c3f
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * $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_EnvelopeFactory.h"
+#include "AUD_EnvelopeReader.h"
+
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+                                                                                float release, float threshold,
+                                                                                float arthreshold) :
+               AUD_EffectFactory(factory),
+               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()
+{
+       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;
+}
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
new file mode 100644 (file)
index 0000000..c79e547
--- /dev/null
@@ -0,0 +1,82 @@
+/*
+ * $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_ENVELOPEFACTORY
+#define AUD_ENVELOPEFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates an envelope follower reader.
+ */
+class AUD_EnvelopeFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       float m_attack;
+
+       /**
+        * The release value in seconds.
+        */
+       float m_release;
+
+       /**
+        * The threshold value.
+        */
+       float m_threshold;
+
+       /**
+        * The attack/release threshold value.
+        */
+       float m_arthreshold;
+
+public:
+       /**
+        * Creates a new envelope factory.
+        * \param factory The input 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(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();
+};
+
+#endif //AUD_ENVELOPEFACTORY
diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.cpp b/intern/audaspace/FX/AUD_EnvelopeReader.cpp
new file mode 100644 (file)
index 0000000..f41aee1
--- /dev/null
@@ -0,0 +1,86 @@
+/*
+ * $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_EnvelopeReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
+                                                                          float release, float threshold,
+                                                                          float arthreshold) :
+               AUD_EffectReader(reader),
+               m_threshold(threshold)
+{
+       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.0/(specs.rate * attack));
+       m_bRelease = pow(arthreshold, 1.0/(specs.rate * release));
+}
+
+AUD_EnvelopeReader::~AUD_EnvelopeReader()
+{
+       delete m_buffer; AUD_DELETE("buffer")
+       delete m_envelopes; AUD_DELETE("buffer")
+}
+
+void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
+{
+       sample_t* buf;
+       sample_t* envelopes;
+       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));
+
+       buffer = m_buffer->getBuffer();
+
+       sample_t value;
+
+       for(int channel = 0; channel < specs.channels; channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       value = fabs(buf[i * specs.channels + channel]);
+                       if(value < m_threshold)
+                               value = 0.0f;
+
+                       buffer[i * specs.channels + channel] = envelopes[channel] =
+                               ((value > envelopes[channel]) ? m_bAttack : m_bRelease) *
+                                (envelopes[channel] - value) + value;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.h b/intern/audaspace/FX/AUD_EnvelopeReader.h
new file mode 100644 (file)
index 0000000..ff9dd23
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * $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_ENVELOPEREADER
+#define AUD_ENVELOPEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This class represents an envelope follower.
+ */
+class AUD_EnvelopeReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer *m_buffer;
+
+       /**
+        * The last envelopes buffer.
+        */
+       AUD_Buffer *m_envelopes;
+
+       /**
+        * Attack b value.
+        */
+       float m_bAttack;
+
+       /**
+        * Release b value.
+        */
+       float m_bRelease;
+
+       /**
+        * Threshold value.
+        */
+       float m_threshold;
+
+public:
+       /**
+        * Creates a new envelope reader.
+        * \param reader The reader to read from.
+        * \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.
+        * \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);
+};
+
+#endif //AUD_ENVELOPEREADER
index d5096e7fae1f478e9a732c618f43dae97bcd37ac..6c7ea6e0a01204db216ec5d6eb8650505f413c1f 100644 (file)
@@ -35,35 +35,6 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
                m_start(start),
                m_length(length)
 {
-       int bigendian = 1;
-       bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
-       switch(m_reader->getSpecs().format)
-       {
-       case AUD_FORMAT_S16:
-               m_adjust = AUD_volume_adjust<int16_t>;
-               break;
-       case AUD_FORMAT_S32:
-               m_adjust = AUD_volume_adjust<int32_t>;
-               break;
-       case AUD_FORMAT_FLOAT32:
-               m_adjust = AUD_volume_adjust<float>;
-               break;
-       case AUD_FORMAT_FLOAT64:
-               m_adjust = AUD_volume_adjust<double>;
-               break;
-       case AUD_FORMAT_U8:
-               m_adjust = AUD_volume_adjust_u8;
-               break;
-       case AUD_FORMAT_S24:
-               m_adjust = bigendian ? AUD_volume_adjust_s24_be :
-                                                          AUD_volume_adjust_s24_le;
-               break;
-       default:
-               delete m_reader;
-               AUD_THROW(AUD_ERROR_READER);
-       }
-
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
@@ -93,9 +64,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
                if(m_type != AUD_FADE_OUT)
                {
                        buffer = m_buffer->getBuffer();
-                       memset(buffer,
-                                  specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
-                                  length * samplesize);
+                       memset(buffer, 0, length * samplesize);
                }
        }
        else if(position / (float)specs.rate >= m_start+m_length)
@@ -103,9 +72,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
                if(m_type == AUD_FADE_OUT)
                {
                        buffer = m_buffer->getBuffer();
-                       memset(buffer,
-                                  specs.format == AUD_FORMAT_U8 ? 0x80 : 0,
-                                  length * samplesize);
+                       memset(buffer, 0, length * samplesize);
                }
        }
        else
@@ -113,19 +80,21 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
                sample_t* buf = m_buffer->getBuffer();
                float volume;
 
-               for(int i = 0; i < length; i++)
+               for(int i = 0; i < length * specs.channels; i++)
                {
-                       volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
-                       if(volume > 1.0f)
-                               volume = 1.0f;
-                       else if(volume < 0.0f)
-                               volume = 0.0f;
+                       if(i % specs.channels == 0)
+                       {
+                               volume = (((position+i)/(float)specs.rate)-m_start) / m_length;
+                               if(volume > 1.0f)
+                                       volume = 1.0f;
+                               else if(volume < 0.0f)
+                                       volume = 0.0f;
 
-                       if(m_type == AUD_FADE_OUT)
-                               volume = 1.0f - volume;
+                               if(m_type == AUD_FADE_OUT)
+                                       volume = 1.0f - volume;
+                       }
 
-                       m_adjust(buf + i * samplesize, buffer + i * samplesize,
-                                        specs.channels, volume);
+                       buf[i] = buffer[i] * volume;
                }
 
                buffer = buf;
index 773643b2f5df73066d540442edfcb688820a80a0..a75ac6e7a47553da010ed79e9aa68d80a142a3a1 100644 (file)
@@ -27,7 +27,6 @@
 #define AUD_FADERREADER
 
 #include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
 class AUD_Buffer;
 
 /**
@@ -58,11 +57,6 @@ private:
         */
        float m_length;
 
-       /**
-        * Volume adjustment function.
-        */
-       AUD_volume_adjust_f m_adjust;
-
 public:
        /**
         * Creates a new fader reader.
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
new file mode 100644 (file)
index 0000000..384d36b
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $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_HighpassFactory.h"
+#include "AUD_HighpassReader.h"
+
+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()
+{
+       AUD_IReader* reader = getReader();
+
+       if(reader != 0)
+       {
+               reader = new AUD_HighpassReader(reader, m_frequency, m_Q);
+               AUD_NEW("reader")
+       }
+
+       return reader;
+}
similarity index 51%
rename from intern/audaspace/SDL/AUD_SDLMixer.h
rename to intern/audaspace/FX/AUD_HighpassFactory.h
index 2cc4e51f66d89f578c750e787116c372d9e76c59..cce21eed27d99e198e2f94d19aa52fe18d821eab 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_SDLMIXER
-#define AUD_SDLMIXER
+#ifndef AUD_HIGHPASSFACTORY
+#define AUD_HIGHPASSFACTORY
 
-#include "AUD_IMixer.h"
-class AUD_SDLMixerFactory;
-#include <list>
-
-struct AUD_SDLMixerBuffer
-{
-       sample_t* buffer;
-       int length;
-       float volume;
-};
+#include "AUD_EffectFactory.h"
 
 /**
- * This class is able to mix audiosignals with the help of SDL.
+ * This factory creates a highpass filter reader.
  */
-class AUD_SDLMixer : public AUD_IMixer
+class AUD_HighpassFactory : public AUD_EffectFactory
 {
 private:
        /**
-        * The mixer factory that prepares all readers for superposition.
+        * The attack value in seconds.
         */
-       AUD_SDLMixerFactory* m_factory;
+       float m_frequency;
 
        /**
-        * The list of buffers to superpose.
+        * The Q factor.
         */
-       std::list<AUD_SDLMixerBuffer> m_buffers;
+       float m_Q;
 
+public:
        /**
-        * The size of an output sample.
+        * Creates a new highpass factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
         */
-       int m_samplesize;
+       AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0);
 
-public:
        /**
-        * Creates the mixer.
+        * Creates a new highpass factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
         */
-       AUD_SDLMixer();
-
-       virtual ~AUD_SDLMixer();
+       AUD_HighpassFactory(float frequency, float Q = 1.0);
 
-       virtual AUD_IReader* prepare(AUD_IReader* reader);
-       virtual void setSpecs(AUD_Specs specs);
-       virtual void add(sample_t* buffer, AUD_Specs specs, int length,
-                                        float volume);
-       virtual void superpose(sample_t* buffer, int length, float volume);
+       virtual AUD_IReader* createReader();
 };
 
-#endif //AUD_SDLMIXER
+#endif //AUD_HIGHPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_HighpassReader.cpp b/intern/audaspace/FX/AUD_HighpassReader.cpp
new file mode 100644 (file)
index 0000000..8240854
--- /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_HighpassReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#define CC channels + channel
+
+AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
+                                                                          float Q) :
+               AUD_EffectReader(reader)
+{
+       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);
+
+       m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER);
+       AUD_NEW("buffer")
+       memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER);
+
+       m_position = 0;
+
+       // calculate coefficients
+       float w0 = 2.0 * M_PI * frequency / specs.rate;
+       float alpha = sin(w0) / (2 * Q);
+       float norm = 1 + alpha;
+       m_coeff[0][0] = 0;
+       m_coeff[0][1] = -2 * cos(w0) / norm;
+       m_coeff[0][2] = (1 - alpha) / norm;
+       m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm);
+       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();
+
+       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();
+       int channels = specs.channels;
+
+       for(int channel = 0; channel < channels; channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       invalues[m_position * CC] = buf[i * CC];
+                       outvalues[m_position * CC] = 0;
+
+                       for(int j = 0; j < AUD_HIGHPASS_ORDER; j++)
+                       {
+                               outvalues[m_position * CC] += m_coeff[1][j] *
+                                               invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] -
+                                               m_coeff[0][j] *
+                                               outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC];
+                       }
+
+                       buffer[i * CC] = outvalues[m_position * CC];
+
+                       m_position = (m_position + AUD_HIGHPASS_ORDER-1) %
+                                                AUD_HIGHPASS_ORDER;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_HighpassReader.h b/intern/audaspace/FX/AUD_HighpassReader.h
new file mode 100644 (file)
index 0000000..dc28a62
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $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_HIGHPASSREADER
+#define AUD_HIGHPASSREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+#define AUD_HIGHPASS_ORDER 3
+
+/**
+ * This class represents a highpass filter.
+ */
+class AUD_HighpassReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer *m_buffer;
+
+       /**
+        * The last out values buffer.
+        */
+       AUD_Buffer *m_outvalues;
+
+       /**
+        * The last in values buffer.
+        */
+       AUD_Buffer *m_invalues;
+
+       /**
+        * The position for buffer cycling.
+        */
+       int m_position;
+
+       /**
+        * Filter coefficients.
+        */
+       float m_coeff[2][AUD_HIGHPASS_ORDER];
+
+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);
+};
+
+#endif //AUD_HIGHPASSREADER
index 9e2703210134f464f4ba0f4f85cc1b3c1b385618..7d70fc2022170d1590678c4a706e1d6f5bec72a0 100644 (file)
@@ -27,7 +27,6 @@
 #include "AUD_Buffer.h"
 
 #include <cstring>
-#include <stdio.h>
 
 AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
                AUD_EffectReader(reader), m_loop(loop)
@@ -62,7 +61,8 @@ bool AUD_LoopReader::notify(AUD_Message &message)
 
 void AUD_LoopReader::read(int & length, sample_t* & buffer)
 {
-       int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+       AUD_Specs specs = m_reader->getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
 
        int len = length;
 
@@ -72,10 +72,10 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
        {
                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);
 
-               memcpy(m_buffer->getBuffer() + pos * samplesize,
+               memcpy(m_buffer->getBuffer() + pos * specs.channels,
                           buffer, len * samplesize);
 
                pos += len;
@@ -93,7 +93,7 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
                        if(!len)
                                break;
 
-                       memcpy(m_buffer->getBuffer() + pos * samplesize,
+                       memcpy(m_buffer->getBuffer() + pos * specs.channels,
                                   buffer, len * samplesize);
 
                        pos += len;
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
new file mode 100644 (file)
index 0000000..05dc5ff
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * $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_LowpassFactory.h"
+#include "AUD_LowpassReader.h"
+
+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()
+{
+       AUD_IReader* reader = getReader();
+
+       if(reader != 0)
+       {
+               reader = new AUD_LowpassReader(reader, m_frequency, m_Q);
+               AUD_NEW("reader")
+       }
+
+       return reader;
+}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
new file mode 100644 (file)
index 0000000..0455e24
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * $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_LOWPASSFACTORY
+#define AUD_LOWPASSFACTORY
+
+#include "AUD_EffectFactory.h"
+
+/**
+ * This factory creates a lowpass filter reader.
+ */
+class AUD_LowpassFactory : public AUD_EffectFactory
+{
+private:
+       /**
+        * The attack value in seconds.
+        */
+       float m_frequency;
+
+       /**
+        * The Q factor.
+        */
+       float m_Q;
+
+public:
+       /**
+        * Creates a new lowpass factory.
+        * \param factory The input factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
+        */
+       AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0);
+
+       /**
+        * Creates a new lowpass factory.
+        * \param frequency The cutoff frequency.
+        * \param Q The Q factor.
+        */
+       AUD_LowpassFactory(float frequency, float Q = 1.0);
+
+       virtual AUD_IReader* createReader();
+};
+
+#endif //AUD_LOWPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_LowpassReader.cpp b/intern/audaspace/FX/AUD_LowpassReader.cpp
new file mode 100644 (file)
index 0000000..373d021
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * $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_LowpassReader.h"
+#include "AUD_Buffer.h"
+
+#include <cstring>
+#include <cmath>
+
+#define CC channels + channel
+
+AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
+                                                                        float Q) :
+               AUD_EffectReader(reader)
+{
+       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);
+
+       m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER);
+       AUD_NEW("buffer")
+       memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER);
+
+       m_position = 0;
+
+       // calculate coefficients
+       float w0 = 2.0 * M_PI * frequency / specs.rate;
+       float alpha = sin(w0) / (2 * Q);
+       float norm = 1 + alpha;
+       m_coeff[0][0] = 0;
+       m_coeff[0][1] = -2 * cos(w0) / norm;
+       m_coeff[0][2] = (1 - alpha) / norm;
+       m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm);
+       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();
+
+       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();
+       int channels = specs.channels;
+
+       for(int channel = 0; channel < channels; channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       invalues[m_position * CC] = buf[i * CC];
+                       outvalues[m_position * CC] = 0;
+
+                       for(int j = 0; j < AUD_LOWPASS_ORDER; j++)
+                       {
+                               outvalues[m_position * CC] += m_coeff[1][j] *
+                                               invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] -
+                                               m_coeff[0][j] *
+                                               outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC];
+                       }
+
+                       buffer[i * CC] = outvalues[m_position * CC];
+
+                       m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_LowpassReader.h b/intern/audaspace/FX/AUD_LowpassReader.h
new file mode 100644 (file)
index 0000000..a490ba5
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * $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_LOWPASSREADER
+#define AUD_LOWPASSREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+#define AUD_LOWPASS_ORDER 3
+
+/**
+ * This class represents a lowpass filter.
+ */
+class AUD_LowpassReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer *m_buffer;
+
+       /**
+        * The last out values buffer.
+        */
+       AUD_Buffer *m_outvalues;
+
+       /**
+        * The last in values buffer.
+        */
+       AUD_Buffer *m_invalues;
+
+       /**
+        * The position for buffer cycling.
+        */
+       int m_position;
+
+       /**
+        * Filter coefficients.
+        */
+       float m_coeff[2][AUD_LOWPASS_ORDER];
+
+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);
+};
+
+#endif //AUD_LOWPASSREADER
index 9839aefa83824bc617e886d57fa8b567d4d59606..5d3ce80e811e58f6eaedc8d34860b8e05d6c7c66 100644 (file)
 #include "AUD_RectifyReader.h"
 #include "AUD_Buffer.h"
 
-#include <cstring>
+#include <cmath>
 
 AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
                AUD_EffectReader(reader)
 {
-       int bigendian = 1;
-       bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
-       switch(m_reader->getSpecs().format)
-       {
-       case AUD_FORMAT_S16:
-               m_rectify = AUD_rectify<int16_t>;
-               break;
-       case AUD_FORMAT_S32:
-               m_rectify = AUD_rectify<int32_t>;
-               break;
-       case AUD_FORMAT_FLOAT32:
-               m_rectify = AUD_rectify<float>;
-               break;
-       case AUD_FORMAT_FLOAT64:
-               m_rectify = AUD_rectify<double>;
-               break;
-       case AUD_FORMAT_U8:
-               m_rectify = AUD_rectify_u8;
-               break;
-       case AUD_FORMAT_S24:
-               m_rectify = bigendian ? AUD_rectify_s24_be : AUD_rectify_s24_le;
-               break;
-       default:
-               delete m_reader;
-               AUD_THROW(AUD_ERROR_READER);
-       }
-
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
@@ -73,10 +45,11 @@ 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();
 
-       m_rectify(buffer, buf, length * specs.channels);
+       for(int i = 0; i < length * specs.channels; i++)
+               buffer[i] = fabs(buf[i]);
 }
index 17423811cdc935d2be15f03be637d5bf892c3d4b..afbe2e59cabc1cf466c60e2e18695e2e8dc0ec2e 100644 (file)
@@ -27,7 +27,6 @@
 #define AUD_RECTIFYREADER
 
 #include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
 class AUD_Buffer;
 
 /**
@@ -41,11 +40,6 @@ private:
         */
        AUD_Buffer *m_buffer;
 
-       /**
-        * Rectifying function.
-        */
-       AUD_rectify_f m_rectify;
-
 public:
        /**
         * Creates a new rectify reader.
index 043480b91b9b531993a8534392476eb20764e2f0..82d6c70ce53fa48eafaabddf556286d01aad5cd8 100644 (file)
@@ -65,7 +65,7 @@ int AUD_ReverseReader::getPosition()
 void AUD_ReverseReader::read(int & length, sample_t* & buffer)
 {
        // first correct the length
-       if(m_position+length > m_length)
+       if(m_position + length > m_length)
                length = m_length-m_position;
 
        if(length <= 0)
@@ -74,7 +74,8 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
                return;
        }
 
-       int samplesize = AUD_SAMPLE_SIZE(getSpecs());
+       AUD_Specs specs = getSpecs();
+       int samplesize = AUD_SAMPLE_SIZE(specs);
 
        // resize buffer if needed
        if(m_buffer->getSize() < length * samplesize)
@@ -86,23 +87,20 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
        int len = length;
 
        // read from reader
-       m_reader->seek(m_length-m_position-len);
+       m_reader->seek(m_length - m_position - len);
        m_reader->read(len, buf);
 
        // set null if reader didn't give enough data
        if(len < length)
        {
-               if(getSpecs().format == AUD_FORMAT_U8)
-                       memset(buffer, 0x80, (length-len)*samplesize);
-               else
-                       memset(buffer, 0, (length-len)*samplesize);
-               buffer += length-len;
+               memset(buffer, 0, (length - len) * samplesize);
+               buffer += (length - len) * specs.channels;
        }
 
        // copy the samples reverted
        for(int i = 0; i < len; i++)
-               memcpy(buffer + i * samplesize,
-                          buf + (len - 1 - i) * samplesize,
+               memcpy(buffer + i * specs.channels,
+                          buf + (len - 1 - i) * specs.channels,
                           samplesize);
 
        m_position += length;
index fc3f20152a6aaa594cb9494250ba7a806ba9fd74..f094c1e4ea3bdbcf43a6362201acda28a1985562 100644 (file)
@@ -32,35 +32,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
                AUD_EffectReader(reader),
                m_volume(volume)
 {
-       int bigendian = 1;
-       bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
-
-       switch(m_reader->getSpecs().format)
-       {
-       case AUD_FORMAT_S16:
-               m_adjust = AUD_volume_adjust<int16_t>;
-               break;
-       case AUD_FORMAT_S32:
-               m_adjust = AUD_volume_adjust<int32_t>;
-               break;
-       case AUD_FORMAT_FLOAT32:
-               m_adjust = AUD_volume_adjust<float>;
-               break;
-       case AUD_FORMAT_FLOAT64:
-               m_adjust = AUD_volume_adjust<double>;
-               break;
-       case AUD_FORMAT_U8:
-               m_adjust = AUD_volume_adjust_u8;
-               break;
-       case AUD_FORMAT_S24:
-               m_adjust = bigendian ? AUD_volume_adjust_s24_be :
-                                                          AUD_volume_adjust_s24_le;
-               break;
-       default:
-               delete m_reader;
-               AUD_THROW(AUD_ERROR_READER);
-       }
-
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
@@ -93,5 +64,6 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer)
 
        buffer = m_buffer->getBuffer();
 
-       m_adjust(buffer, buf, length * specs.channels, m_volume);
+       for(int i = 0; i < length * specs.channels; i++)
+               buffer[i] = buf[i] * m_volume;
 }
index f38ae4d265c37166e94530a3ba2dae2040923121..489f85b10f214d63d364b95eea0566b3ebde7b3d 100644 (file)
@@ -27,7 +27,6 @@
 #define AUD_VOLUMEREADER
 
 #include "AUD_EffectReader.h"
-#include "AUD_ConverterFunctions.h"
 class AUD_Buffer;
 
 /**
@@ -46,11 +45,6 @@ private:
         */
        float m_volume;
 
-       /**
-        * Volume adjustment function.
-        */
-       AUD_volume_adjust_f m_adjust;
-
 public:
        /**
         * Creates a new volume reader.
index aa9f425d6fb91d4595d6b06805888fbb413be8a1..dfd5d29e4aa319faa4b53ccbf642c4391aa9e503 100644 (file)
@@ -25,7 +25,6 @@
 
 #include "AUD_OpenALDevice.h"
 #include "AUD_IReader.h"
-#include "AUD_IMixer.h"
 #include "AUD_ConverterFactory.h"
 #include "AUD_SourceCaps.h"
 
@@ -119,7 +118,7 @@ void AUD_OpenALDevice::updateStreams()
        sample_t* buffer;
 
        ALint info;
-       AUD_Specs specs;
+       AUD_DeviceSpecs specs = m_specs;
 
        while(1)
        {
@@ -145,7 +144,7 @@ void AUD_OpenALDevice::updateStreams()
 
                                        if(info)
                                        {
-                                               specs = sound->reader->getSpecs();
+                                               specs.specs = sound->reader->getSpecs();
 
                                                // for all empty buffers
                                                while(info--)
@@ -177,8 +176,8 @@ void AUD_OpenALDevice::updateStreams()
                                                                // fill with new data
                                                                alBufferData(sound->buffers[sound->current],
                                                                                         sound->format,
-                                                                                        buffer,
-                                                                                        length * AUD_SAMPLE_SIZE(specs),
+                                                                                        buffer, length *
+                                                                                        AUD_DEVICE_SAMPLE_SIZE(specs),
                                                                                         specs.rate);
 
                                                                if(alGetError() != AL_NO_ERROR)
@@ -264,7 +263,7 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
        return false;
 }
 
-AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
+AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
 {
        // cannot determine how many channels or which format OpenAL uses, but
        // it at least is able to play 16 bit stereo audio
@@ -289,14 +288,17 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs 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;
 
        alGetError();
 
-       m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
-
        m_specs = specs;
        m_buffersize = buffersize;
        m_playing = false;
@@ -378,12 +380,13 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
        alcDestroyContext(m_context);
        alcCloseDevice(m_device);
 
-       delete m_converter; AUD_DELETE("factory")
+       if(m_converter)
+               delete m_converter; AUD_DELETE("factory")
 
        pthread_mutex_destroy(&m_mutex);
 }
 
-AUD_Specs AUD_OpenALDevice::getSpecs()
+AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
 {
        return m_specs;
 }
@@ -393,45 +396,8 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
        bool valid = true;
        format = 0;
 
-       switch(specs.format)
+       switch(m_specs.format)
        {
-       case AUD_FORMAT_U8:
-               switch(specs.channels)
-               {
-               case AUD_CHANNELS_MONO:
-                       format = AL_FORMAT_MONO8;
-                       break;
-               case AUD_CHANNELS_STEREO:
-                       format = AL_FORMAT_STEREO8;
-                       break;
-               case AUD_CHANNELS_SURROUND4:
-                       if(m_useMC)
-                       {
-                               format = alGetEnumValue("AL_FORMAT_QUAD8");
-                               break;
-                       }
-               case AUD_CHANNELS_SURROUND51:
-                       if(m_useMC)
-                       {
-                               format = alGetEnumValue("AL_FORMAT_51CHN8");
-                               break;
-                       }
-               case AUD_CHANNELS_SURROUND61:
-                       if(m_useMC)
-                       {
-                               format = alGetEnumValue("AL_FORMAT_61CHN8");
-                               break;
-                       }
-               case AUD_CHANNELS_SURROUND71:
-                       if(m_useMC)
-                       {
-                               format = alGetEnumValue("AL_FORMAT_71CHN8");
-                               break;
-                       }
-               default:
-                       valid = false;
-               }
-               break;
        case AUD_FORMAT_S16:
                switch(specs.channels)
                {
@@ -591,23 +557,16 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        if(reader == NULL)
                AUD_THROW(AUD_ERROR_READER);
 
-       AUD_Specs specs;
-
-       specs = reader->getSpecs();
+       AUD_DeviceSpecs specs = m_specs;
+       specs.specs = reader->getSpecs();
 
        // check format
-       bool valid = true;
+       bool valid = specs.channels != AUD_CHANNELS_INVALID;
 
-       if(specs.format == AUD_FORMAT_INVALID)
-               valid = false;
-       else if(specs.format == AUD_FORMAT_S24 ||
-                       specs.format == AUD_FORMAT_S32 ||
-                       specs.format == AUD_FORMAT_FLOAT32 ||
-                       specs.format == AUD_FORMAT_FLOAT64)
+       if(m_converter)
        {
                m_converter->setReader(reader);
                reader = m_converter->createReader();
-               specs = reader->getSpecs();
        }
 
        // create the handle
@@ -618,7 +577,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
        sound->isBuffered = false;
        sound->data_end = false;
 
-       valid &= getFormat(sound->format, specs);
+       valid &= getFormat(sound->format, specs.specs);
 
        if(!valid)
        {
@@ -647,7 +606,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
                                length = m_buffersize;
                                reader->read(length, buf);
                                alBufferData(sound->buffers[i], sound->format, buf,
-                                                        length * AUD_SAMPLE_SIZE(specs), specs.rate);
+                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
+                                                        specs.rate);
                                if(alGetError() != AL_NO_ERROR)
                                        AUD_THROW(AUD_ERROR_OPENAL);
                        }
@@ -875,14 +835,16 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
                                {
                                        sample_t* buf;
                                        int length;
-                                       AUD_Specs specs = alhandle->reader->getSpecs();
+                                       AUD_DeviceSpecs specs = m_specs;
+                                       specs.specs = alhandle->reader->getSpecs();
 
                                        for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
                                        {
                                                length = m_buffersize;
                                                alhandle->reader->read(length, buf);
                                                alBufferData(alhandle->buffers[i], alhandle->format,
-                                                                        buf, length * AUD_SAMPLE_SIZE(specs),
+                                                                        buf,
+                                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
                                                                         specs.rate);
 
                                                if(alGetError() != AL_NO_ERROR)
@@ -1021,6 +983,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
                        // load the factory into an OpenAL buffer
                        if(factory)
                        {
+                               // check if the factory is already buffered
                                lock();
                                for(AUD_BFIterator i = m_bufferedFactories->begin();
                                        i != m_bufferedFactories->end(); i++)
@@ -1040,32 +1003,25 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
                                if(reader == NULL)
                                        return false;
 
-                               AUD_Specs specs;
-
-                               specs = reader->getSpecs();
+                               AUD_DeviceSpecs specs = m_specs;
+                               specs.specs = reader->getSpecs();
 
                                // determine format
                                bool valid = reader->getType() == AUD_TYPE_BUFFER;
 
                                if(valid)
                                {
-                                       if(specs.format == AUD_FORMAT_INVALID)
-                                               valid = false;
-                                       else if(specs.format == AUD_FORMAT_S24 ||
-                                                       specs.format == AUD_FORMAT_S32 ||
-                                                       specs.format == AUD_FORMAT_FLOAT32 ||
-                                                       specs.format == AUD_FORMAT_FLOAT64)
+                                       if(m_converter)
                                        {
                                                m_converter->setReader(reader);
                                                reader = m_converter->createReader();
-                                               specs = reader->getSpecs();
                                        }
                                }
 
                                ALenum format;
 
                                if(valid)
-                                       valid = getFormat(format, specs);
+                                       valid = getFormat(format, specs.specs);
 
                                if(!valid)
                                {
@@ -1094,7 +1050,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
 
                                                reader->read(length, buf);
                                                alBufferData(bf->buffer, format, buf,
-                                                                        length * AUD_SAMPLE_SIZE(specs),
+                                                                        length * AUD_DEVICE_SAMPLE_SIZE(specs),
                                                                         specs.rate);
                                                if(alGetError() != AL_NO_ERROR)
                                                        AUD_THROW(AUD_ERROR_OPENAL);
index 074cd3d1924cd8250ff3e9bad114561856cafacd..cb8c83ab810e247e5bfdf972d543a9e997bfc9aa 100644 (file)
@@ -56,7 +56,7 @@ private:
        /**
         * The specification of the device.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
        /**
         * Whether the device has the AL_EXT_MCFORMATS extension.
@@ -64,8 +64,8 @@ private:
        bool m_useMC;
 
        /**
-        * The converter factory for readers with wrong input format.
-        */
+       * The converter factory for readers with wrong input format.
+       */
        AUD_ConverterFactory* m_converter;
 
        /**
@@ -118,7 +118,7 @@ private:
        /**
         * Gets the format according to the specs.
         * \param format The variable to put the format into.
-        * \param specs The specs to read the format from.
+        * \param specs The specs to read the channel count from.
         * \return Whether the format is valid or not.
         */
        bool getFormat(ALenum &format, AUD_Specs specs);
@@ -132,7 +132,8 @@ public:
         * \note The buffersize will be multiplicated by three for this device.
         * \exception AUD_Exception Thrown if the audio device cannot be opened.
         */
-       AUD_OpenALDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+       AUD_OpenALDevice(AUD_DeviceSpecs specs,
+                                        int buffersize = AUD_DEFAULT_BUFFER_SIZE);
 
        /**
         * Streaming thread main function.
@@ -141,7 +142,7 @@ public:
 
        virtual ~AUD_OpenALDevice();
 
-       virtual AUD_Specs getSpecs();
+       virtual AUD_DeviceSpecs getSpecs();
        virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
        virtual bool pause(AUD_Handle* handle);
        virtual bool resume(AUD_Handle* handle);
index dd443e7f5c72559095b8b67515ddb27dff619e15..1a385af8a0c67b48f6fc63ca0594525762824ea3 100644 (file)
@@ -23,7 +23,6 @@
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_SDLMixer.h"
 #include "AUD_SDLDevice.h"
 #include "AUD_IReader.h"
 
@@ -31,10 +30,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
 {
        AUD_SDLDevice* device = (AUD_SDLDevice*)data;
 
-       device->mix((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs));
+       device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
 }
 
-AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
+AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
 {
        if(specs.channels == AUD_CHANNELS_INVALID)
                specs.channels = AUD_CHANNELS_STEREO;
@@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
        else
                AUD_THROW(AUD_ERROR_SDL);
 
-       m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
-       m_mixer->setSpecs(m_specs);
-
        create();
 }
 
index e2c6f7631b71caf6946699b93e1a6c0362efd819..4b7de1996e8fe28ac5fa19bbf6a87ab66bd2c9de 100644 (file)
@@ -55,7 +55,8 @@ public:
         * \note The specification really used for opening the device may differ.
         * \exception AUD_Exception Thrown if the audio device cannot be opened.
         */
-       AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+       AUD_SDLDevice(AUD_DeviceSpecs specs,
+                                 int buffersize = AUD_DEFAULT_BUFFER_SIZE);
 
        /**
         * Closes the SDL audio device.
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.cpp b/intern/audaspace/SDL/AUD_SDLMixer.cpp
deleted file mode 100644 (file)
index cacc0c7..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * $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_SDLMixer.h"
-#include "AUD_SDLMixerFactory.h"
-
-#include <SDL.h>
-
-AUD_SDLMixer::AUD_SDLMixer()
-{
-       m_factory = NULL;
-}
-
-AUD_SDLMixer::~AUD_SDLMixer()
-{
-       if(m_factory)
-       {
-               delete m_factory; AUD_DELETE("factory")
-       }
-}
-
-AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
-{
-       m_factory->setReader(reader);
-       return m_factory->createReader();
-}
-
-void AUD_SDLMixer::setSpecs(AUD_Specs specs)
-{
-       m_samplesize = AUD_SAMPLE_SIZE(specs);
-       if(m_factory)
-       {
-               delete m_factory; AUD_DELETE("factory")
-       }
-       m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
-}
-
-void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
-                                          float volume)
-{
-       AUD_SDLMixerBuffer buf;
-       buf.buffer = buffer;
-       buf.length = length;
-       buf.volume = volume;
-       m_buffers.push_back(buf);
-}
-
-void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
-{
-       AUD_SDLMixerBuffer buf;
-
-       while(!m_buffers.empty())
-       {
-               buf = m_buffers.front();
-               m_buffers.pop_front();
-               SDL_MixAudio((Uint8*)buffer,
-                                        (Uint8*)buf.buffer,
-                                        buf.length * m_samplesize,
-                                        (int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
-       }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
deleted file mode 100644 (file)
index 0a47e36..0000000
+++ /dev/null
@@ -1,216 +0,0 @@
-/*
- * $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_SDLMixerReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
-{
-       // SDL only supports 8 and 16 bit audio
-       switch(format)
-       {
-       case AUD_FORMAT_U8:
-               return AUDIO_U8;
-       case AUD_FORMAT_S16:
-               return AUDIO_S16SYS;
-       default:
-               AUD_THROW(AUD_ERROR_SDL);
-       }
-}
-
-// greatest common divisor
-inline int gcd(int a, int b)
-{
-       int c;
-
-       // make sure a is the bigger
-       if(b > a)
-       {
-               c = b;
-               b = a;
-               a = c;
-       }
-
-       // greetings from Euclides
-       while(b != 0)
-       {
-               c = a % b;
-               a = b;
-               b = c;
-       }
-       return a;
-}
-
-AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
-                                                                                        AUD_Specs specs)
-{
-       if(reader == NULL)
-               AUD_THROW(AUD_ERROR_READER);
-
-       m_reader = reader;
-       m_tspecs = specs;
-       m_sspecs = reader->getSpecs();
-
-       try
-       {
-               // SDL only supports 8 and 16 bit sample formats
-               if(SDL_BuildAudioCVT(&m_cvt,
-                                                        AUD_TO_SDL(m_sspecs.format),
-                                                        m_sspecs.channels,
-                                                        m_sspecs.rate,
-                                                        AUD_TO_SDL(specs.format),
-                                                        specs.channels,
-                                                        specs.rate) == -1)
-                       AUD_THROW(AUD_ERROR_SDL);
-       }
-       catch(AUD_Exception)
-       {
-               delete m_reader; AUD_DELETE("reader")
-               throw;
-       }
-
-       m_eor = false;
-       m_rsposition = 0;
-       m_rssize = 0;
-       m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
-       m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
-
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-       m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_SDLMixerReader::~AUD_SDLMixerReader()
-{
-       delete m_reader; AUD_DELETE("reader")
-       delete m_buffer; AUD_DELETE("buffer")
-       delete m_rsbuffer; AUD_DELETE("buffer")
-}
-
-bool AUD_SDLMixerReader::isSeekable()
-{
-       return m_reader->isSeekable();
-}
-
-void AUD_SDLMixerReader::seek(int position)
-{
-       m_reader->seek(position * m_ssize / m_tsize);
-       m_eor = false;
-}
-
-int AUD_SDLMixerReader::getLength()
-{
-       return m_reader->getLength() * m_tsize / m_ssize;
-}
-
-int AUD_SDLMixerReader::getPosition()
-{
-       return m_reader->getPosition() * m_tsize / m_ssize;
-}
-
-AUD_Specs AUD_SDLMixerReader::getSpecs()
-{
-       return m_tspecs;
-}
-
-AUD_ReaderType AUD_SDLMixerReader::getType()
-{
-       return m_reader->getType();
-}
-
-bool AUD_SDLMixerReader::notify(AUD_Message &message)
-{
-       return m_reader->notify(message);
-}
-
-void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
-{
-       // sample count for the target buffer without getting a shift
-       int tns = length + m_tsize - length % m_tsize;
-       // sample count for the source buffer without getting a shift
-       int sns = tns * m_ssize / m_tsize;
-       // target sample size
-       int tss = AUD_SAMPLE_SIZE(m_tspecs);
-       // source sample size
-       int sss = AUD_SAMPLE_SIZE(m_sspecs);
-
-       // input is output buffer
-       int buf_size = AUD_MAX(tns*tss, sns*sss);
-
-       // resize if necessary
-       if(m_rsbuffer->getSize() < buf_size)
-               m_rsbuffer->resize(buf_size, true);
-
-       if(m_buffer->getSize() < length*tss)
-               m_buffer->resize(length*tss);
-
-       buffer = m_buffer->getBuffer();
-       int size;
-       int index = 0;
-       sample_t* buf;
-
-       while(index < length)
-       {
-               if(m_rsposition == m_rssize)
-               {
-                       // no more data
-                       if(m_eor)
-                               length = index;
-                       // mix
-                       else
-                       {
-                               // read from source
-                               size = sns;
-                               m_reader->read(size, buf);
-
-                               // prepare
-                               m_cvt.buf = m_rsbuffer->getBuffer();
-                               m_cvt.len = size*sss;
-                               memcpy(m_cvt.buf, buf, size*sss);
-
-                               // convert
-                               SDL_ConvertAudio(&m_cvt);
-
-                               // end of reader
-                               if(size < sns)
-                                       m_eor = true;
-
-                               m_rsposition = 0;
-                               m_rssize = size * m_tsize / m_ssize;
-                       }
-               }
-
-               // size to copy
-               size = AUD_MIN(m_rssize-m_rsposition, length-index);
-
-               // copy
-               memcpy(m_buffer->getBuffer() + index * tss,
-                          m_rsbuffer->getBuffer() + m_rsposition * tss,
-                          size*tss);
-               m_rsposition += size;
-               index += size;
-       }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.h b/intern/audaspace/SDL/AUD_SDLMixerReader.h
deleted file mode 100644 (file)
index 56668d0..0000000
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * $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_SDLMIXERREADER
-#define AUD_SDLMIXERREADER
-
-#include "AUD_IReader.h"
-class AUD_Buffer;
-
-#include <SDL.h>
-
-/**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- *          class doesn't check for compliance, so in case of other factors,
- *          the behaviour is undefined.
- */
-class AUD_SDLMixerReader : public AUD_IReader
-{
-private:
-       /**
-        * The reader that is being mixed.
-        */
-       AUD_IReader* m_reader;
-
-       /**
-        * The current reading position in the resampling buffer.
-        */
-       int m_rsposition;
-
-       /**
-        * The count of mixed samples in the resampling buffer.
-        */
-       int m_rssize;
-
-       /**
-        * The smallest count of source samples to get a fractionless resampling
-        * factor.
-        */
-       int m_ssize;
-
-       /**
-        * The smallest count of target samples to get a fractionless resampling
-        * factor.
-        */
-       int m_tsize;
-
-       /**
-        * The sound output buffer.
-        */
-       AUD_Buffer *m_buffer;
-
-       /**
-        * The resampling buffer.
-        */
-       AUD_Buffer *m_rsbuffer;
-
-       /**
-        * The target specification.
-        */
-       AUD_Specs m_tspecs;
-
-       /**
-        * The sample specification of the source.
-        */
-       AUD_Specs m_sspecs;
-
-       /**
-        * Saves whether the end of the source has been reached.
-        */
-       bool m_eor;
-
-       /**
-        * The SDL_AudioCVT structure used for resampling.
-        */
-       SDL_AudioCVT m_cvt;
-
-public:
-       /**
-        * Creates a resampling reader.
-        * \param reader The reader to mix.
-        * \param specs The target specification.
-        * \exception AUD_Exception Thrown if the source specification cannot be
-        *            mixed to the target specification or if the reader is
-        *            NULL.
-        */
-       AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
-       /**
-        * Destroys the reader.
-        */
-       ~AUD_SDLMixerReader();
-
-       virtual bool isSeekable();
-       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 void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_SDLMIXERREADER
index bcace340b24d874977179b8a31362dd37e0c3e6b..caafbd1432799908afaf4e790a54a4f4d3177453 100644 (file)
 #include "AUD_SRCResampleReader.h"
 
 AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
-                                                                                          AUD_Specs specs) :
+                                                                                          AUD_DeviceSpecs specs) :
                AUD_ResampleFactory(reader, specs) {}
 
 AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
-                                                                                          AUD_Specs specs) :
+                                                                                          AUD_DeviceSpecs specs) :
                AUD_ResampleFactory(factory, specs) {}
 
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_DeviceSpecs specs) :
                AUD_ResampleFactory(specs) {}
 
 AUD_IReader* AUD_SRCResampleFactory::createReader()
@@ -45,7 +45,7 @@ AUD_IReader* AUD_SRCResampleFactory::createReader()
        {
                if(reader->getSpecs().rate != m_specs.rate)
                {
-                       reader = new AUD_SRCResampleReader(reader, m_specs);
+                       reader = new AUD_SRCResampleReader(reader, m_specs.specs);
                        AUD_NEW("reader")
                }
        }
index c23c1d2c82e13a03e73fe377dc6aa7e087cc4515..4b16c70169cefe1e90271dd07753178fa600f488 100644 (file)
 /**
  * This factory creates a resampling reader that uses libsamplerate for
  * resampling.
- * \note The format of the input must be float.
  */
 class AUD_SRCResampleFactory : public AUD_ResampleFactory
 {
 public:
-       AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
-       AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
-       AUD_SRCResampleFactory(AUD_Specs specs);
+       AUD_SRCResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+       AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+       AUD_SRCResampleFactory(AUD_DeviceSpecs specs);
 
        virtual AUD_IReader* createReader();
 };
index f7564d3c010e4dce91024303663177f78be1415f..940f4245316c80dfabc2308522d477afc6bc6afe 100644 (file)
@@ -26,9 +26,9 @@
 #include "AUD_SRCResampleReader.h"
 #include "AUD_Buffer.h"
 
-#include <math.h>
+#include <cmath>
 #include <cstring>
-#include <stdio.h>
+#include <cstdio>
 
 static long src_callback(void *cb_data, float **data)
 {
@@ -41,15 +41,8 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
 {
        m_sspecs = reader->getSpecs();
 
-       if(m_sspecs.format != AUD_FORMAT_FLOAT32)
-       {
-               delete m_reader; AUD_DELETE("reader")
-               AUD_THROW(AUD_ERROR_READER);
-       }
-
        m_tspecs = specs;
        m_tspecs.channels = m_sspecs.channels;
-       m_tspecs.format = m_sspecs.format;
        m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
 
        int error;
@@ -71,9 +64,9 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
 
 AUD_SRCResampleReader::~AUD_SRCResampleReader()
 {
-       delete m_buffer; AUD_DELETE("buffer")
-
        src_delete(m_src);
+
+       delete m_buffer; AUD_DELETE("buffer")
 }
 
 long AUD_SRCResampleReader::doCallback(float** data)
@@ -83,7 +76,7 @@ long AUD_SRCResampleReader::doCallback(float** data)
 
        m_reader->read(length, buffer);
 
-       *data = (float*)buffer;
+       *data = buffer;
        return length;
 }
 
@@ -110,10 +103,12 @@ AUD_Specs AUD_SRCResampleReader::getSpecs()
 
 void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
 {
-       if(m_buffer->getSize() < length * m_tspecs.channels * 4)
-               m_buffer->resize(length * m_tspecs.channels * 4);
+       int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+
+       if(m_buffer->getSize() < size)
+               m_buffer->resize(size);
 
        buffer = m_buffer->getBuffer();
 
-       length = src_callback_read(m_src, m_factor, length, (float*)buffer);
+       length = src_callback_read(m_src, m_factor, length, buffer);
 }
index 1bacdb3965caad4ac53b17961110e0aa5f94544a..4fe30b48c6e7aa41eb7d81893ffda01af3797379 100644 (file)
@@ -32,13 +32,7 @@ class AUD_Buffer;
 #include <samplerate.h>
 
 /**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- *          class doesn't check for compliance, so in case of other factors,
- *          the behaviour is undefined.
+ * This resampling reader uses libsamplerate for resampling.
  */
 class AUD_SRCResampleReader : public AUD_EffectReader
 {
index 0384ba5e0e660ba05ad616824d0cdfedb610f651..027ac015eb5ac50369c53eb069e2727e0698a9f9 100644 (file)
@@ -34,26 +34,6 @@ extern "C" {
 #include <libavformat/avformat.h>
 }
 
-// This function transforms a FFMPEG SampleFormat to our own sample format
-static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
-{
-       switch(fmt)
-       {
-       case SAMPLE_FMT_U8:
-               return AUD_FORMAT_U8;
-       case SAMPLE_FMT_S16:
-               return AUD_FORMAT_S16;
-       case SAMPLE_FMT_S32:
-               return AUD_FORMAT_S32;
-       case SAMPLE_FMT_FLT:
-               return AUD_FORMAT_FLOAT32;
-       case SAMPLE_FMT_DBL:
-               return AUD_FORMAT_FLOAT64;
-       default:
-               return AUD_FORMAT_INVALID;
-       }
-}
-
 int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
 {
        // save packet parameters
@@ -78,11 +58,11 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
                // read samples from the packet
                data_size = buf_size - buf_pos;
                /*read_length = avcodec_decode_audio3(m_codecCtx,
-                       (int16_t*)(buffer->getBuffer()+buf_pos),
+                       (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
                        &data_size,
                        packet);*/
                read_length = avcodec_decode_audio2(m_codecCtx,
-                       (int16_t*)(buffer->getBuffer()+buf_pos),
+                       (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
                        &data_size,
                        audio_pkg_data,
                        audio_pkg_size);
@@ -101,78 +81,108 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
        return buf_pos;
 }
 
-AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+void AUD_FFMPEGReader::init()
 {
        m_position = 0;
        m_pkgbuf_left = 0;
-       m_byteiocontext = NULL;
 
-       // open file
-       if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
-               AUD_THROW(AUD_ERROR_FILE);
+       if(av_find_stream_info(m_formatCtx)<0)
+               AUD_THROW(AUD_ERROR_FFMPEG);
 
-       try
-       {
-               if(av_find_stream_info(m_formatCtx)<0)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
+       // find audio stream and codec
+       m_stream = -1;
 
-               // find audio stream and codec
-               m_stream = -1;
+       for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
+               if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
+                       && (m_stream < 0))
+               {
+                       m_stream=i;
+                       break;
+               }
+       if(m_stream == -1)
+               AUD_THROW(AUD_ERROR_FFMPEG);
 
-               for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
-                       if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
-                               && (m_stream < 0))
-                       {
-                               m_stream=i;
-                               break;
-                       }
-               if(m_stream == -1)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
+       m_codecCtx = m_formatCtx->streams[m_stream]->codec;
 
-               m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+       // get a decoder and open it
+       AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+       if(!aCodec)
+               AUD_THROW(AUD_ERROR_FFMPEG);
 
-               // get a decoder and open it
-               AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
-               if(!aCodec)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
+       if(avcodec_open(m_codecCtx, aCodec)<0)
+               AUD_THROW(AUD_ERROR_FFMPEG);
 
-               if(avcodec_open(m_codecCtx, aCodec)<0)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
+       // XXX this prints file information to stdout:
+       //dump_format(m_formatCtx, 0, NULL, 0);
 
-               // XXX this prints file information to stdout:
-               //dump_format(m_formatCtx, 0, filename, 0);
+       m_specs.channels = (AUD_Channels) m_codecCtx->channels;
 
-               m_specs.channels = (AUD_Channels) m_codecCtx->channels;
-               m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
-               m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
-       }
-       catch(AUD_Exception)
+       switch(m_codecCtx->sample_fmt)
        {
-               av_close_input_file(m_formatCtx);
-               throw;
+       case SAMPLE_FMT_U8:
+               m_convert = AUD_convert_u8_float;
+               m_specs.format = AUD_FORMAT_U8;
+               break;
+       case SAMPLE_FMT_S16:
+               m_convert = AUD_convert_s16_float;
+               m_specs.format = AUD_FORMAT_S16;
+               break;
+       case SAMPLE_FMT_S32:
+               m_convert = AUD_convert_s32_float;
+               m_specs.format = AUD_FORMAT_S32;
+               break;
+       case SAMPLE_FMT_FLT:
+               m_convert = AUD_convert_copy<float>;
+               m_specs.format = AUD_FORMAT_FLOAT32;
+               break;
+       case SAMPLE_FMT_DBL:
+               m_convert = AUD_convert_double_float;
+               m_specs.format = AUD_FORMAT_FLOAT64;
+               break;
+       default:
+               AUD_THROW(AUD_ERROR_FILE);
        }
 
+       m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+
        // last but not least if there hasn't been any error, create the buffers
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
        m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
        AUD_NEW("buffer")
 }
 
+AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+{
+       m_byteiocontext = NULL;
+
+       // open file
+       if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
+               AUD_THROW(AUD_ERROR_FILE);
+
+       try
+       {
+               init();
+       }
+       catch(AUD_Exception)
+       {
+               av_close_input_file(m_formatCtx);
+               throw;
+       }
+}
+
 AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
 {
-       m_position = 0;
-       m_pkgbuf_left = 0;
        m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
        AUD_NEW("byteiocontext")
        m_membuffer = buffer;
 
-       if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
-                                        NULL, NULL, NULL, NULL) != 0)
+       if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
+                                        buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
                AUD_THROW(AUD_ERROR_FILE);
 
        AVProbeData probe_data;
        probe_data.filename = "";
-       probe_data.buf = buffer.get()->getBuffer();
+       probe_data.buf = (data_t*)buffer.get()->getBuffer();
        probe_data.buf_size = buffer.get()->getSize();
        AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
 
@@ -182,38 +192,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
 
        try
        {
-               if(av_find_stream_info(m_formatCtx)<0)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
-
-               // find audio stream and codec
-               m_stream = -1;
-
-               for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
-                       if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
-                               && (m_stream < 0))
-                       {
-                               m_stream=i;
-                               break;
-                       }
-               if(m_stream == -1)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
-
-               m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
-               // get a decoder and open it
-               AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
-               if(!aCodec)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
-
-               if(avcodec_open(m_codecCtx, aCodec)<0)
-                       AUD_THROW(AUD_ERROR_FFMPEG);
-
-               // XXX this prints stream information to stdout:
-               //dump_format(m_formatCtx, 0, NULL, 0);
-
-               m_specs.channels = (AUD_Channels) m_codecCtx->channels;
-               m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
-               m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+               init();
        }
        catch(AUD_Exception)
        {
@@ -221,11 +200,6 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
                av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
                throw;
        }
-
-       // last but not least if there hasn't been any error, create the buffers
-       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
-       m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
-       AUD_NEW("buffer")
 }
 
 AUD_FFMPEGReader::~AUD_FFMPEGReader()
@@ -316,7 +290,7 @@ int AUD_FFMPEGReader::getPosition()
 
 AUD_Specs AUD_FFMPEGReader::getSpecs()
 {
-       return m_specs;
+       return m_specs.specs;
 }
 
 AUD_ReaderType AUD_FFMPEGReader::getType()
@@ -336,11 +310,11 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
        int data_size = 0;
        int pkgbuf_pos;
        int left = length;
-       int sample_size = AUD_SAMPLE_SIZE(m_specs);
+       int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
 
        // resize output buffer if necessary
-       if(m_buffer->getSize() < length*sample_size)
-               m_buffer->resize(length*sample_size);
+       if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(m_specs))
+               m_buffer->resize(length * AUD_SAMPLE_SIZE(m_specs));
 
        buffer = m_buffer->getBuffer();
        pkgbuf_pos = m_pkgbuf_left;
@@ -350,8 +324,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
        if(pkgbuf_pos > 0)
        {
                data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
-               memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
-               buffer += data_size;
+               m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+                                 data_size / AUD_FORMAT_SIZE(m_specs.format));
+               buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
                left -= data_size/sample_size;
        }
 
@@ -366,8 +341,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
 
                        // copy to output buffer
                        data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
-                       memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
-                       buffer += data_size;
+                       m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+                                         data_size / AUD_FORMAT_SIZE(m_specs.format));
+                       buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
                        left -= data_size/sample_size;
                }
                av_free_packet(&packet);
@@ -376,7 +352,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
        if(pkgbuf_pos > data_size)
        {
                m_pkgbuf_left = pkgbuf_pos-data_size;
-               memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
+               memmove(m_pkgbuf->getBuffer(),
+                               ((data_t*)m_pkgbuf->getBuffer())+data_size,
                                pkgbuf_pos-data_size);
        }
 
index 6e303934f3603da05c6a698328b4144651a61a1f..f992fdf7a340997bda1c6ab6f9b93f8b7da1438c 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef AUD_FFMPEGREADER
 #define AUD_FFMPEGREADER
 
+#include "AUD_ConverterFunctions.h"
 #include "AUD_IReader.h"
 #include "AUD_Reference.h"
 class AUD_Buffer;
@@ -59,7 +60,7 @@ private:
        /**
         * The specification of the audio data.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
        /**
         * The buffer for package reading.
@@ -91,6 +92,11 @@ private:
         */
        int m_stream;
 
+       /**
+        * Converter function.
+        */
+       AUD_convert_f m_convert;
+
        /**
         * The memory file to read from, only saved to keep the buffer alive.
         */
@@ -104,6 +110,11 @@ private:
         */
        int decode(AVPacket* packet, AUD_Buffer* buffer);
 
+       /**
+        * Initializes the object.
+        */
+       void init();
+
 public:
        /**
         * Creates a new reader.
index 5a957081208ad12dbac745f4d3ab9ec2310b545e..2950cdf8bad75dd086b3a528d921b4bacf51bdbf 100644 (file)
@@ -63,16 +63,8 @@ AUD_IReader* AUD_BandPassFactory::createReader()
 
        if(reader != 0)
        {
-               if(reader->getSpecs().format == AUD_FORMAT_FLOAT32)
-               {
-                       reader = new AUD_BandPassReader(reader, m_low, m_high);
-                       AUD_NEW("reader")
-               }
-               else
-               {
-                       delete reader; AUD_DELETE("reader")
-                       return 0;
-               }
+               reader = new AUD_BandPassReader(reader, m_low, m_high);
+               AUD_NEW("reader")
        }
 
        return reader;
index 34d7193866f0fb8c0aaffd0e9199d377ea5635c5..e77b69863f13747d1764a1b71b3014c0d9c7c4b0 100644 (file)
@@ -77,7 +77,6 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
                        }
 
                        m_length = length;
-                       printf("WINDOW: %d\n", m_length);
 
                        if(m_length * sizeof(double) > m_in->getSize())
                        {
@@ -95,16 +94,15 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
                                                                                          FFTW_ESTIMATE);
                }
 
-               float* source = (float*) buffer;
                double* target = (double*) m_in->getBuffer();
-               float* target2 = (float*) m_buffer->getBuffer();
+               sample_t* target2 = m_buffer->getBuffer();
                fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
                float frequency;
 
                for(int channel = 0; channel < specs.channels; channel++)
                {
                        for(int i = 0; i < m_length; i++)
-                               target[i] = source[i * specs.channels + channel];
+                               target[i] = buffer[i * specs.channels + channel];
 
                        fftw_execute(m_forward);
 
index 71deae0e87e50f1b8924daed32ff9880f394d5fe..a8e74a023bf91fad03ab4d595c43ac69b6f31708 100644 (file)
 #include "AUD_Space.h"
 
 #include <cstring>
-#include <stdlib.h>
+#include <cstdlib>
 
 #define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
 
 AUD_Buffer::AUD_Buffer(int size)
 {
        m_size = size;
-       m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+       m_buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
 }
 
 AUD_Buffer::~AUD_Buffer()
@@ -44,7 +44,7 @@ AUD_Buffer::~AUD_Buffer()
 
 sample_t* AUD_Buffer::getBuffer()
 {
-       return AUD_ALIGN(m_buffer);
+       return (sample_t*) AUD_ALIGN(m_buffer);
 }
 
 int AUD_Buffer::getSize()
@@ -54,7 +54,7 @@ int AUD_Buffer::getSize()
 
 void AUD_Buffer::resize(int size, bool keep)
 {
-       sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+       data_t* buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
 
        // copy old data over if wanted
        if(keep)
index 64959b0379967afaf7bfba5e207f375ea773a08d..f745ee6154b773a7dc6325a84fc13f5cf5e4865d 100644 (file)
@@ -39,7 +39,7 @@ private:
        int m_size;
 
        /// The pointer to the buffer memory.
-       sample_t* m_buffer;
+       data_t* m_buffer;
 
 public:
        /**
index 6cea849bdfc54dba0c77902e65296d32cfc6e0ad..0101de338bdf233f6da19d736f6710aec2541d04 100644 (file)
@@ -79,11 +79,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
 {
        int sample_size = AUD_SAMPLE_SIZE(m_specs);
 
-       buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
+       buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
 
        // in case the end of the buffer is reached
-       if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
-               length = m_buffer.get()->getSize()/sample_size-m_position;
+       if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
+               length = m_buffer.get()->getSize() / sample_size - m_position;
 
        if(length < 0)
                length = 0;
index cd6b95b1d9eef60942a384456594d826c866b786..964ac2e650c84bb59f7278066ef2b47d7ab04dc0 100644 (file)
@@ -23,6 +23,9 @@
  * ***** END LGPL LICENSE BLOCK *****
  */
 
+#include <cstdlib>
+#include <cstring>
+
 #include "AUD_NULLDevice.h"
 #include "AUD_I3DDevice.h"
 #include "AUD_FileFactory.h"
 #include "AUD_PingPongFactory.h"
 #include "AUD_LoopFactory.h"
 #include "AUD_RectifyFactory.h"
+#include "AUD_EnvelopeFactory.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_ChannelMapperFactory.h"
+#include "AUD_Buffer.h"
 #include "AUD_ReadDevice.h"
 #include "AUD_SourceCaps.h"
 #include "AUD_IReader.h"
 
 #ifdef WITH_SDL
 #include "AUD_SDLDevice.h"
-#include "AUD_FloatMixer.h"
 #endif
 
 #ifdef WITH_OPENAL
@@ -55,7 +63,7 @@ extern "C" {
 }
 #endif
 
-#include <assert.h>
+#include <cassert>
 
 typedef AUD_IFactory AUD_Sound;
 typedef AUD_ReadDevice AUD_Device;
@@ -71,7 +79,7 @@ static AUD_IDevice* AUD_device = NULL;
 static int AUD_available_devices[4];
 static AUD_I3DDevice* AUD_3ddevice = NULL;
 
-int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
+int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
 {
 #ifdef WITH_FFMPEG
        av_register_all();
@@ -90,12 +98,8 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
                        break;
 #ifdef WITH_SDL
                case AUD_SDL_DEVICE:
-                       {
-                               dev = new AUD_SDLDevice(specs, buffersize);
-                               AUD_FloatMixer* mixer = new AUD_FloatMixer();
-                               ((AUD_SDLDevice*)dev)->setMixer(mixer);
-                               break;
-                       }
+                       dev = new AUD_SDLDevice(specs, buffersize);
+                       break;
 #endif
 #ifdef WITH_OPENAL
                case AUD_OPENAL_DEVICE:
@@ -177,7 +181,6 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
        else
        {
                info.specs.channels = AUD_CHANNELS_INVALID;
-               info.specs.format = AUD_FORMAT_INVALID;
                info.specs.rate = AUD_RATE_INVALID;
                info.length = 0.0;
        }
@@ -519,7 +522,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
        return false;
 }
 
-AUD_Device* AUD_openReadDevice(AUD_Specs specs)
+AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
 {
        try
        {
@@ -578,7 +581,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
        return false;
 }
 
-int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
+int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
 {
        assert(device);
        assert(buffer);
@@ -605,3 +608,43 @@ void AUD_closeReadDevice(AUD_Device* device)
        {
        }
 }
+
+float* AUD_readSoundBuffer(const char* filename, float low, float high,
+                                                  float attack, float release, float threshold,
+                                                  int samplerate, int* length)
+{
+       AUD_Buffer buffer;
+       AUD_DeviceSpecs specs;
+       specs.channels = AUD_CHANNELS_MONO;
+       specs.rate = (AUD_SampleRate)samplerate;
+
+       AUD_FileFactory file(filename);
+       AUD_ChannelMapperFactory mapper(&file, specs);
+       AUD_LowpassFactory lowpass(&mapper, high);
+       AUD_HighpassFactory highpass(&lowpass, low);
+       AUD_EnvelopeFactory envelope(&highpass, attack, release, threshold, 0.1f);
+       AUD_LinearResampleFactory resampler(&envelope, specs);
+
+       AUD_IReader* reader = resampler.createReader();
+
+       if(reader == NULL)
+               return NULL;
+
+       int len;
+       int position = 0;
+       sample_t* readbuffer;
+       do
+       {
+               len = samplerate;
+               buffer.resize((position + len) * sizeof(float), true);
+               reader->read(len, readbuffer);
+               memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
+               position += len;
+       } while(len != 0);
+       delete reader;
+
+       float* result = (float*)malloc(position * sizeof(float));
+       memcpy(result, buffer.getBuffer(), position * sizeof(float));
+       *length = position;
+       return result;
+}
index 866f0248cb21cd762a175ddf691e8cddba67f19f..9223c870ccfb0515dee5acc856f75d474b8d7529 100644 (file)
@@ -59,7 +59,7 @@ typedef struct
  * \param buffersize The buffersize for the device.
  * \return Whether the device has been initialized.
  */
-extern int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
+extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
 
 /**
  * Returns a integer list with available sound devices. The last one is always
@@ -304,7 +304,7 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
  * \param specs The specification of the audio data.
  * \return A device handle.
  */
-extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
+extern AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs);
 
 /**
  * Sets the main volume of a device.
@@ -342,7 +342,7 @@ extern int AUD_setDeviceSoundVolume(AUD_Device* device,
  *         played back currently, in that case the buffer is filled with
  *         silence.
  */
-extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
+extern int AUD_readDevice(AUD_Device* device, data_t* buffer, int length);
 
 /**
  * Closes a read device.
@@ -350,6 +350,14 @@ extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
  */
 extern void AUD_closeReadDevice(AUD_Device* device);
 
+/**
+ * Reads a sound file into a newly created float buffer.
+ * The sound is therefore bandpassed, rectified and resampled.
+ */
+extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
+                                                                 float attack, float release, float threshold,
+                                                                 int samplerate, int* length);
+
 #ifdef __cplusplus
 }
 #endif
index 66205a5801575abb8c1a79758059c8bd0da4edff..3420ed166496459ae92517b41d0769364ca49a74 100644 (file)
 #include <cstring>
 
 AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
-                                                                                  AUD_Specs specs) :
+                                                                                                  AUD_DeviceSpecs specs) :
                AUD_MixerFactory(reader, specs)
 {
        memset(m_mapping, 0, sizeof(m_mapping));
 }
 
 AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
-                                                                                  AUD_Specs specs) :
+                                                                                                  AUD_DeviceSpecs specs) :
                AUD_MixerFactory(factory, specs)
 {
        memset(m_mapping, 0, sizeof(m_mapping));
 }
 
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_DeviceSpecs specs) :
                AUD_MixerFactory(specs)
 {
        memset(m_mapping, 0, sizeof(m_mapping));
index c2c39f4bdf6492378bb550a35fc6707637cdd2e4..a67bfa12123a44079f72c70ab266f55a0164b0db 100644 (file)
@@ -41,9 +41,9 @@ private:
        float **m_mapping[9];
 
 public:
-       AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
-       AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
-       AUD_ChannelMapperFactory(AUD_Specs specs);
+       AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+       AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+       AUD_ChannelMapperFactory(AUD_DeviceSpecs specs);
 
        virtual ~AUD_ChannelMapperFactory();
 
index 61f97c08a8eb93cc70d1b265419a281924cca127..4de5875a33fa9d3479d66cc02d55b578cb4ec16d 100644 (file)
@@ -32,12 +32,6 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
 {
        m_specs = reader->getSpecs();
 
-       if(m_specs.format != AUD_FORMAT_FLOAT32)
-       {
-               delete m_reader; AUD_DELETE("reader")
-               AUD_THROW(AUD_ERROR_READER);
-       }
-
        int channels = -1;
        m_rch = m_specs.channels;
        while(mapping[++channels] != 0);
@@ -89,9 +83,9 @@ void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
        if(m_buffer->getSize() < length * 4 * channels)
                m_buffer->resize(length * 4 * channels);
 
-       float* in = (float*)buffer;
-       float* out = (float*)m_buffer->getBuffer();
-       float sum;
+       sample_t* in = buffer;
+       sample_t* out = m_buffer->getBuffer();
+       sample_t sum;
 
        for(int i = 0; i < length; i++)
        {
index a1a86662072b3c3e102c3d90b58ce7a67a4f56ef..1c6d5468251c4dea6f4621cb7153fb631c3e17b4 100644 (file)
 #include "AUD_ConverterReader.h"
 
 AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
-                                                                                  AUD_Specs specs) :
+                                                                                  AUD_DeviceSpecs specs) :
                AUD_MixerFactory(reader, specs) {}
 
 AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
-                                                                                  AUD_Specs specs) :
+                                                                                  AUD_DeviceSpecs specs) :
                AUD_MixerFactory(factory, specs) {}
 
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_DeviceSpecs specs) :
                AUD_MixerFactory(specs) {}
 
 AUD_IReader* AUD_ConverterFactory::createReader()
@@ -43,7 +43,7 @@ AUD_IReader* AUD_ConverterFactory::createReader()
 
        if(reader != 0)
        {
-               if(reader->getSpecs().format != m_specs.format)
+               if(m_specs.format != AUD_FORMAT_FLOAT32)
                {
                        reader = new AUD_ConverterReader(reader, m_specs);
                        AUD_NEW("reader")
index 3778e8d8f03b28e22b135d112762b6fdd0e1a9c4..11ca6c9f0a89976c8471ac3e4e46fdf6760f79bc 100644 (file)
@@ -35,9 +35,9 @@
 class AUD_ConverterFactory : public AUD_MixerFactory
 {
 public:
-       AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
-       AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
-       AUD_ConverterFactory(AUD_Specs specs);
+       AUD_ConverterFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+       AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+       AUD_ConverterFactory(AUD_DeviceSpecs specs);
 
        virtual AUD_IReader* createReader();
 };
index 1b5d07bcc613cfbe1e012ffffd44a5e65da72142..70018917d43a376f1dba0f43d24d50aa12115fc6 100644 (file)
 #define AUD_FLT_MAX            1.0
 #define AUD_FLT_MIN            -1.0
 
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
 }
 
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
 {
        for(int i = 0; i < length; i++)
        {
@@ -53,7 +53,7 @@ void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
 {
        for(int i = 0; i < length; i++)
        {
@@ -63,35 +63,35 @@ void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
 {
        int32_t* t = (int32_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
 }
 
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_float(data_t* target, data_t* source, int length)
 {
        float* t = (float*) target;
        for(int i = 0; i < length; i++)
                t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
 }
 
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_double(data_t* target, data_t* source, int length)
 {
        double* t = (double*) target;
        for(int i = 0; i < length; i++)
                t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
 }
 
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        for(int i = 0; i < length; i++)
                target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
 }
 
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        for(int i = 0; i < length; i++)
@@ -102,7 +102,7 @@ void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        for(int i = 0; i < length; i++)
@@ -113,7 +113,7 @@ void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        int32_t* t = (int32_t*) target;
@@ -121,7 +121,7 @@ void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
                t[i] = ((int32_t)s[i]) << 16;
 }
 
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_float(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        float* t = (float*) target;
@@ -129,7 +129,7 @@ void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
                t[i] = s[i] / AUD_S16_FLT;
 }
 
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_double(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        double* t = (double*) target;
@@ -137,52 +137,52 @@ void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
                t[i] = s[i] / AUD_S16_FLT;
 }
 
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
 {
        for(int i = 0; i < length; i++)
                target[i] = source[i*3] ^ AUD_U8_0;
 }
 
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
 {
        for(int i = 0; i < length; i++)
                target[i] = source[i*3+2] ^ AUD_U8_0;
 }
 
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = source[i*3] << 8 | source[i*3+1];
 }
 
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = source[i*3+2] << 8 | source[i*3+1];
 }
 
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
 {
        memcpy(target, source, length * 3);
 }
 
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
 {
        int32_t* t = (int32_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
 }
 
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
 {
        int32_t* t = (int32_t*) target;
        for(int i = 0; i < length; i++)
                t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
 }
 
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
 {
        float* t = (float*) target;
        int32_t s;
@@ -193,7 +193,7 @@ void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
 {
        float* t = (float*) target;
        int32_t s;
@@ -204,7 +204,7 @@ void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
 {
        double* t = (double*) target;
        int32_t s;
@@ -215,7 +215,7 @@ void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
 {
        double* t = (double*) target;
        int32_t s;
@@ -226,14 +226,14 @@ void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        for(int i = 0; i < length; i++)
                target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
 }
 
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        int32_t* s = (int32_t*) source;
@@ -241,7 +241,7 @@ void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
                t[i] = s[i] >> 16;
 }
 
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
 {
        int32_t* s = (int32_t*) source;
        for(int i = 0; i < length; i++)
@@ -252,7 +252,7 @@ void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
 {
        int16_t* s = (int16_t*) source;
        for(int i = 0; i < length; i++)
@@ -263,7 +263,7 @@ void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_float(data_t* target, data_t* source, int length)
 {
        int32_t* s = (int32_t*) source;
        float* t = (float*) target;
@@ -271,7 +271,7 @@ void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
                t[i] = s[i] / AUD_S32_FLT;
 }
 
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_double(data_t* target, data_t* source, int length)
 {
        int32_t* s = (int32_t*) source;
        double* t = (double*) target;
@@ -279,7 +279,7 @@ void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
                t[i] = s[i] / AUD_S32_FLT;
 }
 
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_u8(data_t* target, data_t* source, int length)
 {
        float* s = (float*) source;
        float t;
@@ -295,7 +295,7 @@ void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s16(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        float* s = (float*) source;
@@ -310,7 +310,7 @@ void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
 {
        int32_t t;
        float* s = (float*) source;
@@ -328,7 +328,7 @@ void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
 {
        int32_t t;
        float* s = (float*) source;
@@ -346,7 +346,7 @@ void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s32(data_t* target, data_t* source, int length)
 {
        int32_t* t = (int32_t*) target;
        float* s = (float*) source;
@@ -361,7 +361,7 @@ void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_double(data_t* target, data_t* source, int length)
 {
        float* s = (float*) source;
        double* t = (double*) target;
@@ -369,7 +369,7 @@ void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
                t[i] = s[i];
 }
 
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_u8(data_t* target, data_t* source, int length)
 {
        double* s = (double*) source;
        double t;
@@ -385,7 +385,7 @@ void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s16(data_t* target, data_t* source, int length)
 {
        int16_t* t = (int16_t*) target;
        double* s = (double*) source;
@@ -400,7 +400,7 @@ void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
 {
        int32_t t;
        double* s = (double*) source;
@@ -418,7 +418,7 @@ void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
 {
        int32_t t;
        double* s = (double*) source;
@@ -436,7 +436,7 @@ void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s32(data_t* target, data_t* source, int length)
 {
        int32_t* t = (int32_t*) target;
        double* s = (double*) source;
@@ -451,92 +451,10 @@ void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
        }
 }
 
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_float(data_t* target, data_t* source, int length)
 {
        double* s = (double*) source;
        float* t = (float*) target;
        for(int i = 0; i < length; i++)
                t[i] = s[i];
 }
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
-                                                 int count, float volume)
-{
-       for(int i=0; i<count; i++)
-               target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
-}
-
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
-                                                         int count, float volume)
-{
-       count *= 3;
-       int value;
-
-       for(int i=0; i<count; i+=3)
-       {
-               value = source[i+2] << 16 | source[i+1] << 8 | source[i];
-               value |= (((value & 0x800000) >> 23) * 255) << 24;
-               value *= volume;
-               target[i+2] = value >> 16;
-               target[i+1] = value >> 8;
-               target[i] = value;
-       }
-}
-
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
-                                                         int count, float volume)
-{
-       count *= 3;
-       int value;
-
-       for(int i=0; i < count; i+=3)
-       {
-               value = source[i] << 16 | source[i+1] << 8 | source[i+2];
-               value |= (((value & 0x800000) >> 23) * 255) << 24;
-               value *= volume;
-               target[i] = value >> 16;
-               target[i+1] = value >> 8;
-               target[i+2] = value;
-       }
-}
-
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count)
-{
-       for(int i=0; i<count; i++)
-               target[i] = source[i] < 0x80 ? 0x0100 - source[i] : source[i];
-}
-
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count)
-{
-       count *= 3;
-       int value;
-
-       for(int i=0; i<count; i+=3)
-       {
-               value = source[i+2] << 16 | source[i+1] << 8 | source[i];
-               value |= (((value & 0x800000) >> 23) * 255) << 24;
-               if(value < 0)
-                       value = -value;
-               target[i+2] = value >> 16;
-               target[i+1] = value >> 8;
-               target[i] = value;
-       }
-}
-
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count)
-{
-       count *= 3;
-       int value;
-
-       for(int i=0; i < count; i+=3)
-       {
-               value = source[i] << 16 | source[i+1] << 8 | source[i+2];
-               value |= (((value & 0x800000) >> 23) * 255) << 24;
-               if(value < 0)
-                       value = -value;
-               target[i] = value >> 16;
-               target[i+1] = value >> 8;
-               target[i+2] = value;
-       }
-}
-
index 686e58704b79de6e89e7f10ef4d8db0ca5b132dd..a925f138aa2934f5802a3a887c8dc3d41ed88b47 100644 (file)
 #include <stdint.h>
 #endif
 
-typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
-
-typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
-                                                                       int count, float volume);
-
-typedef void (*AUD_rectify_f)(sample_t* target, sample_t* source, int count);
+typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
 
 template <class T>
-void AUD_convert_copy(sample_t* target, sample_t* source, int length)
+void AUD_convert_copy(data_t* target, data_t* source, int length)
 {
        memcpy(target, source, length*sizeof(T));
 }
 
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
 
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
 
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_float(data_t* target, data_t* source, int length);
 
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_double(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_float(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_double(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_float(data_t* target, data_t* source, int length);
 
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_double(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_u8(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s16(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s32(data_t* target, data_t* source, int length);
 
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_double(data_t* target, data_t* source, int length);
 
-template <class T>
-void AUD_volume_adjust(sample_t* target, sample_t* source,
-                                          int count, float volume)
-{
-       T* t = (T*)target;
-       T* s = (T*)source;
-       for(int i=0; i < count; i++)
-               t[i] = (T)(s[i] * volume);
-}
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
-                                                 int count, float volume);
+void AUD_convert_double_u8(data_t* target, data_t* source, int length);
 
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
-                                                         int count, float volume);
+void AUD_convert_double_s16(data_t* target, data_t* source, int length);
 
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
-                                                         int count, float volume);
-
-template <class T>
-void AUD_rectify(sample_t* target, sample_t* source, int count)
-{
-       T* t = (T*)target;
-       T* s = (T*)source;
-       for(int i=0; i < count; i++)
-               t[i] = s[i] < 0 ? -s[i] : s[i];
-}
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
 
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
 
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s32(data_t* target, data_t* source, int length);
 
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_float(data_t* target, data_t* source, int length);
 
 #endif //AUD_CONVERTERFUNCTIONS
index da25a2b74601ef02ee208eb84c23686419465607..808144085bbdb5bb4bbe416cc9de724d016e6ab4 100644 (file)
 #include "AUD_ConverterReader.h"
 #include "AUD_Buffer.h"
 
-AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
+AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
+                                                                                AUD_DeviceSpecs specs) :
                AUD_EffectReader(reader)
 {
-       m_specs = reader->getSpecs();
+       m_specs.specs = reader->getSpecs();
 
        int bigendian = 1;
        bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
 
-       switch(m_specs.format)
+       switch(specs.format)
        {
        case AUD_FORMAT_U8:
-               switch(specs.format)
-               {
-               case AUD_FORMAT_U8:
-                       m_convert = AUD_convert_copy<unsigned char>;
-                       break;
-               case AUD_FORMAT_S16:
-                       m_convert = AUD_convert_u8_s16;
-                       break;
-               case AUD_FORMAT_S24:
-                       if(bigendian)
-                               m_convert = AUD_convert_u8_s24_be;
-                       else
-                               m_convert = AUD_convert_u8_s24_le;
-                       break;
-               case AUD_FORMAT_S32:
-                       m_convert = AUD_convert_u8_s32;
-                       break;
-               case AUD_FORMAT_FLOAT32:
-                       m_convert = AUD_convert_u8_float;
-                       break;
-               case AUD_FORMAT_FLOAT64:
-                       m_convert = AUD_convert_u8_double;
-                       break;
-               default:
-                       break;
-               }
+               m_convert = AUD_convert_float_u8;
                break;
        case AUD_FORMAT_S16:
-               switch(specs.format)
-               {
-               case AUD_FORMAT_U8:
-                       m_convert = AUD_convert_s16_u8;
-                       break;
-               case AUD_FORMAT_S16:
-                       m_convert = AUD_convert_copy<int16_t>;
-                       break;
-               case AUD_FORMAT_S24:
-                       if(bigendian)
-                               m_convert = AUD_convert_s16_s24_be;
-                       else
-                               m_convert = AUD_convert_s16_s24_le;
-                       break;
-               case AUD_FORMAT_S32:
-                       m_convert = AUD_convert_s16_s32;
-                       break;
-               case AUD_FORMAT_FLOAT32:
-                       m_convert = AUD_convert_s16_float;
-                       break;
-               case AUD_FORMAT_FLOAT64:
-                       m_convert = AUD_convert_s16_double;
-                       break;
-               default:
-                       break;
-               }
+               m_convert = AUD_convert_float_s16;
                break;
        case AUD_FORMAT_S24:
                if(bigendian)
-                       switch(specs.format)
-                       {
-                       case AUD_FORMAT_U8:
-                               m_convert = AUD_convert_u8_s24_be;
-                               break;
-                       case AUD_FORMAT_S16:
-                               m_convert = AUD_convert_s16_s24_be;
-                               break;
-                       case AUD_FORMAT_S24:
-                               m_convert = AUD_convert_s24_s24;
-                               break;
-                       case AUD_FORMAT_S32:
-                               m_convert = AUD_convert_s32_s24_be;
-                               break;
-                       case AUD_FORMAT_FLOAT32:
-                               m_convert = AUD_convert_float_s24_be;
-                               break;
-                       case AUD_FORMAT_FLOAT64:
-                               m_convert = AUD_convert_double_s24_be;
-                               break;
-                       default:
-                               break;
-                       }
+                       m_convert = AUD_convert_float_s24_be;
                else
-                       switch(specs.format)
-                       {
-                       case AUD_FORMAT_U8:
-                               m_convert = AUD_convert_u8_s24_le;
-                               break;
-                       case AUD_FORMAT_S16:
-                               m_convert = AUD_convert_s16_s24_le;
-                               break;
-                       case AUD_FORMAT_S24:
-                               m_convert = AUD_convert_s24_s24;
-                               break;
-                       case AUD_FORMAT_S32:
-                               m_convert = AUD_convert_s32_s24_le;
-                               break;
-                       case AUD_FORMAT_FLOAT32:
-                               m_convert = AUD_convert_float_s24_le;
-                               break;
-                       case AUD_FORMAT_FLOAT64:
-                               m_convert = AUD_convert_double_s24_le;
-                               break;
-                       default:
-                               break;
-                       }
+                       m_convert = AUD_convert_float_s24_le;
                break;
        case AUD_FORMAT_S32:
-               switch(specs.format)
-               {
-               case AUD_FORMAT_U8:
-                       m_convert = AUD_convert_s32_u8;
-                       break;
-               case AUD_FORMAT_S16:
-                       m_convert = AUD_convert_s32_s16;
-                       break;
-               case AUD_FORMAT_S24:
-                       if(bigendian)
-                               m_convert = AUD_convert_s32_s24_be;
-                       else
-                               m_convert = AUD_convert_s32_s24_le;
-                       break;
-               case AUD_FORMAT_S32:
-                       m_convert = AUD_convert_copy<int32_t>;
-                       break;
-               case AUD_FORMAT_FLOAT32:
-                       m_convert = AUD_convert_s32_float;
-                       break;
-               case AUD_FORMAT_FLOAT64:
-                       m_convert = AUD_convert_s32_double;
-                       break;
-               default:
-                       break;
-               }
+               m_convert = AUD_convert_float_s32;
                break;
        case AUD_FORMAT_FLOAT32:
-               switch(specs.format)
-               {
-               case AUD_FORMAT_U8:
-                       m_convert = AUD_convert_float_u8;
-                       break;
-               case AUD_FORMAT_S16:
-                       m_convert = AUD_convert_float_s16;
-                       break;
-               case AUD_FORMAT_S24:
-                       if(bigendian)
-                               m_convert = AUD_convert_float_s24_be;
-                       else
-                               m_convert = AUD_convert_float_s24_le;
-                       break;
-               case AUD_FORMAT_S32:
-                       m_convert = AUD_convert_float_s32;
-                       break;
-               case AUD_FORMAT_FLOAT32:
-                       m_convert = AUD_convert_copy<float>;
-                       break;
-               case AUD_FORMAT_FLOAT64:
-                       m_convert = AUD_convert_float_double;
-                       break;
-               default:
-                       break;
-               }
+               m_convert = AUD_convert_copy<float>;
                break;
        case AUD_FORMAT_FLOAT64:
-               switch(specs.format)
-               {
-               case AUD_FORMAT_U8:
-                       m_convert = AUD_convert_double_u8;
-                       break;
-               case AUD_FORMAT_S16:
-                       m_convert = AUD_convert_double_s16;
-                       break;
-               case AUD_FORMAT_S24:
-                       if(bigendian)
-                               m_convert = AUD_convert_double_s24_be;
-                       else
-                               m_convert = AUD_convert_double_s24_le;
-                       break;
-               case AUD_FORMAT_S32:
-                       m_convert = AUD_convert_double_s32;
-                       break;
-               case AUD_FORMAT_FLOAT32:
-                       m_convert = AUD_convert_double_float;
-                       break;
-               case AUD_FORMAT_FLOAT64:
-                       m_convert = AUD_convert_copy<double>;
-                       break;
-               default:
-                       break;
-               }
+               m_convert = AUD_convert_float_double;
                break;
        default:
                break;
@@ -242,7 +74,7 @@ AUD_ConverterReader::~AUD_ConverterReader()
 
 AUD_Specs AUD_ConverterReader::getSpecs()
 {
-       return m_specs;
+       return m_specs.specs;
 }
 
 void AUD_ConverterReader::read(int & length, sample_t* & buffer)
@@ -254,7 +86,8 @@ void AUD_ConverterReader::read(int & length, sample_t* & buffer)
        if(m_buffer->getSize() < length*samplesize)
                m_buffer->resize(length*samplesize);
 
-       m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
+       m_convert((data_t*)m_buffer->getBuffer(), (data_t*)buffer,
+                         length * m_specs.channels);
 
        buffer = m_buffer->getBuffer();
 }
index f855372b6364e4d05cf9ed775ae7f18875f76921..ba49bbfd9ba693ffba10067d23b12039cbf7def8 100644 (file)
@@ -44,7 +44,7 @@ private:
        /**
         * The target specification.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
        /**
         * Converter function.
@@ -58,7 +58,7 @@ public:
         * \param specs The target specification.
         * \exception AUD_Exception Thrown if the reader is NULL.
         */
-       AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
+       AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
        /**
         * Destroys the reader.
         */
diff --git a/intern/audaspace/intern/AUD_FloatMixer.h b/intern/audaspace/intern/AUD_FloatMixer.h
deleted file mode 100644 (file)
index 728a0fa..0000000
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * $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_FLOATMIXER
-#define AUD_FLOATMIXER
-
-#include "AUD_IMixer.h"
-#include "AUD_ConverterFunctions.h"
-class AUD_ConverterFactory;
-class AUD_SRCResampleFactory;
-class AUD_ChannelMapperFactory;
-class AUD_Buffer;
-#include <list>
-
-struct AUD_FloatMixerBuffer
-{
-       sample_t* buffer;
-       int length;
-       float volume;
-};
-
-/**
- * This class is able to mix two audiosignals with floats.
- */
-class AUD_FloatMixer : public AUD_IMixer
-{
-private:
-       /**
-        * The converter factory that converts all readers for superposition.
-        */
-       AUD_ConverterFactory* m_converter;
-
-       /**
-        * The resampling factory that resamples all readers for superposition.
-        */
-       AUD_SRCResampleFactory* m_resampler;
-
-       /**
-        * The channel mapper factory that maps all readers for superposition.
-        */
-       AUD_ChannelMapperFactory* m_mapper;
-
-       /**
-        * The list of buffers to superpose.
-        */
-       std::list<AUD_FloatMixerBuffer> m_buffers;
-
-       /**
-        * The output specification.
-        */
-       AUD_Specs m_specs;
-
-       /**
-        * The temporary mixing buffer.
-        */
-       AUD_Buffer* m_buffer;
-
-       /**
-        * Converter function.
-        */
-       AUD_convert_f m_convert;
-
-public:
-       /**
-        * Creates the mixer.
-        */
-       AUD_FloatMixer();
-
-       virtual ~AUD_FloatMixer();
-
-       virtual AUD_IReader* prepare(AUD_IReader* reader);
-       virtual void setSpecs(AUD_Specs specs);
-       virtual void add(sample_t* buffer, AUD_Specs specs, int length,
-                                        float volume);
-       virtual void superpose(sample_t* buffer, int length, float volume);
-};
-
-#endif //AUD_FLOATMIXER
index af2cae206f381da16f50077df694e2f93b536e23..e924f57cefc27ee1bcc3c1b7160ba434f8538d44 100644 (file)
@@ -53,7 +53,7 @@ public:
        /**
         * Returns the specification of the device.
         */
-       virtual AUD_Specs getSpecs()=0;
+       virtual AUD_DeviceSpecs getSpecs()=0;
 
        /**
         * Plays a sound source.
similarity index 53%
rename from intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
rename to intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index e0b0c7d36033639eb796176efccfdf090aa5936e..e738fc17693bfa4445176f5e846a59c909ea3da9 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_SDLMixerFactory.h"
-#include "AUD_SDLMixerReader.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LinearResampleReader.h"
 
-#include <cstring>
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IReader* reader,
+                                                                                                        AUD_DeviceSpecs specs) :
+               AUD_ResampleFactory(reader, specs) {}
 
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
-               AUD_MixerFactory(reader, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
+                                                                                                        AUD_DeviceSpecs specs) :
+               AUD_ResampleFactory(factory, specs) {}
 
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
-               AUD_MixerFactory(factory, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_DeviceSpecs specs) :
+               AUD_ResampleFactory(specs) {}
 
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
-               AUD_MixerFactory(specs) {}
-
-AUD_IReader* AUD_SDLMixerFactory::createReader()
+AUD_IReader* AUD_LinearResampleFactory::createReader()
 {
        AUD_IReader* reader = getReader();
 
        if(reader != 0)
        {
-               AUD_Specs specs = reader->getSpecs();
-               if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
+               if(reader->getSpecs().rate != m_specs.rate)
                {
-                       try
-                       {
-                               reader = new AUD_SDLMixerReader(reader, m_specs);
-                               AUD_NEW("reader")
-                       }
-                       catch(AUD_Exception e)
-                       {
-                               // return 0 in case SDL cannot mix the source
-                               if(e.error != AUD_ERROR_SDL)
-                                       throw;
-                               else
-                                       reader = NULL;
-                       }
+                       reader = new AUD_LinearResampleReader(reader, m_specs.specs);
+                       AUD_NEW("reader")
                }
        }
        return reader;
similarity index 65%
rename from intern/audaspace/SDL/AUD_SDLMixerFactory.h
rename to intern/audaspace/intern/AUD_LinearResampleFactory.h
index 44b36d06859747cb1c41d1f2679996df3990e7fc..81a9d62381530fa477b846249623bfe2f9d19a40 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_SDLMIXERFACTORY
-#define AUD_SDLMIXERFACTORY
+#ifndef AUD_LINEARRESAMPLEFACTORY
+#define AUD_LINEARRESAMPLEFACTORY
 
-#include "AUD_MixerFactory.h"
+#include "AUD_ResampleFactory.h"
 
 /**
- * This factory creates a resampling reader that uses SDL's resampling
- * functionality which unfortunately is very very very limited.
+ * This factory creates a resampling reader that does simple linear resampling.
  */
-class AUD_SDLMixerFactory : public AUD_MixerFactory
+class AUD_LinearResampleFactory : public AUD_ResampleFactory
 {
 public:
-       AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
-       AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
-       AUD_SDLMixerFactory(AUD_Specs specs);
+       AUD_LinearResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+       AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+       AUD_LinearResampleFactory(AUD_DeviceSpecs specs);
 
        virtual AUD_IReader* createReader();
 };
 
-#endif //AUD_SDLMIXERFACTORY
+#endif //AUD_LINEARRESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
new file mode 100644 (file)
index 0000000..70e29b9
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * $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_LinearResampleReader.h"
+#include "AUD_Buffer.h"
+
+#include <cmath>
+#include <cstring>
+#include <cstdio>
+
+AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
+                                                                                                  AUD_Specs specs) :
+               AUD_EffectReader(reader)
+{
+       m_sspecs = reader->getSpecs();
+
+       m_tspecs = specs;
+       m_tspecs.channels = m_sspecs.channels;
+       m_factor = (float)m_tspecs.rate / (float)m_sspecs.rate;
+
+       m_position = 0;
+       m_sposition = 0;
+
+       m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+       m_cache = new AUD_Buffer(2 * AUD_SAMPLE_SIZE(specs)); AUD_NEW("buffer")
+}
+
+AUD_LinearResampleReader::~AUD_LinearResampleReader()
+{
+       delete m_buffer; AUD_DELETE("buffer")
+       delete m_cache; AUD_DELETE("buffer")
+}
+
+void AUD_LinearResampleReader::seek(int position)
+{
+       m_position = position;
+       m_sposition = floor(position / m_factor);
+       m_reader->seek(m_sposition);
+}
+
+int AUD_LinearResampleReader::getLength()
+{
+       return m_reader->getLength() * m_factor;
+}
+
+int AUD_LinearResampleReader::getPosition()
+{
+       return m_position;
+}
+
+AUD_Specs AUD_LinearResampleReader::getSpecs()
+{
+       return m_tspecs;
+}
+
+void AUD_LinearResampleReader::read(int & length, sample_t* & buffer)
+{
+       int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+
+       if(m_buffer->getSize() < size)
+               m_buffer->resize(size);
+
+       int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
+       int len = need;
+       sample_t* buf;
+       buffer = m_buffer->getBuffer();
+
+       m_reader->read(len, buf);
+
+       if(len < need)
+               length = floor((m_sposition + len - 1) * m_factor) - m_position;
+
+       float spos;
+       sample_t low, high;
+       int channels = m_sspecs.channels;
+
+       for(int channel = 0; channel < channels; channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       spos = (m_position + i) / m_factor - m_sposition;
+
+                       if((floor(spos) < -2) || (ceil(spos) >= len))
+                       {
+                               fprintf(stderr, "FATAL ERROR: REPORT THIS TO neXyon!\n");
+//                             exit(1);
+                       }
+
+                       if(floor(spos) < 0)
+                       {
+                               low = m_cache->getBuffer()[(int)(floor(spos) + 2) * channels
+                                                                                  + channel];
+                               if(ceil(spos) < 0)
+                                       high = m_cache->getBuffer()[(int)(ceil(spos) + 2)
+                                                                                               * channels + channel];
+                               else
+                                       high = buf[(int)ceil(spos) * channels + channel];
+                       }
+                       else
+                       {
+                                       low = buf[(int)floor(spos) * channels + channel];
+                                       high = buf[(int)ceil(spos) * channels + channel];
+                       }
+                       buffer[i * channels + channel] = low + (spos - floor(spos)) *
+                                                                                                  (high - low);
+               }
+       }
+
+       if(len > 1)
+               memcpy(m_cache->getBuffer(), buf + (len - 2) * channels, 2 * channels);
+       else if(len == 1)
+               memcpy(m_cache->getBuffer() + 1 * channels, buf, channels);
+
+       m_sposition += len;
+       m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
new file mode 100644 (file)
index 0000000..c86b8b7
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+ * $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_LINEARRESAMPLEREADER
+#define AUD_LINEARRESAMPLEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This resampling reader uses libsamplerate for resampling.
+ */
+class AUD_LinearResampleReader : public AUD_EffectReader
+{
+private:
+       /**
+        * The resampling factor.
+        */
+       float m_factor;
+
+       /**
+        * The current position.
+        */
+       int m_position;
+
+       /**
+        * The current reading source position.
+        */
+       int m_sposition;
+
+       /**
+        * The sound output buffer.
+        */
+       AUD_Buffer *m_buffer;
+
+       /**
+        * The input caching buffer.
+        */
+       AUD_Buffer *m_cache;
+
+       /**
+        * The target specification.
+        */
+       AUD_Specs m_tspecs;
+
+       /**
+        * The sample specification of the source.
+        */
+       AUD_Specs m_sspecs;
+
+public:
+       /**
+        * Creates a resampling reader.
+        * \param reader The reader to mix.
+        * \param specs The target specification.
+        * \exception AUD_Exception Thrown if the reader is NULL.
+        */
+       AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
+
+       /**
+        * Destroys the reader.
+        */
+       ~AUD_LinearResampleReader();
+
+       virtual void seek(int position);
+       virtual int getLength();
+       virtual int getPosition();
+       virtual AUD_Specs getSpecs();
+       virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LINEARRESAMPLEREADER
similarity index 75%
rename from intern/audaspace/intern/AUD_FloatMixer.cpp
rename to intern/audaspace/intern/AUD_Mixer.cpp
index f7133b9c30ef470a044ab05fe81ea2ed10d26f20..bddc719b17959ada7452b32f5af246546e50ded9 100644 (file)
@@ -23,8 +23,7 @@
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_FloatMixer.h"
-#include "AUD_ConverterFactory.h"
+#include "AUD_Mixer.h"
 #include "AUD_SRCResampleFactory.h"
 #include "AUD_ChannelMapperFactory.h"
 #include "AUD_IReader.h"
 
 #include <cstring>
 
-AUD_FloatMixer::AUD_FloatMixer()
+AUD_Mixer::AUD_Mixer()
 {
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 
-       m_converter = NULL;
        m_resampler = NULL;
        m_mapper = NULL;
 }
 
-AUD_FloatMixer::~AUD_FloatMixer()
+AUD_Mixer::~AUD_Mixer()
 {
        delete m_buffer; AUD_DELETE("buffer")
 
-       if(m_converter)
-       {
-               delete m_converter; AUD_DELETE("factory")
-       }
+
        if(m_resampler)
        {
                delete m_resampler; AUD_DELETE("factory")
@@ -59,11 +54,8 @@ AUD_FloatMixer::~AUD_FloatMixer()
        }
 }
 
-AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
+AUD_IReader* AUD_Mixer::prepare(AUD_IReader* reader)
 {
-       m_converter->setReader(reader);
-       reader = m_converter->createReader();
-
        m_resampler->setReader(reader);
        reader = m_resampler->createReader();
 
@@ -76,14 +68,10 @@ AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
        return reader;
 }
 
-void AUD_FloatMixer::setSpecs(AUD_Specs specs)
+void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
 {
        m_specs = specs;
 
-       if(m_converter)
-       {
-               delete m_converter; AUD_DELETE("factory")
-       }
        if(m_resampler)
        {
                delete m_resampler; AUD_DELETE("factory")
@@ -93,9 +81,6 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
                delete m_mapper; AUD_DELETE("factory")
        }
 
-       specs.format = AUD_FORMAT_FLOAT32;
-
-       m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
        m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
        m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
 
@@ -130,27 +115,26 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
        }
 }
 
-void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
-                                                float volume)
+void AUD_Mixer::add(sample_t* buffer, int length, float volume)
 {
-       AUD_FloatMixerBuffer buf;
+       AUD_MixerBuffer buf;
        buf.buffer = buffer;
        buf.length = length;
        buf.volume = volume;
        m_buffers.push_back(buf);
 }
 
-void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
+void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
 {
-       AUD_FloatMixerBuffer buf;
+       AUD_MixerBuffer buf;
 
        int channels = m_specs.channels;
 
        if(m_buffer->getSize() < length * channels * 4)
                m_buffer->resize(length * channels * 4);
 
-       float* out = (float*)m_buffer->getBuffer();
-       float* in;
+       sample_t* out = m_buffer->getBuffer();
+       sample_t* in;
 
        memset(out, 0, length * channels * 4);
 
@@ -162,11 +146,11 @@ void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
                m_buffers.pop_front();
 
                end = buf.length*channels;
-               in = (float*) buf.buffer;
+               in = buf.buffer;
 
                for(int i = 0; i < end; i++)
                        out[i] += in[i]*buf.volume * volume;
        }
 
-       m_convert(buffer, (sample_t*) out, length * channels);
+       m_convert(buffer, (data_t*) out, length * channels);
 }
similarity index 56%
rename from intern/audaspace/intern/AUD_IMixer.h
rename to intern/audaspace/intern/AUD_Mixer.h
index c65e4c69cf73706c3c72c5ea700bb51bfed21c59..5097b9ec2a6e3a7b57a97627339d2b9fbb66d219 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_IMIXER
-#define AUD_IMIXER
+#ifndef AUD_MIXER
+#define AUD_MIXER
 
-#include "AUD_Space.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_ConverterFactory;
+class AUD_SRCResampleFactory;
+class AUD_ChannelMapperFactory;
+class AUD_Buffer;
 class AUD_IReader;
+#include <list>
+
+struct AUD_MixerBuffer
+{
+       sample_t* buffer;
+       int length;
+       float volume;
+};
 
 /**
- * This class is able to mix audiosignals of different format and channel count.
- * \note This class doesn't do resampling!
+ * This class is able to mix audiosignals of different channel count and sample
+ * rate and convert it to a specific output format.
+ * It uses a default ChannelMapperFactory and a SRCResampleFactory for
+ * the perparation.
  */
-class AUD_IMixer
+class AUD_Mixer
 {
+private:
+       /**
+        * The resampling factory that resamples all readers for superposition.
+        */
+       AUD_SRCResampleFactory* m_resampler;
+
+       /**
+        * The channel mapper factory that maps all readers for superposition.
+        */
+       AUD_ChannelMapperFactory* m_mapper;
+
+       /**
+        * The list of buffers to superpose.
+        */
+       std::list<AUD_MixerBuffer> m_buffers;
+
+       /**
+        * The output specification.
+        */
+       AUD_DeviceSpecs m_specs;
+
+       /**
+        * The temporary mixing buffer.
+        */
+       AUD_Buffer* m_buffer;
+
+       /**
+        * Converter function.
+        */
+       AUD_convert_f m_convert;
+
 public:
+       /**
+        * Creates the mixer.
+        */
+       AUD_Mixer();
+
        /**
         * Destroys the mixer.
         */
-       virtual ~AUD_IMixer(){}
+       ~AUD_Mixer();
 
        /**
         * This funuction prepares a reader for playback.
         * \param reader The reader to prepare.
         * \return The reader that should be used for playback.
         */
-       virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+       AUD_IReader* prepare(AUD_IReader* reader);
 
        /**
         * Sets the target specification for superposing.
         * \param specs The target specification.
         */
-       virtual void setSpecs(AUD_Specs specs)=0;
+       void setSpecs(AUD_DeviceSpecs specs);
 
        /**
         * Adds a buffer for superposition.
         * \param buffer The buffer to superpose.
-        * \param specs The specification of the buffer.
         * \param start The start sample of the buffer.
         * \param length The length of the buffer in samples.
         * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
         */
-       virtual void add(sample_t* buffer, AUD_Specs specs, int length,
-                                        float volume)=0;
+       void add(sample_t* buffer, int length, float volume);
 
        /**
         * Superposes all added buffers into an output buffer.
@@ -71,7 +119,7 @@ public:
         * \param length The length of the buffer in samples.
         * \param volume The mixing volume. Must be a value between 0.0 and 1.0.
         */
-       virtual void superpose(sample_t* buffer, int length, float volume)=0;
+       void superpose(data_t* buffer, int length, float volume);
 };
 
-#endif //AUD_IMIXER
+#endif //AUD_MIXER
index db38d1004db040d1f370ce5a6c0bb76b725f72b0..e78818301fa3f4dd3e46019a1a1aa24fd39b536e 100644 (file)
@@ -49,7 +49,7 @@ AUD_IReader* AUD_MixerFactory::getReader()
 }
 
 AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
-                                                                                          AUD_Specs specs)
+                                                                  AUD_DeviceSpecs specs)
 {
        m_specs = specs;
        m_reader = reader;
@@ -57,14 +57,14 @@ AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
 }
 
 AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
-                                                                                          AUD_Specs specs)
+                                                                  AUD_DeviceSpecs specs)
 {
        m_specs = specs;
        m_reader = 0;
        m_factory = factory;
 }
 
-AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
+AUD_MixerFactory::AUD_MixerFactory(AUD_DeviceSpecs specs)
 {
        m_specs = specs;
        m_reader = 0;
@@ -79,12 +79,12 @@ AUD_MixerFactory::~AUD_MixerFactory()
        }
 }
 
-AUD_Specs AUD_MixerFactory::getSpecs()
+AUD_DeviceSpecs AUD_MixerFactory::getSpecs()
 {
        return m_specs;
 }
 
-void AUD_MixerFactory::setSpecs(AUD_Specs specs)
+void AUD_MixerFactory::setSpecs(AUD_DeviceSpecs specs)
 {
        m_specs = specs;
 }
index c61dd283c674f8c0013d7569c9175397ddfc8005..a2f4aa78d76720b6e685505b0881a35ea84f7b35 100644 (file)
@@ -47,7 +47,7 @@ protected:
        /**
         * The target specification for resampling.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
        /**
         * Returns the reader created out of the factory or taken from m_reader.
@@ -63,20 +63,20 @@ public:
         * \param reader The reader to mix.
         * \param specs The target specification.
         */
-       AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
+       AUD_MixerFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
 
        /**
         * Creates a new factory.
         * \param factory The factory to create the readers to mix out of.
         * \param specs The target specification.
         */
-       AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
+       AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
 
        /**
         * Creates a new factory.
         * \param specs The target specification.
         */
-       AUD_MixerFactory(AUD_Specs specs);
+       AUD_MixerFactory(AUD_DeviceSpecs specs);
 
        /**
         * Destroys the resampling factory.
@@ -86,13 +86,13 @@ public:
        /**
         * Returns the target specification for resampling.
         */
-       AUD_Specs getSpecs();
+       AUD_DeviceSpecs getSpecs();
 
        /**
         * Sets the target specification for resampling.
         * \param specs The specification.
         */
-       void setSpecs(AUD_Specs specs);
+       void setSpecs(AUD_DeviceSpecs specs);
 
        /**
         * Sets the reader for resampling.
index d237b71b67e4e1e3b7839d0469713fa791c01b2c..3936695c28fc06c974ae8ab13d74e402a75e8f09 100644 (file)
@@ -34,7 +34,7 @@ AUD_NULLDevice::AUD_NULLDevice()
        m_specs.rate = AUD_RATE_INVALID;
 }
 
-AUD_Specs AUD_NULLDevice::getSpecs()
+AUD_DeviceSpecs AUD_NULLDevice::getSpecs()
 {
        return m_specs;
 }
index 155f24f8837229e8a689e03d914009fed7cfe47c..91ddd23cf7121fed753c05b9977b4f4e9871b451 100644 (file)
@@ -37,7 +37,7 @@ private:
        /**
         * The specs of the device.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
 public:
        /**
@@ -45,7 +45,7 @@ public:
         */
        AUD_NULLDevice();
 
-       virtual AUD_Specs getSpecs();
+       virtual AUD_DeviceSpecs getSpecs();
        virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
        virtual bool pause(AUD_Handle* handle);
        virtual bool resume(AUD_Handle* handle);
index e2c1d2fac81f663b44daa51fde32f66ce1f08ba1..37a7d1ae295801c792ade37fff27c60e8844d960 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
 #include "AUD_ReadDevice.h"
 #include "AUD_IReader.h"
 
 #include <cstring>
 
-AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
+AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs)
 {
        m_specs = specs;
 
-       m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
+       m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
        m_mixer->setSpecs(m_specs);
 
        m_playing = false;
@@ -46,15 +46,15 @@ AUD_ReadDevice::~AUD_ReadDevice()
        destroy();
 }
 
-bool AUD_ReadDevice::read(sample_t* buffer, int length)
+bool AUD_ReadDevice::read(data_t* buffer, int length)
 {
        if(m_playing)
                mix(buffer, length);
        else
                if(m_specs.format == AUD_FORMAT_U8)
-                       memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
+                       memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
                else
-                       memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
+                       memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
        return m_playing;
 }
 
index d69b0c31ea550f1e39f42ae7d2f34d9d7e6d0007..3fd90df77556f136de531bf868453ffda01a6dd7 100644 (file)
@@ -47,7 +47,7 @@ public:
         * Creates a new read device.
         * \param specs The wanted audio specification.
         */
-       AUD_ReadDevice(AUD_Specs specs);
+       AUD_ReadDevice(AUD_DeviceSpecs specs);
 
        /**
         * Closes the device.
@@ -62,7 +62,7 @@ public:
         *         played back currently, in that case the buffer is filled with
         *         silence.
         */
-       bool read(sample_t* buffer, int length);
+       bool read(data_t* buffer, int length);
 };
 
 #endif //AUD_READDEVICE
index 87e2f789d66dddc27588bdcb6487a248b963e49c..83a1a3ed3c38da3e2bb9daea913c1f6cd453b9bb 100644 (file)
@@ -26,7 +26,7 @@
 #include "AUD_SinusReader.h"
 #include "AUD_Buffer.h"
 
-#include <math.h>
+#include <cmath>
 
 #ifndef M_PI
 #define M_PI 3.14159265358979323846
@@ -69,8 +69,7 @@ AUD_Specs AUD_SinusReader::getSpecs()
 {
        AUD_Specs specs;
        specs.rate = m_sampleRate;
-       specs.format = AUD_FORMAT_S16;
-       specs.channels = AUD_CHANNELS_STEREO;
+       specs.channels = AUD_CHANNELS_MONO;
        return specs;
 }
 
@@ -87,18 +86,16 @@ bool AUD_SinusReader::notify(AUD_Message &message)
 void AUD_SinusReader::read(int & length, sample_t* & buffer)
 {
        // resize if necessary
-       if(m_buffer->getSize() < length*4)
-               m_buffer->resize(length*4);
+       if(m_buffer->getSize() < length * sizeof(sample_t))
+               m_buffer->resize(length * sizeof(sample_t));
 
        // fill with sine data
-       short* buf = (short*) m_buffer->getBuffer();
-       for(int i=0; i < length; i++)
+       buffer = m_buffer->getBuffer();
+       for(int i = 0; i < length; i++)
        {
-               buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
-                                          (float)m_sampleRate) * 32700;
-               buf[i*2+1] = buf[i*2];
+               buffer[i] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
+                                               (float)m_sampleRate);
        }
 
-       buffer = (sample_t*)buf;
        m_position += length;
 }
index 42a90a6f15e391bf35159afe6def79ddf0950a37..142251c7e2d066eae77f52d066a5d8c62ada7e1d 100644 (file)
@@ -25,7 +25,7 @@
 
 #include "AUD_SoftwareDevice.h"
 #include "AUD_IReader.h"
-#include "AUD_IMixer.h"
+#include "AUD_Mixer.h"
 #include "AUD_IFactory.h"
 #include "AUD_SourceCaps.h"
 
@@ -52,6 +52,8 @@ void AUD_SoftwareDevice::create()
        m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
        m_playback = false;
        m_volume = 1.0;
+       m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
+       m_mixer->setSpecs(m_specs);
 
        pthread_mutexattr_t attr;
        pthread_mutexattr_init(&attr);
@@ -90,7 +92,7 @@ void AUD_SoftwareDevice::destroy()
        pthread_mutex_destroy(&m_mutex);
 }
 
-void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
+void AUD_SoftwareDevice::mix(data_t* buffer, int length)
 {
        lock();
 
@@ -98,7 +100,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
                AUD_SoftwareHandle* sound;
                int len;
                sample_t* buf;
-               int sample_size = AUD_SAMPLE_SIZE(m_specs);
+               int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
                std::list<AUD_SoftwareHandle*> stopSounds;
 
                // for all sounds
@@ -114,7 +116,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
                        len = length;
                        sound->reader->read(len, buf);
 
-                       m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
+                       m_mixer->add(buf, len, sound->volume);
 
                        // in case the end of the sound is reached
                        if(len < length)
@@ -159,14 +161,7 @@ bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
        return false;
 }
 
-void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
-{
-       delete m_mixer; AUD_DELETE("mixer")
-       m_mixer = mixer;
-       mixer->setSpecs(m_specs);
-}
-
-AUD_Specs AUD_SoftwareDevice::getSpecs()
+AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs()
 {
        return m_specs;
 }
index 3768786fa9c3c9df3d9a7ccb2ab23ac7472dd039..a12fddb1e00c0ee1f976907720eb7676193bc65b 100644 (file)
@@ -28,7 +28,7 @@
 
 #include "AUD_IDevice.h"
 struct AUD_SoftwareHandle;
-class AUD_IMixer;
+class AUD_Mixer;
 
 #include <list>
 #include <pthread.h>
@@ -47,12 +47,12 @@ protected:
        /**
         * The specification of the device.
         */
-       AUD_Specs m_specs;
+       AUD_DeviceSpecs m_specs;
 
        /**
-        * The mixer. Will be deleted by the destroy function.
+        * The mixer.
         */
-       AUD_IMixer* m_mixer;
+       AUD_Mixer* m_mixer;
 
        /**
         * Initializes member variables.
@@ -69,7 +69,7 @@ protected:
         * \param buffer The target buffer.
         * \param length The length in samples to be filled.
         */
-       void mix(sample_t* buffer, int length);
+       void mix(data_t* buffer, int length);
 
        /**
         * This function tells the device, to start or pause playback.
@@ -111,13 +111,7 @@ private:
        bool isValid(AUD_Handle* handle);
 
 public:
-       /**
-        * Sets a new mixer.
-        * \param mixer The new mixer.
-        */
-       void setMixer(AUD_IMixer* mixer);
-
-       virtual AUD_Specs getSpecs();
+       virtual AUD_DeviceSpecs getSpecs();
        virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
        virtual bool pause(AUD_Handle* handle);
        virtual bool resume(AUD_Handle* handle);
index 123d9c272a085f2876e04ecb105883d9bbde2fce..1d60be3979b0043012dc315a3fbab54d39e77401 100644 (file)
 
 /// The size of a format in bytes.
 #define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified device format in bytes.
+#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
 /// The size of a sample in the specified format in bytes.
-#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
 /// Throws a AUD_Exception with the provided error code.
 #define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
 
@@ -233,22 +235,42 @@ typedef enum
        AUD_3DSS_CONE_OUTER_GAIN                /// Cone outer gain.
 } AUD_3DSourceSetting;
 
-/// Sample pointer type.
-typedef unsigned char sample_t;
+/// Sample type.(float samples)
+typedef float sample_t;
 
-/// Specification of a sound source or device.
+/// Sample data type (format samples)
+typedef unsigned char data_t;
+
+/// Specification of a sound source.
 typedef struct
 {
        /// Sample rate in Hz.
        AUD_SampleRate rate;
 
-       /// Sample format.
-       AUD_SampleFormat format;
-
        /// Channel count.
        AUD_Channels channels;
 } AUD_Specs;
 
+/// Specification of a sound device.
+typedef struct
+{
+       /// Sample format.
+       AUD_SampleFormat format;
+
+       union
+       {
+               struct
+               {
+                       /// Sample rate in Hz.
+                       AUD_SampleRate rate;
+
+                       /// Channel count.
+                       AUD_Channels channels;
+               };
+               AUD_Specs specs;
+       };
+} AUD_DeviceSpecs;
+
 /// Exception structure.
 typedef struct
 {
index 11391fa4a08fd2ed6bd77508c9e0401c4ee4f5bd..4d2cd9e2505fa89ec1594c4c4e66e70160059ab0 100644 (file)
@@ -61,9 +61,9 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
                // read more
                length = size-index;
                reader->read(length, buffer);
-               memcpy(m_buffer.get()->getBuffer()+index*sample_size,
+               memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
                           buffer,
-                          length*sample_size);
+                          length * sample_size);
                size += AUD_BUFFER_RESIZE_BYTES / sample_size;
                index += length;
        }
index 4d8ab93d6723db2472cfe283da40b80f4fa0ca7d..acd37de870ce68154361f048960a4764e973800e 100644 (file)
@@ -23,7 +23,7 @@
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
 #include "AUD_JackDevice.h"
 #include "AUD_IReader.h"
 #include "AUD_Buffer.h"
@@ -38,7 +38,7 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
        unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
        if(device->m_buffer->getSize() < samplesize * length)
                device->m_buffer->resize(samplesize * length);
-       device->mix(device->m_buffer->getBuffer(), length);
+       device->mix((data_t*)device->m_buffer->getBuffer(), length);
 
        float* in = (float*) device->m_buffer->getBuffer();
        float* out;
@@ -60,7 +60,7 @@ void AUD_JackDevice::jack_shutdown(void *data)
        device->m_valid = false;
 }
 
-AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
+AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs)
 {
        if(specs.channels == AUD_CHANNELS_INVALID)
                specs.channels = AUD_CHANNELS_STEREO;
@@ -123,9 +123,6 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
                free(ports);
        }
 
-       m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
-       m_mixer->setSpecs(m_specs);
-
        m_valid = true;
 
        create();
index f0c887a2f43f96639e76948d91aab2b112f4f53c..5a073a6943282ff0fb04024f92a81cb6d647e3ef 100644 (file)
@@ -81,7 +81,7 @@ public:
         * \param specs The wanted audio specification, where only the channel count is important.
         * \exception AUD_Exception Thrown if the audio device cannot be opened.
         */
-       AUD_JackDevice(AUD_Specs specs);
+       AUD_JackDevice(AUD_DeviceSpecs specs);
 
        /**
         * Closes the Jack client.
index 485818552bb061e3dc349f4f58d0df912f919f74..f9ed8d6388e9d4932c308eada858ffacd55c7caf 100644 (file)
 
 #include <cstring>
 
-// This function transforms a  SampleFormat to our own sample format
-static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
-{
-       switch(fmt & SF_FORMAT_SUBMASK)
-       {
-       // only read s16, s32 and double as they are
-       case SF_FORMAT_PCM_16:
-               return AUD_FORMAT_S16;
-       case SF_FORMAT_PCM_32:
-               return AUD_FORMAT_S32;
-       case SF_FORMAT_DOUBLE:
-               return AUD_FORMAT_FLOAT64;
-       // read all other formats as floats
-       default:
-               return AUD_FORMAT_FLOAT32;
-       }
-}
-
 sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
 {
        AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
        return reader->m_membuffer.get()->getSize();
 }
 
-sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user_data)
+sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
+                                                                          void *user_data)
 {
        AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
 
@@ -72,14 +55,16 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user
        return reader->m_memoffset;
 }
 
-sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, void *user_data)
+sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
+                                                                          void *user_data)
 {
        AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
 
        if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
                count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
 
-       memcpy(ptr, reader->m_membuffer.get()->getBuffer() + reader->m_memoffset, count);
+       memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
+                  reader->m_memoffset, count);
        reader->m_memoffset += count;
 
        return count;
@@ -103,27 +88,11 @@ AUD_SndFileReader::AUD_SndFileReader(const char* filename)
                AUD_THROW(AUD_ERROR_FILE);
 
        m_specs.channels = (AUD_Channels) sfinfo.channels;
-       m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
        m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
        m_length = sfinfo.frames;
        m_seekable = sfinfo.seekable;
        m_position = 0;
 
-       switch(m_specs.format)
-       {
-       case AUD_FORMAT_S16:
-               m_read = (sf_read_f) sf_readf_short;
-               break;
-       case AUD_FORMAT_S32:
-               m_read = (sf_read_f) sf_readf_int;
-               break;
-       case AUD_FORMAT_FLOAT64:
-               m_read = (sf_read_f) sf_readf_double;
-               break;
-       default:
-               m_read = (sf_read_f) sf_readf_float;
-       }
-
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
@@ -147,27 +116,11 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
                AUD_THROW(AUD_ERROR_FILE);
 
        m_specs.channels = (AUD_Channels) sfinfo.channels;
-       m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
        m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
        m_length = sfinfo.frames;
        m_seekable = sfinfo.seekable;
        m_position = 0;
 
-       switch(m_specs.format)
-       {
-       case AUD_FORMAT_S16:
-               m_read = (sf_read_f) sf_readf_short;
-               break;
-       case AUD_FORMAT_S32:
-               m_read = (sf_read_f) sf_readf_int;
-               break;
-       case AUD_FORMAT_FLOAT64:
-               m_read = (sf_read_f) sf_readf_double;
-               break;
-       default:
-               m_read = (sf_read_f) sf_readf_float;
-       }
-
        m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
 }
 
@@ -227,7 +180,7 @@ void AUD_SndFileReader::read(int & length, sample_t* & buffer)
 
        buffer = m_buffer->getBuffer();
 
-       length = m_read(m_sndfile, buffer, length);
+       length = sf_readf_float(m_sndfile, buffer, length);
 
        m_position += length;
 }
index da890ef53ca47cd62e26fb6fd261f2f3389326bd..8886b6e9efc550fa7345cd50e979145e34ce7351 100644 (file)
@@ -70,11 +70,6 @@ private:
         */
        SNDFILE* m_sndfile;
 
-       /**
-        * The reading function.
-        */
-       sf_read_f m_read;
-
        /**
         * The virtual IO structure for memory file reading.
         */
index 64ce1983e7d1f1ab43c4e8a247a983b3813ffe40..8722485b97deee0867ca449daaafda652d2c7d82 100644 (file)
@@ -73,7 +73,7 @@ void sound_update_playing(struct bContext *C);
 void sound_scrub(struct bContext *C);
 
 #ifdef AUD_CAPI
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume);
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume);
 #endif
 
 void sound_stop_all(struct bContext *C);
index aa81cea79f5ada4ddeb2b564fa9800a02d4a60af..767834159b24efd51d0ddfb9a20a0c48724d4218 100644 (file)
@@ -3792,7 +3792,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
 
        info = AUD_getInfo(sound->handle);
 
-       if (info.specs.format == AUD_FORMAT_INVALID) {
+       if (info.specs.channels == AUD_CHANNELS_INVALID) {
                sound_delete(C, sound);
                //if(op)
                //      BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
index 74c6afdc018bee4a8dc206ea4a7bea57f6beabbd..3232e2677b53ea255afa38a2ba0a868e40be2ac8 100644 (file)
@@ -40,7 +40,7 @@ void sound_disable()
 
 void sound_init()
 {
-       AUD_Specs specs;
+       AUD_DeviceSpecs specs;
        int device, buffersize;
 
        device = U.audiodevice;
@@ -455,7 +455,7 @@ void sound_scrub(struct bContext *C)
        }
 }
 
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume)
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume)
 {
        AUD_Device* mixdown = AUD_openReadDevice(specs);
        SoundHandle *handle;
index 417679417e4a5799aaac48bb95b2c0e1ff056a85..5b58f0bfedcc68d13de8319cf7891176ddc85bbe 100644 (file)
@@ -832,7 +832,7 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
        if(ffmpeg_multiplex_audio && audio_stream)
        {
                AVCodecContext* c = get_codec_from_stream(audio_stream);
-               AUD_Specs specs;
+               AUD_DeviceSpecs specs;
                specs.channels = c->channels;
                specs.format = AUD_FORMAT_S16;
                specs.rate = rd->ffcodecdata.audio_mixrate;
index 3b42fc7b382075a260b0c5dc5c0ad816675e9344..d48a322f56291c6b5d40a606d04dc03ccf8c461f 100644 (file)
@@ -81,7 +81,7 @@ static int open_exec(bContext *C, wmOperator *op)
 
        info = AUD_getInfo(sound->handle);
 
-       if (info.specs.format == AUD_FORMAT_INVALID) {
+       if (info.specs.channels == AUD_CHANNELS_INVALID) {
                sound_delete(C, sound);
                BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
                return OPERATOR_CANCELLED;
index 8ac3f2efefb1fd8b2f1ad7f65428d05ed64f10c9..607425665af2f69d29b3b2e2069375e2c11c019d 100644 (file)
@@ -36,6 +36,8 @@
 #include <config.h>
 #endif
 
+#include "AUD_C-API.h"
+
 #include "MEM_guardedalloc.h"
 
 #include "BLI_blenlib.h"
@@ -990,6 +992,139 @@ void GRAPH_OT_bake (wmOperatorType *ot)
        // todo: add props for start/end frames
 }
 
+/* ******************** Sound Bake F-Curve Operator *********************** */
+/* This operator bakes the given sound to the selected F-Curves */
+
+/* ------------------- */
+
+/* Custom data storage passed to the F-Sample-ing function,
+ * which provides the necessary info for baking the sound
+ */
+typedef struct tSoundBakeInfo {
+       float* samples;
+       int length;
+       int cfra;
+} tSoundBakeInfo;
+
+/* ------------------- */
+
+/* Sampling callback used to determine the value from the sound to
+ * save in the F-Curve at the specified frame
+ */
+static float fcurve_samplingcb_sound (FCurve *fcu, void *data, float evaltime)
+{
+       tSoundBakeInfo *sbi= (tSoundBakeInfo *)data;
+
+       int position = evaltime - sbi->cfra;
+       if((position < 0) || (position >= sbi->length))
+               return 0.0f;
+
+       return sbi->samples[position];
+}
+
+/* ------------------- */
+
+static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
+{
+       bAnimContext ac;
+       ListBase anim_data = {NULL, NULL};
+       bAnimListElem *ale;
+       int filter;
+
+       tSoundBakeInfo sbi;
+       Scene *scene= NULL;
+       int start, end;
+
+       char path[FILE_MAX];
+
+       /* get editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+
+       RNA_string_get(op->ptr, "path", path);
+
+       scene= ac.scene;        /* current scene */
+
+       /* store necessary data for the baking steps */
+       sbi.samples = AUD_readSoundBuffer(path,
+                                                                         RNA_float_get(op->ptr, "low"),
+                                                                         RNA_float_get(op->ptr, "high"),
+                                                                         RNA_float_get(op->ptr, "attack"),
+                                                                         RNA_float_get(op->ptr, "release"),
+                                                                         RNA_float_get(op->ptr, "threshold"),
+                                                                         FPS, &sbi.length);
+
+       if (sbi.samples == NULL) {
+               BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+               return OPERATOR_CANCELLED;
+       }
+
+       /* determine extents of the baking */
+       sbi.cfra = start = CFRA;
+       end = CFRA + sbi.length - 1;
+
+       /* filter anim channels */
+       filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+       ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+       /* loop through all selected F-Curves, replacing its data with the sound samples */
+       for (ale= anim_data.first; ale; ale= ale->next) {
+               FCurve *fcu= (FCurve *)ale->key_data;
+
+               /* sample the sound */
+               fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
+       }
+
+       /* free sample data */
+       free(sbi.samples);
+
+       /* admin and redraws */
+       BLI_freelistN(&anim_data);
+
+       /* validate keyframes after editing */
+       ANIM_editkeyframes_refresh(&ac);
+
+       /* set notifier that 'keyframes' have changed */
+       WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+       return OPERATOR_FINISHED;
+}
+
+static int graphkeys_sound_bake_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+       bAnimContext ac;
+
+       /* verify editor data */
+       if (ANIM_animdata_get_context(C, &ac) == 0)
+               return OPERATOR_CANCELLED;
+
+       return WM_operator_filesel(C, op, event);
+}
+
+void GRAPH_OT_sound_bake (wmOperatorType *ot)
+{
+       /* identifiers */
+       ot->name= "Bake Sound to F-Curves";
+       ot->idname= "GRAPH_OT_sound_bake";
+       ot->description= "Bakes a sound wave to selected F-Curves.";
+
+       /* api callbacks */
+       ot->invoke= graphkeys_sound_bake_invoke;
+       ot->exec= graphkeys_sound_bake_exec;
+       ot->poll= graphop_selected_fcurve_poll;
+
+       /* flags */
+       ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+       /* properties */
+       WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL);
+       RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency", "", 0.1, 1000.00);
+       RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency", "", 0.1, 1000.00);
+       RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time", "", 0.01, 0.1);
+       RNA_def_float(ot->srna, "release", 0.2, 0.0, 5.0, "Release time", "", 0.01, 0.2);
+       RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 0.1);
+}
+
 /* ******************** Sample Keyframes Operator *********************** */
 /* This operator 'bakes' the values of the curve into new keyframes between pairs
  * of selected keyframes. It is useful for creating keyframes for tweaking overlap.
index 87e03247353fe28745db1b1841825f8aea6df3db..ec6f38c93b709e4f4145aaf00a4345a806d57bb1 100644 (file)
@@ -100,6 +100,7 @@ void GRAPH_OT_delete(struct wmOperatorType *ot);
 void GRAPH_OT_clean(struct wmOperatorType *ot);
 void GRAPH_OT_sample(struct wmOperatorType *ot);
 void GRAPH_OT_bake(struct wmOperatorType *ot);
+void GRAPH_OT_sound_bake(struct wmOperatorType *ot);
 void GRAPH_OT_smooth(struct wmOperatorType *ot);
 
 void GRAPH_OT_handle_type(struct wmOperatorType *ot);
index 295ee86997942535bfb839bb3f4036bb4fa8f65c..7be2d7b3e4b661a36832a818abecd727acdcfa73 100644 (file)
@@ -247,6 +247,7 @@ void graphedit_operatortypes(void)
        WM_operatortype_append(GRAPH_OT_extrapolation_type);
        WM_operatortype_append(GRAPH_OT_sample);
        WM_operatortype_append(GRAPH_OT_bake);
+       WM_operatortype_append(GRAPH_OT_sound_bake);
        WM_operatortype_append(GRAPH_OT_smooth);
        WM_operatortype_append(GRAPH_OT_clean);
        WM_operatortype_append(GRAPH_OT_delete);