diff options
author | Joerg Mueller <nexyon@gmail.com> | 2010-01-01 08:09:30 +0300 |
---|---|---|
committer | Joerg Mueller <nexyon@gmail.com> | 2010-01-01 08:09:30 +0300 |
commit | 174eccf07851c4e7f669b194cd8951ca98bc5c81 (patch) | |
tree | 42d11467df2d006fcbaa562023ffe09796879716 /intern/audaspace/FX | |
parent | 3fa927a42e893709ac78f7d9419c22979b05bf3f (diff) |
Huge new year audio commit!
* Refactored the whole audaspace library to use float as sample format over all readers.
* Added new Readers like the linear resampler, envelope, lowpass, highpass and butterworth.
* Note: The butterworth filter isn't working correctly, some bug in there... Maybe also true for the envelope.
* Added a sound to f-curve operator that behaves mostly like the soundtracker script of technoestupido.
Diffstat (limited to 'intern/audaspace/FX')
26 files changed, 1292 insertions, 158 deletions
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp new file mode 100644 index 00000000000..fd0a53def7c --- /dev/null +++ b/intern/audaspace/FX/AUD_ButterworthFactory.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_ButterworthFactory.h" +#include "AUD_ButterworthReader.h" + +AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory, + float frequency) : + AUD_EffectFactory(factory), + m_frequency(frequency) {} + +AUD_ButterworthFactory::AUD_ButterworthFactory(float frequency) : + AUD_EffectFactory(0), + m_frequency(frequency) {} + +AUD_IReader* AUD_ButterworthFactory::createReader() +{ + AUD_IReader* reader = getReader(); + + if(reader != 0) + { + reader = new AUD_ButterworthReader(reader, m_frequency); + AUD_NEW("reader") + } + + return reader; +} diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h new file mode 100644 index 00000000000..69169531d70 --- /dev/null +++ b/intern/audaspace/FX/AUD_ButterworthFactory.h @@ -0,0 +1,59 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_BUTTERWORTHFACTORY +#define AUD_BUTTERWORTHFACTORY + +#include "AUD_EffectFactory.h" + +/** + * This factory creates a butterworth filter reader. + */ +class AUD_ButterworthFactory : public AUD_EffectFactory +{ +private: + /** + * The attack value in seconds. + */ + float m_frequency; + +public: + /** + * Creates a new butterworth factory. + * \param factory The input factory. + * \param frequency The cutoff frequency. + */ + AUD_ButterworthFactory(AUD_IFactory* factory, float frequency); + + /** + * Creates a new butterworth factory. + * \param frequency The cutoff frequency. + */ + AUD_ButterworthFactory(float frequency); + + virtual AUD_IReader* createReader(); +}; + +#endif //AUD_BUTTERWORTHFACTORY diff --git a/intern/audaspace/FX/AUD_ButterworthReader.cpp b/intern/audaspace/FX/AUD_ButterworthReader.cpp new file mode 100644 index 00000000000..adcae87ce9f --- /dev/null +++ b/intern/audaspace/FX/AUD_ButterworthReader.cpp @@ -0,0 +1,120 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_ButterworthReader.h" +#include "AUD_Buffer.h" + +#include <cstring> +#include <cmath> + +#define BWPB41 0.76536686473 +#define BWPB42 1.84775906502 +#define CC channels + channel + +AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader, + float frequency) : + AUD_EffectReader(reader) +{ + AUD_Specs specs = reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); + + m_buffer = new AUD_Buffer(); AUD_NEW("buffer") + + m_outvalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer") + memset(m_outvalues->getBuffer(), 0, samplesize * 5); + + m_invalues = new AUD_Buffer(samplesize * 5); AUD_NEW("buffer") + memset(m_invalues->getBuffer(), 0, samplesize * 5); + + m_position = 0; + + // calculate coefficients + float omega = 2 * tan(frequency * M_PI / specs.rate); + float o2 = omega * omega; + float o4 = o2 * o2; + float x1 = o2 + 2 * BWPB41 * omega + 4; + float x2 = o2 + 2 * BWPB42 * omega + 4; + float y1 = o2 - 2 * BWPB41 * omega + 4; + float y2 = o2 - 2 * BWPB42 * omega + 4; + float o228 = 2 * o2 - 8; + float norm = x1 * x2; + m_coeff[0][0] = 0; + m_coeff[0][1] = (x1 + x2) * o228 / norm; + m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm; + m_coeff[0][3] = (y1 + y2) * o228 / norm; + m_coeff[0][4] = y1 * y2 / norm; + m_coeff[1][4] = m_coeff[1][0] = o4 / norm; + m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm; + m_coeff[1][2] = 6 * o4 / norm; +} + +AUD_ButterworthReader::~AUD_ButterworthReader() +{ + delete m_buffer; AUD_DELETE("buffer") + + delete m_outvalues; AUD_DELETE("buffer") + delete m_invalues; AUD_DELETE("buffer"); +} + +void AUD_ButterworthReader::read(int & length, sample_t* & buffer) +{ + sample_t* buf; + sample_t* outvalues; + sample_t* invalues; + + outvalues = m_outvalues->getBuffer(); + invalues = m_invalues->getBuffer(); + + AUD_Specs specs = m_reader->getSpecs(); + + m_reader->read(length, buf); + + if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) + m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); + + buffer = m_buffer->getBuffer(); + int channels = specs.channels; + + for(int channel = 0; channel < channels; channel++) + { + for(int i = 0; i < length; i++) + { + invalues[m_position * CC] = buf[i * CC]; + outvalues[m_position * CC] = 0; + + for(int j = 0; j < 4; j++) + { + outvalues[m_position * CC] += m_coeff[1][j] * + invalues[((m_position + j) % 5) * CC] - + m_coeff[0][j] * + outvalues[((m_position + j) % 5) * CC]; + } + + buffer[i * CC] = outvalues[m_position * CC]; + + m_position = (m_position + 4) % 5; + } + } +} diff --git a/intern/audaspace/FX/AUD_ButterworthReader.h b/intern/audaspace/FX/AUD_ButterworthReader.h new file mode 100644 index 00000000000..b1cbd4e3820 --- /dev/null +++ b/intern/audaspace/FX/AUD_ButterworthReader.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_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_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp index 38d3b893b5c..f2521f645aa 100644 --- a/intern/audaspace/FX/AUD_DelayReader.cpp +++ b/intern/audaspace/FX/AUD_DelayReader.cpp @@ -77,31 +77,26 @@ void AUD_DelayReader::read(int & length, sample_t* & buffer) { if(m_remdelay > 0) { - int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs()); + AUD_Specs specs = m_reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); - if(m_buffer->getSize() < length*samplesize) - m_buffer->resize(length*samplesize); + if(m_buffer->getSize() < length * samplesize) + m_buffer->resize(length * samplesize); if(length > m_remdelay) { - if(getSpecs().format == AUD_FORMAT_U8) - memset(m_buffer->getBuffer(), 0x80, m_remdelay*samplesize); - else - memset(m_buffer->getBuffer(), 0, m_remdelay*samplesize); + memset(m_buffer->getBuffer(), 0, m_remdelay * samplesize); int len = length - m_remdelay; m_reader->read(len, buffer); - memcpy(m_buffer->getBuffer()+m_remdelay*samplesize, - buffer, len*samplesize); + memcpy(m_buffer->getBuffer() + m_remdelay * specs.channels, + buffer, len * samplesize); if(len < length-m_remdelay) length = m_remdelay + len; m_remdelay = 0; } else { - if(getSpecs().format == AUD_FORMAT_U8) - memset(m_buffer->getBuffer(), 0x80, length*samplesize); - else - memset(m_buffer->getBuffer(), 0, length*samplesize); + memset(m_buffer->getBuffer(), 0, length * samplesize); m_remdelay -= length; } buffer = m_buffer->getBuffer(); diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp index 8d3afbf2f1d..1e51a094427 100644 --- a/intern/audaspace/FX/AUD_DoubleReader.cpp +++ b/intern/audaspace/FX/AUD_DoubleReader.cpp @@ -137,15 +137,16 @@ void AUD_DoubleReader::read(int & length, sample_t* & buffer) m_reader1->read(len, buffer); if(len < length) { - int samplesize = AUD_SAMPLE_SIZE(m_reader1->getSpecs()); + AUD_Specs specs = m_reader1->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); if(m_buffer->getSize() < length * samplesize) m_buffer->resize(length * samplesize); - memcpy(m_buffer->getBuffer(), buffer, len*samplesize); + memcpy(m_buffer->getBuffer(), buffer, len * samplesize); len = length - len; length -= len; m_reader2->read(len, buffer); - memcpy(m_buffer->getBuffer() + length*samplesize, - buffer, len*samplesize); + memcpy(m_buffer->getBuffer() + length * specs.channels, buffer, + len * samplesize); length += len; buffer = m_buffer->getBuffer(); m_finished1 = true; diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp new file mode 100644 index 00000000000..c3b2c3f24fe --- /dev/null +++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp @@ -0,0 +1,58 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_EnvelopeFactory.h" +#include "AUD_EnvelopeReader.h" + +AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, + float release, float threshold, + float arthreshold) : + AUD_EffectFactory(factory), + m_attack(attack), + m_release(release), + m_threshold(threshold), + m_arthreshold(arthreshold) {} + +AUD_EnvelopeFactory::AUD_EnvelopeFactory(float attack, float release, + float threshold, float arthreshold) : + AUD_EffectFactory(0), + m_attack(attack), + m_release(release), + m_threshold(threshold), + m_arthreshold(arthreshold) {} + +AUD_IReader* AUD_EnvelopeFactory::createReader() +{ + AUD_IReader* reader = getReader(); + + if(reader != 0) + { + reader = new AUD_EnvelopeReader(reader, m_attack, m_release, + m_threshold, m_arthreshold); + AUD_NEW("reader") + } + + return reader; +} diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h new file mode 100644 index 00000000000..c79e5472e30 --- /dev/null +++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h @@ -0,0 +1,82 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_ENVELOPEFACTORY +#define AUD_ENVELOPEFACTORY + +#include "AUD_EffectFactory.h" + +/** + * This factory creates an envelope follower reader. + */ +class AUD_EnvelopeFactory : public AUD_EffectFactory +{ +private: + /** + * The attack value in seconds. + */ + float m_attack; + + /** + * The release value in seconds. + */ + float m_release; + + /** + * The threshold value. + */ + float m_threshold; + + /** + * The attack/release threshold value. + */ + float m_arthreshold; + +public: + /** + * Creates a new envelope factory. + * \param factory The input factory. + * \param attack The attack value in seconds. + * \param release The release value in seconds. + * \param threshold The threshold value. + * \param arthreshold The attack/release threshold value. + */ + AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release, + float threshold, float arthreshold); + + /** + * Creates a new envelope factory. + * \param attack The attack value in seconds. + * \param release The release value in seconds. + * \param threshold The threshold value. + * \param arthreshold The attack/release threshold value. + */ + AUD_EnvelopeFactory(float attack, float release, float threshold, + float arthreshold); + + virtual AUD_IReader* createReader(); +}; + +#endif //AUD_ENVELOPEFACTORY diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.cpp b/intern/audaspace/FX/AUD_EnvelopeReader.cpp new file mode 100644 index 00000000000..f41aee1d4bc --- /dev/null +++ b/intern/audaspace/FX/AUD_EnvelopeReader.cpp @@ -0,0 +1,86 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_EnvelopeReader.h" +#include "AUD_Buffer.h" + +#include <cstring> +#include <cmath> + +AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack, + float release, float threshold, + float arthreshold) : + AUD_EffectReader(reader), + m_threshold(threshold) +{ + AUD_Specs specs = reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); + + m_buffer = new AUD_Buffer(); AUD_NEW("buffer") + + m_envelopes = new AUD_Buffer(samplesize); + AUD_NEW("buffer") + memset(m_envelopes->getBuffer(), 0, samplesize); + + m_bAttack = pow(arthreshold, 1.0/(specs.rate * attack)); + m_bRelease = pow(arthreshold, 1.0/(specs.rate * release)); +} + +AUD_EnvelopeReader::~AUD_EnvelopeReader() +{ + delete m_buffer; AUD_DELETE("buffer") + delete m_envelopes; AUD_DELETE("buffer") +} + +void AUD_EnvelopeReader::read(int & length, sample_t* & buffer) +{ + sample_t* buf; + sample_t* envelopes; + envelopes = m_envelopes->getBuffer(); + + AUD_Specs specs = m_reader->getSpecs(); + + m_reader->read(length, buf); + if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) + m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); + + buffer = m_buffer->getBuffer(); + + sample_t value; + + for(int channel = 0; channel < specs.channels; channel++) + { + for(int i = 0; i < length; i++) + { + value = fabs(buf[i * specs.channels + channel]); + if(value < m_threshold) + value = 0.0f; + + buffer[i * specs.channels + channel] = envelopes[channel] = + ((value > envelopes[channel]) ? m_bAttack : m_bRelease) * + (envelopes[channel] - value) + value; + } + } +} diff --git a/intern/audaspace/FX/AUD_EnvelopeReader.h b/intern/audaspace/FX/AUD_EnvelopeReader.h new file mode 100644 index 00000000000..ff9dd23d34c --- /dev/null +++ b/intern/audaspace/FX/AUD_EnvelopeReader.h @@ -0,0 +1,84 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#ifndef AUD_ENVELOPEREADER +#define AUD_ENVELOPEREADER + +#include "AUD_EffectReader.h" +class AUD_Buffer; + +/** + * This class represents an envelope follower. + */ +class AUD_EnvelopeReader : public AUD_EffectReader +{ +private: + /** + * The playback buffer. + */ + AUD_Buffer *m_buffer; + + /** + * The last envelopes buffer. + */ + AUD_Buffer *m_envelopes; + + /** + * Attack b value. + */ + float m_bAttack; + + /** + * Release b value. + */ + float m_bRelease; + + /** + * Threshold value. + */ + float m_threshold; + +public: + /** + * Creates a new envelope reader. + * \param reader The reader to read from. + * \param attack The attack value in seconds. + * \param release The release value in seconds. + * \param threshold The threshold value. + * \param arthreshold The attack/release threshold value. + * \exception AUD_Exception Thrown if the reader specified is NULL. + */ + AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release, + float threshold, float arthreshold); + + /** + * Destroys the reader. + */ + virtual ~AUD_EnvelopeReader(); + + virtual void read(int & length, sample_t* & buffer); +}; + +#endif //AUD_ENVELOPEREADER diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp index d5096e7fae1..6c7ea6e0a01 100644 --- a/intern/audaspace/FX/AUD_FaderReader.cpp +++ b/intern/audaspace/FX/AUD_FaderReader.cpp @@ -35,35 +35,6 @@ AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type, m_start(start), m_length(length) { - int bigendian = 1; - bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian - - switch(m_reader->getSpecs().format) - { - case AUD_FORMAT_S16: - m_adjust = AUD_volume_adjust<int16_t>; - break; - case AUD_FORMAT_S32: - m_adjust = AUD_volume_adjust<int32_t>; - break; - case AUD_FORMAT_FLOAT32: - m_adjust = AUD_volume_adjust<float>; - break; - case AUD_FORMAT_FLOAT64: - m_adjust = AUD_volume_adjust<double>; - break; - case AUD_FORMAT_U8: - m_adjust = AUD_volume_adjust_u8; - break; - case AUD_FORMAT_S24: - m_adjust = bigendian ? AUD_volume_adjust_s24_be : - AUD_volume_adjust_s24_le; - break; - default: - delete m_reader; - AUD_THROW(AUD_ERROR_READER); - } - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") } @@ -93,9 +64,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer) if(m_type != AUD_FADE_OUT) { buffer = m_buffer->getBuffer(); - memset(buffer, - specs.format == AUD_FORMAT_U8 ? 0x80 : 0, - length * samplesize); + memset(buffer, 0, length * samplesize); } } else if(position / (float)specs.rate >= m_start+m_length) @@ -103,9 +72,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer) if(m_type == AUD_FADE_OUT) { buffer = m_buffer->getBuffer(); - memset(buffer, - specs.format == AUD_FORMAT_U8 ? 0x80 : 0, - length * samplesize); + memset(buffer, 0, length * samplesize); } } else @@ -113,19 +80,21 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer) sample_t* buf = m_buffer->getBuffer(); float volume; - for(int i = 0; i < length; i++) + for(int i = 0; i < length * specs.channels; i++) { - volume = (((position+i)/(float)specs.rate)-m_start) / m_length; - if(volume > 1.0f) - volume = 1.0f; - else if(volume < 0.0f) - volume = 0.0f; + if(i % specs.channels == 0) + { + volume = (((position+i)/(float)specs.rate)-m_start) / m_length; + if(volume > 1.0f) + volume = 1.0f; + else if(volume < 0.0f) + volume = 0.0f; - if(m_type == AUD_FADE_OUT) - volume = 1.0f - volume; + if(m_type == AUD_FADE_OUT) + volume = 1.0f - volume; + } - m_adjust(buf + i * samplesize, buffer + i * samplesize, - specs.channels, volume); + buf[i] = buffer[i] * volume; } buffer = buf; diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h index 773643b2f5d..a75ac6e7a47 100644 --- a/intern/audaspace/FX/AUD_FaderReader.h +++ b/intern/audaspace/FX/AUD_FaderReader.h @@ -27,7 +27,6 @@ #define AUD_FADERREADER #include "AUD_EffectReader.h" -#include "AUD_ConverterFunctions.h" class AUD_Buffer; /** @@ -58,11 +57,6 @@ private: */ float m_length; - /** - * Volume adjustment function. - */ - AUD_volume_adjust_f m_adjust; - public: /** * Creates a new fader reader. diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp new file mode 100644 index 00000000000..384d36beab7 --- /dev/null +++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp @@ -0,0 +1,51 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_HighpassFactory.h" +#include "AUD_HighpassReader.h" + +AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency, + float Q) : + AUD_EffectFactory(factory), + m_frequency(frequency), + m_Q(Q) {} + +AUD_HighpassFactory::AUD_HighpassFactory(float frequency, float Q) : + AUD_EffectFactory(0), + m_frequency(frequency), + m_Q(Q) {} + +AUD_IReader* AUD_HighpassFactory::createReader() +{ + AUD_IReader* reader = getReader(); + + if(reader != 0) + { + reader = new AUD_HighpassReader(reader, m_frequency, m_Q); + AUD_NEW("reader") + } + + return reader; +} diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h new file mode 100644 index 00000000000..cce21eed27d --- /dev/null +++ b/intern/audaspace/FX/AUD_HighpassFactory.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_HIGHPASSFACTORY +#define AUD_HIGHPASSFACTORY + +#include "AUD_EffectFactory.h" + +/** + * This factory creates a highpass filter reader. + */ +class AUD_HighpassFactory : public AUD_EffectFactory +{ +private: + /** + * The attack value in seconds. + */ + float m_frequency; + + /** + * The Q factor. + */ + float m_Q; + +public: + /** + * Creates a new highpass factory. + * \param factory The input factory. + * \param frequency The cutoff frequency. + * \param Q The Q factor. + */ + AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0); + + /** + * Creates a new highpass factory. + * \param frequency The cutoff frequency. + * \param Q The Q factor. + */ + AUD_HighpassFactory(float frequency, float Q = 1.0); + + virtual AUD_IReader* createReader(); +}; + +#endif //AUD_HIGHPASSFACTORY diff --git a/intern/audaspace/FX/AUD_HighpassReader.cpp b/intern/audaspace/FX/AUD_HighpassReader.cpp new file mode 100644 index 00000000000..8240854fc06 --- /dev/null +++ b/intern/audaspace/FX/AUD_HighpassReader.cpp @@ -0,0 +1,112 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_HighpassReader.h" +#include "AUD_Buffer.h" + +#include <cstring> +#include <cmath> + +#define CC channels + channel + +AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency, + float Q) : + AUD_EffectReader(reader) +{ + AUD_Specs specs = reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); + + m_buffer = new AUD_Buffer(); AUD_NEW("buffer") + + m_outvalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER); + AUD_NEW("buffer") + memset(m_outvalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER); + + m_invalues = new AUD_Buffer(samplesize * AUD_HIGHPASS_ORDER); + AUD_NEW("buffer") + memset(m_invalues->getBuffer(), 0, samplesize * AUD_HIGHPASS_ORDER); + + m_position = 0; + + // calculate coefficients + float w0 = 2.0 * M_PI * frequency / specs.rate; + float alpha = sin(w0) / (2 * Q); + float norm = 1 + alpha; + m_coeff[0][0] = 0; + m_coeff[0][1] = -2 * cos(w0) / norm; + m_coeff[0][2] = (1 - alpha) / norm; + m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm); + m_coeff[1][1] = (-1 - cos(w0)) / norm; +} + +AUD_HighpassReader::~AUD_HighpassReader() +{ + delete m_buffer; AUD_DELETE("buffer") + + delete m_outvalues; AUD_DELETE("buffer") + delete m_invalues; AUD_DELETE("buffer"); +} + +void AUD_HighpassReader::read(int & length, sample_t* & buffer) +{ + sample_t* buf; + sample_t* outvalues; + sample_t* invalues; + + outvalues = m_outvalues->getBuffer(); + invalues = m_invalues->getBuffer(); + + AUD_Specs specs = m_reader->getSpecs(); + + m_reader->read(length, buf); + + if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) + m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); + + buffer = m_buffer->getBuffer(); + int channels = specs.channels; + + for(int channel = 0; channel < channels; channel++) + { + for(int i = 0; i < length; i++) + { + invalues[m_position * CC] = buf[i * CC]; + outvalues[m_position * CC] = 0; + + for(int j = 0; j < AUD_HIGHPASS_ORDER; j++) + { + outvalues[m_position * CC] += m_coeff[1][j] * + invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] - + m_coeff[0][j] * + outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC]; + } + + buffer[i * CC] = outvalues[m_position * CC]; + + m_position = (m_position + AUD_HIGHPASS_ORDER-1) % + AUD_HIGHPASS_ORDER; + } + } +} diff --git a/intern/audaspace/FX/AUD_HighpassReader.h b/intern/audaspace/FX/AUD_HighpassReader.h new file mode 100644 index 00000000000..dc28a62e45b --- /dev/null +++ b/intern/audaspace/FX/AUD_HighpassReader.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_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_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp index 9e270321013..7d70fc20221 100644 --- a/intern/audaspace/FX/AUD_LoopReader.cpp +++ b/intern/audaspace/FX/AUD_LoopReader.cpp @@ -27,7 +27,6 @@ #include "AUD_Buffer.h" #include <cstring> -#include <stdio.h> AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) : AUD_EffectReader(reader), m_loop(loop) @@ -62,7 +61,8 @@ bool AUD_LoopReader::notify(AUD_Message &message) void AUD_LoopReader::read(int & length, sample_t* & buffer) { - int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs()); + AUD_Specs specs = m_reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); int len = length; @@ -72,10 +72,10 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer) { int pos = 0; - if(m_buffer->getSize() < length*samplesize) - m_buffer->resize(length*samplesize); + if(m_buffer->getSize() < length * samplesize) + m_buffer->resize(length * samplesize); - memcpy(m_buffer->getBuffer() + pos * samplesize, + memcpy(m_buffer->getBuffer() + pos * specs.channels, buffer, len * samplesize); pos += len; @@ -93,7 +93,7 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer) if(!len) break; - memcpy(m_buffer->getBuffer() + pos * samplesize, + memcpy(m_buffer->getBuffer() + pos * specs.channels, buffer, len * samplesize); pos += len; diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp new file mode 100644 index 00000000000..05dc5ff3994 --- /dev/null +++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp @@ -0,0 +1,51 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_LowpassFactory.h" +#include "AUD_LowpassReader.h" + +AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency, + float Q) : + AUD_EffectFactory(factory), + m_frequency(frequency), + m_Q(Q) {} + +AUD_LowpassFactory::AUD_LowpassFactory(float frequency, float Q) : + AUD_EffectFactory(0), + m_frequency(frequency), + m_Q(Q) {} + +AUD_IReader* AUD_LowpassFactory::createReader() +{ + AUD_IReader* reader = getReader(); + + if(reader != 0) + { + reader = new AUD_LowpassReader(reader, m_frequency, m_Q); + AUD_NEW("reader") + } + + return reader; +} diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h new file mode 100644 index 00000000000..0455e2491e6 --- /dev/null +++ b/intern/audaspace/FX/AUD_LowpassFactory.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_LOWPASSFACTORY +#define AUD_LOWPASSFACTORY + +#include "AUD_EffectFactory.h" + +/** + * This factory creates a lowpass filter reader. + */ +class AUD_LowpassFactory : public AUD_EffectFactory +{ +private: + /** + * The attack value in seconds. + */ + float m_frequency; + + /** + * The Q factor. + */ + float m_Q; + +public: + /** + * Creates a new lowpass factory. + * \param factory The input factory. + * \param frequency The cutoff frequency. + * \param Q The Q factor. + */ + AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0); + + /** + * Creates a new lowpass factory. + * \param frequency The cutoff frequency. + * \param Q The Q factor. + */ + AUD_LowpassFactory(float frequency, float Q = 1.0); + + virtual AUD_IReader* createReader(); +}; + +#endif //AUD_LOWPASSFACTORY diff --git a/intern/audaspace/FX/AUD_LowpassReader.cpp b/intern/audaspace/FX/AUD_LowpassReader.cpp new file mode 100644 index 00000000000..373d0218360 --- /dev/null +++ b/intern/audaspace/FX/AUD_LowpassReader.cpp @@ -0,0 +1,111 @@ +/* + * $Id$ + * + * ***** BEGIN LGPL LICENSE BLOCK ***** + * + * Copyright 2009 Jörg Hermann Müller + * + * This file is part of AudaSpace. + * + * AudaSpace is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AudaSpace is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>. + * + * ***** END LGPL LICENSE BLOCK ***** + */ + +#include "AUD_LowpassReader.h" +#include "AUD_Buffer.h" + +#include <cstring> +#include <cmath> + +#define CC channels + channel + +AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency, + float Q) : + AUD_EffectReader(reader) +{ + AUD_Specs specs = reader->getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); + + m_buffer = new AUD_Buffer(); AUD_NEW("buffer") + + m_outvalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER); + AUD_NEW("buffer") + memset(m_outvalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER); + + m_invalues = new AUD_Buffer(samplesize * AUD_LOWPASS_ORDER); + AUD_NEW("buffer") + memset(m_invalues->getBuffer(), 0, samplesize * AUD_LOWPASS_ORDER); + + m_position = 0; + + // calculate coefficients + float w0 = 2.0 * M_PI * frequency / specs.rate; + float alpha = sin(w0) / (2 * Q); + float norm = 1 + alpha; + m_coeff[0][0] = 0; + m_coeff[0][1] = -2 * cos(w0) / norm; + m_coeff[0][2] = (1 - alpha) / norm; + m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm); + m_coeff[1][1] = (1 - cos(w0)) / norm; +} + +AUD_LowpassReader::~AUD_LowpassReader() +{ + delete m_buffer; AUD_DELETE("buffer") + + delete m_outvalues; AUD_DELETE("buffer") + delete m_invalues; AUD_DELETE("buffer"); +} + +void AUD_LowpassReader::read(int & length, sample_t* & buffer) +{ + sample_t* buf; + sample_t* outvalues; + sample_t* invalues; + + outvalues = m_outvalues->getBuffer(); + invalues = m_invalues->getBuffer(); + + AUD_Specs specs = m_reader->getSpecs(); + + m_reader->read(length, buf); + + if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) + m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); + + buffer = m_buffer->getBuffer(); + int channels = specs.channels; + + for(int channel = 0; channel < channels; channel++) + { + for(int i = 0; i < length; i++) + { + invalues[m_position * CC] = buf[i * CC]; + outvalues[m_position * CC] = 0; + + for(int j = 0; j < AUD_LOWPASS_ORDER; j++) + { + outvalues[m_position * CC] += m_coeff[1][j] * + invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] - + m_coeff[0][j] * + outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC]; + } + + buffer[i * CC] = outvalues[m_position * CC]; + + m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER; + } + } +} diff --git a/intern/audaspace/FX/AUD_LowpassReader.h b/intern/audaspace/FX/AUD_LowpassReader.h new file mode 100644 index 00000000000..a490ba52c1c --- /dev/null +++ b/intern/audaspace/FX/AUD_LowpassReader.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_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_RectifyReader.cpp b/intern/audaspace/FX/AUD_RectifyReader.cpp index 9839aefa838..5d3ce80e811 100644 --- a/intern/audaspace/FX/AUD_RectifyReader.cpp +++ b/intern/audaspace/FX/AUD_RectifyReader.cpp @@ -26,39 +26,11 @@ #include "AUD_RectifyReader.h" #include "AUD_Buffer.h" -#include <cstring> +#include <cmath> AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) : AUD_EffectReader(reader) { - int bigendian = 1; - bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian - - switch(m_reader->getSpecs().format) - { - case AUD_FORMAT_S16: - m_rectify = AUD_rectify<int16_t>; - break; - case AUD_FORMAT_S32: - m_rectify = AUD_rectify<int32_t>; - break; - case AUD_FORMAT_FLOAT32: - m_rectify = AUD_rectify<float>; - break; - case AUD_FORMAT_FLOAT64: - m_rectify = AUD_rectify<double>; - break; - case AUD_FORMAT_U8: - m_rectify = AUD_rectify_u8; - break; - case AUD_FORMAT_S24: - m_rectify = bigendian ? AUD_rectify_s24_be : AUD_rectify_s24_le; - break; - default: - delete m_reader; - AUD_THROW(AUD_ERROR_READER); - } - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") } @@ -73,10 +45,11 @@ void AUD_RectifyReader::read(int & length, sample_t* & buffer) AUD_Specs specs = m_reader->getSpecs(); m_reader->read(length, buf); - if(m_buffer->getSize() < length*AUD_SAMPLE_SIZE(specs)) - m_buffer->resize(length*AUD_SAMPLE_SIZE(specs)); + if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(specs)) + m_buffer->resize(length * AUD_SAMPLE_SIZE(specs)); buffer = m_buffer->getBuffer(); - m_rectify(buffer, buf, length * specs.channels); + for(int i = 0; i < length * specs.channels; i++) + buffer[i] = fabs(buf[i]); } diff --git a/intern/audaspace/FX/AUD_RectifyReader.h b/intern/audaspace/FX/AUD_RectifyReader.h index 17423811cdc..afbe2e59cab 100644 --- a/intern/audaspace/FX/AUD_RectifyReader.h +++ b/intern/audaspace/FX/AUD_RectifyReader.h @@ -27,7 +27,6 @@ #define AUD_RECTIFYREADER #include "AUD_EffectReader.h" -#include "AUD_ConverterFunctions.h" class AUD_Buffer; /** @@ -41,11 +40,6 @@ private: */ AUD_Buffer *m_buffer; - /** - * Rectifying function. - */ - AUD_rectify_f m_rectify; - public: /** * Creates a new rectify reader. diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp index 043480b91b9..82d6c70ce53 100644 --- a/intern/audaspace/FX/AUD_ReverseReader.cpp +++ b/intern/audaspace/FX/AUD_ReverseReader.cpp @@ -65,7 +65,7 @@ int AUD_ReverseReader::getPosition() void AUD_ReverseReader::read(int & length, sample_t* & buffer) { // first correct the length - if(m_position+length > m_length) + if(m_position + length > m_length) length = m_length-m_position; if(length <= 0) @@ -74,7 +74,8 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer) return; } - int samplesize = AUD_SAMPLE_SIZE(getSpecs()); + AUD_Specs specs = getSpecs(); + int samplesize = AUD_SAMPLE_SIZE(specs); // resize buffer if needed if(m_buffer->getSize() < length * samplesize) @@ -86,23 +87,20 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer) int len = length; // read from reader - m_reader->seek(m_length-m_position-len); + m_reader->seek(m_length - m_position - len); m_reader->read(len, buf); // set null if reader didn't give enough data if(len < length) { - if(getSpecs().format == AUD_FORMAT_U8) - memset(buffer, 0x80, (length-len)*samplesize); - else - memset(buffer, 0, (length-len)*samplesize); - buffer += length-len; + memset(buffer, 0, (length - len) * samplesize); + buffer += (length - len) * specs.channels; } // copy the samples reverted for(int i = 0; i < len; i++) - memcpy(buffer + i * samplesize, - buf + (len - 1 - i) * samplesize, + memcpy(buffer + i * specs.channels, + buf + (len - 1 - i) * specs.channels, samplesize); m_position += length; diff --git a/intern/audaspace/FX/AUD_VolumeReader.cpp b/intern/audaspace/FX/AUD_VolumeReader.cpp index fc3f20152a6..f094c1e4ea3 100644 --- a/intern/audaspace/FX/AUD_VolumeReader.cpp +++ b/intern/audaspace/FX/AUD_VolumeReader.cpp @@ -32,35 +32,6 @@ AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) : AUD_EffectReader(reader), m_volume(volume) { - int bigendian = 1; - bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian - - switch(m_reader->getSpecs().format) - { - case AUD_FORMAT_S16: - m_adjust = AUD_volume_adjust<int16_t>; - break; - case AUD_FORMAT_S32: - m_adjust = AUD_volume_adjust<int32_t>; - break; - case AUD_FORMAT_FLOAT32: - m_adjust = AUD_volume_adjust<float>; - break; - case AUD_FORMAT_FLOAT64: - m_adjust = AUD_volume_adjust<double>; - break; - case AUD_FORMAT_U8: - m_adjust = AUD_volume_adjust_u8; - break; - case AUD_FORMAT_S24: - m_adjust = bigendian ? AUD_volume_adjust_s24_be : - AUD_volume_adjust_s24_le; - break; - default: - delete m_reader; - AUD_THROW(AUD_ERROR_READER); - } - m_buffer = new AUD_Buffer(); AUD_NEW("buffer") } @@ -93,5 +64,6 @@ void AUD_VolumeReader::read(int & length, sample_t* & buffer) buffer = m_buffer->getBuffer(); - m_adjust(buffer, buf, length * specs.channels, m_volume); + for(int i = 0; i < length * specs.channels; i++) + buffer[i] = buf[i] * m_volume; } diff --git a/intern/audaspace/FX/AUD_VolumeReader.h b/intern/audaspace/FX/AUD_VolumeReader.h index f38ae4d265c..489f85b10f2 100644 --- a/intern/audaspace/FX/AUD_VolumeReader.h +++ b/intern/audaspace/FX/AUD_VolumeReader.h @@ -27,7 +27,6 @@ #define AUD_VOLUMEREADER #include "AUD_EffectReader.h" -#include "AUD_ConverterFunctions.h" class AUD_Buffer; /** @@ -46,11 +45,6 @@ private: */ float m_volume; - /** - * Volume adjustment function. - */ - AUD_volume_adjust_f m_adjust; - public: /** * Creates a new volume reader. |