Audaspace:
authorJoerg Mueller <nexyon@gmail.com>
Sun, 1 Aug 2010 22:33:50 +0000 (22:33 +0000)
committerJoerg Mueller <nexyon@gmail.com>
Sun, 1 Aug 2010 22:33:50 +0000 (22:33 +0000)
* Created awesome filter classes :)
* Made all filter effects use the filter classes instead of having the same implementation everywhere.
* Added a Python API for LTI IIR filters.
* Fixed a warning in creator.c that was introduced when adding game autoplay.

32 files changed:
intern/audaspace/FX/AUD_AccumulatorFactory.cpp
intern/audaspace/FX/AUD_AccumulatorReader.cpp [deleted file]
intern/audaspace/FX/AUD_AccumulatorReader.h [deleted file]
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp [new file with mode: 0644]
intern/audaspace/FX/AUD_BaseIIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_ButterworthFactory.cpp
intern/audaspace/FX/AUD_ButterworthReader.cpp [deleted file]
intern/audaspace/FX/AUD_ButterworthReader.h [deleted file]
intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp [moved from intern/audaspace/FX/AUD_VolumeReader.cpp with 61% similarity]
intern/audaspace/FX/AUD_CallbackIIRFilterReader.h [new file with mode: 0644]
intern/audaspace/FX/AUD_EnvelopeFactory.cpp
intern/audaspace/FX/AUD_EnvelopeReader.cpp [deleted file]
intern/audaspace/FX/AUD_EnvelopeReader.h [deleted file]
intern/audaspace/FX/AUD_HighpassFactory.cpp
intern/audaspace/FX/AUD_HighpassReader.cpp [deleted file]
intern/audaspace/FX/AUD_HighpassReader.h [deleted file]
intern/audaspace/FX/AUD_IIRFilterFactory.cpp [moved from intern/audaspace/FX/AUD_RectifyReader.cpp with 62% similarity]
intern/audaspace/FX/AUD_IIRFilterFactory.h [moved from intern/audaspace/FX/AUD_VolumeReader.h with 55% similarity]
intern/audaspace/FX/AUD_IIRFilterReader.cpp [moved from intern/audaspace/FX/AUD_RectifyReader.h with 56% similarity]
intern/audaspace/FX/AUD_IIRFilterReader.h [moved from intern/audaspace/FX/AUD_SumReader.h with 56% similarity]
intern/audaspace/FX/AUD_LowpassFactory.cpp
intern/audaspace/FX/AUD_LowpassReader.cpp [deleted file]
intern/audaspace/FX/AUD_LowpassReader.h [deleted file]
intern/audaspace/FX/AUD_RectifyFactory.cpp
intern/audaspace/FX/AUD_SquareFactory.cpp
intern/audaspace/FX/AUD_SquareReader.cpp [deleted file]
intern/audaspace/FX/AUD_SquareReader.h [deleted file]
intern/audaspace/FX/AUD_SumFactory.cpp
intern/audaspace/FX/AUD_SumReader.cpp [deleted file]
intern/audaspace/FX/AUD_VolumeFactory.cpp
intern/audaspace/Python/AUD_PyAPI.cpp
source/creator/creator.c

index 6e9130d174bd0cdf2fa42d4c5ec1d2a41aacbb6f..0c51e5241e41cffc293ae33547b41ad46281d019 100644 (file)
  */
 
 #include "AUD_AccumulatorFactory.h"
-#include "AUD_AccumulatorReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       float in = reader->x(0);
+       float lastin = reader->x(-1);
+       float out = reader->y(-1) + in - lastin;
+       if(in > lastin)
+               out += in - lastin;
+       return out;
+}
+
+sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       float in = reader->x(0);
+       float lastin = reader->x(-1);
+       float out = reader->y(-1);
+       if(in > lastin)
+               out += in - lastin;
+       return out;
+}
 
 AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
                                                                                           bool additive) :
@@ -35,5 +55,6 @@ AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
 
 AUD_IReader* AUD_AccumulatorFactory::createReader() const
 {
-       return new AUD_AccumulatorReader(getReader(), m_additive);
+       return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
+                                                       m_additive ? accumulatorFilterAdditive : accumulatorFilter);
 }
