Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/intern
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2010-08-02 02:33:50 +0400
committerJoerg Mueller <nexyon@gmail.com>2010-08-02 02:33:50 +0400
commit52ef66da4d785414e7ae5a60dd44a01727514169 (patch)
treecb9a26f84277abae1a4f47ef6f445a4ef0466587 /intern
parent5c9cf81cf98c99e52064b0cd45be3b2eaba9e40c (diff)
Audaspace:
* 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.
Diffstat (limited to 'intern')
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp25
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorReader.cpp85
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorReader.h73
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp76
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.h114
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp37
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.cpp109
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.h81
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp (renamed from intern/audaspace/FX/AUD_VolumeReader.cpp)32
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h83
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp40
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.cpp72
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.h82
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp25
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.cpp100
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.h81
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp (renamed from intern/audaspace/FX/AUD_RectifyReader.cpp)25
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h (renamed from intern/audaspace/FX/AUD_VolumeReader.h)39
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp (renamed from intern/audaspace/FX/AUD_RectifyReader.h)47
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h (renamed from intern/audaspace/FX/AUD_SumReader.h)36
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp25
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.cpp99
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.h81
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp11
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp23
-rw-r--r--intern/audaspace/FX/AUD_SquareReader.cpp57
-rw-r--r--intern/audaspace/FX/AUD_SquareReader.h63
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_SumReader.cpp57
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp7
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp119
31 files changed, 650 insertions, 1162 deletions
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
index 6e9130d174b..0c51e5241e4 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
@@ -24,7 +24,27 @@
*/
#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
index a8964edcac7..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorReader.cpp
+++ /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
index 68c1360731d..00000000000
--- a/intern/audaspace/FX/AUD_AccumulatorReader.h
+++ /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
index 00000000000..9e14bcf0e40
--- /dev/null
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
@@ -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
index 00000000000..7e2b71983a0
--- /dev/null
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
@@ -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
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
index 1bb1d726a98..874ff0f6351 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -24,7 +24,16 @@
*/
#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
index cfe4205c7f8..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthReader.cpp
+++ /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
index 52cbb642540..00000000000
--- a/intern/audaspace/FX/AUD_ButterworthReader.h
+++ /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
diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
index 7401b508b28..02ab6e185fe 100644
--- a/intern/audaspace/FX/AUD_VolumeReader.cpp
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
@@ -23,27 +23,25 @@
* ***** 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
index 00000000000..6472c7baad3
--- /dev/null
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
@@ -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
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
index 1c625067f1c..4777da70404 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
@@ -24,7 +24,31 @@
*/
#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
index ef64b6fa4eb..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeReader.cpp
+++ /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
index b452ee2119a..00000000000
--- a/intern/audaspace/FX/AUD_EnvelopeReader.h
+++ /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
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
index 1ab5237c8ff..d222e7f615e 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -24,7 +24,13 @@
*/
#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
index 904d6a95867..00000000000
--- a/intern/audaspace/FX/AUD_HighpassReader.cpp
+++ /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
index 845e764ac9f..00000000000
--- a/intern/audaspace/FX/AUD_HighpassReader.h
+++ /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
diff --git a/intern/audaspace/FX/AUD_RectifyReader.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
index c5bf73fac03..8cd49a03708 100644
--- a/intern/audaspace/FX/AUD_RectifyReader.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
@@ -23,26 +23,17 @@
* ***** 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);
}
diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
index 0e96a27e287..567d4f354fe 100644
--- a/intern/audaspace/FX/AUD_VolumeReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.h
@@ -23,41 +23,44 @@
* ***** 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
diff --git a/intern/audaspace/FX/AUD_RectifyReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
index 498f18e5041..120c9f8d0ae 100644
--- a/intern/audaspace/FX/AUD_RectifyReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
@@ -23,35 +23,28 @@
* ***** 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;
+}
diff --git a/intern/audaspace/FX/AUD_SumReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
index 0bb470bac97..303bc6d92df 100644
--- a/intern/audaspace/FX/AUD_SumReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.h
@@ -23,40 +23,44 @@
* ***** 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
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
index dfef0f6f7c3..9244e07631b 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -24,7 +24,13 @@
*/
#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
index 71b5de1234d..00000000000
--- a/intern/audaspace/FX/AUD_LowpassReader.cpp
+++ /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
index 66e4b91b783..00000000000
--- a/intern/audaspace/FX/AUD_LowpassReader.h
+++ /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
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
index 52608c3177b..2228f949dfe 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ b/intern/audaspace/FX/AUD_RectifyFactory.cpp
@@ -24,7 +24,14 @@
*/
#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);
}
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
index b95c9d9bb0f..c321a13d79a 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ b/intern/audaspace/FX/AUD_SquareFactory.cpp
@@ -24,7 +24,23 @@
*/
#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
index 4bf0d87f99b..00000000000
--- a/intern/audaspace/FX/AUD_SquareReader.cpp
+++ /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
index d3a5331b0e8..00000000000
--- a/intern/audaspace/FX/AUD_SquareReader.h
+++ /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
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
index 96ad286bf5c..a128e50504c 100644
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ b/intern/audaspace/FX/AUD_SumFactory.cpp
@@ -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
index 13f0e2271a6..00000000000
--- a/intern/audaspace/FX/AUD_SumReader.cpp
+++ /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];
-}
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
index 9f0fd5821fd..1b341a5a51a 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp
@@ -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);
}
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index dff7334e577..6c8f86dc6c5 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -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