From 52ef66da4d785414e7ae5a60dd44a01727514169 Mon Sep 17 00:00:00 2001 From: Joerg Mueller Date: Sun, 1 Aug 2010 22:33:50 +0000 Subject: 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. --- intern/audaspace/FX/AUD_AccumulatorFactory.cpp | 25 ++++- intern/audaspace/FX/AUD_AccumulatorReader.cpp | 85 --------------- intern/audaspace/FX/AUD_AccumulatorReader.h | 73 ------------- intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp | 76 +++++++++++++ intern/audaspace/FX/AUD_BaseIIRFilterReader.h | 114 ++++++++++++++++++++ intern/audaspace/FX/AUD_ButterworthFactory.cpp | 37 ++++++- intern/audaspace/FX/AUD_ButterworthReader.cpp | 109 ------------------- intern/audaspace/FX/AUD_ButterworthReader.h | 81 -------------- .../audaspace/FX/AUD_CallbackIIRFilterReader.cpp | 47 ++++++++ intern/audaspace/FX/AUD_CallbackIIRFilterReader.h | 83 ++++++++++++++ intern/audaspace/FX/AUD_EnvelopeFactory.cpp | 40 ++++++- intern/audaspace/FX/AUD_EnvelopeReader.cpp | 72 ------------- intern/audaspace/FX/AUD_EnvelopeReader.h | 82 -------------- intern/audaspace/FX/AUD_HighpassFactory.cpp | 25 ++++- intern/audaspace/FX/AUD_HighpassReader.cpp | 100 ----------------- intern/audaspace/FX/AUD_HighpassReader.h | 81 -------------- intern/audaspace/FX/AUD_IIRFilterFactory.cpp | 39 +++++++ intern/audaspace/FX/AUD_IIRFilterFactory.h | 66 ++++++++++++ intern/audaspace/FX/AUD_IIRFilterReader.cpp | 50 +++++++++ intern/audaspace/FX/AUD_IIRFilterReader.h | 66 ++++++++++++ intern/audaspace/FX/AUD_LowpassFactory.cpp | 25 ++++- intern/audaspace/FX/AUD_LowpassReader.cpp | 99 ----------------- intern/audaspace/FX/AUD_LowpassReader.h | 81 -------------- intern/audaspace/FX/AUD_RectifyFactory.cpp | 11 +- intern/audaspace/FX/AUD_RectifyReader.cpp | 48 --------- intern/audaspace/FX/AUD_RectifyReader.h | 57 ---------- intern/audaspace/FX/AUD_SquareFactory.cpp | 23 +++- intern/audaspace/FX/AUD_SquareReader.cpp | 57 ---------- intern/audaspace/FX/AUD_SquareReader.h | 63 ----------- intern/audaspace/FX/AUD_SumFactory.cpp | 8 +- intern/audaspace/FX/AUD_SumReader.cpp | 57 ---------- intern/audaspace/FX/AUD_SumReader.h | 62 ----------- intern/audaspace/FX/AUD_VolumeFactory.cpp | 7 +- intern/audaspace/FX/AUD_VolumeReader.cpp | 49 --------- intern/audaspace/FX/AUD_VolumeReader.h | 63 ----------- intern/audaspace/Python/AUD_PyAPI.cpp | 119 +++++++++++++++++++-- 36 files changed, 834 insertions(+), 1346 deletions(-) delete mode 100644 intern/audaspace/FX/AUD_AccumulatorReader.cpp delete mode 100644 intern/audaspace/FX/AUD_AccumulatorReader.h create mode 100644 intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp create mode 100644 intern/audaspace/FX/AUD_BaseIIRFilterReader.h delete mode 100644 intern/audaspace/FX/AUD_ButterworthReader.cpp delete mode 100644 intern/audaspace/FX/AUD_ButterworthReader.h create mode 100644 intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp create mode 100644 intern/audaspace/FX/AUD_CallbackIIRFilterReader.h delete mode 100644 intern/audaspace/FX/AUD_EnvelopeReader.cpp delete mode 100644 intern/audaspace/FX/AUD_EnvelopeReader.h delete mode 100644 intern/audaspace/FX/AUD_HighpassReader.cpp delete mode 100644 intern/audaspace/FX/AUD_HighpassReader.h create mode 100644 intern/audaspace/FX/AUD_IIRFilterFactory.cpp create mode 100644 intern/audaspace/FX/AUD_IIRFilterFactory.h create mode 100644 intern/audaspace/FX/AUD_IIRFilterReader.cpp create mode 100644 intern/audaspace/FX/AUD_IIRFilterReader.h delete mode 100644 intern/audaspace/FX/AUD_LowpassReader.cpp delete mode 100644 intern/audaspace/FX/AUD_LowpassReader.h delete mode 100644 intern/audaspace/FX/AUD_RectifyReader.cpp delete mode 100644 intern/audaspace/FX/AUD_RectifyReader.h delete mode 100644 intern/audaspace/FX/AUD_SquareReader.cpp delete mode 100644 intern/audaspace/FX/AUD_SquareReader.h delete mode 100644 intern/audaspace/FX/AUD_SumReader.cpp delete mode 100644 intern/audaspace/FX/AUD_SumReader.h delete mode 100644 intern/audaspace/FX/AUD_VolumeReader.cpp delete mode 100644 intern/audaspace/FX/AUD_VolumeReader.h (limited to 'intern') 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_AccumulatorReader.h" - -#include - -#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 . - * - * ***** 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 . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_BaseIIRFilterReader.h" + +#include + +#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 . + * + * ***** 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 + +#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 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_ButterworthReader.h" - -#include -#include - -#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 . - * - * ***** 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_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp new file mode 100644 index 00000000000..02ab6e185fe --- /dev/null +++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp @@ -0,0 +1,47 @@ +/* + * $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 . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_CallbackIIRFilterReader.h" + +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) +{ +} + +AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader() +{ + if(m_endFilter) + m_endFilter(m_data); +} + +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 . + * + * ***** 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 + +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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_EnvelopeReader.h" - -#include -#include - -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 . - * - * ***** 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 + +#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 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_HighpassReader.h" - -#include -#include - -#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 . - * - * ***** 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_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp new file mode 100644 index 00000000000..8cd49a03708 --- /dev/null +++ b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp @@ -0,0 +1,39 @@ +/* + * $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 . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_IIRFilterFactory.h" +#include "AUD_IIRFilterReader.h" + +AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory, + std::vector b, + std::vector a) : + AUD_EffectFactory(factory), m_a(a), m_b(b) +{ +} + +AUD_IReader* AUD_IIRFilterFactory::createReader() const +{ + return new AUD_IIRFilterReader(getReader(), m_b, m_a); +} diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h new file mode 100644 index 00000000000..567d4f354fe --- /dev/null +++ b/intern/audaspace/FX/AUD_IIRFilterFactory.h @@ -0,0 +1,66 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_IIRFILTERFACTORY +#define AUD_IIRFILTERFACTORY + +#include "AUD_EffectFactory.h" + +#include + +/** + * This factory creates a IIR filter reader. + */ +class AUD_IIRFilterFactory : public AUD_EffectFactory +{ +private: + /** + * Output filter coefficients. + */ + std::vector m_a; + + /** + * Input filter coefficients. + */ + std::vector m_b; + + // hide copy constructor and operator= + AUD_IIRFilterFactory(const AUD_IIRFilterFactory&); + AUD_IIRFilterFactory& operator=(const AUD_IIRFilterFactory&); + +public: + /** + * Creates a new IIR filter factory. + * \param factory The input factory. + * \param b The input filter coefficients. + * \param a The output filter coefficients. + */ + AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector b, + std::vector a); + + virtual AUD_IReader* createReader() const; +}; + +#endif //AUD_IIRFILTERFACTORY diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp new file mode 100644 index 00000000000..120c9f8d0ae --- /dev/null +++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp @@ -0,0 +1,50 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_IIRFilterReader.h" + +AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader, + std::vector b, + std::vector a) : + AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b) +{ + 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; +} + +sample_t AUD_IIRFilterReader::filter() +{ + sample_t out = 0; + + 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]; + + return out; +} diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h new file mode 100644 index 00000000000..303bc6d92df --- /dev/null +++ b/intern/audaspace/FX/AUD_IIRFilterReader.h @@ -0,0 +1,66 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see . + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_IIRFILTERREADER +#define AUD_IIRFILTERREADER + +#include "AUD_BaseIIRFilterReader.h" + +#include + +/** + * This class is for infinite impulse response filters with simple coefficients. + */ +class AUD_IIRFilterReader : public AUD_BaseIIRFilterReader +{ +private: + /** + * Output filter coefficients. + */ + std::vector m_a; + + /** + * Input filter coefficients. + */ + std::vector m_b; + + // hide copy constructor and operator= + AUD_IIRFilterReader(const AUD_IIRFilterReader&); + AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&); + +public: + /** + * 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_IIRFilterReader(AUD_IReader* reader, std::vector b, + std::vector a); + + virtual sample_t filter(); +}; + +#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 + +#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 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_LowpassReader.h" - -#include -#include - -#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 . - * - * ***** 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 + +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_RectifyReader.cpp b/intern/audaspace/FX/AUD_RectifyReader.cpp deleted file mode 100644 index c5bf73fac03..00000000000 --- a/intern/audaspace/FX/AUD_RectifyReader.cpp +++ /dev/null @@ -1,48 +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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_RectifyReader.h" - -#include - -AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) : - AUD_EffectReader(reader) -{ -} - -void AUD_RectifyReader::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++) - buffer[i] = fabs(buf[i]); -} diff --git a/intern/audaspace/FX/AUD_RectifyReader.h b/intern/audaspace/FX/AUD_RectifyReader.h deleted file mode 100644 index 498f18e5041..00000000000 --- a/intern/audaspace/FX/AUD_RectifyReader.h +++ /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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_RECTIFYREADER -#define AUD_RECTIFYREADER - -#include "AUD_EffectReader.h" -#include "AUD_Buffer.h" - -/** - * This class reads another reader and rectifies it. - */ -class AUD_RectifyReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer m_buffer; - - // hide copy constructor and operator= - AUD_RectifyReader(const AUD_RectifyReader&); - AUD_RectifyReader& operator=(const AUD_RectifyReader&); - -public: - /** - * Creates a new rectify reader. - * \param reader The reader to read from. - */ - AUD_RectifyReader(AUD_IReader* reader); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_RECTIFYREADER 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_SquareReader.h" - -#include - -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 . - * - * ***** 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 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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_SumReader.h" - -#include - -#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_SumReader.h b/intern/audaspace/FX/AUD_SumReader.h deleted file mode 100644 index 0bb470bac97..00000000000 --- a/intern/audaspace/FX/AUD_SumReader.h +++ /dev/null @@ -1,62 +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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_SUMREADER -#define AUD_SUMREADER - -#include "AUD_EffectReader.h" -#include "AUD_Buffer.h" - -/** - * This class represents an summer. - */ -class AUD_SumReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer m_buffer; - - /** - * The sums of the specific channels. - */ - AUD_Buffer m_sums; - - // hide copy constructor and operator= - AUD_SumReader(const AUD_SumReader&); - AUD_SumReader& operator=(const AUD_SumReader&); - -public: - /** - * Creates a new sum reader. - * \param reader The reader to read from. - */ - AUD_SumReader(AUD_IReader* reader); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_SUMREADER 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 a, b; + a.push_back(1); + b.push_back(m_volume); + return new AUD_IIRFilterReader(getReader(), b, a); } diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_VolumeReader.cpp deleted file mode 100644 index 7401b508b28..00000000000 --- a/intern/audaspace/FX/AUD_VolumeReader.cpp +++ /dev/null @@ -1,49 +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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#include "AUD_VolumeReader.h" - -#include - -AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) : - AUD_EffectReader(reader), - m_volume(volume) -{ -} - -void AUD_VolumeReader::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++) - buffer[i] = buf[i] * m_volume; -} diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_VolumeReader.h deleted file mode 100644 index 0e96a27e287..00000000000 --- a/intern/audaspace/FX/AUD_VolumeReader.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 . - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_VOLUMEREADER -#define AUD_VOLUMEREADER - -#include "AUD_EffectReader.h" -#include "AUD_Buffer.h" - -/** - * This class reads another reader and changes it's volume. - */ -class AUD_VolumeReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer m_buffer; - - /** - * The volume level. - */ - const float m_volume; - - // hide copy constructor and operator= - AUD_VolumeReader(const AUD_VolumeReader&); - AUD_VolumeReader& operator=(const AUD_VolumeReader&); - -public: - /** - * Creates a new volume reader. - * \param reader The reader to read from. - * \param volume The size of the buffer. - */ - AUD_VolumeReader(AUD_IReader* reader, float volume); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_VOLUMEREADER 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 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 -- cgit v1.2.3