diff --git a/intern/audaspace/FX/AUD_AccumulatorReader.cpp b/intern/audaspace/FX/AUD_AccumulatorReader.cpp
deleted file mode 100644 (file)
index a8964ed..0000000
+++ /dev/null
@@ -1,85 +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_AccumulatorReader.h"
-
-#include <cstring>
-
-#define CC specs.channels + channel
-
-AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader,
-                                                                                        bool additive) :
-               AUD_EffectReader(reader),
-               m_additive(additive),
-               m_sums(AUD_SAMPLE_SIZE(reader->getSpecs())),
-               m_prevs(AUD_SAMPLE_SIZE(reader->getSpecs()))
-{
-       memset(m_sums.getBuffer(), 0, m_sums.getSize());
-       memset(m_prevs.getBuffer(), 0, m_prevs.getSize());
-}
-
-void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
-{
-       sample_t* buf;
-       sample_t* sums;
-       sample_t* prevs;
-       sums = m_sums.getBuffer();
-       prevs = m_prevs.getBuffer();
-
-       AUD_Specs specs = m_reader->getSpecs();
-
-       m_reader->read(length, buf);
-       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
-
-       buffer = m_buffer.getBuffer();
-
-       if(m_additive)
-       {
-               for(int channel = 0; channel < specs.channels; channel++)
-               {
-                       for(int i = 0; i < length; i++)
-                       {
-                               if(buf[i * CC] > prevs[channel])
-                                       sums[channel] += buf[i * CC] - prevs[channel];
-                               buffer[i * CC] = sums[channel] + buf[i * CC];
-                               prevs[channel] = buf[i * CC];
-                       }
-               }
-       }
-       else
-       {
-               for(int channel = 0; channel < specs.channels; channel++)
-               {
-                       for(int i = 0; i < length; i++)
-                       {
-                               if(buf[i * CC] > prevs[channel])
-                                       sums[channel] += buf[i * CC] - prevs[channel];
-                               buffer[i * CC] = sums[channel];
-                               prevs[channel] = buf[i * CC];
-                       }
-               }
-       }
-}
diff --git a/intern/audaspace/FX/AUD_AccumulatorReader.h b/intern/audaspace/FX/AUD_AccumulatorReader.h
deleted file mode 100644 (file)
index 68c1360..0000000
+++ /dev/null
@@ -1,73 +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_ACCUMULATORREADER
-#define AUD_ACCUMULATORREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class represents an accumulator.
- */
-class AUD_AccumulatorReader : public AUD_EffectReader
-{
-private:
-       /**
-        * Whether the accumulator is additive.
-        */
-       const bool m_additive;
-
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
-       /**
-        * The sums of the specific channels.
-        */
-       AUD_Buffer m_sums;
-
-       /**
-        * The previous results of the specific channels.
-        */
-       AUD_Buffer m_prevs;
-
-       // hide copy constructor and operator=
-       AUD_AccumulatorReader(const AUD_AccumulatorReader&);
-       AUD_AccumulatorReader& operator=(const AUD_AccumulatorReader&);
-
-public:
-       /**
-        * Creates a new accumulator reader.
-        * \param reader The reader to read from.
-        * \param additive Whether the accumulator is additive.
-        */
-       AUD_AccumulatorReader(AUD_IReader* reader, bool additive);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_ACCUMULATORREADER
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
new file mode 100644 (file)
index 0000000..9e14bcf
--- /dev/null
@@ -0,0 +1,76 @@
+/*
+ * $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_BaseIIRFilterReader.h"
+
+#include <cstring>
+
+#define CC m_channels + m_channel
+
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_IReader* reader, int in,
+                                                                                                int out) :
+               AUD_EffectReader(reader),
+               m_channels(reader->getSpecs().channels),
+               m_xlen(in), m_ylen(out),
+               m_xpos(0), m_ypos(0), m_channel(0)
+{
+       m_x = new sample_t[in * m_channels];
+       m_y = new sample_t[out * m_channels];
+
+       memset(m_x, 0, sizeof(sample_t) * in * m_channels);
+       memset(m_y, 0, sizeof(sample_t) * out * m_channels);
+}
+
+AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
+{
+       delete[] m_x;
+       delete[] m_y;
+}
+
+void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
+{
+       sample_t* buf;
+
+       int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+
+       m_reader->read(length, buf);
+
+       if(m_buffer.getSize() < length * samplesize)
+               m_buffer.resize(length * samplesize);
+
+       buffer = m_buffer.getBuffer();
+
+       for(m_channel = 0; m_channel < m_channels; m_channel++)
+       {
+               for(int i = 0; i < length; i++)
+               {
+                       m_x[m_xpos * CC] = buf[i * CC];
+                       m_y[m_ypos * CC] = buffer[i * CC] = filter();
+
+                       m_xpos = (m_xpos + 1) % m_xlen;
+                       m_ypos = (m_ypos + 1) % m_ylen;
+               }
+       }
+}
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
new file mode 100644 (file)
index 0000000..7e2b719
--- /dev/null
@@ -0,0 +1,114 @@
+/*
+ * $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_BASEIIRFILTERREADER
+#define AUD_BASEIIRFILTERREADER
+
+#include "AUD_EffectReader.h"
+#include "AUD_Buffer.h"
+
+/**
+ * This class is a base class for infinite impulse response filters.
+ */
+class AUD_BaseIIRFilterReader : public AUD_EffectReader
+{
+private:
+       /**
+        * Channel count.
+        */
+       const int m_channels;
+
+       /**
+        * Length of input samples needed.
+        */
+       const int m_xlen;
+
+       /**
+        * Length of output samples needed.
+        */
+       const int m_ylen;
+
+       /**
+        * The playback buffer.
+        */
+       AUD_Buffer m_buffer;
+
+       /**
+        * The last in samples array.
+        */
+       sample_t* m_x;
+
+       /**
+        * The last out samples array.
+        */
+       sample_t* m_y;
+
+       /**
+        * Position of the current input sample in the input array.
+        */
+       int m_xpos;
+
+       /**
+        * Position of the current output sample in the output array.
+        */
+       int m_ypos;
+
+       /**
+        * Current channel.
+        */
+       int m_channel;
+
+       // hide copy constructor and operator=
+       AUD_BaseIIRFilterReader(const AUD_BaseIIRFilterReader&);
+       AUD_BaseIIRFilterReader& operator=(const AUD_BaseIIRFilterReader&);
+
+protected:
+       /**
+        * Creates a new base IIR filter reader.
+        * \param reader The reader to read from.
+        * \param in The count of past input samples needed.
+        * \param out The count of past output samples needed.
+        */
+       AUD_BaseIIRFilterReader(AUD_IReader* reader, int in, int out);
+
+public:
+       inline sample_t x(int pos)
+       {
+               return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_channels + m_channel];
+       }
+
+       inline sample_t y(int pos)
+       {
+               return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_channels + m_channel];
+       }
+
+       virtual ~AUD_BaseIIRFilterReader();
+
+       virtual void read(int & length, sample_t* & buffer);
+
+       virtual sample_t filter()=0;
+};
+
+#endif //AUD_BASEIIRFILTERREADER
index 1bb1d726a9831a845bbb0b801820100081721cba..874ff0f635144acc4cc405723feff3203674e8cb 100644 (file)
  */
 
 #include "AUD_ButterworthFactory.h"
