Return the value matching key, or the default value if its not found.
:return: The key value or a default.
+ .. method:: playAction(name, start_frame, end_frame, layer=0, priority=0 blendin=0, play_mode=ACT_MODE_PLAY, layer_weight=0.0, ipo_flags=0, speed=1.0)
+
+ Plays an action.
+
+ :arg name: the name of the action
+ :type name: string
+ :arg start: the start frame of the action
+ :type start: float
+ :arg end: the end frame of the action
+ :type end: float
+ :arg layer: the layer the action will play in (actions in different layers are added/blended together)
+ :type layer: integer
+ :arg priority: only play this action if there isn't an action currently playing in this layer with a higher (lower number) priority
+ :type priority: integer
+ :arg blendin: the amount of blending between this animation and the previous one on this layer
+ :type blendin: float
+ :arg play_mode: the play mode
+ :type play_mode: KX_ACTION_PLAY, KX_ACTION_LOOP, or KX_ACTION_PING_PONG
+ :arg layer_weight: how much of the previous layer to use for blending (0 = add)
+ :type layer_weight: float
+ :arg ipo_flags: flags for the old IPO behaviors (force, etc)
+ :type ipo_flags: int bitfield
+ :arg speed: the playback speed of the action as a factor (1.0 = normal speed, 2.0 = 2x speed, etc)
+ :type speed: float
+
+ .. method:: getActionFrame(layer)
+
+ Gets the current frame of the action playing in the supplied layer
+
+ :arg layer: The layer that you want to get the frame from.
+ :type layer: integer
+
+ :return: The current frame of the action
+
+ .. method:: setActionFrame(layer, frame)
+
+ Set the current frame of the action playing in the supplied layer
+
+ :arg layer: The layer where you want to set the frame
+ :type layer: integer
+ :arg frame: The frame to set the action to
+ :type frame: float
+
.. class:: KX_IpoActuator(SCA_IActuator)
IPO actuator activates an animation.
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
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
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
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
#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);
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);
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);
#define AUD_ACCUMULATORFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory creates an accumulator reader.
* \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
#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()
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;
}
}
}
+
+void AUD_BaseIIRFilterReader::sampleRateChanged(AUD_SampleRate rate)
+{
+}
{
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.
* \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
#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;
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);
b.push_back(6 * o4 / norm);
b.push_back(b[1]);
b.push_back(b[0]);
-
- return new AUD_IIRFilterReader(reader, b, a);
}
#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:
/**
* \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
#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,
* \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);
#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)
{
return m_delay;
}
-AUD_IReader* AUD_DelayFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_DelayFactory::createReader()
{
return new AUD_DelayReader(getReader(), m_delay);
}
* \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
#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))
{
}
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);
}
class AUD_DelayReader : public AUD_EffectReader
{
private:
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
/**
* The delay level.
*/
*/
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&);
* \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
#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);
}
/**
* 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&);
* \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
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
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);
}
}
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
/**
* 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.
* \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.
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
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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
--- /dev/null
+/*
+ * $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);
+}
--- /dev/null
+/*
+ * $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
#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;
}
{
}
-AUD_IFactory* AUD_EffectFactory::getFactory() const
+AUD_Reference<AUD_IFactory> AUD_EffectFactory::getFactory() const
{
return m_factory;
}
/**
* 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.
* 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();
}
* Creates a new factory.
* \param factory The input factory.
*/
- AUD_EffectFactory(AUD_IFactory* factory);
+ AUD_EffectFactory(AUD_Reference<AUD_IFactory> factory);
/**
* Destroys the factory.
* 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
#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
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);
}
#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
/**
* 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.
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
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);
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),
{
}
-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,
#define AUD_ENVELOPEFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
+struct EnvelopeParameters;
/**
* This factory creates an envelope follower reader.
* \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
#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),
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);
}
* \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);
*/
float getLength() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_FADERFACTORY
#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++)
volume = 1.0f - volume;
}
- buf[i] = buffer[i] * volume;
+ buffer[i] = buffer[i] * volume;
}
-
- buffer = buf;
- m_empty = false;
}
}
*/
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&);
* \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
#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);
}
#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:
/**
* \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
#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);
}
* \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
#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++)
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;
+}
* \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
#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),
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);
}
* \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);
/**
*/
float getEnd() const;
- virtual AUD_IReader* createReader() const;
+ virtual AUD_Reference<AUD_IReader> createReader();
};
#endif //AUD_LIMITERFACTORY
#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));
+ }
}
}
}
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);
}
/**
* 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&);
* \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
#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)
{
return m_loop;
}
-AUD_IReader* AUD_LoopFactory::createReader() const
+AUD_Reference<AUD_IReader> AUD_LoopFactory::createReader()
{
return new AUD_LoopReader(getReader(), m_loop);
}
* \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
#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)
{
}
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--;
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;
}
class AUD_LoopReader : public AUD_EffectReader
{
private:
- /**
- * The playback buffer.
- */
- AUD_Buffer m_buffer;
-
/**
* The loop count.
*/
* \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
#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);
}
#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:
/**
* \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
#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);
}
* 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
#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);
}
* \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
#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)
{
}
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;
+}
/**
* The pitch level.
*/
- const float m_pitch;
+ float m_pitch;
// hide copy constructor and operator=
AUD_PitchReader(const AUD_PitchReader&);
* \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
#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);
}
#define AUD_RECTIFYFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory rectifies another factory.
* 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
#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());
}
* 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
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)
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)
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;
}
*/
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&);
* \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
#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)
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)
{
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,
#define AUD_SQUAREFACTORY
#include "AUD_EffectFactory.h"
+class AUD_CallbackIIRFilterReader;
/**
* This factory Transforms any signal to a square signal.
* \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
#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);
* 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
#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);
}
/**
* 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&);
* \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
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
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;
}
#include "AUD_IReader.h"
#include "AUD_Buffer.h"
+#include "AUD_Reference.h"
/**
* This reader plays two readers with the same specs sequently.
/**
* 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.
* \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.
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
#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)
{
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);
* \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
#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.";
+
+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)
+{
+ AUD_DeviceSpecs specs = m_device->m_specs;
+ specs.specs = m_reader->getSpecs();
+
+ // OpenAL playback code
+ alGenBuffers(CYCLE_BUFFERS, m_buffers);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, genbuffer_error);
+
+ try
+ {
+ m_device->m_buffer.assureSize(m_device->m_buffersize * AUD_DEVICE_SAMPLE_SIZE(specs));
+ int length;
+ bool eos;
+
+ 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);
+ }
+
+ alGenSources(1, &m_source);
+ if(alGetError() != AL_NO_ERROR)
+ AUD_THROW(AUD_ERROR_OPENAL, gensource_error);
+
+ 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);
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
+{
+ if(m_status)
+ {
+ m_device->lock();
+
+ if(m_status == AUD_STATUS_PLAYING)
+ {
+ m_device->m_playingSounds.remove(this);
+ m_device->m_pausedSounds.push_back(this);
+
+ alSourcePause(m_source);
+
+ m_status = AUD_STATUS_PAUSED;
+ m_device->unlock();
+
+ return true;
+ }
+
+ m_device->unlock();
+ }
+
+ return false;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
+{
+ if(m_status)
+ {
+ m_device->lock();
+
+ 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();
+
+ 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;
+}
+
+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 = std::numeric_limits<float>::quiet_NaN();
+
+ if(!m_status)
+ return result;
+
+ 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();
-/// Saves the data for playback.
-struct AUD_OpenALHandle : AUD_Handle
+ alGetSourcef(m_source, AL_CONE_OUTER_ANGLE, &result);
+
+ m_device->unlock();
+
+ return result;
+}
+
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleOuter(float angle)
{
- /// Whether it's a buffered or a streamed source.
- bool isBuffered;
+ if(!m_status)
+ return false;
- /// The reader source.
- AUD_IReader* reader;
+ m_device->lock();
- /// Whether to keep the source if end of it is reached.
- bool keep;
+ alSourcef(m_source, AL_CONE_OUTER_ANGLE, angle);
- /// OpenAL sample format.
- ALenum format;
+ m_device->unlock();
- /// OpenAL source.
- ALuint source;
+ return true;
+}
- /// OpenAL buffers.
- ALuint buffers[AUD_OPENAL_CYCLE_BUFFERS];
+float AUD_OpenALDevice::AUD_OpenALHandle::getConeAngleInner()
+{
+ float result = std::numeric_limits<float>::quiet_NaN();
- /// The first buffer to be read next.
- int current;
+ if(!m_status)
+ return result;
- /// Whether the stream doesn't return any more data.
- bool data_end;
+ m_device->lock();
- /// The loop count of the source.
- int loopcount;
+ alGetSourcef(m_source, AL_CONE_INNER_ANGLE, &result);
- /// The stop callback.
- stopCallback stop;
+ m_device->unlock();
- /// Stop callback data.
- void* stop_data;
-};
+ return result;
+}
-struct AUD_OpenALBufferedFactory
+bool AUD_OpenALDevice::AUD_OpenALHandle::setConeAngleInner(float angle)
{
- /// The factory.
- AUD_IFactory* factory;
+ if(!m_status)
+ return false;
- /// The OpenAL buffer.
- ALuint buffer;
-};
+ 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();
-typedef std::list<AUD_OpenALHandle*>::iterator AUD_HandleIterator;
-typedef std::list<AUD_OpenALBufferedFactory*>::iterator AUD_BFIterator;
+ return true;
+}
/******************************************************************************/
/**************************** Threading Code **********************************/
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)
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;
}
// 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
}
// 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();
}
// stop thread
- if(m_playingSounds->empty() || (cerr != ALC_NO_ERROR))
+ if(m_playingSounds.empty() || (cerr != ALC_NO_ERROR))
{
unlock();
m_playing = false;
/**************************** 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)
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);
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);
else
unlock();
- delete m_playingSounds;
- delete m_pausedSounds;
- delete m_bufferedFactories;
+ //delete m_bufferedFactories;
// quit OpenAL
alcMakeContextCurrent(NULL);
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();
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;
unlock();
if(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 sound;*/
- return status;
+ return play(factory->createReader(), keep);
}
void AUD_OpenALDevice::lock()
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)
if(!getFormat(format, specs.specs))
{
- delete reader;
return false;
}
catch(AUD_Exception&)
{
delete bf;
- delete reader;
alcProcessContext(m_context);
unlock();
return false;
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;
-}
#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>
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.
*/
/**
* 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.
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.
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);
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
#include "structmember.h"
#include "AUD_I3DDevice.h"
+#include "AUD_I3DHandle.h"
#include "AUD_NULLDevice.h"
#include "AUD_DelayFactory.h"
#include "AUD_DoubleFactory.h"
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);
}
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
{
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)
{
{
try
{
- self->factory = new AUD_FileFactory(filename);
+ self->factory = new AUD_Reference<AUD_IFactory>(new AUD_FileFactory(filename));
}
catch(AUD_Exception& e)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
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)
{
{
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)
{
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)
{
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)
{
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);
}
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)
{
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)
{
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)
{
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)
{
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!");
}
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)
{
}
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!");
}
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)
{
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)
{
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!");
}
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)
{
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!");
}
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)
{
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!");
}
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
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!");
}
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
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!");
}
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
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!");
}
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
{
}
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!");
}
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
{
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!");
}
static PyObject *
Handle_get_volume_maximum(Handle *self, void* nothing)