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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoerg Mueller <nexyon@gmail.com>2010-01-01 08:09:30 +0300
committerJoerg Mueller <nexyon@gmail.com>2010-01-01 08:09:30 +0300
commit174eccf07851c4e7f669b194cd8951ca98bc5c81 (patch)
tree42d11467df2d006fcbaa562023ffe09796879716
parent3fa927a42e893709ac78f7d9419c22979b05bf3f (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.
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp49
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h59
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.cpp120
-rw-r--r--intern/audaspace/FX/AUD_ButterworthReader.h83
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp21
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp9
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp58
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h82
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.cpp86
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeReader.h84
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp59
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h6
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp51
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h (renamed from intern/audaspace/SDL/AUD_SDLMixer.h)52
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.cpp112
-rw-r--r--intern/audaspace/FX/AUD_HighpassReader.h83
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp12
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp51
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h66
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.cpp111
-rw-r--r--intern/audaspace/FX/AUD_LowpassReader.h83
-rw-r--r--intern/audaspace/FX/AUD_RectifyReader.cpp37
-rw-r--r--intern/audaspace/FX/AUD_RectifyReader.h6
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp18
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.cpp32
-rw-r--r--intern/audaspace/FX/AUD_VolumeReader.h6
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp106
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h13
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.cpp8
-rw-r--r--intern/audaspace/SDL/AUD_SDLDevice.h3
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixer.cpp83
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.cpp216
-rw-r--r--intern/audaspace/SDL/AUD_SDLMixerReader.h128
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp8
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h7
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp25
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h8
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp195
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h13
-rw-r--r--intern/audaspace/fftw/AUD_BandPassFactory.cpp12
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.cpp6
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp8
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h2
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp6
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp67
-rw-r--r--intern/audaspace/intern/AUD_C-API.h14
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h6
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp12
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp8
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h6
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp164
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.h125
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp195
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h4
-rw-r--r--intern/audaspace/intern/AUD_FloatMixer.h100
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h2
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp (renamed from intern/audaspace/SDL/AUD_SDLMixerFactory.cpp)40
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h (renamed from intern/audaspace/SDL/AUD_SDLMixerFactory.h)19
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp138
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h94
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp (renamed from intern/audaspace/intern/AUD_FloatMixer.cpp)44
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h (renamed from intern/audaspace/intern/AUD_IMixer.h)76
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp10
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h12
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp2
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h4
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp12
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.h4
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp19
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp19
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h18
-rw-r--r--intern/audaspace/intern/AUD_Space.h36
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp4
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp9
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.h2
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp61
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h5
-rw-r--r--source/blender/blenkernel/BKE_sound.h2
-rw-r--r--source/blender/blenkernel/intern/sequencer.c2
-rw-r--r--source/blender/blenkernel/intern/sound.c4
-rw-r--r--source/blender/blenkernel/intern/writeffmpeg.c2
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_graph/graph_edit.c135
-rw-r--r--source/blender/editors/space_graph/graph_intern.h1
-rw-r--r--source/blender/editors/space_graph/graph_ops.c1
86 files changed, 2159 insertions, 1610 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/SDL/AUD_SDLMixer.h b/intern/audaspace/FX/AUD_HighpassFactory.h
index 2cc4e51f66d..cce21eed27d 100644
--- a/intern/audaspace/SDL/AUD_SDLMixer.h
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -23,54 +23,44 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_SDLMIXER
-#define AUD_SDLMIXER
+#ifndef AUD_HIGHPASSFACTORY
+#define AUD_HIGHPASSFACTORY
-#include "AUD_IMixer.h"
-class AUD_SDLMixerFactory;
-#include <list>
-
-struct AUD_SDLMixerBuffer
-{
- sample_t* buffer;
- int length;
- float volume;
-};
+#include "AUD_EffectFactory.h"
/**
- * This class is able to mix audiosignals with the help of SDL.
+ * This factory creates a highpass filter reader.
*/
-class AUD_SDLMixer : public AUD_IMixer
+class AUD_HighpassFactory : public AUD_EffectFactory
{
private:
/**
- * The mixer factory that prepares all readers for superposition.
+ * The attack value in seconds.
*/
- AUD_SDLMixerFactory* m_factory;
+ float m_frequency;
/**
- * The list of buffers to superpose.
+ * The Q factor.
*/
- std::list<AUD_SDLMixerBuffer> m_buffers;
+ float m_Q;
+public:
/**
- * The size of an output sample.
+ * Creates a new highpass factory.
+ * \param factory The input factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
*/
- int m_samplesize;
+ AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0);
-public:
/**
- * Creates the mixer.
+ * Creates a new highpass factory.
+ * \param frequency The cutoff frequency.
+ * \param Q The Q factor.
*/
- AUD_SDLMixer();
-
- virtual ~AUD_SDLMixer();
+ AUD_HighpassFactory(float frequency, float Q = 1.0);
- virtual AUD_IReader* prepare(AUD_IReader* reader);
- virtual void setSpecs(AUD_Specs specs);
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume);
- virtual void superpose(sample_t* buffer, int length, float volume);
+ virtual AUD_IReader* createReader();
};
-#endif //AUD_SDLMIXER
+#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.
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index aa9f425d6fb..dfd5d29e4aa 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -25,7 +25,6 @@
#include "AUD_OpenALDevice.h"
#include "AUD_IReader.h"
-#include "AUD_IMixer.h"
#include "AUD_ConverterFactory.h"
#include "AUD_SourceCaps.h"
@@ -119,7 +118,7 @@ void AUD_OpenALDevice::updateStreams()
sample_t* buffer;
ALint info;
- AUD_Specs specs;
+ AUD_DeviceSpecs specs = m_specs;
while(1)
{
@@ -145,7 +144,7 @@ void AUD_OpenALDevice::updateStreams()
if(info)
{
- specs = sound->reader->getSpecs();
+ specs.specs = sound->reader->getSpecs();
// for all empty buffers
while(info--)
@@ -177,8 +176,8 @@ void AUD_OpenALDevice::updateStreams()
// fill with new data
alBufferData(sound->buffers[sound->current],
sound->format,
- buffer,
- length * AUD_SAMPLE_SIZE(specs),
+ buffer, length *
+ AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
@@ -264,7 +263,7 @@ bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
return false;
}
-AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
+AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
{
// cannot determine how many channels or which format OpenAL uses, but
// it at least is able to play 16 bit stereo audio
@@ -289,14 +288,17 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_Specs specs, int buffersize)
// check for specific formats and channel counts to be played back
if(alIsExtensionPresent("AL_EXT_FLOAT32") == AL_TRUE)
+ {
specs.format = AUD_FORMAT_FLOAT32;
+ m_converter = NULL;
+ }
+ else
+ m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
m_useMC = alIsExtensionPresent("AL_EXT_MCFORMATS") == AL_TRUE;
alGetError();
- m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
-
m_specs = specs;
m_buffersize = buffersize;
m_playing = false;
@@ -378,12 +380,13 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
alcDestroyContext(m_context);
alcCloseDevice(m_device);
- delete m_converter; AUD_DELETE("factory")
+ if(m_converter)
+ delete m_converter; AUD_DELETE("factory")
pthread_mutex_destroy(&m_mutex);
}
-AUD_Specs AUD_OpenALDevice::getSpecs()
+AUD_DeviceSpecs AUD_OpenALDevice::getSpecs()
{
return m_specs;
}
@@ -393,45 +396,8 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
bool valid = true;
format = 0;
- switch(specs.format)
+ switch(m_specs.format)
{
- case AUD_FORMAT_U8:
- switch(specs.channels)
- {
- case AUD_CHANNELS_MONO:
- format = AL_FORMAT_MONO8;
- break;
- case AUD_CHANNELS_STEREO:
- format = AL_FORMAT_STEREO8;
- break;
- case AUD_CHANNELS_SURROUND4:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_QUAD8");
- break;
- }
- case AUD_CHANNELS_SURROUND51:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_51CHN8");
- break;
- }
- case AUD_CHANNELS_SURROUND61:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_61CHN8");
- break;
- }
- case AUD_CHANNELS_SURROUND71:
- if(m_useMC)
- {
- format = alGetEnumValue("AL_FORMAT_71CHN8");
- break;
- }
- default:
- valid = false;
- }
- break;
case AUD_FORMAT_S16:
switch(specs.channels)
{
@@ -591,23 +557,16 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
if(reader == NULL)
AUD_THROW(AUD_ERROR_READER);
- AUD_Specs specs;
-
- specs = reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = reader->getSpecs();
// check format
- bool valid = true;
+ bool valid = specs.channels != AUD_CHANNELS_INVALID;
- if(specs.format == AUD_FORMAT_INVALID)
- valid = false;
- else if(specs.format == AUD_FORMAT_S24 ||
- specs.format == AUD_FORMAT_S32 ||
- specs.format == AUD_FORMAT_FLOAT32 ||
- specs.format == AUD_FORMAT_FLOAT64)
+ if(m_converter)
{
m_converter->setReader(reader);
reader = m_converter->createReader();
- specs = reader->getSpecs();
}
// create the handle
@@ -618,7 +577,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
sound->isBuffered = false;
sound->data_end = false;
- valid &= getFormat(sound->format, specs);
+ valid &= getFormat(sound->format, specs.specs);
if(!valid)
{
@@ -647,7 +606,8 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
length = m_buffersize;
reader->read(length, buf);
alBufferData(sound->buffers[i], sound->format, buf,
- length * AUD_SAMPLE_SIZE(specs), specs.rate);
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
+ specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
}
@@ -875,14 +835,16 @@ bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
{
sample_t* buf;
int length;
- AUD_Specs specs = alhandle->reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = alhandle->reader->getSpecs();
for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
{
length = m_buffersize;
alhandle->reader->read(length, buf);
alBufferData(alhandle->buffers[i], alhandle->format,
- buf, length * AUD_SAMPLE_SIZE(specs),
+ buf,
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
@@ -1021,6 +983,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
// load the factory into an OpenAL buffer
if(factory)
{
+ // check if the factory is already buffered
lock();
for(AUD_BFIterator i = m_bufferedFactories->begin();
i != m_bufferedFactories->end(); i++)
@@ -1040,32 +1003,25 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
if(reader == NULL)
return false;
- AUD_Specs specs;
-
- specs = reader->getSpecs();
+ AUD_DeviceSpecs specs = m_specs;
+ specs.specs = reader->getSpecs();
// determine format
bool valid = reader->getType() == AUD_TYPE_BUFFER;
if(valid)
{
- if(specs.format == AUD_FORMAT_INVALID)
- valid = false;
- else if(specs.format == AUD_FORMAT_S24 ||
- specs.format == AUD_FORMAT_S32 ||
- specs.format == AUD_FORMAT_FLOAT32 ||
- specs.format == AUD_FORMAT_FLOAT64)
+ if(m_converter)
{
m_converter->setReader(reader);
reader = m_converter->createReader();
- specs = reader->getSpecs();
}
}
ALenum format;
if(valid)
- valid = getFormat(format, specs);
+ valid = getFormat(format, specs.specs);
if(!valid)
{
@@ -1094,7 +1050,7 @@ bool AUD_OpenALDevice::setCapability(int capability, void *value)
reader->read(length, buf);
alBufferData(bf->buffer, format, buf,
- length * AUD_SAMPLE_SIZE(specs),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 074cd3d1924..cb8c83ab810 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -56,7 +56,7 @@ private:
/**
* The specification of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Whether the device has the AL_EXT_MCFORMATS extension.
@@ -64,8 +64,8 @@ private:
bool m_useMC;
/**
- * The converter factory for readers with wrong input format.
- */
+ * The converter factory for readers with wrong input format.
+ */
AUD_ConverterFactory* m_converter;
/**
@@ -118,7 +118,7 @@ private:
/**
* Gets the format according to the specs.
* \param format The variable to put the format into.
- * \param specs The specs to read the format from.
+ * \param specs The specs to read the channel count from.
* \return Whether the format is valid or not.
*/
bool getFormat(ALenum &format, AUD_Specs specs);
@@ -132,7 +132,8 @@ public:
* \note The buffersize will be multiplicated by three for this device.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_OpenALDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ AUD_OpenALDevice(AUD_DeviceSpecs specs,
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Streaming thread main function.
@@ -141,7 +142,7 @@ public:
virtual ~AUD_OpenALDevice();
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.cpp b/intern/audaspace/SDL/AUD_SDLDevice.cpp
index dd443e7f5c7..1a385af8a0c 100644
--- a/intern/audaspace/SDL/AUD_SDLDevice.cpp
+++ b/intern/audaspace/SDL/AUD_SDLDevice.cpp
@@ -23,7 +23,6 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_SDLMixer.h"
#include "AUD_SDLDevice.h"
#include "AUD_IReader.h"
@@ -31,10 +30,10 @@ void AUD_SDLDevice::SDL_mix(void *data, Uint8* buffer, int length)
{
AUD_SDLDevice* device = (AUD_SDLDevice*)data;
- device->mix((sample_t*)buffer, length/AUD_SAMPLE_SIZE(device->m_specs));
+ device->mix((data_t*)buffer,length/AUD_DEVICE_SAMPLE_SIZE(device->m_specs));
}
-AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
+AUD_SDLDevice::AUD_SDLDevice(AUD_DeviceSpecs specs, int buffersize)
{
if(specs.channels == AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO;
@@ -69,9 +68,6 @@ AUD_SDLDevice::AUD_SDLDevice(AUD_Specs specs, int buffersize)
else
AUD_THROW(AUD_ERROR_SDL);
- m_mixer = new AUD_SDLMixer(); AUD_NEW("mixer")
- m_mixer->setSpecs(m_specs);
-
create();
}
diff --git a/intern/audaspace/SDL/AUD_SDLDevice.h b/intern/audaspace/SDL/AUD_SDLDevice.h
index e2c6f7631b7..4b7de1996e8 100644
--- a/intern/audaspace/SDL/AUD_SDLDevice.h
+++ b/intern/audaspace/SDL/AUD_SDLDevice.h
@@ -55,7 +55,8 @@ public:
* \note The specification really used for opening the device may differ.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_SDLDevice(AUD_Specs specs, int buffersize = AUD_DEFAULT_BUFFER_SIZE);
+ AUD_SDLDevice(AUD_DeviceSpecs specs,
+ int buffersize = AUD_DEFAULT_BUFFER_SIZE);
/**
* Closes the SDL audio device.
diff --git a/intern/audaspace/SDL/AUD_SDLMixer.cpp b/intern/audaspace/SDL/AUD_SDLMixer.cpp
deleted file mode 100644
index cacc0c7063c..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixer.cpp
+++ /dev/null
@@ -1,83 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#include "AUD_SDLMixer.h"
-#include "AUD_SDLMixerFactory.h"
-
-#include <SDL.h>
-
-AUD_SDLMixer::AUD_SDLMixer()
-{
- m_factory = NULL;
-}
-
-AUD_SDLMixer::~AUD_SDLMixer()
-{
- if(m_factory)
- {
- delete m_factory; AUD_DELETE("factory")
- }
-}
-
-AUD_IReader* AUD_SDLMixer::prepare(AUD_IReader* reader)
-{
- m_factory->setReader(reader);
- return m_factory->createReader();
-}
-
-void AUD_SDLMixer::setSpecs(AUD_Specs specs)
-{
- m_samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_factory)
- {
- delete m_factory; AUD_DELETE("factory")
- }
- m_factory = new AUD_SDLMixerFactory(specs); AUD_NEW("factory")
-}
-
-void AUD_SDLMixer::add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)
-{
- AUD_SDLMixerBuffer buf;
- buf.buffer = buffer;
- buf.length = length;
- buf.volume = volume;
- m_buffers.push_back(buf);
-}
-
-void AUD_SDLMixer::superpose(sample_t* buffer, int length, float volume)
-{
- AUD_SDLMixerBuffer buf;
-
- while(!m_buffers.empty())
- {
- buf = m_buffers.front();
- m_buffers.pop_front();
- SDL_MixAudio((Uint8*)buffer,
- (Uint8*)buf.buffer,
- buf.length * m_samplesize,
- (int)(SDL_MIX_MAXVOLUME * volume * buf.volume));
- }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp b/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
deleted file mode 100644
index 0a47e36533a..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixerReader.cpp
+++ /dev/null
@@ -1,216 +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_SDLMixerReader.h"
-#include "AUD_Buffer.h"
-
-#include <cstring>
-
-inline Uint16 AUD_TO_SDL(AUD_SampleFormat format)
-{
- // SDL only supports 8 and 16 bit audio
- switch(format)
- {
- case AUD_FORMAT_U8:
- return AUDIO_U8;
- case AUD_FORMAT_S16:
- return AUDIO_S16SYS;
- default:
- AUD_THROW(AUD_ERROR_SDL);
- }
-}
-
-// greatest common divisor
-inline int gcd(int a, int b)
-{
- int c;
-
- // make sure a is the bigger
- if(b > a)
- {
- c = b;
- b = a;
- a = c;
- }
-
- // greetings from Euclides
- while(b != 0)
- {
- c = a % b;
- a = b;
- b = c;
- }
- return a;
-}
-
-AUD_SDLMixerReader::AUD_SDLMixerReader(AUD_IReader* reader,
- AUD_Specs specs)
-{
- if(reader == NULL)
- AUD_THROW(AUD_ERROR_READER);
-
- m_reader = reader;
- m_tspecs = specs;
- m_sspecs = reader->getSpecs();
-
- try
- {
- // SDL only supports 8 and 16 bit sample formats
- if(SDL_BuildAudioCVT(&m_cvt,
- AUD_TO_SDL(m_sspecs.format),
- m_sspecs.channels,
- m_sspecs.rate,
- AUD_TO_SDL(specs.format),
- specs.channels,
- specs.rate) == -1)
- AUD_THROW(AUD_ERROR_SDL);
- }
- catch(AUD_Exception)
- {
- delete m_reader; AUD_DELETE("reader")
- throw;
- }
-
- m_eor = false;
- m_rsposition = 0;
- m_rssize = 0;
- m_ssize = m_sspecs.rate / gcd(specs.rate, m_sspecs.rate);
- m_tsize = m_tspecs.rate * m_ssize / m_sspecs.rate;
-
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_rsbuffer = new AUD_Buffer(); AUD_NEW("buffer")
-}
-
-AUD_SDLMixerReader::~AUD_SDLMixerReader()
-{
- delete m_reader; AUD_DELETE("reader")
- delete m_buffer; AUD_DELETE("buffer")
- delete m_rsbuffer; AUD_DELETE("buffer")
-}
-
-bool AUD_SDLMixerReader::isSeekable()
-{
- return m_reader->isSeekable();
-}
-
-void AUD_SDLMixerReader::seek(int position)
-{
- m_reader->seek(position * m_ssize / m_tsize);
- m_eor = false;
-}
-
-int AUD_SDLMixerReader::getLength()
-{
- return m_reader->getLength() * m_tsize / m_ssize;
-}
-
-int AUD_SDLMixerReader::getPosition()
-{
- return m_reader->getPosition() * m_tsize / m_ssize;
-}
-
-AUD_Specs AUD_SDLMixerReader::getSpecs()
-{
- return m_tspecs;
-}
-
-AUD_ReaderType AUD_SDLMixerReader::getType()
-{
- return m_reader->getType();
-}
-
-bool AUD_SDLMixerReader::notify(AUD_Message &message)
-{
- return m_reader->notify(message);
-}
-
-void AUD_SDLMixerReader::read(int & length, sample_t* & buffer)
-{
- // sample count for the target buffer without getting a shift
- int tns = length + m_tsize - length % m_tsize;
- // sample count for the source buffer without getting a shift
- int sns = tns * m_ssize / m_tsize;
- // target sample size
- int tss = AUD_SAMPLE_SIZE(m_tspecs);
- // source sample size
- int sss = AUD_SAMPLE_SIZE(m_sspecs);
-
- // input is output buffer
- int buf_size = AUD_MAX(tns*tss, sns*sss);
-
- // resize if necessary
- if(m_rsbuffer->getSize() < buf_size)
- m_rsbuffer->resize(buf_size, true);
-
- if(m_buffer->getSize() < length*tss)
- m_buffer->resize(length*tss);
-
- buffer = m_buffer->getBuffer();
- int size;
- int index = 0;
- sample_t* buf;
-
- while(index < length)
- {
- if(m_rsposition == m_rssize)
- {
- // no more data
- if(m_eor)
- length = index;
- // mix
- else
- {
- // read from source
- size = sns;
- m_reader->read(size, buf);
-
- // prepare
- m_cvt.buf = m_rsbuffer->getBuffer();
- m_cvt.len = size*sss;
- memcpy(m_cvt.buf, buf, size*sss);
-
- // convert
- SDL_ConvertAudio(&m_cvt);
-
- // end of reader
- if(size < sns)
- m_eor = true;
-
- m_rsposition = 0;
- m_rssize = size * m_tsize / m_ssize;
- }
- }
-
- // size to copy
- size = AUD_MIN(m_rssize-m_rsposition, length-index);
-
- // copy
- memcpy(m_buffer->getBuffer() + index * tss,
- m_rsbuffer->getBuffer() + m_rsposition * tss,
- size*tss);
- m_rsposition += size;
- index += size;
- }
-}
diff --git a/intern/audaspace/SDL/AUD_SDLMixerReader.h b/intern/audaspace/SDL/AUD_SDLMixerReader.h
deleted file mode 100644
index 56668d02171..00000000000
--- a/intern/audaspace/SDL/AUD_SDLMixerReader.h
+++ /dev/null
@@ -1,128 +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_SDLMIXERREADER
-#define AUD_SDLMIXERREADER
-
-#include "AUD_IReader.h"
-class AUD_Buffer;
-
-#include <SDL.h>
-
-/**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- * class doesn't check for compliance, so in case of other factors,
- * the behaviour is undefined.
- */
-class AUD_SDLMixerReader : public AUD_IReader
-{
-private:
- /**
- * The reader that is being mixed.
- */
- AUD_IReader* m_reader;
-
- /**
- * The current reading position in the resampling buffer.
- */
- int m_rsposition;
-
- /**
- * The count of mixed samples in the resampling buffer.
- */
- int m_rssize;
-
- /**
- * The smallest count of source samples to get a fractionless resampling
- * factor.
- */
- int m_ssize;
-
- /**
- * The smallest count of target samples to get a fractionless resampling
- * factor.
- */
- int m_tsize;
-
- /**
- * The sound output buffer.
- */
- AUD_Buffer *m_buffer;
-
- /**
- * The resampling buffer.
- */
- AUD_Buffer *m_rsbuffer;
-
- /**
- * The target specification.
- */
- AUD_Specs m_tspecs;
-
- /**
- * The sample specification of the source.
- */
- AUD_Specs m_sspecs;
-
- /**
- * Saves whether the end of the source has been reached.
- */
- bool m_eor;
-
- /**
- * The SDL_AudioCVT structure used for resampling.
- */
- SDL_AudioCVT m_cvt;
-
-public:
- /**
- * Creates a resampling reader.
- * \param reader The reader to mix.
- * \param specs The target specification.
- * \exception AUD_Exception Thrown if the source specification cannot be
- * mixed to the target specification or if the reader is
- * NULL.
- */
- AUD_SDLMixerReader(AUD_IReader* reader, AUD_Specs specs);
- /**
- * Destroys the reader.
- */
- ~AUD_SDLMixerReader();
-
- virtual bool isSeekable();
- virtual void seek(int position);
- virtual int getLength();
- virtual int getPosition();
- virtual AUD_Specs getSpecs();
- virtual AUD_ReaderType getType();
- virtual bool notify(AUD_Message &message);
- virtual void read(int & length, sample_t* & buffer);
-};
-
-#endif //AUD_SDLMIXERREADER
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
index bcace340b24..caafbd14327 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
@@ -27,14 +27,14 @@
#include "AUD_SRCResampleReader.h"
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_ResampleFactory(reader, specs) {}
AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_ResampleFactory(factory, specs) {}
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Specs specs) :
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_DeviceSpecs specs) :
AUD_ResampleFactory(specs) {}
AUD_IReader* AUD_SRCResampleFactory::createReader()
@@ -45,7 +45,7 @@ AUD_IReader* AUD_SRCResampleFactory::createReader()
{
if(reader->getSpecs().rate != m_specs.rate)
{
- reader = new AUD_SRCResampleReader(reader, m_specs);
+ reader = new AUD_SRCResampleReader(reader, m_specs.specs);
AUD_NEW("reader")
}
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
index c23c1d2c82e..4b16c70169c 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
@@ -31,14 +31,13 @@
/**
* This factory creates a resampling reader that uses libsamplerate for
* resampling.
- * \note The format of the input must be float.
*/
class AUD_SRCResampleFactory : public AUD_ResampleFactory
{
public:
- AUD_SRCResampleFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_SRCResampleFactory(AUD_Specs specs);
+ AUD_SRCResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_DeviceSpecs specs);
virtual AUD_IReader* createReader();
};
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
index f7564d3c010..940f4245316 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -26,9 +26,9 @@
#include "AUD_SRCResampleReader.h"
#include "AUD_Buffer.h"
-#include <math.h>
+#include <cmath>
#include <cstring>
-#include <stdio.h>
+#include <cstdio>
static long src_callback(void *cb_data, float **data)
{
@@ -41,15 +41,8 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
{
m_sspecs = reader->getSpecs();
- if(m_sspecs.format != AUD_FORMAT_FLOAT32)
- {
- delete m_reader; AUD_DELETE("reader")
- AUD_THROW(AUD_ERROR_READER);
- }
-
m_tspecs = specs;
m_tspecs.channels = m_sspecs.channels;
- m_tspecs.format = m_sspecs.format;
m_factor = (double)m_tspecs.rate / (double)m_sspecs.rate;
int error;
@@ -71,9 +64,9 @@ AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
AUD_SRCResampleReader::~AUD_SRCResampleReader()
{
- delete m_buffer; AUD_DELETE("buffer")
-
src_delete(m_src);
+
+ delete m_buffer; AUD_DELETE("buffer")
}
long AUD_SRCResampleReader::doCallback(float** data)
@@ -83,7 +76,7 @@ long AUD_SRCResampleReader::doCallback(float** data)
m_reader->read(length, buffer);
- *data = (float*)buffer;
+ *data = buffer;
return length;
}
@@ -110,10 +103,12 @@ AUD_Specs AUD_SRCResampleReader::getSpecs()
void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
{
- if(m_buffer->getSize() < length * m_tspecs.channels * 4)
- m_buffer->resize(length * m_tspecs.channels * 4);
+ int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+
+ if(m_buffer->getSize() < size)
+ m_buffer->resize(size);
buffer = m_buffer->getBuffer();
- length = src_callback_read(m_src, m_factor, length, (float*)buffer);
+ length = src_callback_read(m_src, m_factor, length, buffer);
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
index 1bacdb3965c..4fe30b48c6e 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -32,13 +32,7 @@ class AUD_Buffer;
#include <samplerate.h>
/**
- * This class mixes a sound source with help of the SDL library.
- * Unfortunately SDL is only capable of 8 and 16 bit audio, mono and stereo, as
- * well as resampling only 2^n sample rate relationships where n is a natural
- * number.
- * \warning Although SDL can only resample 2^n sample rate relationships, this
- * class doesn't check for compliance, so in case of other factors,
- * the behaviour is undefined.
+ * This resampling reader uses libsamplerate for resampling.
*/
class AUD_SRCResampleReader : public AUD_EffectReader
{
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 0384ba5e0e6..027ac015eb5 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -34,26 +34,6 @@ extern "C" {
#include <libavformat/avformat.h>
}
-// This function transforms a FFMPEG SampleFormat to our own sample format
-static inline AUD_SampleFormat FFMPEG_TO_AUD(SampleFormat fmt)
-{
- switch(fmt)
- {
- case SAMPLE_FMT_U8:
- return AUD_FORMAT_U8;
- case SAMPLE_FMT_S16:
- return AUD_FORMAT_S16;
- case SAMPLE_FMT_S32:
- return AUD_FORMAT_S32;
- case SAMPLE_FMT_FLT:
- return AUD_FORMAT_FLOAT32;
- case SAMPLE_FMT_DBL:
- return AUD_FORMAT_FLOAT64;
- default:
- return AUD_FORMAT_INVALID;
- }
-}
-
int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
{
// save packet parameters
@@ -78,11 +58,11 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
// read samples from the packet
data_size = buf_size - buf_pos;
/*read_length = avcodec_decode_audio3(m_codecCtx,
- (int16_t*)(buffer->getBuffer()+buf_pos),
+ (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
&data_size,
packet);*/
read_length = avcodec_decode_audio2(m_codecCtx,
- (int16_t*)(buffer->getBuffer()+buf_pos),
+ (int16_t*)(((data_t*)buffer->getBuffer())+buf_pos),
&data_size,
audio_pkg_data,
audio_pkg_size);
@@ -101,78 +81,108 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer* buffer)
return buf_pos;
}
-AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+void AUD_FFMPEGReader::init()
{
m_position = 0;
m_pkgbuf_left = 0;
- m_byteiocontext = NULL;
- // open file
- if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
- AUD_THROW(AUD_ERROR_FILE);
+ if(av_find_stream_info(m_formatCtx)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- try
- {
- if(av_find_stream_info(m_formatCtx)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ // find audio stream and codec
+ m_stream = -1;
- // find audio stream and codec
- m_stream = -1;
+ for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
+ if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
+ && (m_stream < 0))
+ {
+ m_stream=i;
+ break;
+ }
+ if(m_stream == -1)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ m_codecCtx = m_formatCtx->streams[m_stream]->codec;
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
+ // get a decoder and open it
+ AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
+ if(!aCodec)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ if(avcodec_open(m_codecCtx, aCodec)<0)
+ AUD_THROW(AUD_ERROR_FFMPEG);
- if(avcodec_open(m_codecCtx, aCodec)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
+ // XXX this prints file information to stdout:
+ //dump_format(m_formatCtx, 0, NULL, 0);
- // XXX this prints file information to stdout:
- //dump_format(m_formatCtx, 0, filename, 0);
+ m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
- }
- catch(AUD_Exception)
+ switch(m_codecCtx->sample_fmt)
{
- av_close_input_file(m_formatCtx);
- throw;
+ case SAMPLE_FMT_U8:
+ m_convert = AUD_convert_u8_float;
+ m_specs.format = AUD_FORMAT_U8;
+ break;
+ case SAMPLE_FMT_S16:
+ m_convert = AUD_convert_s16_float;
+ m_specs.format = AUD_FORMAT_S16;
+ break;
+ case SAMPLE_FMT_S32:
+ m_convert = AUD_convert_s32_float;
+ m_specs.format = AUD_FORMAT_S32;
+ break;
+ case SAMPLE_FMT_FLT:
+ m_convert = AUD_convert_copy<float>;
+ m_specs.format = AUD_FORMAT_FLOAT32;
+ break;
+ case SAMPLE_FMT_DBL:
+ m_convert = AUD_convert_double_float;
+ m_specs.format = AUD_FORMAT_FLOAT64;
+ break;
+ default:
+ AUD_THROW(AUD_ERROR_FILE);
}
+ m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+
// last but not least if there hasn't been any error, create the buffers
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
AUD_NEW("buffer")
}
+AUD_FFMPEGReader::AUD_FFMPEGReader(const char* filename)
+{
+ m_byteiocontext = NULL;
+
+ // open file
+ if(av_open_input_file(&m_formatCtx, filename, NULL, 0, NULL)!=0)
+ AUD_THROW(AUD_ERROR_FILE);
+
+ try
+ {
+ init();
+ }
+ catch(AUD_Exception)
+ {
+ av_close_input_file(m_formatCtx);
+ throw;
+ }
+}
+
AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
{
- m_position = 0;
- m_pkgbuf_left = 0;
m_byteiocontext = (ByteIOContext*)av_mallocz(sizeof(ByteIOContext));
AUD_NEW("byteiocontext")
m_membuffer = buffer;
- if(init_put_byte(m_byteiocontext, buffer.get()->getBuffer(), buffer.get()->getSize(), 0,
- NULL, NULL, NULL, NULL) != 0)
+ if(init_put_byte(m_byteiocontext, (data_t*)buffer.get()->getBuffer(),
+ buffer.get()->getSize(), 0, NULL, NULL, NULL, NULL) != 0)
AUD_THROW(AUD_ERROR_FILE);
AVProbeData probe_data;
probe_data.filename = "";
- probe_data.buf = buffer.get()->getBuffer();
+ probe_data.buf = (data_t*)buffer.get()->getBuffer();
probe_data.buf_size = buffer.get()->getSize();
AVInputFormat* fmt = av_probe_input_format(&probe_data, 1);
@@ -182,38 +192,7 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
try
{
- if(av_find_stream_info(m_formatCtx)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- // find audio stream and codec
- m_stream = -1;
-
- for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
- if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
- && (m_stream < 0))
- {
- m_stream=i;
- break;
- }
- if(m_stream == -1)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- m_codecCtx = m_formatCtx->streams[m_stream]->codec;
-
- // get a decoder and open it
- AVCodec *aCodec = avcodec_find_decoder(m_codecCtx->codec_id);
- if(!aCodec)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- if(avcodec_open(m_codecCtx, aCodec)<0)
- AUD_THROW(AUD_ERROR_FFMPEG);
-
- // XXX this prints stream information to stdout:
- //dump_format(m_formatCtx, 0, NULL, 0);
-
- m_specs.channels = (AUD_Channels) m_codecCtx->channels;
- m_specs.format = FFMPEG_TO_AUD(m_codecCtx->sample_fmt);
- m_specs.rate = (AUD_SampleRate) m_codecCtx->sample_rate;
+ init();
}
catch(AUD_Exception)
{
@@ -221,11 +200,6 @@ AUD_FFMPEGReader::AUD_FFMPEGReader(AUD_Reference<AUD_Buffer> buffer)
av_free(m_byteiocontext); AUD_DELETE("byteiocontext")
throw;
}
-
- // last but not least if there hasn't been any error, create the buffers
- m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_pkgbuf = new AUD_Buffer(AVCODEC_MAX_AUDIO_FRAME_SIZE<<1);
- AUD_NEW("buffer")
}
AUD_FFMPEGReader::~AUD_FFMPEGReader()
@@ -316,7 +290,7 @@ int AUD_FFMPEGReader::getPosition()
AUD_Specs AUD_FFMPEGReader::getSpecs()
{
- return m_specs;
+ return m_specs.specs;
}
AUD_ReaderType AUD_FFMPEGReader::getType()
@@ -336,11 +310,11 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
int data_size = 0;
int pkgbuf_pos;
int left = length;
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
// resize output buffer if necessary
- if(m_buffer->getSize() < length*sample_size)
- m_buffer->resize(length*sample_size);
+ if(m_buffer->getSize() < length * AUD_SAMPLE_SIZE(m_specs))
+ m_buffer->resize(length * AUD_SAMPLE_SIZE(m_specs));
buffer = m_buffer->getBuffer();
pkgbuf_pos = m_pkgbuf_left;
@@ -350,8 +324,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
if(pkgbuf_pos > 0)
{
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
- buffer += data_size;
+ m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+ data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
@@ -366,8 +341,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
// copy to output buffer
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- memcpy(buffer, m_pkgbuf->getBuffer(), data_size);
- buffer += data_size;
+ m_convert((data_t*) buffer, (data_t*) m_pkgbuf->getBuffer(),
+ data_size / AUD_FORMAT_SIZE(m_specs.format));
+ buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
av_free_packet(&packet);
@@ -376,7 +352,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
if(pkgbuf_pos > data_size)
{
m_pkgbuf_left = pkgbuf_pos-data_size;
- memmove(m_pkgbuf->getBuffer(), m_pkgbuf->getBuffer()+data_size,
+ memmove(m_pkgbuf->getBuffer(),
+ ((data_t*)m_pkgbuf->getBuffer())+data_size,
pkgbuf_pos-data_size);
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 6e303934f36..f992fdf7a34 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -26,6 +26,7 @@
#ifndef AUD_FFMPEGREADER
#define AUD_FFMPEGREADER
+#include "AUD_ConverterFunctions.h"
#include "AUD_IReader.h"
#include "AUD_Reference.h"
class AUD_Buffer;
@@ -59,7 +60,7 @@ private:
/**
* The specification of the audio data.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* The buffer for package reading.
@@ -92,6 +93,11 @@ private:
int m_stream;
/**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
+ /**
* The memory file to read from, only saved to keep the buffer alive.
*/
AUD_Reference<AUD_Buffer> m_membuffer;
@@ -104,6 +110,11 @@ private:
*/
int decode(AVPacket* packet, AUD_Buffer* buffer);
+ /**
+ * Initializes the object.
+ */
+ void init();
+
public:
/**
* Creates a new reader.
diff --git a/intern/audaspace/fftw/AUD_BandPassFactory.cpp b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
index 5a957081208..2950cdf8bad 100644
--- a/intern/audaspace/fftw/AUD_BandPassFactory.cpp
+++ b/intern/audaspace/fftw/AUD_BandPassFactory.cpp
@@ -63,16 +63,8 @@ AUD_IReader* AUD_BandPassFactory::createReader()
if(reader != 0)
{
- if(reader->getSpecs().format == AUD_FORMAT_FLOAT32)
- {
- reader = new AUD_BandPassReader(reader, m_low, m_high);
- AUD_NEW("reader")
- }
- else
- {
- delete reader; AUD_DELETE("reader")
- return 0;
- }
+ reader = new AUD_BandPassReader(reader, m_low, m_high);
+ AUD_NEW("reader")
}
return reader;
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.cpp b/intern/audaspace/fftw/AUD_BandPassReader.cpp
index 34d7193866f..e77b69863f1 100644
--- a/intern/audaspace/fftw/AUD_BandPassReader.cpp
+++ b/intern/audaspace/fftw/AUD_BandPassReader.cpp
@@ -77,7 +77,6 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
}
m_length = length;
- printf("WINDOW: %d\n", m_length);
if(m_length * sizeof(double) > m_in->getSize())
{
@@ -95,16 +94,15 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
FFTW_ESTIMATE);
}
- float* source = (float*) buffer;
double* target = (double*) m_in->getBuffer();
- float* target2 = (float*) m_buffer->getBuffer();
+ sample_t* target2 = m_buffer->getBuffer();
fftw_complex* complex = (fftw_complex*) m_out->getBuffer();
float frequency;
for(int channel = 0; channel < specs.channels; channel++)
{
for(int i = 0; i < m_length; i++)
- target[i] = source[i * specs.channels + channel];
+ target[i] = buffer[i * specs.channels + channel];
fftw_execute(m_forward);
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
index 71deae0e87e..a8e74a023bf 100644
--- a/intern/audaspace/intern/AUD_Buffer.cpp
+++ b/intern/audaspace/intern/AUD_Buffer.cpp
@@ -27,14 +27,14 @@
#include "AUD_Space.h"
#include <cstring>
-#include <stdlib.h>
+#include <cstdlib>
#define AUD_ALIGN(a) (a + 16 - ((long)a & 15))
AUD_Buffer::AUD_Buffer(int size)
{
m_size = size;
- m_buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+ m_buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
}
AUD_Buffer::~AUD_Buffer()
@@ -44,7 +44,7 @@ AUD_Buffer::~AUD_Buffer()
sample_t* AUD_Buffer::getBuffer()
{
- return AUD_ALIGN(m_buffer);
+ return (sample_t*) AUD_ALIGN(m_buffer);
}
int AUD_Buffer::getSize()
@@ -54,7 +54,7 @@ int AUD_Buffer::getSize()
void AUD_Buffer::resize(int size, bool keep)
{
- sample_t* buffer = (sample_t*) malloc(size+16); AUD_NEW("buffer")
+ data_t* buffer = (data_t*) malloc(size+16); AUD_NEW("buffer")
// copy old data over if wanted
if(keep)
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
index 64959b03799..f745ee6154b 100644
--- a/intern/audaspace/intern/AUD_Buffer.h
+++ b/intern/audaspace/intern/AUD_Buffer.h
@@ -39,7 +39,7 @@ private:
int m_size;
/// The pointer to the buffer memory.
- sample_t* m_buffer;
+ data_t* m_buffer;
public:
/**
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index 6cea849bdfc..0101de338bd 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -79,11 +79,11 @@ void AUD_BufferReader::read(int & length, sample_t* & buffer)
{
int sample_size = AUD_SAMPLE_SIZE(m_specs);
- buffer = m_buffer.get()->getBuffer()+m_position*sample_size;
+ buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
// in case the end of the buffer is reached
- if(m_buffer.get()->getSize() < (m_position+length)*sample_size)
- length = m_buffer.get()->getSize()/sample_size-m_position;
+ if(m_buffer.get()->getSize() < (m_position + length) * sample_size)
+ length = m_buffer.get()->getSize() / sample_size - m_position;
if(length < 0)
length = 0;
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index cd6b95b1d9e..964ac2e650c 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -23,6 +23,9 @@
* ***** END LGPL LICENSE BLOCK *****
*/
+#include <cstdlib>
+#include <cstring>
+
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
#include "AUD_FileFactory.h"
@@ -32,13 +35,18 @@
#include "AUD_PingPongFactory.h"
#include "AUD_LoopFactory.h"
#include "AUD_RectifyFactory.h"
+#include "AUD_EnvelopeFactory.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LowpassFactory.h"
+#include "AUD_HighpassFactory.h"
+#include "AUD_ChannelMapperFactory.h"
+#include "AUD_Buffer.h"
#include "AUD_ReadDevice.h"
#include "AUD_SourceCaps.h"
#include "AUD_IReader.h"
#ifdef WITH_SDL
#include "AUD_SDLDevice.h"
-#include "AUD_FloatMixer.h"
#endif
#ifdef WITH_OPENAL
@@ -55,7 +63,7 @@ extern "C" {
}
#endif
-#include <assert.h>
+#include <cassert>
typedef AUD_IFactory AUD_Sound;
typedef AUD_ReadDevice AUD_Device;
@@ -71,7 +79,7 @@ static AUD_IDevice* AUD_device = NULL;
static int AUD_available_devices[4];
static AUD_I3DDevice* AUD_3ddevice = NULL;
-int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
+int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
#ifdef WITH_FFMPEG
av_register_all();
@@ -90,12 +98,8 @@ int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize)
break;
#ifdef WITH_SDL
case AUD_SDL_DEVICE:
- {
- dev = new AUD_SDLDevice(specs, buffersize);
- AUD_FloatMixer* mixer = new AUD_FloatMixer();
- ((AUD_SDLDevice*)dev)->setMixer(mixer);
- break;
- }
+ dev = new AUD_SDLDevice(specs, buffersize);
+ break;
#endif
#ifdef WITH_OPENAL
case AUD_OPENAL_DEVICE:
@@ -177,7 +181,6 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
else
{
info.specs.channels = AUD_CHANNELS_INVALID;
- info.specs.format = AUD_FORMAT_INVALID;
info.specs.rate = AUD_RATE_INVALID;
info.length = 0.0;
}
@@ -519,7 +522,7 @@ int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
return false;
}
-AUD_Device* AUD_openReadDevice(AUD_Specs specs)
+AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
{
try
{
@@ -578,7 +581,7 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Handle* handle,
return false;
}
-int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length)
+int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
{
assert(device);
assert(buffer);
@@ -605,3 +608,43 @@ void AUD_closeReadDevice(AUD_Device* device)
{
}
}
+
+float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int samplerate, int* length)
+{
+ AUD_Buffer buffer;
+ AUD_DeviceSpecs specs;
+ specs.channels = AUD_CHANNELS_MONO;
+ specs.rate = (AUD_SampleRate)samplerate;
+
+ AUD_FileFactory file(filename);
+ AUD_ChannelMapperFactory mapper(&file, specs);
+ AUD_LowpassFactory lowpass(&mapper, high);
+ AUD_HighpassFactory highpass(&lowpass, low);
+ AUD_EnvelopeFactory envelope(&highpass, attack, release, threshold, 0.1f);
+ AUD_LinearResampleFactory resampler(&envelope, specs);
+
+ AUD_IReader* reader = resampler.createReader();
+
+ if(reader == NULL)
+ return NULL;
+
+ int len;
+ int position = 0;
+ sample_t* readbuffer;
+ do
+ {
+ len = samplerate;
+ buffer.resize((position + len) * sizeof(float), true);
+ reader->read(len, readbuffer);
+ memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
+ position += len;
+ } while(len != 0);
+ delete reader;
+
+ float* result = (float*)malloc(position * sizeof(float));
+ memcpy(result, buffer.getBuffer(), position * sizeof(float));
+ *length = position;
+ return result;
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index 866f0248cb2..9223c870ccf 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -59,7 +59,7 @@ typedef struct
* \param buffersize The buffersize for the device.
* \return Whether the device has been initialized.
*/
-extern int AUD_init(AUD_DeviceType device, AUD_Specs specs, int buffersize);
+extern int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize);
/**
* Returns a integer list with available sound devices. The last one is always
@@ -304,7 +304,7 @@ extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
* \param specs The specification of the audio data.
* \return A device handle.
*/
-extern AUD_Device* AUD_openReadDevice(AUD_Specs specs);
+extern AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs);
/**
* Sets the main volume of a device.
@@ -342,7 +342,7 @@ extern int AUD_setDeviceSoundVolume(AUD_Device* device,
* played back currently, in that case the buffer is filled with
* silence.
*/
-extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
+extern int AUD_readDevice(AUD_Device* device, data_t* buffer, int length);
/**
* Closes a read device.
@@ -350,6 +350,14 @@ extern int AUD_readDevice(AUD_Device* device, sample_t* buffer, int length);
*/
extern void AUD_closeReadDevice(AUD_Device* device);
+/**
+ * Reads a sound file into a newly created float buffer.
+ * The sound is therefore bandpassed, rectified and resampled.
+ */
+extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
+ float attack, float release, float threshold,
+ int samplerate, int* length);
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
index 66205a58015..3420ed16649 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -29,20 +29,20 @@
#include <cstring>
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(reader, specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
}
AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
}
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Specs specs) :
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_DeviceSpecs specs) :
AUD_MixerFactory(specs)
{
memset(m_mapping, 0, sizeof(m_mapping));
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
index c2c39f4bdf6..a67bfa12123 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -41,9 +41,9 @@ private:
float **m_mapping[9];
public:
- AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_ChannelMapperFactory(AUD_Specs specs);
+ AUD_ChannelMapperFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ChannelMapperFactory(AUD_DeviceSpecs specs);
virtual ~AUD_ChannelMapperFactory();
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
index 61f97c08a8e..4de5875a33f 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -32,12 +32,6 @@ AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
{
m_specs = reader->getSpecs();
- if(m_specs.format != AUD_FORMAT_FLOAT32)
- {
- delete m_reader; AUD_DELETE("reader")
- AUD_THROW(AUD_ERROR_READER);
- }
-
int channels = -1;
m_rch = m_specs.channels;
while(mapping[++channels] != 0);
@@ -89,9 +83,9 @@ void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
if(m_buffer->getSize() < length * 4 * channels)
m_buffer->resize(length * 4 * channels);
- float* in = (float*)buffer;
- float* out = (float*)m_buffer->getBuffer();
- float sum;
+ sample_t* in = buffer;
+ sample_t* out = m_buffer->getBuffer();
+ sample_t sum;
for(int i = 0; i < length; i++)
{
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
index a1a86662072..1c6d5468251 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -27,14 +27,14 @@
#include "AUD_ConverterReader.h"
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IReader* reader,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(reader, specs) {}
AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
- AUD_Specs specs) :
+ AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs) {}
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_Specs specs) :
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_DeviceSpecs specs) :
AUD_MixerFactory(specs) {}
AUD_IReader* AUD_ConverterFactory::createReader()
@@ -43,7 +43,7 @@ AUD_IReader* AUD_ConverterFactory::createReader()
if(reader != 0)
{
- if(reader->getSpecs().format != m_specs.format)
+ if(m_specs.format != AUD_FORMAT_FLOAT32)
{
reader = new AUD_ConverterReader(reader, m_specs);
AUD_NEW("reader")
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
index 3778e8d8f03..11ca6c9f0a8 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -35,9 +35,9 @@
class AUD_ConverterFactory : public AUD_MixerFactory
{
public:
- AUD_ConverterFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_ConverterFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_ConverterFactory(AUD_Specs specs);
+ AUD_ConverterFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_DeviceSpecs specs);
virtual AUD_IReader* createReader();
};
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
index 1b5d07bcc61..70018917d43 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
@@ -36,14 +36,14 @@
#define AUD_FLT_MAX 1.0
#define AUD_FLT_MIN -1.0
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
}
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
{
@@ -53,7 +53,7 @@ void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
{
@@ -63,35 +63,35 @@ void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
}
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_float(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
}
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_u8_double(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
for(int i = 0; i < length; i++)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
}
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
target[i] = (unsigned char)((s[i] >> 8) + AUD_U8_0);
}
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -102,7 +102,7 @@ void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -113,7 +113,7 @@ void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
int32_t* t = (int32_t*) target;
@@ -121,7 +121,7 @@ void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length)
t[i] = ((int32_t)s[i]) << 16;
}
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_float(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
float* t = (float*) target;
@@ -129,7 +129,7 @@ void AUD_convert_s16_float(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S16_FLT;
}
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s16_double(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
double* t = (double*) target;
@@ -137,52 +137,52 @@ void AUD_convert_s16_double(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S16_FLT;
}
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
target[i] = source[i*3] ^ AUD_U8_0;
}
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length)
{
for(int i = 0; i < length; i++)
target[i] = source[i*3+2] ^ AUD_U8_0;
}
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3] << 8 | source[i*3+1];
}
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3+2] << 8 | source[i*3+1];
}
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length)
{
memcpy(target, source, length * 3);
}
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
}
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
for(int i = 0; i < length; i++)
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
}
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
@@ -193,7 +193,7 @@ void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
@@ -204,7 +204,7 @@ void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
@@ -215,7 +215,7 @@ void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
@@ -226,14 +226,14 @@ void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
target[i] = (unsigned char)((s[i] >> 24) + AUD_U8_0);
}
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
int32_t* s = (int32_t*) source;
@@ -241,7 +241,7 @@ void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length)
t[i] = s[i] >> 16;
}
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
for(int i = 0; i < length; i++)
@@ -252,7 +252,7 @@ void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
for(int i = 0; i < length; i++)
@@ -263,7 +263,7 @@ void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_float(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
float* t = (float*) target;
@@ -271,7 +271,7 @@ void AUD_convert_s32_float(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S32_FLT;
}
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_s32_double(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
double* t = (double*) target;
@@ -279,7 +279,7 @@ void AUD_convert_s32_double(sample_t* target, sample_t* source, int length)
t[i] = s[i] / AUD_S32_FLT;
}
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_u8(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
float t;
@@ -295,7 +295,7 @@ void AUD_convert_float_u8(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
float* s = (float*) source;
@@ -310,7 +310,7 @@ void AUD_convert_float_s16(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length)
{
int32_t t;
float* s = (float*) source;
@@ -328,7 +328,7 @@ void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length)
{
int32_t t;
float* s = (float*) source;
@@ -346,7 +346,7 @@ void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
float* s = (float*) source;
@@ -361,7 +361,7 @@ void AUD_convert_float_s32(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
+void AUD_convert_float_double(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
double* t = (double*) target;
@@ -369,7 +369,7 @@ void AUD_convert_float_double(sample_t* target, sample_t* source, int length)
t[i] = s[i];
}
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_u8(data_t* target, data_t* source, int length)
{
double* s = (double*) source;
double t;
@@ -385,7 +385,7 @@ void AUD_convert_double_u8(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s16(data_t* target, data_t* source, int length)
{
int16_t* t = (int16_t*) target;
double* s = (double*) source;
@@ -400,7 +400,7 @@ void AUD_convert_double_s16(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length)
{
int32_t t;
double* s = (double*) source;
@@ -418,7 +418,7 @@ void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length)
{
int32_t t;
double* s = (double*) source;
@@ -436,7 +436,7 @@ void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_s32(data_t* target, data_t* source, int length)
{
int32_t* t = (int32_t*) target;
double* s = (double*) source;
@@ -451,92 +451,10 @@ void AUD_convert_double_s32(sample_t* target, sample_t* source, int length)
}
}
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length)
+void AUD_convert_double_float(data_t* target, data_t* source, int length)
{
double* s = (double*) source;
float* t = (float*) target;
for(int i = 0; i < length; i++)
t[i] = s[i];
}
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
- int count, float volume)
-{
- for(int i=0; i<count; i++)
- target[i] = (unsigned char)((source[i]-0x0080) * volume + 0x80);
-}
-
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
- int count, float volume)
-{
- count *= 3;
- int value;
-
- for(int i=0; i<count; i+=3)
- {
- value = source[i+2] << 16 | source[i+1] << 8 | source[i];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- value *= volume;
- target[i+2] = value >> 16;
- target[i+1] = value >> 8;
- target[i] = value;
- }
-}
-
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
- int count, float volume)
-{
- count *= 3;
- int value;
-
- for(int i=0; i < count; i+=3)
- {
- value = source[i] << 16 | source[i+1] << 8 | source[i+2];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- value *= volume;
- target[i] = value >> 16;
- target[i+1] = value >> 8;
- target[i+2] = value;
- }
-}
-
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count)
-{
- for(int i=0; i<count; i++)
- target[i] = source[i] < 0x80 ? 0x0100 - source[i] : source[i];
-}
-
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count)
-{
- count *= 3;
- int value;
-
- for(int i=0; i<count; i+=3)
- {
- value = source[i+2] << 16 | source[i+1] << 8 | source[i];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- if(value < 0)
- value = -value;
- target[i+2] = value >> 16;
- target[i+1] = value >> 8;
- target[i] = value;
- }
-}
-
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count)
-{
- count *= 3;
- int value;
-
- for(int i=0; i < count; i+=3)
- {
- value = source[i] << 16 | source[i+1] << 8 | source[i+2];
- value |= (((value & 0x800000) >> 23) * 255) << 24;
- if(value < 0)
- value = -value;
- target[i] = value >> 16;
- target[i+1] = value >> 8;
- target[i+2] = value;
- }
-}
-
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.h b/intern/audaspace/intern/AUD_ConverterFunctions.h
index 686e58704b7..a925f138aa2 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.h
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.h
@@ -41,133 +41,94 @@
#include <stdint.h>
#endif
-typedef void (*AUD_convert_f)(sample_t* target, sample_t* source, int length);
-
-typedef void (*AUD_volume_adjust_f)(sample_t* target, sample_t* source,
- int count, float volume);
-
-typedef void (*AUD_rectify_f)(sample_t* target, sample_t* source, int count);
+typedef void (*AUD_convert_f)(data_t* target, data_t* source, int length);
template <class T>
-void AUD_convert_copy(sample_t* target, sample_t* source, int length)
+void AUD_convert_copy(data_t* target, data_t* source, int length)
{
memcpy(target, source, length*sizeof(T));
}
-void AUD_convert_u8_s16(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_be(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s24_le(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_s32(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_float(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_u8_double(sample_t* target, sample_t* source, int length);
-
-void AUD_convert_s16_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s16(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_s16_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_s32(data_t* target, data_t* source, int length);
-void AUD_convert_s16_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_float(data_t* target, data_t* source, int length);
-void AUD_convert_s16_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_u8_double(data_t* target, data_t* source, int length);
-void AUD_convert_s24_u8_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_u8(data_t* target, data_t* source, int length);
-void AUD_convert_s24_u8_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s16_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s16_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_s32(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s24(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_float(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s32_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s16_double(data_t* target, data_t* source, int length);
-void AUD_convert_s24_s32_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_float_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_u8_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_float_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_be(data_t* target, data_t* source, int length);
-void AUD_convert_s24_double_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s16_le(data_t* target, data_t* source, int length);
-void AUD_convert_s24_double_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s24(data_t* target, data_t* source, int length);
-void AUD_convert_s32_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_s32_le(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_float_le(data_t* target, data_t* source, int length);
-void AUD_convert_s32_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_be(data_t* target, data_t* source, int length);
-void AUD_convert_s32_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s24_double_le(data_t* target, data_t* source, int length);
-void AUD_convert_float_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_u8(data_t* target, data_t* source, int length);
-void AUD_convert_float_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s16(data_t* target, data_t* source, int length);
-void AUD_convert_float_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_float_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_float_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_float(data_t* target, data_t* source, int length);
-void AUD_convert_float_double(sample_t* target, sample_t* source, int length);
+void AUD_convert_s32_double(data_t* target, data_t* source, int length);
-void AUD_convert_double_u8(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_u8(data_t* target, data_t* source, int length);
-void AUD_convert_double_s16(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s16(data_t* target, data_t* source, int length);
-void AUD_convert_double_s24_be(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_be(data_t* target, data_t* source, int length);
-void AUD_convert_double_s24_le(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s24_le(data_t* target, data_t* source, int length);
-void AUD_convert_double_s32(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_s32(data_t* target, data_t* source, int length);
-void AUD_convert_double_float(sample_t* target, sample_t* source, int length);
+void AUD_convert_float_double(data_t* target, data_t* source, int length);
-template <class T>
-void AUD_volume_adjust(sample_t* target, sample_t* source,
- int count, float volume)
-{
- T* t = (T*)target;
- T* s = (T*)source;
- for(int i=0; i < count; i++)
- t[i] = (T)(s[i] * volume);
-}
-
-void AUD_volume_adjust_u8(sample_t* target, sample_t* source,
- int count, float volume);
+void AUD_convert_double_u8(data_t* target, data_t* source, int length);
-void AUD_volume_adjust_s24_le(sample_t* target, sample_t* source,
- int count, float volume);
+void AUD_convert_double_s16(data_t* target, data_t* source, int length);
-void AUD_volume_adjust_s24_be(sample_t* target, sample_t* source,
- int count, float volume);
-
-template <class T>
-void AUD_rectify(sample_t* target, sample_t* source, int count)
-{
- T* t = (T*)target;
- T* s = (T*)source;
- for(int i=0; i < count; i++)
- t[i] = s[i] < 0 ? -s[i] : s[i];
-}
+void AUD_convert_double_s24_be(data_t* target, data_t* source, int length);
-void AUD_rectify_u8(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s24_le(data_t* target, data_t* source, int length);
-void AUD_rectify_s24_le(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_s32(data_t* target, data_t* source, int length);
-void AUD_rectify_s24_be(sample_t* target, sample_t* source, int count);
+void AUD_convert_double_float(data_t* target, data_t* source, int length);
#endif //AUD_CONVERTERFUNCTIONS
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
index da25a2b7460..808144085bb 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -26,205 +26,37 @@
#include "AUD_ConverterReader.h"
#include "AUD_Buffer.h"
-AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs) :
+AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
+ AUD_DeviceSpecs specs) :
AUD_EffectReader(reader)
{
- m_specs = reader->getSpecs();
+ m_specs.specs = reader->getSpecs();
int bigendian = 1;
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
- switch(m_specs.format)
+ switch(specs.format)
{
case AUD_FORMAT_U8:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_copy<unsigned char>;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_u8_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_u8_s24_be;
- else
- m_convert = AUD_convert_u8_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_u8_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_u8_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_u8_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_u8;
break;
case AUD_FORMAT_S16:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_s16_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_copy<int16_t>;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_s16_s24_be;
- else
- m_convert = AUD_convert_s16_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s16_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_s16_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_s16_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s16;
break;
case AUD_FORMAT_S24:
if(bigendian)
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_u8_s24_be;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s16_s24_be;
- break;
- case AUD_FORMAT_S24:
- m_convert = AUD_convert_s24_s24;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s32_s24_be;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_float_s24_be;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_double_s24_be;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s24_be;
else
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_u8_s24_le;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s16_s24_le;
- break;
- case AUD_FORMAT_S24:
- m_convert = AUD_convert_s24_s24;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_s32_s24_le;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_float_s24_le;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_double_s24_le;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s24_le;
break;
case AUD_FORMAT_S32:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_s32_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_s32_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_s32_s24_be;
- else
- m_convert = AUD_convert_s32_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_copy<int32_t>;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_s32_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_s32_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_s32;
break;
case AUD_FORMAT_FLOAT32:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_float_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_float_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_float_s24_be;
- else
- m_convert = AUD_convert_float_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_float_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_copy<float>;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_float_double;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_copy<float>;
break;
case AUD_FORMAT_FLOAT64:
- switch(specs.format)
- {
- case AUD_FORMAT_U8:
- m_convert = AUD_convert_double_u8;
- break;
- case AUD_FORMAT_S16:
- m_convert = AUD_convert_double_s16;
- break;
- case AUD_FORMAT_S24:
- if(bigendian)
- m_convert = AUD_convert_double_s24_be;
- else
- m_convert = AUD_convert_double_s24_le;
- break;
- case AUD_FORMAT_S32:
- m_convert = AUD_convert_double_s32;
- break;
- case AUD_FORMAT_FLOAT32:
- m_convert = AUD_convert_double_float;
- break;
- case AUD_FORMAT_FLOAT64:
- m_convert = AUD_convert_copy<double>;
- break;
- default:
- break;
- }
+ m_convert = AUD_convert_float_double;
break;
default:
break;
@@ -242,7 +74,7 @@ AUD_ConverterReader::~AUD_ConverterReader()
AUD_Specs AUD_ConverterReader::getSpecs()
{
- return m_specs;
+ return m_specs.specs;
}
void AUD_ConverterReader::read(int & length, sample_t* & buffer)
@@ -254,7 +86,8 @@ void AUD_ConverterReader::read(int & length, sample_t* & buffer)
if(m_buffer->getSize() < length*samplesize)
m_buffer->resize(length*samplesize);
- m_convert(m_buffer->getBuffer(), buffer, length*m_specs.channels);
+ m_convert((data_t*)m_buffer->getBuffer(), (data_t*)buffer,
+ length * m_specs.channels);
buffer = m_buffer->getBuffer();
}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
index f855372b636..ba49bbfd9ba 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -44,7 +44,7 @@ private:
/**
* The target specification.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Converter function.
@@ -58,7 +58,7 @@ public:
* \param specs The target specification.
* \exception AUD_Exception Thrown if the reader is NULL.
*/
- AUD_ConverterReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
/**
* Destroys the reader.
*/
diff --git a/intern/audaspace/intern/AUD_FloatMixer.h b/intern/audaspace/intern/AUD_FloatMixer.h
deleted file mode 100644
index 728a0faf3cb..00000000000
--- a/intern/audaspace/intern/AUD_FloatMixer.h
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN LGPL LICENSE BLOCK *****
- *
- * Copyright 2009 Jörg Hermann Müller
- *
- * This file is part of AudaSpace.
- *
- * AudaSpace is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Lesser General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * AudaSpace is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
- *
- * ***** END LGPL LICENSE BLOCK *****
- */
-
-#ifndef AUD_FLOATMIXER
-#define AUD_FLOATMIXER
-
-#include "AUD_IMixer.h"
-#include "AUD_ConverterFunctions.h"
-class AUD_ConverterFactory;
-class AUD_SRCResampleFactory;
-class AUD_ChannelMapperFactory;
-class AUD_Buffer;
-#include <list>
-
-struct AUD_FloatMixerBuffer
-{
- sample_t* buffer;
- int length;
- float volume;
-};
-
-/**
- * This class is able to mix two audiosignals with floats.
- */
-class AUD_FloatMixer : public AUD_IMixer
-{
-private:
- /**
- * The converter factory that converts all readers for superposition.
- */
- AUD_ConverterFactory* m_converter;
-
- /**
- * The resampling factory that resamples all readers for superposition.
- */
- AUD_SRCResampleFactory* m_resampler;
-
- /**
- * The channel mapper factory that maps all readers for superposition.
- */
- AUD_ChannelMapperFactory* m_mapper;
-
- /**
- * The list of buffers to superpose.
- */
- std::list<AUD_FloatMixerBuffer> m_buffers;
-
- /**
- * The output specification.
- */
- AUD_Specs m_specs;
-
- /**
- * The temporary mixing buffer.
- */
- AUD_Buffer* m_buffer;
-
- /**
- * Converter function.
- */
- AUD_convert_f m_convert;
-
-public:
- /**
- * Creates the mixer.
- */
- AUD_FloatMixer();
-
- virtual ~AUD_FloatMixer();
-
- virtual AUD_IReader* prepare(AUD_IReader* reader);
- virtual void setSpecs(AUD_Specs specs);
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume);
- virtual void superpose(sample_t* buffer, int length, float volume);
-};
-
-#endif //AUD_FLOATMIXER
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index af2cae206f3..e924f57cefc 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -53,7 +53,7 @@ public:
/**
* Returns the specification of the device.
*/
- virtual AUD_Specs getSpecs()=0;
+ virtual AUD_DeviceSpecs getSpecs()=0;
/**
* Plays a sound source.
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index e0b0c7d3603..e738fc17693 100644
--- a/intern/audaspace/SDL/AUD_SDLMixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
@@ -23,42 +23,30 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_SDLMixerFactory.h"
-#include "AUD_SDLMixerReader.h"
+#include "AUD_LinearResampleFactory.h"
+#include "AUD_LinearResampleReader.h"
-#include <cstring>
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IReader* reader,
+ AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(reader, specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs) :
- AUD_MixerFactory(reader, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
+ AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(factory, specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs) :
- AUD_MixerFactory(factory, specs) {}
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_DeviceSpecs specs) :
+ AUD_ResampleFactory(specs) {}
-AUD_SDLMixerFactory::AUD_SDLMixerFactory(AUD_Specs specs) :
- AUD_MixerFactory(specs) {}
-
-AUD_IReader* AUD_SDLMixerFactory::createReader()
+AUD_IReader* AUD_LinearResampleFactory::createReader()
{
AUD_IReader* reader = getReader();
if(reader != 0)
{
- AUD_Specs specs = reader->getSpecs();
- if(memcmp(&m_specs, &specs, sizeof(AUD_Specs)) != 0)
+ if(reader->getSpecs().rate != m_specs.rate)
{
- try
- {
- reader = new AUD_SDLMixerReader(reader, m_specs);
- AUD_NEW("reader")
- }
- catch(AUD_Exception e)
- {
- // return 0 in case SDL cannot mix the source
- if(e.error != AUD_ERROR_SDL)
- throw;
- else
- reader = NULL;
- }
+ reader = new AUD_LinearResampleReader(reader, m_specs.specs);
+ AUD_NEW("reader")
}
}
return reader;
diff --git a/intern/audaspace/SDL/AUD_SDLMixerFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
index 44b36d06859..81a9d623815 100644
--- a/intern/audaspace/SDL/AUD_SDLMixerFactory.h
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.h
@@ -23,23 +23,22 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_SDLMIXERFACTORY
-#define AUD_SDLMIXERFACTORY
+#ifndef AUD_LINEARRESAMPLEFACTORY
+#define AUD_LINEARRESAMPLEFACTORY
-#include "AUD_MixerFactory.h"
+#include "AUD_ResampleFactory.h"
/**
- * This factory creates a resampling reader that uses SDL's resampling
- * functionality which unfortunately is very very very limited.
+ * This factory creates a resampling reader that does simple linear resampling.
*/
-class AUD_SDLMixerFactory : public AUD_MixerFactory
+class AUD_LinearResampleFactory : public AUD_ResampleFactory
{
public:
- AUD_SDLMixerFactory(AUD_IReader* reader, AUD_Specs specs);
- AUD_SDLMixerFactory(AUD_IFactory* factory, AUD_Specs specs);
- AUD_SDLMixerFactory(AUD_Specs specs);
+ AUD_LinearResampleFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_DeviceSpecs specs);
virtual AUD_IReader* createReader();
};
-#endif //AUD_SDLMIXERFACTORY
+#endif //AUD_LINEARRESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
new file mode 100644
index 00000000000..70e29b9570d
--- /dev/null
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
@@ -0,0 +1,138 @@
+/*
+ * $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_LinearResampleReader.h"
+#include "AUD_Buffer.h"
+
+#include <cmath>
+#include <cstring>
+#include <cstdio>
+
+AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
+ AUD_Specs specs) :
+ AUD_EffectReader(reader)
+{
+ m_sspecs = reader->getSpecs();
+
+ m_tspecs = specs;
+ m_tspecs.channels = m_sspecs.channels;
+ m_factor = (float)m_tspecs.rate / (float)m_sspecs.rate;
+
+ m_position = 0;
+ m_sposition = 0;
+
+ m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
+ m_cache = new AUD_Buffer(2 * AUD_SAMPLE_SIZE(specs)); AUD_NEW("buffer")
+}
+
+AUD_LinearResampleReader::~AUD_LinearResampleReader()
+{
+ delete m_buffer; AUD_DELETE("buffer")
+ delete m_cache; AUD_DELETE("buffer")
+}
+
+void AUD_LinearResampleReader::seek(int position)
+{
+ m_position = position;
+ m_sposition = floor(position / m_factor);
+ m_reader->seek(m_sposition);
+}
+
+int AUD_LinearResampleReader::getLength()
+{
+ return m_reader->getLength() * m_factor;
+}
+
+int AUD_LinearResampleReader::getPosition()
+{
+ return m_position;
+}
+
+AUD_Specs AUD_LinearResampleReader::getSpecs()
+{
+ return m_tspecs;
+}
+
+void AUD_LinearResampleReader::read(int & length, sample_t* & buffer)
+{
+ int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+
+ if(m_buffer->getSize() < size)
+ m_buffer->resize(size);
+
+ int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
+ int len = need;
+ sample_t* buf;
+ buffer = m_buffer->getBuffer();
+
+ m_reader->read(len, buf);
+
+ if(len < need)
+ length = floor((m_sposition + len - 1) * m_factor) - m_position;
+
+ float spos;
+ sample_t low, high;
+ int channels = m_sspecs.channels;
+
+ for(int channel = 0; channel < channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ spos = (m_position + i) / m_factor - m_sposition;
+
+ if((floor(spos) < -2) || (ceil(spos) >= len))
+ {
+ fprintf(stderr, "FATAL ERROR: REPORT THIS TO neXyon!\n");
+// exit(1);
+ }
+
+ if(floor(spos) < 0)
+ {
+ low = m_cache->getBuffer()[(int)(floor(spos) + 2) * channels
+ + channel];
+ if(ceil(spos) < 0)
+ high = m_cache->getBuffer()[(int)(ceil(spos) + 2)
+ * channels + channel];
+ else
+ high = buf[(int)ceil(spos) * channels + channel];
+ }
+ else
+ {
+ low = buf[(int)floor(spos) * channels + channel];
+ high = buf[(int)ceil(spos) * channels + channel];
+ }
+ buffer[i * channels + channel] = low + (spos - floor(spos)) *
+ (high - low);
+ }
+ }
+
+ if(len > 1)
+ memcpy(m_cache->getBuffer(), buf + (len - 2) * channels, 2 * channels);
+ else if(len == 1)
+ memcpy(m_cache->getBuffer() + 1 * channels, buf, channels);
+
+ m_sposition += len;
+ m_position += length;
+}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
new file mode 100644
index 00000000000..c86b8b76c59
--- /dev/null
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.h
@@ -0,0 +1,94 @@
+/*
+ * $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_LINEARRESAMPLEREADER
+#define AUD_LINEARRESAMPLEREADER
+
+#include "AUD_EffectReader.h"
+class AUD_Buffer;
+
+/**
+ * This resampling reader uses libsamplerate for resampling.
+ */
+class AUD_LinearResampleReader : public AUD_EffectReader
+{
+private:
+ /**
+ * The resampling factor.
+ */
+ float m_factor;
+
+ /**
+ * The current position.
+ */
+ int m_position;
+
+ /**
+ * The current reading source position.
+ */
+ int m_sposition;
+
+ /**
+ * The sound output buffer.
+ */
+ AUD_Buffer *m_buffer;
+
+ /**
+ * The input caching buffer.
+ */
+ AUD_Buffer *m_cache;
+
+ /**
+ * The target specification.
+ */
+ AUD_Specs m_tspecs;
+
+ /**
+ * The sample specification of the source.
+ */
+ AUD_Specs m_sspecs;
+
+public:
+ /**
+ * Creates a resampling reader.
+ * \param reader The reader to mix.
+ * \param specs The target specification.
+ * \exception AUD_Exception Thrown if the reader is NULL.
+ */
+ AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
+
+ /**
+ * Destroys the reader.
+ */
+ ~AUD_LinearResampleReader();
+
+ virtual void seek(int position);
+ virtual int getLength();
+ virtual int getPosition();
+ virtual AUD_Specs getSpecs();
+ virtual void read(int & length, sample_t* & buffer);
+};
+
+#endif //AUD_LINEARRESAMPLEREADER
diff --git a/intern/audaspace/intern/AUD_FloatMixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
index f7133b9c30e..bddc719b179 100644
--- a/intern/audaspace/intern/AUD_FloatMixer.cpp
+++ b/intern/audaspace/intern/AUD_Mixer.cpp
@@ -23,8 +23,7 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
-#include "AUD_ConverterFactory.h"
+#include "AUD_Mixer.h"
#include "AUD_SRCResampleFactory.h"
#include "AUD_ChannelMapperFactory.h"
#include "AUD_IReader.h"
@@ -32,23 +31,19 @@
#include <cstring>
-AUD_FloatMixer::AUD_FloatMixer()
+AUD_Mixer::AUD_Mixer()
{
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
- m_converter = NULL;
m_resampler = NULL;
m_mapper = NULL;
}
-AUD_FloatMixer::~AUD_FloatMixer()
+AUD_Mixer::~AUD_Mixer()
{
delete m_buffer; AUD_DELETE("buffer")
- if(m_converter)
- {
- delete m_converter; AUD_DELETE("factory")
- }
+
if(m_resampler)
{
delete m_resampler; AUD_DELETE("factory")
@@ -59,11 +54,8 @@ AUD_FloatMixer::~AUD_FloatMixer()
}
}
-AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
+AUD_IReader* AUD_Mixer::prepare(AUD_IReader* reader)
{
- m_converter->setReader(reader);
- reader = m_converter->createReader();
-
m_resampler->setReader(reader);
reader = m_resampler->createReader();
@@ -76,14 +68,10 @@ AUD_IReader* AUD_FloatMixer::prepare(AUD_IReader* reader)
return reader;
}
-void AUD_FloatMixer::setSpecs(AUD_Specs specs)
+void AUD_Mixer::setSpecs(AUD_DeviceSpecs specs)
{
m_specs = specs;
- if(m_converter)
- {
- delete m_converter; AUD_DELETE("factory")
- }
if(m_resampler)
{
delete m_resampler; AUD_DELETE("factory")
@@ -93,9 +81,6 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
delete m_mapper; AUD_DELETE("factory")
}
- specs.format = AUD_FORMAT_FLOAT32;
-
- m_converter = new AUD_ConverterFactory(specs); AUD_NEW("factory")
m_resampler = new AUD_SRCResampleFactory(specs); AUD_NEW("factory")
m_mapper = new AUD_ChannelMapperFactory(specs); AUD_NEW("factory")
@@ -130,27 +115,26 @@ void AUD_FloatMixer::setSpecs(AUD_Specs specs)
}
}
-void AUD_FloatMixer::add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)
+void AUD_Mixer::add(sample_t* buffer, int length, float volume)
{
- AUD_FloatMixerBuffer buf;
+ AUD_MixerBuffer buf;
buf.buffer = buffer;
buf.length = length;
buf.volume = volume;
m_buffers.push_back(buf);
}
-void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
+void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
{
- AUD_FloatMixerBuffer buf;
+ AUD_MixerBuffer buf;
int channels = m_specs.channels;
if(m_buffer->getSize() < length * channels * 4)
m_buffer->resize(length * channels * 4);
- float* out = (float*)m_buffer->getBuffer();
- float* in;
+ sample_t* out = m_buffer->getBuffer();
+ sample_t* in;
memset(out, 0, length * channels * 4);
@@ -162,11 +146,11 @@ void AUD_FloatMixer::superpose(sample_t* buffer, int length, float volume)
m_buffers.pop_front();
end = buf.length*channels;
- in = (float*) buf.buffer;
+ in = buf.buffer;
for(int i = 0; i < end; i++)
out[i] += in[i]*buf.volume * volume;
}
- m_convert(buffer, (sample_t*) out, length * channels);
+ m_convert(buffer, (data_t*) out, length * channels);
}
diff --git a/intern/audaspace/intern/AUD_IMixer.h b/intern/audaspace/intern/AUD_Mixer.h
index c65e4c69cf7..5097b9ec2a6 100644
--- a/intern/audaspace/intern/AUD_IMixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -23,47 +23,95 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#ifndef AUD_IMIXER
-#define AUD_IMIXER
+#ifndef AUD_MIXER
+#define AUD_MIXER
-#include "AUD_Space.h"
+#include "AUD_ConverterFunctions.h"
+class AUD_ConverterFactory;
+class AUD_SRCResampleFactory;
+class AUD_ChannelMapperFactory;
+class AUD_Buffer;
class AUD_IReader;
+#include <list>
+
+struct AUD_MixerBuffer
+{
+ sample_t* buffer;
+ int length;
+ float volume;
+};
/**
- * This class is able to mix audiosignals of different format and channel count.
- * \note This class doesn't do resampling!
+ * This class is able to mix audiosignals of different channel count and sample
+ * rate and convert it to a specific output format.
+ * It uses a default ChannelMapperFactory and a SRCResampleFactory for
+ * the perparation.
*/
-class AUD_IMixer
+class AUD_Mixer
{
+private:
+ /**
+ * The resampling factory that resamples all readers for superposition.
+ */
+ AUD_SRCResampleFactory* m_resampler;
+
+ /**
+ * The channel mapper factory that maps all readers for superposition.
+ */
+ AUD_ChannelMapperFactory* m_mapper;
+
+ /**
+ * The list of buffers to superpose.
+ */
+ std::list<AUD_MixerBuffer> m_buffers;
+
+ /**
+ * The output specification.
+ */
+ AUD_DeviceSpecs m_specs;
+
+ /**
+ * The temporary mixing buffer.
+ */
+ AUD_Buffer* m_buffer;
+
+ /**
+ * Converter function.
+ */
+ AUD_convert_f m_convert;
+
public:
/**
+ * Creates the mixer.
+ */
+ AUD_Mixer();
+
+ /**
* Destroys the mixer.
*/
- virtual ~AUD_IMixer(){}
+ ~AUD_Mixer();
/**
* This funuction prepares a reader for playback.
* \param reader The reader to prepare.
* \return The reader that should be used for playback.
*/
- virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+ AUD_IReader* prepare(AUD_IReader* reader);
/**
* Sets the target specification for superposing.
* \param specs The target specification.
*/
- virtual void setSpecs(AUD_Specs specs)=0;
+ void setSpecs(AUD_DeviceSpecs specs);
/**
* Adds a buffer for superposition.
* \param buffer The buffer to superpose.
- * \param specs The specification of the buffer.
* \param start The start sample of the buffer.
* \param length The length of the buffer in samples.
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
*/
- virtual void add(sample_t* buffer, AUD_Specs specs, int length,
- float volume)=0;
+ void add(sample_t* buffer, int length, float volume);
/**
* Superposes all added buffers into an output buffer.
@@ -71,7 +119,7 @@ public:
* \param length The length of the buffer in samples.
* \param volume The mixing volume. Must be a value between 0.0 and 1.0.
*/
- virtual void superpose(sample_t* buffer, int length, float volume)=0;
+ void superpose(data_t* buffer, int length, float volume);
};
-#endif //AUD_IMIXER
+#endif //AUD_MIXER
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
index db38d1004db..e78818301fa 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -49,7 +49,7 @@ AUD_IReader* AUD_MixerFactory::getReader()
}
AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
- AUD_Specs specs)
+ AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = reader;
@@ -57,14 +57,14 @@ AUD_MixerFactory::AUD_MixerFactory(AUD_IReader* reader,
}
AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
- AUD_Specs specs)
+ AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = 0;
m_factory = factory;
}
-AUD_MixerFactory::AUD_MixerFactory(AUD_Specs specs)
+AUD_MixerFactory::AUD_MixerFactory(AUD_DeviceSpecs specs)
{
m_specs = specs;
m_reader = 0;
@@ -79,12 +79,12 @@ AUD_MixerFactory::~AUD_MixerFactory()
}
}
-AUD_Specs AUD_MixerFactory::getSpecs()
+AUD_DeviceSpecs AUD_MixerFactory::getSpecs()
{
return m_specs;
}
-void AUD_MixerFactory::setSpecs(AUD_Specs specs)
+void AUD_MixerFactory::setSpecs(AUD_DeviceSpecs specs)
{
m_specs = specs;
}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
index c61dd283c67..a2f4aa78d76 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -47,7 +47,7 @@ protected:
/**
* The target specification for resampling.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
* Returns the reader created out of the factory or taken from m_reader.
@@ -63,20 +63,20 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IReader* reader, AUD_Specs specs);
+ AUD_MixerFactory(AUD_IReader* reader, AUD_DeviceSpecs specs);
/**
* Creates a new factory.
* \param factory The factory to create the readers to mix out of.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IFactory* factory, AUD_Specs specs);
+ AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
/**
* Creates a new factory.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_Specs specs);
+ AUD_MixerFactory(AUD_DeviceSpecs specs);
/**
* Destroys the resampling factory.
@@ -86,13 +86,13 @@ public:
/**
* Returns the target specification for resampling.
*/
- AUD_Specs getSpecs();
+ AUD_DeviceSpecs getSpecs();
/**
* Sets the target specification for resampling.
* \param specs The specification.
*/
- void setSpecs(AUD_Specs specs);
+ void setSpecs(AUD_DeviceSpecs specs);
/**
* Sets the reader for resampling.
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index d237b71b67e..3936695c28f 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -34,7 +34,7 @@ AUD_NULLDevice::AUD_NULLDevice()
m_specs.rate = AUD_RATE_INVALID;
}
-AUD_Specs AUD_NULLDevice::getSpecs()
+AUD_DeviceSpecs AUD_NULLDevice::getSpecs()
{
return m_specs;
}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index 155f24f8837..91ddd23cf71 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -37,7 +37,7 @@ private:
/**
* The specs of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
public:
/**
@@ -45,7 +45,7 @@ public:
*/
AUD_NULLDevice();
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
index e2c1d2fac81..37a7d1ae295 100644
--- a/intern/audaspace/intern/AUD_ReadDevice.cpp
+++ b/intern/audaspace/intern/AUD_ReadDevice.cpp
@@ -23,17 +23,17 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_ReadDevice.h"
#include "AUD_IReader.h"
#include <cstring>
-AUD_ReadDevice::AUD_ReadDevice(AUD_Specs specs)
+AUD_ReadDevice::AUD_ReadDevice(AUD_DeviceSpecs specs)
{
m_specs = specs;
- m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
+ m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
m_mixer->setSpecs(m_specs);
m_playing = false;
@@ -46,15 +46,15 @@ AUD_ReadDevice::~AUD_ReadDevice()
destroy();
}
-bool AUD_ReadDevice::read(sample_t* buffer, int length)
+bool AUD_ReadDevice::read(data_t* buffer, int length)
{
if(m_playing)
mix(buffer, length);
else
if(m_specs.format == AUD_FORMAT_U8)
- memset(buffer, 0x80, length * AUD_SAMPLE_SIZE(m_specs));
+ memset(buffer, 0x80, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
else
- memset(buffer, 0, length * AUD_SAMPLE_SIZE(m_specs));
+ memset(buffer, 0, length * AUD_DEVICE_SAMPLE_SIZE(m_specs));
return m_playing;
}
diff --git a/intern/audaspace/intern/AUD_ReadDevice.h b/intern/audaspace/intern/AUD_ReadDevice.h
index d69b0c31ea5..3fd90df7755 100644
--- a/intern/audaspace/intern/AUD_ReadDevice.h
+++ b/intern/audaspace/intern/AUD_ReadDevice.h
@@ -47,7 +47,7 @@ public:
* Creates a new read device.
* \param specs The wanted audio specification.
*/
- AUD_ReadDevice(AUD_Specs specs);
+ AUD_ReadDevice(AUD_DeviceSpecs specs);
/**
* Closes the device.
@@ -62,7 +62,7 @@ public:
* played back currently, in that case the buffer is filled with
* silence.
*/
- bool read(sample_t* buffer, int length);
+ bool read(data_t* buffer, int length);
};
#endif //AUD_READDEVICE
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
index 87e2f789d66..83a1a3ed3c3 100644
--- a/intern/audaspace/intern/AUD_SinusReader.cpp
+++ b/intern/audaspace/intern/AUD_SinusReader.cpp
@@ -26,7 +26,7 @@
#include "AUD_SinusReader.h"
#include "AUD_Buffer.h"
-#include <math.h>
+#include <cmath>
#ifndef M_PI
#define M_PI 3.14159265358979323846
@@ -69,8 +69,7 @@ AUD_Specs AUD_SinusReader::getSpecs()
{
AUD_Specs specs;
specs.rate = m_sampleRate;
- specs.format = AUD_FORMAT_S16;
- specs.channels = AUD_CHANNELS_STEREO;
+ specs.channels = AUD_CHANNELS_MONO;
return specs;
}
@@ -87,18 +86,16 @@ bool AUD_SinusReader::notify(AUD_Message &message)
void AUD_SinusReader::read(int & length, sample_t* & buffer)
{
// resize if necessary
- if(m_buffer->getSize() < length*4)
- m_buffer->resize(length*4);
+ if(m_buffer->getSize() < length * sizeof(sample_t))
+ m_buffer->resize(length * sizeof(sample_t));
// fill with sine data
- short* buf = (short*) m_buffer->getBuffer();
- for(int i=0; i < length; i++)
+ buffer = m_buffer->getBuffer();
+ for(int i = 0; i < length; i++)
{
- buf[i*2] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
- (float)m_sampleRate) * 32700;
- buf[i*2+1] = buf[i*2];
+ buffer[i] = sin((m_position + i) * 2.0 * M_PI * m_frequency /
+ (float)m_sampleRate);
}
- buffer = (sample_t*)buf;
m_position += length;
}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index 42a90a6f15e..142251c7e2d 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -25,7 +25,7 @@
#include "AUD_SoftwareDevice.h"
#include "AUD_IReader.h"
-#include "AUD_IMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_IFactory.h"
#include "AUD_SourceCaps.h"
@@ -52,6 +52,8 @@ void AUD_SoftwareDevice::create()
m_pausedSounds = new std::list<AUD_SoftwareHandle*>(); AUD_NEW("list")
m_playback = false;
m_volume = 1.0;
+ m_mixer = new AUD_Mixer(); AUD_NEW("mixer")
+ m_mixer->setSpecs(m_specs);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -90,7 +92,7 @@ void AUD_SoftwareDevice::destroy()
pthread_mutex_destroy(&m_mutex);
}
-void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
+void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
lock();
@@ -98,7 +100,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
AUD_SoftwareHandle* sound;
int len;
sample_t* buf;
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
+ int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
std::list<AUD_SoftwareHandle*> stopSounds;
// for all sounds
@@ -114,7 +116,7 @@ void AUD_SoftwareDevice::mix(sample_t* buffer, int length)
len = length;
sound->reader->read(len, buf);
- m_mixer->add(buf, sound->reader->getSpecs(), len, sound->volume);
+ m_mixer->add(buf, len, sound->volume);
// in case the end of the sound is reached
if(len < length)
@@ -159,14 +161,7 @@ bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
return false;
}
-void AUD_SoftwareDevice::setMixer(AUD_IMixer* mixer)
-{
- delete m_mixer; AUD_DELETE("mixer")
- m_mixer = mixer;
- mixer->setSpecs(m_specs);
-}
-
-AUD_Specs AUD_SoftwareDevice::getSpecs()
+AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs()
{
return m_specs;
}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 3768786fa9c..a12fddb1e00 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -28,7 +28,7 @@
#include "AUD_IDevice.h"
struct AUD_SoftwareHandle;
-class AUD_IMixer;
+class AUD_Mixer;
#include <list>
#include <pthread.h>
@@ -47,12 +47,12 @@ protected:
/**
* The specification of the device.
*/
- AUD_Specs m_specs;
+ AUD_DeviceSpecs m_specs;
/**
- * The mixer. Will be deleted by the destroy function.
+ * The mixer.
*/
- AUD_IMixer* m_mixer;
+ AUD_Mixer* m_mixer;
/**
* Initializes member variables.
@@ -69,7 +69,7 @@ protected:
* \param buffer The target buffer.
* \param length The length in samples to be filled.
*/
- void mix(sample_t* buffer, int length);
+ void mix(data_t* buffer, int length);
/**
* This function tells the device, to start or pause playback.
@@ -111,13 +111,7 @@ private:
bool isValid(AUD_Handle* handle);
public:
- /**
- * Sets a new mixer.
- * \param mixer The new mixer.
- */
- void setMixer(AUD_IMixer* mixer);
-
- virtual AUD_Specs getSpecs();
+ virtual AUD_DeviceSpecs getSpecs();
virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
index 123d9c272a0..1d60be3979b 100644
--- a/intern/audaspace/intern/AUD_Space.h
+++ b/intern/audaspace/intern/AUD_Space.h
@@ -28,8 +28,10 @@
/// The size of a format in bytes.
#define AUD_FORMAT_SIZE(format) (format & 0x0F)
+/// The size of a sample in the specified device format in bytes.
+#define AUD_DEVICE_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
/// The size of a sample in the specified format in bytes.
-#define AUD_SAMPLE_SIZE(specs) (specs.channels * (specs.format & 0x0F))
+#define AUD_SAMPLE_SIZE(specs) (specs.channels * sizeof(sample_t))
/// Throws a AUD_Exception with the provided error code.
#define AUD_THROW(exception) { AUD_Exception e; e.error = exception; throw e; }
@@ -233,22 +235,42 @@ typedef enum
AUD_3DSS_CONE_OUTER_GAIN /// Cone outer gain.
} AUD_3DSourceSetting;
-/// Sample pointer type.
-typedef unsigned char sample_t;
+/// Sample type.(float samples)
+typedef float sample_t;
-/// Specification of a sound source or device.
+/// Sample data type (format samples)
+typedef unsigned char data_t;
+
+/// Specification of a sound source.
typedef struct
{
/// Sample rate in Hz.
AUD_SampleRate rate;
- /// Sample format.
- AUD_SampleFormat format;
-
/// Channel count.
AUD_Channels channels;
} AUD_Specs;
+/// Specification of a sound device.
+typedef struct
+{
+ /// Sample format.
+ AUD_SampleFormat format;
+
+ union
+ {
+ struct
+ {
+ /// Sample rate in Hz.
+ AUD_SampleRate rate;
+
+ /// Channel count.
+ AUD_Channels channels;
+ };
+ AUD_Specs specs;
+ };
+} AUD_DeviceSpecs;
+
/// Exception structure.
typedef struct
{
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
index 11391fa4a08..4d2cd9e2505 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -61,9 +61,9 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory)
// read more
length = size-index;
reader->read(length, buffer);
- memcpy(m_buffer.get()->getBuffer()+index*sample_size,
+ memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
buffer,
- length*sample_size);
+ length * sample_size);
size += AUD_BUFFER_RESIZE_BYTES / sample_size;
index += length;
}
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
index 4d8ab93d672..acd37de870c 100644
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -23,7 +23,7 @@
* ***** END LGPL LICENSE BLOCK *****
*/
-#include "AUD_FloatMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_JackDevice.h"
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
@@ -38,7 +38,7 @@ int AUD_JackDevice::jack_mix(jack_nframes_t length, void *data)
unsigned int samplesize = AUD_SAMPLE_SIZE(device->m_specs);
if(device->m_buffer->getSize() < samplesize * length)
device->m_buffer->resize(samplesize * length);
- device->mix(device->m_buffer->getBuffer(), length);
+ device->mix((data_t*)device->m_buffer->getBuffer(), length);
float* in = (float*) device->m_buffer->getBuffer();
float* out;
@@ -60,7 +60,7 @@ void AUD_JackDevice::jack_shutdown(void *data)
device->m_valid = false;
}
-AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
+AUD_JackDevice::AUD_JackDevice(AUD_DeviceSpecs specs)
{
if(specs.channels == AUD_CHANNELS_INVALID)
specs.channels = AUD_CHANNELS_STEREO;
@@ -123,9 +123,6 @@ AUD_JackDevice::AUD_JackDevice(AUD_Specs specs)
free(ports);
}
- m_mixer = new AUD_FloatMixer(); AUD_NEW("mixer")
- m_mixer->setSpecs(m_specs);
-
m_valid = true;
create();
diff --git a/intern/audaspace/jack/AUD_JackDevice.h b/intern/audaspace/jack/AUD_JackDevice.h
index f0c887a2f43..5a073a69432 100644
--- a/intern/audaspace/jack/AUD_JackDevice.h
+++ b/intern/audaspace/jack/AUD_JackDevice.h
@@ -81,7 +81,7 @@ public:
* \param specs The wanted audio specification, where only the channel count is important.
* \exception AUD_Exception Thrown if the audio device cannot be opened.
*/
- AUD_JackDevice(AUD_Specs specs);
+ AUD_JackDevice(AUD_DeviceSpecs specs);
/**
* Closes the Jack client.
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
index 485818552bb..f9ed8d6388e 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -28,31 +28,14 @@
#include <cstring>
-// This function transforms a SampleFormat to our own sample format
-static inline AUD_SampleFormat SNDFILE_TO_AUD(int fmt)
-{
- switch(fmt & SF_FORMAT_SUBMASK)
- {
- // only read s16, s32 and double as they are
- case SF_FORMAT_PCM_16:
- return AUD_FORMAT_S16;
- case SF_FORMAT_PCM_32:
- return AUD_FORMAT_S32;
- case SF_FORMAT_DOUBLE:
- return AUD_FORMAT_FLOAT64;
- // read all other formats as floats
- default:
- return AUD_FORMAT_FLOAT32;
- }
-}
-
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
return reader->m_membuffer.get()->getSize();
}
-sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user_data)
+sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
+ void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
@@ -72,14 +55,16 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence, void *user
return reader->m_memoffset;
}
-sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count, void *user_data)
+sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
+ void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
if(reader->m_memoffset + count > reader->m_membuffer.get()->getSize())
count = reader->m_membuffer.get()->getSize() - reader->m_memoffset;
- memcpy(ptr, reader->m_membuffer.get()->getBuffer() + reader->m_memoffset, count);
+ memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
+ reader->m_memoffset, count);
reader->m_memoffset += count;
return count;
@@ -103,27 +88,11 @@ AUD_SndFileReader::AUD_SndFileReader(const char* filename)
AUD_THROW(AUD_ERROR_FILE);
m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
m_length = sfinfo.frames;
m_seekable = sfinfo.seekable;
m_position = 0;
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- m_read = (sf_read_f) sf_readf_short;
- break;
- case AUD_FORMAT_S32:
- m_read = (sf_read_f) sf_readf_int;
- break;
- case AUD_FORMAT_FLOAT64:
- m_read = (sf_read_f) sf_readf_double;
- break;
- default:
- m_read = (sf_read_f) sf_readf_float;
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -147,27 +116,11 @@ AUD_SndFileReader::AUD_SndFileReader(AUD_Reference<AUD_Buffer> buffer)
AUD_THROW(AUD_ERROR_FILE);
m_specs.channels = (AUD_Channels) sfinfo.channels;
- m_specs.format = SNDFILE_TO_AUD(sfinfo.format);
m_specs.rate = (AUD_SampleRate) sfinfo.samplerate;
m_length = sfinfo.frames;
m_seekable = sfinfo.seekable;
m_position = 0;
- switch(m_specs.format)
- {
- case AUD_FORMAT_S16:
- m_read = (sf_read_f) sf_readf_short;
- break;
- case AUD_FORMAT_S32:
- m_read = (sf_read_f) sf_readf_int;
- break;
- case AUD_FORMAT_FLOAT64:
- m_read = (sf_read_f) sf_readf_double;
- break;
- default:
- m_read = (sf_read_f) sf_readf_float;
- }
-
m_buffer = new AUD_Buffer(); AUD_NEW("buffer")
}
@@ -227,7 +180,7 @@ void AUD_SndFileReader::read(int & length, sample_t* & buffer)
buffer = m_buffer->getBuffer();
- length = m_read(m_sndfile, buffer, length);
+ length = sf_readf_float(m_sndfile, buffer, length);
m_position += length;
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
index da890ef53ca..8886b6e9efc 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -71,11 +71,6 @@ private:
SNDFILE* m_sndfile;
/**
- * The reading function.
- */
- sf_read_f m_read;
-
- /**
* The virtual IO structure for memory file reading.
*/
SF_VIRTUAL_IO m_vio;
diff --git a/source/blender/blenkernel/BKE_sound.h b/source/blender/blenkernel/BKE_sound.h
index 64ce1983e7d..8722485b97d 100644
--- a/source/blender/blenkernel/BKE_sound.h
+++ b/source/blender/blenkernel/BKE_sound.h
@@ -73,7 +73,7 @@ void sound_update_playing(struct bContext *C);
void sound_scrub(struct bContext *C);
#ifdef AUD_CAPI
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume);
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume);
#endif
void sound_stop_all(struct bContext *C);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index aa81cea79f5..767834159b2 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -3792,7 +3792,7 @@ Sequence *sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoadInfo
info = AUD_getInfo(sound->handle);
- if (info.specs.format == AUD_FORMAT_INVALID) {
+ if (info.specs.channels == AUD_CHANNELS_INVALID) {
sound_delete(C, sound);
//if(op)
// BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
diff --git a/source/blender/blenkernel/intern/sound.c b/source/blender/blenkernel/intern/sound.c
index 74c6afdc018..3232e2677b5 100644
--- a/source/blender/blenkernel/intern/sound.c
+++ b/source/blender/blenkernel/intern/sound.c
@@ -40,7 +40,7 @@ void sound_disable()
void sound_init()
{
- AUD_Specs specs;
+ AUD_DeviceSpecs specs;
int device, buffersize;
device = U.audiodevice;
@@ -455,7 +455,7 @@ void sound_scrub(struct bContext *C)
}
}
-AUD_Device* sound_mixdown(struct Scene *scene, AUD_Specs specs, int start, int end, float volume)
+AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start, int end, float volume)
{
AUD_Device* mixdown = AUD_openReadDevice(specs);
SoundHandle *handle;
diff --git a/source/blender/blenkernel/intern/writeffmpeg.c b/source/blender/blenkernel/intern/writeffmpeg.c
index 417679417e4..5b58f0bfedc 100644
--- a/source/blender/blenkernel/intern/writeffmpeg.c
+++ b/source/blender/blenkernel/intern/writeffmpeg.c
@@ -832,7 +832,7 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
if(ffmpeg_multiplex_audio && audio_stream)
{
AVCodecContext* c = get_codec_from_stream(audio_stream);
- AUD_Specs specs;
+ AUD_DeviceSpecs specs;
specs.channels = c->channels;
specs.format = AUD_FORMAT_S16;
specs.rate = rd->ffcodecdata.audio_mixrate;
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index 3b42fc7b382..d48a322f562 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -81,7 +81,7 @@ static int open_exec(bContext *C, wmOperator *op)
info = AUD_getInfo(sound->handle);
- if (info.specs.format == AUD_FORMAT_INVALID) {
+ if (info.specs.channels == AUD_CHANNELS_INVALID) {
sound_delete(C, sound);
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
return OPERATOR_CANCELLED;
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 8ac3f2efefb..607425665af 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -36,6 +36,8 @@
#include <config.h>
#endif
+#include "AUD_C-API.h"
+
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -990,6 +992,139 @@ void GRAPH_OT_bake (wmOperatorType *ot)
// todo: add props for start/end frames
}
+/* ******************** Sound Bake F-Curve Operator *********************** */
+/* This operator bakes the given sound to the selected F-Curves */
+
+/* ------------------- */
+
+/* Custom data storage passed to the F-Sample-ing function,
+ * which provides the necessary info for baking the sound
+ */
+typedef struct tSoundBakeInfo {
+ float* samples;
+ int length;
+ int cfra;
+} tSoundBakeInfo;
+
+/* ------------------- */
+
+/* Sampling callback used to determine the value from the sound to
+ * save in the F-Curve at the specified frame
+ */
+static float fcurve_samplingcb_sound (FCurve *fcu, void *data, float evaltime)
+{
+ tSoundBakeInfo *sbi= (tSoundBakeInfo *)data;
+
+ int position = evaltime - sbi->cfra;
+ if((position < 0) || (position >= sbi->length))
+ return 0.0f;
+
+ return sbi->samples[position];
+}
+
+/* ------------------- */
+
+static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ tSoundBakeInfo sbi;
+ Scene *scene= NULL;
+ int start, end;
+
+ char path[FILE_MAX];
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ RNA_string_get(op->ptr, "path", path);
+
+ scene= ac.scene; /* current scene */
+
+ /* store necessary data for the baking steps */
+ sbi.samples = AUD_readSoundBuffer(path,
+ RNA_float_get(op->ptr, "low"),
+ RNA_float_get(op->ptr, "high"),
+ RNA_float_get(op->ptr, "attack"),
+ RNA_float_get(op->ptr, "release"),
+ RNA_float_get(op->ptr, "threshold"),
+ FPS, &sbi.length);
+
+ if (sbi.samples == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* determine extents of the baking */
+ sbi.cfra = start = CFRA;
+ end = CFRA + sbi.length - 1;
+
+ /* filter anim channels */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* loop through all selected F-Curves, replacing its data with the sound samples */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->key_data;
+
+ /* sample the sound */
+ fcurve_store_samples(fcu, &sbi, start, end, fcurve_samplingcb_sound);
+ }
+
+ /* free sample data */
+ free(sbi.samples);
+
+ /* admin and redraws */
+ BLI_freelistN(&anim_data);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that 'keyframes' have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+static int graphkeys_sound_bake_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+ bAnimContext ac;
+
+ /* verify editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ return WM_operator_filesel(C, op, event);
+}
+
+void GRAPH_OT_sound_bake (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Bake Sound to F-Curves";
+ ot->idname= "GRAPH_OT_sound_bake";
+ ot->description= "Bakes a sound wave to selected F-Curves.";
+
+ /* api callbacks */
+ ot->invoke= graphkeys_sound_bake_invoke;
+ ot->exec= graphkeys_sound_bake_exec;
+ ot->poll= graphop_selected_fcurve_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* properties */
+ WM_operator_properties_filesel(ot, FOLDERFILE|SOUNDFILE|MOVIEFILE, FILE_SPECIAL);
+ RNA_def_float(ot->srna, "low", 0.0f, 0.0, 100000.0, "Lowest frequency", "", 0.1, 1000.00);
+ RNA_def_float(ot->srna, "high", 100000.0, 0.0, 100000.0, "Highest frequency", "", 0.1, 1000.00);
+ RNA_def_float(ot->srna, "attack", 0.005, 0.0, 2.0, "Attack time", "", 0.01, 0.1);
+ RNA_def_float(ot->srna, "release", 0.2, 0.0, 5.0, "Release time", "", 0.01, 0.2);
+ RNA_def_float(ot->srna, "threshold", 0.0, 0.0, 1.0, "Threshold", "", 0.01, 0.1);
+}
+
/* ******************** Sample Keyframes Operator *********************** */
/* This operator 'bakes' the values of the curve into new keyframes between pairs
* of selected keyframes. It is useful for creating keyframes for tweaking overlap.
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 87e03247353..ec6f38c93b7 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -100,6 +100,7 @@ void GRAPH_OT_delete(struct wmOperatorType *ot);
void GRAPH_OT_clean(struct wmOperatorType *ot);
void GRAPH_OT_sample(struct wmOperatorType *ot);
void GRAPH_OT_bake(struct wmOperatorType *ot);
+void GRAPH_OT_sound_bake(struct wmOperatorType *ot);
void GRAPH_OT_smooth(struct wmOperatorType *ot);
void GRAPH_OT_handle_type(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index 295ee869979..7be2d7b3e4b 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -247,6 +247,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_extrapolation_type);
WM_operatortype_append(GRAPH_OT_sample);
WM_operatortype_append(GRAPH_OT_bake);
+ WM_operatortype_append(GRAPH_OT_sound_bake);
WM_operatortype_append(GRAPH_OT_smooth);
WM_operatortype_append(GRAPH_OT_clean);
WM_operatortype_append(GRAPH_OT_delete);