-#include "AUD_ButterworthReader.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#define BWPB41 0.76536686473
+#define BWPB42 1.84775906502
 
 AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
                                                                                           float frequency) :
@@ -35,5 +44,29 @@ AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
 
 AUD_IReader* AUD_ButterworthFactory::createReader() const
 {
-       return new AUD_ButterworthReader(getReader(), m_frequency);
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().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;
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back((x1 + x2) * o228 / norm);
+       a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
+       a.push_back((y1 + y2) * o228 / norm);
+       a.push_back(y1 * y2 / norm);
+       b.push_back(o4 / norm);
+       b.push_back(4 * o4 / norm);
+       b.push_back(6 * o4 / norm);
+       b.push_back(b[1]);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
 }
diff --git a/intern/audaspace/FX/AUD_ButterworthReader.cpp b/intern/audaspace/FX/AUD_ButterworthReader.cpp
deleted file mode 100644 (file)
index cfe4205..0000000
+++ /dev/null
@@ -1,109 +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_ButterworthReader.h"
-
-#include <cstring>
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define BWPB41 0.76536686473
-#define BWPB42 1.84775906502
-#define CC channels + channel
-
-AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
-                                                                                        float frequency) :
-               AUD_EffectReader(reader),
-               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
-               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
-               m_position(0)
-{
-       AUD_Specs specs = reader->getSpecs();
-       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
-       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
-
-       // calculate coefficients
-       float omega = 2 * tan(frequency * M_PI / specs.rate);
-       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;
-}
-
-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
deleted file mode 100644 (file)
index 52cbb64..0000000
+++ /dev/null
@@ -1,81 +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_BUTTERWORTHREADER
-#define AUD_BUTTERWORTHREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * 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];
-
-       // hide copy constructor and operator=
-       AUD_ButterworthReader(const AUD_ButterworthReader&);
-       AUD_ButterworthReader& operator=(const AUD_ButterworthReader&);
-
-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.
-        */
-       AUD_ButterworthReader(AUD_IReader* reader, float frequency);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_BUTTERWORTHREADER
similarity index 61%
rename from intern/audaspace/FX/AUD_VolumeReader.cpp
rename to intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
index 7401b508b28596f0ea900d736f77accb12133438..02ab6e185fee92e016bc9220d4ecb7b05552d50e 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_VolumeReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
 
-#include <cstring>
-
-AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
-               AUD_EffectReader(reader),
-               m_volume(volume)
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
+                                                                                                                int in, int out,
+                                                                                                                doFilterIIR doFilter,
+                                                                                                                endFilterIIR endFilter,
+                                                                                                                void* data) :
+       AUD_BaseIIRFilterReader(reader, in, out),
+       m_filter(doFilter), m_endFilter(endFilter), m_data(data)
 {
 }
 
-void AUD_VolumeReader::read(int & length, sample_t* & buffer)
+AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader()
 {
-       sample_t* buf;
-       AUD_Specs specs = m_reader->getSpecs();
-
-       m_reader->read(length, buf);
-       if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
-               m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
-
-       buffer = m_buffer.getBuffer();
+       if(m_endFilter)
+               m_endFilter(m_data);
+}
 
-       for(int i = 0; i < length * specs.channels; i++)
-               buffer[i] = buf[i] * m_volume;
+sample_t AUD_CallbackIIRFilterReader::filter()
+{
+       return m_filter(this, m_data);
 }
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
new file mode 100644 (file)
index 0000000..6472c7b
--- /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_CALLBACKIIRFILTERREADER
+#define AUD_CALLBACKIIRFILTERREADER
+
+#include "AUD_BaseIIRFilterReader.h"
+#include "AUD_Buffer.h"
+
+class AUD_CallbackIIRFilterReader;
+
+typedef sample_t (*doFilterIIR)(AUD_CallbackIIRFilterReader*, void*);
+typedef void (*endFilterIIR)(void*);
+
+/**
+ * This class provides an interface for infinite impulse response filters via a
+ * callback filter function.
+ */
+class AUD_CallbackIIRFilterReader : public AUD_BaseIIRFilterReader
+{
+private:
+       /**
+        * Filter function.
+        */
+       const doFilterIIR m_filter;
+
+       /**
+        * End filter function.
+        */
+       const endFilterIIR m_endFilter;
+
+       /**
+        * Data pointer.
+        */
+       void* m_data;
+
+       // hide copy constructor and operator=
+       AUD_CallbackIIRFilterReader(const AUD_CallbackIIRFilterReader&);
+       AUD_CallbackIIRFilterReader& operator=(const AUD_CallbackIIRFilterReader&);
+
+public:
+       /**
+        * Creates a new callback IIR filter reader.
+        * \param reader The reader to read from.
+        * \param in The count of past input samples needed.
+        * \param out The count of past output samples needed.
+        * \param doFilter The filter callback.
+        * \param endFilter The finishing callback.
+        * \param data Data pointer for the callbacks.
+        */
+       AUD_CallbackIIRFilterReader(AUD_IReader* reader, int in, int out,
+                                                               doFilterIIR doFilter,
+                                                               endFilterIIR endFilter = 0,
+                                                               void* data = 0);
+
+       virtual ~AUD_CallbackIIRFilterReader();
+
+       virtual sample_t filter();
+};
+
+#endif //AUD_CALLBACKIIRFILTERREADER
index 1c625067f1c59ff88520f063536cecb71bd2d8b9..4777da70404e17a12f3773c0747ea4ae588842af 100644 (file)
  */
 
 #include "AUD_EnvelopeFactory.h"
