diff options
Diffstat (limited to 'intern/audaspace/FX')
77 files changed, 1438 insertions, 2098 deletions
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp index 20709c57ee5..0c51e5241e4 100644 --- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp +++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp @@ -24,26 +24,37 @@ */ #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) : AUD_EffectFactory(factory), - m_additive(additive) {} - -AUD_AccumulatorFactory::AUD_AccumulatorFactory(bool additive) : - AUD_EffectFactory(0), - m_additive(additive) {} - -AUD_IReader* AUD_AccumulatorFactory::createReader() + m_additive(additive) { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_AccumulatorReader(reader, m_additive); - AUD_NEW("reader") - } +} - return reader; +AUD_IReader* AUD_AccumulatorFactory::createReader() const +{ + return new AUD_CallbackIIRFilterReader(getReader(), 2, 2, + m_additive ? accumulatorFilterAdditive : accumulatorFilter); } diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h index e475a19ccf6..2b90fa43bdf 100644 --- a/intern/audaspace/FX/AUD_AccumulatorFactory.h +++ b/intern/audaspace/FX/AUD_AccumulatorFactory.h @@ -37,7 +37,11 @@ private: /** * Whether the accumulator is additive. */ - bool m_additive; + const bool m_additive; + + // hide copy constructor and operator= + AUD_AccumulatorFactory(const AUD_AccumulatorFactory&); + AUD_AccumulatorFactory& operator=(const AUD_AccumulatorFactory&); public: /** @@ -47,13 +51,7 @@ public: */ AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false); - /** - * Creates a new accumulator factory. - * \param additive Whether the accumulator is additive. - */ - AUD_AccumulatorFactory(bool additive = false); - - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_ACCUMULATORFACTORY diff --git a/intern/audaspace/FX/AUD_AccumulatorReader.cpp b/intern/audaspace/FX/AUD_AccumulatorReader.cpp deleted file mode 100644 index 67ab4157f9c..00000000000 --- a/intern/audaspace/FX/AUD_AccumulatorReader.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_AccumulatorReader.h" -#include "AUD_Buffer.h" - -#include <cstring> - -#define CC specs.channels + channel - -AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader, - bool additive) : - AUD_EffectReader(reader), - m_additive(additive) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer") - memset(m_sums->getBuffer(), 0, samplesize); - - m_prevs = new AUD_Buffer(samplesize); AUD_NEW("buffer") - memset(m_prevs->getBuffer(), 0, samplesize); -} - -AUD_AccumulatorReader::~AUD_AccumulatorReader() -{ - delete m_buffer; AUD_DELETE("buffer") - delete m_sums; AUD_DELETE("buffer") - delete m_prevs; AUD_DELETE("buffer") -} - -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 * specs.channels; 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 8ad1dda30f6..00000000000 --- a/intern/audaspace/FX/AUD_AccumulatorReader.h +++ /dev/null @@ -1,75 +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" -class AUD_Buffer; - -/** - * This class represents an accumulator. - */ -class AUD_AccumulatorReader : public AUD_EffectReader -{ -private: - /** - * 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; - - /** - * Whether the accumulator is additive. - */ - bool m_additive; - -public: - /** - * Creates a new accumulator reader. - * \param reader The reader to read from. - * \param additive Whether the accumulator is additive. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_AccumulatorReader(AUD_IReader* reader, bool additive); - - /** - * Destroys the reader. - */ - virtual ~AUD_AccumulatorReader(); - - virtual void read(int & length, sample_t* & buffer); -}; - -#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 fd0a53def7c..874ff0f6351 100644 --- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp +++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp @@ -24,26 +24,49 @@ */ #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) : AUD_EffectFactory(factory), - m_frequency(frequency) {} - -AUD_ButterworthFactory::AUD_ButterworthFactory(float frequency) : - AUD_EffectFactory(0), - m_frequency(frequency) {} + m_frequency(frequency) +{ +} -AUD_IReader* AUD_ButterworthFactory::createReader() +AUD_IReader* AUD_ButterworthFactory::createReader() const { AUD_IReader* reader = getReader(); - if(reader != 0) - { - reader = new AUD_ButterworthReader(reader, m_frequency); - AUD_NEW("reader") - } + // 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 reader; + return new AUD_IIRFilterReader(reader, b, a); } diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h index 69169531d70..30b7a402c57 100644 --- a/intern/audaspace/FX/AUD_ButterworthFactory.h +++ b/intern/audaspace/FX/AUD_ButterworthFactory.h @@ -37,7 +37,11 @@ private: /** * The attack value in seconds. */ - float m_frequency; + const float m_frequency; + + // hide copy constructor and operator= + AUD_ButterworthFactory(const AUD_ButterworthFactory&); + AUD_ButterworthFactory& operator=(const AUD_ButterworthFactory&); public: /** @@ -47,13 +51,7 @@ public: */ AUD_ButterworthFactory(AUD_IFactory* factory, float frequency); - /** - * Creates a new butterworth factory. - * \param frequency The cutoff frequency. - */ - AUD_ButterworthFactory(float frequency); - - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_BUTTERWORTHFACTORY diff --git a/intern/audaspace/FX/AUD_ButterworthReader.cpp b/intern/audaspace/FX/AUD_ButterworthReader.cpp deleted file mode 100644 index 2129dfef798..00000000000 --- a/intern/audaspace/FX/AUD_ButterworthReader.cpp +++ /dev/null @@ -1,124 +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 "AUD_Buffer.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) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_outvalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer") - memset(m_outvalues->getBuffer(), 0, samplesize * 5); - - m_invalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer") - memset(m_invalues->getBuffer(), 0, samplesize * 5); - - m_position = 0; - - // calculate coefficients - float omega = 2 * tan(frequency * M_PI / specs.rate); - float o2 = omega * omega; - float o4 = o2 * o2; - float x1 = o2 + 2 * BWPB41 * omega + 4; - float x2 = o2 + 2 * BWPB42 * omega + 4; - float y1 = o2 - 2 * BWPB41 * omega + 4; - float y2 = o2 - 2 * BWPB42 * omega + 4; - float o228 = 2 * o2 - 8; - float norm = x1 * x2; - m_coeff[0][0] = 0; - m_coeff[0][1] = (x1 + x2) * o228 / norm; - m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm; - m_coeff[0][3] = (y1 + y2) * o228 / norm; - m_coeff[0][4] = y1 * y2 / norm; - m_coeff[1][4] = m_coeff[1][0] = o4 / norm; - m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm; - m_coeff[1][2] = 6 * o4 / norm; -} - -AUD_ButterworthReader::~AUD_ButterworthReader() -{ - delete m_buffer; AUD_DELETE("buffer") - - delete m_outvalues; AUD_DELETE("buffer") - delete m_invalues; AUD_DELETE("buffer"); -} - -void AUD_ButterworthReader::read(int & length, sample_t* & buffer) -{ - sample_t* buf; - sample_t* outvalues; - sample_t* invalues; - - outvalues = m_outvalues->getBuffer(); - invalues = m_invalues->getBuffer(); - - AUD_Specs specs = m_reader->getSpecs(); - - m_reader->read(length, buf); - - if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) - m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); - - buffer = m_buffer->getBuffer(); - int channels = specs.channels; - - for(int channel = 0; channel < channels; channel++) - { - for(int i = 0; i < length; i++) - { - invalues[m_position * CC] = buf[i * CC]; - outvalues[m_position * CC] = 0; - - for(int j = 0; j < 4; j++) - { - outvalues[m_position * CC] += m_coeff[1][j] * - invalues[((m_position + j) % 5) * CC] - - m_coeff[0][j] * - outvalues[((m_position + j) % 5) * CC]; - } - - buffer[i * CC] = outvalues[m_position * CC]; - - m_position = (m_position + 4) % 5; - } - } -} diff --git a/intern/audaspace/FX/AUD_ButterworthReader.h b/intern/audaspace/FX/AUD_ButterworthReader.h deleted file mode 100644 index b1cbd4e3820..00000000000 --- a/intern/audaspace/FX/AUD_ButterworthReader.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_BUTTERWORTHREADER -#define AUD_BUTTERWORTHREADER - -#include "AUD_EffectReader.h" -class AUD_Buffer; - -/** - * This class represents a butterworth filter. - */ -class AUD_ButterworthReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; - - /** - * The last out values buffer. - */ - AUD_Buffer *m_outvalues; - - /** - * The last in values buffer. - */ - AUD_Buffer *m_invalues; - - /** - * The position for buffer cycling. - */ - int m_position; - - /** - * Filter coefficients. - */ - float m_coeff[2][5]; - -public: - /** - * Creates a new butterworth reader. - * \param reader The reader to read from. - * \param attack The attack value in seconds. - * \param release The release value in seconds. - * \param threshold The threshold value. - * \param arthreshold The attack/release threshold value. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_ButterworthReader(AUD_IReader* reader, float frequency); - - /** - * Destroys the reader. - */ - virtual ~AUD_ButterworthReader(); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_BUTTERWORTHREADER diff --git a/intern/audaspace/FX/AUD_RectifyReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp index 5d3ce80e811..02ab6e185fe 100644 --- a/intern/audaspace/FX/AUD_RectifyReader.cpp +++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp @@ -23,33 +23,25 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#include "AUD_RectifyReader.h" -#include "AUD_Buffer.h" - -#include <cmath> - -AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) : - AUD_EffectReader(reader) +#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) { - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") } -AUD_RectifyReader::~AUD_RectifyReader() +AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader() { - delete m_buffer; AUD_DELETE("buffer") + if(m_endFilter) + m_endFilter(m_data); } -void AUD_RectifyReader::read(int & length, sample_t* & buffer) +sample_t AUD_CallbackIIRFilterReader::filter() { - 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 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_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp index 25ce4faed4c..f98743d6fb7 100644 --- a/intern/audaspace/FX/AUD_DelayFactory.cpp +++ b/intern/audaspace/FX/AUD_DelayFactory.cpp @@ -29,30 +29,16 @@ AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) : AUD_EffectFactory(factory), - m_delay(delay) {} - -AUD_DelayFactory::AUD_DelayFactory(float delay) : - AUD_EffectFactory(0), - m_delay(delay) {} - -float AUD_DelayFactory::getDelay() + m_delay(delay) { - return m_delay; } -void AUD_DelayFactory::setDelay(float delay) +float AUD_DelayFactory::getDelay() const { - m_delay = delay; + return m_delay; } -AUD_IReader* AUD_DelayFactory::createReader() +AUD_IReader* AUD_DelayFactory::createReader() const { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_DelayReader(reader, m_delay); AUD_NEW("reader") - } - - return reader; + return new AUD_DelayReader(getReader(), m_delay); } diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h index 5ad4b9ab996..721262fb73f 100644 --- a/intern/audaspace/FX/AUD_DelayFactory.h +++ b/intern/audaspace/FX/AUD_DelayFactory.h @@ -37,7 +37,11 @@ private: /** * The delay in samples. */ - float m_delay; + const float m_delay; + + // hide copy constructor and operator= + AUD_DelayFactory(const AUD_DelayFactory&); + AUD_DelayFactory& operator=(const AUD_DelayFactory&); public: /** @@ -45,26 +49,14 @@ public: * \param factory The input factory. * \param delay The desired delay in seconds. */ - AUD_DelayFactory(AUD_IFactory* factory = 0, float delay = 0); - - /** - * Creates a new delay factory. - * \param delay The desired delay in seconds. - */ - AUD_DelayFactory(float delay); + AUD_DelayFactory(AUD_IFactory* factory, float delay = 0); /** * Returns the delay in seconds. */ - float getDelay(); - - /** - * Sets the delay. - * \param delay The new delay value in seconds. - */ - void setDelay(float delay); + float getDelay() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_DELAYFACTORY diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp index f2521f645aa..e9f0c15b9b4 100644 --- a/intern/audaspace/FX/AUD_DelayReader.cpp +++ b/intern/audaspace/FX/AUD_DelayReader.cpp @@ -24,28 +24,19 @@ */ #include "AUD_DelayReader.h" -#include "AUD_Buffer.h" #include <cstring> AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) : - AUD_EffectReader(reader) + AUD_EffectReader(reader), + m_delay(int(delay * reader->getSpecs().rate)), + m_remdelay(int(delay * reader->getSpecs().rate)), + m_empty(true) { - m_delay = (int)(delay * reader->getSpecs().rate); - m_remdelay = m_delay; - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_DelayReader::~AUD_DelayReader() -{ - delete m_buffer; AUD_DELETE("buffer") } void AUD_DelayReader::seek(int position) { - if(position < 0) - return; - if(position < m_delay) { m_remdelay = m_delay - position; @@ -58,18 +49,18 @@ void AUD_DelayReader::seek(int position) } } -int AUD_DelayReader::getLength() +int AUD_DelayReader::getLength() const { int len = m_reader->getLength(); if(len < 0) return len; - return len+m_delay; + return len + m_delay; } -int AUD_DelayReader::getPosition() +int AUD_DelayReader::getPosition() const { if(m_remdelay > 0) - return m_delay-m_remdelay; + return m_delay - m_remdelay; return m_reader->getPosition() + m_delay; } @@ -80,26 +71,41 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer) AUD_Specs specs = m_reader->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); - if(m_buffer->getSize() < length * samplesize) - m_buffer->resize(length * samplesize); + if(m_buffer.getSize() < length * samplesize) + { + m_buffer.resize(length * samplesize); + m_empty = false; + } + + buffer = m_buffer.getBuffer(); if(length > m_remdelay) { - memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize); + if(!m_empty) + memset(buffer, 0, m_remdelay * samplesize); + int len = length - m_remdelay; - m_reader->read(len, buffer); - memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels, - buffer, len * samplesize); + sample_t* buf; + m_reader->read(len, buf); + + memcpy(buffer + m_remdelay * specs.channels, + buf, len * samplesize); + if(len < length-m_remdelay) length = m_remdelay + len; + m_remdelay = 0; + m_empty = false; } else { - memset(m_buffer->getBuffer(), 0, length * samplesize); + if(!m_empty) + { + memset(buffer, 0, length * samplesize); + m_empty = true; + } m_remdelay -= length; } - buffer = m_buffer->getBuffer(); } else m_reader->read(length, buffer); diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h index 4662b455dfc..121842b0c6b 100644 --- a/intern/audaspace/FX/AUD_DelayReader.h +++ b/intern/audaspace/FX/AUD_DelayReader.h @@ -27,7 +27,7 @@ #define AUD_DELAYREADER #include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_Buffer.h" /** * This class reads another reader and changes it's delay. @@ -38,35 +38,38 @@ private: /** * The playback buffer. */ - AUD_Buffer *m_buffer; + AUD_Buffer m_buffer; /** * The delay level. */ - int m_delay; + const int m_delay; /** * The remaining delay for playback. */ int m_remdelay; + /** + * Whether the buffer is currently filled with zeros. + */ + bool m_empty; + + // hide copy constructor and operator= + AUD_DelayReader(const AUD_DelayReader&); + AUD_DelayReader& operator=(const AUD_DelayReader&); + public: /** * Creates a new delay reader. * \param reader The reader to read from. * \param delay The delay in seconds. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_DelayReader(AUD_IReader* reader, float delay); - /** - * Destroys the reader. - */ - virtual ~AUD_DelayReader(); - virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); + virtual int getLength() const; + virtual int getPosition() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_RectifyReader.h b/intern/audaspace/FX/AUD_DoubleFactory.cpp index afbe2e59cab..9f625d0763f 100644 --- a/intern/audaspace/FX/AUD_RectifyReader.h +++ b/intern/audaspace/FX/AUD_DoubleFactory.cpp @@ -23,37 +23,28 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#ifndef AUD_RECTIFYREADER -#define AUD_RECTIFYREADER +#include "AUD_DoubleFactory.h" +#include "AUD_DoubleReader.h" -#include "AUD_EffectReader.h" -class AUD_Buffer; - -/** - * This class reads another reader and rectifies it. - */ -class AUD_RectifyReader : public AUD_EffectReader +AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) : + m_factory1(factory1), m_factory2(factory2) { -private: - /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; +} -public: - /** - * Creates a new rectify reader. - * \param reader The reader to read from. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_RectifyReader(AUD_IReader* reader); - - /** - * Destroys the reader. - */ - virtual ~AUD_RectifyReader(); +AUD_IReader* AUD_DoubleFactory::createReader() const +{ + AUD_IReader* reader1 = m_factory1->createReader(); + AUD_IReader* reader2; - virtual void read(int & length, sample_t* & buffer); -}; + try + { + reader2 = m_factory2->createReader(); + } + catch(AUD_Exception&) + { + delete reader1; + throw; + } -#endif //AUD_RECTIFYREADER + return new AUD_DoubleReader(reader1, reader2); +} diff --git a/intern/audaspace/FX/AUD_SquareReader.h b/intern/audaspace/FX/AUD_DoubleFactory.h index 63dda351445..f2e83b2e27a 100644 --- a/intern/audaspace/FX/AUD_SquareReader.h +++ b/intern/audaspace/FX/AUD_DoubleFactory.h @@ -23,43 +23,41 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#ifndef AUD_SQUAREREADER -#define AUD_SQUAREREADER +#ifndef AUD_DOUBLEFACTORY +#define AUD_DOUBLEFACTORY -#include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_IFactory.h" /** - * This class changes another signal into a square signal. + * This factory plays two other factories behind each other. + * \note Readers from the underlying factories must have the same sample rate and channel count. */ -class AUD_SquareReader : public AUD_EffectReader +class AUD_DoubleFactory : public AUD_IFactory { private: /** - * The playback buffer. + * First played factory. */ - AUD_Buffer *m_buffer; + AUD_IFactory* m_factory1; /** - * The threshold level. + * Second played factory. */ - float m_threshold; + AUD_IFactory* m_factory2; -public: - /** - * Creates a new square reader. - * \param reader The reader to read from. - * \param threshold The size of the buffer. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_SquareReader(AUD_IReader* reader, float threshold); + // hide copy constructor and operator= + AUD_DoubleFactory(const AUD_DoubleFactory&); + AUD_DoubleFactory& operator=(const AUD_DoubleFactory&); +public: /** - * Destroys the reader. + * Creates a new double factory. + * \param factory1 The first input factory. + * \param factory2 The second input factory. */ - virtual ~AUD_SquareReader(); + AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2); - virtual void read(int & length, sample_t* & buffer); + virtual AUD_IReader* createReader() const; }; -#endif //AUD_SQUAREREADER +#endif //AUD_DOUBLEFACTORY diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 1e51a094427..5c6ca6a1fc5 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -24,80 +24,51 @@ */ #include "AUD_DoubleReader.h" -#include "AUD_Buffer.h" #include <cstring> +static const char* specs_error = "AUD_DoubleReader: Both readers have to have " + "the same specs."; + AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2) : - m_reader1(reader1), m_reader2(reader2) + m_reader1(reader1), m_reader2(reader2), m_finished1(false) { - try - { - if(!reader1) - AUD_THROW(AUD_ERROR_READER); - - if(!reader2) - AUD_THROW(AUD_ERROR_READER); - - AUD_Specs s1, s2; - s1 = reader1->getSpecs(); - s2 = reader2->getSpecs(); - if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0) - AUD_THROW(AUD_ERROR_READER); - } - - catch(AUD_Exception) + AUD_Specs s1, s2; + s1 = reader1->getSpecs(); + s2 = reader2->getSpecs(); + if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0) { - if(reader1) - { - delete reader1; AUD_DELETE("reader") - } - if(reader2) - { - delete reader2; AUD_DELETE("reader") - } - - throw; + delete reader1; + delete reader2; + AUD_THROW(AUD_ERROR_SPECS, specs_error); } - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - m_finished1 = false; } AUD_DoubleReader::~AUD_DoubleReader() { - delete m_reader1; AUD_DELETE("reader") - delete m_reader2; AUD_DELETE("reader") - delete m_buffer; AUD_DELETE("buffer") + delete m_reader1; + delete m_reader2; } -bool AUD_DoubleReader::isSeekable() +bool AUD_DoubleReader::isSeekable() const { - return false; + return m_reader1->isSeekable() && m_reader2->isSeekable(); } void AUD_DoubleReader::seek(int position) { - int length1 = m_reader1->getLength(); + m_reader1->seek(position); - if(position < 0) - position = 0; + int pos1 = m_reader1->getPosition(); - if(position < length1) - { - m_reader1->seek(position); - m_reader2->seek(0); - m_finished1 = false; - } + if((m_finished1 = (pos1 < position))) + m_reader2->seek(position - pos1); else - { - m_reader2->seek(position-length1); - m_finished1 = true; - } + m_reader2->seek(0); } -int AUD_DoubleReader::getLength() +int AUD_DoubleReader::getLength() const { int len1 = m_reader1->getLength(); int len2 = m_reader2->getLength(); @@ -106,49 +77,45 @@ int AUD_DoubleReader::getLength() return len1 + len2; } -int AUD_DoubleReader::getPosition() +int AUD_DoubleReader::getPosition() const { return m_reader1->getPosition() + m_reader2->getPosition(); } -AUD_Specs AUD_DoubleReader::getSpecs() +AUD_Specs AUD_DoubleReader::getSpecs() const { return m_reader1->getSpecs(); } -AUD_ReaderType AUD_DoubleReader::getType() -{ - if(m_reader1->getType() == AUD_TYPE_BUFFER && - m_reader2->getType() == AUD_TYPE_BUFFER) - return AUD_TYPE_BUFFER; - return AUD_TYPE_STREAM; -} - -bool AUD_DoubleReader::notify(AUD_Message &message) -{ - return m_reader1->notify(message) | m_reader2->notify(message); -} - void AUD_DoubleReader::read(int & length, sample_t* & buffer) { if(!m_finished1) { int len = length; m_reader1->read(len, buffer); + if(len < length) { AUD_Specs specs = m_reader1->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); - if(m_buffer->getSize() < length * samplesize) - m_buffer->resize(length * samplesize); - memcpy(m_buffer->getBuffer(), buffer, len * samplesize); + + if(m_buffer.getSize() < length * samplesize) + m_buffer.resize(length * samplesize); + + sample_t* buf = buffer; + buffer = m_buffer.getBuffer(); + + memcpy(buffer, buf, len * samplesize); + len = length - len; length -= len; - m_reader2->read(len, buffer); - memcpy(m_buffer->getBuffer() + length * specs.channels, buffer, + m_reader2->read(len, buf); + + memcpy(buffer + length * specs.channels, buf, len * samplesize); + length += len; - buffer = m_buffer->getBuffer(); + m_finished1 = true; } } diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h index d82b81ec0ba..d80ba33dfe3 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.h +++ b/intern/audaspace/FX/AUD_DoubleReader.h @@ -27,7 +27,7 @@ #define AUD_DOUBLEREADER #include "AUD_IReader.h" -class AUD_Buffer; +#include "AUD_Buffer.h" /** * This reader plays two readers with the same specs sequently. @@ -53,15 +53,18 @@ private: /** * The playback buffer for the intersecting part. */ - AUD_Buffer* m_buffer; + AUD_Buffer m_buffer; + + // hide copy constructor and operator= + AUD_DoubleReader(const AUD_DoubleReader&); + AUD_DoubleReader& operator=(const AUD_DoubleReader&); public: /** * Creates a new ping pong reader. * \param reader1 The first reader to read from. * \param reader2 The second reader to read from. - * \exception AUD_Exception Thrown if one of the reader specified is NULL - * or the specs from the readers differ. + * \exception AUD_Exception Thrown if the specs from the readers differ. */ AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2); @@ -70,13 +73,11 @@ public: */ virtual ~AUD_DoubleReader(); - virtual bool isSeekable(); + virtual bool isSeekable() const; virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); - virtual AUD_Specs getSpecs(); - virtual AUD_ReaderType getType(); - virtual bool notify(AUD_Message &message); + virtual int getLength() const; + virtual int getPosition() const; + virtual AUD_Specs getSpecs() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp index 882499416b7..eda4e4e04b2 100644 --- a/intern/audaspace/FX/AUD_EffectFactory.cpp +++ b/intern/audaspace/FX/AUD_EffectFactory.cpp @@ -26,25 +26,16 @@ #include "AUD_EffectFactory.h" #include "AUD_IReader.h" -AUD_IReader* AUD_EffectFactory::getReader() -{ - if(m_factory != 0) - return m_factory->createReader(); - - return 0; -} - AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory) { m_factory = factory; } -void AUD_EffectFactory::setFactory(AUD_IFactory* factory) +AUD_EffectFactory::~AUD_EffectFactory() { - m_factory = factory; } -AUD_IFactory* AUD_EffectFactory::getFactory() +AUD_IFactory* AUD_EffectFactory::getFactory() const { return m_factory; } diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h index 67259b9e6c3..fd3746d0da3 100644 --- a/intern/audaspace/FX/AUD_EffectFactory.h +++ b/intern/audaspace/FX/AUD_EffectFactory.h @@ -34,6 +34,11 @@ */ class AUD_EffectFactory : public AUD_IFactory { +private: + // hide copy constructor and operator= + AUD_EffectFactory(const AUD_EffectFactory&); + AUD_EffectFactory& operator=(const AUD_EffectFactory&); + protected: /** * If there is no reader it is created out of this factory. @@ -44,9 +49,12 @@ protected: * Returns the reader created out of the factory. * This method can be used for the createReader function of the implementing * classes. - * \return The reader created out of the factory or NULL if there is none. + * \return The reader created out of the factory. */ - AUD_IReader* getReader(); + inline AUD_IReader* getReader() const + { + return m_factory->createReader(); + } public: /** @@ -58,19 +66,13 @@ public: /** * Destroys the factory. */ - virtual ~AUD_EffectFactory() {} - - /** - * Sets the input factory. - * \param factory The input factory. - */ - void setFactory(AUD_IFactory* factory); + virtual ~AUD_EffectFactory(); /** * Returns the saved factory. * \return The factory or NULL if there has no factory been saved. */ - AUD_IFactory* getFactory(); + AUD_IFactory* getFactory() const; }; #endif //AUD_EFFECTFACTORY diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp index 47026b88440..b54ca279088 100644 --- a/intern/audaspace/FX/AUD_EffectReader.cpp +++ b/intern/audaspace/FX/AUD_EffectReader.cpp @@ -27,17 +27,15 @@ AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader) { - if(!reader) - AUD_THROW(AUD_ERROR_READER); m_reader = reader; } AUD_EffectReader::~AUD_EffectReader() { - delete m_reader; AUD_DELETE("reader") + delete m_reader; } -bool AUD_EffectReader::isSeekable() +bool AUD_EffectReader::isSeekable() const { return m_reader->isSeekable(); } @@ -47,31 +45,21 @@ void AUD_EffectReader::seek(int position) m_reader->seek(position); } -int AUD_EffectReader::getLength() +int AUD_EffectReader::getLength() const { return m_reader->getLength(); } -int AUD_EffectReader::getPosition() +int AUD_EffectReader::getPosition() const { return m_reader->getPosition(); } -AUD_Specs AUD_EffectReader::getSpecs() +AUD_Specs AUD_EffectReader::getSpecs() const { return m_reader->getSpecs(); } -AUD_ReaderType AUD_EffectReader::getType() -{ - return m_reader->getType(); -} - -bool AUD_EffectReader::notify(AUD_Message &message) -{ - return m_reader->notify(message); -} - void AUD_EffectReader::read(int & length, sample_t* & buffer) { m_reader->read(length, buffer); diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h index f64bf34077d..c447f79bc6e 100644 --- a/intern/audaspace/FX/AUD_EffectReader.h +++ b/intern/audaspace/FX/AUD_EffectReader.h @@ -34,6 +34,11 @@ */ class AUD_EffectReader : public AUD_IReader { +private: + // hide copy constructor and operator= + AUD_EffectReader(const AUD_EffectReader&); + AUD_EffectReader& operator=(const AUD_EffectReader&); + protected: /** * The reader to read from. @@ -44,7 +49,6 @@ public: /** * Creates a new effect reader. * \param reader The reader to read from. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_EffectReader(AUD_IReader* reader); @@ -53,13 +57,11 @@ public: */ virtual ~AUD_EffectReader(); - virtual bool isSeekable(); + virtual bool isSeekable() const; virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); - virtual AUD_Specs getSpecs(); - virtual AUD_ReaderType getType(); - virtual bool notify(AUD_Message &message); + virtual int getLength() const; + virtual int getPosition() const; + virtual AUD_Specs getSpecs() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp index c3b2c3f24fe..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, @@ -33,26 +57,22 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, m_attack(attack), m_release(release), m_threshold(threshold), - m_arthreshold(arthreshold) {} - -AUD_EnvelopeFactory::AUD_EnvelopeFactory(float attack, float release, - float threshold, float arthreshold) : - AUD_EffectFactory(0), - m_attack(attack), - m_release(release), - m_threshold(threshold), - m_arthreshold(arthreshold) {} + m_arthreshold(arthreshold) +{ +} -AUD_IReader* AUD_EnvelopeFactory::createReader() +AUD_IReader* AUD_EnvelopeFactory::createReader() const { AUD_IReader* reader = getReader(); - if(reader != 0) - { - reader = new AUD_EnvelopeReader(reader, m_attack, m_release, - m_threshold, m_arthreshold); - AUD_NEW("reader") - } + 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 reader; + return new AUD_CallbackIIRFilterReader(reader, 1, 2, + (doFilterIIR) envelopeFilter, + (endFilterIIR) endEnvelopeFilter, + param); } diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h index c79e5472e30..c31c6727d03 100644 --- a/intern/audaspace/FX/AUD_EnvelopeFactory.h +++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h @@ -37,22 +37,26 @@ private: /** * The attack value in seconds. */ - float m_attack; + const float m_attack; /** * The release value in seconds. */ - float m_release; + const float m_release; /** * The threshold value. */ - float m_threshold; + const float m_threshold; /** * The attack/release threshold value. */ - float m_arthreshold; + const float m_arthreshold; + + // hide copy constructor and operator= + AUD_EnvelopeFactory(const AUD_EnvelopeFactory&); + AUD_EnvelopeFactory& operator=(const AUD_EnvelopeFactory&); public: /** @@ -66,17 +70,7 @@ public: AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release, float threshold, float arthreshold); - /** - * Creates a new envelope factory. - * \param attack The attack value in seconds. - * \param release The release value in seconds. - * \param threshold The threshold value. - * \param arthreshold The attack/release threshold value. - */ - AUD_EnvelopeFactory(float attack, float release, float threshold, - float arthreshold); - - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_ENVELOPEFACTORY diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.cpp b/intern/audaspace/FX/AUD_EnvelopeReader.cpp deleted file mode 100644 index 71ccbfd6503..00000000000 --- a/intern/audaspace/FX/AUD_EnvelopeReader.cpp +++ /dev/null @@ -1,86 +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 "AUD_Buffer.h" - -#include <cstring> -#include <cmath> - -AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack, - float release, float threshold, - float arthreshold) : - AUD_EffectReader(reader), - m_threshold(threshold) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_envelopes = new AUD_Buffer(samplesize); - AUD_NEW("buffer") - memset(m_envelopes->getBuffer(), 0, samplesize); - - m_bAttack = pow(arthreshold, 1.0f/(specs.rate * attack)); - m_bRelease = pow(arthreshold, 1.0f/(specs.rate * release)); -} - -AUD_EnvelopeReader::~AUD_EnvelopeReader() -{ - delete m_buffer; AUD_DELETE("buffer") - delete m_envelopes; AUD_DELETE("buffer") -} - -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 ff9dd23d34c..00000000000 --- a/intern/audaspace/FX/AUD_EnvelopeReader.h +++ /dev/null @@ -1,84 +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" -class AUD_Buffer; - -/** - * This class represents an envelope follower. - */ -class AUD_EnvelopeReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; - - /** - * The last envelopes buffer. - */ - AUD_Buffer *m_envelopes; - - /** - * Attack b value. - */ - float m_bAttack; - - /** - * Release b value. - */ - float m_bRelease; - - /** - * Threshold value. - */ - float m_threshold; - -public: - /** - * Creates a new envelope reader. - * \param reader The reader to read from. - * \param attack The attack value in seconds. - * \param release The release value in seconds. - * \param threshold The threshold value. - * \param arthreshold The attack/release threshold value. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release, - float threshold, float arthreshold); - - /** - * Destroys the reader. - */ - virtual ~AUD_EnvelopeReader(); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_ENVELOPEREADER diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp index 4357e11bd43..bbe9319c928 100644 --- a/intern/audaspace/FX/AUD_FaderFactory.cpp +++ b/intern/audaspace/FX/AUD_FaderFactory.cpp @@ -31,54 +31,26 @@ AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type, AUD_EffectFactory(factory), m_type(type), m_start(start), - m_length(length) {} - -AUD_FaderFactory::AUD_FaderFactory(AUD_FadeType type, - float start, float length) : - AUD_EffectFactory(0), - m_type(type), - m_start(start), - m_length(length) {} - -AUD_FadeType AUD_FaderFactory::getType() + m_length(length) { - return m_type; } -void AUD_FaderFactory::setType(AUD_FadeType type) +AUD_FadeType AUD_FaderFactory::getType() const { - m_type = type; + return m_type; } -float AUD_FaderFactory::getStart() +float AUD_FaderFactory::getStart() const { return m_start; } -void AUD_FaderFactory::setStart(float start) -{ - m_start = start; -} - -float AUD_FaderFactory::getLength() +float AUD_FaderFactory::getLength() const { return m_length; } -void AUD_FaderFactory::setLength(float length) +AUD_IReader* AUD_FaderFactory::createReader() const { - m_length = length; -} - -AUD_IReader* AUD_FaderFactory::createReader() -{ - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_FaderReader(reader, m_type, m_start, m_length); - AUD_NEW("reader") - } - - return reader; + return new AUD_FaderReader(getReader(), m_type, m_start, m_length); } diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h index 4999ccac8f1..af5d18538ea 100644 --- a/intern/audaspace/FX/AUD_FaderFactory.h +++ b/intern/audaspace/FX/AUD_FaderFactory.h @@ -39,17 +39,21 @@ private: /** * The fading type. */ - AUD_FadeType m_type; + const AUD_FadeType m_type; /** * The fading start. */ - float m_start; + const float m_start; /** * The fading length. */ - float m_length; + const float m_length; + + // hide copy constructor and operator= + AUD_FaderFactory(const AUD_FaderFactory&); + AUD_FaderFactory& operator=(const AUD_FaderFactory&); public: /** @@ -59,53 +63,26 @@ public: * \param start The time where fading should start in seconds. * \param length How long fading should last in seconds. */ - AUD_FaderFactory(AUD_IFactory* factory = 0, + AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type = AUD_FADE_IN, float start = 0.0f, float length = 1.0f); /** - * Creates a new fader factory. - * \param type The fading type. - * \param start The time where fading should start in seconds. - * \param length How long fading should last in seconds. - */ - AUD_FaderFactory(AUD_FadeType type = AUD_FADE_IN, - float start = 0.0f, float length = 1.0f); - - /** * Returns the fading type. */ - AUD_FadeType getType(); - - /** - * Sets the fading type. - * \param type The new fading type: AUD_FADE_IN or AUD_FADE_OUT. - */ - void setType(AUD_FadeType type); + AUD_FadeType getType() const; /** * Returns the fading start. */ - float getStart(); - - /** - * Sets the fading start. - * \param start The new fading start. - */ - void setStart(float start); + float getStart() const; /** * Returns the fading length. */ - float getLength(); - - /** - * Sets the fading length. - * \param start The new fading length. - */ - void setLength(float length); + float getLength() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_FADERFACTORY diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp index 4e919fff323..2292fa06102 100644 --- a/intern/audaspace/FX/AUD_FaderReader.cpp +++ b/intern/audaspace/FX/AUD_FaderReader.cpp @@ -24,7 +24,6 @@ */ #include "AUD_FaderReader.h" -#include "AUD_Buffer.h" #include <cstring> @@ -33,19 +32,9 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type, AUD_EffectReader(reader), m_type(type), m_start(start), - m_length(length) + m_length(length), + m_empty(true) { - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_FaderReader::~AUD_FaderReader() -{ - delete m_buffer; AUD_DELETE("buffer") -} - -bool AUD_FaderReader::notify(AUD_Message &message) -{ - return m_reader->notify(message); } void AUD_FaderReader::read(int & length, sample_t* & buffer) @@ -56,28 +45,50 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer) m_reader->read(length, buffer); - if(m_buffer->getSize() < length * samplesize) - m_buffer->resize(length * samplesize); - if((position + length) / (float)specs.rate <= m_start) { if(m_type != AUD_FADE_OUT) { - buffer = m_buffer->getBuffer(); - memset(buffer, 0, length * samplesize); + if(m_buffer.getSize() < length * samplesize) + { + m_buffer.resize(length * samplesize); + m_empty = false; + } + + buffer = m_buffer.getBuffer(); + + if(!m_empty) + { + memset(buffer, 0, length * samplesize); + m_empty = true; + } } } else if(position / (float)specs.rate >= m_start+m_length) { if(m_type == AUD_FADE_OUT) { - buffer = m_buffer->getBuffer(); - memset(buffer, 0, length * samplesize); + if(m_buffer.getSize() < length * samplesize) + { + m_buffer.resize(length * samplesize); + m_empty = false; + } + + buffer = m_buffer.getBuffer(); + + if(!m_empty) + { + memset(buffer, 0, length * samplesize); + m_empty = true; + } } } else { - sample_t* buf = m_buffer->getBuffer(); + if(m_buffer.getSize() < length * samplesize) + m_buffer.resize(length * samplesize); + + sample_t* buf = m_buffer.getBuffer(); float volume = 1.0f; for(int i = 0; i < length * specs.channels; i++) @@ -98,5 +109,6 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer) } buffer = buf; + m_empty = false; } } diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h index a75ac6e7a47..d9d685af956 100644 --- a/intern/audaspace/FX/AUD_FaderReader.h +++ b/intern/audaspace/FX/AUD_FaderReader.h @@ -27,7 +27,7 @@ #define AUD_FADERREADER #include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_Buffer.h" /** * This class fades another reader. @@ -38,24 +38,33 @@ class AUD_FaderReader : public AUD_EffectReader { private: /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; - - /** * The fading type. */ - AUD_FadeType m_type; + const AUD_FadeType m_type; /** * The fading start. */ - float m_start; + const float m_start; /** * The fading length. */ - float m_length; + const float m_length; + + /** + * The playback buffer. + */ + AUD_Buffer m_buffer; + + /** + * Whether the buffer is empty. + */ + bool m_empty; + + // hide copy constructor and operator= + AUD_FaderReader(const AUD_FaderReader&); + AUD_FaderReader& operator=(const AUD_FaderReader&); public: /** @@ -63,17 +72,10 @@ public: * \param type The fading type. * \param start The time where fading should start in seconds. * \param length How long fading should last in seconds. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type, float start,float length); - /** - * Destroys the reader. - */ - virtual ~AUD_FaderReader(); - - virtual bool notify(AUD_Message &message); virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp index 384d36beab7..d222e7f615e 100644 --- a/intern/audaspace/FX/AUD_HighpassFactory.cpp +++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp @@ -24,28 +24,38 @@ */ #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) : AUD_EffectFactory(factory), m_frequency(frequency), - m_Q(Q) {} - -AUD_HighpassFactory::AUD_HighpassFactory(float frequency, float Q) : - AUD_EffectFactory(0), - m_frequency(frequency), - m_Q(Q) {} + m_Q(Q) +{ +} -AUD_IReader* AUD_HighpassFactory::createReader() +AUD_IReader* AUD_HighpassFactory::createReader() const { AUD_IReader* reader = getReader(); - if(reader != 0) - { - reader = new AUD_HighpassReader(reader, m_frequency, m_Q); - AUD_NEW("reader") - } + // 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 reader; + return new AUD_IIRFilterReader(reader, b, a); } diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h index 5e31053ed6c..1220157a776 100644 --- a/intern/audaspace/FX/AUD_HighpassFactory.h +++ b/intern/audaspace/FX/AUD_HighpassFactory.h @@ -37,12 +37,16 @@ private: /** * The attack value in seconds. */ - float m_frequency; + const float m_frequency; /** * The Q factor. */ - float m_Q; + const float m_Q; + + // hide copy constructor and operator= + AUD_HighpassFactory(const AUD_HighpassFactory&); + AUD_HighpassFactory& operator=(const AUD_HighpassFactory&); public: /** @@ -53,14 +57,7 @@ public: */ AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f); - /** - * Creates a new highpass factory. - * \param frequency The cutoff frequency. - * \param Q The Q factor. - */ - AUD_HighpassFactory(float frequency, float Q = 1.0f); - - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_HIGHPASSFACTORY diff --git a/intern/audaspace/FX/AUD_HighpassReader.cpp b/intern/audaspace/FX/AUD_HighpassReader.cpp deleted file mode 100644 index 36b1bb8082e..00000000000 --- a/intern/audaspace/FX/AUD_HighpassReader.cpp +++ /dev/null @@ -1,116 +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 "AUD_Buffer.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) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_outvalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER); - AUD_NEW("buffer") - memset(m_outvalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER); - - m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER); - AUD_NEW("buffer") - memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER); - - m_position = 0; - - // calculate coefficients - float w0 = 2 * M_PI * frequency / specs.rate; - float alpha = sin(w0) / (2 * Q); - float norm = 1 + alpha; - m_coeff[0][0] = 0; - m_coeff[0][1] = -2 * cos(w0) / norm; - m_coeff[0][2] = (1 - alpha) / norm; - m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm); - m_coeff[1][1] = (-1 - cos(w0)) / norm; -} - -AUD_HighpassReader::~AUD_HighpassReader() -{ - delete m_buffer; AUD_DELETE("buffer") - - delete m_outvalues; AUD_DELETE("buffer") - delete m_invalues; AUD_DELETE("buffer"); -} - -void AUD_HighpassReader::read(int & length, sample_t* & buffer) -{ - sample_t* buf; - sample_t* outvalues; - sample_t* invalues; - - outvalues = m_outvalues->getBuffer(); - invalues = m_invalues->getBuffer(); - - AUD_Specs specs = m_reader->getSpecs(); - - m_reader->read(length, buf); - - if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) - m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); - - buffer = m_buffer->getBuffer(); - int channels = specs.channels; - - for(int channel = 0; channel < channels; channel++) - { - for(int i = 0; i < length; i++) - { - invalues[m_position * CC] = buf[i * CC]; - outvalues[m_position * CC] = 0; - - for(int j = 0; j < AUD_HIGHPASS_ORDER; j++) - { - outvalues[m_position * CC] += m_coeff[1][j] * - invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] - - m_coeff[0][j] * - outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC]; - } - - buffer[i * CC] = outvalues[m_position * CC]; - - m_position = (m_position + AUD_HIGHPASS_ORDER-1) % - AUD_HIGHPASS_ORDER; - } - } -} diff --git a/intern/audaspace/FX/AUD_HighpassReader.h b/intern/audaspace/FX/AUD_HighpassReader.h deleted file mode 100644 index dc28a62e45b..00000000000 --- a/intern/audaspace/FX/AUD_HighpassReader.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_HIGHPASSREADER -#define AUD_HIGHPASSREADER - -#include "AUD_EffectReader.h" -class AUD_Buffer; - -#define AUD_HIGHPASS_ORDER 3 - -/** - * This class represents a highpass filter. - */ -class AUD_HighpassReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; - - /** - * The last out values buffer. - */ - AUD_Buffer *m_outvalues; - - /** - * The last in values buffer. - */ - AUD_Buffer *m_invalues; - - /** - * The position for buffer cycling. - */ - int m_position; - - /** - * Filter coefficients. - */ - float m_coeff[2][AUD_HIGHPASS_ORDER]; - -public: - /** - * Creates a new highpass reader. - * \param reader The reader to read from. - * \param frequency The cutoff frequency. - * \param Q The Q factor. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q); - - /** - * Destroys the reader. - */ - virtual ~AUD_HighpassReader(); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_HIGHPASSREADER 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 <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_IIRFilterFactory.h" +#include "AUD_IIRFilterReader.h" + +AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory, + std::vector<float> b, + std::vector<float> 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 <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_IIRFILTERFACTORY +#define AUD_IIRFILTERFACTORY + +#include "AUD_EffectFactory.h" + +#include <vector> + +/** + * This factory creates a IIR filter reader. + */ +class AUD_IIRFilterFactory : public AUD_EffectFactory +{ +private: + /** + * Output filter coefficients. + */ + std::vector<float> m_a; + + /** + * Input filter coefficients. + */ + std::vector<float> 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<float> b, + std::vector<float> a); + + virtual AUD_IReader* createReader() const; +}; + +#endif //AUD_IIRFILTERFACTORY diff --git a/intern/audaspace/FX/AUD_SumReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.cpp index 76ccf2f863a..120c9f8d0ae 100644 --- a/intern/audaspace/FX/AUD_SumReader.h +++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp @@ -23,42 +23,28 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#ifndef AUD_SUMREADER -#define AUD_SUMREADER +#include "AUD_IIRFilterReader.h" -#include "AUD_EffectReader.h" -class AUD_Buffer; - -/** - * This class represents an summer. - */ -class AUD_SumReader : 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; - - /** - * The sums of the specific channels. - */ - AUD_Buffer *m_sums; - -public: - /** - * Creates a new sum reader. - * \param reader The reader to read from. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_SumReader(AUD_IReader* reader); - - /** - * Destroys the reader. - */ - virtual ~AUD_SumReader(); + 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; - 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_SUMREADER + return out; +} diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h index 489f85b10f2..303bc6d92df 100644 --- a/intern/audaspace/FX/AUD_VolumeReader.h +++ b/intern/audaspace/FX/AUD_IIRFilterReader.h @@ -23,44 +23,44 @@ * ***** END LGPL LICENSE BLOCK ***** */ -#ifndef AUD_VOLUMEREADER -#define AUD_VOLUMEREADER +#ifndef AUD_IIRFILTERREADER +#define AUD_IIRFILTERREADER -#include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_BaseIIRFilterReader.h" + +#include <vector> /** - * This class reads another reader and changes it's volume. + * This class is for infinite impulse response filters with simple coefficients. */ -class AUD_VolumeReader : 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 volume level. + * Input filter coefficients. */ - float m_volume; + std::vector<float> m_b; + + // hide copy constructor and operator= + AUD_IIRFilterReader(const AUD_IIRFilterReader&); + AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&); public: /** - * Creates a new volume reader. + * Creates a new IIR filter reader. * \param reader The reader to read from. - * \param volume The size of the buffer. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_VolumeReader(AUD_IReader* reader, float volume); - - /** - * Destroys the reader. + * \param b The input filter coefficients. + * \param a The output filter coefficients. */ - virtual ~AUD_VolumeReader(); + AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b, + std::vector<float> a); - virtual bool notify(AUD_Message &message); - virtual void read(int & length, sample_t* & buffer); + virtual sample_t filter(); }; -#endif //AUD_VOLUMEREADER +#endif //AUD_IIRFILTERREADER diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp index 6f19575240a..75501afcec3 100644 --- a/intern/audaspace/FX/AUD_LimiterFactory.cpp +++ b/intern/audaspace/FX/AUD_LimiterFactory.cpp @@ -31,37 +31,21 @@ AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory, float start, float end) : AUD_EffectFactory(factory), m_start(start), - m_end(end) {} - -float AUD_LimiterFactory::getStart() + m_end(end) { - return m_start; } -void AUD_LimiterFactory::setStart(float start) +float AUD_LimiterFactory::getStart() const { - m_start = start; + return m_start; } -float AUD_LimiterFactory::getEnd() +float AUD_LimiterFactory::getEnd() const { return m_end; } -void AUD_LimiterFactory::setEnd(float end) -{ - m_end = end; -} - -AUD_IReader* AUD_LimiterFactory::createReader() +AUD_IReader* AUD_LimiterFactory::createReader() const { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_LimiterReader(reader, m_start, m_end); - AUD_NEW("reader") - } - - return reader; + return new AUD_LimiterReader(getReader(), m_start, m_end); } diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h index 588fea6eb4b..5d9491f60aa 100644 --- a/intern/audaspace/FX/AUD_LimiterFactory.h +++ b/intern/audaspace/FX/AUD_LimiterFactory.h @@ -37,12 +37,16 @@ private: /** * The start time. */ - float m_start; + const float m_start; /** * The end time. */ - float m_end; + const float m_end; + + // hide copy constructor and operator= + AUD_LimiterFactory(const AUD_LimiterFactory&); + AUD_LimiterFactory& operator=(const AUD_LimiterFactory&); public: /** @@ -52,33 +56,20 @@ public: * \param end The desired end time, a negative value signals that it should * play to the end. */ - AUD_LimiterFactory(AUD_IFactory* factory = 0, + AUD_LimiterFactory(AUD_IFactory* factory, float start = 0, float end = -1); /** * Returns the start time. */ - float getStart(); - - /** - * Sets the start time. - * \param start The new start time. - */ - void setStart(float start); + float getStart() const; /** * Returns the end time. */ - float getEnd(); - - /** - * Sets the end time. - * \param end The new end time, a negative value signals that it should play - * to the end. - */ - void setEnd(float end); + float getEnd() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_LIMITERFACTORY diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp index 05882369001..dd7301213c9 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.cpp +++ b/intern/audaspace/FX/AUD_LimiterReader.cpp @@ -30,31 +30,27 @@ AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader, float start, float end) : - AUD_EffectReader(reader) + AUD_EffectReader(reader), + m_start(int(start * reader->getSpecs().rate)), + m_end(int(end * reader->getSpecs().rate)) { - m_end = (int)(end * reader->getSpecs().rate); - - if(start <= 0) - m_start = 0; - else + if(m_start > 0) { - m_start = (int)(start * reader->getSpecs().rate); if(m_reader->isSeekable()) m_reader->seek(m_start); else { // skip first m_start samples by reading them - int length; + int length = AUD_DEFAULT_BUFFER_SIZE; sample_t* buffer; - for(int i = m_start; - i >= AUD_DEFAULT_BUFFER_SIZE; - i -= AUD_DEFAULT_BUFFER_SIZE) + for(int len = m_start; + length == AUD_DEFAULT_BUFFER_SIZE; + len -= AUD_DEFAULT_BUFFER_SIZE) { - length = AUD_DEFAULT_BUFFER_SIZE; + if(len < AUD_DEFAULT_BUFFER_SIZE) + length = len; m_reader->read(length, buffer); - length = i; } - m_reader->read(length, buffer); } } } @@ -64,18 +60,18 @@ void AUD_LimiterReader::seek(int position) m_reader->seek(position + m_start); } -int AUD_LimiterReader::getLength() +int AUD_LimiterReader::getLength() const { int len = m_reader->getLength(); - if(m_reader->getType() != AUD_TYPE_BUFFER || len < 0 || - (len > m_end && m_end >= 0)) + if(len < 0 || (len > m_end && m_end >= 0)) len = m_end; return len - m_start; } -int AUD_LimiterReader::getPosition() +int AUD_LimiterReader::getPosition() const { - return m_reader->getPosition() - m_start; + int pos = m_reader->getPosition(); + return AUD_MIN(pos, m_end) - m_start; } void AUD_LimiterReader::read(int & length, sample_t* & buffer) @@ -83,7 +79,7 @@ void AUD_LimiterReader::read(int & length, sample_t* & buffer) if(m_end >= 0) { int position = m_reader->getPosition(); - if(position+length > m_end) + if(position + length > m_end) length = m_end - position; if(length < 0) { diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h index 9921f5ee1b0..59d6096dcba 100644 --- a/intern/audaspace/FX/AUD_LimiterReader.h +++ b/intern/audaspace/FX/AUD_LimiterReader.h @@ -37,12 +37,16 @@ private: /** * The start sample: inclusive. */ - int m_start; + const int m_start; /** * The end sample: exlusive. */ - int m_end; + const int m_end; + + // hide copy constructor and operator= + AUD_LimiterReader(const AUD_LimiterReader&); + AUD_LimiterReader& operator=(const AUD_LimiterReader&); public: /** @@ -51,13 +55,12 @@ public: * \param start The desired start sample (inclusive). * \param end The desired end sample (exklusive), a negative value signals * that it should play to the end. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1); virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); + virtual int getLength() const; + virtual int getPosition() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp index 90186f623ff..6805a8e4b42 100644 --- a/intern/audaspace/FX/AUD_LoopFactory.cpp +++ b/intern/audaspace/FX/AUD_LoopFactory.cpp @@ -28,30 +28,16 @@ AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) : AUD_EffectFactory(factory), - m_loop(loop) {} - -AUD_LoopFactory::AUD_LoopFactory(int loop) : - AUD_EffectFactory(0), - m_loop(loop) {} - -int AUD_LoopFactory::getLoop() + m_loop(loop) { - return m_loop; } -void AUD_LoopFactory::setLoop(int loop) +int AUD_LoopFactory::getLoop() const { - m_loop = loop; + return m_loop; } -AUD_IReader* AUD_LoopFactory::createReader() +AUD_IReader* AUD_LoopFactory::createReader() const { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_LoopReader(reader, m_loop); AUD_NEW("reader") - } - - return reader; + return new AUD_LoopReader(getReader(), m_loop); } diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h index c81d906b82e..f9e358af52d 100644 --- a/intern/audaspace/FX/AUD_LoopFactory.h +++ b/intern/audaspace/FX/AUD_LoopFactory.h @@ -38,7 +38,11 @@ private: /** * The loop count. */ - int m_loop; + const int m_loop; + + // hide copy constructor and operator= + AUD_LoopFactory(const AUD_LoopFactory&); + AUD_LoopFactory& operator=(const AUD_LoopFactory&); public: /** @@ -47,28 +51,14 @@ public: * \param loop The desired loop count, negative values result in endless * looping. */ - AUD_LoopFactory(AUD_IFactory* factory = 0, int loop = -1); - - /** - * Creates a new loop factory. - * \param loop The desired loop count, negative values result in endless - * looping. - */ - AUD_LoopFactory(int loop); + AUD_LoopFactory(AUD_IFactory* factory, int loop = -1); /** * Returns the loop count. */ - int getLoop(); - - /** - * Sets the loop count. - * \param loop The desired loop count, negative values result in endless - * looping. - */ - void setLoop(int loop); + int getLoop() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_LOOPFACTORY diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp index 3bcd8c2f9d3..7521f914a5c 100644 --- a/intern/audaspace/FX/AUD_LoopReader.cpp +++ b/intern/audaspace/FX/AUD_LoopReader.cpp @@ -29,36 +29,37 @@ #include <cstring> AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) : - AUD_EffectReader(reader), m_loop(loop) + AUD_EffectReader(reader), m_count(loop), m_left(loop) { - m_samples = -1; - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") } -AUD_LoopReader::~AUD_LoopReader() +void AUD_LoopReader::seek(int position) { - delete m_buffer; AUD_DELETE("buffer") + int len = m_reader->getLength(); + if(len < 0) + m_reader->seek(position); + else + { + if(m_count >= 0) + { + m_left = m_count - (position / len); + if(m_left < 0) + m_left = 0; + } + m_reader->seek(position % len); + } } -AUD_ReaderType AUD_LoopReader::getType() +int AUD_LoopReader::getLength() const { - if(m_loop < 0) - return AUD_TYPE_STREAM; - return m_reader->getType(); + if(m_count < 0) + return -1; + return m_reader->getLength() * m_count; } -bool AUD_LoopReader::notify(AUD_Message &message) +int AUD_LoopReader::getPosition() const { - if(message.type == AUD_MSG_LOOP) - { - m_loop = message.loopcount; - m_samples = message.time * m_reader->getSpecs().rate; - - m_reader->notify(message); - - return true; - } - return m_reader->notify(message); + return m_reader->getPosition() * (m_count < 0 ? 1 : m_count); } void AUD_LoopReader::read(int & length, sample_t* & buffer) @@ -66,50 +67,44 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer) AUD_Specs specs = m_reader->getSpecs(); int samplesize = AUD_SAMPLE_SIZE(specs); - if(m_samples >= 0) - { - if(length > m_samples) - length = m_samples; - m_samples -= length; - } - int len = length; m_reader->read(len, buffer); - if(len < length && m_loop != 0) + if(len < length && m_left) { int pos = 0; - if(m_buffer->getSize() < length * samplesize) - m_buffer->resize(length * samplesize); + if(m_buffer.getSize() < length * samplesize) + m_buffer.resize(length * samplesize); + + sample_t* buf = m_buffer.getBuffer(); - memcpy(m_buffer->getBuffer() + pos * specs.channels, - buffer, len * samplesize); + memcpy(buf + pos * specs.channels, buffer, len * samplesize); pos += len; - while(pos < length && m_loop != 0) + while(pos < length && m_left) { - if(m_loop > 0) - m_loop--; + if(m_left > 0) + m_left--; m_reader->seek(0); len = length - pos; m_reader->read(len, buffer); + // prevent endless loop if(!len) break; - memcpy(m_buffer->getBuffer() + pos * specs.channels, - buffer, len * samplesize); + memcpy(buf + pos * specs.channels, buffer, len * samplesize); pos += len; } length = pos; - buffer = m_buffer->getBuffer(); + buffer = buf; } else length = len; diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h index e61a49cb0db..e0ed4cb6bf3 100644 --- a/intern/audaspace/FX/AUD_LoopReader.h +++ b/intern/audaspace/FX/AUD_LoopReader.h @@ -27,7 +27,7 @@ #define AUD_LOOPREADER #include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_Buffer.h" /** * This class reads another reader and loops it. @@ -39,17 +39,21 @@ private: /** * The playback buffer. */ - AUD_Buffer *m_buffer; + AUD_Buffer m_buffer; /** - * The left loop count. + * The loop count. */ - int m_loop; + const int m_count; /** - * The left samples. + * The left loop count. */ - int m_samples; + int m_left; + + // hide copy constructor and operator= + AUD_LoopReader(const AUD_LoopReader&); + AUD_LoopReader& operator=(const AUD_LoopReader&); public: /** @@ -57,17 +61,12 @@ public: * \param reader The reader to read from. * \param loop The desired loop count, negative values result in endless * looping. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_LoopReader(AUD_IReader* reader, int loop); - /** - * Destroys the reader. - */ - virtual ~AUD_LoopReader(); - - virtual AUD_ReaderType getType(); - virtual bool notify(AUD_Message &message); + virtual void seek(int position); + virtual int getLength() const; + virtual int getPosition() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp index 05dc5ff3994..9244e07631b 100644 --- a/intern/audaspace/FX/AUD_LowpassFactory.cpp +++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp @@ -24,28 +24,38 @@ */ #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) : AUD_EffectFactory(factory), m_frequency(frequency), - m_Q(Q) {} - -AUD_LowpassFactory::AUD_LowpassFactory(float frequency, float Q) : - AUD_EffectFactory(0), - m_frequency(frequency), - m_Q(Q) {} + m_Q(Q) +{ +} -AUD_IReader* AUD_LowpassFactory::createReader() +AUD_IReader* AUD_LowpassFactory::createReader() const { AUD_IReader* reader = getReader(); - if(reader != 0) - { - reader = new AUD_LowpassReader(reader, m_frequency, m_Q); - AUD_NEW("reader") - } + // 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 reader; + return new AUD_IIRFilterReader(reader, b, a); } diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h index 8a419823de0..61b76510a9e 100644 --- a/intern/audaspace/FX/AUD_LowpassFactory.h +++ b/intern/audaspace/FX/AUD_LowpassFactory.h @@ -37,12 +37,16 @@ private: /** * The attack value in seconds. */ - float m_frequency; + const float m_frequency; /** * The Q factor. */ - float m_Q; + const float m_Q; + + // hide copy constructor and operator= + AUD_LowpassFactory(const AUD_LowpassFactory&); + AUD_LowpassFactory& operator=(const AUD_LowpassFactory&); public: /** @@ -53,14 +57,7 @@ public: */ AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f); - /** - * Creates a new lowpass factory. - * \param frequency The cutoff frequency. - * \param Q The Q factor. - */ - AUD_LowpassFactory(float frequency, float Q = 1.0f); - - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_LOWPASSFACTORY diff --git a/intern/audaspace/FX/AUD_LowpassReader.cpp b/intern/audaspace/FX/AUD_LowpassReader.cpp deleted file mode 100644 index 6dc0bf66a96..00000000000 --- a/intern/audaspace/FX/AUD_LowpassReader.cpp +++ /dev/null @@ -1,115 +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 "AUD_Buffer.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) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_outvalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER); - AUD_NEW("buffer") - memset(m_outvalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER); - - m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER); - AUD_NEW("buffer") - memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER); - - m_position = 0; - - // calculate coefficients - float w0 = 2 * M_PI * frequency / specs.rate; - float alpha = sin(w0) / (2 * Q); - float norm = 1 + alpha; - m_coeff[0][0] = 0; - m_coeff[0][1] = -2 * cos(w0) / norm; - m_coeff[0][2] = (1 - alpha) / norm; - m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm); - m_coeff[1][1] = (1 - cos(w0)) / norm; -} - -AUD_LowpassReader::~AUD_LowpassReader() -{ - delete m_buffer; AUD_DELETE("buffer") - - delete m_outvalues; AUD_DELETE("buffer") - delete m_invalues; AUD_DELETE("buffer"); -} - -void AUD_LowpassReader::read(int & length, sample_t* & buffer) -{ - sample_t* buf; - sample_t* outvalues; - sample_t* invalues; - - outvalues = m_outvalues->getBuffer(); - invalues = m_invalues->getBuffer(); - - AUD_Specs specs = m_reader->getSpecs(); - - m_reader->read(length, buf); - - if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) - m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); - - buffer = m_buffer->getBuffer(); - int channels = specs.channels; - - for(int channel = 0; channel < channels; channel++) - { - for(int i = 0; i < length; i++) - { - invalues[m_position * CC] = buf[i * CC]; - outvalues[m_position * CC] = 0; - - for(int j = 0; j < AUD_LOWPASS_ORDER; j++) - { - outvalues[m_position * CC] += m_coeff[1][j] * - invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] - - m_coeff[0][j] * - outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC]; - } - - buffer[i * CC] = outvalues[m_position * CC]; - - m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER; - } - } -} diff --git a/intern/audaspace/FX/AUD_LowpassReader.h b/intern/audaspace/FX/AUD_LowpassReader.h deleted file mode 100644 index a490ba52c1c..00000000000 --- a/intern/audaspace/FX/AUD_LowpassReader.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * $Id$ - * - * ***** BEGIN LGPL LICENSE BLOCK ***** - * - * Copyright 2009 Jörg Hermann Müller - * - * This file is part of AudaSpace. - * - * AudaSpace is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * AudaSpace is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. - * - * ***** END LGPL LICENSE BLOCK ***** - */ - -#ifndef AUD_LOWPASSREADER -#define AUD_LOWPASSREADER - -#include "AUD_EffectReader.h" -class AUD_Buffer; - -#define AUD_LOWPASS_ORDER 3 - -/** - * This class represents a lowpass filter. - */ -class AUD_LowpassReader : public AUD_EffectReader -{ -private: - /** - * The playback buffer. - */ - AUD_Buffer *m_buffer; - - /** - * The last out values buffer. - */ - AUD_Buffer *m_outvalues; - - /** - * The last in values buffer. - */ - AUD_Buffer *m_invalues; - - /** - * The position for buffer cycling. - */ - int m_position; - - /** - * Filter coefficients. - */ - float m_coeff[2][AUD_LOWPASS_ORDER]; - -public: - /** - * Creates a new lowpass reader. - * \param reader The reader to read from. - * \param frequency The cutoff frequency. - * \param Q The Q factor. - * \exception AUD_Exception Thrown if the reader specified is NULL. - */ - AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q); - - /** - * Destroys the reader. - */ - virtual ~AUD_LowpassReader(); - - virtual void read(int & length, sample_t* & buffer); -}; - -#endif //AUD_LOWPASSREADER diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp index 8b72afe05e7..b3aaa9e80a4 100644 --- a/intern/audaspace/FX/AUD_PingPongFactory.cpp +++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp @@ -28,40 +28,25 @@ #include "AUD_ReverseFactory.h" AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) : - AUD_EffectFactory(factory) {} - -AUD_IReader* AUD_PingPongFactory::createReader() + AUD_EffectFactory(factory) { - if(m_factory == 0) - return 0; +} - AUD_IReader* reader = m_factory->createReader(); +AUD_IReader* AUD_PingPongFactory::createReader() const +{ + AUD_IReader* reader = getReader(); + AUD_IReader* reader2; + AUD_ReverseFactory factory(m_factory); - if(reader != 0) + try { - AUD_IReader* reader2; - AUD_ReverseFactory factory(m_factory); - - try - { - reader2 = factory.createReader(); - } - catch(AUD_Exception) - { - reader2 = 0; - } - - if(reader2 != 0) - { - reader = new AUD_DoubleReader(reader, reader2); - AUD_NEW("reader") - } - else - { - delete reader; AUD_DELETE("reader") - reader = 0; - } + reader2 = factory.createReader(); + } + catch(AUD_Exception&) + { + delete reader; + throw; } - return reader; + return new AUD_DoubleReader(reader, reader2); } diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h index b8854da550a..82aedca8f7f 100644 --- a/intern/audaspace/FX/AUD_PingPongFactory.h +++ b/intern/audaspace/FX/AUD_PingPongFactory.h @@ -34,18 +34,19 @@ */ class AUD_PingPongFactory : public AUD_EffectFactory { +private: + // hide copy constructor and operator= + AUD_PingPongFactory(const AUD_PingPongFactory&); + AUD_PingPongFactory& operator=(const AUD_PingPongFactory&); + public: /** * Creates a new ping pong factory. * \param factory The input factory. */ - AUD_PingPongFactory(AUD_IFactory* factory = 0); - - /** - * Destroys the factory. - */ + AUD_PingPongFactory(AUD_IFactory* factory); - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_PINGPONGFACTORY diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp index 5f814283c12..be285562db3 100644 --- a/intern/audaspace/FX/AUD_PitchFactory.cpp +++ b/intern/audaspace/FX/AUD_PitchFactory.cpp @@ -29,20 +29,11 @@ AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) : AUD_EffectFactory(factory), - m_pitch(pitch) {} - -AUD_PitchFactory::AUD_PitchFactory(float pitch) : - AUD_EffectFactory(0), - m_pitch(pitch) {} - -AUD_IReader* AUD_PitchFactory::createReader() + m_pitch(pitch) { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_PitchReader(reader, m_pitch); AUD_NEW("reader") - } +} - return reader; +AUD_IReader* AUD_PitchFactory::createReader() const +{ + return new AUD_PitchReader(getReader(), m_pitch); } diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h index 96c4d0d7e92..52b9b7d99e5 100644 --- a/intern/audaspace/FX/AUD_PitchFactory.h +++ b/intern/audaspace/FX/AUD_PitchFactory.h @@ -37,7 +37,11 @@ private: /** * The pitch. */ - float m_pitch; + const float m_pitch; + + // hide copy constructor and operator= + AUD_PitchFactory(const AUD_PitchFactory&); + AUD_PitchFactory& operator=(const AUD_PitchFactory&); public: /** @@ -45,26 +49,9 @@ public: * \param factory The input factory. * \param pitch The desired pitch. */ - AUD_PitchFactory(AUD_IFactory* factory = 0, float pitch = 1.0f); - - /** - * Creates a new pitch factory. - * \param pitch The desired pitch. - */ - AUD_PitchFactory(float pitch); - - /** - * Returns the pitch. - */ - float getPitch(); - - /** - * Sets the pitch. - * \param pitch The new pitch value. Should be between 0.0 and 1.0. - */ - void setPitch(float pitch); + AUD_PitchFactory(AUD_IFactory* factory, float pitch); - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_PITCHFACTORY diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp index c53264e1350..19c3be31968 100644 --- a/intern/audaspace/FX/AUD_PitchReader.cpp +++ b/intern/audaspace/FX/AUD_PitchReader.cpp @@ -26,12 +26,11 @@ #include "AUD_PitchReader.h" AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) : - AUD_EffectReader(reader) + AUD_EffectReader(reader), m_pitch(pitch) { - m_pitch = pitch; } -AUD_Specs AUD_PitchReader::getSpecs() +AUD_Specs AUD_PitchReader::getSpecs() const { AUD_Specs specs = m_reader->getSpecs(); specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch)); diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h index 440e9cc843c..cc188cf0ee4 100644 --- a/intern/audaspace/FX/AUD_PitchReader.h +++ b/intern/audaspace/FX/AUD_PitchReader.h @@ -37,18 +37,21 @@ private: /** * The pitch level. */ - float m_pitch; + const float m_pitch; + + // hide copy constructor and operator= + AUD_PitchReader(const AUD_PitchReader&); + AUD_PitchReader& operator=(const AUD_PitchReader&); public: /** * Creates a new pitch reader. * \param reader The reader to read from. * \param pitch The size of the buffer. - * \exception AUD_Exception Thrown if the reader specified is NULL. */ AUD_PitchReader(AUD_IReader* reader, float pitch); - virtual AUD_Specs getSpecs(); + virtual AUD_Specs getSpecs() const; }; #endif //AUD_PITCHREADER diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp index f97defd793b..2228f949dfe 100644 --- a/intern/audaspace/FX/AUD_RectifyFactory.cpp +++ b/intern/audaspace/FX/AUD_RectifyFactory.cpp @@ -24,22 +24,21 @@ */ #include "AUD_RectifyFactory.h" -#include "AUD_RectifyReader.h" +#include "AUD_CallbackIIRFilterReader.h" -AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) : - AUD_EffectFactory(factory) {} - -AUD_RectifyFactory::AUD_RectifyFactory() : - AUD_EffectFactory(0) {} +#include <cmath> -AUD_IReader* AUD_RectifyFactory::createReader() +sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless) { - AUD_IReader* reader = getReader(); + return fabs(reader->x(0)); +} - if(reader != 0) - { - reader = new AUD_RectifyReader(reader); AUD_NEW("reader") - } +AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) : + AUD_EffectFactory(factory) +{ +} - return reader; +AUD_IReader* AUD_RectifyFactory::createReader() const +{ + return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter); } diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h index ed00620d318..d8b39e83fdf 100644 --- a/intern/audaspace/FX/AUD_RectifyFactory.h +++ b/intern/audaspace/FX/AUD_RectifyFactory.h @@ -33,19 +33,19 @@ */ class AUD_RectifyFactory : public AUD_EffectFactory { +private: + // hide copy constructor and operator= + AUD_RectifyFactory(const AUD_RectifyFactory&); + AUD_RectifyFactory& operator=(const AUD_RectifyFactory&); + public: /** * Creates a new rectify factory. * \param factory The input factory. */ - AUD_RectifyFactory(AUD_IFactory* factory = 0); - - /** - * Creates a new rectify factory. - */ - AUD_RectifyFactory(); + AUD_RectifyFactory(AUD_IFactory* factory); - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_RECTIFYFACTORY diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp index 1242641c350..1002e2de87e 100644 --- a/intern/audaspace/FX/AUD_ReverseFactory.cpp +++ b/intern/audaspace/FX/AUD_ReverseFactory.cpp @@ -28,16 +28,11 @@ #include "AUD_Space.h" AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) : - AUD_EffectFactory(factory) {} - -AUD_IReader* AUD_ReverseFactory::createReader() + AUD_EffectFactory(factory) { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_ReverseReader(reader); AUD_NEW("reader") - } +} - return reader; +AUD_IReader* AUD_ReverseFactory::createReader() const +{ + return new AUD_ReverseReader(getReader()); } diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h index 4b664c47281..a1995ee68f9 100644 --- a/intern/audaspace/FX/AUD_ReverseFactory.h +++ b/intern/audaspace/FX/AUD_ReverseFactory.h @@ -34,17 +34,19 @@ */ class AUD_ReverseFactory : public AUD_EffectFactory { +private: + // hide copy constructor and operator= + AUD_ReverseFactory(const AUD_ReverseFactory&); + AUD_ReverseFactory& operator=(const AUD_ReverseFactory&); + public: /** * Creates a new reverse factory. * \param factory The input factory. */ - AUD_ReverseFactory(AUD_IFactory* factory = 0); + AUD_ReverseFactory(AUD_IFactory* factory); - /** - * Destroys the factory. - */ - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_REVERSEFACTORY diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp index 82d6c70ce53..c651ea79577 100644 --- a/intern/audaspace/FX/AUD_ReverseReader.cpp +++ b/intern/audaspace/FX/AUD_ReverseReader.cpp @@ -24,27 +24,19 @@ */ #include "AUD_ReverseReader.h" -#include "AUD_Buffer.h" #include <cstring> -AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) : - AUD_EffectReader(reader) -{ - if(reader->getType() != AUD_TYPE_BUFFER) - AUD_THROW(AUD_ERROR_READER); - - m_length = reader->getLength(); - if(m_length < 0) - AUD_THROW(AUD_ERROR_READER); +static const char* props_error = "AUD_ReverseReader: The reader has to be " + "seekable and a finite length."; - m_position = 0; - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_ReverseReader::~AUD_ReverseReader() +AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) : + AUD_EffectReader(reader), + m_length(reader->getLength()), + m_position(0) { - delete m_buffer; AUD_DELETE("buffer") + if(m_length < 0 || !reader->isSeekable()) + AUD_THROW(AUD_ERROR_PROPS, props_error); } void AUD_ReverseReader::seek(int position) @@ -52,12 +44,12 @@ void AUD_ReverseReader::seek(int position) m_position = position; } -int AUD_ReverseReader::getLength() +int AUD_ReverseReader::getLength() const { return m_length; } -int AUD_ReverseReader::getPosition() +int AUD_ReverseReader::getPosition() const { return m_position; } @@ -66,7 +58,7 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer) { // first correct the length if(m_position + length > m_length) - length = m_length-m_position; + length = m_length - m_position; if(length <= 0) { @@ -78,10 +70,10 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer) int samplesize = AUD_SAMPLE_SIZE(specs); // resize buffer if needed - if(m_buffer->getSize() < length * samplesize) - m_buffer->resize(length * samplesize); + if(m_buffer.getSize() < length * samplesize) + m_buffer.resize(length * samplesize); - buffer = m_buffer->getBuffer(); + buffer = m_buffer.getBuffer(); sample_t* buf; int len = length; @@ -105,5 +97,5 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer) m_position += length; - buffer = m_buffer->getBuffer(); + buffer = m_buffer.getBuffer(); } diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h index 045d2ac5a8e..8eb960a5dee 100644 --- a/intern/audaspace/FX/AUD_ReverseReader.h +++ b/intern/audaspace/FX/AUD_ReverseReader.h @@ -27,7 +27,7 @@ #define AUD_REVERSEREADER #include "AUD_EffectReader.h" -class AUD_Buffer; +#include "AUD_Buffer.h" /** * This class reads another reader from back to front. @@ -37,37 +37,36 @@ class AUD_ReverseReader : public AUD_EffectReader { private: /** - * The current position. + * The sample count. */ - int m_position; + const int m_length; /** - * The sample count. + * The current position. */ - int m_length; + int m_position; /** * The playback buffer. */ - AUD_Buffer* m_buffer; + AUD_Buffer m_buffer; + + // hide copy constructor and operator= + AUD_ReverseReader(const AUD_ReverseReader&); + AUD_ReverseReader& operator=(const AUD_ReverseReader&); public: /** * Creates a new reverse reader. * \param reader The reader to read from. - * \exception AUD_Exception Thrown if the reader specified is NULL or not - * a buffer. + * \exception AUD_Exception Thrown if the reader specified has an + * undeterminable/infinite length or is not seekable. */ AUD_ReverseReader(AUD_IReader* reader); - /** - * Destroys the reader. - */ - virtual ~AUD_ReverseReader(); - virtual void seek(int position); - virtual int getLength(); - virtual int getPosition(); + virtual int getLength() const; + virtual int getPosition() const; virtual void read(int & length, sample_t* & buffer); }; diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp index 638acaa9a32..c321a13d79a 100644 --- a/intern/audaspace/FX/AUD_SquareFactory.cpp +++ b/intern/audaspace/FX/AUD_SquareFactory.cpp @@ -24,34 +24,39 @@ */ #include "AUD_SquareFactory.h" -#include "AUD_SquareReader.h" +#include "AUD_CallbackIIRFilterReader.h" -AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) : - AUD_EffectFactory(factory), - m_threshold(threshold) {} - -AUD_SquareFactory::AUD_SquareFactory(float threshold) : - AUD_EffectFactory(0), - m_threshold(threshold) {} - -float AUD_SquareFactory::getThreshold() +sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold) { - return m_threshold; + float in = reader->x(0); + if(in >= *threshold) + return 1; + else if(in <= -*threshold) + return -1; + else + return 0; } -void AUD_SquareFactory::setThreshold(float threshold) +void endSquareFilter(float* threshold) { - m_threshold = threshold; + delete threshold; } -AUD_IReader* AUD_SquareFactory::createReader() +AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) : + AUD_EffectFactory(factory), + m_threshold(threshold) { - AUD_IReader* reader = getReader(); +} - if(reader != 0) - { - reader = new AUD_SquareReader(reader, m_threshold); AUD_NEW("reader") - } +float AUD_SquareFactory::getThreshold() const +{ + return m_threshold; +} - return reader; +AUD_IReader* AUD_SquareFactory::createReader() const +{ + return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, + (doFilterIIR) squareFilter, + (endFilterIIR) endSquareFilter, + new float(m_threshold)); } diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h index dfbe5ae2887..da87dc6f888 100644 --- a/intern/audaspace/FX/AUD_SquareFactory.h +++ b/intern/audaspace/FX/AUD_SquareFactory.h @@ -37,7 +37,11 @@ private: /** * The threshold. */ - float m_threshold; + const float m_threshold; + + // hide copy constructor and operator= + AUD_SquareFactory(const AUD_SquareFactory&); + AUD_SquareFactory& operator=(const AUD_SquareFactory&); public: /** @@ -45,26 +49,14 @@ public: * \param factory The input factory. * \param threshold The threshold. */ - AUD_SquareFactory(AUD_IFactory* factory = 0, float threshold = 0.0f); - - /** - * Creates a new square factory. - * \param threshold The threshold. - */ - AUD_SquareFactory(float threshold); + AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f); /** * Returns the threshold. */ - float getThreshold(); - - /** - * Sets the threshold. - * \param threshold The new threshold value. Should be between 0.0 and 1.0. - */ - void setThreshold(float threshold); + float getThreshold() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_SQUAREFACTORY diff --git a/intern/audaspace/FX/AUD_SquareReader.cpp b/intern/audaspace/FX/AUD_SquareReader.cpp deleted file mode 100644 index 2d4dc52fe27..00000000000 --- a/intern/audaspace/FX/AUD_SquareReader.cpp +++ /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 ***** - */ - -#include "AUD_SquareReader.h" -#include "AUD_Buffer.h" - -#include <cstring> - -AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) : - AUD_EffectReader(reader), - m_threshold(threshold) -{ - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_SquareReader::~AUD_SquareReader() -{ - delete m_buffer; AUD_DELETE("buffer") -} - -void AUD_SquareReader::read(int & length, sample_t* & buffer) -{ - 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_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp index f7990aab8a1..a128e50504c 100644 --- a/intern/audaspace/FX/AUD_SumFactory.cpp +++ b/intern/audaspace/FX/AUD_SumFactory.cpp @@ -24,20 +24,18 @@ */ #include "AUD_SumFactory.h" -#include "AUD_SumReader.h" +#include "AUD_IIRFilterReader.h" AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) : - AUD_EffectFactory(factory) {} - -AUD_IReader* AUD_SumFactory::createReader() + AUD_EffectFactory(factory) { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_SumReader(reader); - AUD_NEW("reader") - } +} - return reader; +AUD_IReader* AUD_SumFactory::createReader() const +{ + 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_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h index 5cb48e26b10..045a0a3a625 100644 --- a/intern/audaspace/FX/AUD_SumFactory.h +++ b/intern/audaspace/FX/AUD_SumFactory.h @@ -33,14 +33,19 @@ */ class AUD_SumFactory : public AUD_EffectFactory { +private: + // hide copy constructor and operator= + AUD_SumFactory(const AUD_SumFactory&); + AUD_SumFactory& operator=(const AUD_SumFactory&); + public: /** * Creates a new sum factory. * \param factory The input factory. */ - AUD_SumFactory(AUD_IFactory* factory = 0); + AUD_SumFactory(AUD_IFactory* factory); - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_SUMFACTORY diff --git a/intern/audaspace/FX/AUD_SumReader.cpp b/intern/audaspace/FX/AUD_SumReader.cpp deleted file mode 100644 index 08747790fc9..00000000000 --- a/intern/audaspace/FX/AUD_SumReader.cpp +++ /dev/null @@ -1,68 +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 "AUD_Buffer.h" - -#include <cstring> - -#define CC specs.channels + channel - -AUD_SumReader::AUD_SumReader(AUD_IReader* reader) : - AUD_EffectReader(reader) -{ - AUD_Specs specs = reader->getSpecs(); - int samplesize = AUD_SAMPLE_SIZE(specs); - - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") - - m_sums = new AUD_Buffer(samplesize); AUD_NEW("buffer") - memset(m_sums->getBuffer(), 0, samplesize); -} - -AUD_SumReader::~AUD_SumReader() -{ - delete m_buffer; AUD_DELETE("buffer") - delete m_sums; AUD_DELETE("buffer") -} - -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_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp new file mode 100644 index 00000000000..6bfc1125ca6 --- /dev/null +++ b/intern/audaspace/FX/AUD_SuperposeFactory.cpp @@ -0,0 +1,49 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_SuperposeFactory.h" +#include "AUD_SuperposeReader.h" + +AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) : + m_factory1(factory1), m_factory2(factory2) +{ +} + +AUD_IReader* AUD_SuperposeFactory::createReader() const +{ + AUD_IReader* reader1 = m_factory1->createReader(); + AUD_IReader* reader2; + try + { + reader2 = m_factory2->createReader(); + } + catch(AUD_Exception&) + { + delete reader1; + throw; + } + + return new AUD_SuperposeReader(reader1, reader2); +} diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h new file mode 100644 index 00000000000..a7fde2c182f --- /dev/null +++ b/intern/audaspace/FX/AUD_SuperposeFactory.h @@ -0,0 +1,63 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_SUPERPOSEFACTORY +#define AUD_SUPERPOSEFACTORY + +#include "AUD_IFactory.h" + +/** + * This factory plays two other factories behind each other. + * \note Readers from the underlying factories must have the same sample rate and channel count. + */ +class AUD_SuperposeFactory : public AUD_IFactory +{ +private: + /** + * First played factory. + */ + AUD_IFactory* m_factory1; + + /** + * Second played factory. + */ + AUD_IFactory* m_factory2; + + // hide copy constructor and operator= + AUD_SuperposeFactory(const AUD_SuperposeFactory&); + AUD_SuperposeFactory& operator=(const AUD_SuperposeFactory&); + +public: + /** + * Creates a new superpose factory. + * \param factory1 The first input factory. + * \param factory2 The second input factory. + */ + AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2); + + virtual AUD_IReader* createReader() const; +}; + +#endif //AUD_SUPERPOSEFACTORY diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp new file mode 100644 index 00000000000..546b79a3a77 --- /dev/null +++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp @@ -0,0 +1,115 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_SuperposeReader.h" + +#include <cstring> + +static const char* specs_error = "AUD_SuperposeReader: Both readers have to " + "have the same specs."; + +AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) : + m_reader1(reader1), m_reader2(reader2) +{ + try + { + AUD_Specs s1, s2; + s1 = reader1->getSpecs(); + s2 = reader2->getSpecs(); + if(memcmp(&s1, &s2, sizeof(AUD_Specs))) + AUD_THROW(AUD_ERROR_SPECS, specs_error); + } + catch(AUD_Exception&) + { + delete reader1; + delete reader2; + + throw; + } +} + +AUD_SuperposeReader::~AUD_SuperposeReader() +{ + delete m_reader1; + delete m_reader2; +} + +bool AUD_SuperposeReader::isSeekable() const +{ + return m_reader1->isSeekable() && m_reader2->isSeekable(); +} + +void AUD_SuperposeReader::seek(int position) +{ + m_reader1->seek(position); + m_reader2->seek(position); +} + +int AUD_SuperposeReader::getLength() const +{ + int len1 = m_reader1->getLength(); + int len2 = m_reader2->getLength(); + if((len1 < 0) || (len2 < 0)) + return -1; + return AUD_MIN(len1, len2); +} + +int AUD_SuperposeReader::getPosition() const +{ + int pos1 = m_reader1->getPosition(); + int pos2 = m_reader2->getPosition(); + return AUD_MAX(pos1, pos2); +} + +AUD_Specs AUD_SuperposeReader::getSpecs() const +{ + return m_reader1->getSpecs(); +} + +void AUD_SuperposeReader::read(int & length, sample_t* & buffer) +{ + AUD_Specs specs = m_reader1->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); + + if(m_buffer.getSize() < length * samplesize) + m_buffer.resize(length * samplesize); + buffer = m_buffer.getBuffer(); + + int len1 = length; + sample_t* buf; + m_reader1->read(len1, buf); + memcpy(buffer, buf, len1 * samplesize); + + if(len1 < length) + memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize); + + int len2 = length; + m_reader2->read(len2, buf); + + for(int i = 0; i < len2 * specs.channels; i++) + buffer[i] += buf[i]; + + length = AUD_MAX(len1, len2); +} diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h new file mode 100644 index 00000000000..eeceb9adfeb --- /dev/null +++ b/intern/audaspace/FX/AUD_SuperposeReader.h @@ -0,0 +1,79 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_SUPERPOSEREADER +#define AUD_SUPERPOSEREADER + +#include "AUD_IReader.h" +#include "AUD_Buffer.h" + +/** + * This reader plays two readers with the same specs sequently. + */ +class AUD_SuperposeReader : public AUD_IReader +{ +private: + /** + * The first reader. + */ + AUD_IReader* m_reader1; + + /** + * The second reader. + */ + AUD_IReader* m_reader2; + + /** + * The playback buffer for the intersecting part. + */ + AUD_Buffer m_buffer; + + // hide copy constructor and operator= + AUD_SuperposeReader(const AUD_SuperposeReader&); + AUD_SuperposeReader& operator=(const AUD_SuperposeReader&); + +public: + /** + * Creates a new superpose reader. + * \param reader1 The first reader to read from. + * \param reader2 The second reader to read from. + * \exception AUD_Exception Thrown if the specs from the readers differ. + */ + AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2); + + /** + * Destroys the reader. + */ + virtual ~AUD_SuperposeReader(); + + virtual bool isSeekable() const; + virtual void seek(int position); + virtual int getLength() const; + virtual int getPosition() const; + virtual AUD_Specs getSpecs() const; + virtual void read(int & length, sample_t* & buffer); +}; + +#endif //AUD_SUPERPOSEREADER diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp index fbde608aa12..1b341a5a51a 100644 --- a/intern/audaspace/FX/AUD_VolumeFactory.cpp +++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp @@ -24,34 +24,23 @@ */ #include "AUD_VolumeFactory.h" -#include "AUD_VolumeReader.h" +#include "AUD_IIRFilterReader.h" AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) : AUD_EffectFactory(factory), - m_volume(volume) {} - -AUD_VolumeFactory::AUD_VolumeFactory(float volume) : - AUD_EffectFactory(0), - m_volume(volume) {} - -float AUD_VolumeFactory::getVolume() + m_volume(volume) { - return m_volume; } -void AUD_VolumeFactory::setVolume(float volume) +float AUD_VolumeFactory::getVolume() const { - m_volume = volume; + return m_volume; } -AUD_IReader* AUD_VolumeFactory::createReader() +AUD_IReader* AUD_VolumeFactory::createReader() const { - AUD_IReader* reader = getReader(); - - if(reader != 0) - { - reader = new AUD_VolumeReader(reader, m_volume); AUD_NEW("reader") - } - - return reader; + 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/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h index 09f91241b47..a086aab4640 100644 --- a/intern/audaspace/FX/AUD_VolumeFactory.h +++ b/intern/audaspace/FX/AUD_VolumeFactory.h @@ -39,7 +39,11 @@ private: /** * The volume. */ - float m_volume; + const float m_volume; + + // hide copy constructor and operator= + AUD_VolumeFactory(const AUD_VolumeFactory&); + AUD_VolumeFactory& operator=(const AUD_VolumeFactory&); public: /** @@ -47,26 +51,14 @@ public: * \param factory The input factory. * \param volume The desired volume. */ - AUD_VolumeFactory(AUD_IFactory* factory = 0, float volume = 1.0f); - - /** - * Creates a new volume factory. - * \param volume The desired volume. - */ - AUD_VolumeFactory(float volume); + AUD_VolumeFactory(AUD_IFactory* factory, float volume); /** * Returns the volume. */ - float getVolume(); - - /** - * Sets the volume. - * \param volume The new volume value. Should be between 0.0 and 1.0. - */ - void setVolume(float volume); + float getVolume() const; - virtual AUD_IReader* createReader(); + virtual AUD_IReader* createReader() const; }; #endif //AUD_VOLUMEFACTORY diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_VolumeReader.cpp deleted file mode 100644 index f094c1e4ea3..00000000000 --- a/intern/audaspace/FX/AUD_VolumeReader.cpp +++ /dev/null @@ -1,69 +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_VolumeReader.h" -#include "AUD_Buffer.h" - -#include <cstring> - -AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) : - AUD_EffectReader(reader), - m_volume(volume) -{ - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") -} - -AUD_VolumeReader::~AUD_VolumeReader() -{ - delete m_buffer; AUD_DELETE("buffer") -} - -bool AUD_VolumeReader::notify(AUD_Message &message) -{ - if(message.type == AUD_MSG_VOLUME) - { - m_volume = message.volume; - - m_reader->notify(message); - - return true; - } - return m_reader->notify(message); -} - -void AUD_VolumeReader::read(int & length, sample_t* & buffer) -{ - 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; -} |