forked from bartvdbraak/blender
Audaspace:
* Created awesome filter classes :) * Made all filter effects use the filter classes instead of having the same implementation everywhere. * Added a Python API for LTI IIR filters. * Fixed a warning in creator.c that was introduced when adding game autoplay.
This commit is contained in:
parent
5c9cf81cf9
commit
52ef66da4d
@ -24,7 +24,27 @@
|
||||
*/
|
||||
|
||||
#include "AUD_AccumulatorFactory.h"
|
||||
#include "AUD_AccumulatorReader.h"
|
||||
#include "AUD_CallbackIIRFilterReader.h"
|
||||
|
||||
sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
|
||||
{
|
||||
float in = reader->x(0);
|
||||
float lastin = reader->x(-1);
|
||||
float out = reader->y(-1) + in - lastin;
|
||||
if(in > lastin)
|
||||
out += in - lastin;
|
||||
return out;
|
||||
}
|
||||
|
||||
sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
|
||||
{
|
||||
float in = reader->x(0);
|
||||
float lastin = reader->x(-1);
|
||||
float out = reader->y(-1);
|
||||
if(in > lastin)
|
||||
out += in - lastin;
|
||||
return out;
|
||||
}
|
||||
|
||||
AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
|
||||
bool additive) :
|
||||
@ -35,5 +55,6 @@ AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
|
||||
|
||||
AUD_IReader* AUD_AccumulatorFactory::createReader() const
|
||||
{
|
||||
return new AUD_AccumulatorReader(getReader(), m_additive);
|
||||
return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
|
||||
m_additive ? accumulatorFilterAdditive : accumulatorFilter);
|
||||
}
|
||||
|
@ -1,85 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_AccumulatorReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define CC specs.channels + channel
|
||||
|
||||
AUD_AccumulatorReader::AUD_AccumulatorReader(AUD_IReader* reader,
|
||||
bool additive) :
|
||||
AUD_EffectReader(reader),
|
||||
m_additive(additive),
|
||||
m_sums(AUD_SAMPLE_SIZE(reader->getSpecs())),
|
||||
m_prevs(AUD_SAMPLE_SIZE(reader->getSpecs()))
|
||||
{
|
||||
memset(m_sums.getBuffer(), 0, m_sums.getSize());
|
||||
memset(m_prevs.getBuffer(), 0, m_prevs.getSize());
|
||||
}
|
||||
|
||||
void AUD_AccumulatorReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* sums;
|
||||
sample_t* prevs;
|
||||
sums = m_sums.getBuffer();
|
||||
prevs = m_prevs.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
if(m_additive)
|
||||
{
|
||||
for(int channel = 0; channel < specs.channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(buf[i * CC] > prevs[channel])
|
||||
sums[channel] += buf[i * CC] - prevs[channel];
|
||||
buffer[i * CC] = sums[channel] + buf[i * CC];
|
||||
prevs[channel] = buf[i * CC];
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(int channel = 0; channel < specs.channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
if(buf[i * CC] > prevs[channel])
|
||||
sums[channel] += buf[i * CC] - prevs[channel];
|
||||
buffer[i * CC] = sums[channel];
|
||||
prevs[channel] = buf[i * CC];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_ACCUMULATORREADER
|
||||
#define AUD_ACCUMULATORREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class represents an accumulator.
|
||||
*/
|
||||
class AUD_AccumulatorReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Whether the accumulator is additive.
|
||||
*/
|
||||
const bool m_additive;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The sums of the specific channels.
|
||||
*/
|
||||
AUD_Buffer m_sums;
|
||||
|
||||
/**
|
||||
* The previous results of the specific channels.
|
||||
*/
|
||||
AUD_Buffer m_prevs;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_AccumulatorReader(const AUD_AccumulatorReader&);
|
||||
AUD_AccumulatorReader& operator=(const AUD_AccumulatorReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new accumulator reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param additive Whether the accumulator is additive.
|
||||
*/
|
||||
AUD_AccumulatorReader(AUD_IReader* reader, bool additive);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_ACCUMULATORREADER
|
76
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
Normal file
76
intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
114
intern/audaspace/FX/AUD_BaseIIRFilterReader.h
Normal file
114
intern/audaspace/FX/AUD_BaseIIRFilterReader.h
Normal file
@ -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
|
@ -24,7 +24,16 @@
|
||||
*/
|
||||
|
||||
#include "AUD_ButterworthFactory.h"
|
||||
#include "AUD_ButterworthReader.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define BWPB41 0.76536686473
|
||||
#define BWPB42 1.84775906502
|
||||
|
||||
AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
|
||||
float frequency) :
|
||||
@ -35,5 +44,29 @@ AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
|
||||
|
||||
AUD_IReader* AUD_ButterworthFactory::createReader() const
|
||||
{
|
||||
return new AUD_ButterworthReader(getReader(), m_frequency);
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
// calculate coefficients
|
||||
float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
|
||||
float o2 = omega * omega;
|
||||
float o4 = o2 * o2;
|
||||
float x1 = o2 + 2 * BWPB41 * omega + 4;
|
||||
float x2 = o2 + 2 * BWPB42 * omega + 4;
|
||||
float y1 = o2 - 2 * BWPB41 * omega + 4;
|
||||
float y2 = o2 - 2 * BWPB42 * omega + 4;
|
||||
float o228 = 2 * o2 - 8;
|
||||
float norm = x1 * x2;
|
||||
std::vector<float> a, b;
|
||||
a.push_back(1);
|
||||
a.push_back((x1 + x2) * o228 / norm);
|
||||
a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
|
||||
a.push_back((y1 + y2) * o228 / norm);
|
||||
a.push_back(y1 * y2 / norm);
|
||||
b.push_back(o4 / norm);
|
||||
b.push_back(4 * o4 / norm);
|
||||
b.push_back(6 * o4 / norm);
|
||||
b.push_back(b[1]);
|
||||
b.push_back(b[0]);
|
||||
|
||||
return new AUD_IIRFilterReader(reader, b, a);
|
||||
}
|
||||
|
@ -1,109 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_ButterworthReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define BWPB41 0.76536686473
|
||||
#define BWPB42 1.84775906502
|
||||
#define CC channels + channel
|
||||
|
||||
AUD_ButterworthReader::AUD_ButterworthReader(AUD_IReader* reader,
|
||||
float frequency) :
|
||||
AUD_EffectReader(reader),
|
||||
m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
|
||||
m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * 5),
|
||||
m_position(0)
|
||||
{
|
||||
AUD_Specs specs = reader->getSpecs();
|
||||
memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
|
||||
memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
|
||||
|
||||
// calculate coefficients
|
||||
float omega = 2 * tan(frequency * M_PI / specs.rate);
|
||||
float o2 = omega * omega;
|
||||
float o4 = o2 * o2;
|
||||
float x1 = o2 + 2 * BWPB41 * omega + 4;
|
||||
float x2 = o2 + 2 * BWPB42 * omega + 4;
|
||||
float y1 = o2 - 2 * BWPB41 * omega + 4;
|
||||
float y2 = o2 - 2 * BWPB42 * omega + 4;
|
||||
float o228 = 2 * o2 - 8;
|
||||
float norm = x1 * x2;
|
||||
m_coeff[0][0] = 0;
|
||||
m_coeff[0][1] = (x1 + x2) * o228 / norm;
|
||||
m_coeff[0][2] = (x1 * y2 + x2 * y1 + o228 * o228) / norm;
|
||||
m_coeff[0][3] = (y1 + y2) * o228 / norm;
|
||||
m_coeff[0][4] = y1 * y2 / norm;
|
||||
m_coeff[1][4] = m_coeff[1][0] = o4 / norm;
|
||||
m_coeff[1][3] = m_coeff[1][1] = 4 * o4 / norm;
|
||||
m_coeff[1][2] = 6 * o4 / norm;
|
||||
}
|
||||
|
||||
void AUD_ButterworthReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* outvalues;
|
||||
sample_t* invalues;
|
||||
|
||||
outvalues = m_outvalues.getBuffer();
|
||||
invalues = m_invalues.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
int channels = specs.channels;
|
||||
|
||||
for(int channel = 0; channel < channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
invalues[m_position * CC] = buf[i * CC];
|
||||
outvalues[m_position * CC] = 0;
|
||||
|
||||
for(int j = 0; j < 4; j++)
|
||||
{
|
||||
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||
invalues[((m_position + j) % 5) * CC] -
|
||||
m_coeff[0][j] *
|
||||
outvalues[((m_position + j) % 5) * CC];
|
||||
}
|
||||
|
||||
buffer[i * CC] = outvalues[m_position * CC];
|
||||
|
||||
m_position = (m_position + 4) % 5;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_BUTTERWORTHREADER
|
||||
#define AUD_BUTTERWORTHREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class represents a butterworth filter.
|
||||
*/
|
||||
class AUD_ButterworthReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The last out values buffer.
|
||||
*/
|
||||
AUD_Buffer m_outvalues;
|
||||
|
||||
/**
|
||||
* The last in values buffer.
|
||||
*/
|
||||
AUD_Buffer m_invalues;
|
||||
|
||||
/**
|
||||
* The position for buffer cycling.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* Filter coefficients.
|
||||
*/
|
||||
float m_coeff[2][5];
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_ButterworthReader(const AUD_ButterworthReader&);
|
||||
AUD_ButterworthReader& operator=(const AUD_ButterworthReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new butterworth reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param attack The attack value in seconds.
|
||||
* \param release The release value in seconds.
|
||||
* \param threshold The threshold value.
|
||||
* \param arthreshold The attack/release threshold value.
|
||||
*/
|
||||
AUD_ButterworthReader(AUD_IReader* reader, float frequency);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_BUTTERWORTHREADER
|
@ -23,27 +23,25 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_VolumeReader.h"
|
||||
#include "AUD_CallbackIIRFilterReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_VolumeReader::AUD_VolumeReader(AUD_IReader* reader, float volume) :
|
||||
AUD_EffectReader(reader),
|
||||
m_volume(volume)
|
||||
AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
|
||||
int in, int out,
|
||||
doFilterIIR doFilter,
|
||||
endFilterIIR endFilter,
|
||||
void* data) :
|
||||
AUD_BaseIIRFilterReader(reader, in, out),
|
||||
m_filter(doFilter), m_endFilter(endFilter), m_data(data)
|
||||
{
|
||||
}
|
||||
|
||||
void AUD_VolumeReader::read(int & length, sample_t* & buffer)
|
||||
AUD_CallbackIIRFilterReader::~AUD_CallbackIIRFilterReader()
|
||||
{
|
||||
sample_t* buf;
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
for(int i = 0; i < length * specs.channels; i++)
|
||||
buffer[i] = buf[i] * m_volume;
|
||||
if(m_endFilter)
|
||||
m_endFilter(m_data);
|
||||
}
|
||||
|
||||
sample_t AUD_CallbackIIRFilterReader::filter()
|
||||
{
|
||||
return m_filter(this, m_data);
|
||||
}
|
83
intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
Normal file
83
intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
Normal file
@ -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
|
@ -24,7 +24,31 @@
|
||||
*/
|
||||
|
||||
#include "AUD_EnvelopeFactory.h"
|
||||
#include "AUD_EnvelopeReader.h"
|
||||
#include "AUD_CallbackIIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
struct EnvelopeParameters
|
||||
{
|
||||
float attack;
|
||||
float release;
|
||||
float threshold;
|
||||
float arthreshold;
|
||||
};
|
||||
|
||||
sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
|
||||
{
|
||||
float in = fabs(reader->x(0));
|
||||
float out = reader->y(-1);
|
||||
if(in < param->threshold)
|
||||
in = 0.0f;
|
||||
return (in > out ? param->attack : param->release) * (out - in) + in;
|
||||
}
|
||||
|
||||
void endEnvelopeFilter(EnvelopeParameters* param)
|
||||
{
|
||||
delete param;
|
||||
}
|
||||
|
||||
AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
|
||||
float release, float threshold,
|
||||
@ -39,6 +63,16 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
|
||||
|
||||
AUD_IReader* AUD_EnvelopeFactory::createReader() const
|
||||
{
|
||||
return new AUD_EnvelopeReader(getReader(), m_attack, m_release, m_threshold,
|
||||
m_arthreshold);
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
EnvelopeParameters* param = new EnvelopeParameters();
|
||||
param->arthreshold = m_arthreshold;
|
||||
param->attack = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_attack));
|
||||
param->release = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_release));
|
||||
param->threshold = m_threshold;
|
||||
|
||||
return new AUD_CallbackIIRFilterReader(reader, 1, 2,
|
||||
(doFilterIIR) envelopeFilter,
|
||||
(endFilterIIR) endEnvelopeFilter,
|
||||
param);
|
||||
}
|
||||
|
@ -1,72 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_EnvelopeReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
AUD_EnvelopeReader::AUD_EnvelopeReader(AUD_IReader* reader, float attack,
|
||||
float release, float threshold,
|
||||
float arthreshold) :
|
||||
AUD_EffectReader(reader),
|
||||
m_bAttack(pow(arthreshold, 1.0f/(reader->getSpecs().rate * attack))),
|
||||
m_bRelease(pow(arthreshold, 1.0f/(reader->getSpecs().rate * release))),
|
||||
m_threshold(threshold),
|
||||
m_envelopes(AUD_SAMPLE_SIZE(reader->getSpecs()))
|
||||
{
|
||||
memset(m_envelopes.getBuffer(), 0, m_envelopes.getSize());
|
||||
}
|
||||
|
||||
void AUD_EnvelopeReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* envelopes;
|
||||
envelopes = m_envelopes.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
sample_t value;
|
||||
|
||||
for(int channel = 0; channel < specs.channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
value = fabs(buf[i * specs.channels + channel]);
|
||||
if(value < m_threshold)
|
||||
value = 0.0f;
|
||||
|
||||
buffer[i * specs.channels + channel] = envelopes[channel] =
|
||||
((value > envelopes[channel]) ? m_bAttack : m_bRelease) *
|
||||
(envelopes[channel] - value) + value;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,82 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_ENVELOPEREADER
|
||||
#define AUD_ENVELOPEREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class represents an envelope follower.
|
||||
*/
|
||||
class AUD_EnvelopeReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* Attack b value.
|
||||
*/
|
||||
const float m_bAttack;
|
||||
|
||||
/**
|
||||
* Release b value.
|
||||
*/
|
||||
const float m_bRelease;
|
||||
|
||||
/**
|
||||
* Threshold value.
|
||||
*/
|
||||
const float m_threshold;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The last envelopes buffer.
|
||||
*/
|
||||
AUD_Buffer m_envelopes;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_EnvelopeReader(const AUD_EnvelopeReader&);
|
||||
AUD_EnvelopeReader& operator=(const AUD_EnvelopeReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new envelope reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param attack The attack value in seconds.
|
||||
* \param release The release value in seconds.
|
||||
* \param threshold The threshold value.
|
||||
* \param arthreshold The attack/release threshold value.
|
||||
*/
|
||||
AUD_EnvelopeReader(AUD_IReader* reader, float attack, float release,
|
||||
float threshold, float arthreshold);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_ENVELOPEREADER
|
@ -24,7 +24,13 @@
|
||||
*/
|
||||
|
||||
#include "AUD_HighpassFactory.h"
|
||||
#include "AUD_HighpassReader.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
|
||||
float Q) :
|
||||
@ -36,5 +42,20 @@ AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
|
||||
|
||||
AUD_IReader* AUD_HighpassFactory::createReader() const
|
||||
{
|
||||
return new AUD_HighpassReader(getReader(), m_frequency, m_Q);
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
// calculate coefficients
|
||||
float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
|
||||
float alpha = sin(w0) / (2 * m_Q);
|
||||
float norm = 1 + alpha;
|
||||
float c = cos(w0);
|
||||
std::vector<float> a, b;
|
||||
a.push_back(1);
|
||||
a.push_back(-2 * c / norm);
|
||||
a.push_back((1 - alpha) / norm);
|
||||
b.push_back((1 + c) / (2 * norm));
|
||||
b.push_back((-1 - c) / norm);
|
||||
b.push_back(b[0]);
|
||||
|
||||
return new AUD_IIRFilterReader(reader, b, a);
|
||||
}
|
||||
|
@ -1,100 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_HighpassReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define CC channels + channel
|
||||
|
||||
AUD_HighpassReader::AUD_HighpassReader(AUD_IReader* reader, float frequency,
|
||||
float Q) :
|
||||
AUD_EffectReader(reader),
|
||||
m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
|
||||
m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_HIGHPASS_ORDER),
|
||||
m_position(0)
|
||||
{
|
||||
memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
|
||||
memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
|
||||
|
||||
AUD_Specs specs = reader->getSpecs();
|
||||
|
||||
// calculate coefficients
|
||||
float w0 = 2 * M_PI * frequency / specs.rate;
|
||||
float alpha = sin(w0) / (2 * Q);
|
||||
float norm = 1 + alpha;
|
||||
m_coeff[0][0] = 0;
|
||||
m_coeff[0][1] = -2 * cos(w0) / norm;
|
||||
m_coeff[0][2] = (1 - alpha) / norm;
|
||||
m_coeff[1][2] = m_coeff[1][0] = (1 + cos(w0)) / (2 * norm);
|
||||
m_coeff[1][1] = (-1 - cos(w0)) / norm;
|
||||
}
|
||||
|
||||
void AUD_HighpassReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* outvalues;
|
||||
sample_t* invalues;
|
||||
|
||||
outvalues = m_outvalues.getBuffer();
|
||||
invalues = m_invalues.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
int channels = specs.channels;
|
||||
|
||||
for(int channel = 0; channel < channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
invalues[m_position * CC] = buf[i * CC];
|
||||
outvalues[m_position * CC] = 0;
|
||||
|
||||
for(int j = 0; j < AUD_HIGHPASS_ORDER; j++)
|
||||
{
|
||||
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||
invalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC] -
|
||||
m_coeff[0][j] *
|
||||
outvalues[((m_position + j) % AUD_HIGHPASS_ORDER) * CC];
|
||||
}
|
||||
|
||||
buffer[i * CC] = outvalues[m_position * CC];
|
||||
|
||||
m_position = (m_position + AUD_HIGHPASS_ORDER-1) %
|
||||
AUD_HIGHPASS_ORDER;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_HIGHPASSREADER
|
||||
#define AUD_HIGHPASSREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#define AUD_HIGHPASS_ORDER 3
|
||||
|
||||
/**
|
||||
* This class represents a highpass filter.
|
||||
*/
|
||||
class AUD_HighpassReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The last out values buffer.
|
||||
*/
|
||||
AUD_Buffer m_outvalues;
|
||||
|
||||
/**
|
||||
* The last in values buffer.
|
||||
*/
|
||||
AUD_Buffer m_invalues;
|
||||
|
||||
/**
|
||||
* The position for buffer cycling.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* Filter coefficients.
|
||||
*/
|
||||
float m_coeff[2][AUD_HIGHPASS_ORDER];
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_HighpassReader(const AUD_HighpassReader&);
|
||||
AUD_HighpassReader& operator=(const AUD_HighpassReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new highpass reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param frequency The cutoff frequency.
|
||||
* \param Q The Q factor.
|
||||
*/
|
||||
AUD_HighpassReader(AUD_IReader* reader, float frequency, float Q);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_HIGHPASSREADER
|
@ -23,26 +23,17 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_RectifyReader.h"
|
||||
#include "AUD_IIRFilterFactory.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
AUD_RectifyReader::AUD_RectifyReader(AUD_IReader* reader) :
|
||||
AUD_EffectReader(reader)
|
||||
AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
|
||||
std::vector<float> b,
|
||||
std::vector<float> a) :
|
||||
AUD_EffectFactory(factory), m_a(a), m_b(b)
|
||||
{
|
||||
}
|
||||
|
||||
void AUD_RectifyReader::read(int & length, sample_t* & buffer)
|
||||
AUD_IReader* AUD_IIRFilterFactory::createReader() const
|
||||
{
|
||||
sample_t* buf;
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
for(int i = 0; i < length * specs.channels; i++)
|
||||
buffer[i] = fabs(buf[i]);
|
||||
return new AUD_IIRFilterReader(getReader(), m_b, m_a);
|
||||
}
|
@ -23,41 +23,44 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_VOLUMEREADER
|
||||
#define AUD_VOLUMEREADER
|
||||
#ifndef AUD_IIRFILTERFACTORY
|
||||
#define AUD_IIRFILTERFACTORY
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
#include "AUD_EffectFactory.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* This class reads another reader and changes it's volume.
|
||||
* This factory creates a IIR filter reader.
|
||||
*/
|
||||
class AUD_VolumeReader : public AUD_EffectReader
|
||||
class AUD_IIRFilterFactory : public AUD_EffectFactory
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
* Output filter coefficients.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
std::vector<float> m_a;
|
||||
|
||||
/**
|
||||
* The volume level.
|
||||
* Input filter coefficients.
|
||||
*/
|
||||
const float m_volume;
|
||||
std::vector<float> m_b;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_VolumeReader(const AUD_VolumeReader&);
|
||||
AUD_VolumeReader& operator=(const AUD_VolumeReader&);
|
||||
AUD_IIRFilterFactory(const AUD_IIRFilterFactory&);
|
||||
AUD_IIRFilterFactory& operator=(const AUD_IIRFilterFactory&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new volume reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param volume The size of the buffer.
|
||||
* Creates a new IIR filter factory.
|
||||
* \param factory The input factory.
|
||||
* \param b The input filter coefficients.
|
||||
* \param a The output filter coefficients.
|
||||
*/
|
||||
AUD_VolumeReader(AUD_IReader* reader, float volume);
|
||||
AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
|
||||
std::vector<float> a);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
virtual AUD_IReader* createReader() const;
|
||||
};
|
||||
|
||||
#endif //AUD_VOLUMEREADER
|
||||
#endif //AUD_IIRFILTERFACTORY
|
@ -23,35 +23,28 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_RECTIFYREADER
|
||||
#define AUD_RECTIFYREADER
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class reads another reader and rectifies it.
|
||||
*/
|
||||
class AUD_RectifyReader : public AUD_EffectReader
|
||||
AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
|
||||
std::vector<float> b,
|
||||
std::vector<float> a) :
|
||||
AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
for(int i = 1; i < m_a.size(); i++)
|
||||
m_a[i] /= m_a[0];
|
||||
for(int i = 0; i < m_b.size(); i++)
|
||||
m_b[i] /= m_a[0];
|
||||
m_a[0] = 1;
|
||||
}
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_RectifyReader(const AUD_RectifyReader&);
|
||||
AUD_RectifyReader& operator=(const AUD_RectifyReader&);
|
||||
sample_t AUD_IIRFilterReader::filter()
|
||||
{
|
||||
sample_t out = 0;
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new rectify reader.
|
||||
* \param reader The reader to read from.
|
||||
*/
|
||||
AUD_RectifyReader(AUD_IReader* reader);
|
||||
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];
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_RECTIFYREADER
|
||||
return out;
|
||||
}
|
@ -23,40 +23,44 @@
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_SUMREADER
|
||||
#define AUD_SUMREADER
|
||||
#ifndef AUD_IIRFILTERREADER
|
||||
#define AUD_IIRFILTERREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
#include "AUD_BaseIIRFilterReader.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
/**
|
||||
* This class represents an summer.
|
||||
* This class is for infinite impulse response filters with simple coefficients.
|
||||
*/
|
||||
class AUD_SumReader : public AUD_EffectReader
|
||||
class AUD_IIRFilterReader : public AUD_BaseIIRFilterReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
* Output filter coefficients.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
std::vector<float> m_a;
|
||||
|
||||
/**
|
||||
* The sums of the specific channels.
|
||||
* Input filter coefficients.
|
||||
*/
|
||||
AUD_Buffer m_sums;
|
||||
std::vector<float> m_b;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_SumReader(const AUD_SumReader&);
|
||||
AUD_SumReader& operator=(const AUD_SumReader&);
|
||||
AUD_IIRFilterReader(const AUD_IIRFilterReader&);
|
||||
AUD_IIRFilterReader& operator=(const AUD_IIRFilterReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new sum reader.
|
||||
* Creates a new IIR filter reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param b The input filter coefficients.
|
||||
* \param a The output filter coefficients.
|
||||
*/
|
||||
AUD_SumReader(AUD_IReader* reader);
|
||||
AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
|
||||
std::vector<float> a);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
virtual sample_t filter();
|
||||
};
|
||||
|
||||
#endif //AUD_SUMREADER
|
||||
#endif //AUD_IIRFILTERREADER
|
@ -24,7 +24,13 @@
|
||||
*/
|
||||
|
||||
#include "AUD_LowpassFactory.h"
|
||||
#include "AUD_LowpassReader.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
|
||||
float Q) :
|
||||
@ -36,5 +42,20 @@ AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
|
||||
|
||||
AUD_IReader* AUD_LowpassFactory::createReader() const
|
||||
{
|
||||
return new AUD_LowpassReader(getReader(), m_frequency, m_Q);
|
||||
AUD_IReader* reader = getReader();
|
||||
|
||||
// calculate coefficients
|
||||
float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
|
||||
float alpha = sin(w0) / (2 * m_Q);
|
||||
float norm = 1 + alpha;
|
||||
float c = cos(w0);
|
||||
std::vector<float> a, b;
|
||||
a.push_back(1);
|
||||
a.push_back(-2 * c / norm);
|
||||
a.push_back((1 - alpha) / norm);
|
||||
b.push_back((1 - c) / (2 * norm));
|
||||
b.push_back((1 - c) / norm);
|
||||
b.push_back(b[0]);
|
||||
|
||||
return new AUD_IIRFilterReader(reader, b, a);
|
||||
}
|
||||
|
@ -1,99 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_LowpassReader.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <cmath>
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846
|
||||
#endif
|
||||
|
||||
#define CC channels + channel
|
||||
|
||||
AUD_LowpassReader::AUD_LowpassReader(AUD_IReader* reader, float frequency,
|
||||
float Q) :
|
||||
AUD_EffectReader(reader),
|
||||
m_outvalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
|
||||
m_invalues(AUD_SAMPLE_SIZE(reader->getSpecs()) * AUD_LOWPASS_ORDER),
|
||||
m_position(0)
|
||||
{
|
||||
memset(m_outvalues.getBuffer(), 0, m_outvalues.getSize());
|
||||
memset(m_invalues.getBuffer(), 0, m_invalues.getSize());
|
||||
|
||||
AUD_Specs specs = reader->getSpecs();
|
||||
|
||||
// calculate coefficients
|
||||
float w0 = 2 * M_PI * frequency / specs.rate;
|
||||
float alpha = sin(w0) / (2 * Q);
|
||||
float norm = 1 + alpha;
|
||||
m_coeff[0][0] = 0;
|
||||
m_coeff[0][1] = -2 * cos(w0) / norm;
|
||||
m_coeff[0][2] = (1 - alpha) / norm;
|
||||
m_coeff[1][2] = m_coeff[1][0] = (1 - cos(w0)) / (2 * norm);
|
||||
m_coeff[1][1] = (1 - cos(w0)) / norm;
|
||||
}
|
||||
|
||||
void AUD_LowpassReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* outvalues;
|
||||
sample_t* invalues;
|
||||
|
||||
outvalues = m_outvalues.getBuffer();
|
||||
invalues = m_invalues.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
int channels = specs.channels;
|
||||
|
||||
for(int channel = 0; channel < channels; channel++)
|
||||
{
|
||||
for(int i = 0; i < length; i++)
|
||||
{
|
||||
invalues[m_position * CC] = buf[i * CC];
|
||||
outvalues[m_position * CC] = 0;
|
||||
|
||||
for(int j = 0; j < AUD_LOWPASS_ORDER; j++)
|
||||
{
|
||||
outvalues[m_position * CC] += m_coeff[1][j] *
|
||||
invalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC] -
|
||||
m_coeff[0][j] *
|
||||
outvalues[((m_position + j) % AUD_LOWPASS_ORDER) * CC];
|
||||
}
|
||||
|
||||
buffer[i * CC] = outvalues[m_position * CC];
|
||||
|
||||
m_position = (m_position + AUD_LOWPASS_ORDER-1) % AUD_LOWPASS_ORDER;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,81 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_LOWPASSREADER
|
||||
#define AUD_LOWPASSREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
#define AUD_LOWPASS_ORDER 3
|
||||
|
||||
/**
|
||||
* This class represents a lowpass filter.
|
||||
*/
|
||||
class AUD_LowpassReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The last out values buffer.
|
||||
*/
|
||||
AUD_Buffer m_outvalues;
|
||||
|
||||
/**
|
||||
* The last in values buffer.
|
||||
*/
|
||||
AUD_Buffer m_invalues;
|
||||
|
||||
/**
|
||||
* The position for buffer cycling.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* Filter coefficients.
|
||||
*/
|
||||
float m_coeff[2][AUD_LOWPASS_ORDER];
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_LowpassReader(const AUD_LowpassReader&);
|
||||
AUD_LowpassReader& operator=(const AUD_LowpassReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new lowpass reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param frequency The cutoff frequency.
|
||||
* \param Q The Q factor.
|
||||
*/
|
||||
AUD_LowpassReader(AUD_IReader* reader, float frequency, float Q);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_LOWPASSREADER
|
@ -24,7 +24,14 @@
|
||||
*/
|
||||
|
||||
#include "AUD_RectifyFactory.h"
|
||||
#include "AUD_RectifyReader.h"
|
||||
#include "AUD_CallbackIIRFilterReader.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
|
||||
{
|
||||
return fabs(reader->x(0));
|
||||
}
|
||||
|
||||
AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
|
||||
AUD_EffectFactory(factory)
|
||||
@ -33,5 +40,5 @@ AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
|
||||
|
||||
AUD_IReader* AUD_RectifyFactory::createReader() const
|
||||
{
|
||||
return new AUD_RectifyReader(getReader());
|
||||
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
|
||||
}
|
||||
|
@ -24,7 +24,23 @@
|
||||
*/
|
||||
|
||||
#include "AUD_SquareFactory.h"
|
||||
#include "AUD_SquareReader.h"
|
||||
#include "AUD_CallbackIIRFilterReader.h"
|
||||
|
||||
sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
|
||||
{
|
||||
float in = reader->x(0);
|
||||
if(in >= *threshold)
|
||||
return 1;
|
||||
else if(in <= -*threshold)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void endSquareFilter(float* threshold)
|
||||
{
|
||||
delete threshold;
|
||||
}
|
||||
|
||||
AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
|
||||
AUD_EffectFactory(factory),
|
||||
@ -39,5 +55,8 @@ float AUD_SquareFactory::getThreshold() const
|
||||
|
||||
AUD_IReader* AUD_SquareFactory::createReader() const
|
||||
{
|
||||
return new AUD_SquareReader(getReader(), m_threshold);
|
||||
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
|
||||
(doFilterIIR) squareFilter,
|
||||
(endFilterIIR) endSquareFilter,
|
||||
new float(m_threshold));
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SquareReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_SquareReader::AUD_SquareReader(AUD_IReader* reader, float threshold) :
|
||||
AUD_EffectReader(reader),
|
||||
m_threshold(threshold)
|
||||
{
|
||||
}
|
||||
|
||||
void AUD_SquareReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
for(int i = 0; i < length * specs.channels; i++)
|
||||
{
|
||||
if(buf[i] >= m_threshold)
|
||||
buffer[i] = 1.0f;
|
||||
else if(buf[i] <= -m_threshold)
|
||||
buffer[i] = -1.0f;
|
||||
else
|
||||
buffer[i] = 0.0f;
|
||||
}
|
||||
}
|
@ -1,63 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef AUD_SQUAREREADER
|
||||
#define AUD_SQUAREREADER
|
||||
|
||||
#include "AUD_EffectReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class changes another signal into a square signal.
|
||||
*/
|
||||
class AUD_SquareReader : public AUD_EffectReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
/**
|
||||
* The threshold level.
|
||||
*/
|
||||
const float m_threshold;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_SquareReader(const AUD_SquareReader&);
|
||||
AUD_SquareReader& operator=(const AUD_SquareReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new square reader.
|
||||
* \param reader The reader to read from.
|
||||
* \param threshold The size of the buffer.
|
||||
*/
|
||||
AUD_SquareReader(AUD_IReader* reader, float threshold);
|
||||
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_SQUAREREADER
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "AUD_SumFactory.h"
|
||||
#include "AUD_SumReader.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
|
||||
AUD_EffectFactory(factory)
|
||||
@ -33,5 +33,9 @@ AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
|
||||
|
||||
AUD_IReader* AUD_SumFactory::createReader() const
|
||||
{
|
||||
return new AUD_SumReader(getReader());
|
||||
std::vector<float> a, b;
|
||||
a.push_back(1);
|
||||
a.push_back(-1);
|
||||
b.push_back(1);
|
||||
return new AUD_IIRFilterReader(getReader(), b, a);
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SumReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
#define CC specs.channels + channel
|
||||
|
||||
AUD_SumReader::AUD_SumReader(AUD_IReader* reader) :
|
||||
AUD_EffectReader(reader),
|
||||
m_sums(AUD_SAMPLE_SIZE(reader->getSpecs()))
|
||||
{
|
||||
memset(m_sums.getBuffer(), 0, m_sums.getSize());
|
||||
}
|
||||
|
||||
void AUD_SumReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
sample_t* buf;
|
||||
sample_t* sums;
|
||||
sums = m_sums.getBuffer();
|
||||
|
||||
AUD_Specs specs = m_reader->getSpecs();
|
||||
|
||||
m_reader->read(length, buf);
|
||||
|
||||
if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(specs))
|
||||
m_buffer.resize(length * AUD_SAMPLE_SIZE(specs));
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
|
||||
for(int channel = 0; channel < specs.channels; channel++)
|
||||
for(int i = 0; i < length * specs.channels; i++)
|
||||
buffer[i * CC] = sums[channel] = sums[channel] + buf[i * CC];
|
||||
}
|
@ -24,7 +24,7 @@
|
||||
*/
|
||||
|
||||
#include "AUD_VolumeFactory.h"
|
||||
#include "AUD_VolumeReader.h"
|
||||
#include "AUD_IIRFilterReader.h"
|
||||
|
||||
AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
|
||||
AUD_EffectFactory(factory),
|
||||
@ -39,5 +39,8 @@ float AUD_VolumeFactory::getVolume() const
|
||||
|
||||
AUD_IReader* AUD_VolumeFactory::createReader() const
|
||||
{
|
||||
return new AUD_VolumeReader(getReader(), m_volume);
|
||||
std::vector<float> a, b;
|
||||
a.push_back(1);
|
||||
b.push_back(m_volume);
|
||||
return new AUD_IIRFilterReader(getReader(), b, a);
|
||||
}
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include "AUD_StreamBufferFactory.h"
|
||||
#include "AUD_SuperposeFactory.h"
|
||||
#include "AUD_VolumeFactory.h"
|
||||
#include "AUD_IIRFilterFactory.h"
|
||||
|
||||
#ifdef WITH_SDL
|
||||
#include "AUD_SDLDevice.h"
|
||||
@ -142,10 +143,12 @@ static PyObject *
|
||||
Sound_file(PyObject* nothing, PyObject* args);
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_lowpass_doc,
|
||||
"lowpass(frequency)\n\n"
|
||||
"Creates a low quality lowpass filter.\n\n"
|
||||
"lowpass(frequency[, Q])\n\n"
|
||||
"Creates a second order lowpass filter.\n\n"
|
||||
":arg frequency: The cut off trequency of the lowpass.\n"
|
||||
":type frequency: float\n"
|
||||
":arg Q: Q factor of the lowpass.\n"
|
||||
":type Q: float\n"
|
||||
":return: The created aud.Sound object.\n"
|
||||
":rtype: aud.Sound");
|
||||
|
||||
@ -177,10 +180,12 @@ static PyObject *
|
||||
Sound_join(Sound* self, PyObject* object);
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_highpass_doc,
|
||||
"highpass(frequency)\n\n"
|
||||
"Creates a low quality highpass filter.\n\n"
|
||||
"highpass(frequency[, Q])\n\n"
|
||||
"Creates a second order highpass filter.\n\n"
|
||||
":arg frequency: The cut off trequency of the highpass.\n"
|
||||
":type frequency: float\n"
|
||||
":arg Q: Q factor of the lowpass.\n"
|
||||
":type Q: float\n"
|
||||
":return: The created aud.Sound object.\n"
|
||||
":rtype: aud.Sound");
|
||||
|
||||
@ -322,6 +327,19 @@ PyDoc_STRVAR(M_aud_Sound_square_doc,
|
||||
static PyObject *
|
||||
Sound_square(Sound* self, PyObject* args);
|
||||
|
||||
PyDoc_STRVAR(M_aud_Sound_filter_doc,
|
||||
"filter(b[, a = (1)])\n\n"
|
||||
"Filters a sound with the supplied IIR filter coefficients.\n\n"
|
||||
":arg b: The nominator filter coefficients.\n"
|
||||
":type b: sequence of float\n"
|
||||
":arg a: The denominator filter coefficients.\n"
|
||||
":type a: sequence of float\n"
|
||||
":return: The created aud.Sound object.\n"
|
||||
":rtype: aud.Sound");
|
||||
|
||||
static PyObject *
|
||||
Sound_filter(Sound* self, PyObject* args);
|
||||
|
||||
static PyMethodDef Sound_methods[] = {
|
||||
{"sine", (PyCFunction)Sound_sine, METH_VARARGS | METH_STATIC,
|
||||
M_aud_Sound_sine_doc
|
||||
@ -374,6 +392,9 @@ static PyMethodDef Sound_methods[] = {
|
||||
{"square", (PyCFunction)Sound_square, METH_VARARGS,
|
||||
M_aud_Sound_square_doc
|
||||
},
|
||||
{"filter", (PyCFunction)Sound_filter, METH_VARARGS,
|
||||
M_aud_Sound_filter_doc
|
||||
},
|
||||
{NULL} /* Sentinel */
|
||||
};
|
||||
|
||||
@ -483,8 +504,9 @@ static PyObject *
|
||||
Sound_lowpass(Sound* self, PyObject* args)
|
||||
{
|
||||
float frequency;
|
||||
float Q = 0.5;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "f", &frequency))
|
||||
if(!PyArg_ParseTuple(args, "f|f", &frequency, &Q))
|
||||
return NULL;
|
||||
|
||||
Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
|
||||
@ -496,7 +518,7 @@ Sound_lowpass(Sound* self, PyObject* args)
|
||||
|
||||
try
|
||||
{
|
||||
parent->factory = new AUD_LowpassFactory(self->factory, frequency, 0.9);
|
||||
parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
@ -574,8 +596,9 @@ static PyObject *
|
||||
Sound_highpass(Sound* self, PyObject* args)
|
||||
{
|
||||
float frequency;
|
||||
float Q = 0.5;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "f", &frequency))
|
||||
if(!PyArg_ParseTuple(args, "f|f", &frequency, &Q))
|
||||
return NULL;
|
||||
|
||||
Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
|
||||
@ -587,7 +610,7 @@ Sound_highpass(Sound* self, PyObject* args)
|
||||
|
||||
try
|
||||
{
|
||||
parent->factory = new AUD_HighpassFactory(self->factory, frequency, 0.9);
|
||||
parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
@ -919,6 +942,86 @@ Sound_square(Sound* self, PyObject* args)
|
||||
return (PyObject *)parent;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
Sound_filter(Sound* self, PyObject* args)
|
||||
{
|
||||
PyObject* py_b;
|
||||
PyObject* py_a = NULL;
|
||||
|
||||
if(!PyArg_ParseTuple(args, "O|O", &py_b, &py_a))
|
||||
return NULL;
|
||||
|
||||
if(!PySequence_Check(py_b) || (py_a != NULL && !PySequence_Check(py_a)))
|
||||
{
|
||||
PyErr_SetString(AUDError, "Supplied parameter is not a sequence!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!PySequence_Length(py_b) || (py_a != NULL && !PySequence_Length(py_a)))
|
||||
{
|
||||
PyErr_SetString(AUDError, "The sequence has to contain at least one value!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
std::vector<float> a, b;
|
||||
PyObject* py_value;
|
||||
float value;
|
||||
int result;
|
||||
|
||||
for(int i = 0; i < PySequence_Length(py_b); i++)
|
||||
{
|
||||
py_value = PySequence_GetItem(py_b, i);
|
||||
result = PyArg_Parse(py_value, "f", &value);
|
||||
Py_DECREF(py_value);
|
||||
|
||||
if(!result)
|
||||
return NULL;
|
||||
|
||||
b.push_back(value);
|
||||
}
|
||||
|
||||
if(py_a)
|
||||
{
|
||||
for(int i = 0; i < PySequence_Length(py_a); i++)
|
||||
{
|
||||
py_value = PySequence_GetItem(py_a, i);
|
||||
result = PyArg_Parse(py_value, "f", &value);
|
||||
Py_DECREF(py_value);
|
||||
|
||||
if(!result)
|
||||
return NULL;
|
||||
|
||||
a.push_back(value);
|
||||
}
|
||||
|
||||
if(a[0] == 0)
|
||||
a[0] = 1;
|
||||
}
|
||||
else
|
||||
a.push_back(1);
|
||||
|
||||
Sound *parent = (Sound*)SoundType.tp_alloc(&SoundType, 0);
|
||||
|
||||
if(parent != NULL)
|
||||
{
|
||||
Py_INCREF(self);
|
||||
parent->child_list = (PyObject*)self;
|
||||
|
||||
try
|
||||
{
|
||||
parent->factory = new AUD_IIRFilterFactory(self->factory, b, a);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
Py_DECREF(parent);
|
||||
PyErr_SetString(AUDError, "IIRFilterFactory couldn't be created!");
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return (PyObject *)parent;
|
||||
}
|
||||
|
||||
// ========== Handle ==================================================
|
||||
|
||||
static void
|
||||
|
@ -1138,9 +1138,10 @@ int main(int argc, char **argv)
|
||||
|
||||
else {
|
||||
if((G.fileflags & G_FILE_AUTOPLAY) && (G.f & G_SCRIPT_AUTOEXEC))
|
||||
{
|
||||
if(WM_init_game(C))
|
||||
return 0;
|
||||
|
||||
}
|
||||
else if(!G.file_loaded)
|
||||
WM_init_splash(C);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user