-#include "AUD_EnvelopeReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+struct EnvelopeParameters
+{
+       float attack;
+       float release;
+       float threshold;
+       float arthreshold;
+};
+
+sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+{
+       float in = fabs(reader->x(0));
+       float out = reader->y(-1);
+       if(in < param->threshold)
+               in = 0.0f;
+       return (in > out ? param->attack : param->release) * (out - in) + in;
+}
+
+void endEnvelopeFilter(EnvelopeParameters* param)
+{
+       delete param;
+}
 
 AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
                                                                                 float release, float threshold,
@@ -39,6 +63,16 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
 
 AUD_IReader* AUD_EnvelopeFactory::createReader() const
 {
-       return new AUD_EnvelopeReader(getReader(), m_attack, m_release, m_threshold,
-                                                                 m_arthreshold);
+       AUD_IReader* reader = getReader();
+
+       EnvelopeParameters* param = new EnvelopeParameters();
+       param->arthreshold = m_arthreshold;
+       param->attack = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_attack));
+       param->release = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_release));
+       param->threshold = m_threshold;
+
+       return new AUD_CallbackIIRFilterReader(reader, 1, 2,
+                                                                                  (doFilterIIR) envelopeFilter,
+                                                                                  (endFilterIIR) endEnvelopeFilter,
+                                                                                  param);
 }
diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.cpp b/intern/audaspace/FX/AUD_EnvelopeReader.cpp
deleted file mode 100644 (file)
index ef64b6f..0000000
+++ /dev/null
@@ -1,72 +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_EnvelopeReader.h"
-
-#include <cstring>
-#include <cmath>
-
-AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
-                                                                          float release, float threshold,
-                                                                          float arthreshold) :
-               AUD_EffectReader(reader),
-               m_bAttack(pow(arthreshold, 1.0f/(reader->getSpecs().rate * attack))),
-               m_bRelease(pow(arthreshold, 1.0f/(reader->getSpecs().rate * release))),
-               m_threshold(threshold),
-               m_envelopes(AUD_SAMPLE_SIZE(reader->getSpecs()))
-{
-       memset(m_envelopes.getBuffer(), 0, m_envelopes.getSize());
-}
-
-void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
-{
-       sample_t* buf;
-       sample_t* envelopes;
-       envelopes = m_envelopes.getBuffer();
-
-       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
deleted file mode 100644 (file)
index b452ee2..0000000
+++ /dev/null
@@ -1,82 +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_ENVELOPEREADER
-#define AUD_ENVELOPEREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class represents an envelope follower.
- */
-class AUD_EnvelopeReader : public AUD_EffectReader
-{
-private:
-       /**
-        * Attack b value.
-        */
-       const float m_bAttack;
-
-       /**
-        * Release b value.
-        */
-       const float m_bRelease;
-
-       /**
-        * Threshold value.
-        */
-       const float m_threshold;
-
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
-       /**
-        * The last envelopes buffer.
-        */
-       AUD_Buffer m_envelopes;
-
-       // hide copy constructor and operator=
-       AUD_EnvelopeReader(const AUD_EnvelopeReader&);
-       AUD_EnvelopeReader& operator=(const AUD_EnvelopeReader&);
-
-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.
-        */
-       AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release,
-                                          float threshold, float arthreshold);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_ENVELOPEREADER
index 1ab5237c8ffb29e8f36ca23c382ee75313e0d5b2..d222e7f615e7da48da5753d9f2f9c074479152c7 100644 (file)
  */
 
 #include "AUD_HighpassFactory.h"
-#include "AUD_HighpassReader.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
 
 AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
                                                                                 float Q) :
@@ -36,5 +42,20 @@ AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
 
 AUD_IReader* AUD_HighpassFactory::createReader() const
 {
-       return new AUD_HighpassReader(getReader(), m_frequency, m_Q);
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float alpha = sin(w0) / (2 * m_Q);
+       float norm = 1 + alpha;
+       float c = cos(w0);
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-2 * c / norm);
+       a.push_back((1 - alpha) / norm);
+       b.push_back((1 + c) / (2 * norm));
+       b.push_back((-1 - c) / norm);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
 }
diff --git a/intern/audaspace/FX/AUD_HighpassReader.cpp b/intern/audaspace/FX/AUD_HighpassReader.cpp
deleted file mode 100644 (file)
index 904d6a9..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 *****
- */
-
-#include "AUD_HighpassReader.h"
-
-#include <cstring>
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define CC channels + channel
-
-AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
-                                                                          float Q) :
-               AUD_EffectReader(reader),
-               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
-               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
-               m_position(0)
-{
-       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
-       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
-
-       AUD_Specs specs = reader->getSpecs();
-
-       // calculate coefficients
-       float w0 = 2 * 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;
-}
-
-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
deleted file mode 100644 (file)
index 845e764..0000000
+++ /dev/null
@@ -1,81 +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_HIGHPASSREADER
-#define AUD_HIGHPASSREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-#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];
-
-       // hide copy constructor and operator=
-       AUD_HighpassReader(const AUD_HighpassReader&);
-       AUD_HighpassReader& operator=(const AUD_HighpassReader&);
-
-public:
-       /**
-        * Creates a new highpass reader.
-        * \param reader The reader to read from.
-        * \param frequency The cutoff frequency.
-        * \param Q The Q factor.
-        */
-       AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_HIGHPASSREADER
similarity index 62%
rename from intern/audaspace/FX/AUD_RectifyReader.cpp
rename to intern/audaspace/FX/AUD_IIRFilterFactory.cpp
index c5bf73fac0316d27758434580254a84f4ee16ec3..8cd49a0370856bba620c79f23b6aa9ac92407d36 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#include "AUD_RectifyReader.h"
+#include "AUD_IIRFilterFactory.h"
+#include "AUD_IIRFilterReader.h"
 
