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:
Diffstat (limited to 'intern/audaspace')
-rw-r--r--intern/audaspace/CMakeLists.txt12
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_AccumulatorFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp89
-rw-r--r--intern/audaspace/FX/AUD_BaseIIRFilterReader.h24
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.cpp16
-rw-r--r--intern/audaspace/FX/AUD_ButterworthFactory.h10
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp2
-rw-r--r--intern/audaspace/FX/AUD_CallbackIIRFilterReader.h2
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_DelayFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.cpp36
-rw-r--r--intern/audaspace/FX/AUD_DelayReader.h14
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.cpp18
-rw-r--r--intern/audaspace/FX/AUD_DoubleFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.cpp51
-rw-r--r--intern/audaspace/FX/AUD_DoubleReader.h9
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp42
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h49
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp45
-rw-r--r--intern/audaspace/FX/AUD_DynamicIIRFilterReader.h52
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_EffectFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.cpp7
-rw-r--r--intern/audaspace/FX/AUD_EffectReader.h7
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.cpp14
-rw-r--r--intern/audaspace/FX/AUD_EnvelopeFactory.h9
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_FaderFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.cpp46
-rw-r--r--intern/audaspace/FX/AUD_FaderReader.h14
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.cpp16
-rw-r--r--intern/audaspace/FX/AUD_HighpassFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.cpp14
-rw-r--r--intern/audaspace/FX/AUD_IIRFilterReader.h7
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_LimiterFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.cpp92
-rw-r--r--intern/audaspace/FX/AUD_LimiterReader.h8
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_LoopFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.cpp32
-rw-r--r--intern/audaspace/FX/AUD_LoopReader.h9
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.cpp16
-rw-r--r--intern/audaspace/FX/AUD_LowpassFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.cpp18
-rw-r--r--intern/audaspace/FX/AUD_PingPongFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_PitchFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.cpp14
-rw-r--r--intern/audaspace/FX/AUD_PitchReader.h7
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.cpp6
-rw-r--r--intern/audaspace/FX/AUD_RectifyFactory.h7
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_ReverseFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.cpp36
-rw-r--r--intern/audaspace/FX/AUD_ReverseReader.h9
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.cpp8
-rw-r--r--intern/audaspace/FX/AUD_SquareFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_SumFactory.h4
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.cpp17
-rw-r--r--intern/audaspace/FX/AUD_SuperposeFactory.h8
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.cpp38
-rw-r--r--intern/audaspace/FX/AUD_SuperposeReader.h9
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.cpp4
-rw-r--r--intern/audaspace/FX/AUD_VolumeFactory.h4
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.cpp1635
-rw-r--r--intern/audaspace/OpenAL/AUD_OpenALDevice.h159
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.cpp366
-rw-r--r--intern/audaspace/Python/AUD_PyAPI.h19
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.cpp13
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleFactory.h8
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.cpp74
-rw-r--r--intern/audaspace/SRC/AUD_SRCResampleReader.h27
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp10
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h2
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp34
-rw-r--r--intern/audaspace/ffmpeg/AUD_FFMPEGReader.h7
-rw-r--r--intern/audaspace/fftw/AUD_BandPassReader.cpp3
-rw-r--r--intern/audaspace/intern/AUD_3DMath.h138
-rw-r--r--intern/audaspace/intern/AUD_Buffer.cpp6
-rw-r--r--intern/audaspace/intern/AUD_Buffer.h10
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.cpp22
-rw-r--r--intern/audaspace/intern/AUD_BufferReader.h2
-rw-r--r--intern/audaspace/intern/AUD_C-API.cpp567
-rw-r--r--intern/audaspace/intern/AUD_C-API.h97
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.cpp73
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperFactory.h23
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.cpp343
-rw-r--r--intern/audaspace/intern/AUD_ChannelMapperReader.h56
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_ConverterFactory.h4
-rw-r--r--intern/audaspace/intern/AUD_ConverterFunctions.cpp68
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.cpp32
-rw-r--r--intern/audaspace/intern/AUD_ConverterReader.h7
-rw-r--r--intern/audaspace/intern/AUD_DefaultMixer.cpp77
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.cpp16
-rw-r--r--intern/audaspace/intern/AUD_FileFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_I3DDevice.h196
-rw-r--r--intern/audaspace/intern/AUD_I3DHandle.h213
-rw-r--r--intern/audaspace/intern/AUD_IDevice.h156
-rw-r--r--intern/audaspace/intern/AUD_IFactory.h3
-rw-r--r--intern/audaspace/intern/AUD_IHandle.h181
-rw-r--r--intern/audaspace/intern/AUD_IReader.h8
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.cpp13
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleFactory.h8
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.cpp146
-rw-r--r--intern/audaspace/intern/AUD_LinearResampleReader.h31
-rw-r--r--intern/audaspace/intern/AUD_Mixer.cpp46
-rw-r--r--intern/audaspace/intern/AUD_Mixer.h42
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.cpp6
-rw-r--r--intern/audaspace/intern/AUD_MixerFactory.h8
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.cpp80
-rw-r--r--intern/audaspace/intern/AUD_NULLDevice.h20
-rw-r--r--intern/audaspace/intern/AUD_ReadDevice.cpp1
-rw-r--r--intern/audaspace/intern/AUD_Reference.h158
-rw-r--r--intern/audaspace/intern/AUD_ReferenceHandler.cpp (renamed from intern/audaspace/intern/AUD_ResampleFactory.h)12
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.cpp47
-rw-r--r--intern/audaspace/intern/AUD_ResampleReader.h (renamed from intern/audaspace/intern/AUD_DefaultMixer.h)36
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.cpp59
-rw-r--r--intern/audaspace/intern/AUD_SequencerFactory.h22
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.cpp150
-rw-r--r--intern/audaspace/intern/AUD_SequencerReader.h31
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SilenceFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.cpp12
-rw-r--r--intern/audaspace/intern/AUD_SilenceReader.h7
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.cpp2
-rw-r--r--intern/audaspace/intern/AUD_SinusFactory.h2
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.cpp11
-rw-r--r--intern/audaspace/intern/AUD_SinusReader.h7
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.cpp1015
-rw-r--r--intern/audaspace/intern/AUD_SoftwareDevice.h211
-rw-r--r--intern/audaspace/intern/AUD_Space.h26
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.cpp25
-rw-r--r--intern/audaspace/intern/AUD_StreamBufferFactory.h4
-rw-r--r--intern/audaspace/jack/AUD_JackDevice.cpp2
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.cpp10
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileFactory.h2
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.cpp22
-rw-r--r--intern/audaspace/sndfile/AUD_SndFileReader.h7
144 files changed, 4494 insertions, 3529 deletions
diff --git a/intern/audaspace/CMakeLists.txt b/intern/audaspace/CMakeLists.txt
index 7eef13b103b..603e98a5782 100644
--- a/intern/audaspace/CMakeLists.txt
+++ b/intern/audaspace/CMakeLists.txt
@@ -41,6 +41,8 @@ set(SRC
FX/AUD_DelayReader.cpp
FX/AUD_DoubleFactory.cpp
FX/AUD_DoubleReader.cpp
+ FX/AUD_DynamicIIRFilterFactory.cpp
+ FX/AUD_DynamicIIRFilterReader.cpp
FX/AUD_EffectFactory.cpp
FX/AUD_EffectReader.cpp
FX/AUD_EnvelopeFactory.cpp
@@ -82,13 +84,13 @@ set(SRC
intern/AUD_ConverterFunctions.h
intern/AUD_ConverterReader.cpp
intern/AUD_ConverterReader.h
- intern/AUD_DefaultMixer.cpp
- intern/AUD_DefaultMixer.h
intern/AUD_FileFactory.cpp
intern/AUD_FileFactory.h
intern/AUD_I3DDevice.h
+ intern/AUD_I3DHandle.h
intern/AUD_IDevice.h
intern/AUD_IFactory.h
+ intern/AUD_IHandle.h
intern/AUD_IReader.h
intern/AUD_LinearResampleFactory.cpp
intern/AUD_LinearResampleFactory.h
@@ -104,7 +106,9 @@ set(SRC
intern/AUD_ReadDevice.cpp
intern/AUD_ReadDevice.h
intern/AUD_Reference.h
- intern/AUD_ResampleFactory.h
+ intern/AUD_ReferenceHandler.cpp
+ intern/AUD_ResampleReader.cpp
+ intern/AUD_ResampleReader.h
intern/AUD_SequencerFactory.cpp
intern/AUD_SequencerFactory.h
intern/AUD_SequencerReader.cpp
@@ -131,6 +135,8 @@ set(SRC
FX/AUD_DelayReader.h
FX/AUD_DoubleFactory.h
FX/AUD_DoubleReader.h
+ FX/AUD_DynamicIIRFilterFactory.h
+ FX/AUD_DynamicIIRFilterReader.h
FX/AUD_EffectFactory.h
FX/AUD_EffectReader.h
FX/AUD_EnvelopeFactory.h
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
index d60924958b1..0dffa7fc9ea 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_AccumulatorFactory.h"
#include "AUD_CallbackIIRFilterReader.h"
-sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_AccumulatorFactory::accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless)
{
float in = reader->x(0);
float lastin = reader->x(-1);
@@ -42,7 +42,7 @@ sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* us
return out;
}
-sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_AccumulatorFactory::accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
{
float in = reader->x(0);
float lastin = reader->x(-1);
@@ -52,14 +52,14 @@ sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
return out;
}
-AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_IFactory* factory,
+AUD_AccumulatorFactory::AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory,
bool additive) :
AUD_EffectFactory(factory),
m_additive(additive)
{
}
-AUD_IReader* AUD_AccumulatorFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_AccumulatorFactory::createReader()
{
return new AUD_CallbackIIRFilterReader(getReader(), 2, 2,
m_additive ? accumulatorFilterAdditive : accumulatorFilter);
diff --git a/intern/audaspace/FX/AUD_AccumulatorFactory.h b/intern/audaspace/FX/AUD_AccumulatorFactory.h
index 3c3b32ce071..5838ccee7f0 100644
--- a/intern/audaspace/FX/AUD_AccumulatorFactory.h
+++ b/intern/audaspace/FX/AUD_AccumulatorFactory.h
@@ -33,6 +33,7 @@
#define AUD_ACCUMULATORFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory creates an accumulator reader.
@@ -55,9 +56,12 @@ public:
* \param factory The input factory.
* \param additive Whether the accumulator is additive.
*/
- AUD_AccumulatorFactory(AUD_IFactory* factory, bool additive = false);
+ AUD_AccumulatorFactory(AUD_Reference<AUD_IFactory> factory, bool additive = false);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
+
+ static sample_t accumulatorFilterAdditive(AUD_CallbackIIRFilterReader* reader, void* useless);
+ static sample_t accumulatorFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
};
#endif //AUD_ACCUMULATORFACTORY
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
index 563722d9213..29ff6d90080 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.cpp
@@ -33,20 +33,20 @@
#include <cstring>
-#define CC m_channels + m_channel
+#define CC m_specs.channels + m_channel
-AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_IReader* reader, int in,
+AUD_BaseIIRFilterReader::AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in,
int out) :
AUD_EffectReader(reader),
- m_channels(reader->getSpecs().channels),
+ m_specs(reader->getSpecs()),
m_xlen(in), m_ylen(out),
m_xpos(0), m_ypos(0), m_channel(0)
{
- m_x = new sample_t[in * m_channels];
- m_y = new sample_t[out * m_channels];
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
- memset(m_x, 0, sizeof(sample_t) * in * m_channels);
- memset(m_y, 0, sizeof(sample_t) * out * m_channels);
+ memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
}
AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
@@ -55,24 +55,77 @@ AUD_BaseIIRFilterReader::~AUD_BaseIIRFilterReader()
delete[] m_y;
}
-void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
+void AUD_BaseIIRFilterReader::setLengths(int in, int out)
{
- sample_t* buf;
+ if(in != m_xlen)
+ {
+ sample_t* xn = new sample_t[in * m_specs.channels];
+ memset(xn, 0, sizeof(sample_t) * in * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= in && i <= m_xlen; i++)
+ {
+ xn[(in - i) * CC] = x(-i);
+ }
+ }
+
+ delete[] m_x;
+ m_x = xn;
+ m_xpos = 0;
+ m_xlen = in;
+ }
+
+ if(out != m_ylen)
+ {
+ sample_t* yn = new sample_t[out * m_specs.channels];
+ memset(yn, 0, sizeof(sample_t) * out * m_specs.channels);
+
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
+ {
+ for(int i = 1; i <= out && i <= m_ylen; i++)
+ {
+ yn[(out - i) * CC] = y(-i);
+ }
+ }
+
+ delete[] m_y;
+ m_y = yn;
+ m_ypos = 0;
+ m_ylen = out;
+ }
+}
+
+void AUD_BaseIIRFilterReader::read(int& length, bool& eos, sample_t* buffer)
+{
+ AUD_Specs specs = m_reader->getSpecs();
+ if(specs.channels != m_specs.channels)
+ {
+ m_specs.channels = specs.channels;
+
+ delete[] m_x;
+ delete[] m_y;
- int samplesize = AUD_SAMPLE_SIZE(m_reader->getSpecs());
+ m_x = new sample_t[m_xlen * m_specs.channels];
+ m_y = new sample_t[m_ylen * m_specs.channels];
- m_reader->read(length, buf);
+ memset(m_x, 0, sizeof(sample_t) * m_xlen * m_specs.channels);
+ memset(m_y, 0, sizeof(sample_t) * m_ylen * m_specs.channels);
+ }
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
+ if(specs.rate != m_specs.rate)
+ {
+ m_specs = specs;
+ sampleRateChanged(m_specs.rate);
+ }
- buffer = m_buffer.getBuffer();
+ m_reader->read(length, eos, buffer);
- for(m_channel = 0; m_channel < m_channels; m_channel++)
+ for(m_channel = 0; m_channel < m_specs.channels; m_channel++)
{
for(int i = 0; i < length; i++)
{
- m_x[m_xpos * CC] = buf[i * CC];
+ m_x[m_xpos * CC] = buffer[i * CC];
m_y[m_ypos * CC] = buffer[i * CC] = filter();
m_xpos = (m_xpos + 1) % m_xlen;
@@ -80,3 +133,7 @@ void AUD_BaseIIRFilterReader::read(int & length, sample_t* & buffer)
}
}
}
+
+void AUD_BaseIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
+{
+}
diff --git a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
index 436e6469a58..644bcffbfaf 100644
--- a/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_BaseIIRFilterReader.h
@@ -42,24 +42,19 @@ class AUD_BaseIIRFilterReader : public AUD_EffectReader
{
private:
/**
- * Channel count.
+ * Specs.
*/
- const int m_channels;
+ AUD_Specs m_specs;
/**
* Length of input samples needed.
*/
- const int m_xlen;
+ int m_xlen;
/**
* Length of output samples needed.
*/
- const int m_ylen;
-
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
+ int m_ylen;
/**
* The last in samples array.
@@ -97,24 +92,27 @@ protected:
* \param in The count of past input samples needed.
* \param out The count of past output samples needed.
*/
- AUD_BaseIIRFilterReader(AUD_IReader* reader, int in, int out);
+ AUD_BaseIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out);
+
+ void setLengths(int in, int out);
public:
inline sample_t x(int pos)
{
- return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_channels + m_channel];
+ return m_x[(m_xpos + pos + m_xlen) % m_xlen * m_specs.channels + m_channel];
}
inline sample_t y(int pos)
{
- return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_channels + m_channel];
+ return m_y[(m_ypos + pos + m_ylen) % m_ylen * m_specs.channels + m_channel];
}
virtual ~AUD_BaseIIRFilterReader();
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
virtual sample_t filter()=0;
+ virtual void sampleRateChanged(AUD_SampleRate rate);
};
#endif //AUD_BASEIIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.cpp b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
index ea957c81ed3..4b45512ffa6 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.cpp
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.cpp
@@ -41,19 +41,18 @@
#define BWPB41 0.76536686473
#define BWPB42 1.84775906502
-AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_IFactory* factory,
+AUD_ButterworthFactory::AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory,
float frequency) :
- AUD_EffectFactory(factory),
+ AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency)
{
}
-AUD_IReader* AUD_ButterworthFactory::createReader() const
+void AUD_ButterworthFactory::recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float> &b,
+ std::vector<float> &a)
{
- AUD_IReader* reader = getReader();
-
- // calculate coefficients
- float omega = 2 * tan(m_frequency * M_PI / reader->getSpecs().rate);
+ float omega = 2 * tan(m_frequency * M_PI / rate);
float o2 = omega * omega;
float o4 = o2 * o2;
float x1 = o2 + 2 * BWPB41 * omega + 4;
@@ -62,7 +61,6 @@ AUD_IReader* AUD_ButterworthFactory::createReader() const
float y2 = o2 - 2 * BWPB42 * omega + 4;
float o228 = 2 * o2 - 8;
float norm = x1 * x2;
- std::vector<float> a, b;
a.push_back(1);
a.push_back((x1 + x2) * o228 / norm);
a.push_back((x1 * y2 + x2 * y1 + o228 * o228) / norm);
@@ -73,6 +71,4 @@ AUD_IReader* AUD_ButterworthFactory::createReader() const
b.push_back(6 * o4 / norm);
b.push_back(b[1]);
b.push_back(b[0]);
-
- return new AUD_IIRFilterReader(reader, b, a);
}
diff --git a/intern/audaspace/FX/AUD_ButterworthFactory.h b/intern/audaspace/FX/AUD_ButterworthFactory.h
index c8b731449c4..16d0b3dbc23 100644
--- a/intern/audaspace/FX/AUD_ButterworthFactory.h
+++ b/intern/audaspace/FX/AUD_ButterworthFactory.h
@@ -32,12 +32,12 @@
#ifndef AUD_BUTTERWORTHFACTORY
#define AUD_BUTTERWORTHFACTORY
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
/**
* This factory creates a butterworth filter reader.
*/
-class AUD_ButterworthFactory : public AUD_EffectFactory
+class AUD_ButterworthFactory : public AUD_DynamicIIRFilterFactory
{
private:
/**
@@ -55,9 +55,11 @@ public:
* \param factory The input factory.
* \param frequency The cutoff frequency.
*/
- AUD_ButterworthFactory(AUD_IFactory* factory, float frequency);
+ AUD_ButterworthFactory(AUD_Reference<AUD_IFactory> factory, float frequency);
- virtual AUD_IReader* createReader() const;
+ virtual void recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float>& b,
+ std::vector<float>& a);
};
#endif //AUD_BUTTERWORTHFACTORY
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
index 2f9bb7762a0..e6c83322435 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_CallbackIIRFilterReader.h"
-AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_IReader* reader,
+AUD_CallbackIIRFilterReader::AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader,
int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter,
diff --git a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
index a969db7297e..6d53edeecc2 100644
--- a/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_CallbackIIRFilterReader.h
@@ -76,7 +76,7 @@ public:
* \param endFilter The finishing callback.
* \param data Data pointer for the callbacks.
*/
- AUD_CallbackIIRFilterReader(AUD_IReader* reader, int in, int out,
+ AUD_CallbackIIRFilterReader(AUD_Reference<AUD_IReader> reader, int in, int out,
doFilterIIR doFilter,
endFilterIIR endFilter = 0,
void* data = 0);
diff --git a/intern/audaspace/FX/AUD_DelayFactory.cpp b/intern/audaspace/FX/AUD_DelayFactory.cpp
index 1d2d99adc03..e452870281d 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.cpp
+++ b/intern/audaspace/FX/AUD_DelayFactory.cpp
@@ -33,7 +33,7 @@
#include "AUD_DelayReader.h"
#include "AUD_Space.h"
-AUD_DelayFactory::AUD_DelayFactory(AUD_IFactory* factory, float delay) :
+AUD_DelayFactory::AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay) :
AUD_EffectFactory(factory),
m_delay(delay)
{
@@ -44,7 +44,7 @@ float AUD_DelayFactory::getDelay() const
return m_delay;
}
-AUD_IReader* AUD_DelayFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DelayFactory::createReader()
{
return new AUD_DelayReader(getReader(), m_delay);
}
diff --git a/intern/audaspace/FX/AUD_DelayFactory.h b/intern/audaspace/FX/AUD_DelayFactory.h
index 1e67cd68990..5ab7f850d2f 100644
--- a/intern/audaspace/FX/AUD_DelayFactory.h
+++ b/intern/audaspace/FX/AUD_DelayFactory.h
@@ -55,14 +55,14 @@ public:
* \param factory The input factory.
* \param delay The desired delay in seconds.
*/
- AUD_DelayFactory(AUD_IFactory* factory, float delay = 0);
+ AUD_DelayFactory(AUD_Reference<AUD_IFactory> factory, float delay = 0);
/**
* Returns the delay in seconds.
*/
float getDelay() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_DELAYFACTORY
diff --git a/intern/audaspace/FX/AUD_DelayReader.cpp b/intern/audaspace/FX/AUD_DelayReader.cpp
index 374b876455d..7d58b3dae4f 100644
--- a/intern/audaspace/FX/AUD_DelayReader.cpp
+++ b/intern/audaspace/FX/AUD_DelayReader.cpp
@@ -33,11 +33,10 @@
#include <cstring>
-AUD_DelayReader::AUD_DelayReader(AUD_IReader* reader, float delay) :
+AUD_DelayReader::AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay) :
AUD_EffectReader(reader),
m_delay(int(delay * reader->getSpecs().rate)),
- m_remdelay(int(delay * reader->getSpecs().rate)),
- m_empty(true)
+ m_remdelay(int(delay * reader->getSpecs().rate))
{
}
@@ -70,49 +69,30 @@ int AUD_DelayReader::getPosition() const
return m_reader->getPosition() + m_delay;
}
-void AUD_DelayReader::read(int & length, sample_t* & buffer)
+void AUD_DelayReader::read(int& length, bool& eos, sample_t* buffer)
{
if(m_remdelay > 0)
{
AUD_Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_buffer.getSize() < length * samplesize)
- {
- m_buffer.resize(length * samplesize);
- m_empty = false;
- }
-
- buffer = m_buffer.getBuffer();
-
if(length > m_remdelay)
{
- if(!m_empty)
- memset(buffer, 0, m_remdelay * samplesize);
+ memset(buffer, 0, m_remdelay * samplesize);
int len = length - m_remdelay;
- sample_t* buf;
- m_reader->read(len, buf);
-
- memcpy(buffer + m_remdelay * specs.channels,
- buf, len * samplesize);
+ m_reader->read(len, eos, buffer + m_remdelay * specs.channels);
- if(len < length-m_remdelay)
- length = m_remdelay + len;
+ length = m_remdelay + len;
m_remdelay = 0;
- m_empty = false;
}
else
{
- if(!m_empty)
- {
- memset(buffer, 0, length * samplesize);
- m_empty = true;
- }
+ memset(buffer, 0, length * samplesize);
m_remdelay -= length;
}
}
else
- m_reader->read(length, buffer);
+ m_reader->read(length, eos, buffer);
}
diff --git a/intern/audaspace/FX/AUD_DelayReader.h b/intern/audaspace/FX/AUD_DelayReader.h
index 5f0af660bdf..a89afe73b37 100644
--- a/intern/audaspace/FX/AUD_DelayReader.h
+++ b/intern/audaspace/FX/AUD_DelayReader.h
@@ -42,11 +42,6 @@ class AUD_DelayReader : public AUD_EffectReader
{
private:
/**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
* The delay level.
*/
const int m_delay;
@@ -56,11 +51,6 @@ private:
*/
int m_remdelay;
- /**
- * Whether the buffer is currently filled with zeros.
- */
- bool m_empty;
-
// hide copy constructor and operator=
AUD_DelayReader(const AUD_DelayReader&);
AUD_DelayReader& operator=(const AUD_DelayReader&);
@@ -71,12 +61,12 @@ public:
* \param reader The reader to read from.
* \param delay The delay in seconds.
*/
- AUD_DelayReader(AUD_IReader* reader, float delay);
+ AUD_DelayReader(AUD_Reference<AUD_IReader> reader, float delay);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_DELAYREADER
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.cpp b/intern/audaspace/FX/AUD_DoubleFactory.cpp
index 7a40f1f8c96..e1e6ba50435 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.cpp
+++ b/intern/audaspace/FX/AUD_DoubleFactory.cpp
@@ -32,25 +32,15 @@
#include "AUD_DoubleFactory.h"
#include "AUD_DoubleReader.h"
-AUD_DoubleFactory::AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_DoubleFactory::AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_IReader* AUD_DoubleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DoubleFactory::createReader()
{
- AUD_IReader* reader1 = m_factory1->createReader();
- AUD_IReader* reader2;
-
- try
- {
- reader2 = m_factory2->createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+ AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
return new AUD_DoubleReader(reader1, reader2);
}
diff --git a/intern/audaspace/FX/AUD_DoubleFactory.h b/intern/audaspace/FX/AUD_DoubleFactory.h
index 52a299c7157..f2be7132442 100644
--- a/intern/audaspace/FX/AUD_DoubleFactory.h
+++ b/intern/audaspace/FX/AUD_DoubleFactory.h
@@ -44,12 +44,12 @@ private:
/**
* First played factory.
*/
- AUD_IFactory* m_factory1;
+ AUD_Reference<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_IFactory* m_factory2;
+ AUD_Reference<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_DoubleFactory(const AUD_DoubleFactory&);
@@ -61,9 +61,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_DoubleFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+ AUD_DoubleFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_DOUBLEFACTORY
diff --git a/intern/audaspace/FX/AUD_DoubleReader.cpp b/intern/audaspace/FX/AUD_DoubleReader.cpp
index 113bed14ce3..96352b0963c 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.cpp
+++ b/intern/audaspace/FX/AUD_DoubleReader.cpp
@@ -33,28 +33,17 @@
#include <cstring>
-static const char* specs_error = "AUD_DoubleReader: Both readers have to have "
- "the same specs.";
-
-AUD_DoubleReader::AUD_DoubleReader(AUD_IReader* reader1,
- AUD_IReader* reader2) :
+AUD_DoubleReader::AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1,
+ AUD_Reference<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2), m_finished1(false)
{
AUD_Specs s1, s2;
s1 = reader1->getSpecs();
s2 = reader2->getSpecs();
- if(memcmp(&s1, &s2, sizeof(AUD_Specs)) != 0)
- {
- delete reader1;
- delete reader2;
- AUD_THROW(AUD_ERROR_SPECS, specs_error);
- }
}
AUD_DoubleReader::~AUD_DoubleReader()
{
- delete m_reader1;
- delete m_reader2;
}
bool AUD_DoubleReader::isSeekable() const
@@ -90,43 +79,19 @@ int AUD_DoubleReader::getPosition() const
AUD_Specs AUD_DoubleReader::getSpecs() const
{
- return m_reader1->getSpecs();
+ return m_finished1 ? m_reader1->getSpecs() : m_reader2->getSpecs();
}
-void AUD_DoubleReader::read(int & length, sample_t* & buffer)
+void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
{
+ eos = false;
+
if(!m_finished1)
{
- int len = length;
- m_reader1->read(len, buffer);
-
- if(len < length)
- {
- AUD_Specs specs = m_reader1->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
-
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
-
- sample_t* buf = buffer;
- buffer = m_buffer.getBuffer();
-
- memcpy(buffer, buf, len * samplesize);
-
- len = length - len;
- length -= len;
- m_reader2->read(len, buf);
-
- memcpy(buffer + length * specs.channels, buf,
- len * samplesize);
-
- length += len;
-
- m_finished1 = true;
- }
+ m_reader1->read(length, m_finished1, buffer);
}
else
{
- m_reader2->read(length, buffer);
+ m_reader2->read(length, eos, buffer);
}
}
diff --git a/intern/audaspace/FX/AUD_DoubleReader.h b/intern/audaspace/FX/AUD_DoubleReader.h
index 7b3b812ef80..86f636e2cb2 100644
--- a/intern/audaspace/FX/AUD_DoubleReader.h
+++ b/intern/audaspace/FX/AUD_DoubleReader.h
@@ -34,6 +34,7 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ private:
/**
* The first reader.
*/
- AUD_IReader* m_reader1;
+ AUD_Reference<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_IReader* m_reader2;
+ AUD_Reference<AUD_IReader> m_reader2;
/**
* Whether we've reached the end of the first reader.
@@ -72,7 +73,7 @@ public:
* \param reader2 The second reader to read from.
* \exception AUD_Exception Thrown if the specs from the readers differ.
*/
- AUD_DoubleReader(AUD_IReader* reader1, AUD_IReader* reader2);
+ AUD_DoubleReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
/**
* Destroys the reader.
@@ -84,7 +85,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_DOUBLEREADER
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
new file mode 100644
index 00000000000..3018a2df571
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
@@ -0,0 +1,42 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.cpp
+ * \ingroup audfx
+ */
+
+#include "AUD_DynamicIIRFilterFactory.h"
+#include "AUD_DynamicIIRFilterReader.h"
+
+AUD_DynamicIIRFilterFactory::AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory) :
+ AUD_EffectFactory(factory)
+{
+}
+
+AUD_Reference<AUD_IReader> AUD_DynamicIIRFilterFactory::createReader()
+{
+ return new AUD_DynamicIIRFilterReader(getReader(), this);
+}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
new file mode 100644
index 00000000000..19c1a0f0a54
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterFactory.h
@@ -0,0 +1,49 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/FX/AUD_DynamicIIRFilterFactory.h
+ * \ingroup audfx
+ */
+
+#ifndef AUD_DYNAMICIIRFILTERFACTORY
+#define AUD_DYNAMICIIRFILTERFACTORY
+
+#include "AUD_EffectFactory.h"
+#include <vector>
+
+class AUD_DynamicIIRFilterFactory : public AUD_EffectFactory
+{
+public:
+ AUD_DynamicIIRFilterFactory(AUD_Reference<AUD_IFactory> factory);
+
+ virtual AUD_Reference<AUD_IReader> createReader();
+
+ virtual void recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float>& b,
+ std::vector<float>& a)=0;
+};
+
+#endif // AUD_DYNAMICIIRFILTERFACTORY
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
new file mode 100644
index 00000000000..ed9b2d3871d
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.cpp
@@ -0,0 +1,45 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/FX/AUD_DynamicIIRFilterReader.cpp
+ * \ingroup audfx
+ */
+
+#include "AUD_DynamicIIRFilterReader.h"
+
+AUD_DynamicIIRFilterReader::AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
+ AUD_Reference<AUD_DynamicIIRFilterFactory> factory) :
+ AUD_IIRFilterReader(reader, std::vector<float>(), std::vector<float>())
+{
+ sampleRateChanged(reader->getSpecs().rate);
+}
+
+void AUD_DynamicIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
+{
+ std::vector<float> a, b;
+ m_factory->recalculateCoefficients(rate, b, a);
+ setCoefficients(b, a);
+}
diff --git a/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
new file mode 100644
index 00000000000..92f491f04d4
--- /dev/null
+++ b/intern/audaspace/FX/AUD_DynamicIIRFilterReader.h
@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/FX/AUD_DynamicIIRFilterReader.h
+ * \ingroup audfx
+ */
+
+#ifndef AUD_DYNAMICIIRFILTERREADER
+#define AUD_DYNAMICIIRFILTERREADER
+
+#include "AUD_IIRFilterReader.h"
+#include "AUD_DynamicIIRFilterFactory.h"
+
+class AUD_DynamicIIRFilterReader : public AUD_IIRFilterReader
+{
+private:
+ /**
+ * The factory for dynamically recalculating filter coefficients.
+ */
+ AUD_Reference<AUD_DynamicIIRFilterFactory> m_factory;
+
+public:
+ AUD_DynamicIIRFilterReader(AUD_Reference<AUD_IReader> reader,
+ AUD_Reference<AUD_DynamicIIRFilterFactory> factory);
+
+ virtual void sampleRateChanged(AUD_SampleRate rate);
+};
+
+#endif // AUD_DYNAMICIIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_EffectFactory.cpp b/intern/audaspace/FX/AUD_EffectFactory.cpp
index a0d9256e691..6173ffb5a97 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.cpp
+++ b/intern/audaspace/FX/AUD_EffectFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_EffectFactory.h"
#include "AUD_IReader.h"
-AUD_EffectFactory::AUD_EffectFactory(AUD_IFactory* factory)
+AUD_EffectFactory::AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory)
{
m_factory = factory;
}
@@ -41,7 +41,7 @@ AUD_EffectFactory::~AUD_EffectFactory()
{
}
-AUD_IFactory* AUD_EffectFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_EffectFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/FX/AUD_EffectFactory.h b/intern/audaspace/FX/AUD_EffectFactory.h
index a6a28eea577..72fdb3f0833 100644
--- a/intern/audaspace/FX/AUD_EffectFactory.h
+++ b/intern/audaspace/FX/AUD_EffectFactory.h
@@ -49,7 +49,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_IFactory* m_factory;
+ AUD_Reference<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -57,7 +57,7 @@ protected:
* classes.
* \return The reader created out of the factory.
*/
- inline AUD_IReader* getReader() const
+ inline AUD_Reference<AUD_IReader> getReader() const
{
return m_factory->createReader();
}
@@ -67,7 +67,7 @@ public:
* Creates a new factory.
* \param factory The input factory.
*/
- AUD_EffectFactory(AUD_IFactory* factory);
+ AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory);
/**
* Destroys the factory.
@@ -78,7 +78,7 @@ public:
* Returns the saved factory.
* \return The factory or NULL if there has no factory been saved.
*/
- AUD_IFactory* getFactory() const;
+ AUD_Reference<AUD_IFactory> getFactory() const;
};
#endif //AUD_EFFECTFACTORY
diff --git a/intern/audaspace/FX/AUD_EffectReader.cpp b/intern/audaspace/FX/AUD_EffectReader.cpp
index 3ad9f67bfd6..4d14af76438 100644
--- a/intern/audaspace/FX/AUD_EffectReader.cpp
+++ b/intern/audaspace/FX/AUD_EffectReader.cpp
@@ -31,14 +31,13 @@
#include "AUD_EffectReader.h"
-AUD_EffectReader::AUD_EffectReader(AUD_IReader* reader)
+AUD_EffectReader::AUD_EffectReader(AUD_Reference<AUD_IReader> reader)
{
m_reader = reader;
}
AUD_EffectReader::~AUD_EffectReader()
{
- delete m_reader;
}
bool AUD_EffectReader::isSeekable() const
@@ -66,7 +65,7 @@ AUD_Specs AUD_EffectReader::getSpecs() const
return m_reader->getSpecs();
}
-void AUD_EffectReader::read(int & length, sample_t* & buffer)
+void AUD_EffectReader::read(int& length, bool& eos, sample_t* buffer)
{
- m_reader->read(length, buffer);
+ m_reader->read(length, eos, buffer);
}
diff --git a/intern/audaspace/FX/AUD_EffectReader.h b/intern/audaspace/FX/AUD_EffectReader.h
index fb8066f36d8..c03abd11828 100644
--- a/intern/audaspace/FX/AUD_EffectReader.h
+++ b/intern/audaspace/FX/AUD_EffectReader.h
@@ -33,6 +33,7 @@
#define AUD_EFFECTREADER
#include "AUD_IReader.h"
+#include "AUD_Reference.h"
/**
* This reader is a base class for all effect readers that take one other reader
@@ -49,14 +50,14 @@ protected:
/**
* The reader to read from.
*/
- AUD_IReader* m_reader;
+ AUD_Reference<AUD_IReader> m_reader;
public:
/**
* Creates a new effect reader.
* \param reader The reader to read from.
*/
- AUD_EffectReader(AUD_IReader* reader);
+ AUD_EffectReader(AUD_Reference<AUD_IReader> reader);
/**
* Destroys the reader.
@@ -68,7 +69,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_EFFECTREADER
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
index 069317d1c8b..80df7e9f874 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.cpp
@@ -42,7 +42,7 @@ struct EnvelopeParameters
float arthreshold;
};
-sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
+sample_t AUD_EnvelopeFactory::envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param)
{
float in = fabs(reader->x(0));
float out = reader->y(-1);
@@ -51,12 +51,12 @@ sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters*
return (in > out ? param->attack : param->release) * (out - in) + in;
}
-void endEnvelopeFilter(EnvelopeParameters* param)
+void AUD_EnvelopeFactory::endEnvelopeFilter(EnvelopeParameters* param)
{
delete param;
}
-AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
+AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack,
float release, float threshold,
float arthreshold) :
AUD_EffectFactory(factory),
@@ -67,14 +67,14 @@ AUD_EnvelopeFactory::AUD_EnvelopeFactory(AUD_IFactory* factory, float attack,
{
}
-AUD_IReader* AUD_EnvelopeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_EnvelopeFactory::createReader()
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
EnvelopeParameters* param = new EnvelopeParameters();
param->arthreshold = m_arthreshold;
- param->attack = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_attack));
- param->release = pow(m_arthreshold, 1.0f/(reader->getSpecs().rate * m_release));
+ param->attack = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_attack));
+ param->release = pow(m_arthreshold, 1.0f/(static_cast<float>(reader->getSpecs().rate) * m_release));
param->threshold = m_threshold;
return new AUD_CallbackIIRFilterReader(reader, 1, 2,
diff --git a/intern/audaspace/FX/AUD_EnvelopeFactory.h b/intern/audaspace/FX/AUD_EnvelopeFactory.h
index 45ee811b6e0..a480a05d478 100644
--- a/intern/audaspace/FX/AUD_EnvelopeFactory.h
+++ b/intern/audaspace/FX/AUD_EnvelopeFactory.h
@@ -33,6 +33,8 @@
#define AUD_ENVELOPEFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
+struct EnvelopeParameters;
/**
* This factory creates an envelope follower reader.
@@ -73,10 +75,13 @@ public:
* \param threshold The threshold value.
* \param arthreshold The attack/release threshold value.
*/
- AUD_EnvelopeFactory(AUD_IFactory* factory, float attack, float release,
+ AUD_EnvelopeFactory(AUD_Reference<AUD_IFactory> factory, float attack, float release,
float threshold, float arthreshold);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
+
+ static sample_t envelopeFilter(AUD_CallbackIIRFilterReader* reader, EnvelopeParameters* param);
+ static void endEnvelopeFilter(EnvelopeParameters* param);
};
#endif //AUD_ENVELOPEFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderFactory.cpp b/intern/audaspace/FX/AUD_FaderFactory.cpp
index d887e9e68d9..635873e0ee5 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.cpp
+++ b/intern/audaspace/FX/AUD_FaderFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_FaderFactory.h"
#include "AUD_FaderReader.h"
-AUD_FaderFactory::AUD_FaderFactory(AUD_IFactory* factory, AUD_FadeType type,
+AUD_FaderFactory::AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory, AUD_FadeType type,
float start, float length) :
AUD_EffectFactory(factory),
m_type(type),
@@ -56,7 +56,7 @@ float AUD_FaderFactory::getLength() const
return m_length;
}
-AUD_IReader* AUD_FaderFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FaderFactory::createReader()
{
return new AUD_FaderReader(getReader(), m_type, m_start, m_length);
}
diff --git a/intern/audaspace/FX/AUD_FaderFactory.h b/intern/audaspace/FX/AUD_FaderFactory.h
index b85475bc534..d8314c77ed4 100644
--- a/intern/audaspace/FX/AUD_FaderFactory.h
+++ b/intern/audaspace/FX/AUD_FaderFactory.h
@@ -69,7 +69,7 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderFactory(AUD_IFactory* factory,
+ AUD_FaderFactory(AUD_Reference<AUD_IFactory> factory,
AUD_FadeType type = AUD_FADE_IN,
float start = 0.0f, float length = 1.0f);
@@ -88,7 +88,7 @@ public:
*/
float getLength() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_FADERFACTORY
diff --git a/intern/audaspace/FX/AUD_FaderReader.cpp b/intern/audaspace/FX/AUD_FaderReader.cpp
index 6114bb486fc..4a6050cf0f3 100644
--- a/intern/audaspace/FX/AUD_FaderReader.cpp
+++ b/intern/audaspace/FX/AUD_FaderReader.cpp
@@ -33,68 +33,39 @@
#include <cstring>
-AUD_FaderReader::AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+AUD_FaderReader::AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
float start,float length) :
AUD_EffectReader(reader),
m_type(type),
m_start(start),
- m_length(length),
- m_empty(true)
+ m_length(length)
{
}
-void AUD_FaderReader::read(int & length, sample_t* & buffer)
+void AUD_FaderReader::read(int& length, bool& eos, sample_t* buffer)
{
int position = m_reader->getPosition();
AUD_Specs specs = m_reader->getSpecs();
int samplesize = AUD_SAMPLE_SIZE(specs);
- m_reader->read(length, buffer);
+ m_reader->read(length, eos, buffer);
if((position + length) / (float)specs.rate <= m_start)
{
if(m_type != AUD_FADE_OUT)
{
- if(m_buffer.getSize() < length * samplesize)
- {
- m_buffer.resize(length * samplesize);
- m_empty = false;
- }
-
- buffer = m_buffer.getBuffer();
-
- if(!m_empty)
- {
- memset(buffer, 0, length * samplesize);
- m_empty = true;
- }
+ memset(buffer, 0, length * samplesize);
}
}
else if(position / (float)specs.rate >= m_start+m_length)
{
if(m_type == AUD_FADE_OUT)
{
- if(m_buffer.getSize() < length * samplesize)
- {
- m_buffer.resize(length * samplesize);
- m_empty = false;
- }
-
- buffer = m_buffer.getBuffer();
-
- if(!m_empty)
- {
- memset(buffer, 0, length * samplesize);
- m_empty = true;
- }
+ memset(buffer, 0, length * samplesize);
}
}
else
{
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
-
- sample_t* buf = m_buffer.getBuffer();
float volume = 1.0f;
for(int i = 0; i < length * specs.channels; i++)
@@ -111,10 +82,7 @@ void AUD_FaderReader::read(int & length, sample_t* & buffer)
volume = 1.0f - volume;
}
- buf[i] = buffer[i] * volume;
+ buffer[i] = buffer[i] * volume;
}
-
- buffer = buf;
- m_empty = false;
}
}
diff --git a/intern/audaspace/FX/AUD_FaderReader.h b/intern/audaspace/FX/AUD_FaderReader.h
index fb927192b45..e702ac0ec19 100644
--- a/intern/audaspace/FX/AUD_FaderReader.h
+++ b/intern/audaspace/FX/AUD_FaderReader.h
@@ -58,16 +58,6 @@ private:
*/
const float m_length;
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
- * Whether the buffer is empty.
- */
- bool m_empty;
-
// hide copy constructor and operator=
AUD_FaderReader(const AUD_FaderReader&);
AUD_FaderReader& operator=(const AUD_FaderReader&);
@@ -79,10 +69,10 @@ public:
* \param start The time where fading should start in seconds.
* \param length How long fading should last in seconds.
*/
- AUD_FaderReader(AUD_IReader* reader, AUD_FadeType type,
+ AUD_FaderReader(AUD_Reference<AUD_IReader> reader, AUD_FadeType type,
float start,float length);
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_FADERREADER
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.cpp b/intern/audaspace/FX/AUD_HighpassFactory.cpp
index 61008eea44e..399ec5ca406 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_HighpassFactory.cpp
@@ -38,30 +38,26 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_HighpassFactory::AUD_HighpassFactory(AUD_IFactory* factory, float frequency,
+AUD_HighpassFactory::AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
float Q) :
- AUD_EffectFactory(factory),
+ AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency),
m_Q(Q)
{
}
-AUD_IReader* AUD_HighpassFactory::createReader() const
+void AUD_HighpassFactory::recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float> &b,
+ std::vector<float> &a)
{
- AUD_IReader* reader = getReader();
-
- // calculate coefficients
- float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+ float w0 = 2 * M_PI * m_frequency / rate;
float alpha = sin(w0) / (2 * m_Q);
float norm = 1 + alpha;
float c = cos(w0);
- std::vector<float> a, b;
a.push_back(1);
a.push_back(-2 * c / norm);
a.push_back((1 - alpha) / norm);
b.push_back((1 + c) / (2 * norm));
b.push_back((-1 - c) / norm);
b.push_back(b[0]);
-
- return new AUD_IIRFilterReader(reader, b, a);
}
diff --git a/intern/audaspace/FX/AUD_HighpassFactory.h b/intern/audaspace/FX/AUD_HighpassFactory.h
index 48f4c1baefc..51d5f55cb36 100644
--- a/intern/audaspace/FX/AUD_HighpassFactory.h
+++ b/intern/audaspace/FX/AUD_HighpassFactory.h
@@ -32,12 +32,12 @@
#ifndef AUD_HIGHPASSFACTORY
#define AUD_HIGHPASSFACTORY
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
/**
* This factory creates a highpass filter reader.
*/
-class AUD_HighpassFactory : public AUD_EffectFactory
+class AUD_HighpassFactory : public AUD_DynamicIIRFilterFactory
{
private:
/**
@@ -61,9 +61,9 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_HighpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+ AUD_HighpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
- virtual AUD_IReader* createReader() const;
+ virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
#endif //AUD_HIGHPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
index ff90ce62739..f6ccda6f67e 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.cpp
@@ -32,14 +32,14 @@
#include "AUD_IIRFilterFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_IFactory* factory,
+AUD_IIRFilterFactory::AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory,
std::vector<float> b,
std::vector<float> a) :
AUD_EffectFactory(factory), m_a(a), m_b(b)
{
}
-AUD_IReader* AUD_IIRFilterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_IIRFilterFactory::createReader()
{
return new AUD_IIRFilterReader(getReader(), m_b, m_a);
}
diff --git a/intern/audaspace/FX/AUD_IIRFilterFactory.h b/intern/audaspace/FX/AUD_IIRFilterFactory.h
index d48ad453ee4..0e92ab1a568 100644
--- a/intern/audaspace/FX/AUD_IIRFilterFactory.h
+++ b/intern/audaspace/FX/AUD_IIRFilterFactory.h
@@ -63,10 +63,10 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterFactory(AUD_IFactory* factory, std::vector<float> b,
+ AUD_IIRFilterFactory(AUD_Reference<AUD_IFactory> factory, std::vector<float> b,
std::vector<float> a);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_IIRFILTERFACTORY
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.cpp b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
index 0d55421d2b4..1bfb9b97b62 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.cpp
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.cpp
@@ -31,9 +31,9 @@
#include "AUD_IIRFilterReader.h"
-AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_IReader* reader,
- std::vector<float> b,
- std::vector<float> a) :
+AUD_IIRFilterReader::AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader,
+ const std::vector<float>& b,
+ const std::vector<float>& a) :
AUD_BaseIIRFilterReader(reader, b.size(), a.size()), m_a(a), m_b(b)
{
for(int i = 1; i < m_a.size(); i++)
@@ -54,3 +54,11 @@ sample_t AUD_IIRFilterReader::filter()
return out;
}
+
+void AUD_IIRFilterReader::setCoefficients(const std::vector<float>& b,
+ const std::vector<float>& a)
+{
+ setLengths(m_b.size(), m_a.size());
+ m_a = a;
+ m_b = b;
+}
diff --git a/intern/audaspace/FX/AUD_IIRFilterReader.h b/intern/audaspace/FX/AUD_IIRFilterReader.h
index af50b6f1cdc..41de67d4d27 100644
--- a/intern/audaspace/FX/AUD_IIRFilterReader.h
+++ b/intern/audaspace/FX/AUD_IIRFilterReader.h
@@ -63,10 +63,13 @@ public:
* \param b The input filter coefficients.
* \param a The output filter coefficients.
*/
- AUD_IIRFilterReader(AUD_IReader* reader, std::vector<float> b,
- std::vector<float> a);
+ AUD_IIRFilterReader(AUD_Reference<AUD_IReader> reader, const std::vector<float>& b,
+ const std::vector<float>& a);
virtual sample_t filter();
+
+ void setCoefficients(const std::vector<float>& b,
+ const std::vector<float>& a);
};
#endif //AUD_IIRFILTERREADER
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.cpp b/intern/audaspace/FX/AUD_LimiterFactory.cpp
index 62ea01bb761..8d1dd14f3ae 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.cpp
+++ b/intern/audaspace/FX/AUD_LimiterFactory.cpp
@@ -33,7 +33,7 @@
#include "AUD_LimiterReader.h"
#include "AUD_Space.h"
-AUD_LimiterFactory::AUD_LimiterFactory(AUD_IFactory* factory,
+AUD_LimiterFactory::AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
float start, float end) :
AUD_EffectFactory(factory),
m_start(start),
@@ -51,7 +51,7 @@ float AUD_LimiterFactory::getEnd() const
return m_end;
}
-AUD_IReader* AUD_LimiterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LimiterFactory::createReader()
{
return new AUD_LimiterReader(getReader(), m_start, m_end);
}
diff --git a/intern/audaspace/FX/AUD_LimiterFactory.h b/intern/audaspace/FX/AUD_LimiterFactory.h
index f93f4b3276c..c04bfe861b2 100644
--- a/intern/audaspace/FX/AUD_LimiterFactory.h
+++ b/intern/audaspace/FX/AUD_LimiterFactory.h
@@ -62,7 +62,7 @@ public:
* \param end The desired end time, a negative value signals that it should
* play to the end.
*/
- AUD_LimiterFactory(AUD_IFactory* factory,
+ AUD_LimiterFactory(AUD_Reference<AUD_IFactory> factory,
float start = 0, float end = -1);
/**
@@ -75,7 +75,7 @@ public:
*/
float getEnd() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_LIMITERFACTORY
diff --git a/intern/audaspace/FX/AUD_LimiterReader.cpp b/intern/audaspace/FX/AUD_LimiterReader.cpp
index d67fbb4d0e5..dc31477d2eb 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.cpp
+++ b/intern/audaspace/FX/AUD_LimiterReader.cpp
@@ -32,30 +32,46 @@
#include "AUD_LimiterReader.h"
#include "AUD_Buffer.h"
-#include <iostream>
-
-AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
+AUD_LimiterReader::AUD_LimiterReader(AUD_Reference<AUD_IReader> reader,
float start, float end) :
AUD_EffectReader(reader),
- m_start(int(start * reader->getSpecs().rate)),
- m_end(int(end * reader->getSpecs().rate))
+ m_start(start),
+ m_end(end)
{
if(m_start > 0)
{
+ AUD_Specs specs = m_reader->getSpecs();
+ AUD_Specs specs2;
+
if(m_reader->isSeekable())
- m_reader->seek(m_start);
+ m_reader->seek(m_start * specs.rate);
else
{
// skip first m_start samples by reading them
int length = AUD_DEFAULT_BUFFER_SIZE;
- sample_t* buffer;
- for(int len = m_start;
- length == AUD_DEFAULT_BUFFER_SIZE;
- len -= AUD_DEFAULT_BUFFER_SIZE)
+ AUD_Buffer buffer(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+ bool eos = false;
+ for(int len = m_start * specs.rate;
+ length > 0 && !eos;
+ len -= length)
{
if(len < AUD_DEFAULT_BUFFER_SIZE)
length = len;
- m_reader->read(length, buffer);
+
+ m_reader->read(length, eos, buffer.getBuffer());
+
+ specs2 = m_reader->getSpecs();
+ if(specs2.rate != specs.rate)
+ {
+ len = len * specs2.rate / specs.rate;
+ specs.rate = specs2.rate;
+ }
+
+ if(specs2.channels != specs.channels)
+ {
+ specs = specs2;
+ buffer.assureSize(AUD_DEFAULT_BUFFER_SIZE * AUD_SAMPLE_SIZE(specs));
+ }
}
}
}
@@ -63,35 +79,71 @@ AUD_LimiterReader::AUD_LimiterReader(AUD_IReader* reader,
void AUD_LimiterReader::seek(int position)
{
- m_reader->seek(position + m_start);
+ m_reader->seek(position + m_start * m_reader->getSpecs().rate);
}
int AUD_LimiterReader::getLength() const
{
int len = m_reader->getLength();
- if(len < 0 || (len > m_end && m_end >= 0))
- len = m_end;
- return len - m_start;
+ AUD_SampleRate rate = m_reader->getSpecs().rate;
+ if(len < 0 || (len > m_end * rate && m_end >= 0))
+ len = m_end * rate;
+ return len - m_start * rate;
}
int AUD_LimiterReader::getPosition() const
{
int pos = m_reader->getPosition();
- return AUD_MIN(pos, m_end) - m_start;
+ AUD_SampleRate rate = m_reader->getSpecs().rate;
+ return AUD_MIN(pos, m_end * rate) - m_start * rate;
}
-void AUD_LimiterReader::read(int & length, sample_t* & buffer)
+void AUD_LimiterReader::read(int& length, bool& eos, sample_t* buffer)
{
+ eos = false;
if(m_end >= 0)
{
int position = m_reader->getPosition();
- if(position + length > m_end)
- length = m_end - position;
+ AUD_SampleRate rate = m_reader->getSpecs().rate;
+
+ if(position + length > m_end * rate)
+ {
+ length = m_end * rate - position;
+ eos = true;
+ }
+
+ if(position < m_start * rate)
+ {
+ int len2 = length;
+ for(int len = m_start * rate - position;
+ len2 == length && !eos;
+ len -= length)
+ {
+ if(len < length)
+ len2 = len;
+
+ m_reader->read(len2, eos, buffer);
+ position += len2;
+ }
+
+ if(position < m_start * rate)
+ {
+ length = 0;
+ return;
+ }
+ }
+
if(length < 0)
{
length = 0;
return;
}
}
- m_reader->read(length, buffer);
+ if(eos)
+ {
+ m_reader->read(length, eos, buffer);
+ eos = true;
+ }
+ else
+ m_reader->read(length, eos, buffer);
}
diff --git a/intern/audaspace/FX/AUD_LimiterReader.h b/intern/audaspace/FX/AUD_LimiterReader.h
index 4375ed9e10d..d9bee6f6463 100644
--- a/intern/audaspace/FX/AUD_LimiterReader.h
+++ b/intern/audaspace/FX/AUD_LimiterReader.h
@@ -43,12 +43,12 @@ private:
/**
* The start sample: inclusive.
*/
- const int m_start;
+ const float m_start;
/**
* The end sample: exlusive.
*/
- const int m_end;
+ const float m_end;
// hide copy constructor and operator=
AUD_LimiterReader(const AUD_LimiterReader&);
@@ -62,12 +62,12 @@ public:
* \param end The desired end sample (exklusive), a negative value signals
* that it should play to the end.
*/
- AUD_LimiterReader(AUD_IReader* reader, float start = 0, float end = -1);
+ AUD_LimiterReader(AUD_Reference<AUD_IReader> reader, float start = 0, float end = -1);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_LIMITERREADER
diff --git a/intern/audaspace/FX/AUD_LoopFactory.cpp b/intern/audaspace/FX/AUD_LoopFactory.cpp
index 49d3481757f..fd39ac901c1 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.cpp
+++ b/intern/audaspace/FX/AUD_LoopFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_LoopFactory.h"
#include "AUD_LoopReader.h"
-AUD_LoopFactory::AUD_LoopFactory(AUD_IFactory* factory, int loop) :
+AUD_LoopFactory::AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop) :
AUD_EffectFactory(factory),
m_loop(loop)
{
@@ -43,7 +43,7 @@ int AUD_LoopFactory::getLoop() const
return m_loop;
}
-AUD_IReader* AUD_LoopFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LoopFactory::createReader()
{
return new AUD_LoopReader(getReader(), m_loop);
}
diff --git a/intern/audaspace/FX/AUD_LoopFactory.h b/intern/audaspace/FX/AUD_LoopFactory.h
index dfbbbe4fd20..03c00dc40ce 100644
--- a/intern/audaspace/FX/AUD_LoopFactory.h
+++ b/intern/audaspace/FX/AUD_LoopFactory.h
@@ -57,14 +57,14 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopFactory(AUD_IFactory* factory, int loop = -1);
+ AUD_LoopFactory(AUD_Reference<AUD_IFactory> factory, int loop = -1);
/**
* Returns the loop count.
*/
int getLoop() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_LOOPFACTORY
diff --git a/intern/audaspace/FX/AUD_LoopReader.cpp b/intern/audaspace/FX/AUD_LoopReader.cpp
index b2e8e97a602..de67a445ab2 100644
--- a/intern/audaspace/FX/AUD_LoopReader.cpp
+++ b/intern/audaspace/FX/AUD_LoopReader.cpp
@@ -34,7 +34,7 @@
#include <cstring>
-AUD_LoopReader::AUD_LoopReader(AUD_IReader* reader, int loop) :
+AUD_LoopReader::AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop) :
AUD_EffectReader(reader), m_count(loop), m_left(loop)
{
}
@@ -68,29 +68,20 @@ int AUD_LoopReader::getPosition() const
return m_reader->getPosition() * (m_count < 0 ? 1 : m_count);
}
-void AUD_LoopReader::read(int & length, sample_t* & buffer)
+void AUD_LoopReader::read(int& length, bool& eos, sample_t* buffer)
{
- AUD_Specs specs = m_reader->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
+ const AUD_Specs specs = m_reader->getSpecs();
int len = length;
- m_reader->read(len, buffer);
+ m_reader->read(length, eos, buffer);
- if(len < length && m_left)
+ if(length < len && eos && m_left)
{
- int pos = 0;
-
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
-
- sample_t* buf = m_buffer.getBuffer();
-
- memcpy(buf + pos * specs.channels, buffer, len * samplesize);
-
- pos += len;
+ int pos = length;
+ length = len;
- while(pos < length && m_left)
+ while(pos < length && eos && m_left)
{
if(m_left > 0)
m_left--;
@@ -98,20 +89,15 @@ void AUD_LoopReader::read(int & length, sample_t* & buffer)
m_reader->seek(0);
len = length - pos;
- m_reader->read(len, buffer);
+ m_reader->read(len, eos, buffer + pos * specs.channels);
// prevent endless loop
if(!len)
break;
- memcpy(buf + pos * specs.channels, buffer, len * samplesize);
-
pos += len;
}
length = pos;
- buffer = buf;
}
- else
- length = len;
}
diff --git a/intern/audaspace/FX/AUD_LoopReader.h b/intern/audaspace/FX/AUD_LoopReader.h
index 45017901c56..5ccf7e543a0 100644
--- a/intern/audaspace/FX/AUD_LoopReader.h
+++ b/intern/audaspace/FX/AUD_LoopReader.h
@@ -43,11 +43,6 @@ class AUD_LoopReader : public AUD_EffectReader
{
private:
/**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
* The loop count.
*/
const int m_count;
@@ -68,12 +63,12 @@ public:
* \param loop The desired loop count, negative values result in endless
* looping.
*/
- AUD_LoopReader(AUD_IReader* reader, int loop);
+ AUD_LoopReader(AUD_Reference<AUD_IReader> reader, int loop);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_LOOPREADER
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.cpp b/intern/audaspace/FX/AUD_LowpassFactory.cpp
index d24a04b5a94..3ef25c3c16e 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.cpp
+++ b/intern/audaspace/FX/AUD_LowpassFactory.cpp
@@ -38,30 +38,26 @@
#define M_PI 3.14159265358979323846
#endif
-AUD_LowpassFactory::AUD_LowpassFactory(AUD_IFactory* factory, float frequency,
+AUD_LowpassFactory::AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency,
float Q) :
- AUD_EffectFactory(factory),
+ AUD_DynamicIIRFilterFactory(factory),
m_frequency(frequency),
m_Q(Q)
{
}
-AUD_IReader* AUD_LowpassFactory::createReader() const
+void AUD_LowpassFactory::recalculateCoefficients(AUD_SampleRate rate,
+ std::vector<float> &b,
+ std::vector<float> &a)
{
- AUD_IReader* reader = getReader();
-
- // calculate coefficients
- float w0 = 2 * M_PI * m_frequency / reader->getSpecs().rate;
+ float w0 = 2 * M_PI * m_frequency / rate;
float alpha = sin(w0) / (2 * m_Q);
float norm = 1 + alpha;
float c = cos(w0);
- std::vector<float> a, b;
a.push_back(1);
a.push_back(-2 * c / norm);
a.push_back((1 - alpha) / norm);
b.push_back((1 - c) / (2 * norm));
b.push_back((1 - c) / norm);
b.push_back(b[0]);
-
- return new AUD_IIRFilterReader(reader, b, a);
}
diff --git a/intern/audaspace/FX/AUD_LowpassFactory.h b/intern/audaspace/FX/AUD_LowpassFactory.h
index d60c0bd22d1..6558663df4e 100644
--- a/intern/audaspace/FX/AUD_LowpassFactory.h
+++ b/intern/audaspace/FX/AUD_LowpassFactory.h
@@ -32,12 +32,12 @@
#ifndef AUD_LOWPASSFACTORY
#define AUD_LOWPASSFACTORY
-#include "AUD_EffectFactory.h"
+#include "AUD_DynamicIIRFilterFactory.h"
/**
* This factory creates a lowpass filter reader.
*/
-class AUD_LowpassFactory : public AUD_EffectFactory
+class AUD_LowpassFactory : public AUD_DynamicIIRFilterFactory
{
private:
/**
@@ -61,9 +61,9 @@ public:
* \param frequency The cutoff frequency.
* \param Q The Q factor.
*/
- AUD_LowpassFactory(AUD_IFactory* factory, float frequency, float Q = 1.0f);
+ AUD_LowpassFactory(AUD_Reference<AUD_IFactory> factory, float frequency, float Q = 1.0f);
- virtual AUD_IReader* createReader() const;
+ virtual void recalculateCoefficients(AUD_SampleRate rate, std::vector<float> &b, std::vector<float> &a);
};
#endif //AUD_LOWPASSFACTORY
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.cpp b/intern/audaspace/FX/AUD_PingPongFactory.cpp
index fa140555943..e5f2193ea56 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.cpp
+++ b/intern/audaspace/FX/AUD_PingPongFactory.cpp
@@ -33,26 +33,16 @@
#include "AUD_DoubleReader.h"
#include "AUD_ReverseFactory.h"
-AUD_PingPongFactory::AUD_PingPongFactory(AUD_IFactory* factory) :
+AUD_PingPongFactory::AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_PingPongFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PingPongFactory::createReader()
{
- AUD_IReader* reader = getReader();
- AUD_IReader* reader2;
+ AUD_Reference<AUD_IReader> reader = getReader();
AUD_ReverseFactory factory(m_factory);
-
- try
- {
- reader2 = factory.createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader2 = factory.createReader();
return new AUD_DoubleReader(reader, reader2);
}
diff --git a/intern/audaspace/FX/AUD_PingPongFactory.h b/intern/audaspace/FX/AUD_PingPongFactory.h
index 4ae0c494eb7..908591a6ebe 100644
--- a/intern/audaspace/FX/AUD_PingPongFactory.h
+++ b/intern/audaspace/FX/AUD_PingPongFactory.h
@@ -50,9 +50,9 @@ public:
* Creates a new ping pong factory.
* \param factory The input factory.
*/
- AUD_PingPongFactory(AUD_IFactory* factory);
+ AUD_PingPongFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_PINGPONGFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchFactory.cpp b/intern/audaspace/FX/AUD_PitchFactory.cpp
index b4ae8582caf..e52028754e9 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.cpp
+++ b/intern/audaspace/FX/AUD_PitchFactory.cpp
@@ -33,13 +33,13 @@
#include "AUD_PitchReader.h"
#include "AUD_Space.h"
-AUD_PitchFactory::AUD_PitchFactory(AUD_IFactory* factory, float pitch) :
+AUD_PitchFactory::AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch) :
AUD_EffectFactory(factory),
m_pitch(pitch)
{
}
-AUD_IReader* AUD_PitchFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_PitchFactory::createReader()
{
return new AUD_PitchReader(getReader(), m_pitch);
}
diff --git a/intern/audaspace/FX/AUD_PitchFactory.h b/intern/audaspace/FX/AUD_PitchFactory.h
index 8fa5be9293f..2642d41af89 100644
--- a/intern/audaspace/FX/AUD_PitchFactory.h
+++ b/intern/audaspace/FX/AUD_PitchFactory.h
@@ -55,9 +55,9 @@ public:
* \param factory The input factory.
* \param pitch The desired pitch.
*/
- AUD_PitchFactory(AUD_IFactory* factory, float pitch);
+ AUD_PitchFactory(AUD_Reference<AUD_IFactory> factory, float pitch);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_PITCHFACTORY
diff --git a/intern/audaspace/FX/AUD_PitchReader.cpp b/intern/audaspace/FX/AUD_PitchReader.cpp
index e2e89e2c457..81dd6e4355c 100644
--- a/intern/audaspace/FX/AUD_PitchReader.cpp
+++ b/intern/audaspace/FX/AUD_PitchReader.cpp
@@ -31,7 +31,7 @@
#include "AUD_PitchReader.h"
-AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
+AUD_PitchReader::AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch) :
AUD_EffectReader(reader), m_pitch(pitch)
{
}
@@ -39,6 +39,16 @@ AUD_PitchReader::AUD_PitchReader(AUD_IReader* reader, float pitch) :
AUD_Specs AUD_PitchReader::getSpecs() const
{
AUD_Specs specs = m_reader->getSpecs();
- specs.rate = (AUD_SampleRate)((int)(specs.rate * m_pitch));
+ specs.rate *= m_pitch;
return specs;
}
+
+float AUD_PitchReader::getPitch() const
+{
+ return m_pitch;
+}
+
+void AUD_PitchReader::setPitch(float pitch)
+{
+ m_pitch = pitch;
+}
diff --git a/intern/audaspace/FX/AUD_PitchReader.h b/intern/audaspace/FX/AUD_PitchReader.h
index 120cebc58be..7418531ca55 100644
--- a/intern/audaspace/FX/AUD_PitchReader.h
+++ b/intern/audaspace/FX/AUD_PitchReader.h
@@ -43,7 +43,7 @@ private:
/**
* The pitch level.
*/
- const float m_pitch;
+ float m_pitch;
// hide copy constructor and operator=
AUD_PitchReader(const AUD_PitchReader&);
@@ -55,9 +55,12 @@ public:
* \param reader The reader to read from.
* \param pitch The size of the buffer.
*/
- AUD_PitchReader(AUD_IReader* reader, float pitch);
+ AUD_PitchReader(AUD_Reference<AUD_IReader> reader, float pitch);
virtual AUD_Specs getSpecs() const;
+
+ float getPitch() const;
+ void setPitch(float pitch);
};
#endif //AUD_PITCHREADER
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.cpp b/intern/audaspace/FX/AUD_RectifyFactory.cpp
index 609d827cce4..cbb676a9a32 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.cpp
+++ b/intern/audaspace/FX/AUD_RectifyFactory.cpp
@@ -34,17 +34,17 @@
#include <cmath>
-sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
+sample_t AUD_RectifyFactory::rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless)
{
return fabs(reader->x(0));
}
-AUD_RectifyFactory::AUD_RectifyFactory(AUD_IFactory* factory) :
+AUD_RectifyFactory::AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_RectifyFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_RectifyFactory::createReader()
{
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1, rectifyFilter);
}
diff --git a/intern/audaspace/FX/AUD_RectifyFactory.h b/intern/audaspace/FX/AUD_RectifyFactory.h
index c3529c7beef..16b44469c05 100644
--- a/intern/audaspace/FX/AUD_RectifyFactory.h
+++ b/intern/audaspace/FX/AUD_RectifyFactory.h
@@ -33,6 +33,7 @@
#define AUD_RECTIFYFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory rectifies another factory.
@@ -49,9 +50,11 @@ public:
* Creates a new rectify factory.
* \param factory The input factory.
*/
- AUD_RectifyFactory(AUD_IFactory* factory);
+ AUD_RectifyFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
+
+ static sample_t rectifyFilter(AUD_CallbackIIRFilterReader* reader, void* useless);
};
#endif //AUD_RECTIFYFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.cpp b/intern/audaspace/FX/AUD_ReverseFactory.cpp
index 22b12e31420..060a618dd68 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.cpp
+++ b/intern/audaspace/FX/AUD_ReverseFactory.cpp
@@ -33,12 +33,12 @@
#include "AUD_ReverseReader.h"
#include "AUD_Space.h"
-AUD_ReverseFactory::AUD_ReverseFactory(AUD_IFactory* factory) :
+AUD_ReverseFactory::AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_ReverseFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ReverseFactory::createReader()
{
return new AUD_ReverseReader(getReader());
}
diff --git a/intern/audaspace/FX/AUD_ReverseFactory.h b/intern/audaspace/FX/AUD_ReverseFactory.h
index 7b20546302e..b501b4e76c8 100644
--- a/intern/audaspace/FX/AUD_ReverseFactory.h
+++ b/intern/audaspace/FX/AUD_ReverseFactory.h
@@ -50,9 +50,9 @@ public:
* Creates a new reverse factory.
* \param factory The input factory.
*/
- AUD_ReverseFactory(AUD_IFactory* factory);
+ AUD_ReverseFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_REVERSEFACTORY
diff --git a/intern/audaspace/FX/AUD_ReverseReader.cpp b/intern/audaspace/FX/AUD_ReverseReader.cpp
index a4a03936c76..73f6830f3fa 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.cpp
+++ b/intern/audaspace/FX/AUD_ReverseReader.cpp
@@ -36,7 +36,7 @@
static const char* props_error = "AUD_ReverseReader: The reader has to be "
"seekable and a finite length.";
-AUD_ReverseReader::AUD_ReverseReader(AUD_IReader* reader) :
+AUD_ReverseReader::AUD_ReverseReader(AUD_Reference<AUD_IReader> reader) :
AUD_EffectReader(reader),
m_length(reader->getLength()),
m_position(0)
@@ -60,7 +60,7 @@ int AUD_ReverseReader::getPosition() const
return m_position;
}
-void AUD_ReverseReader::read(int & length, sample_t* & buffer)
+void AUD_ReverseReader::read(int& length, bool& eos, sample_t* buffer)
{
// first correct the length
if(m_position + length > m_length)
@@ -69,39 +69,39 @@ void AUD_ReverseReader::read(int & length, sample_t* & buffer)
if(length <= 0)
{
length = 0;
+ eos = true;
return;
}
- AUD_Specs specs = getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
+ const AUD_Specs specs = getSpecs();
+ const int samplesize = AUD_SAMPLE_SIZE(specs);
- // resize buffer if needed
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
+ sample_t temp[AUD_CHANNEL_MAX];
- buffer = m_buffer.getBuffer();
-
- sample_t* buf;
int len = length;
// read from reader
m_reader->seek(m_length - m_position - len);
- m_reader->read(len, buf);
+ m_reader->read(len, eos, buffer);
// set null if reader didn't give enough data
if(len < length)
- {
memset(buffer, 0, (length - len) * samplesize);
- buffer += (length - len) * specs.channels;
- }
// copy the samples reverted
- for(int i = 0; i < len; i++)
+ for(int i = 0; i < length / 2; i++)
+ {
+ memcpy(temp,
+ buffer + (len - 1 - i) * specs.channels,
+ samplesize);
+ memcpy(buffer + (len - 1 - i) * specs.channels,
+ buffer + i * specs.channels,
+ samplesize);
memcpy(buffer + i * specs.channels,
- buf + (len - 1 - i) * specs.channels,
+ temp,
samplesize);
+ }
m_position += length;
-
- buffer = m_buffer.getBuffer();
+ eos = false;
}
diff --git a/intern/audaspace/FX/AUD_ReverseReader.h b/intern/audaspace/FX/AUD_ReverseReader.h
index e12f2b21191..da0add9464e 100644
--- a/intern/audaspace/FX/AUD_ReverseReader.h
+++ b/intern/audaspace/FX/AUD_ReverseReader.h
@@ -52,11 +52,6 @@ private:
*/
int m_position;
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
// hide copy constructor and operator=
AUD_ReverseReader(const AUD_ReverseReader&);
AUD_ReverseReader& operator=(const AUD_ReverseReader&);
@@ -68,12 +63,12 @@ public:
* \exception AUD_Exception Thrown if the reader specified has an
* undeterminable/infinite length or is not seekable.
*/
- AUD_ReverseReader(AUD_IReader* reader);
+ AUD_ReverseReader(AUD_Reference<AUD_IReader> reader);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_REVERSEREADER
diff --git a/intern/audaspace/FX/AUD_SquareFactory.cpp b/intern/audaspace/FX/AUD_SquareFactory.cpp
index a075773d2cb..226085a1814 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.cpp
+++ b/intern/audaspace/FX/AUD_SquareFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_SquareFactory.h"
#include "AUD_CallbackIIRFilterReader.h"
-sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
+sample_t AUD_SquareFactory::squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
{
float in = reader->x(0);
if(in >= *threshold)
@@ -43,12 +43,12 @@ sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold)
return 0;
}
-void endSquareFilter(float* threshold)
+void AUD_SquareFactory::endSquareFilter(float* threshold)
{
delete threshold;
}
-AUD_SquareFactory::AUD_SquareFactory(AUD_IFactory* factory, float threshold) :
+AUD_SquareFactory::AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold) :
AUD_EffectFactory(factory),
m_threshold(threshold)
{
@@ -59,7 +59,7 @@ float AUD_SquareFactory::getThreshold() const
return m_threshold;
}
-AUD_IReader* AUD_SquareFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SquareFactory::createReader()
{
return new AUD_CallbackIIRFilterReader(getReader(), 1, 1,
(doFilterIIR) squareFilter,
diff --git a/intern/audaspace/FX/AUD_SquareFactory.h b/intern/audaspace/FX/AUD_SquareFactory.h
index 8060e98e281..21284361cca 100644
--- a/intern/audaspace/FX/AUD_SquareFactory.h
+++ b/intern/audaspace/FX/AUD_SquareFactory.h
@@ -33,6 +33,7 @@
#define AUD_SQUAREFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory Transforms any signal to a square signal.
@@ -55,14 +56,17 @@ public:
* \param factory The input factory.
* \param threshold The threshold.
*/
- AUD_SquareFactory(AUD_IFactory* factory, float threshold = 0.0f);
+ AUD_SquareFactory(AUD_Reference<AUD_IFactory> factory, float threshold = 0.0f);
/**
* Returns the threshold.
*/
float getThreshold() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
+
+ static sample_t squareFilter(AUD_CallbackIIRFilterReader* reader, float* threshold);
+ static void endSquareFilter(float* threshold);
};
#endif //AUD_SQUAREFACTORY
diff --git a/intern/audaspace/FX/AUD_SumFactory.cpp b/intern/audaspace/FX/AUD_SumFactory.cpp
index 6d8368d6e35..befcc30360f 100644
--- a/intern/audaspace/FX/AUD_SumFactory.cpp
+++ b/intern/audaspace/FX/AUD_SumFactory.cpp
@@ -32,12 +32,12 @@
#include "AUD_SumFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_SumFactory::AUD_SumFactory(AUD_IFactory* factory) :
+AUD_SumFactory::AUD_SumFactory(AUD_Reference<AUD_IFactory> factory) :
AUD_EffectFactory(factory)
{
}
-AUD_IReader* AUD_SumFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SumFactory::createReader()
{
std::vector<float> a, b;
a.push_back(1);
diff --git a/intern/audaspace/FX/AUD_SumFactory.h b/intern/audaspace/FX/AUD_SumFactory.h
index ed19a0f258a..cdb4caf6e49 100644
--- a/intern/audaspace/FX/AUD_SumFactory.h
+++ b/intern/audaspace/FX/AUD_SumFactory.h
@@ -49,9 +49,9 @@ public:
* Creates a new sum factory.
* \param factory The input factory.
*/
- AUD_SumFactory(AUD_IFactory* factory);
+ AUD_SumFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SUMFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.cpp b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
index c13a0d0dd95..d514bfd8fca 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.cpp
@@ -32,24 +32,15 @@
#include "AUD_SuperposeFactory.h"
#include "AUD_SuperposeReader.h"
-AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2) :
+AUD_SuperposeFactory::AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2) :
m_factory1(factory1), m_factory2(factory2)
{
}
-AUD_IReader* AUD_SuperposeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SuperposeFactory::createReader()
{
- AUD_IReader* reader1 = m_factory1->createReader();
- AUD_IReader* reader2;
- try
- {
- reader2 = m_factory2->createReader();
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- throw;
- }
+ AUD_Reference<AUD_IReader> reader1 = m_factory1->createReader();
+ AUD_Reference<AUD_IReader> reader2 = m_factory2->createReader();
return new AUD_SuperposeReader(reader1, reader2);
}
diff --git a/intern/audaspace/FX/AUD_SuperposeFactory.h b/intern/audaspace/FX/AUD_SuperposeFactory.h
index 32232012e4e..ac7ec080134 100644
--- a/intern/audaspace/FX/AUD_SuperposeFactory.h
+++ b/intern/audaspace/FX/AUD_SuperposeFactory.h
@@ -44,12 +44,12 @@ private:
/**
* First played factory.
*/
- AUD_IFactory* m_factory1;
+ AUD_Reference<AUD_IFactory> m_factory1;
/**
* Second played factory.
*/
- AUD_IFactory* m_factory2;
+ AUD_Reference<AUD_IFactory> m_factory2;
// hide copy constructor and operator=
AUD_SuperposeFactory(const AUD_SuperposeFactory&);
@@ -61,9 +61,9 @@ public:
* \param factory1 The first input factory.
* \param factory2 The second input factory.
*/
- AUD_SuperposeFactory(AUD_IFactory* factory1, AUD_IFactory* factory2);
+ AUD_SuperposeFactory(AUD_Reference<AUD_IFactory> factory1, AUD_Reference<AUD_IFactory> factory2);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SUPERPOSEFACTORY
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.cpp b/intern/audaspace/FX/AUD_SuperposeReader.cpp
index e64cf79188e..a0dc12fea96 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.cpp
+++ b/intern/audaspace/FX/AUD_SuperposeReader.cpp
@@ -36,30 +36,13 @@
static const char* specs_error = "AUD_SuperposeReader: Both readers have to "
"have the same specs.";
-AUD_SuperposeReader::AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2) :
+AUD_SuperposeReader::AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2) :
m_reader1(reader1), m_reader2(reader2)
{
- try
- {
- AUD_Specs s1, s2;
- s1 = reader1->getSpecs();
- s2 = reader2->getSpecs();
- if(memcmp(&s1, &s2, sizeof(AUD_Specs)))
- AUD_THROW(AUD_ERROR_SPECS, specs_error);
- }
- catch(AUD_Exception&)
- {
- delete reader1;
- delete reader2;
-
- throw;
- }
}
AUD_SuperposeReader::~AUD_SuperposeReader()
{
- delete m_reader1;
- delete m_reader2;
}
bool AUD_SuperposeReader::isSeekable() const
@@ -94,28 +77,31 @@ AUD_Specs AUD_SuperposeReader::getSpecs() const
return m_reader1->getSpecs();
}
-void AUD_SuperposeReader::read(int & length, sample_t* & buffer)
+void AUD_SuperposeReader::read(int& length, bool& eos, sample_t* buffer)
{
AUD_Specs specs = m_reader1->getSpecs();
+ AUD_Specs s2 = m_reader2->getSpecs();
+ if(memcmp(&specs, &s2, sizeof(AUD_Specs)))
+ AUD_THROW(AUD_ERROR_SPECS, specs_error);
+
int samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
- buffer = m_buffer.getBuffer();
+ m_buffer.assureSize(length * samplesize);
int len1 = length;
- sample_t* buf;
- m_reader1->read(len1, buf);
- memcpy(buffer, buf, len1 * samplesize);
+ m_reader1->read(len1, eos, buffer);
if(len1 < length)
memset(buffer + len1 * specs.channels, 0, (length - len1) * samplesize);
int len2 = length;
- m_reader2->read(len2, buf);
+ bool eos2;
+ sample_t* buf = m_buffer.getBuffer();
+ m_reader2->read(len2, eos2, buf);
for(int i = 0; i < len2 * specs.channels; i++)
buffer[i] += buf[i];
length = AUD_MAX(len1, len2);
+ eos &= eos2;
}
diff --git a/intern/audaspace/FX/AUD_SuperposeReader.h b/intern/audaspace/FX/AUD_SuperposeReader.h
index b256aade7ba..a87f1fdb739 100644
--- a/intern/audaspace/FX/AUD_SuperposeReader.h
+++ b/intern/audaspace/FX/AUD_SuperposeReader.h
@@ -34,6 +34,7 @@
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
@@ -44,12 +45,12 @@ private:
/**
* The first reader.
*/
- AUD_IReader* m_reader1;
+ AUD_Reference<AUD_IReader> m_reader1;
/**
* The second reader.
*/
- AUD_IReader* m_reader2;
+ AUD_Reference<AUD_IReader> m_reader2;
/**
* The playback buffer for the intersecting part.
@@ -67,7 +68,7 @@ public:
* \param reader2 The second reader to read from.
* \exception AUD_Exception Thrown if the specs from the readers differ.
*/
- AUD_SuperposeReader(AUD_IReader* reader1, AUD_IReader* reader2);
+ AUD_SuperposeReader(AUD_Reference<AUD_IReader> reader1, AUD_Reference<AUD_IReader> reader2);
/**
* Destroys the reader.
@@ -79,7 +80,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SUPERPOSEREADER
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.cpp b/intern/audaspace/FX/AUD_VolumeFactory.cpp
index 166fbf61512..17cefd4f3c3 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.cpp
+++ b/intern/audaspace/FX/AUD_VolumeFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_VolumeFactory.h"
#include "AUD_IIRFilterReader.h"
-AUD_VolumeFactory::AUD_VolumeFactory(AUD_IFactory* factory, float volume) :
+AUD_VolumeFactory::AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume) :
AUD_EffectFactory(factory),
m_volume(volume)
{
@@ -43,7 +43,7 @@ float AUD_VolumeFactory::getVolume() const
return m_volume;
}
-AUD_IReader* AUD_VolumeFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_VolumeFactory::createReader()
{
std::vector<float> a, b;
a.push_back(1);
diff --git a/intern/audaspace/FX/AUD_VolumeFactory.h b/intern/audaspace/FX/AUD_VolumeFactory.h
index fa40ca11082..bcc08e7d04a 100644
--- a/intern/audaspace/FX/AUD_VolumeFactory.h
+++ b/intern/audaspace/FX/AUD_VolumeFactory.h
@@ -57,14 +57,14 @@ public:
* \param factory The input factory.
* \param volume The desired volume.
*/
- AUD_VolumeFactory(AUD_IFactory* factory, float volume);
+ AUD_VolumeFactory(AUD_Reference<AUD_IFactory> factory, float volume);
/**
* Returns the volume.
*/
float getVolume() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_VOLUMEFACTORY
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
index b9e30bbf62a..65b1d3f3b64 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.cpp
@@ -43,56 +43,726 @@
#include <unistd.h>
#endif
-#define AUD_OPENAL_CYCLE_BUFFERS 3
+/*struct AUD_OpenALBufferedFactory
+{
+ /// The factory.
+ AUD_IFactory* factory;
+
+ /// The OpenAL buffer.
+ ALuint buffer;
+};*/
+
+//typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+
+
+/******************************************************************************/
+/*********************** AUD_OpenALHandle Handle Code *************************/
+/******************************************************************************/
+
+static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "generated.";
+static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
+ "generated.";
+static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "queued to the source.";
+static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
+ "filled with data.";
-/// Saves the data for playback.
-struct AUD_OpenALHandle : AUD_Handle
+AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep) :
+ m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
+ m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
+ m_device(device)
{
- /// Whether it's a buffered or a streamed source.
- bool isBuffered;
+ AUD_DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
- /// The reader source.
- AUD_IReader* reader;
+ // OpenAL playback code
+ alGenBuffers(CYCLE_BUFFERS, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
- /// Whether to keep the source if end of it is reached.
- bool keep;
+ try
+ {
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+ int length;
+ bool eos;
- /// OpenAL sample format.
- ALenum format;
+ for(int i = 0; i < CYCLE_BUFFERS; i++)
+ {
+ length = m_device->m_buffersize;
+ reader->read(length, eos, m_device->m_buffer.getBuffer());
+ alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs),
+ specs.rate);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
+ }
- /// OpenAL source.
- ALuint source;
+ alGenSources(1, &m_source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
- /// OpenAL buffers.
- ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+ try
+ {
+ alSourceQueueBuffers(m_source, CYCLE_BUFFERS,
+ m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, queue_error);
+ }
+ catch(AUD_Exception&)
+ {
+ alDeleteSources(1, &m_source);
+ throw;
+ }
+ }
+ catch(AUD_Exception&)
+ {
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+ throw;
+ }
+ alSourcei(m_source, AL_SOURCE_RELATIVE, 1);
+}
- /// The first buffer to be read next.
- int current;
+bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
+{
+ if(m_status)
+ {
+ m_device->lock();
- /// Whether the stream doesn't return any more data.
- bool data_end;
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(this);
+ m_device->m_pausedSounds.push_back(this);
- /// The loop count of the source.
- int loopcount;
+ alSourcePause(m_source);
- /// The stop callback.
- stopCallback stop;
+ m_status = AUD_STATUS_PAUSED;
+ m_device->unlock();
- /// Stop callback data.
- void* stop_data;
-};
+ return true;
+ }
+
+ m_device->unlock();
+ }
-struct AUD_OpenALBufferedFactory
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
{
- /// The factory.
- AUD_IFactory* factory;
+ if(m_status)
+ {
+ m_device->lock();
- /// The OpenAL buffer.
- ALuint buffer;
-};
+ if(m_status == AUD_STATUS_PAUSED)
+ {
+ m_device->m_pausedSounds.remove(this);
+ m_device->m_playingSounds.push_back(this);
+
+ m_device->start();
+ m_status = AUD_STATUS_PLAYING;
+ m_device->unlock();
+ return true;
+ }
+
+ m_device->unlock();
+ }
+
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::stop()
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ // AUD_XXX Create a reference of our own object so that it doesn't get
+ // deleted before the end of this function
+ AUD_Reference<AUD_OpenALHandle> This = this;
+
+ if(m_status == AUD_STATUS_PLAYING)
+ m_device->m_playingSounds.remove(This);
+ else
+ m_device->m_pausedSounds.remove(This);
+
+ m_device->unlock();
+
+ alDeleteSources(1, &m_source);
+ if(!m_isBuffered)
+ alDeleteBuffers(CYCLE_BUFFERS, m_buffers);
+
+ m_status = AUD_STATUS_INVALID;
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::getKeep()
+{
+ if(m_status)
+ return m_keep;
+
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setKeep(bool keep)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_keep = keep;
+
+ m_device->unlock();
+
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ if(m_isBuffered)
+ alSourcef(m_source, AL_SEC_OFFSET, position);
+ else
+ {
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
+ m_eos = false;
+
+ ALint info;
+
+ alGetSourcei(m_source, AL_SOURCE_STATE, &info);
+
+ if(info != AL_PLAYING)
+ {
+ if(info == AL_PAUSED)
+ alSourceStop(m_source);
+
+ alSourcei(m_source, AL_BUFFER, 0);
+ m_current = 0;
+
+ ALenum err;
+ if((err = alGetError()) == AL_NO_ERROR)
+ {
+ int length;
+ AUD_DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+
+ for(int i = 0; i < CYCLE_BUFFERS; i++)
+ {
+ length = m_device->m_buffersize;
+ m_reader->read(length, m_eos, m_device->m_buffer.getBuffer());
+ alBufferData(m_buffers[i], m_format, m_device->m_buffer.getBuffer(),
+ length * AUD_DEVICE_SAMPLE_SIZE(specs), specs.rate);
+
+ if(alGetError() != AL_NO_ERROR)
+ break;
+ }
+
+ if(m_loopcount != 0)
+ m_eos = false;
+
+ alSourceQueueBuffers(m_source, CYCLE_BUFFERS, m_buffers);
+ }
+
+ alSourceRewind(m_source);
+ }
+ }
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPosition()
+{
+ if(!m_status)
+ return 0.0f;
+
+ m_device->lock();
+
+ float position = 0.0f;
+
+ alGetSourcef(m_source, AL_SEC_OFFSET, &position);
+
+ if(!m_isBuffered)
+ {
+ AUD_Specs specs = m_reader->getSpecs();
+ position += (m_reader->getPosition() - m_device->m_buffersize *
+ CYCLE_BUFFERS) / (float)specs.rate;
+ }
+
+ m_device->unlock();
+
+ return position;
+}
+
+AUD_Status AUD_OpenALDevice::AUD_OpenALHandle::getStatus()
+{
+ return m_status;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolume()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getPitch()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_PITCH, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setPitch(float pitch)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_PITCH, pitch);
+
+ m_device->unlock();
+
+ return true;
+}
+
+int AUD_OpenALDevice::AUD_OpenALHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+ m_loopcount = count;
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_stop = callback;
+ m_stop_data = data;
+
+ m_device->unlock();
+
+ return true;
+}
+
+/******************************************************************************/
+/********************* AUD_OpenALHandle 3DHandle Code *************************/
+/******************************************************************************/
+
+AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceLocation()
+{
+ AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ ALfloat p[3];
+ alGetSourcefv(m_source, AL_POSITION, p);
+
+ m_device->unlock();
+
+ result = AUD_Vector3(p[0], p[1], p[2]);
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceLocation(const AUD_Vector3& location)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcefv(m_source, AL_POSITION, (ALfloat*)location.get());
+
+ m_device->unlock();
+
+ return true;
+}
+
+AUD_Vector3 AUD_OpenALDevice::AUD_OpenALHandle::getSourceVelocity()
+{
+ AUD_Vector3 result = AUD_Vector3(0, 0, 0);
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ ALfloat v[3];
+ alGetSourcefv(m_source, AL_VELOCITY, v);
+
+ m_device->unlock();
+
+ result = AUD_Vector3(v[0], v[1], v[2]);
+
+ return result;
+}
-typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
-typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceVelocity(const AUD_Vector3& velocity)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcefv(m_source, AL_VELOCITY, (ALfloat*)velocity.get());
+
+ m_device->unlock();
+
+ return true;
+}
+
+AUD_Quaternion AUD_OpenALDevice::AUD_OpenALHandle::getSourceOrientation()
+{
+ // AUD_XXX not implemented yet
+ return AUD_Quaternion(0, 0, 0, 0);
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setSourceOrientation(const AUD_Quaternion& orientation)
+{
+ if(!m_status)
+ return false;
+
+ ALfloat direction[3];
+ direction[0] = -2 * (orientation.w() * orientation.y() +
+ orientation.x() * orientation.z());
+ direction[1] = 2 * (orientation.x() * orientation.w() -
+ orientation.z() * orientation.y());
+ direction[2] = 2 * (orientation.x() * orientation.x() +
+ orientation.y() * orientation.y()) - 1;
+ m_device->lock();
+
+ alSourcefv(m_source, AL_DIRECTION, direction);
+
+ m_device->unlock();
+
+ return true;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::isRelative()
+{
+ int result;
+
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alGetSourcei(m_source, AL_SOURCE_RELATIVE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcei(m_source, AL_SOURCE_RELATIVE, relative);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MAX_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MAX_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getVolumeMinimum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MIN_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MIN_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceMaximum()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_MAX_DISTANCE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_MAX_DISTANCE, distance);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getDistanceReference()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_REFERENCE_DISTANCE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_REFERENCE_DISTANCE, distance);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getAttenuation()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_ROLLOFF_FACTOR, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_ROLLOFF_FACTOR, factor);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_INNER_ANGLE, angle);
+
+ m_device->unlock();
+
+ return true;
+}
+
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeVolumeOuter()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ m_device->lock();
+
+ alGetSourcef(m_source, AL_CONE_OUTER_GAIN, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ alSourcef(m_source, AL_CONE_OUTER_GAIN, volume);
+
+ m_device->unlock();
+
+ return true;
+}
/******************************************************************************/
/**************************** Threading Code **********************************/
@@ -127,16 +797,15 @@ void AUD_OpenALDevice::start()
void AUD_OpenALDevice::updateStreams()
{
- AUD_OpenALHandle* sound;
+ AUD_Reference<AUD_OpenALHandle> sound;
int length;
- sample_t* buffer;
ALint info;
AUD_DeviceSpecs specs = m_specs;
ALCenum cerr;
- std::list<AUD_OpenALHandle*> stopSounds;
- std::list<AUD_OpenALHandle*> pauseSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > stopSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > pauseSounds;
AUD_HandleIterator it;
while(1)
@@ -148,83 +817,86 @@ void AUD_OpenALDevice::updateStreams()
if(cerr == ALC_NO_ERROR)
{
// for all sounds
- for(it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
+ for(it = m_playingSounds.begin(); it != m_playingSounds.end(); it++)
{
sound = *it;
// is it a streamed sound?
- if(!sound->isBuffered)
+ if(!sound->m_isBuffered)
{
// check for buffer refilling
- alGetSourcei(sound->source, AL_BUFFERS_PROCESSED, &info);
+ alGetSourcei(sound->m_source, AL_BUFFERS_PROCESSED, &info);
if(info)
{
- specs.specs = sound->reader->getSpecs();
+ specs.specs = sound->m_reader->getSpecs();
+ m_buffer.assureSize(m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
// for all empty buffers
while(info--)
{
// if there's still data to play back
- if(!sound->data_end)
+ if(!sound->m_eos)
{
// read data
length = m_buffersize;
- sound->reader->read(length, buffer);
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
// looping necessary?
- if(length == 0 && sound->loopcount)
+ if(length == 0 && sound->m_loopcount)
{
- if(sound->loopcount > 0)
- sound->loopcount--;
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
- sound->reader->seek(0);
+ sound->m_reader->seek(0);
length = m_buffersize;
- sound->reader->read(length, buffer);
+ sound->m_reader->read(length, sound->m_eos, m_buffer.getBuffer());
}
+ if(sound->m_loopcount != 0)
+ sound->m_eos = false;
+
// read nothing?
if(length == 0)
{
- sound->data_end = true;
break;
}
// unqueue buffer
- alSourceUnqueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
+ alSourceUnqueueBuffers(sound->m_source, 1,
+ &sound->m_buffers[sound->m_current]);
ALenum err;
if((err = alGetError()) != AL_NO_ERROR)
{
- sound->data_end = true;
+ sound->m_eos = true;
break;
}
// fill with new data
- alBufferData(sound->buffers[sound->current],
- sound->format,
- buffer, length *
+ alBufferData(sound->m_buffers[sound->m_current],
+ sound->m_format,
+ m_buffer.getBuffer(), length *
AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if((err = alGetError()) != AL_NO_ERROR)
{
- sound->data_end = true;
+ sound->m_eos = true;
break;
}
// and queue again
- alSourceQueueBuffers(sound->source, 1,
- &sound->buffers[sound->current]);
+ alSourceQueueBuffers(sound->m_source, 1,
+ &sound->m_buffers[sound->m_current]);
if(alGetError() != AL_NO_ERROR)
{
- sound->data_end = true;
+ sound->m_eos = true;
break;
}
- sound->current = (sound->current+1) %
- AUD_OPENAL_CYCLE_BUFFERS;
+ sound->m_current = (sound->m_current+1) %
+ AUD_OpenALHandle::CYCLE_BUFFERS;
}
else
break;
@@ -233,18 +905,18 @@ void AUD_OpenALDevice::updateStreams()
}
// check if the sound has been stopped
- alGetSourcei(sound->source, AL_SOURCE_STATE, &info);
+ alGetSourcei(sound->m_source, AL_SOURCE_STATE, &info);
if(info != AL_PLAYING)
{
// if it really stopped
- if(sound->data_end)
+ if(sound->m_eos)
{
- if(sound->stop)
- sound->stop(sound->stop_data);
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
// pause or
- if(sound->keep)
+ if(sound->m_keep)
pauseSounds.push_back(sound);
// stop
else
@@ -252,15 +924,15 @@ void AUD_OpenALDevice::updateStreams()
}
// continue playing
else
- alSourcePlay(sound->source);
+ alSourcePlay(sound->m_source);
}
}
for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
- pause(*it);
+ (*it)->pause();
for(it = stopSounds.begin(); it != stopSounds.end(); it++)
- stop(*it);
+ (*it)->stop();
pauseSounds.clear();
stopSounds.clear();
@@ -269,7 +941,7 @@ void AUD_OpenALDevice::updateStreams()
}
// stop thread
- if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR))
+ if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
{
unlock();
m_playing = false;
@@ -290,19 +962,6 @@ void AUD_OpenALDevice::updateStreams()
/**************************** IDevice Code ************************************/
/******************************************************************************/
-bool AUD_OpenALDevice::isValid(AUD_Handle* handle)
-{
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- if(*i == handle)
- return true;
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- if(*i == handle)
- return true;
- return false;
-}
-
static const char* open_error = "AUD_OpenALDevice: Device couldn't be opened.";
AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
@@ -355,9 +1014,7 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
m_buffersize = buffersize;
m_playing = false;
- m_playingSounds = new std::list<AUD_OpenALHandle*>();
- m_pausedSounds = new std::list<AUD_OpenALHandle*>();
- m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
+// m_bufferedFactories = new std::list<AUD_OpenALBufferedFactory*>();
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
@@ -370,46 +1027,23 @@ AUD_OpenALDevice::AUD_OpenALDevice(AUD_DeviceSpecs specs, int buffersize)
AUD_OpenALDevice::~AUD_OpenALDevice()
{
- AUD_OpenALHandle* sound;
-
lock();
alcSuspendContext(m_context);
- // delete all playing sounds
- while(!m_playingSounds->empty())
- {
- sound = *(m_playingSounds->begin());
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- delete sound->reader;
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete sound;
- m_playingSounds->erase(m_playingSounds->begin());
- }
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
- // delete all paused sounds
- while(!m_pausedSounds->empty())
- {
- sound = *(m_pausedSounds->begin());
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- delete sound->reader;
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete sound;
- m_pausedSounds->erase(m_pausedSounds->begin());
- }
// delete all buffered factories
- while(!m_bufferedFactories->empty())
+ /*while(!m_bufferedFactories->empty())
{
alDeleteBuffers(1, &(*(m_bufferedFactories->begin()))->buffer);
delete *m_bufferedFactories->begin();
m_bufferedFactories->erase(m_bufferedFactories->begin());
- }
+ }*/
alcProcessContext(m_context);
@@ -422,9 +1056,7 @@ AUD_OpenALDevice::~AUD_OpenALDevice()
else
unlock();
- delete m_playingSounds;
- delete m_pausedSounds;
- delete m_bufferedFactories;
+ //delete m_bufferedFactories;
// quit OpenAL
alcMakeContextCurrent(NULL);
@@ -530,120 +1162,54 @@ bool AUD_OpenALDevice::getFormat(ALenum &format, AUD_Specs specs)
return valid;
}
-static const char* genbuffer_error = "AUD_OpenALDevice: Buffer couldn't be "
- "generated.";
-static const char* gensource_error = "AUD_OpenALDevice: Source couldn't be "
- "generated.";
-static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
- "queued to the source.";
-static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
- "filled with data.";
-
-AUD_Handle* AUD_OpenALDevice::play(AUD_IReader* reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
- AUD_OpenALHandle* sound = NULL;
-
- AUD_DeviceSpecs specs = m_specs;
- specs.specs = reader->getSpecs();
+ AUD_Specs specs = reader->getSpecs();
// check format
- bool valid = specs.channels != AUD_CHANNELS_INVALID;
+ if(specs.channels == AUD_CHANNELS_INVALID)
+ return NULL;
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
- // create the handle
- sound = new AUD_OpenALHandle;
- sound->keep = keep;
- sound->reader = reader;
- sound->current = 0;
- sound->isBuffered = false;
- sound->data_end = false;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
-
- valid &= getFormat(sound->format, specs.specs);
+ ALenum format;
- if(!valid)
- {
- delete sound;
- delete reader;
+ if(!getFormat(format, specs))
return NULL;
- }
lock();
alcSuspendContext(m_context);
- // OpenAL playback code
+ AUD_Reference<AUD_OpenALDevice::AUD_OpenALHandle> sound;
+
try
{
- alGenBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
-
- try
- {
- sample_t* buf;
- int length;
-
- for(int i = 0; i < AUD_OPENAL_CYCLE_BUFFERS; i++)
- {
- length = m_buffersize;
- reader->read(length, buf);
- alBufferData(sound->buffers[i], sound->format, buf,
- length * AUD_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, bufferdata_error);
- }
-
- alGenSources(1, &sound->source);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
-
- try
- {
- alSourceQueueBuffers(sound->source, AUD_OPENAL_CYCLE_BUFFERS,
- sound->buffers);
- if(alGetError() != AL_NO_ERROR)
- AUD_THROW(AUD_ERROR_OPENAL, queue_error);
- }
- catch(AUD_Exception&)
- {
- alDeleteSources(1, &sound->source);
- throw;
- }
- }
- catch(AUD_Exception&)
- {
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- throw;
- }
+ // create the handle
+ sound = new AUD_OpenALDevice::AUD_OpenALHandle(this, format, reader, keep);
}
catch(AUD_Exception&)
{
- delete sound;
- delete reader;
alcProcessContext(m_context);
unlock();
throw;
}
+ alcProcessContext(m_context);
+
// play sound
- m_playingSounds->push_back(sound);
- alSourcei(sound->source, AL_SOURCE_RELATIVE, 1);
+ m_playingSounds.push_back(sound);
start();
- alcProcessContext(m_context);
unlock();
- return sound;
+ return AUD_Reference<AUD_IHandle>(sound);
}
-AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_OpenALDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
+ /* AUD_XXX disabled
AUD_OpenALHandle* sound = NULL;
lock();
@@ -661,7 +1227,7 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
sound->keep = keep;
sound->current = -1;
sound->isBuffered = true;
- sound->data_end = true;
+ sound->eos = true;
sound->loopcount = 0;
sound->stop = NULL;
sound->stop_data = NULL;
@@ -713,266 +1279,11 @@ AUD_Handle* AUD_OpenALDevice::play(AUD_IFactory* factory, bool keep)
unlock();
if(sound)
- return sound;
+ return sound;*/
return play(factory->createReader(), keep);
}
-bool AUD_OpenALDevice::pause(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are played can be paused
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- m_pausedSounds->push_back(*i);
- alSourcePause((*i)->source);
- m_playingSounds->erase(i);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::resume(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- // only songs that are paused can be resumed
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- m_playingSounds->push_back(*i);
- start();
- m_pausedSounds->erase(i);
- result = true;
- break;
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::stop(AUD_Handle* handle)
-{
- AUD_OpenALHandle* sound;
-
- bool result = false;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- sound = *i;
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- delete sound->reader;
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete *i;
- m_playingSounds->erase(i);
- result = true;
- break;
- }
- }
- if(!result)
- {
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- sound = *i;
- alDeleteSources(1, &sound->source);
- if(!sound->isBuffered)
- {
- delete sound->reader;
- alDeleteBuffers(AUD_OPENAL_CYCLE_BUFFERS, sound->buffers);
- }
- delete *i;
- m_pausedSounds->erase(i);
- result = true;
- break;
- }
- }
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- result = ((AUD_OpenALHandle*)handle)->keep;
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- {
- ((AUD_OpenALHandle*)handle)->keep = keep;
- result = true;
- }
-
- unlock();
-
- return result;
-}
-
-bool AUD_OpenALDevice::seek(AUD_Handle* handle, float position)
-{
- bool result = false;
-
- lock();
-
- if(isValid(handle))
- {
- AUD_OpenALHandle* alhandle = (AUD_OpenALHandle*)handle;
- if(alhandle->isBuffered)
- alSourcef(alhandle->source, AL_SEC_OFFSET, position);
- else
- {
- alhandle->reader->seek((int)(position *
- alhandle->reader->getSpecs().rate));
- alhandle->data_end = false;
-
- ALint info;
-
- alGetSourcei(alhandle->source, AL_SOURCE_STATE, &info);
-
- if(info != AL_PLAYING)
- {
- if(info == AL_PAUSED)
- alSourceStop(alhandle->source);
-
- alSourcei(alhandle->source, AL_BUFFER, 0);
- alhandle->current = 0;
-
- ALenum err;
- if((err = alGetError()) == AL_NO_ERROR)
- {
- sample_t* buf;
- int length;
- 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_DEVICE_SAMPLE_SIZE(specs),
- specs.rate);
-
- if(alGetError() != AL_NO_ERROR)
- break;
- }
-
- alSourceQueueBuffers(alhandle->source,
- AUD_OPENAL_CYCLE_BUFFERS,
- alhandle->buffers);
- }
-
- alSourceRewind(alhandle->source);
- }
- }
- result = true;
- }
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getPosition(AUD_Handle* handle)
-{
- float position = 0.0f;
-
- lock();
-
- if(isValid(handle))
- {
- AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
- alGetSourcef(h->source, AL_SEC_OFFSET, &position);
- if(!h->isBuffered)
- {
- AUD_Specs specs = h->reader->getSpecs();
- position += (h->reader->getPosition() - m_buffersize *
- AUD_OPENAL_CYCLE_BUFFERS) /
- (float)specs.rate;
- }
- }
-
- unlock();
- return position;
-}
-
-AUD_Status AUD_OpenALDevice::getStatus(AUD_Handle* handle)
-{
- AUD_Status status = AUD_STATUS_INVALID;
-
- lock();
-
- for(AUD_HandleIterator i = m_playingSounds->begin();
- i != m_playingSounds->end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PLAYING;
- break;
- }
- }
- if(status == AUD_STATUS_INVALID)
- {
- for(AUD_HandleIterator i = m_pausedSounds->begin();
- i != m_pausedSounds->end(); i++)
- {
- if(*i == handle)
- {
- status = AUD_STATUS_PAUSED;
- break;
- }
- }
- }
-
- unlock();
-
- return status;
-}
-
void AUD_OpenALDevice::lock()
{
pthread_mutex_lock(&m_mutex);
@@ -995,80 +1306,6 @@ void AUD_OpenALDevice::setVolume(float volume)
alListenerf(AL_GAIN, volume);
}
-float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
-{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
-{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
- unlock();
- return result;
-}
-
-int AUD_OpenALDevice::getLoopCount(AUD_Handle* handle)
-{
- lock();
- int result = 0;
- if(isValid(handle))
- result = ((AUD_OpenALHandle*)handle)->loopcount;
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- ((AUD_OpenALHandle*)handle)->loopcount = count;
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
- lock();
- bool result = isValid(handle);
- if(result)
- {
- AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
- h->stop = callback;
- h->stop_data = data;
- }
- unlock();
- return result;
-}
-
/* AUD_XXX Temorary disabled
bool AUD_OpenALDevice::bufferFactory(void *value)
@@ -1109,7 +1346,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
if(!getFormat(format, specs.specs))
{
- delete reader;
return false;
}
@@ -1147,7 +1383,6 @@ bool AUD_OpenALDevice::bufferFactory(void *value)
catch(AUD_Exception&)
{
delete bf;
- delete reader;
alcProcessContext(m_context);
unlock();
return false;
@@ -1308,333 +1543,3 @@ void AUD_OpenALDevice::setDistanceModel(AUD_DistanceModel model)
alDistanceModel(AL_NONE);
}
}
-
-AUD_Vector3 AUD_OpenALDevice::getSourceLocation(AUD_Handle* handle)
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
- ALfloat p[3];
- lock();
-
- if(isValid(handle))
- {
- alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION, p);
- result = AUD_Vector3(p[0], p[1], p[2]);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_POSITION,
- (ALfloat*)location.get());
-
- unlock();
- return result;
-}
-
-AUD_Vector3 AUD_OpenALDevice::getSourceVelocity(AUD_Handle* handle)
-{
- AUD_Vector3 result = AUD_Vector3(0, 0, 0);
- ALfloat v[3];
- lock();
-
- if(isValid(handle))
- {
- alGetSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY, v);
- result = AUD_Vector3(v[0], v[1], v[2]);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_VELOCITY,
- (ALfloat*)velocity.get());
-
- unlock();
- return result;
-}
-
-AUD_Quaternion AUD_OpenALDevice::getSourceOrientation(AUD_Handle* handle)
-{
- // AUD_XXX not implemented yet
- return AUD_Quaternion(0, 0, 0, 0);
-}
-
-bool AUD_OpenALDevice::setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- {
- ALfloat direction[3];
- direction[0] = -2 * (orientation.w() * orientation.y() +
- orientation.x() * orientation.z());
- direction[1] = 2 * (orientation.x() * orientation.w() -
- orientation.z() * orientation.y());
- direction[2] = 2 * (orientation.x() * orientation.x() +
- orientation.y() * orientation.y()) - 1;
- alSourcefv(((AUD_OpenALHandle*)handle)->source, AL_DIRECTION,
- direction);
- }
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::isRelative(AUD_Handle* handle)
-{
- int result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setRelative(AUD_Handle* handle, bool relative)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcei(((AUD_OpenALHandle*)handle)->source, AL_SOURCE_RELATIVE,
- relative);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getVolumeMaximum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMaximum(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
-
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_GAIN,
- volume);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getVolumeMinimum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setVolumeMinimum(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MIN_GAIN,
- volume);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getDistanceMaximum(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setDistanceMaximum(AUD_Handle* handle, float distance)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_MAX_DISTANCE,
- distance);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getDistanceReference(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setDistanceReference(AUD_Handle* handle, float distance)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_REFERENCE_DISTANCE,
- distance);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getAttenuation(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setAttenuation(AUD_Handle* handle, float factor)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_ROLLOFF_FACTOR,
- factor);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeAngleOuter(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleOuter(AUD_Handle* handle, float angle)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_ANGLE,
- angle);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeAngleInner(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeAngleInner(AUD_Handle* handle, float angle)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_INNER_ANGLE,
- angle);
-
- unlock();
- return result;
-}
-
-float AUD_OpenALDevice::getConeVolumeOuter(AUD_Handle* handle)
-{
- float result = std::numeric_limits<float>::quiet_NaN();;
-
- lock();
-
- if(isValid(handle))
- alGetSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
- &result);
-
- unlock();
- return result;
-}
-
-bool AUD_OpenALDevice::setConeVolumeOuter(AUD_Handle* handle, float volume)
-{
- lock();
- bool result = isValid(handle);
-
- if(result)
- alSourcef(((AUD_OpenALHandle*)handle)->source, AL_CONE_OUTER_GAIN,
- volume);
-
- unlock();
- return result;
-}
diff --git a/intern/audaspace/OpenAL/AUD_OpenALDevice.h b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
index 3bbbe85d7e6..ea4f9ca1ea8 100644
--- a/intern/audaspace/OpenAL/AUD_OpenALDevice.h
+++ b/intern/audaspace/OpenAL/AUD_OpenALDevice.h
@@ -33,9 +33,11 @@
#define AUD_OPENALDEVICE
#include "AUD_IDevice.h"
+#include "AUD_IHandle.h"
#include "AUD_I3DDevice.h"
-struct AUD_OpenALHandle;
-struct AUD_OpenALBufferedFactory;
+#include "AUD_I3DHandle.h"
+#include "AUD_Buffer.h"
+//struct AUD_OpenALBufferedFactory;
#include <AL/al.h>
#include <AL/alc.h>
@@ -48,6 +50,100 @@ struct AUD_OpenALBufferedFactory;
class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
{
private:
+ /// Saves the data for playback.
+ class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
+ {
+ public:
+ static const int CYCLE_BUFFERS = 3;
+
+ /// Whether it's a buffered or a streamed source.
+ bool m_isBuffered;
+
+ /// The reader source.
+ AUD_Reference<AUD_IReader> m_reader;
+
+ /// Whether to keep the source if end of it is reached.
+ bool m_keep;
+
+ /// OpenAL sample format.
+ ALenum m_format;
+
+ /// OpenAL source.
+ ALuint m_source;
+
+ /// OpenAL buffers.
+ ALuint m_buffers[CYCLE_BUFFERS];
+
+ /// The first buffer to be read next.
+ int m_current;
+
+ /// Whether the stream doesn't return any more data.
+ bool m_eos;
+
+ /// The loop count of the source.
+ int m_loopcount;
+
+ /// The stop callback.
+ stopCallback m_stop;
+
+ /// Stop callback data.
+ void* m_stop_data;
+
+ /// Current status of the handle
+ AUD_Status m_status;
+
+ /// Own device.
+ AUD_OpenALDevice* m_device;
+
+ public:
+
+ AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep);
+
+ virtual ~AUD_OpenALHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual AUD_Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+
+ virtual AUD_Vector3 getSourceLocation();
+ virtual bool setSourceLocation(const AUD_Vector3& location);
+ virtual AUD_Vector3 getSourceVelocity();
+ virtual bool setSourceVelocity(const AUD_Vector3& velocity);
+ virtual AUD_Quaternion getSourceOrientation();
+ virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual bool isRelative();
+ virtual bool setRelative(bool relative);
+ virtual float getVolumeMaximum();
+ virtual bool setVolumeMaximum(float volume);
+ virtual float getVolumeMinimum();
+ virtual bool setVolumeMinimum(float volume);
+ virtual float getDistanceMaximum();
+ virtual bool setDistanceMaximum(float distance);
+ virtual float getDistanceReference();
+ virtual bool setDistanceReference(float distance);
+ virtual float getAttenuation();
+ virtual bool setAttenuation(float factor);
+ virtual float getConeAngleOuter();
+ virtual bool setConeAngleOuter(float angle);
+ virtual float getConeAngleInner();
+ virtual bool setConeAngleInner(float angle);
+ virtual float getConeVolumeOuter();
+ virtual bool setConeVolumeOuter(float volume);
+ };
+
+ typedef std::list<AUD_Reference<AUD_OpenALHandle> >::iterator AUD_HandleIterator;
+
/**
* The OpenAL device handle.
*/
@@ -71,17 +167,17 @@ private:
/**
* The list of sounds that are currently playing.
*/
- std::list<AUD_OpenALHandle*>* m_playingSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_OpenALHandle*>* m_pausedSounds;
+ std::list<AUD_Reference<AUD_OpenALHandle> > m_pausedSounds;
/**
* The list of buffered factories.
*/
- std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
+ //std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
/**
* The mutex for locking.
@@ -104,16 +200,14 @@ private:
int m_buffersize;
/**
- * Starts the streaming thread.
+ * Device buffer.
*/
- void start();
+ AUD_Buffer m_buffer;
/**
- * Checks if a handle is valid.
- * \param handle The handle to check.
- * \return Whether the handle is valid.
+ * Starts the streaming thread.
*/
- bool isValid(AUD_Handle* handle);
+ void start();
/**
* Gets the format according to the specs.
@@ -147,27 +241,12 @@ public:
virtual ~AUD_OpenALDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
virtual AUD_Vector3 getListenerLocation() const;
virtual void setListenerLocation(const AUD_Vector3& location);
@@ -181,30 +260,6 @@ public:
virtual void setDopplerFactor(float factor);
virtual AUD_DistanceModel getDistanceModel() const;
virtual void setDistanceModel(AUD_DistanceModel model);
- virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
- virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
- virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
- virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
- virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
- virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
- virtual bool isRelative(AUD_Handle* handle);
- virtual bool setRelative(AUD_Handle* handle, bool relative);
- virtual float getVolumeMaximum(AUD_Handle* handle);
- virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
- virtual float getVolumeMinimum(AUD_Handle* handle);
- virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
- virtual float getDistanceMaximum(AUD_Handle* handle);
- virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
- virtual float getDistanceReference(AUD_Handle* handle);
- virtual bool setDistanceReference(AUD_Handle* handle, float distance);
- virtual float getAttenuation(AUD_Handle* handle);
- virtual bool setAttenuation(AUD_Handle* handle, float factor);
- virtual float getConeAngleOuter(AUD_Handle* handle);
- virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
- virtual float getConeAngleInner(AUD_Handle* handle);
- virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
- virtual float getConeVolumeOuter(AUD_Handle* handle);
- virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
};
#endif //AUD_OPENALDEVICE
diff --git a/intern/audaspace/Python/AUD_PyAPI.cpp b/intern/audaspace/Python/AUD_PyAPI.cpp
index 22376a2fcd1..12bb19644f0 100644
--- a/intern/audaspace/Python/AUD_PyAPI.cpp
+++ b/intern/audaspace/Python/AUD_PyAPI.cpp
@@ -33,6 +33,7 @@
#include "structmember.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_NULLDevice.h"
#include "AUD_DelayFactory.h"
#include "AUD_DoubleFactory.h"
@@ -91,7 +92,7 @@ static void
Factory_dealloc(Factory* self)
{
if(self->factory)
- delete self->factory;
+ delete reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory);
Py_XDECREF(self->child_list);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -115,7 +116,7 @@ Factory_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -155,7 +156,7 @@ Factory_sine(PyTypeObject* type, PyObject* args)
{
try
{
- self->factory = new AUD_SinusFactory(frequency, (AUD_SampleRate)rate);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_SinusFactory(frequency, (AUD_SampleRate)rate));
}
catch(AUD_Exception& e)
{
@@ -194,7 +195,7 @@ Factory_file(PyTypeObject* type, PyObject* args)
{
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
@@ -237,7 +238,7 @@ Factory_lowpass(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LowpassFactory(self->factory, frequency, Q);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LowpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -278,7 +279,7 @@ Factory_delay(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_DelayFactory(self->factory, delay);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DelayFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), delay));
}
catch(AUD_Exception& e)
{
@@ -322,7 +323,7 @@ Factory_join(Factory* self, PyObject* object)
try
{
- parent->factory = new AUD_DoubleFactory(self->factory, child->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_DoubleFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -365,7 +366,7 @@ Factory_highpass(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_HighpassFactory(self->factory, frequency, Q);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_HighpassFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), frequency, Q));
}
catch(AUD_Exception& e)
{
@@ -406,7 +407,7 @@ Factory_limit(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LimiterFactory(self->factory, start, end);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LimiterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), start, end));
}
catch(AUD_Exception& e)
{
@@ -450,7 +451,7 @@ Factory_pitch(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_PitchFactory(self->factory, factor);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PitchFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), factor));
}
catch(AUD_Exception& e)
{
@@ -492,7 +493,7 @@ Factory_volume(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_VolumeFactory(self->factory, volume);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_VolumeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), volume));
}
catch(AUD_Exception& e)
{
@@ -535,7 +536,7 @@ Factory_fadein(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_IN, start, length);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_IN, start, length));
}
catch(AUD_Exception& e)
{
@@ -579,7 +580,7 @@ Factory_fadeout(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_FaderFactory(self->factory, AUD_FADE_OUT, start, length);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_FaderFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), AUD_FADE_OUT, start, length));
}
catch(AUD_Exception& e)
{
@@ -621,7 +622,7 @@ Factory_loop(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_LoopFactory(self->factory, loop);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_LoopFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), loop));
}
catch(AUD_Exception& e)
{
@@ -664,7 +665,7 @@ Factory_mix(Factory* self, PyObject* object)
try
{
- parent->factory = new AUD_SuperposeFactory(self->factory, child->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SuperposeFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), *reinterpret_cast<AUD_Reference<AUD_IFactory>*>(child->factory)));
}
catch(AUD_Exception& e)
{
@@ -697,7 +698,7 @@ Factory_pingpong(Factory* self)
try
{
- parent->factory = new AUD_PingPongFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_PingPongFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -736,7 +737,7 @@ Factory_reverse(Factory* self)
try
{
- parent->factory = new AUD_ReverseFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_ReverseFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -771,7 +772,7 @@ Factory_buffer(Factory* self)
{
try
{
- parent->factory = new AUD_StreamBufferFactory(self->factory);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_StreamBufferFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory)));
}
catch(AUD_Exception& e)
{
@@ -813,7 +814,7 @@ Factory_square(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_SquareFactory(self->factory, threshold);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_SquareFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), threshold));
}
catch(AUD_Exception& e)
{
@@ -910,7 +911,7 @@ Factory_filter(Factory* self, PyObject* args)
try
{
- parent->factory = new AUD_IIRFilterFactory(self->factory, b, a);
+ parent->factory = new AUD_Reference<AUD_IFactory>(new AUD_IIRFilterFactory(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(self->factory), b, a));
}
catch(AUD_Exception& e)
{
@@ -1033,7 +1034,8 @@ static PyTypeObject FactoryType = {
static void
Handle_dealloc(Handle* self)
{
- Py_XDECREF(self->device);
+ if(self->handle)
+ delete reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -1046,11 +1048,9 @@ PyDoc_STRVAR(M_aud_Handle_pause_doc,
static PyObject *
Handle_pause(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)device->device->pause(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->pause());
}
catch(AUD_Exception& e)
{
@@ -1068,11 +1068,9 @@ PyDoc_STRVAR(M_aud_Handle_resume_doc,
static PyObject *
Handle_resume(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)device->device->resume(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->resume());
}
catch(AUD_Exception& e)
{
@@ -1091,11 +1089,9 @@ PyDoc_STRVAR(M_aud_Handle_stop_doc,
static PyObject *
Handle_stop(Handle *self)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)device->device->stop(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->stop());
}
catch(AUD_Exception& e)
{
@@ -1123,11 +1119,9 @@ PyDoc_STRVAR(M_aud_Handle_position_doc,
static PyObject *
Handle_get_position(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", device->device->getPosition(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPosition());
}
catch(AUD_Exception& e)
{
@@ -1144,11 +1138,9 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:position", &position))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if(device->device->seek(self->handle, position))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->seek(position))
return 0;
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
@@ -1172,11 +1164,9 @@ PyDoc_STRVAR(M_aud_Handle_keep_doc,
static PyObject *
Handle_get_keep(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)device->device->getKeep(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getKeep());
}
catch(AUD_Exception& e)
{
@@ -1195,11 +1185,10 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing)
}
bool keep = args == Py_True;
- Device* device = (Device*)self->device;
try
{
- if(device->device->setKeep(self->handle, keep))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setKeep(keep))
return 0;
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
@@ -1217,11 +1206,9 @@ PyDoc_STRVAR(M_aud_Handle_status_doc,
static PyObject *
Handle_get_status(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return PyBool_FromLong((long)device->device->getStatus(self->handle));
+ return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getStatus());
}
catch(AUD_Exception& e)
{
@@ -1236,11 +1223,9 @@ PyDoc_STRVAR(M_aud_Handle_volume_doc,
static PyObject *
Handle_get_volume(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", device->device->getVolume(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -1257,11 +1242,9 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume", &volume))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if(device->device->setVolume(self->handle, volume))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setVolume(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
@@ -1279,11 +1262,9 @@ PyDoc_STRVAR(M_aud_Handle_pitch_doc,
static PyObject *
Handle_get_pitch(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("f", device->device->getPitch(self->handle));
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPitch());
}
catch(AUD_Exception& e)
{
@@ -1300,11 +1281,9 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:pitch", &pitch))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if(device->device->setPitch(self->handle, pitch))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setPitch(pitch))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
@@ -1322,11 +1301,9 @@ PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
static PyObject *
Handle_get_loop_count(Handle *self, void* nothing)
{
- Device* device = (Device*)self->device;
-
try
{
- return Py_BuildValue("i", device->device->getLoopCount(self->handle));
+ return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getLoopCount());
}
catch(AUD_Exception& e)
{
@@ -1343,11 +1320,9 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "i:loop_count", &loops))
return -1;
- Device* device = (Device*)self->device;
-
try
{
- if(device->device->setLoopCount(self->handle, loops))
+ if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
return 0;
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
@@ -1365,14 +1340,12 @@ PyDoc_STRVAR(M_aud_Handle_location_doc,
static PyObject *
Handle_get_location(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Vector3 v = device->getSourceLocation(self->handle);
+ AUD_Vector3 v = handle->getSourceLocation();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1396,15 +1369,13 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Vector3 location(x, y, z);
- if(device->setSourceLocation(self->handle, location))
+ if(handle->setSourceLocation(location))
return 0;
PyErr_SetString(AUDError, "Location couldn't be set!");
}
@@ -1425,14 +1396,12 @@ PyDoc_STRVAR(M_aud_Handle_velocity_doc,
static PyObject *
Handle_get_velocity(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Vector3 v = device->getSourceVelocity(self->handle);
+ AUD_Vector3 v = handle->getSourceVelocity();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1456,15 +1425,13 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Vector3 velocity(x, y, z);
- if(device->setSourceVelocity(self->handle, velocity))
+ if(handle->setSourceVelocity(velocity))
return 0;
PyErr_SetString(AUDError, "Couldn't set the velocity!");
}
@@ -1485,14 +1452,12 @@ PyDoc_STRVAR(M_aud_Handle_orientation_doc,
static PyObject *
Handle_get_orientation(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- AUD_Quaternion o = device->getSourceOrientation(self->handle);
+ AUD_Quaternion o = handle->getSourceOrientation();
return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
}
else
@@ -1516,15 +1481,13 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
AUD_Quaternion orientation(w, x, y, z);
- if(device->setSourceOrientation(self->handle, orientation))
+ if(handle->setSourceOrientation(orientation))
return 0;
PyErr_SetString(AUDError, "Couldn't set the orientation!");
}
@@ -1545,14 +1508,12 @@ PyDoc_STRVAR(M_aud_Handle_relative_doc,
static PyObject *
Handle_get_relative(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return PyBool_FromLong((long)device->isRelative(self->handle));
+ return PyBool_FromLong((long)handle->isRelative());
}
else
{
@@ -1577,14 +1538,13 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
}
bool relative = (args == Py_True);
- Device* dev = (Device*)self->device;
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setRelative(self->handle, relative))
+ if(handle->setRelative(relative))
return 0;
PyErr_SetString(AUDError, "Couldn't set the relativeness!");
}
@@ -1606,14 +1566,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
static PyObject *
Handle_get_volume_minimum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
+ return Py_BuildValue("f", handle->getVolumeMinimum());
}
else
{
@@ -1636,14 +1594,12 @@ Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_minimum", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setVolumeMinimum(self->handle, volume))
+ if(handle->setVolumeMinimum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
}
@@ -1665,14 +1621,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
static PyObject *
Handle_get_volume_maximum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
+ return Py_BuildValue("f", handle->getVolumeMaximum());
}
else
{
@@ -1695,14 +1649,12 @@ Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_maximum", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setVolumeMaximum(self->handle, volume))
+ if(handle->setVolumeMaximum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
}
@@ -1725,14 +1677,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
static PyObject *
Handle_get_distance_reference(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getDistanceReference(self->handle));
+ return Py_BuildValue("f", handle->getDistanceReference());
}
else
{
@@ -1755,14 +1705,12 @@ Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_reference", &distance))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setDistanceReference(self->handle, distance))
+ if(handle->setDistanceReference(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the reference distance!");
}
@@ -1785,14 +1733,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
static PyObject *
Handle_get_distance_maximum(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
+ return Py_BuildValue("f", handle->getDistanceMaximum());
}
else
{
@@ -1815,14 +1761,12 @@ Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_maximum", &distance))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setDistanceMaximum(self->handle, distance))
+ if(handle->setDistanceMaximum(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
}
@@ -1845,14 +1789,12 @@ PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
static PyObject *
Handle_get_attenuation(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getAttenuation(self->handle));
+ return Py_BuildValue("f", handle->getAttenuation());
}
else
{
@@ -1875,14 +1817,12 @@ Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:attenuation", &factor))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setAttenuation(self->handle, factor))
+ if(handle->setAttenuation(factor))
return 0;
PyErr_SetString(AUDError, "Couldn't set the attenuation!");
}
@@ -1910,14 +1850,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
static PyObject *
Handle_get_cone_angle_inner(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeAngleInner(self->handle));
+ return Py_BuildValue("f", handle->getConeAngleInner());
}
else
{
@@ -1940,14 +1878,12 @@ Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeAngleInner(self->handle, angle))
+ if(handle->setConeAngleInner(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
}
@@ -1969,14 +1905,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
static PyObject *
Handle_get_cone_angle_outer(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
+ return Py_BuildValue("f", handle->getConeAngleOuter());
}
else
{
@@ -1999,14 +1933,12 @@ Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeAngleOuter(self->handle, angle))
+ if(handle->setConeAngleOuter(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
}
@@ -2028,14 +1960,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
static PyObject *
Handle_get_cone_volume_outer(Handle *self, void* nothing)
{
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
+ return Py_BuildValue("f", handle->getConeVolumeOuter());
}
else
{
@@ -2058,14 +1988,12 @@ Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
return -1;
- Device* dev = (Device*)self->device;
-
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(dev->device);
- if(device)
+ AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
+ if(handle)
{
- if(device->setConeVolumeOuter(self->handle, volume))
+ if(handle->setConeVolumeOuter(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
}
@@ -2172,7 +2100,7 @@ static void
Device_dealloc(Device* self)
{
if(self->device)
- delete self->device;
+ delete reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -2183,13 +2111,13 @@ Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
static const char *kwlist[] = {"type", "rate", "channels", "format", "buffer_size", "name", NULL};
int device;
- int rate = AUD_RATE_44100;
+ double rate = AUD_RATE_44100;
int channels = AUD_CHANNELS_STEREO;
int format = AUD_FORMAT_FLOAT32;
int buffersize = AUD_DEFAULT_BUFFER_SIZE;
const char* name = "Audaspace";
- if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|iiiis:Device", const_cast<char**>(kwlist),
+ if(!PyArg_ParseTupleAndKeywords(args, kwds, "i|diiis:Device", const_cast<char**>(kwlist),
&device, &rate, &channels, &format, &buffersize, &name))
return NULL;
@@ -2215,21 +2143,21 @@ Device_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
case AUD_DEVICE_NULL:
(void)specs; /* quiet warning when others disabled */
- self->device = new AUD_NULLDevice();
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_NULLDevice());
break;
case AUD_DEVICE_OPENAL:
#ifdef WITH_OPENAL
- self->device = new AUD_OpenALDevice(specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_OpenALDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_SDL:
#ifdef WITH_SDL
- self->device = new AUD_SDLDevice(specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_SDLDevice(specs, buffersize));
#endif
break;
case AUD_DEVICE_JACK:
#ifdef WITH_JACK
- self->device = new AUD_JackDevice(name, specs, buffersize);
+ self->device = new AUD_Reference<AUD_IDevice>(new AUD_JackDevice(name, specs, buffersize));
#endif
break;
case AUD_DEVICE_READ:
@@ -2302,12 +2230,9 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
if(handle != NULL)
{
- handle->device = (PyObject*)self;
- Py_INCREF(self);
-
try
{
- handle->handle = self->device->play(sound->factory, keep);
+ handle->handle = new AUD_Reference<AUD_IHandle>((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep));
}
catch(AUD_Exception& e)
{
@@ -2336,7 +2261,7 @@ Device_lock(Device *self)
{
try
{
- self->device->lock();
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->lock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2356,7 +2281,7 @@ Device_unlock(Device *self)
{
try
{
- self->device->unlock();
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->unlock();
Py_RETURN_NONE;
}
catch(AUD_Exception& e)
@@ -2387,7 +2312,7 @@ Device_get_rate(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.rate);
}
catch(AUD_Exception& e)
@@ -2405,7 +2330,7 @@ Device_get_format(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.format);
}
catch(AUD_Exception& e)
@@ -2423,7 +2348,7 @@ Device_get_channels(Device *self, void* nothing)
{
try
{
- AUD_DeviceSpecs specs = self->device->getSpecs();
+ AUD_DeviceSpecs specs = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getSpecs();
return Py_BuildValue("i", specs.channels);
}
catch(AUD_Exception& e)
@@ -2441,7 +2366,7 @@ Device_get_volume(Device *self, void* nothing)
{
try
{
- return Py_BuildValue("f", self->device->getVolume());
+ return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -2460,7 +2385,7 @@ Device_set_volume(Device *self, PyObject* args, void* nothing)
try
{
- self->device->setVolume(volume);
+ (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->setVolume(volume);
return 0;
}
catch(AUD_Exception& e)
@@ -2478,7 +2403,7 @@ Device_get_listener_location(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerLocation();
@@ -2507,7 +2432,7 @@ Device_set_listener_location(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 location(x, y, z);
@@ -2533,7 +2458,7 @@ Device_get_listener_velocity(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 v = device->getListenerVelocity();
@@ -2562,7 +2487,7 @@ Device_set_listener_velocity(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Vector3 velocity(x, y, z);
@@ -2588,7 +2513,7 @@ Device_get_listener_orientation(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion o = device->getListenerOrientation();
@@ -2617,7 +2542,7 @@ Device_set_listener_orientation(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
AUD_Quaternion orientation(w, x, y, z);
@@ -2644,7 +2569,7 @@ Device_get_speed_of_sound(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getSpeedOfSound());
@@ -2672,7 +2597,7 @@ Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setSpeedOfSound(speed);
@@ -2700,7 +2625,7 @@ Device_get_doppler_factor(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("f", device->getDopplerFactor());
@@ -2728,7 +2653,7 @@ Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDopplerFactor(factor);
@@ -2754,7 +2679,7 @@ Device_get_distance_model(Device *self, void* nothing)
{
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
return Py_BuildValue("i", int(device->getDistanceModel()));
@@ -2782,7 +2707,7 @@ Device_set_distance_model(Device *self, PyObject* args, void* nothing)
try
{
- AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(self->device);
+ AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device)->get());
if(device)
{
device->setDistanceModel(AUD_DistanceModel(model));
@@ -2875,6 +2800,25 @@ Device_empty()
return DeviceType.tp_alloc(&DeviceType, 0);
}
+PyObject *
+Factory_empty()
+{
+ return FactoryType.tp_alloc(&FactoryType, 0);
+}
+
+Factory*
+checkFactory(PyObject* factory)
+{
+ if(!PyObject_TypeCheck(factory, &FactoryType))
+ {
+ PyErr_SetString(PyExc_TypeError, "Object is not of type Factory!");
+ return NULL;
+ }
+
+ return (Factory*)factory;
+}
+
+
// ====================================================================
PyDoc_STRVAR(M_aud_doc,
diff --git a/intern/audaspace/Python/AUD_PyAPI.h b/intern/audaspace/Python/AUD_PyAPI.h
index 6e217b07213..e234ad4dded 100644
--- a/intern/audaspace/Python/AUD_PyAPI.h
+++ b/intern/audaspace/Python/AUD_PyAPI.h
@@ -36,35 +36,38 @@
#ifdef __cplusplus
extern "C" {
-#include "AUD_IDevice.h"
#else
typedef void AUD_IFactory;
typedef void AUD_IDevice;
-typedef void AUD_Handle;
+typedef void AUD_IHandle;
#endif
+typedef void AUD_Reference_AUD_IFactory;
+typedef void AUD_Reference_AUD_IDevice;
+typedef void AUD_Reference_AUD_IHandle;
+
typedef struct {
PyObject_HEAD
PyObject* child_list;
- AUD_IFactory* factory;
+ AUD_Reference_AUD_IFactory* factory;
} Factory;
typedef struct {
PyObject_HEAD
- AUD_Handle* handle;
- PyObject* device;
+ AUD_Reference_AUD_IHandle* handle;
} Handle;
typedef struct {
PyObject_HEAD
- AUD_IDevice* device;
+ AUD_Reference_AUD_IDevice* device;
} Device;
PyMODINIT_FUNC
PyInit_aud(void);
-extern PyObject *
-Device_empty();
+extern PyObject* Device_empty();
+extern PyObject* Factory_empty();
+extern Factory* checkFactory(PyObject* factory);
#ifdef __cplusplus
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
index 17cf09efc1d..c4402e88c65 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.cpp
@@ -32,18 +32,13 @@
#include "AUD_SRCResampleFactory.h"
#include "AUD_SRCResampleReader.h"
-AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_IFactory* factory,
+AUD_SRCResampleFactory::AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
- AUD_ResampleFactory(factory, specs)
+ AUD_MixerFactory(factory, specs)
{
}
-AUD_IReader* AUD_SRCResampleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SRCResampleFactory::createReader()
{
- AUD_IReader* reader = getReader();
-
- if(reader->getSpecs().rate != m_specs.rate)
- reader = new AUD_SRCResampleReader(reader, m_specs.specs);
-
- return reader;
+ return new AUD_SRCResampleReader(getReader(), m_specs.specs);
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleFactory.h b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
index 716def960fd..2f5fe30ac47 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleFactory.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleFactory.h
@@ -32,13 +32,13 @@
#ifndef AUD_SRCRESAMPLEFACTORY
#define AUD_SRCRESAMPLEFACTORY
-#include "AUD_ResampleFactory.h"
+#include "AUD_MixerFactory.h"
/**
* This factory creates a resampling reader that uses libsamplerate for
* resampling.
*/
-class AUD_SRCResampleFactory : public AUD_ResampleFactory
+class AUD_SRCResampleFactory : public AUD_MixerFactory
{
private:
// hide copy constructor and operator=
@@ -46,9 +46,9 @@ private:
AUD_SRCResampleFactory& operator=(const AUD_SRCResampleFactory&);
public:
- AUD_SRCResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_SRCResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SRCRESAMPLEFACTORY
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
index 1026514a9b8..a72d8ba393b 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.cpp
@@ -43,20 +43,16 @@ static long src_callback(void *cb_data, float **data)
static const char* state_error = "AUD_SRCResampleReader: SRC State couldn't be "
"created.";
-AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_IReader* reader,
+AUD_SRCResampleReader::AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader,
AUD_Specs specs) :
- AUD_EffectReader(reader),
- m_sspecs(reader->getSpecs()),
- m_factor(double(specs.rate) / double(m_sspecs.rate)),
- m_tspecs(specs),
+ AUD_ResampleReader(reader, specs.rate),
+ m_channels(reader->getSpecs().channels),
m_position(0)
{
- m_tspecs.channels = m_sspecs.channels;
-
int error;
m_src = src_callback_new(src_callback,
SRC_SINC_MEDIUM_QUALITY,
- m_sspecs.channels,
+ m_channels,
&error,
this);
@@ -74,25 +70,32 @@ AUD_SRCResampleReader::~AUD_SRCResampleReader()
long AUD_SRCResampleReader::doCallback(float** data)
{
- int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(m_tspecs);
- sample_t* buffer;
+ AUD_Specs specs;
+ specs.channels = m_channels;
+ specs.rate = m_rate;
+
+ int length = m_buffer.getSize() / AUD_SAMPLE_SIZE(specs);
- m_reader->read(length, buffer);
+ *data = m_buffer.getBuffer();
+ m_reader->read(length, m_eos, *data);
- *data = buffer;
return length;
}
void AUD_SRCResampleReader::seek(int position)
{
- m_reader->seek(position / m_factor);
+ AUD_Specs specs = m_reader->getSpecs();
+ double factor = double(m_rate) / double(specs.rate);
+ m_reader->seek(position / factor);
src_reset(m_src);
m_position = position;
}
int AUD_SRCResampleReader::getLength() const
{
- return m_reader->getLength() * m_factor;
+ AUD_Specs specs = m_reader->getSpecs();
+ double factor = double(m_rate) / double(specs.rate);
+ return m_reader->getLength() * factor;
}
int AUD_SRCResampleReader::getPosition() const
@@ -102,19 +105,48 @@ int AUD_SRCResampleReader::getPosition() const
AUD_Specs AUD_SRCResampleReader::getSpecs() const
{
- return m_tspecs;
+ AUD_Specs specs = m_reader->getSpecs();
+ specs.rate = m_rate;
+ return specs;
}
-void AUD_SRCResampleReader::read(int & length, sample_t* & buffer)
+void AUD_SRCResampleReader::read(int& length, bool& eos, sample_t* buffer)
{
- int size = length * AUD_SAMPLE_SIZE(m_tspecs);
+ AUD_Specs specs = m_reader->getSpecs();
+
+ double factor = double(m_rate) / double(specs.rate);
- if(m_buffer.getSize() < size)
- m_buffer.resize(size);
+ specs.rate = m_rate;
- buffer = m_buffer.getBuffer();
+ int size = length;
- length = src_callback_read(m_src, m_factor, length, buffer);
+ m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs));
+
+ if(specs.channels != m_channels)
+ {
+ src_delete(m_src);
+
+ m_channels = specs.channels;
+
+ int error;
+ m_src = src_callback_new(src_callback,
+ SRC_SINC_MEDIUM_QUALITY,
+ m_channels,
+ &error,
+ this);
+
+ if(!m_src)
+ {
+ // XXX printf("%s\n", src_strerror(error));
+ AUD_THROW(AUD_ERROR_SRC, state_error);
+ }
+ }
+
+ m_eos = false;
+
+ length = src_callback_read(m_src, factor, length, buffer);
m_position += length;
+
+ eos = m_eos && (length < size);
}
diff --git a/intern/audaspace/SRC/AUD_SRCResampleReader.h b/intern/audaspace/SRC/AUD_SRCResampleReader.h
index 27019c0ed9f..dddfeb6a452 100644
--- a/intern/audaspace/SRC/AUD_SRCResampleReader.h
+++ b/intern/audaspace/SRC/AUD_SRCResampleReader.h
@@ -32,7 +32,7 @@
#ifndef AUD_SRCRESAMPLEREADER
#define AUD_SRCRESAMPLEREADER
-#include "AUD_EffectReader.h"
+#include "AUD_ResampleReader.h"
#include "AUD_Buffer.h"
#include <samplerate.h>
@@ -40,28 +40,18 @@
/**
* This resampling reader uses libsamplerate for resampling.
*/
-class AUD_SRCResampleReader : public AUD_EffectReader
+class AUD_SRCResampleReader : public AUD_ResampleReader
{
private:
/**
- * The sample specification of the source.
- */
- const AUD_Specs m_sspecs;
-
- /**
- * The resampling factor.
- */
- const double m_factor;
-
- /**
* The sound output buffer.
*/
AUD_Buffer m_buffer;
/**
- * The target specification.
+ * The reader channels.
*/
- AUD_Specs m_tspecs;
+ AUD_Channels m_channels;
/**
* The src state structure.
@@ -73,6 +63,11 @@ private:
*/
int m_position;
+ /**
+ * Whether reader reached end of stream.
+ */
+ bool m_eos;
+
// hide copy constructor and operator=
AUD_SRCResampleReader(const AUD_SRCResampleReader&);
AUD_SRCResampleReader& operator=(const AUD_SRCResampleReader&);
@@ -85,7 +80,7 @@ public:
* \exception AUD_Exception Thrown if the source specification cannot be
* resampled to the target specification.
*/
- AUD_SRCResampleReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_SRCResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
/**
* Destroys the reader.
@@ -104,7 +99,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SRCRESAMPLEREADER
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
index 38de3e8867a..909f41302d7 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.cpp
@@ -46,13 +46,13 @@ AUD_FFMPEGFactory::AUD_FFMPEGFactory(std::string filename) :
AUD_FFMPEGFactory::AUD_FFMPEGFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_IReader* AUD_FFMPEGFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FFMPEGFactory::createReader()
{
- if(m_buffer.get())
- return new AUD_FFMPEGReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_FFMPEGReader(m_filename);
+ else
+ return new AUD_FFMPEGReader(m_buffer);
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
index 12687402fb6..af95e3a3b81 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGFactory.h
@@ -74,7 +74,7 @@ public:
*/
AUD_FFMPEGFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_FFMPEGFACTORY
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
index 4597432e7d1..b7690d55383 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.cpp
@@ -255,12 +255,12 @@ int AUD_FFMPEGReader::read_packet(void* opaque, uint8_t* buf, int buf_size)
{
AUD_FFMPEGReader* reader = reinterpret_cast<AUD_FFMPEGReader*>(opaque);
- int size = AUD_MIN(buf_size, reader->m_membuffer.get()->getSize() - reader->m_membufferpos);
+ int size = AUD_MIN(buf_size, reader->m_membuffer->getSize() - reader->m_membufferpos);
if(size < 0)
return -1;
- memcpy(buf, ((data_t*)reader->m_membuffer.get()->getBuffer()) + reader->m_membufferpos, size);
+ memcpy(buf, ((data_t*)reader->m_membuffer->getBuffer()) + reader->m_membufferpos, size);
reader->m_membufferpos += size;
return size;
@@ -276,10 +276,10 @@ int64_t AUD_FFMPEGReader::seek_packet(void* opaque, int64_t offset, int whence)
reader->m_membufferpos = 0;
break;
case SEEK_END:
- reader->m_membufferpos = reader->m_membuffer.get()->getSize();
+ reader->m_membufferpos = reader->m_membuffer->getSize();
break;
case AVSEEK_SIZE:
- return reader->m_membuffer.get()->getSize();
+ return reader->m_membuffer->getSize();
}
return (reader->m_membufferpos += offset);
@@ -341,14 +341,15 @@ void AUD_FFMPEGReader::seek(int position)
{
// read until we're at the right position
int length = AUD_DEFAULT_BUFFER_SIZE;
- sample_t* buffer;
+ AUD_Buffer buffer(length * AUD_SAMPLE_SIZE(m_specs));
+ bool eos;
for(int len = position - m_position;
length == AUD_DEFAULT_BUFFER_SIZE;
len -= AUD_DEFAULT_BUFFER_SIZE)
{
if(len < AUD_DEFAULT_BUFFER_SIZE)
length = len;
- read(length, buffer);
+ read(length, eos, buffer.getBuffer());
}
}
}
@@ -381,7 +382,7 @@ AUD_Specs AUD_FFMPEGReader::getSpecs() const
return m_specs.specs;
}
-void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
+void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
{
// read packages and decode them
AVPacket packet;
@@ -390,11 +391,7 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
int left = length;
int sample_size = AUD_DEVICE_SAMPLE_SIZE(m_specs);
- // resize output buffer if necessary
- if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(m_specs))
- m_buffer.resize(length * AUD_SAMPLE_SIZE(m_specs));
-
- buffer = m_buffer.getBuffer();
+ sample_t* buf = buffer;
pkgbuf_pos = m_pkgbuf_left;
m_pkgbuf_left = 0;
@@ -402,9 +399,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
if(pkgbuf_pos > 0)
{
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buffer, (data_t*) m_pkgbuf.getBuffer(),
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
data_size / AUD_FORMAT_SIZE(m_specs.format));
- buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
@@ -419,9 +416,9 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
// copy to output buffer
data_size = AUD_MIN(pkgbuf_pos, left * sample_size);
- m_convert((data_t*) buffer, (data_t*) m_pkgbuf.getBuffer(),
+ m_convert((data_t*) buf, (data_t*) m_pkgbuf.getBuffer(),
data_size / AUD_FORMAT_SIZE(m_specs.format));
- buffer += data_size / AUD_FORMAT_SIZE(m_specs.format);
+ buf += data_size / AUD_FORMAT_SIZE(m_specs.format);
left -= data_size/sample_size;
}
av_free_packet(&packet);
@@ -435,9 +432,8 @@ void AUD_FFMPEGReader::read(int & length, sample_t* & buffer)
pkgbuf_pos-data_size);
}
- buffer = m_buffer.getBuffer();
-
- if(left > 0)
+ if((eos = (left > 0)))
length -= left;
+
m_position += length;
}
diff --git a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
index 26e66859451..06d6fe1e5f6 100644
--- a/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
+++ b/intern/audaspace/ffmpeg/AUD_FFMPEGReader.h
@@ -61,11 +61,6 @@ private:
int m_position;
/**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
* The specification of the audio data.
*/
AUD_DeviceSpecs m_specs;
@@ -167,7 +162,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_FFMPEGREADER
diff --git a/intern/audaspace/fftw/AUD_BandPassReader.cpp b/intern/audaspace/fftw/AUD_BandPassReader.cpp
index 06f0a2af0ad..22c65b18d76 100644
--- a/intern/audaspace/fftw/AUD_BandPassReader.cpp
+++ b/intern/audaspace/fftw/AUD_BandPassReader.cpp
@@ -71,8 +71,7 @@ void AUD_BandPassReader::read(int & length, sample_t* & buffer)
if(length > 0)
{
- if(length * AUD_SAMPLE_SIZE(specs) > m_buffer->getSize())
- m_buffer->resize(length * AUD_SAMPLE_SIZE(specs));
+ m_buffer->assureSize(length * AUD_SAMPLE_SIZE(specs));
if(length != m_length)
{
diff --git a/intern/audaspace/intern/AUD_3DMath.h b/intern/audaspace/intern/AUD_3DMath.h
index fc095ebaca7..3a6abf811ce 100644
--- a/intern/audaspace/intern/AUD_3DMath.h
+++ b/intern/audaspace/intern/AUD_3DMath.h
@@ -32,15 +32,16 @@
#ifndef AUD_3DMATH
#define AUD_3DMATH
-class AUD_Quaternion
+#include <cmath>
+
+class AUD_Vector3
{
private:
union
{
- float m_v[4];
+ float m_v[3];
struct
{
- float m_w;
float m_x;
float m_y;
float m_z;
@@ -49,28 +50,18 @@ private:
public:
/**
- * Creates a new quaternion.
- * \param w The w component.
+ * Creates a new 3 dimensional vector.
* \param x The x component.
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Quaternion(float w, float x, float y, float z) :
- m_w(w), m_x(x), m_y(y), m_z(z)
- {
- }
-
- /**
- * Retrieves the w component of the quarternion.
- * \return The w component.
- */
- inline const float& w() const
+ inline AUD_Vector3(float x = 0, float y = 0, float z = 0) :
+ m_x(x), m_y(y), m_z(z)
{
- return m_w;
}
/**
- * Retrieves the x component of the quarternion.
+ * Retrieves the x component of the vector.
* \return The x component.
*/
inline const float& x() const
@@ -79,7 +70,7 @@ public:
}
/**
- * Retrieves the y component of the quarternion.
+ * Retrieves the y component of the vector.
* \return The y component.
*/
inline const float& y() const
@@ -88,7 +79,7 @@ public:
}
/**
- * Retrieves the z component of the quarternion.
+ * Retrieves the z component of the vector.
* \return The z component.
*/
inline const float& z() const
@@ -98,34 +89,80 @@ public:
/**
* Retrieves the components of the vector.
- * \param destination Where the 4 float values should be saved to.
+ * \param destination Where the 3 float values should be saved to.
*/
inline void get(float* destination) const
{
- destination[0] = m_w;
- destination[1] = m_x;
- destination[2] = m_y;
- destination[3] = m_z;
+ destination[0] = m_x;
+ destination[1] = m_y;
+ destination[2] = m_z;
}
/**
* Retrieves the components of the vector.
- * \return The components as float[4].
+ * \return The components as float[3].
*/
inline const float* get() const
{
return m_v;
}
+
+ /**
+ * Retrieves the length of the vector.
+ * \return The length of the vector.
+ */
+ inline float length() const
+ {
+ return sqrt(m_x*m_x + m_y*m_y + m_z*m_z);
+ }
+
+ inline AUD_Vector3 cross(const AUD_Vector3& op) const
+ {
+ return AUD_Vector3(m_y * op.m_z - m_z * op.m_y,
+ m_z * op.m_x - m_x * op.m_z,
+ m_x * op.m_y - m_y * op.m_x);
+ }
+
+ /**
+ * Retrieves the dot product.
+ * \param op The second operand.
+ * \return The dot product of the two vectors.
+ */
+ inline float operator*(const AUD_Vector3& op) const
+ {
+ return m_x * op.m_x + m_y * op.m_y + m_z * op.m_z;
+ }
+
+ inline AUD_Vector3 operator*(const float& op) const
+ {
+ return AUD_Vector3(m_x * op, m_y * op, m_z * op);
+ }
+
+ inline AUD_Vector3 operator+(const AUD_Vector3& op) const
+ {
+ return AUD_Vector3(m_x + op.m_x, m_y + op.m_y, m_z + op.m_z);
+ }
+
+ inline AUD_Vector3 operator-(const AUD_Vector3& op) const
+ {
+ return AUD_Vector3(m_x - op.m_x, m_y - op.m_y, m_z - op.m_z);
+ }
+
+ inline AUD_Vector3 operator-() const
+ {
+ return AUD_Vector3(-m_x, -m_y, -m_z);
+ }
};
-class AUD_Vector3
+class AUD_Quaternion
{
private:
union
{
- float m_v[3];
+ float m_v[4];
struct
{
+ float m_w;
float m_x;
float m_y;
float m_z;
@@ -134,18 +171,28 @@ private:
public:
/**
- * Creates a new 3 dimensional vector.
+ * Creates a new quaternion.
+ * \param w The w component.
* \param x The x component.
* \param y The y component.
* \param z The z component.
*/
- inline AUD_Vector3(float x, float y, float z) :
- m_x(x), m_y(y), m_z(z)
+ inline AUD_Quaternion(float w = 1, float x = 0, float y = 0, float z = 0) :
+ m_w(w), m_x(x), m_y(y), m_z(z)
{
}
/**
- * Retrieves the x component of the vector.
+ * Retrieves the w component of the quarternion.
+ * \return The w component.
+ */
+ inline const float& w() const
+ {
+ return m_w;
+ }
+
+ /**
+ * Retrieves the x component of the quarternion.
* \return The x component.
*/
inline const float& x() const
@@ -154,7 +201,7 @@ public:
}
/**
- * Retrieves the y component of the vector.
+ * Retrieves the y component of the quarternion.
* \return The y component.
*/
inline const float& y() const
@@ -163,7 +210,7 @@ public:
}
/**
- * Retrieves the z component of the vector.
+ * Retrieves the z component of the quarternion.
* \return The z component.
*/
inline const float& z() const
@@ -173,23 +220,38 @@ public:
/**
* Retrieves the components of the vector.
- * \param destination Where the 3 float values should be saved to.
+ * \param destination Where the 4 float values should be saved to.
*/
inline void get(float* destination) const
{
- destination[0] = m_x;
- destination[1] = m_y;
- destination[2] = m_z;
+ destination[0] = m_w;
+ destination[1] = m_x;
+ destination[2] = m_y;
+ destination[3] = m_z;
}
/**
* Retrieves the components of the vector.
- * \return The components as float[3].
+ * \return The components as float[4].
*/
inline const float* get() const
{
return m_v;
}
+
+ inline AUD_Vector3 getLookAt() const
+ {
+ return AUD_Vector3(-2 * (m_w * m_y + m_x * m_z),
+ 2 * (m_x * m_w - m_z * m_y),
+ 2 * (m_x * m_x + m_y * m_y) - 1);
+ }
+
+ inline AUD_Vector3 getUp() const
+ {
+ return AUD_Vector3(2 * (m_x * m_y - m_w * m_z),
+ 1 - 2 * (m_x * m_x + m_z * m_z),
+ 2 * (m_w * m_x + m_y * m_z));
+ }
};
#endif //AUD_3DMATH
diff --git a/intern/audaspace/intern/AUD_Buffer.cpp b/intern/audaspace/intern/AUD_Buffer.cpp
index 37c05fd1cc0..43955b54988 100644
--- a/intern/audaspace/intern/AUD_Buffer.cpp
+++ b/intern/audaspace/intern/AUD_Buffer.cpp
@@ -74,3 +74,9 @@ void AUD_Buffer::resize(int size, bool keep)
m_size = size;
}
+
+void AUD_Buffer::assureSize(int size, bool keep)
+{
+ if(m_size < size)
+ resize(size, keep);
+}
diff --git a/intern/audaspace/intern/AUD_Buffer.h b/intern/audaspace/intern/AUD_Buffer.h
index 9b199d82fbb..4a37bc17464 100644
--- a/intern/audaspace/intern/AUD_Buffer.h
+++ b/intern/audaspace/intern/AUD_Buffer.h
@@ -80,6 +80,16 @@ public:
* the data at the end will be lost.
*/
void resize(int size, bool keep = false);
+
+ /**
+ * Makes sure the buffer has a minimum size.
+ * If size is >= current size, nothing will happen.
+ * Otherwise the buffer is resized with keep as parameter.
+ * \param size The new minimum size of the buffer, measured in bytes.
+ * \param keep Whether to keep the old data. If the new buffer is smaller,
+ * the data at the end will be lost.
+ */
+ void assureSize(int size, bool keep = false);
};
#endif //AUD_BUFFER
diff --git a/intern/audaspace/intern/AUD_BufferReader.cpp b/intern/audaspace/intern/AUD_BufferReader.cpp
index 78111ba104c..99a99069378 100644
--- a/intern/audaspace/intern/AUD_BufferReader.cpp
+++ b/intern/audaspace/intern/AUD_BufferReader.cpp
@@ -33,6 +33,8 @@
#include "AUD_Buffer.h"
#include "AUD_Space.h"
+#include <cstring>
+
AUD_BufferReader::AUD_BufferReader(AUD_Reference<AUD_Buffer> buffer,
AUD_Specs specs) :
m_position(0), m_buffer(buffer), m_specs(specs)
@@ -51,7 +53,7 @@ void AUD_BufferReader::seek(int position)
int AUD_BufferReader::getLength() const
{
- return m_buffer.get()->getSize() / AUD_SAMPLE_SIZE(m_specs);
+ return m_buffer->getSize() / AUD_SAMPLE_SIZE(m_specs);
}
int AUD_BufferReader::getPosition() const
@@ -64,17 +66,27 @@ AUD_Specs AUD_BufferReader::getSpecs() const
return m_specs;
}
-void AUD_BufferReader::read(int & length, sample_t* & buffer)
+void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer)
{
+ eos = false;
+
int sample_size = AUD_SAMPLE_SIZE(m_specs);
- buffer = m_buffer.get()->getBuffer() + m_position * m_specs.channels;
+ sample_t* buf = m_buffer->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->getSize() < (m_position + length) * sample_size)
+ {
+ length = m_buffer->getSize() / sample_size - m_position;
+ eos = true;
+ }
if(length < 0)
+ {
length = 0;
+ return;
+ }
+
m_position += length;
+ memcpy(buffer, buf, length * sample_size);
}
diff --git a/intern/audaspace/intern/AUD_BufferReader.h b/intern/audaspace/intern/AUD_BufferReader.h
index 3369672703c..5ba6c503855 100644
--- a/intern/audaspace/intern/AUD_BufferReader.h
+++ b/intern/audaspace/intern/AUD_BufferReader.h
@@ -76,7 +76,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_BUFFERREADER
diff --git a/intern/audaspace/intern/AUD_C-API.cpp b/intern/audaspace/intern/AUD_C-API.cpp
index 0119bb105d8..db76b9b4faf 100644
--- a/intern/audaspace/intern/AUD_C-API.cpp
+++ b/intern/audaspace/intern/AUD_C-API.cpp
@@ -37,9 +37,6 @@
#ifdef WITH_PYTHON
#include "AUD_PyInit.h"
#include "AUD_PyAPI.h"
-
-Device* g_device;
-bool g_pyinitialized = false;
#endif
#include <cstdlib>
@@ -48,6 +45,7 @@ bool g_pyinitialized = false;
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_FileFactory.h"
#include "AUD_StreamBufferFactory.h"
#include "AUD_DelayFactory.h"
@@ -90,9 +88,10 @@ extern "C" {
#include <cassert>
-typedef AUD_IFactory AUD_Sound;
-typedef AUD_ReadDevice AUD_Device;
-typedef AUD_Handle AUD_Channel;
+typedef AUD_Reference<AUD_IFactory> AUD_Sound;
+typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
+typedef AUD_Reference<AUD_IHandle> AUD_Handle;
+typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
#define AUD_CAPI_IMPLEMENTATION
#include "AUD_C-API.h"
@@ -101,8 +100,8 @@ typedef AUD_Handle AUD_Channel;
#define NULL 0
#endif
-static AUD_IDevice* AUD_device = NULL;
-static AUD_I3DDevice* AUD_3ddevice = NULL;
+static AUD_Reference<AUD_IDevice> AUD_device;
+static AUD_I3DDevice* AUD_3ddevice;
void AUD_initOnce()
{
@@ -113,9 +112,9 @@ void AUD_initOnce()
int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
{
- AUD_IDevice* dev = NULL;
+ AUD_Reference<AUD_IDevice> dev = NULL;
- if(AUD_device)
+ if(!AUD_device.isNull())
AUD_exit();
try
@@ -145,18 +144,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
}
AUD_device = dev;
- AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
-
-#ifdef WITH_PYTHON
- if(g_pyinitialized)
- {
- g_device = (Device*)Device_empty();
- if(g_device != NULL)
- {
- g_device->device = dev;
- }
- }
-#endif
+ AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device.get());
return true;
}
@@ -168,16 +156,6 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
void AUD_exit()
{
-#ifdef WITH_PYTHON
- if(g_device)
- {
- Py_XDECREF(g_device);
- g_device = NULL;
- }
- else
-#endif
- if(AUD_device)
- delete AUD_device;
AUD_device = NULL;
AUD_3ddevice = NULL;
}
@@ -185,11 +163,16 @@ void AUD_exit()
#ifdef WITH_PYTHON
static PyObject* AUD_getCDevice(PyObject* self)
{
- if(g_device)
+ if(!AUD_device.isNull())
{
- Py_INCREF(g_device);
- return (PyObject*)g_device;
+ Device* device = (Device*)Device_empty();
+ if(device != NULL)
+ {
+ device->device = new AUD_Reference<AUD_IDevice>(AUD_device);
+ return (PyObject*)device;
+ }
}
+
Py_RETURN_NONE;
}
@@ -199,34 +182,87 @@ static PyMethodDef meth_getcdevice[] = {{ "device", (PyCFunction)AUD_getCDevice,
":return: The application's :class:`Device`.\n"
":rtype: :class:`Device`"}};
+extern "C" {
+extern void* sound_get_factory(void* sound);
+}
+
+static PyObject* AUD_getSoundFromPointer(PyObject* self, PyObject* args)
+{
+ long int lptr;
+
+ if(PyArg_Parse(args, "l:_sound_from_pointer", &lptr))
+ {
+ if(lptr)
+ {
+ AUD_Reference<AUD_IFactory>* factory = (AUD_Reference<AUD_IFactory>*) sound_get_factory((void*) lptr);
+
+ if(factory)
+ {
+ Factory* obj = (Factory*) Factory_empty();
+ if(obj)
+ {
+ obj->factory = new AUD_Reference<AUD_IFactory>(*factory);
+ return (PyObject*) obj;
+ }
+ }
+ }
+ }
+
+ Py_RETURN_NONE;
+}
+
+static PyMethodDef meth_sound_from_pointer[] = {{ "_sound_from_pointer", (PyCFunction)AUD_getSoundFromPointer, METH_O,
+ "_sound_from_pointer(pointer)\n\n"
+ "Returns the corresponding :class:`Factory` object.\n\n"
+ ":arg pointer: The pointer to the bSound object as long.\n"
+ ":type pointer: long\n"
+ ":return: The corresponding :class:`Factory` object.\n"
+ ":rtype: :class:`Factory`"}};
+
PyObject* AUD_initPython()
{
PyObject* module = PyInit_aud();
- PyModule_AddObject(module, "device", (PyObject *)PyCFunction_New(meth_getcdevice, NULL));
+ PyModule_AddObject(module, "device", (PyObject*)PyCFunction_New(meth_getcdevice, NULL));
+ PyModule_AddObject(module, "_sound_from_pointer", (PyObject*)PyCFunction_New(meth_sound_from_pointer, NULL));
PyDict_SetItemString(PyImport_GetModuleDict(), "aud", module);
- if(AUD_device)
+
+ return module;
+}
+
+PyObject* AUD_getPythonFactory(AUD_Sound* sound)
+{
+ if(sound)
{
- g_device = (Device*)Device_empty();
- if(g_device != NULL)
+ Factory* obj = (Factory*) Factory_empty();
+ if(obj)
{
- g_device->device = AUD_device;
+ obj->factory = new AUD_Reference<AUD_IFactory>(*sound);
+ return (PyObject*) obj;
}
}
- g_pyinitialized = true;
- return module;
+ return NULL;
+}
+
+AUD_Sound* AUD_getPythonSound(PyObject* sound)
+{
+ Factory* factory = checkFactory(sound);
+
+ if(!factory)
+ return NULL;
+
+ return new AUD_Reference<AUD_IFactory>(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(factory->factory));
}
+
#endif
void AUD_lock()
{
- assert(AUD_device);
AUD_device->lock();
}
void AUD_unlock()
{
- assert(AUD_device);
AUD_device->unlock();
}
@@ -241,13 +277,12 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
try
{
- AUD_IReader* reader = sound->createReader();
+ AUD_Reference<AUD_IReader> reader = (*sound)->createReader();
- if(reader)
+ if(!reader.isNull())
{
info.specs = reader->getSpecs();
info.length = reader->getLength() / (float) info.specs.rate;
- delete reader;
}
}
catch(AUD_Exception&)
@@ -260,13 +295,13 @@ AUD_SoundInfo AUD_getInfo(AUD_Sound* sound)
AUD_Sound* AUD_load(const char* filename)
{
assert(filename);
- return new AUD_FileFactory(filename);
+ return new AUD_Sound(new AUD_FileFactory(filename));
}
AUD_Sound* AUD_loadBuffer(unsigned char* buffer, int size)
{
assert(buffer);
- return new AUD_FileFactory(buffer, size);
+ return new AUD_Sound(new AUD_FileFactory(buffer, size));
}
AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
@@ -275,7 +310,7 @@ AUD_Sound* AUD_bufferSound(AUD_Sound* sound)
try
{
- return new AUD_StreamBufferFactory(sound);
+ return new AUD_Sound(new AUD_StreamBufferFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -289,7 +324,7 @@ AUD_Sound* AUD_delaySound(AUD_Sound* sound, float delay)
try
{
- return new AUD_DelayFactory(sound, delay);
+ return new AUD_Sound(new AUD_DelayFactory(*sound, delay));
}
catch(AUD_Exception&)
{
@@ -303,7 +338,7 @@ AUD_Sound* AUD_limitSound(AUD_Sound* sound, float start, float end)
try
{
- return new AUD_LimiterFactory(sound, start, end);
+ return new AUD_Sound(new AUD_LimiterFactory(*sound, start, end));
}
catch(AUD_Exception&)
{
@@ -317,7 +352,7 @@ AUD_Sound* AUD_pingpongSound(AUD_Sound* sound)
try
{
- return new AUD_PingPongFactory(sound);
+ return new AUD_Sound(new AUD_PingPongFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -331,7 +366,7 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
try
{
- return new AUD_LoopFactory(sound);
+ return new AUD_Sound(new AUD_LoopFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -339,18 +374,18 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
}
}
-int AUD_setLoop(AUD_Channel* handle, int loops)
+int AUD_setLoop(AUD_Handle* handle, int loops)
{
- if(handle)
+ assert(handle);
+
+ try
+ {
+ return (*handle)->setLoopCount(loops);
+ }
+ catch(AUD_Exception&)
{
- try
- {
- return AUD_device->setLoopCount(handle, loops);
- }
- catch(AUD_Exception&)
- {
- }
}
+
return false;
}
@@ -360,7 +395,7 @@ AUD_Sound* AUD_rectifySound(AUD_Sound* sound)
try
{
- return new AUD_RectifyFactory(sound);
+ return new AUD_Sound(new AUD_RectifyFactory(*sound));
}
catch(AUD_Exception&)
{
@@ -374,67 +409,67 @@ void AUD_unload(AUD_Sound* sound)
delete sound;
}
-AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
+AUD_Handle* AUD_play(AUD_Sound* sound, int keep)
{
- assert(AUD_device);
assert(sound);
try
{
- return AUD_device->play(sound, keep);
+ AUD_Handle handle = AUD_device->play(*sound, keep);
+ if(!handle.isNull())
+ return new AUD_Handle(handle);
}
catch(AUD_Exception&)
{
- return NULL;
}
+ return NULL;
}
-int AUD_pause(AUD_Channel* handle)
+int AUD_pause(AUD_Handle* handle)
{
- assert(AUD_device);
- return AUD_device->pause(handle);
+ assert(handle);
+ return (*handle)->pause();
}
-int AUD_resume(AUD_Channel* handle)
+int AUD_resume(AUD_Handle* handle)
{
- assert(AUD_device);
- return AUD_device->resume(handle);
+ assert(handle);
+ return (*handle)->resume();
}
-int AUD_stop(AUD_Channel* handle)
+int AUD_stop(AUD_Handle* handle)
{
- if(AUD_device)
- return AUD_device->stop(handle);
- return false;
+ assert(handle);
+ int result = (*handle)->stop();
+ delete handle;
+ return result;
}
-int AUD_setKeep(AUD_Channel* handle, int keep)
+int AUD_setKeep(AUD_Handle* handle, int keep)
{
- assert(AUD_device);
- return AUD_device->setKeep(handle, keep);
+ assert(handle);
+ return (*handle)->setKeep(keep);
}
-int AUD_seek(AUD_Channel* handle, float seekTo)
+int AUD_seek(AUD_Handle* handle, float seekTo)
{
- assert(AUD_device);
- return AUD_device->seek(handle, seekTo);
+ assert(handle);
+ return (*handle)->seek(seekTo);
}
-float AUD_getPosition(AUD_Channel* handle)
+float AUD_getPosition(AUD_Handle* handle)
{
- assert(AUD_device);
- return AUD_device->getPosition(handle);
+ assert(handle);
+ return (*handle)->getPosition();
}
-AUD_Status AUD_getStatus(AUD_Channel* handle)
+AUD_Status AUD_getStatus(AUD_Handle* handle)
{
- assert(AUD_device);
- return AUD_device->getStatus(handle);
+ assert(handle);
+ return (*handle)->getStatus();
}
int AUD_setListenerLocation(const float* location)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(location[0], location[1], location[2]);
@@ -447,8 +482,6 @@ int AUD_setListenerLocation(const float* location)
int AUD_setListenerVelocity(const float* velocity)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
@@ -461,8 +494,6 @@ int AUD_setListenerVelocity(const float* velocity)
int AUD_setListenerOrientation(const float* orientation)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
@@ -475,8 +506,6 @@ int AUD_setListenerOrientation(const float* orientation)
int AUD_setSpeedOfSound(float speed)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setSpeedOfSound(speed);
@@ -488,8 +517,6 @@ int AUD_setSpeedOfSound(float speed)
int AUD_setDopplerFactor(float factor)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setDopplerFactor(factor);
@@ -501,8 +528,6 @@ int AUD_setDopplerFactor(float factor)
int AUD_setDistanceModel(AUD_DistanceModel model)
{
- assert(AUD_device);
-
if(AUD_3ddevice)
{
AUD_3ddevice->setDistanceModel(model);
@@ -512,180 +537,184 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
return false;
}
-int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
+int AUD_setSourceLocation(AUD_Handle* handle, const float* location)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
AUD_Vector3 v(location[0], location[1], location[2]);
- return AUD_3ddevice->setSourceLocation(handle, v);
+ return h->setSourceLocation(v);
}
return false;
}
-int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
+int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
- return AUD_3ddevice->setSourceVelocity(handle, v);
+ return h->setSourceVelocity(v);
}
return false;
}
-int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
+int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
- return AUD_3ddevice->setSourceOrientation(handle, q);
+ return h->setSourceOrientation(q);
}
return false;
}
-int AUD_setRelative(AUD_Channel* handle, int relative)
+int AUD_setRelative(AUD_Handle* handle, int relative)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setRelative(handle, relative);
+ return h->setRelative(relative);
}
return false;
}
-int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
+int AUD_setVolumeMaximum(AUD_Handle* handle, float volume)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setVolumeMaximum(handle, volume);
+ return h->setVolumeMaximum(volume);
}
return false;
}
-int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
+int AUD_setVolumeMinimum(AUD_Handle* handle, float volume)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setVolumeMinimum(handle, volume);
+ return h->setVolumeMinimum(volume);
}
return false;
}
-int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
+int AUD_setDistanceMaximum(AUD_Handle* handle, float distance)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setDistanceMaximum(handle, distance);
+ return h->setDistanceMaximum(distance);
}
return false;
}
-int AUD_setDistanceReference(AUD_Channel* handle, float distance)
+int AUD_setDistanceReference(AUD_Handle* handle, float distance)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setDistanceReference(handle, distance);
+ return h->setDistanceReference(distance);
}
return false;
}
-int AUD_setAttenuation(AUD_Channel* handle, float factor)
+int AUD_setAttenuation(AUD_Handle* handle, float factor)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setAttenuation(handle, factor);
+ return h->setAttenuation(factor);
}
return false;
}
-int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
+int AUD_setConeAngleOuter(AUD_Handle* handle, float angle)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeAngleOuter(handle, angle);
+ return h->setConeAngleOuter(angle);
}
return false;
}
-int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
+int AUD_setConeAngleInner(AUD_Handle* handle, float angle)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeAngleInner(handle, angle);
+ return h->setConeAngleInner(angle);
}
return false;
}
-int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
+int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume)
{
- assert(AUD_device);
+ assert(handle);
+ AUD_Reference<AUD_I3DHandle> h(*handle);
- if(AUD_3ddevice)
+ if(!h.isNull())
{
- return AUD_3ddevice->setConeVolumeOuter(handle, volume);
+ return h->setConeVolumeOuter(volume);
}
return false;
}
-int AUD_setSoundVolume(AUD_Channel* handle, float volume)
+int AUD_setSoundVolume(AUD_Handle* handle, float volume)
{
- if(handle)
+ assert(handle);
+ try
{
- assert(AUD_device);
-
- try
- {
- return AUD_device->setVolume(handle, volume);
- }
- catch(AUD_Exception&) {}
+ return (*handle)->setVolume(volume);
}
+ catch(AUD_Exception&) {}
return false;
}
-int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
+int AUD_setSoundPitch(AUD_Handle* handle, float pitch)
{
- if(handle)
+ assert(handle);
+ try
{
- assert(AUD_device);
-
- try
- {
- return AUD_device->setPitch(handle, pitch);
- }
- catch(AUD_Exception&) {}
+ return (*handle)->setPitch(pitch);
}
+ catch(AUD_Exception&) {}
return false;
}
@@ -693,7 +722,7 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
{
try
{
- return new AUD_ReadDevice(specs);
+ return new AUD_Device(new AUD_ReadDevice(specs));
}
catch(AUD_Exception&)
{
@@ -701,21 +730,24 @@ AUD_Device* AUD_openReadDevice(AUD_DeviceSpecs specs)
}
}
-AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
+AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
{
assert(device);
assert(sound);
try
{
- AUD_Channel* handle = device->play(sound);
- device->seek(handle, seek);
- return handle;
+ AUD_Handle handle = (*device)->play(*sound);
+ if(!handle.isNull())
+ {
+ handle->seek(seek);
+ return new AUD_Handle(handle);
+ }
}
catch(AUD_Exception&)
{
- return NULL;
}
+ return NULL;
}
int AUD_setDeviceVolume(AUD_Device* device, float volume)
@@ -724,7 +756,7 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
try
{
- device->setVolume(volume);
+ (*device)->setVolume(volume);
return true;
}
catch(AUD_Exception&) {}
@@ -732,22 +764,6 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
return false;
}
-int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
- float volume)
-{
- if(handle)
- {
- assert(device);
-
- try
- {
- return device->setVolume(handle, volume);
- }
- catch(AUD_Exception&) {}
- }
- return false;
-}
-
int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
{
assert(device);
@@ -755,7 +771,7 @@ int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
try
{
- return device->read(buffer, length);
+ return (*device)->read(buffer, length);
}
catch(AUD_Exception&)
{
@@ -779,58 +795,52 @@ void AUD_closeReadDevice(AUD_Device* device)
float* AUD_readSoundBuffer(const char* filename, float low, float high,
float attack, float release, float threshold,
int accumulate, int additive, int square,
- float sthreshold, int samplerate, int* length)
+ float sthreshold, double samplerate, int* length)
{
AUD_Buffer buffer;
AUD_DeviceSpecs specs;
specs.channels = AUD_CHANNELS_MONO;
specs.rate = (AUD_SampleRate)samplerate;
- AUD_Sound* sound;
+ AUD_Reference<AUD_IFactory> sound;
- AUD_FileFactory file(filename);
+ AUD_Reference<AUD_IFactory> file = new AUD_FileFactory(filename);
- AUD_IReader* reader = file.createReader();
+ AUD_Reference<AUD_IReader> reader = file->createReader();
AUD_SampleRate rate = reader->getSpecs().rate;
- delete reader;
- AUD_ChannelMapperFactory mapper(&file, specs);
- sound = &mapper;
- AUD_LowpassFactory lowpass(sound, high);
+ sound = new AUD_ChannelMapperFactory(file, specs);
+
if(high < rate)
- sound = &lowpass;
- AUD_HighpassFactory highpass(sound, low);
+ sound = new AUD_LowpassFactory(sound, high);
if(low > 0)
- sound = &highpass;
- AUD_EnvelopeFactory envelope(sound, attack, release, threshold, 0.1f);
- AUD_LinearResampleFactory resampler(&envelope, specs);
- sound = &resampler;
- AUD_SquareFactory squaref(sound, sthreshold);
+ sound = new AUD_HighpassFactory(sound, low);;
+
+ sound = new AUD_EnvelopeFactory(sound, attack, release, threshold, 0.1f);
+ sound = new AUD_LinearResampleFactory(sound, specs);
+
if(square)
- sound = &squaref;
- AUD_AccumulatorFactory accumulator(sound, additive);
- AUD_SumFactory sum(sound);
+ sound = new AUD_SquareFactory(sound, sthreshold);
+
if(accumulate)
- sound = &accumulator;
+ sound = new AUD_AccumulatorFactory(sound, additive);
else if(additive)
- sound = &sum;
+ sound = new AUD_SumFactory(sound);
reader = sound->createReader();
- if(reader == NULL)
+ if(reader.isNull())
return NULL;
int len;
int position = 0;
- sample_t* readbuffer;
+ bool eos;
do
{
len = samplerate;
buffer.resize((position + len) * sizeof(float), true);
- reader->read(len, readbuffer);
- memcpy(buffer.getBuffer() + position, readbuffer, len * sizeof(float));
+ reader->read(len, eos, buffer.getBuffer() + position);
position += len;
- } while(len != 0);
- delete reader;
+ } while(!eos);
float* result = (float*)malloc(position * sizeof(float));
memcpy(result, buffer.getBuffer(), position * sizeof(float));
@@ -838,100 +848,121 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
return result;
}
-static void pauseSound(AUD_Channel* handle)
+static void pauseSound(AUD_Handle* handle)
{
- assert(AUD_device);
-
- AUD_device->pause(handle);
+ assert(handle);
+ (*handle)->pause();
}
-AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
+AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds)
{
- assert(AUD_device);
+ AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
+ AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
- AUD_SilenceFactory silence;
- AUD_LimiterFactory limiter(&silence, 0, seconds);
+ AUD_device->lock();
try
{
- AUD_Channel* channel = AUD_device->play(&limiter);
- AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
- return channel;
+ AUD_Handle handle2 = AUD_device->play(limiter);
+ if(!handle2.isNull())
+ {
+ handle2->setStopCallback((stopCallback)pauseSound, handle);
+ AUD_device->unlock();
+ return new AUD_Handle(handle2);
+ }
}
catch(AUD_Exception&)
{
- return NULL;
}
+
+ AUD_device->unlock();
+
+ return NULL;
}
AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume)
{
-/* AUD_XXX should be this: but AUD_createSequencer is called before the device
- * is initialized.
-
- return new AUD_SequencerFactory(AUD_device->getSpecs().specs, data, volume);
-*/
+ // specs are changed at a later point!
AUD_Specs specs;
specs.channels = AUD_CHANNELS_STEREO;
specs.rate = AUD_RATE_44100;
- return new AUD_SequencerFactory(specs, muted, data, volume);
+ AUD_Reference<AUD_SequencerFactory>* sequencer = new AUD_Reference<AUD_SequencerFactory>(new AUD_SequencerFactory(specs, muted, data, volume));
+ return reinterpret_cast<AUD_Sound*>(sequencer);
}
void AUD_destroySequencer(AUD_Sound* sequencer)
{
- delete ((AUD_SequencerFactory*)sequencer);
+ delete sequencer;
}
void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted)
{
- ((AUD_SequencerFactory*)sequencer)->mute(muted);
+ ((AUD_SequencerFactory*)sequencer->get())->mute(muted);
}
-AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
+AUD_Reference<AUD_SequencerEntry>* AUD_addSequencer(AUD_Sound* sequencer, AUD_Sound** sound,
float begin, float end, float skip, void* data)
{
- return ((AUD_SequencerFactory*)sequencer)->add((AUD_IFactory**) sound, begin, end, skip, data);
+ return new AUD_Reference<AUD_SequencerEntry>(((AUD_SequencerFactory*)sequencer->get())->add(sound, begin, end, skip, data));
}
-void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry)
+void AUD_removeSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry)
{
- ((AUD_SequencerFactory*)sequencer)->remove(entry);
+ ((AUD_SequencerFactory*)sequencer->get())->remove(*entry);
+ delete entry;
}
-void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+void AUD_moveSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry,
float begin, float end, float skip)
{
- ((AUD_SequencerFactory*)sequencer)->move(entry, begin, end, skip);
+ ((AUD_SequencerFactory*)sequencer->get())->move(*entry, begin, end, skip);
+}
+
+void AUD_muteSequencer(AUD_Sound* sequencer, AUD_Reference<AUD_SequencerEntry>* entry, char mute)
+{
+ ((AUD_SequencerFactory*)sequencer->get())->mute(*entry, mute);
+}
+
+void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer)
+{
+ ((AUD_SequencerFactory*)sequencer->get())->setSpecs(AUD_device->getSpecs().specs);
}
-void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry, char mute)
+void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs)
{
- ((AUD_SequencerFactory*)sequencer)->mute(entry, mute);
+ ((AUD_SequencerFactory*)sequencer->get())->setSpecs(specs);
}
int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
{
AUD_DeviceSpecs specs;
sample_t* buf;
+ AUD_Buffer aBuffer;
specs.rate = AUD_RATE_INVALID;
specs.channels = AUD_CHANNELS_MONO;
specs.format = AUD_FORMAT_INVALID;
- AUD_ChannelMapperFactory mapper(sound, specs);
-
- AUD_IReader* reader = mapper.createReader();
+ AUD_Reference<AUD_IReader> reader = AUD_ChannelMapperFactory(*sound, specs).createReader();
int len = reader->getLength();
float samplejump = (float)len / (float)length;
float min, max;
+ bool eos;
for(int i = 0; i < length; i++)
{
len = floor(samplejump * (i+1)) - floor(samplejump * i);
- reader->read(len, buf);
- if(len < 1)
+ if(aBuffer.getSize() < len * AUD_SAMPLE_SIZE(reader->getSpecs()))
+ {
+ aBuffer.resize(len * AUD_SAMPLE_SIZE(reader->getSpecs()));
+ buf = aBuffer.getBuffer();
+ }
+
+ reader->read(len, eos, buf);
+
+ if(eos)
{
length = i;
break;
@@ -949,15 +980,13 @@ int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length)
}
}
- delete reader;
-
return length;
}
void AUD_startPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->startPlayback();
#endif
@@ -966,42 +995,44 @@ void AUD_startPlayback()
void AUD_stopPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->stopPlayback();
#endif
}
-void AUD_seekSequencer(AUD_Channel* handle, float time)
+void AUD_seekSequencer(AUD_Handle* handle, float time)
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->seekPlayback(time);
else
#endif
{
- AUD_device->seek(handle, time);
+ assert(handle);
+ (*handle)->seek(time);
}
}
-float AUD_getSequencerPosition(AUD_Channel* handle)
+float AUD_getSequencerPosition(AUD_Handle* handle)
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
return device->getPlaybackPosition();
else
#endif
{
- return AUD_device->getPosition(handle);
+ assert(handle);
+ return (*handle)->getPosition();
}
}
#ifdef WITH_JACK
void AUD_setSyncCallback(AUD_syncFunction function, void* data)
{
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
device->setSyncCallback(function, data);
}
@@ -1010,9 +1041,19 @@ void AUD_setSyncCallback(AUD_syncFunction function, void* data)
int AUD_doesPlayback()
{
#ifdef WITH_JACK
- AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device);
+ AUD_JackDevice* device = dynamic_cast<AUD_JackDevice*>(AUD_device.get());
if(device)
return device->doesPlayback();
#endif
return -1;
}
+
+AUD_Sound* AUD_copy(AUD_Sound* sound)
+{
+ return new AUD_Reference<AUD_IFactory>(*sound);
+}
+
+void AUD_freeHandle(AUD_Handle* handle)
+{
+ delete handle;
+}
diff --git a/intern/audaspace/intern/AUD_C-API.h b/intern/audaspace/intern/AUD_C-API.h
index b2242f09547..72d423e847b 100644
--- a/intern/audaspace/intern/AUD_C-API.h
+++ b/intern/audaspace/intern/AUD_C-API.h
@@ -31,6 +31,10 @@
#ifndef AUD_CAPI
#define AUD_CAPI
+#ifdef WITH_PYTHON
+#include "Python.h"
+#endif
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -53,9 +57,9 @@ typedef struct
#ifndef AUD_CAPI_IMPLEMENTATION
typedef void AUD_Sound;
- typedef void AUD_Channel;
+ typedef void AUD_Handle;
typedef void AUD_Device;
- typedef void AUD_SequencerEntry;
+ typedef void AUD_SEntry;
typedef float (*AUD_volumeFunction)(void*, void*, float);
typedef void (*AUD_syncFunction)(void*, int, float);
#endif
@@ -155,7 +159,7 @@ extern AUD_Sound* AUD_loopSound(AUD_Sound* sound);
* \param loops The count of remaining loops, -1 for infinity.
* \return Whether the handle is valid.
*/
-extern int AUD_setLoop(AUD_Channel* handle, int loops);
+extern int AUD_setLoop(AUD_Handle* handle, int loops);
/**
* Rectifies a sound.
@@ -177,28 +181,28 @@ extern void AUD_unload(AUD_Sound* sound);
* paused when its end has been reached.
* \return A handle to the played back sound.
*/
-extern AUD_Channel* AUD_play(AUD_Sound* sound, int keep);
+extern AUD_Handle* AUD_play(AUD_Sound* sound, int keep);
/**
* Pauses a played back sound.
* \param handle The handle to the sound.
* \return Whether the handle has been playing or not.
*/
-extern int AUD_pause(AUD_Channel* handle);
+extern int AUD_pause(AUD_Handle* handle);
/**
* Resumes a paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been paused or not.
*/
-extern int AUD_resume(AUD_Channel* handle);
+extern int AUD_resume(AUD_Handle* handle);
/**
* Stops a playing or paused sound.
* \param handle The handle to the sound.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_stop(AUD_Channel* handle);
+extern int AUD_stop(AUD_Handle* handle);
/**
* Sets the end behaviour of a playing or paused sound.
@@ -207,7 +211,7 @@ extern int AUD_stop(AUD_Channel* handle);
* paused when its end has been reached.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_setKeep(AUD_Channel* handle, int keep);
+extern int AUD_setKeep(AUD_Handle* handle, int keep);
/**
* Seeks a playing or paused sound.
@@ -215,7 +219,7 @@ extern int AUD_setKeep(AUD_Channel* handle, int keep);
* \param seekTo From where the sound file should be played back in seconds.
* \return Whether the handle has been valid or not.
*/
-extern int AUD_seek(AUD_Channel* handle, float seekTo);
+extern int AUD_seek(AUD_Handle* handle, float seekTo);
/**
* Retrieves the playback position of a handle.
@@ -223,14 +227,14 @@ extern int AUD_seek(AUD_Channel* handle, float seekTo);
* \return The current playback position in seconds or 0.0 if the handle is
* invalid.
*/
-extern float AUD_getPosition(AUD_Channel* handle);
+extern float AUD_getPosition(AUD_Handle* handle);
/**
* Returns the status of a playing, paused or stopped sound.
* \param handle The handle to the sound.
* \return The status of the sound behind the handle.
*/
-extern AUD_Status AUD_getStatus(AUD_Channel* handle);
+extern AUD_Status AUD_getStatus(AUD_Handle* handle);
/**
* Sets the listener location.
@@ -277,7 +281,7 @@ extern int AUD_setDistanceModel(AUD_DistanceModel model);
* \param location The new location.
* \return Whether the action succeeded.
*/
-extern int AUD_setSourceLocation(AUD_Channel* handle, const float* location);
+extern int AUD_setSourceLocation(AUD_Handle* handle, const float* location);
/**
* Sets the velocity of a source.
@@ -285,7 +289,7 @@ extern int AUD_setSourceLocation(AUD_Channel* handle, const float* location);
* \param velocity The new velocity.
* \return Whether the action succeeded.
*/
-extern int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity);
+extern int AUD_setSourceVelocity(AUD_Handle* handle, const float* velocity);
/**
* Sets the orientation of a source.
@@ -293,7 +297,7 @@ extern int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity);
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
*/
-extern int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation);
+extern int AUD_setSourceOrientation(AUD_Handle* handle, const float* orientation);
/**
* Sets whether the source location, velocity and orientation are relative
@@ -302,7 +306,7 @@ extern int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientatio
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
*/
-extern int AUD_setRelative(AUD_Channel* handle, int relative);
+extern int AUD_setRelative(AUD_Handle* handle, int relative);
/**
* Sets the maximum volume of a source.
@@ -310,7 +314,7 @@ extern int AUD_setRelative(AUD_Channel* handle, int relative);
* \param volume The new maximum volume.
* \return Whether the action succeeded.
*/
-extern int AUD_setVolumeMaximum(AUD_Channel* handle, float volume);
+extern int AUD_setVolumeMaximum(AUD_Handle* handle, float volume);
/**
* Sets the minimum volume of a source.
@@ -318,7 +322,7 @@ extern int AUD_setVolumeMaximum(AUD_Channel* handle, float volume);
* \param volume The new minimum volume.
* \return Whether the action succeeded.
*/
-extern int AUD_setVolumeMinimum(AUD_Channel* handle, float volume);
+extern int AUD_setVolumeMinimum(AUD_Handle* handle, float volume);
/**
* Sets the maximum distance of a source.
@@ -328,7 +332,7 @@ extern int AUD_setVolumeMinimum(AUD_Channel* handle, float volume);
* \param distance The new maximum distance.
* \return Whether the action succeeded.
*/
-extern int AUD_setDistanceMaximum(AUD_Channel* handle, float distance);
+extern int AUD_setDistanceMaximum(AUD_Handle* handle, float distance);
/**
* Sets the reference distance of a source.
@@ -336,7 +340,7 @@ extern int AUD_setDistanceMaximum(AUD_Channel* handle, float distance);
* \param distance The new reference distance.
* \return Whether the action succeeded.
*/
-extern int AUD_setDistanceReference(AUD_Channel* handle, float distance);
+extern int AUD_setDistanceReference(AUD_Handle* handle, float distance);
/**
* Sets the attenuation of a source.
@@ -345,7 +349,7 @@ extern int AUD_setDistanceReference(AUD_Channel* handle, float distance);
* \param factor The new attenuation.
* \return Whether the action succeeded.
*/
-extern int AUD_setAttenuation(AUD_Channel* handle, float factor);
+extern int AUD_setAttenuation(AUD_Handle* handle, float factor);
/**
* Sets the outer angle of the cone of a source.
@@ -353,7 +357,7 @@ extern int AUD_setAttenuation(AUD_Channel* handle, float factor);
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
*/
-extern int AUD_setConeAngleOuter(AUD_Channel* handle, float angle);
+extern int AUD_setConeAngleOuter(AUD_Handle* handle, float angle);
/**
* Sets the inner angle of the cone of a source.
@@ -361,7 +365,7 @@ extern int AUD_setConeAngleOuter(AUD_Channel* handle, float angle);
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
*/
-extern int AUD_setConeAngleInner(AUD_Channel* handle, float angle);
+extern int AUD_setConeAngleInner(AUD_Handle* handle, float angle);
/**
* Sets the outer volume of the cone of a source.
@@ -371,7 +375,7 @@ extern int AUD_setConeAngleInner(AUD_Channel* handle, float angle);
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
*/
-extern int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume);
+extern int AUD_setConeVolumeOuter(AUD_Handle* handle, float volume);
/**
* Sets the volume of a played back sound.
@@ -379,7 +383,7 @@ extern int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume);
* \param volume The new volume, must be between 0.0 and 1.0.
* \return Whether the action succeeded.
*/
-extern int AUD_setSoundVolume(AUD_Channel* handle, float volume);
+extern int AUD_setSoundVolume(AUD_Handle* handle, float volume);
/**
* Sets the pitch of a played back sound.
@@ -387,7 +391,7 @@ extern int AUD_setSoundVolume(AUD_Channel* handle, float volume);
* \param pitch The new pitch.
* \return Whether the action succeeded.
*/
-extern int AUD_setSoundPitch(AUD_Channel* handle, float pitch);
+extern int AUD_setSoundPitch(AUD_Handle* handle, float pitch);
/**
* Opens a read device, with which audio data can be read.
@@ -411,18 +415,7 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
* \param seek The position where the sound should be seeked to.
* \return A handle to the played back sound.
*/
-extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
-
-/**
- * Sets the volume of a played back sound of a read device.
- * \param device The read device.
- * \param handle The handle to the sound.
- * \param volume The new volume, must be between 0.0 and 1.0.
- * \return Whether the action succeeded.
- */
-extern int AUD_setDeviceSoundVolume(AUD_Device* device,
- AUD_Channel* handle,
- float volume);
+extern AUD_Handle* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
/**
* Reads the next samples into the supplied buffer.
@@ -448,7 +441,7 @@ extern void AUD_closeReadDevice(AUD_Device* device);
extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
float attack, float release, float threshold,
int accumulate, int additive, int square,
- float sthreshold, int samplerate,
+ float sthreshold, double samplerate,
int* length);
/**
@@ -457,7 +450,7 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
* \param time The time in seconds.
* \return The silence handle.
*/
-extern AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds);
+extern AUD_Handle* AUD_pauseAfter(AUD_Handle* handle, float seconds);
extern AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume);
@@ -465,26 +458,30 @@ extern void AUD_destroySequencer(AUD_Sound* sequencer);
extern void AUD_setSequencerMuted(AUD_Sound* sequencer, int muted);
-extern AUD_SequencerEntry* AUD_addSequencer(AUD_Sound** sequencer, AUD_Sound* sound,
+extern AUD_SEntry* AUD_addSequencer(AUD_Sound* sequencer, AUD_Sound** sound,
float begin, float end, float skip, void* data);
-extern void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry);
+extern void AUD_removeSequencer(AUD_Sound* sequencer, AUD_SEntry* entry);
-extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+extern void AUD_moveSequencer(AUD_Sound* sequencer, AUD_SEntry* entry,
float begin, float end, float skip);
-extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SequencerEntry* entry,
+extern void AUD_muteSequencer(AUD_Sound* sequencer, AUD_SEntry* entry,
char mute);
+extern void AUD_setSequencerDeviceSpecs(AUD_Sound* sequencer);
+
+extern void AUD_setSequencerSpecs(AUD_Sound* sequencer, AUD_Specs specs);
+
extern int AUD_readSound(AUD_Sound* sound, sample_t* buffer, int length);
extern void AUD_startPlayback(void);
extern void AUD_stopPlayback(void);
-extern void AUD_seekSequencer(AUD_Channel* handle, float time);
+extern void AUD_seekSequencer(AUD_Handle* handle, float time);
-extern float AUD_getSequencerPosition(AUD_Channel* handle);
+extern float AUD_getSequencerPosition(AUD_Handle* handle);
#ifdef WITH_JACK
extern void AUD_setSyncCallback(AUD_syncFunction function, void* data);
@@ -492,6 +489,16 @@ extern void AUD_setSyncCallback(AUD_syncFunction function, void* data);
extern int AUD_doesPlayback(void);
+extern AUD_Sound* AUD_copy(AUD_Sound* sound);
+
+extern void AUD_freeHandle(AUD_Handle* channel);
+
+#ifdef WITH_PYTHON
+extern PyObject* AUD_getPythonFactory(AUD_Sound* sound);
+
+extern AUD_Sound* AUD_getPythonSound(PyObject* sound);
+#endif
+
#ifdef __cplusplus
}
#endif
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
index b474fbad444..ea6c738cb58 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.cpp
@@ -34,79 +34,14 @@
#include <cstring>
-AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_IFactory* factory,
+AUD_ChannelMapperFactory::AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
- memset(m_mapping, 0, sizeof(m_mapping));
}
-AUD_ChannelMapperFactory::~AUD_ChannelMapperFactory()
+AUD_Reference<AUD_IReader> AUD_ChannelMapperFactory::createReader()
{
- for(int i = 1; i < 10; i++)
- deleteMapping(i);
-}
-
-float** AUD_ChannelMapperFactory::getMapping(int ic)
-{
- ic--;
- if(ic > 8 || ic < 0)
- return 0;
-
- if(m_mapping[ic])
- {
- int channels = -1;
- while(m_mapping[ic][++channels] != 0);
- if(channels != m_specs.channels)
- deleteMapping(ic+1);
- }
-
- if(!m_mapping[ic])
- {
- int channels = m_specs.channels;
-
- m_mapping[ic] = new float*[channels+1];
- m_mapping[ic][channels] = 0;
-
- for(int i = 0; i < channels; i++)
- {
- m_mapping[ic][i] = new float[ic+1];
- for(int j = 0; j <= ic; j++)
- m_mapping[ic][i][j] = ((i == j) || (channels == 1) ||
- (ic == 0)) ? 1.0f : 0.0f;
- }
- }
-
- return m_mapping[ic];
-}
-
-void AUD_ChannelMapperFactory::deleteMapping(int ic)
-{
- ic--;
- if(ic > 8 || ic < 0)
- return;
-
- if(m_mapping[ic])
- {
- for(int i = 0; 1; i++)
- {
- if(m_mapping[ic][i] != 0)
- {
- delete[] m_mapping[ic][i];
- }
- else
- break;
- }
- delete[] m_mapping[ic];
- m_mapping[ic] = 0;
- }
-}
-
-AUD_IReader* AUD_ChannelMapperFactory::createReader() const
-{
- AUD_IReader* reader = getReader();
- int ic = reader->getSpecs().channels;
-
- return new AUD_ChannelMapperReader(reader,
- const_cast<AUD_ChannelMapperFactory*>(this)->getMapping(ic));
+ AUD_Reference<AUD_IReader> reader = getReader();
+ return new AUD_ChannelMapperReader(reader, m_specs.channels);
}
diff --git a/intern/audaspace/intern/AUD_ChannelMapperFactory.h b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
index 9d622f5e322..ce43c6462de 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperFactory.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperFactory.h
@@ -41,33 +41,14 @@
class AUD_ChannelMapperFactory : public AUD_MixerFactory
{
private:
- /**
- * The mapping specification.
- */
- float **m_mapping[9];
-
// hide copy constructor and operator=
AUD_ChannelMapperFactory(const AUD_ChannelMapperFactory&);
AUD_ChannelMapperFactory& operator=(const AUD_ChannelMapperFactory&);
public:
- AUD_ChannelMapperFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
-
- virtual ~AUD_ChannelMapperFactory();
-
- /**
- * Returns the mapping array for editing.
- * \param ic The count of input channels the array should have.
- * \note The count of output channels is read of the desired output specs.
- */
- float** getMapping(int ic);
-
- /**
- * Deletes the current channel mapping.
- */
- void deleteMapping(int ic);
+ AUD_ChannelMapperFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_CHANNELMAPPERFACTORY
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
index dec70aaecf6..27d10ce6dc8 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.cpp
@@ -28,74 +28,343 @@
* \ingroup audaspaceintern
*/
+#include <cmath>
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+#ifndef M_PI_2
+#define M_PI_2 1.57079632679489661923
+#endif
#include "AUD_ChannelMapperReader.h"
-AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_IReader* reader,
- float **mapping) :
- AUD_EffectReader(reader)
+AUD_ChannelMapperReader::AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader,
+ AUD_Channels channels) :
+ AUD_EffectReader(reader), m_target_channels(channels),
+ m_source_channels(AUD_CHANNELS_INVALID), m_mapping(0), m_map_size(0), m_mono_angle(0)
{
- m_specs = reader->getSpecs();
+}
- int channels = -1;
- m_rch = m_specs.channels;
- while(mapping[++channels] != 0);
+AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
+{
+ delete[] m_mapping;
+}
- m_mapping = new float*[channels];
- m_specs.channels = (AUD_Channels)channels;
+void AUD_ChannelMapperReader::setChannels(AUD_Channels channels)
+{
+ m_target_channels = channels;
+ calculateMapping();
+}
- float sum;
- int i;
+void AUD_ChannelMapperReader::setMonoAngle(float angle)
+{
+ if(angle != angle)
+ angle = 0;
+ m_mono_angle = angle;
+ if(m_source_channels == AUD_CHANNELS_MONO)
+ calculateMapping();
+}
- while(channels--)
- {
- m_mapping[channels] = new float[m_rch];
- sum = 0.0f;
- for(i=0; i < m_rch; i++)
- sum += mapping[channels][i];
- for(i=0; i < m_rch; i++)
- m_mapping[channels][i] = sum > 0.0f ?
- mapping[channels][i]/sum : 0.0f;
- }
+float AUD_ChannelMapperReader::angleDistance(float alpha, float beta)
+{
+ alpha = fabs(alpha - beta);
+
+ if(alpha > M_PI)
+ alpha = fabs(alpha - 2 * M_PI);
+
+ return alpha;
}
-AUD_ChannelMapperReader::~AUD_ChannelMapperReader()
+void AUD_ChannelMapperReader::calculateMapping()
{
- int channels = m_specs.channels;
+ if(m_map_size < m_source_channels * m_target_channels)
+ {
+ delete[] m_mapping;
+ m_mapping = new float[m_source_channels * m_target_channels];
+ m_map_size = m_source_channels * m_target_channels;
+ }
+
+ for(int i = 0; i < m_source_channels * m_target_channels; i++)
+ m_mapping[i] = 0;
+
+ const AUD_Channel* source_channels = CHANNEL_MAPS[m_source_channels - 1];
+ const AUD_Channel* target_channels = CHANNEL_MAPS[m_target_channels - 1];
- while(channels--)
+ int lfe = -1;
+
+ for(int i = 0; i < m_target_channels; i++)
{
- delete[] m_mapping[channels];
+ if(target_channels[i] == AUD_CHANNEL_LFE)
+ {
+ lfe = i;
+ break;
+ }
}
- delete[] m_mapping;
+ const float* source_angles = CHANNEL_ANGLES[m_source_channels - 1];
+ const float* target_angles = CHANNEL_ANGLES[m_target_channels - 1];
+
+ if(m_source_channels == AUD_CHANNELS_MONO)
+ source_angles = &m_mono_angle;
+
+ int channel_min1, channel_min2;
+ float angle_min1, angle_min2, angle;
+
+ for(int i = 0; i < m_source_channels; i++)
+ {
+ if(source_channels[i] == AUD_CHANNEL_LFE)
+ {
+ if(lfe != -1)
+ m_mapping[lfe * m_source_channels + i] = 1;
+
+ continue;
+ }
+
+ channel_min1 = channel_min2 = -1;
+ angle_min1 = angle_min2 = 2 * M_PI;
+
+ for(int j = 0; j < m_target_channels; j++)
+ {
+ if(j == lfe)
+ continue;
+ angle = angleDistance(source_angles[i], target_angles[j]);
+ if(angle < angle_min1)
+ {
+ channel_min2 = channel_min1;
+ angle_min2 = angle_min1;
+
+ channel_min1 = j;
+ angle_min1 = angle;
+ }
+ else if(angle < angle_min2)
+ {
+ channel_min2 = j;
+ angle_min2 = angle;
+ }
+ }
+
+ angle = angle_min1 + angle_min2;
+ if(channel_min2 == -1 || angle == 0)
+ {
+ m_mapping[channel_min1 * m_source_channels + i] = 1;
+ }
+ else
+ {
+ m_mapping[channel_min1 * m_source_channels + i] = cos(M_PI_2 * angle_min1 / angle);
+ m_mapping[channel_min2 * m_source_channels + i] = cos(M_PI_2 * angle_min2 / angle);
+ }
+ }
+
+ /* AUD_XXX for(int i = 0; i < m_source_channels; i++)
+ {
+ for(int j = 0; j < m_target_channels; j++)
+ {
+ std::cout << m_mapping[i * m_source_channels + j] << " ";
+ }
+ std::cout << std::endl;
+ }*/
}
AUD_Specs AUD_ChannelMapperReader::getSpecs() const
{
- return m_specs;
+ AUD_Specs specs = m_reader->getSpecs();
+ specs.channels = m_target_channels;
+ return specs;
}
-void AUD_ChannelMapperReader::read(int & length, sample_t* & buffer)
+void AUD_ChannelMapperReader::read(int& length, bool& eos, sample_t* buffer)
{
- sample_t* in = buffer;
+ AUD_Channels channels = m_reader->getSpecs().channels;
+ if(channels != m_source_channels)
+ {
+ m_source_channels = channels;
+ calculateMapping();
+ }
- m_reader->read(length, in);
+ if(m_source_channels == m_target_channels)
+ {
+ m_reader->read(length, eos, buffer);
+ return;
+ }
- if(m_buffer.getSize() < length * AUD_SAMPLE_SIZE(m_specs))
- m_buffer.resize(length * AUD_SAMPLE_SIZE(m_specs));
+ m_buffer.assureSize(length * channels * sizeof(sample_t));
+
+ sample_t* in = m_buffer.getBuffer();
+
+ m_reader->read(length, eos, in);
- buffer = m_buffer.getBuffer();
sample_t sum;
for(int i = 0; i < length; i++)
{
- for(int j = 0; j < m_specs.channels; j++)
+ for(int j = 0; j < m_target_channels; j++)
{
sum = 0;
- for(int k = 0; k < m_rch; k++)
- sum += m_mapping[j][k] * in[i * m_rch + k];
- buffer[i * m_specs.channels + j] = sum;
+ for(int k = 0; k < m_source_channels; k++)
+ sum += m_mapping[j * m_source_channels + k] * in[i * m_source_channels + k];
+ buffer[i * m_target_channels + j] = sum;
}
}
}
+
+const AUD_Channel AUD_ChannelMapperReader::MONO_MAP[] =
+{
+ AUD_CHANNEL_FRONT_CENTER
+};
+
+const AUD_Channel AUD_ChannelMapperReader::STEREO_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT
+};
+
+const AUD_Channel AUD_ChannelMapperReader::STEREO_LFE_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_LFE
+};
+
+const AUD_Channel AUD_ChannelMapperReader::SURROUND4_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT
+};
+
+const AUD_Channel AUD_ChannelMapperReader::SURROUND5_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_FRONT_CENTER,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT
+};
+
+const AUD_Channel AUD_ChannelMapperReader::SURROUND51_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_FRONT_CENTER,
+ AUD_CHANNEL_LFE,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT
+};
+
+const AUD_Channel AUD_ChannelMapperReader::SURROUND61_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_FRONT_CENTER,
+ AUD_CHANNEL_LFE,
+ AUD_CHANNEL_REAR_CENTER,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT
+};
+
+const AUD_Channel AUD_ChannelMapperReader::SURROUND71_MAP[] =
+{
+ AUD_CHANNEL_FRONT_LEFT,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_FRONT_CENTER,
+ AUD_CHANNEL_LFE,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT,
+ AUD_CHANNEL_SIDE_LEFT,
+ AUD_CHANNEL_SIDE_RIGHT
+};
+
+const AUD_Channel* AUD_ChannelMapperReader::CHANNEL_MAPS[] =
+{
+ AUD_ChannelMapperReader::MONO_MAP,
+ AUD_ChannelMapperReader::STEREO_MAP,
+ AUD_ChannelMapperReader::STEREO_LFE_MAP,
+ AUD_ChannelMapperReader::SURROUND4_MAP,
+ AUD_ChannelMapperReader::SURROUND5_MAP,
+ AUD_ChannelMapperReader::SURROUND51_MAP,
+ AUD_ChannelMapperReader::SURROUND61_MAP,
+ AUD_ChannelMapperReader::SURROUND71_MAP
+};
+
+const float AUD_ChannelMapperReader::MONO_ANGLES[] =
+{
+ 0.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::STEREO_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::STEREO_LFE_ANGLES[] =
+{
+ -90.0f * M_PI / 180.0f,
+ 90.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::SURROUND4_ANGLES[] =
+{
+ -45.0f * M_PI / 180.0f,
+ 45.0f * M_PI / 180.0f,
+ -135.0f * M_PI / 180.0f,
+ 135.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::SURROUND5_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::SURROUND51_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::SURROUND61_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 180.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+};
+
+const float AUD_ChannelMapperReader::SURROUND71_ANGLES[] =
+{
+ -30.0f * M_PI / 180.0f,
+ 30.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ 0.0f * M_PI / 180.0f,
+ -110.0f * M_PI / 180.0f,
+ 110.0f * M_PI / 180.0f
+ -150.0f * M_PI / 180.0f,
+ 150.0f * M_PI / 180.0f
+};
+
+const float* AUD_ChannelMapperReader::CHANNEL_ANGLES[] =
+{
+ AUD_ChannelMapperReader::MONO_ANGLES,
+ AUD_ChannelMapperReader::STEREO_ANGLES,
+ AUD_ChannelMapperReader::STEREO_LFE_ANGLES,
+ AUD_ChannelMapperReader::SURROUND4_ANGLES,
+ AUD_ChannelMapperReader::SURROUND5_ANGLES,
+ AUD_ChannelMapperReader::SURROUND51_ANGLES,
+ AUD_ChannelMapperReader::SURROUND61_ANGLES,
+ AUD_ChannelMapperReader::SURROUND71_ANGLES
+};
diff --git a/intern/audaspace/intern/AUD_ChannelMapperReader.h b/intern/audaspace/intern/AUD_ChannelMapperReader.h
index 091ed06db15..fa035531763 100644
--- a/intern/audaspace/intern/AUD_ChannelMapperReader.h
+++ b/intern/audaspace/intern/AUD_ChannelMapperReader.h
@@ -43,44 +43,88 @@ class AUD_ChannelMapperReader : public AUD_EffectReader
{
private:
/**
- * The sound output buffer.
+ * The sound reading buffer.
*/
AUD_Buffer m_buffer;
/**
* The output specification.
*/
- AUD_Specs m_specs;
+ AUD_Channels m_target_channels;
/**
* The channel count of the reader.
*/
- int m_rch;
+ AUD_Channels m_source_channels;
/**
* The mapping specification.
*/
- float **m_mapping;
+ float* m_mapping;
+
+ /**
+ * The size of the mapping.
+ */
+ int m_map_size;
+
+ /**
+ * The mono source angle.
+ */
+ float m_mono_angle;
+
+ static const AUD_Channel MONO_MAP[];
+ static const AUD_Channel STEREO_MAP[];
+ static const AUD_Channel STEREO_LFE_MAP[];
+ static const AUD_Channel SURROUND4_MAP[];
+ static const AUD_Channel SURROUND5_MAP[];
+ static const AUD_Channel SURROUND51_MAP[];
+ static const AUD_Channel SURROUND61_MAP[];
+ static const AUD_Channel SURROUND71_MAP[];
+ static const AUD_Channel* CHANNEL_MAPS[];
+
+ static const float MONO_ANGLES[];
+ static const float STEREO_ANGLES[];
+ static const float STEREO_LFE_ANGLES[];
+ static const float SURROUND4_ANGLES[];
+ static const float SURROUND5_ANGLES[];
+ static const float SURROUND51_ANGLES[];
+ static const float SURROUND61_ANGLES[];
+ static const float SURROUND71_ANGLES[];
+ static const float* CHANNEL_ANGLES[];
// hide copy constructor and operator=
AUD_ChannelMapperReader(const AUD_ChannelMapperReader&);
AUD_ChannelMapperReader& operator=(const AUD_ChannelMapperReader&);
+ /**
+ * Calculates the mapping matrix.
+ */
+ void calculateMapping();
+
+ /**
+ * Calculates the distance between two angles.
+ */
+ float angleDistance(float alpha, float beta);
+
public:
/**
* Creates a channel mapper reader.
* \param reader The reader to map.
* \param mapping The mapping specification as two dimensional float array.
*/
- AUD_ChannelMapperReader(AUD_IReader* reader, float **mapping);
+ AUD_ChannelMapperReader(AUD_Reference<AUD_IReader> reader, AUD_Channels channels);
/**
* Destroys the reader.
*/
~AUD_ChannelMapperReader();
+ void setChannels(AUD_Channels channels);
+
+ void setMonoAngle(float angle);
+
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_CHANNELMAPPERREADER
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.cpp b/intern/audaspace/intern/AUD_ConverterFactory.cpp
index cce0f273616..bf9a3586616 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFactory.cpp
@@ -32,15 +32,15 @@
#include "AUD_ConverterFactory.h"
#include "AUD_ConverterReader.h"
-AUD_ConverterFactory::AUD_ConverterFactory(AUD_IFactory* factory,
+AUD_ConverterFactory::AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
AUD_MixerFactory(factory, specs)
{
}
-AUD_IReader* AUD_ConverterFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_ConverterFactory::createReader()
{
- AUD_IReader* reader = getReader();
+ AUD_Reference<AUD_IReader> reader = getReader();
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
diff --git a/intern/audaspace/intern/AUD_ConverterFactory.h b/intern/audaspace/intern/AUD_ConverterFactory.h
index b9eac94de40..8f0221addb7 100644
--- a/intern/audaspace/intern/AUD_ConverterFactory.h
+++ b/intern/audaspace/intern/AUD_ConverterFactory.h
@@ -46,9 +46,9 @@ private:
AUD_ConverterFactory& operator=(const AUD_ConverterFactory&);
public:
- AUD_ConverterFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_ConverterFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_CONVERTERFACTORY
diff --git a/intern/audaspace/intern/AUD_ConverterFunctions.cpp b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
index d3cc9fa8202..c45fde72b1b 100644
--- a/intern/audaspace/intern/AUD_ConverterFunctions.cpp
+++ b/intern/audaspace/intern/AUD_ConverterFunctions.cpp
@@ -45,13 +45,13 @@
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++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = (((int16_t)source[i]) - AUD_U8_0) << 8;
}
void AUD_convert_u8_s24_be(data_t* target, data_t* source, int length)
{
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
{
target[i*3] = source[i] - AUD_U8_0;
target[i*3+1] = 0;
@@ -61,7 +61,7 @@ void AUD_convert_u8_s24_be(data_t* target, data_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++)
+ for(int i = length - 1; i >= 0; i--)
{
target[i*3+2] = source[i] - AUD_U8_0;
target[i*3+1] = 0;
@@ -72,21 +72,21 @@ void AUD_convert_u8_s24_le(data_t* target, data_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++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = (((int32_t)source[i]) - AUD_U8_0) << 24;
}
void AUD_convert_u8_float(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((float)AUD_U8_0);
}
void AUD_convert_u8_double(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = (((int32_t)source[i]) - AUD_U8_0) / ((double)AUD_U8_0);
}
@@ -100,10 +100,12 @@ void AUD_convert_s16_u8(data_t* target, data_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++)
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
{
- target[i*3] = s[i] >> 8 & 0xFF;
- target[i*3+1] = s[i] & 0xFF;
+ t = s[i];
+ target[i*3] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
target[i*3+2] = 0;
}
}
@@ -111,10 +113,12 @@ void AUD_convert_s16_s24_be(data_t* target, data_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++)
+ int16_t t;
+ for(int i = length - 1; i >= 0; i--)
{
- target[i*3+2] = s[i] >> 8 & 0xFF;
- target[i*3+1] = s[i] & 0xFF;
+ t = s[i];
+ target[i*3+2] = t >> 8 & 0xFF;
+ target[i*3+1] = t & 0xFF;
target[i*3] = 0;
}
}
@@ -123,7 +127,7 @@ 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;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = ((int32_t)s[i]) << 16;
}
@@ -131,7 +135,7 @@ void AUD_convert_s16_float(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
float* t = (float*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = s[i] / AUD_S16_FLT;
}
@@ -139,7 +143,7 @@ void AUD_convert_s16_double(data_t* target, data_t* source, int length)
{
int16_t* s = (int16_t*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = s[i] / AUD_S16_FLT;
}
@@ -177,14 +181,14 @@ void AUD_convert_s24_s24(data_t* target, data_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++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
}
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++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
}
@@ -192,7 +196,7 @@ void AUD_convert_s24_float_be(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
{
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
t[i] = s / AUD_S32_FLT;
@@ -203,7 +207,7 @@ void AUD_convert_s24_float_le(data_t* target, data_t* source, int length)
{
float* t = (float*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
{
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
t[i] = s / AUD_S32_FLT;
@@ -214,7 +218,7 @@ void AUD_convert_s24_double_be(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
{
s = source[i*3] << 24 | source[i*3+1] << 16 | source[i*3+2] << 8;
t[i] = s / AUD_S32_FLT;
@@ -225,7 +229,7 @@ void AUD_convert_s24_double_le(data_t* target, data_t* source, int length)
{
double* t = (double*) target;
int32_t s;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
{
s = source[i*3+2] << 24 | source[i*3+1] << 16 | source[i*3] << 8;
t[i] = s / AUD_S32_FLT;
@@ -250,22 +254,26 @@ void AUD_convert_s32_s16(data_t* target, data_t* source, int length)
void AUD_convert_s32_s24_be(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
+ int32_t t;
for(int i = 0; i < length; i++)
{
- target[i*3] = s[i] >> 24 & 0xFF;
- target[i*3+1] = s[i] >> 16 & 0xFF;
- target[i*3+2] = s[i] >> 8 & 0xFF;
+ t = s[i];
+ target[i*3] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3+2] = t >> 8 & 0xFF;
}
}
void AUD_convert_s32_s24_le(data_t* target, data_t* source, int length)
{
- int16_t* s = (int16_t*) source;
+ int32_t* s = (int32_t*) source;
+ int32_t t;
for(int i = 0; i < length; i++)
{
- target[i*3+2] = s[i] >> 24 & 0xFF;
- target[i*3+1] = s[i] >> 16 & 0xFF;
- target[i*3] = s[i] >> 8 & 0xFF;
+ t = s[i];
+ target[i*3+2] = t >> 24 & 0xFF;
+ target[i*3+1] = t >> 16 & 0xFF;
+ target[i*3] = t >> 8 & 0xFF;
}
}
@@ -281,7 +289,7 @@ void AUD_convert_s32_double(data_t* target, data_t* source, int length)
{
int32_t* s = (int32_t*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i--)
t[i] = s[i] / AUD_S32_FLT;
}
@@ -371,7 +379,7 @@ void AUD_convert_float_double(data_t* target, data_t* source, int length)
{
float* s = (float*) source;
double* t = (double*) target;
- for(int i = 0; i < length; i++)
+ for(int i = length - 1; i >= 0; i++)
t[i] = s[i];
}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.cpp b/intern/audaspace/intern/AUD_ConverterReader.cpp
index 70297b8f5e8..b3d669379f8 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.cpp
+++ b/intern/audaspace/intern/AUD_ConverterReader.cpp
@@ -31,16 +31,15 @@
#include "AUD_ConverterReader.h"
-AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
+AUD_ConverterReader::AUD_ConverterReader(AUD_Reference<AUD_IReader> reader,
AUD_DeviceSpecs specs) :
- AUD_EffectReader(reader)
+ AUD_EffectReader(reader),
+ m_format(specs.format)
{
- m_specs.specs = reader->getSpecs();
-
int bigendian = 1;
bigendian = (((char*)&bigendian)[0]) ? 0: 1; // 1 if Big Endian
- switch(specs.format)
+ switch(m_format)
{
case AUD_FORMAT_U8:
m_convert = AUD_convert_float_u8;
@@ -66,26 +65,17 @@ AUD_ConverterReader::AUD_ConverterReader(AUD_IReader* reader,
default:
break;
}
-
- m_specs.format = specs.format;
-}
-
-AUD_Specs AUD_ConverterReader::getSpecs() const
-{
- return m_specs.specs;
}
-void AUD_ConverterReader::read(int & length, sample_t* & buffer)
+void AUD_ConverterReader::read(int& length, bool& eos, sample_t* buffer)
{
- m_reader->read(length, buffer);
-
- int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ AUD_Specs specs = m_reader->getSpecs();
+ int samplesize = AUD_SAMPLE_SIZE(specs);
- if(m_buffer.getSize() < length * samplesize)
- m_buffer.resize(length * samplesize);
+ m_buffer.assureSize(length * samplesize);
- m_convert((data_t*)m_buffer.getBuffer(), (data_t*)buffer,
- length * m_specs.channels);
+ m_reader->read(length, eos, m_buffer.getBuffer());
- buffer = m_buffer.getBuffer();
+ m_convert((data_t*)buffer, (data_t*)m_buffer.getBuffer(),
+ length * specs.channels);
}
diff --git a/intern/audaspace/intern/AUD_ConverterReader.h b/intern/audaspace/intern/AUD_ConverterReader.h
index a7a425adc54..4a637becbb5 100644
--- a/intern/audaspace/intern/AUD_ConverterReader.h
+++ b/intern/audaspace/intern/AUD_ConverterReader.h
@@ -50,7 +50,7 @@ private:
/**
* The target specification.
*/
- AUD_DeviceSpecs m_specs;
+ AUD_SampleFormat m_format;
/**
* Converter function.
@@ -67,10 +67,9 @@ public:
* \param reader The reader to convert.
* \param specs The target specification.
*/
- AUD_ConverterReader(AUD_IReader* reader, AUD_DeviceSpecs specs);
+ AUD_ConverterReader(AUD_Reference<AUD_IReader> reader, AUD_DeviceSpecs specs);
- virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_CONVERTERREADER
diff --git a/intern/audaspace/intern/AUD_DefaultMixer.cpp b/intern/audaspace/intern/AUD_DefaultMixer.cpp
deleted file mode 100644
index 20471d6e874..00000000000
--- a/intern/audaspace/intern/AUD_DefaultMixer.cpp
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * $Id$
- *
- * ***** BEGIN GPL LICENSE BLOCK *****
- *
- * Copyright 2009-2011 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 General Public License as published by
- * the Free Software Foundation; either version 2 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with Audaspace; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- *
- * ***** END GPL LICENSE BLOCK *****
- */
-
-/** \file audaspace/intern/AUD_DefaultMixer.cpp
- * \ingroup audaspaceintern
- */
-
-
-#include "AUD_DefaultMixer.h"
-#ifdef WITH_SAMPLERATE
-#include "AUD_SRCResampleReader.h"
-#else
-#include "AUD_LinearResampleReader.h"
-#endif
-#include "AUD_ChannelMapperReader.h"
-#include "AUD_ChannelMapperFactory.h"
-
-#include <cstring>
-
-AUD_DefaultMixer::AUD_DefaultMixer(AUD_DeviceSpecs specs) :
- AUD_Mixer(specs)
-{
-}
-
-AUD_IReader* AUD_DefaultMixer::prepare(AUD_IReader* reader)
-{
- // hacky for now, until a better channel mapper reader is available
- AUD_ChannelMapperFactory cmf(NULL, m_specs);
-
- AUD_Specs specs = reader->getSpecs();
-
- // if channel count is lower in output, rechannel before resampling
- if(specs.channels < m_specs.channels)
- {
- reader = new AUD_ChannelMapperReader(reader,
- cmf.getMapping(specs.channels));
- specs.channels = m_specs.channels;
- }
-
- // resample
- if(specs.rate != m_specs.rate)
-#ifdef WITH_SAMPLERATE
- reader = new AUD_SRCResampleReader(reader, m_specs.specs);
-#else
- reader = new AUD_LinearResampleReader(reader, m_specs.specs);
-#endif
-
- // rechannel
- if(specs.channels != m_specs.channels)
- reader = new AUD_ChannelMapperReader(reader,
- cmf.getMapping(specs.channels));
-
- return reader;
-}
diff --git a/intern/audaspace/intern/AUD_FileFactory.cpp b/intern/audaspace/intern/AUD_FileFactory.cpp
index 1c8bb03bc92..684fbb13fb2 100644
--- a/intern/audaspace/intern/AUD_FileFactory.cpp
+++ b/intern/audaspace/intern/AUD_FileFactory.cpp
@@ -54,20 +54,20 @@ AUD_FileFactory::AUD_FileFactory(std::string filename) :
AUD_FileFactory::AUD_FileFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
static const char* read_error = "AUD_FileFactory: File couldn't be read.";
-AUD_IReader* AUD_FileFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_FileFactory::createReader()
{
#ifdef WITH_SNDFILE
try
{
- if(m_buffer.get())
- return new AUD_SndFileReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_SndFileReader(m_filename);
+ else
+ return new AUD_SndFileReader(m_buffer);
}
catch(AUD_Exception&) {}
#endif
@@ -75,10 +75,10 @@ AUD_IReader* AUD_FileFactory::createReader() const
#ifdef WITH_FFMPEG
try
{
- if(m_buffer.get())
- return new AUD_FFMPEGReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_FFMPEGReader(m_filename);
+ else
+ return new AUD_FFMPEGReader(m_buffer);
}
catch(AUD_Exception&) {}
#endif
diff --git a/intern/audaspace/intern/AUD_FileFactory.h b/intern/audaspace/intern/AUD_FileFactory.h
index a2ab94ae148..dfca70bc3fd 100644
--- a/intern/audaspace/intern/AUD_FileFactory.h
+++ b/intern/audaspace/intern/AUD_FileFactory.h
@@ -72,7 +72,7 @@ public:
*/
AUD_FileFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_FILEFACTORY
diff --git a/intern/audaspace/intern/AUD_I3DDevice.h b/intern/audaspace/intern/AUD_I3DDevice.h
index df341dbb319..036f7b1fa94 100644
--- a/intern/audaspace/intern/AUD_I3DDevice.h
+++ b/intern/audaspace/intern/AUD_I3DDevice.h
@@ -35,8 +35,6 @@
#include "AUD_Space.h"
#include "AUD_3DMath.h"
-struct AUD_Handle;
-
/**
* This class represents an output device for 3D sound.
*/
@@ -121,200 +119,6 @@ public:
* \param model distance model.
*/
virtual void setDistanceModel(AUD_DistanceModel model)=0;
-
-
-
- /**
- * Retrieves the location of a source.
- * \param handle The handle of the source.
- * \return The location.
- */
- virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle)=0;
-
- /**
- * Sets the location of a source.
- * \param handle The handle of the source.
- * \param location The new location.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)=0;
-
- /**
- * Retrieves the velocity of a source.
- * \param handle The handle of the source.
- * \return The velocity.
- */
- virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle)=0;
-
- /**
- * Sets the velocity of a source.
- * \param handle The handle of the source.
- * \param velocity The new velocity.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)=0;
-
- /**
- * Retrieves the orientation of a source.
- * \param handle The handle of the source.
- * \return The orientation as quaternion.
- */
- virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle)=0;
-
- /**
- * Sets the orientation of a source.
- * \param handle The handle of the source.
- * \param orientation The new orientation as quaternion.
- * \return Whether the action succeeded.
- */
- virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)=0;
-
-
- /**
- * Checks whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \return Whether the source is relative.
- */
- virtual bool isRelative(AUD_Handle* handle)=0;
-
- /**
- * Sets whether the source location, velocity and orientation are relative
- * to the listener.
- * \param handle The handle of the source.
- * \param relative Whether the source is relative.
- * \return Whether the action succeeded.
- */
- virtual bool setRelative(AUD_Handle* handle, bool relative)=0;
-
- /**
- * Retrieves the maximum volume of a source.
- * \param handle The handle of the source.
- * \return The maximum volume.
- */
- virtual float getVolumeMaximum(AUD_Handle* handle)=0;
-
- /**
- * Sets the maximum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new maximum volume.
- * \return Whether the action succeeded.
- */
- virtual bool setVolumeMaximum(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the minimum volume of a source.
- * \param handle The handle of the source.
- * \return The minimum volume.
- */
- virtual float getVolumeMinimum(AUD_Handle* handle)=0;
-
- /**
- * Sets the minimum volume of a source.
- * \param handle The handle of the source.
- * \param volume The new minimum volume.
- * \return Whether the action succeeded.
- */
- virtual bool setVolumeMinimum(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \return The maximum distance.
- */
- virtual float getDistanceMaximum(AUD_Handle* handle)=0;
-
- /**
- * Sets the maximum distance of a source.
- * If a source is further away from the reader than this distance, the
- * volume will automatically be set to 0.
- * \param handle The handle of the source.
- * \param distance The new maximum distance.
- * \return Whether the action succeeded.
- */
- virtual bool setDistanceMaximum(AUD_Handle* handle, float distance)=0;
-
- /**
- * Retrieves the reference distance of a source.
- * \param handle The handle of the source.
- * \return The reference distance.
- */
- virtual float getDistanceReference(AUD_Handle* handle)=0;
-
- /**
- * Sets the reference distance of a source.
- * \param handle The handle of the source.
- * \param distance The new reference distance.
- * \return Whether the action succeeded.
- */
- virtual bool setDistanceReference(AUD_Handle* handle, float distance)=0;
-
- /**
- * Retrieves the attenuation of a source.
- * \param handle The handle of the source.
- * \return The attenuation.
- */
- virtual float getAttenuation(AUD_Handle* handle)=0;
-
- /**
- * Sets the attenuation of a source.
- * This value is used for distance calculation.
- * \param handle The handle of the source.
- * \param factor The new attenuation.
- * \return Whether the action succeeded.
- */
- virtual bool setAttenuation(AUD_Handle* handle, float factor)=0;
-
- /**
- * Retrieves the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \return The outer angle of the cone.
- */
- virtual float getConeAngleOuter(AUD_Handle* handle)=0;
-
- /**
- * Sets the outer angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new outer angle of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeAngleOuter(AUD_Handle* handle, float angle)=0;
-
- /**
- * Retrieves the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \return The inner angle of the cone.
- */
- virtual float getConeAngleInner(AUD_Handle* handle)=0;
-
- /**
- * Sets the inner angle of the cone of a source.
- * \param handle The handle of the source.
- * \param angle The new inner angle of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeAngleInner(AUD_Handle* handle, float angle)=0;
-
- /**
- * Retrieves the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \return The outer volume of the cone.
- */
- virtual float getConeVolumeOuter(AUD_Handle* handle)=0;
-
- /**
- * Sets the outer volume of the cone of a source.
- * The volume between inner and outer angle is interpolated between inner
- * volume and this value.
- * \param handle The handle of the source.
- * \param volume The new outer volume of the cone.
- * \return Whether the action succeeded.
- */
- virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume)=0;
};
#endif //AUD_I3DDEVICE
diff --git a/intern/audaspace/intern/AUD_I3DHandle.h b/intern/audaspace/intern/AUD_I3DHandle.h
new file mode 100644
index 00000000000..259c702bf86
--- /dev/null
+++ b/intern/audaspace/intern/AUD_I3DHandle.h
@@ -0,0 +1,213 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_I3DHandle.h
+ * \ingroup audaspaceintern
+ */
+
+
+#ifndef AUD_I3DHANDLE
+#define AUD_I3DHANDLE
+
+#include "AUD_Space.h"
+#include "AUD_3DMath.h"
+
+/**
+ * This class represents an output device for 3D sound.
+ */
+class AUD_I3DHandle
+{
+public:
+ /**
+ * Retrieves the location of a source.
+ * \return The location.
+ */
+ virtual AUD_Vector3 getSourceLocation()=0;
+
+ /**
+ * Sets the location of a source.
+ * \param location The new location.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceLocation(const AUD_Vector3& location)=0;
+
+ /**
+ * Retrieves the velocity of a source.
+ * \return The velocity.
+ */
+ virtual AUD_Vector3 getSourceVelocity()=0;
+
+ /**
+ * Sets the velocity of a source.
+ * \param velocity The new velocity.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
+
+ /**
+ * Retrieves the orientation of a source.
+ * \return The orientation as quaternion.
+ */
+ virtual AUD_Quaternion getSourceOrientation()=0;
+
+ /**
+ * Sets the orientation of a source.
+ * \param orientation The new orientation as quaternion.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
+
+
+ /**
+ * Checks whether the source location, velocity and orientation are relative
+ * to the listener.
+ * \return Whether the source is relative.
+ */
+ virtual bool isRelative()=0;
+
+ /**
+ * Sets whether the source location, velocity and orientation are relative
+ * to the listener.
+ * \param relative Whether the source is relative.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setRelative(bool relative)=0;
+
+ /**
+ * Retrieves the maximum volume of a source.
+ * \return The maximum volume.
+ */
+ virtual float getVolumeMaximum()=0;
+
+ /**
+ * Sets the maximum volume of a source.
+ * \param volume The new maximum volume.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setVolumeMaximum(float volume)=0;
+
+ /**
+ * Retrieves the minimum volume of a source.
+ * \return The minimum volume.
+ */
+ virtual float getVolumeMinimum()=0;
+
+ /**
+ * Sets the minimum volume of a source.
+ * \param volume The new minimum volume.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setVolumeMinimum(float volume)=0;
+
+ /**
+ * Retrieves the maximum distance of a source.
+ * If a source is further away from the reader than this distance, the
+ * volume will automatically be set to 0.
+ * \return The maximum distance.
+ */
+ virtual float getDistanceMaximum()=0;
+
+ /**
+ * Sets the maximum distance of a source.
+ * If a source is further away from the reader than this distance, the
+ * volume will automatically be set to 0.
+ * \param distance The new maximum distance.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setDistanceMaximum(float distance)=0;
+
+ /**
+ * Retrieves the reference distance of a source.
+ * \return The reference distance.
+ */
+ virtual float getDistanceReference()=0;
+
+ /**
+ * Sets the reference distance of a source.
+ * \param distance The new reference distance.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setDistanceReference(float distance)=0;
+
+ /**
+ * Retrieves the attenuation of a source.
+ * \return The attenuation.
+ */
+ virtual float getAttenuation()=0;
+
+ /**
+ * Sets the attenuation of a source.
+ * This value is used for distance calculation.
+ * \param factor The new attenuation.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setAttenuation(float factor)=0;
+
+ /**
+ * Retrieves the outer angle of the cone of a source.
+ * \return The outer angle of the cone.
+ */
+ virtual float getConeAngleOuter()=0;
+
+ /**
+ * Sets the outer angle of the cone of a source.
+ * \param angle The new outer angle of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeAngleOuter(float angle)=0;
+
+ /**
+ * Retrieves the inner angle of the cone of a source.
+ * \return The inner angle of the cone.
+ */
+ virtual float getConeAngleInner()=0;
+
+ /**
+ * Sets the inner angle of the cone of a source.
+ * \param angle The new inner angle of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeAngleInner(float angle)=0;
+
+ /**
+ * Retrieves the outer volume of the cone of a source.
+ * The volume between inner and outer angle is interpolated between inner
+ * volume and this value.
+ * \return The outer volume of the cone.
+ */
+ virtual float getConeVolumeOuter()=0;
+
+ /**
+ * Sets the outer volume of the cone of a source.
+ * The volume between inner and outer angle is interpolated between inner
+ * volume and this value.
+ * \param volume The new outer volume of the cone.
+ * \return Whether the action succeeded.
+ */
+ virtual bool setConeVolumeOuter(float volume)=0;
+};
+
+#endif //AUD_I3DHANDLE
diff --git a/intern/audaspace/intern/AUD_IDevice.h b/intern/audaspace/intern/AUD_IDevice.h
index 4856b913b38..992e3347366 100644
--- a/intern/audaspace/intern/AUD_IDevice.h
+++ b/intern/audaspace/intern/AUD_IDevice.h
@@ -33,15 +33,10 @@
#define AUD_IDEVICE
#include "AUD_Space.h"
+#include "AUD_Reference.h"
class AUD_IFactory;
class AUD_IReader;
-
-/// Handle structure, for inherition.
-struct AUD_Handle
-{
-};
-
-typedef void (*stopCallback)(void*);
+class AUD_IHandle;
/**
* This class represents an output device for sound sources.
@@ -74,7 +69,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false)=0;
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
/**
* Plays a sound source.
@@ -86,87 +81,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false)=0;
-
- /**
- * Pauses a played back sound.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been paused.
- * - false if the sound isn't playing back or the handle is invalid.
- */
- virtual bool pause(AUD_Handle* handle)=0;
-
- /**
- * Resumes a paused sound.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been resumed.
- * - false if the sound isn't paused or the handle is invalid.
- */
- virtual bool resume(AUD_Handle* handle)=0;
-
- /**
- * Stops a played back or paused sound. The handle is definitely invalid
- * afterwards.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the sound has been stopped.
- * - false if the handle is invalid.
- */
- virtual bool stop(AUD_Handle* handle)=0;
-
- /**
- * Gets the behaviour of the device for a played back sound when the sound
- * doesn't return any more samples.
- * \param handle The handle returned by the play function.
- * \return
- * - true if the source will be paused when it's end is reached
- * - false if the handle won't kept or is invalid.
- */
- virtual bool getKeep(AUD_Handle* handle)=0;
-
- /**
- * Sets the behaviour of the device for a played back sound when the sound
- * doesn't return any more samples.
- * \param handle The handle returned by the play function.
- * \param keep True when the source should be paused and not deleted.
- * \return
- * - true if the behaviour has been changed.
- * - false if the handle is invalid.
- */
- virtual bool setKeep(AUD_Handle* handle, bool keep)=0;
-
- /**
- * Seeks in a played back sound.
- * \param handle The handle returned by the play function.
- * \param position The new position from where to play back, in seconds.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- * \warning Whether the seek works or not depends on the sound source.
- */
- virtual bool seek(AUD_Handle* handle, float position)=0;
-
- /**
- * Retrieves the current playback position of a sound.
- * \param handle The handle returned by the play function.
- * \return The playback position in seconds, or 0.0 if the handle is
- * invalid.
- */
- virtual float getPosition(AUD_Handle* handle)=0;
-
- /**
- * Returns the status of a played back sound.
- * \param handle The handle returned by the play function.
- * \return
- * - AUD_STATUS_INVALID if the sound has stopped or the handle is
- *. invalid
- * - AUD_STATUS_PLAYING if the sound is currently played back.
- * - AUD_STATUS_PAUSED if the sound is currently paused.
- * \see AUD_Status
- */
- virtual AUD_Status getStatus(AUD_Handle* handle)=0;
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
* Locks the device.
@@ -195,69 +110,6 @@ public:
* \param volume The overall device volume.
*/
virtual void setVolume(float volume)=0;
-
- /**
- * Retrieves the volume of a playing sound.
- * \param handle The sound handle.
- * \return The volume.
- */
- virtual float getVolume(AUD_Handle* handle)=0;
-
- /**
- * Sets the volume of a playing sound.
- * \param handle The sound handle.
- * \param volume The volume.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setVolume(AUD_Handle* handle, float volume)=0;
-
- /**
- * Retrieves the pitch of a playing sound.
- * \return The pitch.
- */
- virtual float getPitch(AUD_Handle* handle)=0;
-
- /**
- * Sets the pitch of a playing sound.
- * \param handle The sound handle.
- * \param pitch The pitch.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setPitch(AUD_Handle* handle, float pitch)=0;
-
- /**
- * Retrieves the loop count of a playing sound.
- * A negative value indicates infinity.
- * \return The remaining loop count.
- */
- virtual int getLoopCount(AUD_Handle* handle)=0;
-
- /**
- * Sets the loop count of a playing sound.
- * A negative value indicates infinity.
- * \param handle The sound handle.
- * \param count The new loop count.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setLoopCount(AUD_Handle* handle, int count)=0;
-
- /**
- * Sets the callback function that's called when the end of a playing sound
- * is reached.
- * \param handle The sound handle.
- * \param callback The callback function.
- * \param data The data that should be passed to the callback function.
- * \return
- * - true if the handle is valid.
- * - false if the handle is invalid.
- */
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0)=0;
};
#endif //AUD_IDevice
diff --git a/intern/audaspace/intern/AUD_IFactory.h b/intern/audaspace/intern/AUD_IFactory.h
index 40a61279a55..c1a9de7f724 100644
--- a/intern/audaspace/intern/AUD_IFactory.h
+++ b/intern/audaspace/intern/AUD_IFactory.h
@@ -33,6 +33,7 @@
#define AUD_IFACTORY
#include "AUD_Space.h"
+#include "AUD_Reference.h"
class AUD_IReader;
/**
@@ -55,7 +56,7 @@ public:
* \exception AUD_Exception An exception may be thrown if there has been
* a more unexpected error during reader creation.
*/
- virtual AUD_IReader* createReader() const=0;
+ virtual AUD_Reference<AUD_IReader> createReader()=0;
};
#endif //AUD_IFACTORY
diff --git a/intern/audaspace/intern/AUD_IHandle.h b/intern/audaspace/intern/AUD_IHandle.h
new file mode 100644
index 00000000000..51d8e0ca2e5
--- /dev/null
+++ b/intern/audaspace/intern/AUD_IHandle.h
@@ -0,0 +1,181 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_IHandle.h
+ * \ingroup audaspaceintern
+ */
+
+#ifndef AUD_IHANDLE
+#define AUD_IHANDLE
+
+//#include "AUD_Space.h"
+//#include "AUD_Reference.h"
+
+typedef void (*stopCallback)(void*);
+
+/**
+ * This class represents a playback handles for specific devices.
+ */
+class AUD_IHandle
+{
+public:
+ /**
+ * Destroys the device.
+ */
+ virtual ~AUD_IHandle() {}
+
+ /**
+ * Pauses a played back sound.
+ * \return
+ * - true if the sound has been paused.
+ * - false if the sound isn't playing back or the handle is invalid.
+ */
+ virtual bool pause()=0;
+
+ /**
+ * Resumes a paused sound.
+ * \return
+ * - true if the sound has been resumed.
+ * - false if the sound isn't paused or the handle is invalid.
+ */
+ virtual bool resume()=0;
+
+ /**
+ * Stops a played back or paused sound. The handle is definitely invalid
+ * afterwards.
+ * \return
+ * - true if the sound has been stopped.
+ * - false if the handle is invalid.
+ */
+ virtual bool stop()=0;
+
+ /**
+ * Gets the behaviour of the device for a played back sound when the sound
+ * doesn't return any more samples.
+ * \return
+ * - true if the source will be paused when it's end is reached
+ * - false if the handle won't kept or is invalid.
+ */
+ virtual bool getKeep()=0;
+
+ /**
+ * Sets the behaviour of the device for a played back sound when the sound
+ * doesn't return any more samples.
+ * \param keep True when the source should be paused and not deleted.
+ * \return
+ * - true if the behaviour has been changed.
+ * - false if the handle is invalid.
+ */
+ virtual bool setKeep(bool keep)=0;
+
+ /**
+ * Seeks in a played back sound.
+ * \param position The new position from where to play back, in seconds.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ * \warning Whether the seek works or not depends on the sound source.
+ */
+ virtual bool seek(float position)=0;
+
+ /**
+ * Retrieves the current playback position of a sound.
+ * \return The playback position in seconds, or 0.0 if the handle is
+ * invalid.
+ */
+ virtual float getPosition()=0;
+
+ /**
+ * Returns the status of a played back sound.
+ * \return
+ * - AUD_STATUS_INVALID if the sound has stopped or the handle is
+ *. invalid
+ * - AUD_STATUS_PLAYING if the sound is currently played back.
+ * - AUD_STATUS_PAUSED if the sound is currently paused.
+ * \see AUD_Status
+ */
+ virtual AUD_Status getStatus()=0;
+
+ /**
+ * Retrieves the volume of a playing sound.
+ * \return The volume.
+ */
+ virtual float getVolume()=0;
+
+ /**
+ * Sets the volume of a playing sound.
+ * \param volume The volume.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setVolume(float volume)=0;
+
+ /**
+ * Retrieves the pitch of a playing sound.
+ * \return The pitch.
+ */
+ virtual float getPitch()=0;
+
+ /**
+ * Sets the pitch of a playing sound.
+ * \param pitch The pitch.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setPitch(float pitch)=0;
+
+ /**
+ * Retrieves the loop count of a playing sound.
+ * A negative value indicates infinity.
+ * \return The remaining loop count.
+ */
+ virtual int getLoopCount()=0;
+
+ /**
+ * Sets the loop count of a playing sound.
+ * A negative value indicates infinity.
+ * \param count The new loop count.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setLoopCount(int count)=0;
+
+ /**
+ * Sets the callback function that's called when the end of a playing sound
+ * is reached.
+ * \param callback The callback function.
+ * \param data The data that should be passed to the callback function.
+ * \return
+ * - true if the handle is valid.
+ * - false if the handle is invalid.
+ */
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
+};
+
+#endif //AUD_IHandle
diff --git a/intern/audaspace/intern/AUD_IReader.h b/intern/audaspace/intern/AUD_IReader.h
index 7c31c593964..b1a282c9d49 100644
--- a/intern/audaspace/intern/AUD_IReader.h
+++ b/intern/audaspace/intern/AUD_IReader.h
@@ -92,15 +92,15 @@ public:
/**
* Request to read the next length samples out of the source.
- * The buffer for reading has to stay valid until the next call of this
- * method or until the reader is deleted.
+ * The buffer supplied has the needed size.
* \param[in,out] length The count of samples that should be read. Shall
* contain the real count of samples after reading, in case
* there were only fewer samples available.
* A smaller value also indicates the end of the reader.
- * \param[out] buffer The pointer to the buffer with the samples.
+ * \param[out] eos End of stream, whether the end is reached or not.
+ * \param[int] buffer The pointer to the buffer to read into.
*/
- virtual void read(int & length, sample_t* & buffer)=0;
+ virtual void read(int& length, bool& eos, sample_t* buffer)=0;
};
#endif //AUD_IREADER
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
index a90dc5cb860..7bedd93b7d5 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.cpp
@@ -32,18 +32,13 @@
#include "AUD_LinearResampleFactory.h"
#include "AUD_LinearResampleReader.h"
-AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_IFactory* factory,
+AUD_LinearResampleFactory::AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
- AUD_ResampleFactory(factory, specs)
+ AUD_MixerFactory(factory, specs)
{
}
-AUD_IReader* AUD_LinearResampleFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LinearResampleFactory::createReader()
{
- AUD_IReader* reader = getReader();
-
- if(reader->getSpecs().rate != m_specs.rate)
- reader = new AUD_LinearResampleReader(reader, m_specs.specs);
-
- return reader;
+ return new AUD_LinearResampleReader(getReader(), m_specs.specs);
}
diff --git a/intern/audaspace/intern/AUD_LinearResampleFactory.h b/intern/audaspace/intern/AUD_LinearResampleFactory.h
index 678aa0b80cb..de015610a73 100644
--- a/intern/audaspace/intern/AUD_LinearResampleFactory.h
+++ b/intern/audaspace/intern/AUD_LinearResampleFactory.h
@@ -32,12 +32,12 @@
#ifndef AUD_LINEARRESAMPLEFACTORY
#define AUD_LINEARRESAMPLEFACTORY
-#include "AUD_ResampleFactory.h"
+#include "AUD_MixerFactory.h"
/**
* This factory creates a resampling reader that does simple linear resampling.
*/
-class AUD_LinearResampleFactory : public AUD_ResampleFactory
+class AUD_LinearResampleFactory : public AUD_MixerFactory
{
private:
// hide copy constructor and operator=
@@ -45,9 +45,9 @@ private:
AUD_LinearResampleFactory& operator=(const AUD_LinearResampleFactory&);
public:
- AUD_LinearResampleFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_LinearResampleFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_LINEARRESAMPLEFACTORY
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.cpp b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
index 05fb39b2cca..c33017e912a 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.cpp
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.cpp
@@ -34,95 +34,139 @@
#include <cmath>
#include <cstring>
-#define CC channels + channel
+#define CC m_channels + channel
-AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_IReader* reader,
+AUD_LinearResampleReader::AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader,
AUD_Specs specs) :
- AUD_EffectReader(reader),
- m_sspecs(reader->getSpecs()),
- m_factor(float(specs.rate) / float(m_sspecs.rate)),
- m_tspecs(specs),
+ AUD_ResampleReader(reader, specs.rate),
+ m_channels(reader->getSpecs().channels),
m_position(0),
- m_sposition(0)
+ m_cache_pos(0),
+ m_cache_ok(false)
{
- m_tspecs.channels = m_sspecs.channels;
- m_cache.resize(2 * AUD_SAMPLE_SIZE(m_tspecs));
+ specs.channels = m_channels;
+ m_cache.resize(2 * AUD_SAMPLE_SIZE(specs));
}
void AUD_LinearResampleReader::seek(int position)
{
- m_position = position;
- m_sposition = floor(position / m_factor);
- m_reader->seek(m_sposition);
+ position = floor(position * double(m_reader->getSpecs().rate) / double(m_rate));
+ m_reader->seek(position);
+ m_cache_ok = false;
+ m_cache_pos = 0;
}
int AUD_LinearResampleReader::getLength() const
{
- return m_reader->getLength() * m_factor;
+ return floor(m_reader->getLength() * double(m_rate) / double(m_reader->getSpecs().rate));
}
int AUD_LinearResampleReader::getPosition() const
{
- return m_position;
+ return floor((m_reader->getPosition() + (m_cache_ok ? m_cache_pos - 2 : 0))
+ * m_rate / m_reader->getSpecs().rate);
}
AUD_Specs AUD_LinearResampleReader::getSpecs() const
{
- return m_tspecs;
+ AUD_Specs specs = m_reader->getSpecs();
+ specs.rate = m_rate;
+ return specs;
}
-void AUD_LinearResampleReader::read(int & length, sample_t* & buffer)
+void AUD_LinearResampleReader::read(int& length, bool& eos, sample_t* buffer)
{
- int samplesize = AUD_SAMPLE_SIZE(m_tspecs);
- int size = length * samplesize;
+ AUD_Specs specs = m_reader->getSpecs();
- if(m_buffer.getSize() < size)
- m_buffer.resize(size);
+ int samplesize = AUD_SAMPLE_SIZE(specs);
+ int size = length;
+ float factor = float(m_rate) / float(m_reader->getSpecs().rate);
+ float spos;
+ sample_t low, high;
+ eos = false;
+
+ if(factor == 1 && (!m_cache_ok || m_cache_pos == 0))
+ {
+ // can read directly!
+ m_reader->read(length, eos, buffer);
+ return;
+ }
+
+ // check for channels changed
+
+ if(specs.channels != m_channels)
+ {
+ m_cache.resize(2 * samplesize);
+ m_channels = specs.channels;
+ m_cache_ok = false;
+ }
- int need = ceil((m_position + length) / m_factor) + 1 - m_sposition;
- int len = need;
+ int len;
sample_t* buf;
- buffer = m_buffer.getBuffer();
- m_reader->read(len, buf);
+ if(m_cache_ok)
+ {
+ int need = ceil(length / factor - (1 - m_cache_pos));
- if(len < need)
- length = floor((m_sposition + len - 1) * m_factor) - m_position;
+ len = need;
- float spos;
- sample_t low, high;
- int channels = m_sspecs.channels;
+ m_buffer.assureSize((len + 3) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ memcpy(buf, m_cache.getBuffer(), 2 * samplesize);
+ m_reader->read(len, eos, buf + 2 * m_channels);
- for(int channel = 0; channel < channels; channel++)
+ if(len < need)
+ length = floor((len + (1 - m_cache_pos)) * factor);
+ }
+ else
{
- for(int i = 0; i < length; i++)
- {
- spos = (m_position + i) / m_factor - m_sposition;
+ int need = ceil(length / factor) + 1;
+
+ len = need;
- if(floor(spos) < 0)
+ m_buffer.assureSize((len + 1) * samplesize);
+ buf = m_buffer.getBuffer();
+
+ m_reader->read(len, eos, buf);
+
+ if(len < need)
+ {
+ if(eos)
{
- low = m_cache.getBuffer()[(int)(floor(spos) + 2) * CC];
- if(ceil(spos) < 0)
- high = m_cache.getBuffer()[(int)(ceil(spos) + 2) * CC];
- else
- high = buf[(int)ceil(spos) * CC];
+ length = floor(len * factor);
+ memset(buf + len * m_channels, 0, samplesize);
}
else
- {
- low = buf[(int)floor(spos) * CC];
- high = buf[(int)ceil(spos) * CC];
- }
+ length = ceil((len - 1) * factor);
+ }
+ m_cache_ok = true;
+ m_cache_pos = 0;
+ }
+
+ for(int channel = 0; channel < m_channels; channel++)
+ {
+ for(int i = 0; i < length; i++)
+ {
+ spos = (i + 1) / factor + m_cache_pos;
+
+ low = buf[(int)floor(spos) * CC];
+ high = buf[(int)ceil(spos) * CC];
+
buffer[i * CC] = low + (spos - floor(spos)) * (high - low);
}
}
- if(len > 1)
- memcpy(m_cache.getBuffer(),
- buf + (len - 2) * channels,
- 2 * samplesize);
- else if(len == 1)
- memcpy(m_cache.getBuffer() + 1 * channels, buf, samplesize);
+ if(floor(spos) == spos)
+ {
+ memcpy(m_cache.getBuffer(), buf + int(floor(spos - 1)) * m_channels, 2 * samplesize);
+ m_cache_pos = 1;
+ }
+ else
+ {
+ memcpy(m_cache.getBuffer(), buf + int(floor(spos)) * m_channels, 2 * samplesize);
+ m_cache_pos = spos - floor(spos);
+ }
- m_sposition += len;
- m_position += length;
+ eos &= length < size;
}
diff --git a/intern/audaspace/intern/AUD_LinearResampleReader.h b/intern/audaspace/intern/AUD_LinearResampleReader.h
index 419c96be2fa..2d92d106697 100644
--- a/intern/audaspace/intern/AUD_LinearResampleReader.h
+++ b/intern/audaspace/intern/AUD_LinearResampleReader.h
@@ -32,29 +32,19 @@
#ifndef AUD_LINEARRESAMPLEREADER
#define AUD_LINEARRESAMPLEREADER
-#include "AUD_EffectReader.h"
+#include "AUD_ResampleReader.h"
#include "AUD_Buffer.h"
/**
* This resampling reader uses libsamplerate for resampling.
*/
-class AUD_LinearResampleReader : public AUD_EffectReader
+class AUD_LinearResampleReader : public AUD_ResampleReader
{
private:
/**
- * The sample specification of the source.
+ * The reader channels.
*/
- const AUD_Specs m_sspecs;
-
- /**
- * The resampling factor.
- */
- const float m_factor;
-
- /**
- * The target specification.
- */
- AUD_Specs m_tspecs;
+ AUD_Channels m_channels;
/**
* The current position.
@@ -62,9 +52,9 @@ private:
int m_position;
/**
- * The current reading source position.
+ * The position in the cache.
*/
- int m_sposition;
+ float m_cache_pos;
/**
* The sound output buffer.
@@ -76,6 +66,11 @@ private:
*/
AUD_Buffer m_cache;
+ /**
+ * Whether the cache contains valid data.
+ */
+ bool m_cache_ok;
+
// hide copy constructor and operator=
AUD_LinearResampleReader(const AUD_LinearResampleReader&);
AUD_LinearResampleReader& operator=(const AUD_LinearResampleReader&);
@@ -86,13 +81,13 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_LinearResampleReader(AUD_IReader* reader, AUD_Specs specs);
+ AUD_LinearResampleReader(AUD_Reference<AUD_IReader> reader, AUD_Specs specs);
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_LINEARRESAMPLEREADER
diff --git a/intern/audaspace/intern/AUD_Mixer.cpp b/intern/audaspace/intern/AUD_Mixer.cpp
index 03488ac46b1..74ff180627a 100644
--- a/intern/audaspace/intern/AUD_Mixer.cpp
+++ b/intern/audaspace/intern/AUD_Mixer.cpp
@@ -73,43 +73,37 @@ AUD_DeviceSpecs AUD_Mixer::getSpecs() const
return m_specs;
}
-void AUD_Mixer::add(sample_t* buffer, int start, int length, float volume)
+void AUD_Mixer::setSpecs(AUD_Specs specs)
{
- AUD_MixerBuffer buf;
- buf.buffer = buffer;
- buf.start = start;
- buf.length = length;
- buf.volume = volume;
- m_buffers.push_back(buf);
+ m_specs.specs = specs;
}
-void AUD_Mixer::superpose(data_t* buffer, int length, float volume)
+void AUD_Mixer::clear(int length)
{
- AUD_MixerBuffer buf;
+ m_buffer.assureSize(length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
- int channels = m_specs.channels;
+ m_length = length;
- if(m_buffer.getSize() < length * channels * 4)
- m_buffer.resize(length * channels * 4);
+ memset(m_buffer.getBuffer(), 0, length * m_specs.channels * AUD_SAMPLE_SIZE(m_specs));
+}
+void AUD_Mixer::mix(sample_t* buffer, int start, int length, float volume)
+{
sample_t* out = m_buffer.getBuffer();
- sample_t* in;
- memset(out, 0, length * channels * 4);
+ length = (AUD_MIN(m_length, length + start) - start) * m_specs.channels;
+ start *= m_specs.channels;
- int end;
-
- while(!m_buffers.empty())
- {
- buf = m_buffers.front();
- m_buffers.pop_front();
+ for(int i = 0; i < length; i++)
+ out[i + start] += buffer[i] * volume;
+}
- end = buf.length * channels;
- in = buf.buffer;
+void AUD_Mixer::read(data_t* buffer, float volume)
+{
+ sample_t* out = m_buffer.getBuffer();
- for(int i = 0; i < end; i++)
- out[i + buf.start * channels] += in[i] * buf.volume * volume;
- }
+ for(int i = 0; i < m_length * m_specs.channels; i++)
+ out[i] *= volume;
- m_convert(buffer, (data_t*) out, length * channels);
+ m_convert(buffer, (data_t*) out, m_length * m_specs.channels);
}
diff --git a/intern/audaspace/intern/AUD_Mixer.h b/intern/audaspace/intern/AUD_Mixer.h
index 277d5bfe2bd..5ca801b1690 100644
--- a/intern/audaspace/intern/AUD_Mixer.h
+++ b/intern/audaspace/intern/AUD_Mixer.h
@@ -34,16 +34,8 @@
#include "AUD_ConverterFunctions.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
class AUD_IReader;
-#include <list>
-
-struct AUD_MixerBuffer
-{
- sample_t* buffer;
- int start;
- int length;
- float volume;
-};
/**
* This abstract class is able to mix audiosignals of different channel count
@@ -53,17 +45,17 @@ class AUD_Mixer
{
protected:
/**
- * The list of buffers to superpose.
+ * The output specification.
*/
- std::list<AUD_MixerBuffer> m_buffers;
+ AUD_DeviceSpecs m_specs;
/**
- * The output specification.
+ * The length of the mixing buffer.
*/
- const AUD_DeviceSpecs m_specs;
+ int m_length;
/**
- * The temporary mixing buffer.
+ * The mixing buffer.
*/
AUD_Buffer m_buffer;
@@ -90,28 +82,32 @@ public:
AUD_DeviceSpecs getSpecs() const;
/**
- * This funuction prepares a reader for playback.
- * \param reader The reader to prepare.
- * \return The reader that should be used for playback.
+ * Sets the target specification for superposing.
+ * \param specs The target specification.
*/
- virtual AUD_IReader* prepare(AUD_IReader* reader)=0;
+ void setSpecs(AUD_Specs specs);
/**
- * Adds a buffer for superposition.
+ * Mixes a buffer.
* \param buffer The buffer to superpose.
* \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, int start, int length, float volume);
+ void mix(sample_t* buffer, int start, int length, float volume);
/**
- * Superposes all added buffers into an output buffer.
+ * Writes the mixing buffer into an output buffer.
* \param buffer The target buffer for superposing.
- * \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(data_t* buffer, int length, float volume);
+ void read(data_t* buffer, float volume);
+
+ /**
+ * Clears the mixing buffer.
+ * \param length The length of the buffer in samples.
+ */
+ void clear(int length);
};
#endif //AUD_MIXER
diff --git a/intern/audaspace/intern/AUD_MixerFactory.cpp b/intern/audaspace/intern/AUD_MixerFactory.cpp
index e65b149b94c..c3bf6b4fa99 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.cpp
+++ b/intern/audaspace/intern/AUD_MixerFactory.cpp
@@ -32,12 +32,12 @@
#include "AUD_MixerFactory.h"
#include "AUD_IReader.h"
-AUD_IReader* AUD_MixerFactory::getReader() const
+AUD_Reference<AUD_IReader> AUD_MixerFactory::getReader() const
{
return m_factory->createReader();
}
-AUD_MixerFactory::AUD_MixerFactory(AUD_IFactory* factory,
+AUD_MixerFactory::AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory,
AUD_DeviceSpecs specs) :
m_specs(specs), m_factory(factory)
{
@@ -48,7 +48,7 @@ AUD_DeviceSpecs AUD_MixerFactory::getSpecs() const
return m_specs;
}
-AUD_IFactory* AUD_MixerFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_MixerFactory::getFactory() const
{
return m_factory;
}
diff --git a/intern/audaspace/intern/AUD_MixerFactory.h b/intern/audaspace/intern/AUD_MixerFactory.h
index 2adabbd13ca..27c703b1898 100644
--- a/intern/audaspace/intern/AUD_MixerFactory.h
+++ b/intern/audaspace/intern/AUD_MixerFactory.h
@@ -48,7 +48,7 @@ protected:
/**
* If there is no reader it is created out of this factory.
*/
- AUD_IFactory* m_factory;
+ AUD_Reference<AUD_IFactory> m_factory;
/**
* Returns the reader created out of the factory.
@@ -56,7 +56,7 @@ protected:
* classes.
* \return The reader to mix.
*/
- AUD_IReader* getReader() const;
+ AUD_Reference<AUD_IReader> getReader() const;
public:
/**
@@ -64,7 +64,7 @@ public:
* \param factory The factory to create the readers to mix out of.
* \param specs The target specification.
*/
- AUD_MixerFactory(AUD_IFactory* factory, AUD_DeviceSpecs specs);
+ AUD_MixerFactory(AUD_Reference<AUD_IFactory> factory, AUD_DeviceSpecs specs);
/**
* Returns the target specification for resampling.
@@ -75,7 +75,7 @@ public:
* Returns the saved factory.
* \return The factory.
*/
- AUD_IFactory* getFactory() const;
+ AUD_Reference<AUD_IFactory> getFactory() const;
};
#endif //AUD_MIXERFACTORY
diff --git a/intern/audaspace/intern/AUD_NULLDevice.cpp b/intern/audaspace/intern/AUD_NULLDevice.cpp
index ab824799d88..6cb13111a43 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.cpp
+++ b/intern/audaspace/intern/AUD_NULLDevice.cpp
@@ -34,6 +34,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_IReader.h"
#include "AUD_IFactory.h"
+#include "AUD_IHandle.h"
AUD_NULLDevice::AUD_NULLDevice()
{
@@ -48,56 +49,16 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
return specs;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_IReader* reader, bool keep)
+AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
return 0;
}
-AUD_Handle* AUD_NULLDevice::play(AUD_IFactory* factory, bool keep)
+AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return 0;
}
-bool AUD_NULLDevice::pause(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::resume(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::stop(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::getKeep(AUD_Handle* handle)
-{
- return false;
-}
-
-bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep)
-{
- return false;
-}
-
-bool AUD_NULLDevice::seek(AUD_Handle* handle, float position)
-{
- return false;
-}
-
-float AUD_NULLDevice::getPosition(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle)
-{
- return AUD_STATUS_INVALID;
-}
-
void AUD_NULLDevice::lock()
{
}
@@ -114,38 +75,3 @@ float AUD_NULLDevice::getVolume() const
void AUD_NULLDevice::setVolume(float volume)
{
}
-
-float AUD_NULLDevice::getVolume(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::setVolume(AUD_Handle* handle, float volume)
-{
- return false;
-}
-
-float AUD_NULLDevice::getPitch(AUD_Handle* handle)
-{
- return std::numeric_limits<float>::quiet_NaN();
-}
-
-bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch)
-{
- return false;
-}
-
-int AUD_NULLDevice::getLoopCount(AUD_Handle* handle)
-{
- return 0;
-}
-
-bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count)
-{
- return false;
-}
-
-bool AUD_NULLDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
-{
- return false;
-}
diff --git a/intern/audaspace/intern/AUD_NULLDevice.h b/intern/audaspace/intern/AUD_NULLDevice.h
index f700bea477b..69ca5b74f3b 100644
--- a/intern/audaspace/intern/AUD_NULLDevice.h
+++ b/intern/audaspace/intern/AUD_NULLDevice.h
@@ -32,6 +32,7 @@
#ifndef AUD_NULLDEVICE
#define AUD_NULLDEVICE
+#include "AUD_IReader.h"
#include "AUD_IDevice.h"
/**
@@ -46,27 +47,12 @@ public:
AUD_NULLDevice();
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0);
};
#endif //AUD_NULLDEVICE
diff --git a/intern/audaspace/intern/AUD_ReadDevice.cpp b/intern/audaspace/intern/AUD_ReadDevice.cpp
index eb5177330bb..5c1876aeb34 100644
--- a/intern/audaspace/intern/AUD_ReadDevice.cpp
+++ b/intern/audaspace/intern/AUD_ReadDevice.cpp
@@ -29,7 +29,6 @@
*/
-#include "AUD_DefaultMixer.h"
#include "AUD_ReadDevice.h"
#include "AUD_IReader.h"
diff --git a/intern/audaspace/intern/AUD_Reference.h b/intern/audaspace/intern/AUD_Reference.h
index 3232ca3b609..3ddeab2eff1 100644
--- a/intern/audaspace/intern/AUD_Reference.h
+++ b/intern/audaspace/intern/AUD_Reference.h
@@ -28,10 +28,52 @@
* \ingroup audaspaceintern
*/
-
#ifndef AUD_REFERENCE
#define AUD_REFERENCE
+#include <map>
+
+#ifdef MEM_DEBUG
+#include <iostream>
+#include <typeinfo>
+#endif
+
+class AUD_ReferenceHandler
+{
+private:
+ static std::map<void*, int> m_references;
+
+public:
+ static inline void incref(void* reference)
+ {
+ if(!reference)
+ return;
+
+ std::map<void*, int>::iterator result = m_references.find(reference);
+ if(result != m_references.end())
+ {
+ m_references[reference]++;
+ }
+ else
+ {
+ m_references[reference] = 1;
+ }
+ }
+
+ static inline bool decref(void* reference)
+ {
+ if(!reference)
+ return false;
+
+ if(!--m_references[reference])
+ {
+ m_references.erase(reference);
+ return true;
+ }
+ return false;
+ }
+};
+
template <class T>
/**
* This class provides reference counting functionality.
@@ -41,8 +83,7 @@ class AUD_Reference
private:
/// The reference.
T* m_reference;
- /// The reference counter.
- int* m_refcount;
+ void* m_original;
public:
/**
* Creates a new reference counter.
@@ -50,9 +91,12 @@ public:
*/
AUD_Reference(T* reference = 0)
{
- m_reference = reference;
- m_refcount = new int;
- *m_refcount = 1;
+ m_original = m_reference = reference;
+ AUD_ReferenceHandler::incref(reference);
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
}
/**
@@ -61,9 +105,24 @@ public:
*/
AUD_Reference(const AUD_Reference& ref)
{
- m_reference = ref.m_reference;
- m_refcount = ref.m_refcount;
- (*m_refcount)++;
+ m_original = m_reference = ref.m_reference;
+ AUD_ReferenceHandler::incref(m_reference);
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
+ }
+
+ template <class U>
+ explicit AUD_Reference(const AUD_Reference<U>& ref)
+ {
+ m_original = ref.get();
+ m_reference = dynamic_cast<T*>(ref.get());
+ AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
}
/**
@@ -72,15 +131,12 @@ public:
*/
~AUD_Reference()
{
- (*m_refcount)--;
- if(*m_refcount == 0)
- {
- if(m_reference)
- {
- delete m_reference;
- }
- delete m_refcount;
- }
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "-" << typeid(*m_reference).name() << std::endl;
+#endif
+ if(AUD_ReferenceHandler::decref(m_original))
+ delete m_reference;
}
/**
@@ -92,30 +148,72 @@ public:
if(&ref == this)
return *this;
- (*m_refcount)--;
- if(*m_refcount == 0)
- {
- if(m_reference)
- {
- delete m_reference;
- }
- delete m_refcount;
- }
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "-" << typeid(*m_reference).name() << std::endl;
+#endif
+ if(AUD_ReferenceHandler::decref(m_original))
+ delete m_reference;
+ m_original = ref.m_original;
m_reference = ref.m_reference;
- m_refcount = ref.m_refcount;
- (*m_refcount)++;
+ AUD_ReferenceHandler::incref(m_original);
+#ifdef MEM_DEBUG
+ if(m_reference != 0)
+ std::cerr << "+" << typeid(*m_reference).name() << std::endl;
+#endif
return *this;
}
/**
+ * Returns whether the reference is NULL.
+ */
+ inline bool isNull() const
+ {
+ return m_reference == 0;
+ }
+
+ /**
* Returns the reference.
*/
- T* get() const
+ inline T* get() const
+ {
+ return m_reference;
+ }
+
+ inline void* getOriginal() const
+ {
+ return m_original;
+ }
+
+ /**
+ * Returns the reference.
+ */
+ inline T& operator*() const
+ {
+ return *m_reference;
+ }
+
+ /**
+ * Returns the reference.
+ */
+ inline T* operator->() const
{
return m_reference;
}
};
+template<class T, class U>
+inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+{
+ return a.getOriginal() == b.getOriginal();
+}
+
+template<class T, class U>
+inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
+{
+ return a.getOriginal() != b.getOriginal();
+}
+
#endif // AUD_REFERENCE
diff --git a/intern/audaspace/intern/AUD_ResampleFactory.h b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
index 634b82b3c96..cfc3c9441a8 100644
--- a/intern/audaspace/intern/AUD_ResampleFactory.h
+++ b/intern/audaspace/intern/AUD_ReferenceHandler.cpp
@@ -24,16 +24,10 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file audaspace/intern/AUD_ResampleFactory.h
+/** \file audaspace/intern/AUD_Reference.cpp
* \ingroup audaspaceintern
*/
+#include "AUD_Reference.h"
-#ifndef AUD_RESAMPLEFACTORY
-#define AUD_RESAMPLEFACTORY
-
-#include "AUD_MixerFactory.h"
-
-typedef AUD_MixerFactory AUD_ResampleFactory;
-
-#endif //AUD_RESAMPLEFACTORY
+std::map<void*, int> AUD_ReferenceHandler::m_references;
diff --git a/intern/audaspace/intern/AUD_ResampleReader.cpp b/intern/audaspace/intern/AUD_ResampleReader.cpp
new file mode 100644
index 00000000000..e74d21eb743
--- /dev/null
+++ b/intern/audaspace/intern/AUD_ResampleReader.cpp
@@ -0,0 +1,47 @@
+/*
+ * $Id$
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * Copyright 2009-2011 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 General Public License as published by
+ * the Free Software Foundation; either version 2 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 General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with Audaspace; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file audaspace/intern/AUD_ResampleReader.cpp
+ * \ingroup audaspaceintern
+ */
+
+
+#include "AUD_ResampleReader.h"
+
+AUD_ResampleReader::AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate) :
+ AUD_EffectReader(reader), m_rate(rate)
+{
+}
+
+void AUD_ResampleReader::setRate(AUD_SampleRate rate)
+{
+ m_rate = rate;
+}
+
+AUD_SampleRate AUD_ResampleReader::getRate()
+{
+ return m_rate;
+}
diff --git a/intern/audaspace/intern/AUD_DefaultMixer.h b/intern/audaspace/intern/AUD_ResampleReader.h
index a347141b5e0..4c1a1ece9d9 100644
--- a/intern/audaspace/intern/AUD_DefaultMixer.h
+++ b/intern/audaspace/intern/AUD_ResampleReader.h
@@ -24,36 +24,28 @@
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file audaspace/intern/AUD_DefaultMixer.h
+/** \file audaspace/intern/AUD_ResampleReader.h
* \ingroup audaspaceintern
*/
+#ifndef AUD_RESAMPLEREADER
+#define AUD_RESAMPLEREADER
-#ifndef AUD_DEFAULTMIXER
-#define AUD_DEFAULTMIXER
+#include "AUD_EffectReader.h"
-#include "AUD_Mixer.h"
-
-/**
- * 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_DefaultMixer : public AUD_Mixer
+class AUD_ResampleReader : public AUD_EffectReader
{
-public:
+protected:
/**
- * Creates the mixer.
+ * The target sampling rate.
*/
- AUD_DefaultMixer(AUD_DeviceSpecs specs);
+ AUD_SampleRate m_rate;
- /**
- * 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);
+ AUD_ResampleReader(AUD_Reference<AUD_IReader> reader, AUD_SampleRate rate);
+
+public:
+ virtual void setRate(AUD_SampleRate rate);
+ AUD_SampleRate getRate();
};
-#endif //AUD_DEFAULTMIXER
+#endif // AUD_RESAMPLEREADER
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.cpp b/intern/audaspace/intern/AUD_SequencerFactory.cpp
index f49dd94fe11..6907d7683c9 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.cpp
+++ b/intern/audaspace/intern/AUD_SequencerFactory.cpp
@@ -32,7 +32,7 @@
#include "AUD_SequencerFactory.h"
#include "AUD_SequencerReader.h"
-typedef std::list<AUD_SequencerReader*>::iterator AUD_ReaderIterator;
+typedef std::list<AUD_Reference<AUD_SequencerReader> >::iterator AUD_ReaderIterator;
AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, bool muted,
void* data,
@@ -46,22 +46,14 @@ AUD_SequencerFactory::AUD_SequencerFactory(AUD_Specs specs, bool muted,
AUD_SequencerFactory::~AUD_SequencerFactory()
{
- AUD_SequencerReader* reader;
- AUD_SequencerEntry* entry;
-
- while(!m_readers.empty())
- {
- reader = m_readers.front();
- m_readers.pop_front();
- reader->destroy();
- }
-
- while(!m_entries.empty())
- {
- entry = m_entries.front();
- m_entries.pop_front();
- delete entry;
- }
+}
+
+void AUD_SequencerFactory::setSpecs(AUD_Specs specs)
+{
+ m_specs = specs;
+
+ for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++)
+ (*i)->setSpecs(m_specs);
}
void AUD_SequencerFactory::mute(bool muted)
@@ -74,19 +66,9 @@ bool AUD_SequencerFactory::getMute() const
return m_muted;
}
-AUD_IReader* AUD_SequencerFactory::newReader()
+AUD_Reference<AUD_SequencerEntry> AUD_SequencerFactory::add(AUD_Reference<AUD_IFactory>** sound, float begin, float end, float skip, void* data)
{
- AUD_SequencerReader* reader = new AUD_SequencerReader(this, m_entries,
- m_specs, m_data,
- m_volume);
- m_readers.push_front(reader);
-
- return reader;
-}
-
-AUD_SequencerEntry* AUD_SequencerFactory::add(AUD_IFactory** sound, float begin, float end, float skip, void* data)
-{
- AUD_SequencerEntry* entry = new AUD_SequencerEntry;
+ AUD_Reference<AUD_SequencerEntry> entry = new AUD_SequencerEntry;
entry->sound = sound;
entry->begin = begin;
entry->skip = skip;
@@ -102,34 +84,37 @@ AUD_SequencerEntry* AUD_SequencerFactory::add(AUD_IFactory** sound, float begin,
return entry;
}
-void AUD_SequencerFactory::remove(AUD_SequencerEntry* entry)
+void AUD_SequencerFactory::remove(AUD_Reference<AUD_SequencerEntry> entry)
{
for(AUD_ReaderIterator i = m_readers.begin(); i != m_readers.end(); i++)
(*i)->remove(entry);
m_entries.remove(entry);
-
- delete entry;
}
-void AUD_SequencerFactory::move(AUD_SequencerEntry* entry, float begin, float end, float skip)
+void AUD_SequencerFactory::move(AUD_Reference<AUD_SequencerEntry> entry, float begin, float end, float skip)
{
entry->begin = begin;
entry->skip = skip;
entry->end = end;
}
-void AUD_SequencerFactory::mute(AUD_SequencerEntry* entry, bool mute)
+void AUD_SequencerFactory::mute(AUD_Reference<AUD_SequencerEntry> entry, bool mute)
{
entry->muted = mute;
}
-AUD_IReader* AUD_SequencerFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
{
- return const_cast<AUD_SequencerFactory*>(this)->newReader();
+ AUD_Reference<AUD_SequencerReader> reader = new AUD_SequencerReader(this, m_entries,
+ m_specs, m_data,
+ m_volume);
+ m_readers.push_front(reader);
+
+ return AUD_Reference<AUD_IReader>(reader);
}
-void AUD_SequencerFactory::removeReader(AUD_SequencerReader* reader)
+void AUD_SequencerFactory::removeReader(AUD_Reference<AUD_SequencerReader> reader)
{
m_readers.remove(reader);
}
diff --git a/intern/audaspace/intern/AUD_SequencerFactory.h b/intern/audaspace/intern/AUD_SequencerFactory.h
index 8f3466f75ce..4e57a224c65 100644
--- a/intern/audaspace/intern/AUD_SequencerFactory.h
+++ b/intern/audaspace/intern/AUD_SequencerFactory.h
@@ -40,7 +40,7 @@ typedef float (*AUD_volumeFunction)(void*, void*, float);
struct AUD_SequencerEntry
{
- AUD_IFactory** sound;
+ AUD_Reference<AUD_IFactory>** sound;
float begin;
float end;
float skip;
@@ -61,14 +61,12 @@ private:
*/
AUD_Specs m_specs;
- std::list<AUD_SequencerEntry*> m_entries;
- std::list<AUD_SequencerReader*> m_readers;
+ std::list<AUD_Reference<AUD_SequencerEntry> > m_entries;
+ std::list<AUD_Reference<AUD_SequencerReader> > m_readers;
bool m_muted;
void* m_data;
AUD_volumeFunction m_volume;
- AUD_IReader* newReader();
-
// hide copy constructor and operator=
AUD_SequencerFactory(const AUD_SequencerFactory&);
AUD_SequencerFactory& operator=(const AUD_SequencerFactory&);
@@ -77,16 +75,18 @@ public:
AUD_SequencerFactory(AUD_Specs specs, bool muted, void* data, AUD_volumeFunction volume);
~AUD_SequencerFactory();
+ void setSpecs(AUD_Specs specs);
+
void mute(bool muted);
bool getMute() const;
- AUD_SequencerEntry* add(AUD_IFactory** sound, float begin, float end, float skip, void* data);
- void remove(AUD_SequencerEntry* entry);
- void move(AUD_SequencerEntry* entry, float begin, float end, float skip);
- void mute(AUD_SequencerEntry* entry, bool mute);
+ AUD_Reference<AUD_SequencerEntry> add(AUD_Reference<AUD_IFactory>** sound, float begin, float end, float skip, void* data);
+ void remove(AUD_Reference<AUD_SequencerEntry> entry);
+ void move(AUD_Reference<AUD_SequencerEntry> entry, float begin, float end, float skip);
+ void mute(AUD_Reference<AUD_SequencerEntry> entry, bool mute);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
- void removeReader(AUD_SequencerReader* reader);
+ void removeReader(AUD_Reference<AUD_SequencerReader> reader);
};
#endif //AUD_SEQUENCERFACTORY
diff --git a/intern/audaspace/intern/AUD_SequencerReader.cpp b/intern/audaspace/intern/AUD_SequencerReader.cpp
index 95e0dca6323..a9309311d6a 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.cpp
+++ b/intern/audaspace/intern/AUD_SequencerReader.cpp
@@ -30,27 +30,32 @@
#include "AUD_SequencerReader.h"
-#include "AUD_DefaultMixer.h"
+#include "AUD_Mixer.h"
+
+#ifdef WITH_SAMPLERATE
+#include "AUD_SRCResampleReader.h"
+#else
+#include "AUD_LinearResampleReader.h"
+#endif
+#include "AUD_ChannelMapperReader.h"
#include <math.h>
-typedef std::list<AUD_SequencerStrip*>::iterator AUD_StripIterator;
-typedef std::list<AUD_SequencerEntry*>::iterator AUD_EntryIterator;
+typedef std::list<AUD_Reference<AUD_SequencerStrip> >::iterator AUD_StripIterator;
+typedef std::list<AUD_Reference<AUD_SequencerEntry> >::iterator AUD_EntryIterator;
-AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory,
- std::list<AUD_SequencerEntry*> &entries, AUD_Specs specs,
- void* data, AUD_volumeFunction volume)
+AUD_SequencerReader::AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory,
+ std::list<AUD_Reference<AUD_SequencerEntry> > &entries, AUD_Specs specs,
+ void* data, AUD_volumeFunction volume) :
+ m_position(0), m_factory(factory), m_data(data), m_volume(volume)
{
AUD_DeviceSpecs dspecs;
dspecs.specs = specs;
dspecs.format = AUD_FORMAT_FLOAT32;
- m_mixer = new AUD_DefaultMixer(dspecs);
- m_factory = factory;
- m_data = data;
- m_volume = volume;
+ m_mixer = new AUD_Mixer(dspecs);
- AUD_SequencerStrip* strip;
+ AUD_Reference<AUD_SequencerStrip> strip;
for(AUD_EntryIterator i = entries.begin(); i != entries.end(); i++)
{
@@ -58,89 +63,54 @@ AUD_SequencerReader::AUD_SequencerReader(AUD_SequencerFactory* factory,
strip->entry = *i;
strip->old_sound = NULL;
- if(strip->old_sound)
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
- else
- strip->reader = NULL;
-
m_strips.push_front(strip);
}
-
- m_position = 0;
}
AUD_SequencerReader::~AUD_SequencerReader()
{
- if(m_factory != NULL)
- m_factory->removeReader(this);
-
- AUD_SequencerStrip* strip;
-
- while(!m_strips.empty())
- {
- strip = m_strips.front();
- m_strips.pop_front();
- if(strip->reader)
- {
- delete strip->reader;
- }
- delete strip;
- }
-
- delete m_mixer;
+ m_factory->removeReader(this);
}
-void AUD_SequencerReader::destroy()
+void AUD_SequencerReader::add(AUD_Reference<AUD_SequencerEntry> entry)
{
- m_factory = NULL;
- AUD_SequencerStrip* strip;
-
- while(!m_strips.empty())
- {
- strip = m_strips.front();
- m_strips.pop_front();
- delete strip;
- }
-}
-
-void AUD_SequencerReader::add(AUD_SequencerEntry* entry)
-{
- AUD_SequencerStrip* strip = new AUD_SequencerStrip;
+ AUD_Reference<AUD_SequencerStrip> strip = new AUD_SequencerStrip;
strip->entry = entry;
- if(*strip->entry->sound)
- {
- strip->old_sound = *strip->entry->sound;
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
- }
- else
- {
- strip->reader = NULL;
- strip->old_sound = NULL;
- }
m_strips.push_front(strip);
}
-void AUD_SequencerReader::remove(AUD_SequencerEntry* entry)
+void AUD_SequencerReader::remove(AUD_Reference<AUD_SequencerEntry> entry)
{
- AUD_SequencerStrip* strip;
+ AUD_Reference<AUD_SequencerStrip> strip;
for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
{
strip = *i;
if(strip->entry == entry)
{
i++;
- if(strip->reader)
- {
- delete strip->reader;
- }
m_strips.remove(strip);
- delete strip;
return;
}
}
}
+void AUD_SequencerReader::setSpecs(AUD_Specs specs)
+{
+ m_mixer->setSpecs(specs);
+
+ AUD_Reference<AUD_SequencerStrip> strip;
+ for(AUD_StripIterator i = m_strips.begin(); i != m_strips.end(); i++)
+ {
+ strip = *i;
+ if(!strip->mapper.isNull())
+ {
+ strip->mapper->setChannels(specs.channels);
+ strip->resampler->setRate(specs.rate);
+ }
+ }
+}
+
bool AUD_SequencerReader::isSeekable() const
{
return true;
@@ -166,21 +136,16 @@ AUD_Specs AUD_SequencerReader::getSpecs() const
return m_mixer->getSpecs().specs;
}
-void AUD_SequencerReader::read(int & length, sample_t* & buffer)
+void AUD_SequencerReader::read(int& length, bool& eos, sample_t* buffer)
{
AUD_DeviceSpecs specs = m_mixer->getSpecs();
- int samplesize = AUD_SAMPLE_SIZE(specs);
int rate = specs.rate;
- int size = length * samplesize;
-
int start, end, current, skip, len;
- AUD_SequencerStrip* strip;
- sample_t* buf;
+ AUD_Reference<AUD_SequencerStrip> strip;
+ m_buffer.assureSize(length * AUD_SAMPLE_SIZE(specs));
- if(m_buffer.getSize() < size)
- m_buffer.resize(size);
- buffer = m_buffer.getBuffer();
+ m_mixer->clear(length);
if(!m_factory->getMute())
{
@@ -192,25 +157,38 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
if(strip->old_sound != *strip->entry->sound)
{
strip->old_sound = *strip->entry->sound;
- if(strip->reader)
- delete strip->reader;
if(strip->old_sound)
{
try
{
- strip->reader = m_mixer->prepare(strip->old_sound->createReader());
+ strip->reader = (*strip->old_sound)->createReader();
+ // resample
+ #ifdef WITH_SAMPLERATE
+ strip->resampler = new AUD_SRCResampleReader(strip->reader, m_mixer->getSpecs().specs);
+ #else
+ strip->resampler = new AUD_LinearResampleReader(strip->reader, m_mixer->getSpecs().specs);
+ #endif
+
+ // rechannel
+ strip->mapper = new AUD_ChannelMapperReader(AUD_Reference<AUD_IReader>(strip->resampler), m_mixer->getSpecs().channels);
}
catch(AUD_Exception)
{
strip->reader = NULL;
+ strip->resampler = NULL;
+ strip->mapper = NULL;
}
}
else
+ {
strip->reader = NULL;
+ strip->resampler = NULL;
+ strip->mapper = NULL;
+ }
}
- if(strip->reader)
+ if(!strip->mapper.isNull())
{
end = floor(strip->entry->end * rate);
if(m_position < end)
@@ -229,10 +207,10 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
current += strip->entry->skip * rate;
len = length > end - m_position ? end - m_position : length;
len -= skip;
- if(strip->reader->getPosition() != current)
- strip->reader->seek(current);
- strip->reader->read(len, buf);
- m_mixer->add(buf, skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate));
+ if(strip->mapper->getPosition() != current)
+ strip->mapper->seek(current);
+ strip->mapper->read(len, eos, m_buffer.getBuffer());
+ m_mixer->mix(m_buffer.getBuffer(), skip, len, m_volume(m_data, strip->entry->data, (float)m_position / (float)rate));
}
}
}
@@ -240,7 +218,9 @@ void AUD_SequencerReader::read(int & length, sample_t* & buffer)
}
}
- m_mixer->superpose((data_t*)buffer, length, 1.0f);
+ m_mixer->read((data_t*)buffer, 1.0f);
m_position += length;
+
+ eos = false;
}
diff --git a/intern/audaspace/intern/AUD_SequencerReader.h b/intern/audaspace/intern/AUD_SequencerReader.h
index 53baf521acc..625bad3c3ae 100644
--- a/intern/audaspace/intern/AUD_SequencerReader.h
+++ b/intern/audaspace/intern/AUD_SequencerReader.h
@@ -35,13 +35,17 @@
#include "AUD_IReader.h"
#include "AUD_SequencerFactory.h"
#include "AUD_Buffer.h"
-class AUD_Mixer;
+#include "AUD_Mixer.h"
+#include "AUD_ResampleReader.h"
+#include "AUD_ChannelMapperReader.h"
struct AUD_SequencerStrip
{
- AUD_IFactory* old_sound;
- AUD_IReader* reader;
- AUD_SequencerEntry* entry;
+ AUD_Reference<AUD_IReader> reader;
+ AUD_Reference<AUD_ResampleReader> resampler;
+ AUD_Reference<AUD_ChannelMapperReader> mapper;
+ AUD_Reference<AUD_SequencerEntry> entry;
+ AUD_Reference<AUD_IFactory>* old_sound;
};
/**
@@ -56,21 +60,21 @@ private:
int m_position;
/**
- * The sound output buffer.
+ * The reading buffer.
*/
AUD_Buffer m_buffer;
/**
* The target specification.
*/
- AUD_Mixer* m_mixer;
+ AUD_Reference<AUD_Mixer> m_mixer;
/**
* Saves the SequencerFactory the reader belongs to.
*/
- AUD_SequencerFactory* m_factory;
+ AUD_Reference<AUD_SequencerFactory> m_factory;
- std::list<AUD_SequencerStrip*> m_strips;
+ std::list<AUD_Reference<AUD_SequencerStrip> > m_strips;
void* m_data;
AUD_volumeFunction m_volume;
@@ -85,24 +89,23 @@ public:
* \param reader The reader to mix.
* \param specs The target specification.
*/
- AUD_SequencerReader(AUD_SequencerFactory* factory, std::list<AUD_SequencerEntry*> &entries, const AUD_Specs specs, void* data, AUD_volumeFunction volume);
+ AUD_SequencerReader(AUD_Reference<AUD_SequencerFactory> factory, std::list<AUD_Reference<AUD_SequencerEntry> > &entries, const AUD_Specs specs, void* data, AUD_volumeFunction volume);
/**
* Destroys the reader.
*/
~AUD_SequencerReader();
- void destroy();
-
- void add(AUD_SequencerEntry* entry);
- void remove(AUD_SequencerEntry* entry);
+ void add(AUD_Reference<AUD_SequencerEntry> entry);
+ void remove(AUD_Reference<AUD_SequencerEntry> entry);
+ void setSpecs(AUD_Specs specs);
virtual bool isSeekable() const;
virtual void seek(int position);
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SEQUENCERREADER
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.cpp b/intern/audaspace/intern/AUD_SilenceFactory.cpp
index dc3f0626591..aefd561a584 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.cpp
+++ b/intern/audaspace/intern/AUD_SilenceFactory.cpp
@@ -37,7 +37,7 @@ AUD_SilenceFactory::AUD_SilenceFactory()
{
}
-AUD_IReader* AUD_SilenceFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SilenceFactory::createReader()
{
return new AUD_SilenceReader();
}
diff --git a/intern/audaspace/intern/AUD_SilenceFactory.h b/intern/audaspace/intern/AUD_SilenceFactory.h
index fb6afc34189..69b446408d7 100644
--- a/intern/audaspace/intern/AUD_SilenceFactory.h
+++ b/intern/audaspace/intern/AUD_SilenceFactory.h
@@ -50,7 +50,7 @@ public:
*/
AUD_SilenceFactory();
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SILENCEFACTORY
diff --git a/intern/audaspace/intern/AUD_SilenceReader.cpp b/intern/audaspace/intern/AUD_SilenceReader.cpp
index bdff4fe75a6..d34fea72bb3 100644
--- a/intern/audaspace/intern/AUD_SilenceReader.cpp
+++ b/intern/audaspace/intern/AUD_SilenceReader.cpp
@@ -66,15 +66,9 @@ AUD_Specs AUD_SilenceReader::getSpecs() const
return specs;
}
-void AUD_SilenceReader::read(int & length, sample_t* & buffer)
+void AUD_SilenceReader::read(int& length, bool& eos, sample_t* buffer)
{
- // resize if necessary
- if(m_buffer.getSize() < length * sizeof(sample_t))
- {
- m_buffer.resize(length * sizeof(sample_t));
- memset(m_buffer.getBuffer(), 0, m_buffer.getSize());
- }
-
- buffer = m_buffer.getBuffer();
+ memset(buffer, 0, length * sizeof(sample_t));
m_position += length;
+ eos = false;
}
diff --git a/intern/audaspace/intern/AUD_SilenceReader.h b/intern/audaspace/intern/AUD_SilenceReader.h
index b35b4cfab42..29966aef0a7 100644
--- a/intern/audaspace/intern/AUD_SilenceReader.h
+++ b/intern/audaspace/intern/AUD_SilenceReader.h
@@ -51,11 +51,6 @@ private:
*/
int m_position;
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
// hide copy constructor and operator=
AUD_SilenceReader(const AUD_SilenceReader&);
AUD_SilenceReader& operator=(const AUD_SilenceReader&);
@@ -71,7 +66,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SILENCEREADER
diff --git a/intern/audaspace/intern/AUD_SinusFactory.cpp b/intern/audaspace/intern/AUD_SinusFactory.cpp
index 9ea7a031b16..b79f6bee6d7 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.cpp
+++ b/intern/audaspace/intern/AUD_SinusFactory.cpp
@@ -44,7 +44,7 @@ float AUD_SinusFactory::getFrequency() const
return m_frequency;
}
-AUD_IReader* AUD_SinusFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SinusFactory::createReader()
{
return new AUD_SinusReader(m_frequency, m_sampleRate);
}
diff --git a/intern/audaspace/intern/AUD_SinusFactory.h b/intern/audaspace/intern/AUD_SinusFactory.h
index 6d8b355784b..a6bc7f2110c 100644
--- a/intern/audaspace/intern/AUD_SinusFactory.h
+++ b/intern/audaspace/intern/AUD_SinusFactory.h
@@ -68,7 +68,7 @@ public:
*/
float getFrequency() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SINUSFACTORY
diff --git a/intern/audaspace/intern/AUD_SinusReader.cpp b/intern/audaspace/intern/AUD_SinusReader.cpp
index f32464f067a..bb5477ed5cf 100644
--- a/intern/audaspace/intern/AUD_SinusReader.cpp
+++ b/intern/audaspace/intern/AUD_SinusReader.cpp
@@ -72,19 +72,14 @@ AUD_Specs AUD_SinusReader::getSpecs() const
return specs;
}
-void AUD_SinusReader::read(int & length, sample_t* & buffer)
+void AUD_SinusReader::read(int& length, bool& eos, sample_t* buffer)
{
- // resize if necessary
- if(m_buffer.getSize() < length * sizeof(sample_t))
- m_buffer.resize(length * sizeof(sample_t));
-
// fill with sine data
- buffer = m_buffer.getBuffer();
for(int i = 0; i < length; i++)
{
- buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency /
- (float)m_sampleRate);
+ buffer[i] = sin((m_position + i) * 2 * M_PI * m_frequency / m_sampleRate);
}
m_position += length;
+ eos = false;
}
diff --git a/intern/audaspace/intern/AUD_SinusReader.h b/intern/audaspace/intern/AUD_SinusReader.h
index e807f03226d..69e9a3ca576 100644
--- a/intern/audaspace/intern/AUD_SinusReader.h
+++ b/intern/audaspace/intern/AUD_SinusReader.h
@@ -57,11 +57,6 @@ private:
int m_position;
/**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
* The sample rate for the output.
*/
const AUD_SampleRate m_sampleRate;
@@ -83,7 +78,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SINUSREADER
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.cpp b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
index b44b2f02d29..125b9d705dd 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.cpp
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.cpp
@@ -31,409 +31,780 @@
#include "AUD_SoftwareDevice.h"
#include "AUD_IReader.h"
-#include "AUD_DefaultMixer.h"
+#include "AUD_Mixer.h"
#include "AUD_IFactory.h"
+#ifdef WITH_SAMPLERATE
+#include "AUD_SRCResampleReader.h"
+#else
+#include "AUD_LinearResampleReader.h"
+#endif
#include <cstring>
+#include <cmath>
#include <limits>
-/// Saves the data for playback.
-struct AUD_SoftwareHandle : AUD_Handle
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
+typedef enum
+{
+ AUD_RENDER_DISTANCE = 0x01,
+ AUD_RENDER_DOPPLER = 0x02,
+ AUD_RENDER_CONE = 0x04,
+ AUD_RENDER_VOLUME = 0x08
+} AUD_RenderFlags;
+
+#define AUD_PITCH_MAX 10
+
+/******************************************************************************/
+/********************** AUD_SoftwareHandle Handle Code ************************/
+/******************************************************************************/
+
+AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_PitchReader> pitch, AUD_Reference<AUD_ChannelMapperReader> mapper, bool keep) :
+ m_reader(reader), m_pitch(pitch), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_volume(1.0f), m_loopcount(0),
+ m_relative(false), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
+ m_distance_reference(1.0f), m_attenuation(1.0f), m_cone_angle_outer(M_PI), m_cone_angle_inner(M_PI), m_cone_volume_outer(0),
+ m_flags(AUD_RENDER_CONE), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
{
- /// The reader source.
- AUD_IReader* reader;
+}
- /// Whether to keep the source if end of it is reached.
- bool keep;
+void AUD_SoftwareDevice::AUD_SoftwareHandle::update()
+{
+ int flags = 0;
- /// The volume of the source.
- float volume;
+ AUD_Vector3 SL;
+ if(m_relative)
+ SL = m_location;
+ else
+ SL = m_device->m_location - m_location;
+ float distance = SL * SL;
- /// The loop count of the source.
- int loopcount;
+ if(distance > 0)
+ distance = sqrt(distance);
+ else
+ flags |= AUD_RENDER_DOPPLER | AUD_RENDER_DISTANCE;
- /// The stop callback.
- stopCallback stop;
+ if(m_pitch->getSpecs().channels != AUD_CHANNELS_MONO)
+ {
+ m_volume = m_user_volume;
+ m_pitch->setPitch(m_user_pitch);
+ return;
+ }
- /// Stop callback data.
- void* stop_data;
-};
+ flags = ~(flags | m_flags | m_device->m_flags);
-typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
+ // Doppler and Pitch
-void AUD_SoftwareDevice::create()
-{
- m_playback = false;
- m_volume = 1.0f;
- m_mixer = new AUD_DefaultMixer(m_specs);
+ if(flags & AUD_RENDER_DOPPLER)
+ {
+ float vls;
+ if(m_relative)
+ vls = 0;
+ else
+ vls = SL * m_device->m_velocity / distance;
+ float vss = SL * m_velocity / distance;
+ float max = m_device->m_speed_of_sound / m_device->m_doppler_factor;
+ if(vss >= max)
+ {
+ m_pitch->setPitch(AUD_PITCH_MAX);
+ }
+ else
+ {
+ if(vls > max)
+ vls = max;
- pthread_mutexattr_t attr;
- pthread_mutexattr_init(&attr);
- pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+ m_pitch->setPitch((m_device->m_speed_of_sound - m_device->m_doppler_factor * vls) / (m_device->m_speed_of_sound - m_device->m_doppler_factor * vss) * m_user_pitch);
+ }
+ }
+ else
+ m_pitch->setPitch(m_user_pitch);
- pthread_mutex_init(&m_mutex, &attr);
+ if(flags & AUD_RENDER_VOLUME)
+ {
+ // Distance
- pthread_mutexattr_destroy(&attr);
-}
+ if(flags & AUD_RENDER_DISTANCE)
+ {
+ if(m_device->m_distance_model == AUD_DISTANCE_MODEL_INVERSE_CLAMPED || m_device->m_distance_model == AUD_DISTANCE_MODEL_LINEAR_CLAMPED || m_device->m_distance_model == AUD_DISTANCE_MODEL_EXPONENT_CLAMPED)
+ {
+ distance = AUD_MAX(AUD_MIN(m_distance_max, distance), m_distance_reference);
+ }
-void AUD_SoftwareDevice::destroy()
-{
- if(m_playback)
- playing(m_playback = false);
+ switch(m_device->m_distance_model)
+ {
+ case AUD_DISTANCE_MODEL_INVERSE:
+ case AUD_DISTANCE_MODEL_INVERSE_CLAMPED:
+ m_volume = m_distance_reference / (m_distance_reference + m_attenuation * (distance - m_distance_reference));
+ break;
+ case AUD_DISTANCE_MODEL_LINEAR:
+ case AUD_DISTANCE_MODEL_LINEAR_CLAMPED:
+ {
+ float temp = m_distance_max - m_distance_reference;
+ if(temp == 0)
+ {
+ if(distance > m_distance_reference)
+ m_volume = 0.0f;
+ else
+ m_volume = 1.0f;
+ }
+ else
+ m_volume = 1.0f - m_attenuation * (distance - m_distance_reference) / (m_distance_max - m_distance_reference);
+ break;
+ }
+ case AUD_DISTANCE_MODEL_EXPONENT:
+ case AUD_DISTANCE_MODEL_EXPONENT_CLAMPED:
+ if(m_distance_reference == 0)
+ m_volume = 0;
+ else
+ m_volume = pow(distance / m_distance_reference, -m_attenuation);
+ break;
+ default:
+ m_volume = 1.0f;
+ }
+ }
+ else
+ m_volume = 1.0f;
- delete m_mixer;
+ // Cone
- AUD_SoftwareHandle* handle;
+ if(flags & AUD_RENDER_CONE)
+ {
+ AUD_Vector3 SZ = m_orientation.getLookAt();
- // delete all playing sounds
- while(!m_playingSounds.empty())
- {
- handle = m_playingSounds.front();
- m_playingSounds.pop_front();
- delete handle->reader;
- delete handle;
+ float phi = acos(float(SZ * SL / (SZ.length() * SL.length())));
+ float t = (phi - m_cone_angle_inner)/(m_cone_angle_outer - m_cone_angle_inner);
+
+ if(t > 0)
+ {
+ if(t > 1)
+ m_volume *= m_cone_volume_outer;
+ else
+ m_volume *= 1 + t * (m_cone_volume_outer - 1);
+ }
+ }
+
+ // Volume
+
+ m_volume *= m_user_volume;
}
- // delete all paused sounds
- while(!m_pausedSounds.empty())
+ // 3D Cue
+
+ AUD_Quaternion orientation;
+
+ if(!m_relative)
+ orientation = m_device->m_orientation;
+
+ AUD_Vector3 Z = orientation.getLookAt();
+ AUD_Vector3 N = orientation.getUp();
+ AUD_Vector3 A = N * ((SL * N) / (N * N)) - SL;
+
+ float Asquare = A * A;
+
+ if(Asquare > 0)
{
- handle = m_pausedSounds.front();
- m_pausedSounds.pop_front();
- delete handle->reader;
- delete handle;
- }
+ float phi = acos(float(Z * A / (Z.length() * sqrt(Asquare))));
+ if(N.cross(Z) * A > 0)
+ phi = -phi;
- pthread_mutex_destroy(&m_mutex);
+ m_mapper->setMonoAngle(phi);
+ }
+ else
+ m_mapper->setMonoAngle(0);
}
-void AUD_SoftwareDevice::mix(data_t* buffer, int length)
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
{
- lock();
-
+ if(m_status)
{
- AUD_SoftwareHandle* sound;
- int len;
- int pos;
- sample_t* buf;
- std::list<AUD_SoftwareHandle*> stopSounds;
- std::list<AUD_Buffer*> tempBufs;
- AUD_Buffer* tempbuf;
- int samplesize = AUD_SAMPLE_SIZE(m_specs);
+ m_device->lock();
- // for all sounds
- AUD_HandleIterator it = m_playingSounds.begin();
- while(it != m_playingSounds.end())
+ if(m_status == AUD_STATUS_PLAYING)
{
- sound = *it;
- // increment the iterator to make sure it's valid,
- // in case the sound gets deleted after stopping
- ++it;
+ m_device->m_playingSounds.remove(this);
+ m_device->m_pausedSounds.push_back(this);
- // get the buffer from the source
- pos = 0;
- len = length;
- sound->reader->read(len, buf);
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
+ m_status = AUD_STATUS_PAUSED;
+ m_device->unlock();
- // in case of looping
- while(pos + len < length && sound->loopcount)
- {
- tempbuf = new AUD_Buffer(len * samplesize);
- memcpy(tempbuf->getBuffer(), buf, len * samplesize);
- tempBufs.push_back(tempbuf);
- m_mixer->add(tempbuf->getBuffer(), pos, len, sound->volume);
+ return true;
+ }
- pos += len;
+ m_device->unlock();
+ }
- if(sound->loopcount > 0)
- sound->loopcount--;
+ return false;
+}
- sound->reader->seek(0);
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
+{
+ if(m_status)
+ {
+ m_device->lock();
- len = length - pos;
- sound->reader->read(len, buf);
+ if(m_status == AUD_STATUS_PAUSED)
+ {
+ m_device->m_pausedSounds.remove(this);
+ m_device->m_playingSounds.push_back(this);
- // prevent endless loop
- if(!len)
- break;
- }
+ if(!m_device->m_playback)
+ m_device->playing(m_device->m_playback = true);
+ m_status = AUD_STATUS_PLAYING;
+ m_device->unlock();
+ return true;
+ }
- m_mixer->add(buf, pos, len, sound->volume);
- pos += len;
+ m_device->unlock();
+ }
- // in case the end of the sound is reached
- if(pos < length)
- {
- if(sound->stop)
- sound->stop(sound->stop_data);
+ return false;
+}
- if(sound->keep)
- pause(sound);
- else
- stopSounds.push_back(sound);
- }
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
+{
+ if(!m_status)
+ return false;
- // superpose
- m_mixer->superpose(buffer, length, m_volume);
+ m_device->lock();
- // cleanup
- while(!stopSounds.empty())
- {
- sound = stopSounds.front();
- stopSounds.pop_front();
- stop(sound);
- }
+ // AUD_XXX Create a reference of our own object so that it doesn't get
+ // deleted before the end of this function
+ AUD_Reference<AUD_SoftwareHandle> This = this;
- while(!tempBufs.empty())
- {
- tempbuf = tempBufs.front();
- tempBufs.pop_front();
- delete tempbuf;
- }
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(This);
+
+ if(m_device->m_playingSounds.empty())
+ m_device->playing(m_device->m_playback = false);
}
+ else
+ m_device->m_pausedSounds.remove(This);
- unlock();
+ m_device->unlock();
+ m_status = AUD_STATUS_INVALID;
+ return true;
}
-bool AUD_SoftwareDevice::isValid(AUD_Handle* handle)
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep()
{
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- if(*i == handle)
- return true;
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- if(*i == handle)
- return true;
+ if(m_status)
+ return m_keep;
+
return false;
}
-AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
{
- return m_specs;
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_keep = keep;
+
+ m_device->unlock();
+
+ return true;
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_IReader* reader, bool keep)
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
{
- // prepare the reader
- reader = m_mixer->prepare(reader);
- if(reader == NULL)
- return NULL;
+ if(!m_status)
+ return false;
- // play sound
- AUD_SoftwareHandle* sound = new AUD_SoftwareHandle;
- sound->keep = keep;
- sound->reader = reader;
- sound->volume = 1.0f;
- sound->loopcount = 0;
- sound->stop = NULL;
- sound->stop_data = NULL;
+ m_device->lock();
- lock();
- m_playingSounds.push_back(sound);
+ m_reader->seek((int)(position * m_reader->getSpecs().rate));
- if(!m_playback)
- playing(m_playback = true);
- unlock();
+ m_device->unlock();
- return sound;
+ return true;
}
-AUD_Handle* AUD_SoftwareDevice::play(AUD_IFactory* factory, bool keep)
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
{
- return play(factory->createReader(), keep);
+ if(!m_status)
+ return 0.0f;
+
+ m_device->lock();
+
+ float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
+
+ m_device->unlock();
+
+ return position;
}
-bool AUD_SoftwareDevice::pause(AUD_Handle* handle)
+AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus()
{
- bool result = false;
+ return m_status;
+}
- lock();
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume()
+{
+ return m_user_volume;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
+{
+ if(!m_status)
+ return false;
+ m_user_volume = volume;
- // only songs that are played can be paused
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
+ if(volume == 0)
{
- if(*i == handle)
- {
- m_pausedSounds.push_back(*i);
- m_playingSounds.erase(i);
- if(m_playingSounds.empty())
- playing(m_playback = false);
- result = true;
- break;
- }
+ m_volume = volume;
+ m_flags |= AUD_RENDER_VOLUME;
}
+ else
+ m_flags &= ~AUD_RENDER_VOLUME;
- unlock();
+ return true;
+}
- return result;
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch()
+{
+ return m_user_pitch;
}
-bool AUD_SoftwareDevice::resume(AUD_Handle* handle)
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch)
{
- bool result = false;
+ if(!m_status)
+ return false;
+ m_user_pitch = pitch;
+ return true;
+}
- lock();
+int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount()
+{
+ if(!m_status)
+ return 0;
+ return m_loopcount;
+}
- // only songs that are paused can be resumed
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- {
- if(*i == handle)
- {
- m_playingSounds.push_back(*i);
- m_pausedSounds.erase(i);
- if(!m_playback)
- playing(m_playback = true);
- result = true;
- break;
- }
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
+{
+ if(!m_status)
+ return false;
+ m_loopcount = count;
+ return true;
+}
- unlock();
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data)
+{
+ if(!m_status)
+ return false;
+
+ m_device->lock();
+
+ m_stop = callback;
+ m_stop_data = data;
- return result;
+ m_device->unlock();
+
+ return true;
}
-bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
+
+
+/******************************************************************************/
+/******************** AUD_SoftwareHandle 3DHandle Code ************************/
+/******************************************************************************/
+
+AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceLocation()
{
- bool result = false;
+ if(!m_status)
+ return AUD_Vector3();
- lock();
+ return m_location;
+}
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
- {
- if(*i == handle)
- {
- delete (*i)->reader;
- delete *i;
- m_playingSounds.erase(i);
- if(m_playingSounds.empty())
- playing(m_playback = false);
- result = true;
- break;
- }
- }
- if(!result)
- {
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
- {
- if(*i == handle)
- {
- delete (*i)->reader;
- delete *i;
- m_pausedSounds.erase(i);
- result = true;
- break;
- }
- }
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceLocation(const AUD_Vector3& location)
+{
+ if(!m_status)
+ return false;
- unlock();
+ m_location = location;
- return result;
+ return true;
}
-bool AUD_SoftwareDevice::getKeep(AUD_Handle* handle)
+AUD_Vector3 AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceVelocity()
{
- bool result = false;
+ if(!m_status)
+ return AUD_Vector3();
- lock();
+ return m_velocity;
+}
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->keep;
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceVelocity(const AUD_Vector3& velocity)
+{
+ if(!m_status)
+ return false;
- unlock();
+ m_velocity = velocity;
- return result;
+ return true;
}
-bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
+AUD_Quaternion AUD_SoftwareDevice::AUD_SoftwareHandle::getSourceOrientation()
{
- bool result = false;
+ if(!m_status)
+ return AUD_Quaternion();
- lock();
+ return m_orientation;
+}
- if(isValid(handle))
- {
- ((AUD_SoftwareHandle*)handle)->keep = keep;
- result = true;
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setSourceOrientation(const AUD_Quaternion& orientation)
+{
+ if(!m_status)
+ return false;
- unlock();
+ m_orientation = orientation;
- return result;
+ return true;
}
-bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::isRelative()
{
- lock();
+ if(!m_status)
+ return false;
- bool result = false;
+ return m_relative;
+}
- if(isValid(handle))
- {
- AUD_IReader* reader = ((AUD_SoftwareHandle*)handle)->reader;
- reader->seek((int)(position * reader->getSpecs().rate));
- result = true;
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setRelative(bool relative)
+{
+ if(!m_status)
+ return false;
- unlock();
+ m_relative = relative;
- return result;
+ return true;
}
-float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMaximum()
{
- lock();
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
- float position = 0.0f;
+ return m_volume_max;
+}
- if(isValid(handle))
- {
- AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
- position = h->reader->getPosition() / (float)m_specs.rate;
- }
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMaximum(float volume)
+{
+ if(!m_status)
+ return false;
- unlock();
+ m_volume_max = volume;
- return position;
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolumeMinimum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();;
+
+ return m_volume_min;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolumeMinimum(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_volume_min = volume;
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceMaximum()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_max;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceMaximum(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_max = distance;
+
+ return true;
}
-AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getDistanceReference()
{
- AUD_Status status = AUD_STATUS_INVALID;
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_distance_reference;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setDistanceReference(float distance)
+{
+ if(!m_status)
+ return false;
+
+ m_distance_reference = distance;
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getAttenuation()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_attenuation;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setAttenuation(float factor)
+{
+ if(!m_status)
+ return false;
+
+ m_attenuation = factor;
+
+ if(factor == 0)
+ m_flags |= AUD_RENDER_DISTANCE;
+ else
+ m_flags &= ~AUD_RENDER_DISTANCE;
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_outer * 360.0f / M_PI;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleOuter(float angle)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_angle_outer = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeAngleInner()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();
+
+ return m_cone_angle_inner * 360.0f / M_PI;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeAngleInner(float angle)
+{
+ if(!m_status)
+ return false;
+
+ if(angle >= 360)
+ m_flags |= AUD_RENDER_CONE;
+ else
+ m_flags &= ~AUD_RENDER_CONE;
+
+ m_cone_angle_inner = angle * M_PI / 360.0f;
+
+ return true;
+}
+
+float AUD_SoftwareDevice::AUD_SoftwareHandle::getConeVolumeOuter()
+{
+ if(!m_status)
+ return std::numeric_limits<float>::quiet_NaN();;
+
+ return m_cone_volume_outer;
+}
+
+bool AUD_SoftwareDevice::AUD_SoftwareHandle::setConeVolumeOuter(float volume)
+{
+ if(!m_status)
+ return false;
+
+ m_cone_volume_outer = volume;
+
+ return true;
+}
+
+/******************************************************************************/
+/**************************** IDevice Code ************************************/
+/******************************************************************************/
+
+void AUD_SoftwareDevice::create()
+{
+ m_playback = false;
+ m_volume = 1.0f;
+ m_mixer = new AUD_Mixer(m_specs);
+ m_speed_of_sound = 343.0f;
+ m_doppler_factor = 1.0f;
+ m_distance_model = AUD_DISTANCE_MODEL_INVERSE_CLAMPED;
+ m_flags = 0;
+
+ pthread_mutexattr_t attr;
+ pthread_mutexattr_init(&attr);
+ pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
+
+ pthread_mutex_init(&m_mutex, &attr);
+
+ pthread_mutexattr_destroy(&attr);
+}
+
+void AUD_SoftwareDevice::destroy()
+{
+ if(m_playback)
+ playing(m_playback = false);
+
+ while(!m_playingSounds.empty())
+ m_playingSounds.front()->stop();
+
+ while(!m_pausedSounds.empty())
+ m_pausedSounds.front()->stop();
+
+ pthread_mutex_destroy(&m_mutex);
+}
+
+void AUD_SoftwareDevice::mix(data_t* buffer, int length)
+{
+ m_buffer.assureSize(length * AUD_SAMPLE_SIZE(m_specs));
lock();
- for(AUD_HandleIterator i = m_playingSounds.begin();
- i != m_playingSounds.end(); i++)
{
- if(*i == handle)
- {
- status = AUD_STATUS_PLAYING;
- break;
- }
- }
- if(status == AUD_STATUS_INVALID)
- {
- for(AUD_HandleIterator i = m_pausedSounds.begin();
- i != m_pausedSounds.end(); i++)
+ AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
+ int len;
+ int pos;
+ bool eos;
+ std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
+ sample_t* buf = m_buffer.getBuffer();
+
+ m_mixer->clear(length);
+
+ // for all sounds
+ AUD_HandleIterator it = m_playingSounds.begin();
+ while(it != m_playingSounds.end())
{
- if(*i == handle)
+ sound = *it;
+ // increment the iterator to make sure it's valid,
+ // in case the sound gets deleted after stopping
+ ++it;
+
+ // get the buffer from the source
+ pos = 0;
+ len = length;
+
+ // update 3D Info
+ sound->update();
+
+ sound->m_reader->read(len, eos, buf);
+
+ // in case of looping
+ while(pos + len < length && sound->m_loopcount && eos)
{
- status = AUD_STATUS_PAUSED;
- break;
+ m_mixer->mix(buf, pos, len, sound->m_volume);
+
+ pos += len;
+
+ if(sound->m_loopcount > 0)
+ sound->m_loopcount--;
+
+ sound->m_reader->seek(0);
+
+ len = length - pos;
+ sound->m_reader->read(len, eos, buf);
+
+ // prevent endless loop
+ if(!len)
+ break;
+ }
+
+ m_mixer->mix(buf, pos, len, sound->m_volume);
+
+ // in case the end of the sound is reached
+ if(eos && !sound->m_loopcount)
+ {
+ if(sound->m_stop)
+ sound->m_stop(sound->m_stop_data);
+
+ if(sound->m_keep)
+ sound->pause();
+ else
+ stopSounds.push_back(sound);
}
}
+
+ // superpose
+ m_mixer->read(buffer, m_volume);
+
+ // cleanup
+ while(!stopSounds.empty())
+ {
+ sound = stopSounds.front();
+ stopSounds.pop_front();
+ sound->stop();
+ }
}
unlock();
+}
- return status;
+AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
+{
+ return m_specs;
+}
+
+AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
+{
+ // prepare the reader
+ // pitch
+
+ AUD_Reference<AUD_PitchReader> pitch = new AUD_PitchReader(reader, 1);
+ reader = AUD_Reference<AUD_IReader>(pitch);
+
+ // resample
+ #ifdef WITH_SAMPLERATE
+ reader = new AUD_SRCResampleReader(reader, m_specs.specs);
+ #else
+ reader = new AUD_LinearResampleReader(reader, m_specs.specs);
+ #endif
+
+ // rechannel
+ AUD_Reference<AUD_ChannelMapperReader> mapper = new AUD_ChannelMapperReader(reader, m_specs.channels);
+ reader = AUD_Reference<AUD_IReader>(mapper);
+
+ if(reader.isNull())
+ return NULL;
+
+ // play sound
+ AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, pitch, mapper, keep);
+
+ lock();
+ m_playingSounds.push_back(sound);
+
+ if(!m_playback)
+ playing(m_playback = true);
+ unlock();
+
+ return AUD_Reference<AUD_IHandle>(sound);
+}
+
+AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
+{
+ return play(factory->createReader(), keep);
}
void AUD_SoftwareDevice::lock()
@@ -456,66 +827,74 @@ void AUD_SoftwareDevice::setVolume(float volume)
m_volume = volume;
}
-float AUD_SoftwareDevice::getVolume(AUD_Handle* handle)
+/******************************************************************************/
+/**************************** 3D Device Code **********************************/
+/******************************************************************************/
+
+AUD_Vector3 AUD_SoftwareDevice::getListenerLocation() const
{
- lock();
- float result = std::numeric_limits<float>::quiet_NaN();
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->volume;
- unlock();
- return result;
+ return m_location;
}
-bool AUD_SoftwareDevice::setVolume(AUD_Handle* handle, float volume)
+void AUD_SoftwareDevice::setListenerLocation(const AUD_Vector3& location)
{
- lock();
- bool result = isValid(handle);
- if(result)
- ((AUD_SoftwareHandle*)handle)->volume = volume;
- unlock();
- return result;
+ m_location = location;
}
-float AUD_SoftwareDevice::getPitch(AUD_Handle* handle)
+AUD_Vector3 AUD_SoftwareDevice::getListenerVelocity() const
{
- return std::numeric_limits<float>::quiet_NaN();
+ return m_velocity;
}
-bool AUD_SoftwareDevice::setPitch(AUD_Handle* handle, float pitch)
+void AUD_SoftwareDevice::setListenerVelocity(const AUD_Vector3& velocity)
{
- return false;
+ m_velocity = velocity;
}
-int AUD_SoftwareDevice::getLoopCount(AUD_Handle* handle)
+AUD_Quaternion AUD_SoftwareDevice::getListenerOrientation() const
{
- lock();
- int result = 0;
- if(isValid(handle))
- result = ((AUD_SoftwareHandle*)handle)->loopcount;
- unlock();
- return result;
+ return m_orientation;
}
-bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int count)
+void AUD_SoftwareDevice::setListenerOrientation(const AUD_Quaternion& orientation)
{
- lock();
- bool result = isValid(handle);
- if(result)
- ((AUD_SoftwareHandle*)handle)->loopcount = count;
- unlock();
- return result;
+ m_orientation = orientation;
}
-bool AUD_SoftwareDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
+float AUD_SoftwareDevice::getSpeedOfSound() const
{
- lock();
- bool result = isValid(handle);
- if(result)
- {
- AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
- h->stop = callback;
- h->stop_data = data;
- }
- unlock();
- return result;
+ return m_speed_of_sound;
+}
+
+void AUD_SoftwareDevice::setSpeedOfSound(float speed)
+{
+ m_speed_of_sound = speed;
+}
+
+float AUD_SoftwareDevice::getDopplerFactor() const
+{
+ return m_doppler_factor;
+}
+
+void AUD_SoftwareDevice::setDopplerFactor(float factor)
+{
+ m_doppler_factor = factor;
+ if(factor == 0)
+ m_flags |= AUD_RENDER_DOPPLER;
+ else
+ m_flags &= ~AUD_RENDER_DOPPLER;
+}
+
+AUD_DistanceModel AUD_SoftwareDevice::getDistanceModel() const
+{
+ return m_distance_model;
+}
+
+void AUD_SoftwareDevice::setDistanceModel(AUD_DistanceModel model)
+{
+ m_distance_model = model;
+ if(model == AUD_DISTANCE_MODEL_INVALID)
+ m_flags |= AUD_RENDER_DISTANCE;
+ else
+ m_flags &= ~AUD_RENDER_DISTANCE;
}
diff --git a/intern/audaspace/intern/AUD_SoftwareDevice.h b/intern/audaspace/intern/AUD_SoftwareDevice.h
index 1f6a5ead6e0..c7dbf1d41eb 100644
--- a/intern/audaspace/intern/AUD_SoftwareDevice.h
+++ b/intern/audaspace/intern/AUD_SoftwareDevice.h
@@ -33,9 +33,13 @@
#define AUD_SOFTWAREDEVICE
#include "AUD_IDevice.h"
-struct AUD_SoftwareHandle;
-class AUD_Mixer;
-class AUD_Buffer;
+#include "AUD_IHandle.h"
+#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
+#include "AUD_Mixer.h"
+#include "AUD_Buffer.h"
+#include "AUD_PitchReader.h"
+#include "AUD_ChannelMapperReader.h"
#include <list>
#include <pthread.h>
@@ -48,9 +52,139 @@ class AUD_Buffer;
* - Call the create and destroy functions.
* - Call the mix function to retrieve their audio data.
*/
-class AUD_SoftwareDevice : public AUD_IDevice
+class AUD_SoftwareDevice : public AUD_IDevice, public AUD_I3DDevice
{
protected:
+ /// Saves the data for playback.
+ class AUD_SoftwareHandle : public AUD_IHandle, public AUD_I3DHandle
+ {
+ public:
+ /// The reader source.
+ AUD_Reference<AUD_IReader> m_reader;
+
+ /// The pitch reader in between.
+ AUD_Reference<AUD_PitchReader> m_pitch;
+
+ /// The channel mapper reader in between.
+ AUD_Reference<AUD_ChannelMapperReader> m_mapper;
+
+ /// Whether to keep the source if end of it is reached.
+ bool m_keep;
+
+ /// The user set pitch of the source.
+ float m_user_pitch;
+
+ /// The user set volume of the source.
+ float m_user_volume;
+
+ /// The calculated final volume of the source.
+ float m_volume;
+
+ /// The loop count of the source.
+ int m_loopcount;
+
+ /// Location in 3D Space.
+ AUD_Vector3 m_location;
+
+ /// Velocity in 3D Space.
+ AUD_Vector3 m_velocity;
+
+ /// Orientation in 3D Space.
+ AUD_Quaternion m_orientation;
+
+ /// Whether the position to the listener is relative or absolute
+ bool m_relative;
+
+ /// Maximum volume.
+ float m_volume_max;
+
+ /// Minimum volume.
+ float m_volume_min;
+
+ /// Maximum distance.
+ float m_distance_max;
+
+ /// Reference distance;
+ float m_distance_reference;
+
+ /// Attenuation
+ float m_attenuation;
+
+ /// Cone outer angle.
+ float m_cone_angle_outer;
+
+ /// Cone inner angle.
+ float m_cone_angle_inner;
+
+ /// Cone outer volume.
+ float m_cone_volume_outer;
+
+ /// Rendering flags
+ int m_flags;
+
+ /// The stop callback.
+ stopCallback m_stop;
+
+ /// Stop callback data.
+ void* m_stop_data;
+
+ /// Current status of the handle
+ AUD_Status m_status;
+
+ /// Own device.
+ AUD_SoftwareDevice* m_device;
+
+ public:
+
+ AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, AUD_Reference<AUD_PitchReader> pitch, AUD_Reference<AUD_ChannelMapperReader> mapper, bool keep);
+
+ void update();
+
+ virtual ~AUD_SoftwareHandle() {}
+ virtual bool pause();
+ virtual bool resume();
+ virtual bool stop();
+ virtual bool getKeep();
+ virtual bool setKeep(bool keep);
+ virtual bool seek(float position);
+ virtual float getPosition();
+ virtual AUD_Status getStatus();
+ virtual float getVolume();
+ virtual bool setVolume(float volume);
+ virtual float getPitch();
+ virtual bool setPitch(float pitch);
+ virtual int getLoopCount();
+ virtual bool setLoopCount(int count);
+ virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
+
+ virtual AUD_Vector3 getSourceLocation();
+ virtual bool setSourceLocation(const AUD_Vector3& location);
+ virtual AUD_Vector3 getSourceVelocity();
+ virtual bool setSourceVelocity(const AUD_Vector3& velocity);
+ virtual AUD_Quaternion getSourceOrientation();
+ virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
+ virtual bool isRelative();
+ virtual bool setRelative(bool relative);
+ virtual float getVolumeMaximum();
+ virtual bool setVolumeMaximum(float volume);
+ virtual float getVolumeMinimum();
+ virtual bool setVolumeMinimum(float volume);
+ virtual float getDistanceMaximum();
+ virtual bool setDistanceMaximum(float distance);
+ virtual float getDistanceReference();
+ virtual bool setDistanceReference(float distance);
+ virtual float getAttenuation();
+ virtual bool setAttenuation(float factor);
+ virtual float getConeAngleOuter();
+ virtual bool setConeAngleOuter(float angle);
+ virtual float getConeAngleInner();
+ virtual bool setConeAngleInner(float angle);
+ virtual float getConeVolumeOuter();
+ virtual bool setConeVolumeOuter(float volume);
+ };
+
+ typedef std::list<AUD_Reference<AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
+
/**
* The specification of the device.
*/
@@ -59,7 +193,7 @@ protected:
/**
* The mixer.
*/
- AUD_Mixer* m_mixer;
+ AUD_Reference<AUD_Mixer> m_mixer;
/**
* Initializes member variables.
@@ -86,14 +220,19 @@ protected:
private:
/**
+ * The reading buffer.
+ */
+ AUD_Buffer m_buffer;
+
+ /**
* The list of sounds that are currently playing.
*/
- std::list<AUD_SoftwareHandle*> m_playingSounds;
+ std::list<AUD_Reference<AUD_SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
- std::list<AUD_SoftwareHandle*> m_pausedSounds;
+ std::list<AUD_Reference<AUD_SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -110,36 +249,48 @@ private:
*/
float m_volume;
- /**
- * Checks if a handle is valid.
- * \param handle The handle to check.
- * \return Whether the handle is valid.
- */
- bool isValid(AUD_Handle* handle);
+ /// Listener location.
+ AUD_Vector3 m_location;
+
+ /// Listener velocity.
+ AUD_Vector3 m_velocity;
+
+ /// Listener orientation.
+ AUD_Quaternion m_orientation;
+
+ /// Speed of Sound.
+ float m_speed_of_sound;
+
+ /// Doppler factor.
+ float m_doppler_factor;
+
+ /// Distance model.
+ AUD_DistanceModel m_distance_model;
+
+ /// Rendering flags
+ int m_flags;
public:
virtual AUD_DeviceSpecs getSpecs() const;
- virtual AUD_Handle* play(AUD_IReader* reader, bool keep = false);
- virtual AUD_Handle* play(AUD_IFactory* factory, bool keep = false);
- virtual bool pause(AUD_Handle* handle);
- virtual bool resume(AUD_Handle* handle);
- virtual bool stop(AUD_Handle* handle);
- virtual bool getKeep(AUD_Handle* handle);
- virtual bool setKeep(AUD_Handle* handle, bool keep);
- virtual bool seek(AUD_Handle* handle, float position);
- virtual float getPosition(AUD_Handle* handle);
- virtual AUD_Status getStatus(AUD_Handle* handle);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
+ virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
- virtual float getVolume(AUD_Handle* handle);
- virtual bool setVolume(AUD_Handle* handle, float volume);
- virtual float getPitch(AUD_Handle* handle);
- virtual bool setPitch(AUD_Handle* handle, float pitch);
- virtual int getLoopCount(AUD_Handle* handle);
- virtual bool setLoopCount(AUD_Handle* handle, int count);
- virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = NULL, void* data = NULL);
+
+ virtual AUD_Vector3 getListenerLocation() const;
+ virtual void setListenerLocation(const AUD_Vector3& location);
+ virtual AUD_Vector3 getListenerVelocity() const;
+ virtual void setListenerVelocity(const AUD_Vector3& velocity);
+ virtual AUD_Quaternion getListenerOrientation() const;
+ virtual void setListenerOrientation(const AUD_Quaternion& orientation);
+ virtual float getSpeedOfSound() const;
+ virtual void setSpeedOfSound(float speed);
+ virtual float getDopplerFactor() const;
+ virtual void setDopplerFactor(float factor);
+ virtual AUD_DistanceModel getDistanceModel() const;
+ virtual void setDistanceModel(AUD_DistanceModel model);
};
#endif //AUD_SOFTWAREDEVICE
diff --git a/intern/audaspace/intern/AUD_Space.h b/intern/audaspace/intern/AUD_Space.h
index ee28a05b80d..308e032ff7f 100644
--- a/intern/audaspace/intern/AUD_Space.h
+++ b/intern/audaspace/intern/AUD_Space.h
@@ -41,6 +41,9 @@
/// Throws a AUD_Exception with the provided error code.
#define AUD_THROW(exception, errorstr) { AUD_Exception e; e.error = exception; e.str = errorstr; throw e; }
+/// Returns the bit for a channel mask.
+#define AUD_CHANNEL_BIT(channel) (0x01 << channel)
+
/// Returns the smaller of the two values.
#define AUD_MIN(a, b) (((a) < (b)) ? (a) : (b))
/// Returns the bigger of the two values.
@@ -79,10 +82,24 @@ typedef enum
AUD_CHANNELS_SURROUND5 = 5, /// 5 channel surround sound.
AUD_CHANNELS_SURROUND51 = 6, /// 5.1 surround sound.
AUD_CHANNELS_SURROUND61 = 7, /// 6.1 surround sound.
- AUD_CHANNELS_SURROUND71 = 8, /// 7.1 surround sound.
- AUD_CHANNELS_SURROUND72 = 9 /// 7.2 surround sound.
+ AUD_CHANNELS_SURROUND71 = 8 /// 7.1 surround sound.
} AUD_Channels;
+/// The channel names.
+typedef enum
+{
+ AUD_CHANNEL_FRONT_LEFT = 0,
+ AUD_CHANNEL_FRONT_RIGHT,
+ AUD_CHANNEL_FRONT_CENTER,
+ AUD_CHANNEL_LFE,
+ AUD_CHANNEL_REAR_LEFT,
+ AUD_CHANNEL_REAR_RIGHT,
+ AUD_CHANNEL_REAR_CENTER,
+ AUD_CHANNEL_SIDE_LEFT,
+ AUD_CHANNEL_SIDE_RIGHT,
+ AUD_CHANNEL_MAX
+} AUD_Channel;
+
/**
* The sample rate tells how many samples are played back within one second.
* Some exotic formats may use other sample rates than provided here.
@@ -100,7 +117,7 @@ typedef enum
AUD_RATE_88200 = 88200, /// 88200 Hz.
AUD_RATE_96000 = 96000, /// 96000 Hz.
AUD_RATE_192000 = 192000 /// 192000 Hz.
-} AUD_SampleRate;
+} AUD_DefaultSampleRate;
/// Status of a playback handle.
typedef enum
@@ -149,6 +166,9 @@ typedef float sample_t;
/// Sample data type (format samples)
typedef unsigned char data_t;
+/// Sample rate type.
+typedef double AUD_SampleRate;
+
/// Specification of a sound source.
typedef struct
{
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
index c25442b6f26..ff966c86025 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.cpp
@@ -35,17 +35,17 @@
#include <cstring>
-AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory) :
+AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory) :
m_buffer(new AUD_Buffer())
{
- AUD_IReader* reader = factory->createReader();
+ AUD_Reference<AUD_IReader> reader = factory->createReader();
m_specs = reader->getSpecs();
int sample_size = AUD_SAMPLE_SIZE(m_specs);
int length;
int index = 0;
- sample_t* buffer;
+ bool eos = false;
// get an approximated size if possible
int size = reader->getLength();
@@ -55,27 +55,24 @@ AUD_StreamBufferFactory::AUD_StreamBufferFactory(AUD_IFactory* factory) :
else
size += m_specs.rate;
- // as long as we fill our buffer to the end
- while(index == m_buffer.get()->getSize() / sample_size)
+ // as long as the end of the stream is not reached
+ while(!eos)
{
// increase
- m_buffer.get()->resize(size*sample_size, true);
+ m_buffer->resize(size*sample_size, true);
// read more
length = size-index;
- reader->read(length, buffer);
- memcpy(m_buffer.get()->getBuffer() + index * m_specs.channels,
- buffer,
- length * sample_size);
- size += AUD_BUFFER_RESIZE_BYTES / sample_size;
+ reader->read(length, eos, m_buffer->getBuffer() + index * m_specs.channels);
+ if(index == m_buffer->getSize() / sample_size)
+ size += AUD_BUFFER_RESIZE_BYTES / sample_size;
index += length;
}
- m_buffer.get()->resize(index * sample_size, true);
- delete reader;
+ m_buffer->resize(index * sample_size, true);
}
-AUD_IReader* AUD_StreamBufferFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_StreamBufferFactory::createReader()
{
return new AUD_BufferReader(m_buffer, m_specs);
}
diff --git a/intern/audaspace/intern/AUD_StreamBufferFactory.h b/intern/audaspace/intern/AUD_StreamBufferFactory.h
index b6a44d95744..2783889ff6c 100644
--- a/intern/audaspace/intern/AUD_StreamBufferFactory.h
+++ b/intern/audaspace/intern/AUD_StreamBufferFactory.h
@@ -64,9 +64,9 @@ public:
* \param factory The factory that creates the reader for buffering.
* \exception AUD_Exception Thrown if the reader cannot be created.
*/
- AUD_StreamBufferFactory(AUD_IFactory* factory);
+ AUD_StreamBufferFactory(AUD_Reference<AUD_IFactory> factory);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_STREAMBUFFERFACTORY
diff --git a/intern/audaspace/jack/AUD_JackDevice.cpp b/intern/audaspace/jack/AUD_JackDevice.cpp
index 03a740f5fbf..a8b2625b848 100644
--- a/intern/audaspace/jack/AUD_JackDevice.cpp
+++ b/intern/audaspace/jack/AUD_JackDevice.cpp
@@ -28,8 +28,6 @@
* \ingroup audjack
*/
-
-#include "AUD_Mixer.h"
#include "AUD_JackDevice.h"
#include "AUD_IReader.h"
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
index 2d1d29e50f5..5a0280cdf84 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.cpp
@@ -43,13 +43,13 @@ AUD_SndFileFactory::AUD_SndFileFactory(std::string filename) :
AUD_SndFileFactory::AUD_SndFileFactory(const data_t* buffer, int size) :
m_buffer(new AUD_Buffer(size))
{
- memcpy(m_buffer.get()->getBuffer(), buffer, size);
+ memcpy(m_buffer->getBuffer(), buffer, size);
}
-AUD_IReader* AUD_SndFileFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_SndFileFactory::createReader()
{
- if(m_buffer.get())
- return new AUD_SndFileReader(m_buffer);
- else
+ if(m_buffer.isNull())
return new AUD_SndFileReader(m_filename);
+ else
+ return new AUD_SndFileReader(m_buffer);
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileFactory.h b/intern/audaspace/sndfile/AUD_SndFileFactory.h
index 9c747e1df01..a46dc165264 100644
--- a/intern/audaspace/sndfile/AUD_SndFileFactory.h
+++ b/intern/audaspace/sndfile/AUD_SndFileFactory.h
@@ -72,7 +72,7 @@ public:
*/
AUD_SndFileFactory(const data_t* buffer, int size);
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_SNDFILEFACTORY
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.cpp b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
index f226d2eee4d..16c90b6f0f1 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.cpp
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.cpp
@@ -36,7 +36,7 @@
sf_count_t AUD_SndFileReader::vio_get_filelen(void *user_data)
{
AUD_SndFileReader* reader = (AUD_SndFileReader*)user_data;
- return reader->m_membuffer.get()->getSize();
+ return reader->m_membuffer->getSize();
}
sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
@@ -53,7 +53,7 @@ sf_count_t AUD_SndFileReader::vio_seek(sf_count_t offset, int whence,
reader->m_memoffset = reader->m_memoffset + offset;
break;
case SEEK_END:
- reader->m_memoffset = reader->m_membuffer.get()->getSize() + offset;
+ reader->m_memoffset = reader->m_membuffer->getSize() + offset;
break;
}
@@ -65,10 +65,10 @@ sf_count_t AUD_SndFileReader::vio_read(void *ptr, sf_count_t count,
{
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;
+ if(reader->m_memoffset + count > reader->m_membuffer->getSize())
+ count = reader->m_membuffer->getSize() - reader->m_memoffset;
- memcpy(ptr, ((data_t*)reader->m_membuffer.get()->getBuffer()) +
+ memcpy(ptr, ((data_t*)reader->m_membuffer->getBuffer()) +
reader->m_memoffset, count);
reader->m_memoffset += count;
@@ -161,17 +161,13 @@ AUD_Specs AUD_SndFileReader::getSpecs() const
return m_specs;
}
-void AUD_SndFileReader::read(int & length, sample_t* & buffer)
+void AUD_SndFileReader::read(int& length, bool& eos, sample_t* buffer)
{
- int sample_size = AUD_SAMPLE_SIZE(m_specs);
-
- // resize output buffer if necessary
- if(m_buffer.getSize() < length*sample_size)
- m_buffer.resize(length*sample_size);
-
- buffer = m_buffer.getBuffer();
+ int olen = length;
length = sf_readf_float(m_sndfile, buffer, length);
m_position += length;
+
+ eos = length < olen;
}
diff --git a/intern/audaspace/sndfile/AUD_SndFileReader.h b/intern/audaspace/sndfile/AUD_SndFileReader.h
index af095819c0e..e7f9e9bf6d6 100644
--- a/intern/audaspace/sndfile/AUD_SndFileReader.h
+++ b/intern/audaspace/sndfile/AUD_SndFileReader.h
@@ -68,11 +68,6 @@ private:
AUD_Specs m_specs;
/**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
- /**
* The sndfile.
*/
SNDFILE* m_sndfile;
@@ -129,7 +124,7 @@ public:
virtual int getLength() const;
virtual int getPosition() const;
virtual AUD_Specs getSpecs() const;
- virtual void read(int & length, sample_t* & buffer);
+ virtual void read(int& length, bool& eos, sample_t* buffer);
};
#endif //AUD_SNDFILEREADER