-#include <cmath>
-
-AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
-               AUD_EffectReader(reader)
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
+                                                                                  std::vector<float> b,
+                                                                                  std::vector<float> a) :
+               AUD_EffectFactory(factory), m_a(a), m_b(b)
 {
 }
 
-void AUD_RectifyReader::read(int & length, sample_t* & buffer)
+AUD_IReader* AUD_IIRFilterFactory::createReader() const
 {
-       sample_t* buf;
-       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();
-
-       for(int i = 0; i < length * specs.channels; i++)
-               buffer[i] = fabs(buf[i]);
+       return new AUD_IIRFilterReader(getReader(), m_b, m_a);
 }
similarity index 55%
rename from intern/audaspace/FX/AUD_VolumeReader.h
rename to intern/audaspace/FX/AUD_IIRFilterFactory.h
index 0e96a27e2879223ee93775a110dec421fdb3ff3d..567d4f354fede349a7b2a5e39682f08e1ba11633 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_VOLUMEREADER
-#define AUD_VOLUMEREADER
+#ifndef AUD_IIRFILTERFACTORY
+#define AUD_IIRFILTERFACTORY
 
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
+#include "AUD_EffectFactory.h"
+
+#include <vector>
 
 /**
- * This class reads another reader and changes it's volume.
+ * This factory creates a IIR filter reader.
  */
-class AUD_VolumeReader : public AUD_EffectReader
+class AUD_IIRFilterFactory : public AUD_EffectFactory
 {
 private:
        /**
-        * The playback buffer.
+        * Output filter coefficients.
         */
-       AUD_Buffer m_buffer;
+       std::vector<float> m_a;
 
        /**
-        * The volume level.
+        * Input filter coefficients.
         */
-       const float m_volume;
+       std::vector<float> m_b;
 
        // hide copy constructor and operator=
-       AUD_VolumeReader(const AUD_VolumeReader&);
-       AUD_VolumeReader& operator=(const AUD_VolumeReader&);
+       AUD_IIRFilterFactory(const AUD_IIRFilterFactory&);
+       AUD_IIRFilterFactory& operator=(const AUD_IIRFilterFactory&);
 
 public:
        /**
-        * Creates a new volume reader.
-        * \param reader The reader to read from.
-        * \param volume The size of the buffer.
+        * Creates a new IIR filter factory.
+        * \param factory The input factory.
+        * \param b The input filter coefficients.
+        * \param a The output filter coefficients.
         */
-       AUD_VolumeReader(AUD_IReader* reader, float volume);
+       AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
+                                                std::vector<float> a);
 
-       virtual void read(int & length, sample_t* & buffer);
+       virtual AUD_IReader* createReader() const;
 };
 
-#endif //AUD_VOLUMEREADER
+#endif //AUD_IIRFILTERFACTORY
similarity index 56%
rename from intern/audaspace/FX/AUD_RectifyReader.h
rename to intern/audaspace/FX/AUD_IIRFilterReader.cpp
index 498f18e50411b2c65ea37970bfd6d2992ec0e24f..120c9f8d0ae16887584545e5a3c3356e04e1a345 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_RECTIFYREADER
-#define AUD_RECTIFYREADER
+#include "AUD_IIRFilterReader.h"
 
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class reads another reader and rectifies it.
- */
-class AUD_RectifyReader : public AUD_EffectReader
+AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
+                                                                                std::vector<float> b,
+                                                                                std::vector<float> a) :
+       AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
 {
-private:
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
+       for(int i = 1; i < m_a.size(); i++)
+               m_a[i] /= m_a[0];
+       for(int i = 0; i < m_b.size(); i++)
+               m_b[i] /= m_a[0];
+       m_a[0] = 1;
+}
 
-       // hide copy constructor and operator=
-       AUD_RectifyReader(const AUD_RectifyReader&);
-       AUD_RectifyReader& operator=(const AUD_RectifyReader&);
-
-public:
-       /**
-        * Creates a new rectify reader.
-        * \param reader The reader to read from.
-        */
-       AUD_RectifyReader(AUD_IReader* reader);
+sample_t AUD_IIRFilterReader::filter()
+{
+       sample_t out = 0;
 
-       virtual void read(int & length, sample_t* & buffer);
-};
+       for(int i = 1; i < m_a.size(); i++)
+               out -= y(-i) * m_a[i];
+       for(int i = 0; i < m_b.size(); i++)
+               out += x(-i) * m_b[i];
 
-#endif //AUD_RECTIFYREADER
+       return out;
+}
similarity index 56%
rename from intern/audaspace/FX/AUD_SumReader.h
rename to intern/audaspace/FX/AUD_IIRFilterReader.h
index 0bb470bac97c8f3c51f2323900cf596c1a6a55c2..303bc6d92dfd063a6515ad1a1c47f7fc91849584 100644 (file)
  * ***** END LGPL LICENSE BLOCK *****
  */
 
-#ifndef AUD_SUMREADER
-#define AUD_SUMREADER
+#ifndef AUD_IIRFILTERREADER
+#define AUD_IIRFILTERREADER
 
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
+#include "AUD_BaseIIRFilterReader.h"
+
+#include <vector>
 
 /**
- * This class represents an summer.
+ * This class is for infinite impulse response filters with simple coefficients.
  */
-class AUD_SumReader : public AUD_EffectReader
+class AUD_IIRFilterReader : public AUD_BaseIIRFilterReader
 {
 private:
        /**
-        * The playback buffer.
+        * Output filter coefficients.
         */
-       AUD_Buffer m_buffer;
+       std::vector<float> m_a;
 
        /**
-        * The sums of the specific channels.
+        * Input filter coefficients.
         */
-       AUD_Buffer m_sums;
+       std::vector<float> m_b;
 
        // hide copy constructor and operator=
-       AUD_SumReader(const AUD_SumReader&);
-       AUD_SumReader& operator=(const AUD_SumReader&);
+       AUD_IIRFilterReader(const AUD_IIRFilterReader&);
+       AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&);
 
 public:
        /**
-        * Creates a new sum reader.
+        * Creates a new IIR filter reader.
         * \param reader The reader to read from.
+        * \param b The input filter coefficients.
+        * \param a The output filter coefficients.
         */
-       AUD_SumReader(AUD_IReader* reader);
+       AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
+                                               std::vector<float> a);
 
-       virtual void read(int & length, sample_t* & buffer);
+       virtual sample_t filter();
 };
 
-#endif //AUD_SUMREADER
+#endif //AUD_IIRFILTERREADER
index dfef0f6f7c3aa1a3b4f8c756709f6e872ce67309..9244e07631b483773abbbb6e78999525d1169795 100644 (file)
  */
 
 #include "AUD_LowpassFactory.h"
-#include "AUD_LowpassReader.h"
+#include "AUD_IIRFilterReader.h"
+
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
 
 AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
                                                                           float Q) :
@@ -36,5 +42,20 @@ AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
 
 AUD_IReader* AUD_LowpassFactory::createReader() const
 {
-       return new AUD_LowpassReader(getReader(), m_frequency, m_Q);
+       AUD_IReader* reader = getReader();
+
+       // calculate coefficients
+       float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+       float alpha = sin(w0) / (2 * m_Q);
+       float norm = 1 + alpha;
+       float c = cos(w0);
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-2 * c / norm);
+       a.push_back((1 - alpha) / norm);
+       b.push_back((1 - c) / (2 * norm));
+       b.push_back((1 - c) / norm);
+       b.push_back(b[0]);
+
+       return new AUD_IIRFilterReader(reader, b, a);
 }
diff --git a/intern/audaspace/FX/AUD_LowpassReader.cpp b/intern/audaspace/FX/AUD_LowpassReader.cpp
deleted file mode 100644 (file)
index 71b5de1..0000000
+++ /dev/null
@@ -1,99 +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_LowpassReader.h"
-
-#include <cstring>
-#include <cmath>
-
-#ifndef M_PI
-#define M_PI 3.14159265358979323846
-#endif
-
-#define CC channels + channel
-
-AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
-                                                                        float Q) :
-               AUD_EffectReader(reader),
-               m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
-               m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
-               m_position(0)
-{
-       memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
-       memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
-
-       AUD_Specs specs = reader->getSpecs();
-
-       // calculate coefficients
-       float w0 = 2 * 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;
-}
-
-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
deleted file mode 100644 (file)
index 66e4b91..0000000
+++ /dev/null
@@ -1,81 +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_LOWPASSREADER
-#define AUD_LOWPASSREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-#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];
-
-       // hide copy constructor and operator=
-       AUD_LowpassReader(const AUD_LowpassReader&);
-       AUD_LowpassReader& operator=(const AUD_LowpassReader&);
-
-public:
-       /**
-        * Creates a new lowpass reader.
-        * \param reader The reader to read from.
-        * \param frequency The cutoff frequency.
-        * \param Q The Q factor.
-        */
-       AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_LOWPASSREADER
index 52608c3177b6ab21c113e899ddae0af7af817cf0..2228f949dfeeadb806902e1addfa4d82095b5f5c 100644 (file)
  */
 
 #include "AUD_RectifyFactory.h"
-#include "AUD_RectifyReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+#include <cmath>
+
+sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+{
+       return fabs(reader->x(0));
+}
 
 AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
                AUD_EffectFactory(factory)
@@ -33,5 +40,5 @@ AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
 
 AUD_IReader* AUD_RectifyFactory::createReader() const
 {
-       return new AUD_RectifyReader(getReader());
+       return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
 }
index b95c9d9bb0f95fa039008406f13722978e2109f0..c321a13d79a0e482753f0b4725dcb255db0e956b 100644 (file)
  */
 
 #include "AUD_SquareFactory.h"
-#include "AUD_SquareReader.h"
+#include "AUD_CallbackIIRFilterReader.h"
+
+sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
+{
+       float in = reader->x(0);
+       if(in >= *threshold)
+               return 1;
+       else if(in <= -*threshold)
+               return -1;
+       else
+               return 0;
+}
+
+void endSquareFilter(float* threshold)
+{
+       delete threshold;
+}
 
 AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
                AUD_EffectFactory(factory),
@@ -39,5 +55,8 @@ float AUD_SquareFactory::getThreshold() const
 
 AUD_IReader* AUD_SquareFactory::createReader() const
 {
-       return new AUD_SquareReader(getReader(), m_threshold);
+       return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
+                                                                                  (doFilterIIR) squareFilter,
+                                                                                  (endFilterIIR) endSquareFilter,
+                                                                                  new float(m_threshold));
 }
diff --git a/intern/audaspace/FX/AUD_SquareReader.cpp b/intern/audaspace/FX/AUD_SquareReader.cpp
deleted file mode 100644 (file)
index 4bf0d87..0000000
+++ /dev/null
@@ -1,57 +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_SquareReader.h"
-
-#include <cstring>
-
-AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) :
-               AUD_EffectReader(reader),
-               m_threshold(threshold)
-{
-}
-
-void AUD_SquareReader::read(int & length, sample_t* & buffer)
-{
-       sample_t* buf;
-       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();
-
-       for(int i = 0; i < length * specs.channels; i++)
-       {
-               if(buf[i] >= m_threshold)
-                       buffer[i] = 1.0f;
-               else if(buf[i] <= -m_threshold)
-                       buffer[i] = -1.0f;
-               else
-                       buffer[i] = 0.0f;
-       }
-}
diff --git a/intern/audaspace/FX/AUD_SquareReader.h b/intern/audaspace/FX/AUD_SquareReader.h
deleted file mode 100644 (file)
index d3a5331..0000000
+++ /dev/null
@@ -1,63 +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_SQUAREREADER
-#define AUD_SQUAREREADER
-
-#include "AUD_EffectReader.h"
-#include "AUD_Buffer.h"
-
-/**
- * This class changes another signal into a square signal.
- */
-class AUD_SquareReader : public AUD_EffectReader
-{
-private:
-       /**
-        * The playback buffer.
-        */
-       AUD_Buffer m_buffer;
-
-       /**
-        * The threshold level.
-        */
-       const float m_threshold;
-
-       // hide copy constructor and operator=
-       AUD_SquareReader(const AUD_SquareReader&);
-       AUD_SquareReader& operator=(const AUD_SquareReader&);
-
-public:
-       /**
-        * Creates a new square reader.
-        * \param reader The reader to read from.
-        * \param threshold The size of the buffer.
-        */
-       AUD_SquareReader(AUD_IReader* reader, float threshold);
-
-       virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_SQUAREREADER
index 96ad286bf5c8ffaddd7d700409d5a8f588f879d3..a128e50504cab2e1a6d4409e7b3ac60191971e72 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "AUD_SumFactory.h"
-#include "AUD_SumReader.h"
+#include "AUD_IIRFilterReader.h"
 
 AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
                AUD_EffectFactory(factory)
@@ -33,5 +33,9 @@ AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
 
 AUD_IReader* AUD_SumFactory::createReader() const
 {
-       return new AUD_SumReader(getReader());
+       std::vector<float> a, b;
+       a.push_back(1);
+       a.push_back(-1);
+       b.push_back(1);
+       return new AUD_IIRFilterReader(getReader(), b, a);
 }
diff --git a/intern/audaspace/FX/AUD_SumReader.cpp b/intern/audaspace/FX/AUD_SumReader.cpp
deleted file mode 100644 (file)
index 13f0e22..0000000
+++ /dev/null
@@ -1,57 +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_SumReader.h"
-
-#include <cstring>
-
-#define CC specs.channels + channel
-
-AUD_SumReader::AUD_SumReader(AUD_IReader* reader) :
-               AUD_EffectReader(reader),
-               m_sums(AUD_SAMPLE_SIZE(reader->getSpecs()))
-{
-       memset(m_sums.getBuffer(), 0, m_sums.getSize());
-}
-
-void AUD_SumReader::read(int & length, sample_t* & buffer)
-{
-       sample_t* buf;
-       sample_t* sums;
-       sums = m_sums.getBuffer();
-
-       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();
-
-       for(int channel = 0; channel < specs.channels; channel++)
-               for(int i = 0; i < length * specs.channels; i++)
-                       buffer[i * CC] = sums[channel] = sums[channel] + buf[i * CC];
-}
index 9f0fd5821fd41bc028b1f3509a386f24c7a764d0..1b341a5a51acbe0a146eaafa530c3dad707e57b7 100644 (file)
@@ -24,7 +24,7 @@
  */
 
 #include "AUD_VolumeFactory.h"
-#include "AUD_VolumeReader.h"
+#include "AUD_IIRFilterReader.h"
 
 AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
                AUD_EffectFactory(factory),
@@ -39,5 +39,8 @@ float AUD_VolumeFactory::getVolume() const
 
 AUD_IReader* AUD_VolumeFactory::createReader() const
 {
-       return new AUD_VolumeReader(getReader(), m_volume);
+       std::vector<float> a, b;
+       a.push_back(1);
+       b.push_back(m_volume);
+       return new AUD_IIRFilterReader(getReader(), b, a);
 }
index dff7334e577073853b204910a26f24ea9d51cf7c..6c8f86dc6c5d53861a7f52a83b56507bd0645c47 100644 (file)
@@ -44,6 +44,7 @@
 #include "AUD_StreamBufferFactory.h"
 #include "AUD_SuperposeFactory.h"
 #include "AUD_VolumeFactory.h"
+#include "AUD_IIRFilterFactory.h"
 
 #ifdef WITH_SDL
 #include "AUD_SDLDevice.h"
@@ -142,10 +143,12 @@ static PyObject *
 Sound_file(PyObject* nothing, PyObject* args);
 
 PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
-                        "lowpass(frequency)\n\n"
-                        "Creates a low quality lowpass filter.\n\n"
+                        "lowpass(frequency[, Q])\n\n"
+                        "Creates a second order lowpass filter.\n\n"
                         ":arg frequency: The cut off trequency of the lowpass.\n"
                         ":type frequency: float\n"
+                        ":arg Q: Q factor of the lowpass.\n"
+                        ":type Q: float\n"
                         ":return: The created aud.Sound object.\n"
                         ":rtype: aud.Sound");
 
@@ -177,10 +180,12 @@ static PyObject *
 Sound_join(Sound* self, PyObject* object);
 
 PyDoc_STRVAR(M_aud_Sound_highpass_doc,
-                        "highpass(frequency)\n\n"
-                        "Creates a low quality highpass filter.\n\n"
+                        "highpass(frequency[, Q])\n\n"
+                        "Creates a second order highpass filter.\n\n"
                         ":arg frequency: The cut off trequency of the highpass.\n"
                         ":type frequency: float\n"
+                        ":arg Q: Q factor of the lowpass.\n"
+                        ":type Q: float\n"
                         ":return: The created aud.Sound object.\n"
                         ":rtype: aud.Sound");
 
@@ -322,6 +327,19 @@ PyDoc_STRVAR(M_aud_Sound_square_doc,
 static PyObject *
 Sound_square(Sound* self, PyObject* args);
 
+PyDoc_STRVAR(M_aud_Sound_filter_doc,
+                        "filter(b[, a = (1)])\n\n"
+                        "Filters a sound with the supplied IIR filter coefficients.\n\n"
+                        ":arg b: The nominator filter coefficients.\n"
+                        ":type b: sequence of float\n"
+                        ":arg a: The denominator filter coefficients.\n"
+                        ":type a: sequence of float\n"
+                        ":return: The created aud.Sound object.\n"
+                        ":rtype: aud.Sound");
+
+static PyObject *
+Sound_filter(Sound* self, PyObject* args);
+
 static PyMethodDef Sound_methods[] = {
        {"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
         M_aud_Sound_sine_doc
@@ -374,6 +392,9 @@ static PyMethodDef Sound_methods[] = {
        {"square", (PyCFunction)Sound_square, METH_VARARGS,
         M_aud_Sound_square_doc
        },
+       {"filter", (PyCFunction)Sound_filter, METH_VARARGS,
+        M_aud_Sound_filter_doc
+       },
        {NULL}  /* Sentinel */
 };
 
@@ -483,8 +504,9 @@ static PyObject *
 Sound_lowpass(Sound* self, PyObject* args)
 {
        float frequency;
+       float Q = 0.5;
 
-       if(!PyArg_ParseTuple(args, "f", &frequency))
+       if(!PyArg_ParseTuple(args, "f|f", &frequency, &Q))
                return NULL;
 
        Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
@@ -496,7 +518,7 @@ Sound_lowpass(Sound* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_LowpassFactory(self->factory, frequency, 0.9);
+                       parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
                }
                catch(AUD_Exception&)
                {
@@ -574,8 +596,9 @@ static PyObject *
 Sound_highpass(Sound* self, PyObject* args)
 {
        float frequency;
+       float Q = 0.5;
 
-       if(!PyArg_ParseTuple(args, "f", &frequency))
+       if(!PyArg_ParseTuple(args, "f|f", &frequency, &Q))
                return NULL;
 
        Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
@@ -587,7 +610,7 @@ Sound_highpass(Sound* self, PyObject* args)
 
                try
                {
-                       parent->factory = new AUD_HighpassFactory(self->factory, frequency, 0.9);
+                       parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
                }
                catch(AUD_Exception&)
                {
@@ -919,6 +942,86 @@ Sound_square(Sound* self, PyObject* args)
        return (PyObject *)parent;
 }
 
+static PyObject *
+Sound_filter(Sound* self, PyObject* args)
+{
+       PyObject* py_b;
+       PyObject* py_a = NULL;
+
+       if(!PyArg_ParseTuple(args, "O|O", &py_b, &py_a))
+               return NULL;
+
+       if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a)))
+       {
+               PyErr_SetString(AUDError, "Supplied parameter is not a sequence!");
+               return NULL;
+       }
+
+       if(!PySequence_Length(py_b) || (py_a != NULL && !PySequence_Length(py_a)))
+       {
+               PyErr_SetString(AUDError, "The sequence has to contain at least one value!");
+               return NULL;
+       }
+
+       std::vector<float> a, b;
+       PyObject* py_value;
+       float value;
+       int result;
+
+       for(int i = 0; i < PySequence_Length(py_b); i++)
+       {
+               py_value = PySequence_GetItem(py_b, i);
+               result = PyArg_Parse(py_value, "f", &value);
+               Py_DECREF(py_value);
+
+               if(!result)
+                       return NULL;
+
+               b.push_back(value);
+       }
+
+       if(py_a)
+       {
+               for(int i = 0; i < PySequence_Length(py_a); i++)
+               {
+                       py_value = PySequence_GetItem(py_a, i);
+                       result = PyArg_Parse(py_value, "f", &value);
+                       Py_DECREF(py_value);
+
+                       if(!result)
+                               return NULL;
+
+                       a.push_back(value);
+               }
+
+               if(a[0] == 0)
+                       a[0] = 1;
+       }
+       else
+               a.push_back(1);
+
+       Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
+
+       if(parent != NULL)
+       {
+               Py_INCREF(self);
+               parent->child_list = (PyObject*)self;
+
+               try
+               {
+                       parent->factory = new AUD_IIRFilterFactory(self->factory, b, a);
+               }
+               catch(AUD_Exception&)
+               {
+                       Py_DECREF(parent);
+                       PyErr_SetString(AUDError, "IIRFilterFactory couldn't be created!");
+                       return NULL;
+               }
+       }
+
+       return (PyObject *)parent;
+}
+
 // ========== Handle ==================================================
 
 static void
index 77961ec4d809ad602e9f9b99ff08674ff0589683..e894e0710113f8ce60ac4664380059ccc3ac5a4a 100644 (file)
@@ -1138,9 +1138,10 @@ int main(int argc, char **argv)
 
        else {
                if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
+               {
                        if(WM_init_game(C))
                                return 0;
-
+               }
                else if(!G.file_loaded)
                        WM_init_splash(C);
        }