3D Audio GSoC:

- Created Handle classes
- Changed Reference counting completely
- Fixing some streaming bugs
- Completely disabled OpenAL Buffered Factories (they were unused anyway)
This commit is contained in:
Joerg Mueller
2011-06-21 20:21:43 +00:00
parent cc71dcc218
commit 044887b5a4
23 changed files with 1946 additions and 2066 deletions

View File

@@ -87,8 +87,10 @@ set(SRC
intern/AUD_FileFactory.cpp
intern/AUD_FileFactory.h
intern/AUD_I3DDevice.h
intern/AUD_I3DHandle.h
intern/AUD_IDevice.h
intern/AUD_IFactory.h
intern/AUD_IHandle.h
intern/AUD_IReader.h
intern/AUD_LinearResampleFactory.cpp
intern/AUD_LinearResampleFactory.h
@@ -104,6 +106,7 @@ set(SRC
intern/AUD_ReadDevice.cpp
intern/AUD_ReadDevice.h
intern/AUD_Reference.h
intern/AUD_ReferenceHandler.cpp
intern/AUD_ResampleFactory.h
intern/AUD_SequencerFactory.cpp
intern/AUD_SequencerFactory.h

View File

@@ -91,6 +91,8 @@ AUD_Specs AUD_DoubleReader::getSpecs() const
void AUD_DoubleReader::read(int& length, bool& eos, sample_t* buffer)
{
eos = false;
if(!m_finished1)
{
int len = length;

File diff suppressed because it is too large Load Diff

View File

@@ -33,10 +33,11 @@
#define AUD_OPENALDEVICE
#include "AUD_IDevice.h"
#include "AUD_IHandle.h"
#include "AUD_I3DDevice.h"
#include "AUD_I3DHandle.h"
#include "AUD_Buffer.h"
struct AUD_OpenALHandle;
struct AUD_OpenALBufferedFactory;
//struct AUD_OpenALBufferedFactory;
#include <AL/al.h>
#include <AL/alc.h>
@@ -49,6 +50,99 @@ struct AUD_OpenALBufferedFactory;
class AUD_OpenALDevice : public AUD_IDevice, public AUD_I3DDevice
{
private:
/// Saves the data for playback.
class AUD_OpenALHandle : public AUD_IHandle, public AUD_I3DHandle
{
public:
static const int CYCLE_BUFFERS = 3;
/// Whether it's a buffered or a streamed source.
bool m_isBuffered;
/// The reader source.
AUD_Reference<AUD_IReader> m_reader;
/// Whether to keep the source if end of it is reached.
bool m_keep;
/// OpenAL sample format.
ALenum m_format;
/// OpenAL source.
ALuint m_source;
/// OpenAL buffers.
ALuint m_buffers[CYCLE_BUFFERS];
/// The first buffer to be read next.
int m_current;
/// Whether the stream doesn't return any more data.
bool m_eos;
/// The loop count of the source.
int m_loopcount;
/// The stop callback.
stopCallback m_stop;
/// Stop callback data.
void* m_stop_data;
/// Current status of the handle
AUD_Status m_status;
/// Own device.
AUD_OpenALDevice* m_device;
public:
AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, AUD_Reference<AUD_IReader> reader, bool keep);
virtual ~AUD_OpenALHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
virtual bool getKeep();
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
virtual AUD_Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
virtual bool setPitch(float pitch);
virtual int getLoopCount();
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
virtual AUD_Vector3 getSourceLocation();
virtual bool setSourceLocation(const AUD_Vector3& location);
virtual AUD_Vector3 getSourceVelocity();
virtual bool setSourceVelocity(const AUD_Vector3& velocity);
virtual AUD_Quaternion getSourceOrientation();
virtual bool setSourceOrientation(const AUD_Quaternion& orientation);
virtual bool isRelative();
virtual bool setRelative(bool relative);
virtual float getVolumeMaximum();
virtual bool setVolumeMaximum(float volume);
virtual float getVolumeMinimum();
virtual bool setVolumeMinimum(float volume);
virtual float getDistanceMaximum();
virtual bool setDistanceMaximum(float distance);
virtual float getDistanceReference();
virtual bool setDistanceReference(float distance);
virtual float getAttenuation();
virtual bool setAttenuation(float factor);
virtual float getConeAngleOuter();
virtual bool setConeAngleOuter(float angle);
virtual float getConeAngleInner();
virtual bool setConeAngleInner(float angle);
virtual float getConeVolumeOuter();
virtual bool setConeVolumeOuter(float volume);
};
/**
* The OpenAL device handle.
*/
@@ -72,17 +166,17 @@ private:
/**
* The list of sounds that are currently playing.
*/
std::list<AUD_OpenALHandle*>* m_playingSounds;
std::list<AUD_Reference<AUD_OpenALHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
std::list<AUD_OpenALHandle*>* m_pausedSounds;
std::list<AUD_Reference<AUD_OpenALHandle> > m_pausedSounds;
/**
* The list of buffered factories.
*/
std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
//std::list<AUD_OpenALBufferedFactory*>* m_bufferedFactories;
/**
* The mutex for locking.
@@ -114,13 +208,6 @@ private:
*/
void start();
/**
* Checks if a handle is valid.
* \param handle The handle to check.
* \return Whether the handle is valid.
*/
bool isValid(AUD_Handle* handle);
/**
* Gets the format according to the specs.
* \param format The variable to put the format into.
@@ -153,27 +240,12 @@ public:
virtual ~AUD_OpenALDevice();
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Handle* play(AUD_Reference<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);
@@ -187,30 +259,6 @@ public:
virtual void setDopplerFactor(float factor);
virtual AUD_DistanceModel getDistanceModel() const;
virtual void setDistanceModel(AUD_DistanceModel model);
virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle);
virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location);
virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle);
virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity);
virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle);
virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation);
virtual bool isRelative(AUD_Handle* handle);
virtual bool setRelative(AUD_Handle* handle, bool relative);
virtual float getVolumeMaximum(AUD_Handle* handle);
virtual bool setVolumeMaximum(AUD_Handle* handle, float volume);
virtual float getVolumeMinimum(AUD_Handle* handle);
virtual bool setVolumeMinimum(AUD_Handle* handle, float volume);
virtual float getDistanceMaximum(AUD_Handle* handle);
virtual bool setDistanceMaximum(AUD_Handle* handle, float distance);
virtual float getDistanceReference(AUD_Handle* handle);
virtual bool setDistanceReference(AUD_Handle* handle, float distance);
virtual float getAttenuation(AUD_Handle* handle);
virtual bool setAttenuation(AUD_Handle* handle, float factor);
virtual float getConeAngleOuter(AUD_Handle* handle);
virtual bool setConeAngleOuter(AUD_Handle* handle, float angle);
virtual float getConeAngleInner(AUD_Handle* handle);
virtual bool setConeAngleInner(AUD_Handle* handle, float angle);
virtual float getConeVolumeOuter(AUD_Handle* handle);
virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume);
};
#endif //AUD_OPENALDEVICE

View File

@@ -33,6 +33,7 @@
#include "structmember.h"
#include "AUD_I3DDevice.h"
#include "AUD_I3DHandle.h"
#include "AUD_NULLDevice.h"
#include "AUD_DelayFactory.h"
#include "AUD_DoubleFactory.h"
@@ -1033,7 +1034,8 @@ static PyTypeObject FactoryType = {
static void
Handle_dealloc(Handle* self)
{
Py_XDECREF(self->device);
if(self->handle)
delete reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle);
Py_TYPE(self)->tp_free((PyObject*)self);
}
@@ -1046,11 +1048,9 @@ PyDoc_STRVAR(M_aud_Handle_pause_doc,
static PyObject *
Handle_pause(Handle *self)
{
Device* device = (Device*)self->device;
try
{
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->pause(self->handle));
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->pause());
}
catch(AUD_Exception& e)
{
@@ -1068,11 +1068,9 @@ PyDoc_STRVAR(M_aud_Handle_resume_doc,
static PyObject *
Handle_resume(Handle *self)
{
Device* device = (Device*)self->device;
try
{
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->resume(self->handle));
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->resume());
}
catch(AUD_Exception& e)
{
@@ -1091,11 +1089,9 @@ PyDoc_STRVAR(M_aud_Handle_stop_doc,
static PyObject *
Handle_stop(Handle *self)
{
Device* device = (Device*)self->device;
try
{
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->stop(self->handle));
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->stop());
}
catch(AUD_Exception& e)
{
@@ -1123,11 +1119,9 @@ PyDoc_STRVAR(M_aud_Handle_position_doc,
static PyObject *
Handle_get_position(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPosition(self->handle));
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPosition());
}
catch(AUD_Exception& e)
{
@@ -1144,11 +1138,9 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:position", &position))
return -1;
Device* device = (Device*)self->device;
try
{
if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->seek(self->handle, position))
if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->seek(position))
return 0;
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
@@ -1172,11 +1164,9 @@ PyDoc_STRVAR(M_aud_Handle_keep_doc,
static PyObject *
Handle_get_keep(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getKeep(self->handle));
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getKeep());
}
catch(AUD_Exception& e)
{
@@ -1195,11 +1185,10 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing)
}
bool keep = args == Py_True;
Device* device = (Device*)self->device;
try
{
if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setKeep(self->handle, keep))
if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setKeep(keep))
return 0;
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
@@ -1217,11 +1206,9 @@ PyDoc_STRVAR(M_aud_Handle_status_doc,
static PyObject *
Handle_get_status(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getStatus(self->handle));
return PyBool_FromLong((long)(*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getStatus());
}
catch(AUD_Exception& e)
{
@@ -1236,11 +1223,9 @@ PyDoc_STRVAR(M_aud_Handle_volume_doc,
static PyObject *
Handle_get_volume(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getVolume(self->handle));
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getVolume());
}
catch(AUD_Exception& e)
{
@@ -1257,11 +1242,9 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume", &volume))
return -1;
Device* device = (Device*)self->device;
try
{
if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setVolume(self->handle, volume))
if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setVolume(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
@@ -1279,11 +1262,9 @@ PyDoc_STRVAR(M_aud_Handle_pitch_doc,
static PyObject *
Handle_get_pitch(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getPitch(self->handle));
return Py_BuildValue("f", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getPitch());
}
catch(AUD_Exception& e)
{
@@ -1300,11 +1281,9 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:pitch", &pitch))
return -1;
Device* device = (Device*)self->device;
try
{
if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setPitch(self->handle, pitch))
if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setPitch(pitch))
return 0;
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
@@ -1322,11 +1301,9 @@ PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
static PyObject *
Handle_get_loop_count(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->getLoopCount(self->handle));
return Py_BuildValue("i", (*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->getLoopCount());
}
catch(AUD_Exception& e)
{
@@ -1343,11 +1320,9 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "i:loop_count", &loops))
return -1;
Device* device = (Device*)self->device;
try
{
if((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(device->device))->setLoopCount(self->handle, loops))
if((*reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle))->setLoopCount(loops))
return 0;
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
@@ -1365,14 +1340,12 @@ PyDoc_STRVAR(M_aud_Handle_location_doc,
static PyObject *
Handle_get_location(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 v = device->getSourceLocation(self->handle);
AUD_Vector3 v = handle->getSourceLocation();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1396,15 +1369,13 @@ Handle_set_location(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):location", &x, &y, &z))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 location(x, y, z);
if(device->setSourceLocation(self->handle, location))
if(handle->setSourceLocation(location))
return 0;
PyErr_SetString(AUDError, "Location couldn't be set!");
}
@@ -1425,14 +1396,12 @@ PyDoc_STRVAR(M_aud_Handle_velocity_doc,
static PyObject *
Handle_get_velocity(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 v = device->getSourceVelocity(self->handle);
AUD_Vector3 v = handle->getSourceVelocity();
return Py_BuildValue("(fff)", v.x(), v.y(), v.z());
}
else
@@ -1456,15 +1425,13 @@ Handle_set_velocity(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(fff):velocity", &x, &y, &z))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Vector3 velocity(x, y, z);
if(device->setSourceVelocity(self->handle, velocity))
if(handle->setSourceVelocity(velocity))
return 0;
PyErr_SetString(AUDError, "Couldn't set the velocity!");
}
@@ -1485,14 +1452,12 @@ PyDoc_STRVAR(M_aud_Handle_orientation_doc,
static PyObject *
Handle_get_orientation(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Quaternion o = device->getSourceOrientation(self->handle);
AUD_Quaternion o = handle->getSourceOrientation();
return Py_BuildValue("(ffff)", o.w(), o.x(), o.y(), o.z());
}
else
@@ -1516,15 +1481,13 @@ Handle_set_orientation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "(ffff):orientation", &w, &x, &y, &z))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
AUD_Quaternion orientation(w, x, y, z);
if(device->setSourceOrientation(self->handle, orientation))
if(handle->setSourceOrientation(orientation))
return 0;
PyErr_SetString(AUDError, "Couldn't set the orientation!");
}
@@ -1545,14 +1508,12 @@ PyDoc_STRVAR(M_aud_Handle_relative_doc,
static PyObject *
Handle_get_relative(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return PyBool_FromLong((long)device->isRelative(self->handle));
return PyBool_FromLong((long)handle->isRelative());
}
else
{
@@ -1577,14 +1538,13 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
}
bool relative = (args == Py_True);
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setRelative(self->handle, relative))
if(handle->setRelative(relative))
return 0;
PyErr_SetString(AUDError, "Couldn't set the relativeness!");
}
@@ -1606,14 +1566,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_minimum_doc,
static PyObject *
Handle_get_volume_minimum(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getVolumeMinimum(self->handle));
return Py_BuildValue("f", handle->getVolumeMinimum());
}
else
{
@@ -1636,14 +1594,12 @@ Handle_set_volume_minimum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_minimum", &volume))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setVolumeMinimum(self->handle, volume))
if(handle->setVolumeMinimum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the minimum volume!");
}
@@ -1665,14 +1621,12 @@ PyDoc_STRVAR(M_aud_Handle_volume_maximum_doc,
static PyObject *
Handle_get_volume_maximum(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getVolumeMaximum(self->handle));
return Py_BuildValue("f", handle->getVolumeMaximum());
}
else
{
@@ -1695,14 +1649,12 @@ Handle_set_volume_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:volume_maximum", &volume))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setVolumeMaximum(self->handle, volume))
if(handle->setVolumeMaximum(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum volume!");
}
@@ -1725,14 +1677,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_reference_doc,
static PyObject *
Handle_get_distance_reference(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getDistanceReference(self->handle));
return Py_BuildValue("f", handle->getDistanceReference());
}
else
{
@@ -1755,14 +1705,12 @@ Handle_set_distance_reference(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_reference", &distance))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setDistanceReference(self->handle, distance))
if(handle->setDistanceReference(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the reference distance!");
}
@@ -1785,14 +1733,12 @@ PyDoc_STRVAR(M_aud_Handle_distance_maximum_doc,
static PyObject *
Handle_get_distance_maximum(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getDistanceMaximum(self->handle));
return Py_BuildValue("f", handle->getDistanceMaximum());
}
else
{
@@ -1815,14 +1761,12 @@ Handle_set_distance_maximum(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:distance_maximum", &distance))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setDistanceMaximum(self->handle, distance))
if(handle->setDistanceMaximum(distance))
return 0;
PyErr_SetString(AUDError, "Couldn't set the maximum distance!");
}
@@ -1845,14 +1789,12 @@ PyDoc_STRVAR(M_aud_Handle_attenuation_doc,
static PyObject *
Handle_get_attenuation(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getAttenuation(self->handle));
return Py_BuildValue("f", handle->getAttenuation());
}
else
{
@@ -1875,14 +1817,12 @@ Handle_set_attenuation(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:attenuation", &factor))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setAttenuation(self->handle, factor))
if(handle->setAttenuation(factor))
return 0;
PyErr_SetString(AUDError, "Couldn't set the attenuation!");
}
@@ -1910,14 +1850,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_inner_doc,
static PyObject *
Handle_get_cone_angle_inner(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getConeAngleInner(self->handle));
return Py_BuildValue("f", handle->getConeAngleInner());
}
else
{
@@ -1940,14 +1878,12 @@ Handle_set_cone_angle_inner(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_inner", &angle))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setConeAngleInner(self->handle, angle))
if(handle->setConeAngleInner(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone inner angle!");
}
@@ -1969,14 +1905,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_angle_outer_doc,
static PyObject *
Handle_get_cone_angle_outer(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getConeAngleOuter(self->handle));
return Py_BuildValue("f", handle->getConeAngleOuter());
}
else
{
@@ -1999,14 +1933,12 @@ Handle_set_cone_angle_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_angle_outer", &angle))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setConeAngleOuter(self->handle, angle))
if(handle->setConeAngleOuter(angle))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer angle!");
}
@@ -2028,14 +1960,12 @@ PyDoc_STRVAR(M_aud_Handle_cone_volume_outer_doc,
static PyObject *
Handle_get_cone_volume_outer(Handle *self, void* nothing)
{
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
return Py_BuildValue("f", device->getConeVolumeOuter(self->handle));
return Py_BuildValue("f", handle->getConeVolumeOuter());
}
else
{
@@ -2058,14 +1988,12 @@ Handle_set_cone_volume_outer(Handle *self, PyObject* args, void* nothing)
if(!PyArg_Parse(args, "f:cone_volume_outer", &volume))
return -1;
Device* dev = (Device*)self->device;
try
{
AUD_I3DDevice* device = dynamic_cast<AUD_I3DDevice*>(reinterpret_cast<AUD_Reference<AUD_IDevice>*>(dev->device)->get());
if(device)
AUD_I3DHandle* handle = dynamic_cast<AUD_I3DHandle*>(reinterpret_cast<AUD_Reference<AUD_IHandle>*>(self->handle)->get());
if(handle)
{
if(device->setConeVolumeOuter(self->handle, volume))
if(handle->setConeVolumeOuter(volume))
return 0;
PyErr_SetString(AUDError, "Couldn't set the cone outer volume!");
}
@@ -2302,12 +2230,9 @@ Device_play(Device *self, PyObject *args, PyObject *kwds)
handle = (Handle*)HandleType.tp_alloc(&HandleType, 0);
if(handle != NULL)
{
handle->device = (PyObject*)self;
Py_INCREF(self);
try
{
handle->handle = (*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep);
handle->handle = new AUD_Reference<AUD_IHandle>((*reinterpret_cast<AUD_Reference<AUD_IDevice>*>(self->device))->play(*reinterpret_cast<AUD_Reference<AUD_IFactory>*>(sound->factory), keep));
}
catch(AUD_Exception& e)
{

View File

@@ -36,15 +36,15 @@
#ifdef __cplusplus
extern "C" {
struct AUD_Handle;
#else
typedef void AUD_IFactory;
typedef void AUD_IDevice;
typedef void AUD_Handle;
typedef void AUD_IHandle;
#endif
typedef void AUD_Reference_AUD_IFactory;
typedef void AUD_Reference_AUD_IDevice;
typedef void AUD_Reference_AUD_IHandle;
typedef struct {
PyObject_HEAD
@@ -54,8 +54,7 @@ typedef struct {
typedef struct {
PyObject_HEAD
AUD_Handle* handle;
PyObject* device;
AUD_Reference_AUD_IHandle* handle;
} Handle;
typedef struct {

View File

@@ -432,7 +432,7 @@ void AUD_FFMPEGReader::read(int& length, bool& eos, sample_t* buffer)
pkgbuf_pos-data_size);
}
if(eos = (left > 0))
if((eos = (left > 0)))
length -= left;
m_position += length;

View File

@@ -68,6 +68,8 @@ AUD_Specs AUD_BufferReader::getSpecs() const
void AUD_BufferReader::read(int& length, bool& eos, sample_t* buffer)
{
eos = false;
int sample_size = AUD_SAMPLE_SIZE(m_specs);
sample_t* buf = m_buffer->getBuffer() + m_position * m_specs.channels;

View File

@@ -45,6 +45,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_I3DDevice.h"
#include "AUD_I3DHandle.h"
#include "AUD_FileFactory.h"
#include "AUD_StreamBufferFactory.h"
#include "AUD_DelayFactory.h"
@@ -89,7 +90,7 @@ extern "C" {
typedef AUD_Reference<AUD_IFactory> AUD_Sound;
typedef AUD_Reference<AUD_ReadDevice> AUD_Device;
typedef AUD_Handle AUD_Channel;
typedef AUD_Reference<AUD_IHandle> AUD_Channel;
typedef AUD_Reference<AUD_SequencerEntry> AUD_SEntry;
#define AUD_CAPI_IMPLEMENTATION
@@ -375,16 +376,16 @@ AUD_Sound* AUD_loopSound(AUD_Sound* sound)
int AUD_setLoop(AUD_Channel* handle, int loops)
{
if(handle)
assert(handle);
try
{
try
{
return AUD_device->setLoopCount(handle, loops);
}
catch(AUD_Exception&)
{
}
return (*handle)->setLoopCount(loops);
}
catch(AUD_Exception&)
{
}
return false;
}
@@ -413,49 +414,58 @@ AUD_Channel* AUD_play(AUD_Sound* sound, int keep)
assert(sound);
try
{
return AUD_device->play(*sound, keep);
AUD_Channel channel = AUD_device->play(*sound, keep);
if(!channel.isNull())
return new AUD_Channel(channel);
}
catch(AUD_Exception&)
{
return NULL;
}
return NULL;
}
int AUD_pause(AUD_Channel* handle)
{
return AUD_device->pause(handle);
assert(handle);
return (*handle)->pause();
}
int AUD_resume(AUD_Channel* handle)
{
return AUD_device->resume(handle);
assert(handle);
return (*handle)->resume();
}
int AUD_stop(AUD_Channel* handle)
{
if(!AUD_device.isNull())
return AUD_device->stop(handle);
return false;
assert(handle);
int result = (*handle)->stop();
delete handle;
return result;
}
int AUD_setKeep(AUD_Channel* handle, int keep)
{
return AUD_device->setKeep(handle, keep);
assert(handle);
return (*handle)->setKeep(keep);
}
int AUD_seek(AUD_Channel* handle, float seekTo)
{
return AUD_device->seek(handle, seekTo);
assert(handle);
return (*handle)->seek(seekTo);
}
float AUD_getPosition(AUD_Channel* handle)
{
return AUD_device->getPosition(handle);
assert(handle);
return (*handle)->getPosition();
}
AUD_Status AUD_getStatus(AUD_Channel* handle)
{
return AUD_device->getStatus(handle);
assert(handle);
return (*handle)->getStatus();
}
int AUD_setListenerLocation(const float* location)
@@ -529,10 +539,13 @@ int AUD_setDistanceModel(AUD_DistanceModel model)
int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
AUD_Vector3 v(location[0], location[1], location[2]);
return AUD_3ddevice->setSourceLocation(handle, v);
return h->setSourceLocation(v);
}
return false;
@@ -540,10 +553,13 @@ int AUD_setSourceLocation(AUD_Channel* handle, const float* location)
int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
AUD_Vector3 v(velocity[0], velocity[1], velocity[2]);
return AUD_3ddevice->setSourceVelocity(handle, v);
return h->setSourceVelocity(v);
}
return false;
@@ -551,10 +567,13 @@ int AUD_setSourceVelocity(AUD_Channel* handle, const float* velocity)
int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
AUD_Quaternion q(orientation[3], orientation[0], orientation[1], orientation[2]);
return AUD_3ddevice->setSourceOrientation(handle, q);
return h->setSourceOrientation(q);
}
return false;
@@ -562,9 +581,12 @@ int AUD_setSourceOrientation(AUD_Channel* handle, const float* orientation)
int AUD_setRelative(AUD_Channel* handle, int relative)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setRelative(handle, relative);
return h->setRelative(relative);
}
return false;
@@ -572,9 +594,12 @@ int AUD_setRelative(AUD_Channel* handle, int relative)
int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setVolumeMaximum(handle, volume);
return h->setVolumeMaximum(volume);
}
return false;
@@ -582,9 +607,12 @@ int AUD_setVolumeMaximum(AUD_Channel* handle, float volume)
int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setVolumeMinimum(handle, volume);
return h->setVolumeMinimum(volume);
}
return false;
@@ -592,9 +620,12 @@ int AUD_setVolumeMinimum(AUD_Channel* handle, float volume)
int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setDistanceMaximum(handle, distance);
return h->setDistanceMaximum(distance);
}
return false;
@@ -602,9 +633,12 @@ int AUD_setDistanceMaximum(AUD_Channel* handle, float distance)
int AUD_setDistanceReference(AUD_Channel* handle, float distance)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setDistanceReference(handle, distance);
return h->setDistanceReference(distance);
}
return false;
@@ -612,9 +646,12 @@ int AUD_setDistanceReference(AUD_Channel* handle, float distance)
int AUD_setAttenuation(AUD_Channel* handle, float factor)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setAttenuation(handle, factor);
return h->setAttenuation(factor);
}
return false;
@@ -622,9 +659,12 @@ int AUD_setAttenuation(AUD_Channel* handle, float factor)
int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setConeAngleOuter(handle, angle);
return h->setConeAngleOuter(angle);
}
return false;
@@ -632,9 +672,12 @@ int AUD_setConeAngleOuter(AUD_Channel* handle, float angle)
int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setConeAngleInner(handle, angle);
return h->setConeAngleInner(angle);
}
return false;
@@ -642,9 +685,12 @@ int AUD_setConeAngleInner(AUD_Channel* handle, float angle)
int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
{
if(AUD_3ddevice)
assert(handle);
AUD_Reference<AUD_I3DHandle> h(*handle);
if(!h.isNull())
{
return AUD_3ddevice->setConeVolumeOuter(handle, volume);
return h->setConeVolumeOuter(volume);
}
return false;
@@ -652,27 +698,23 @@ int AUD_setConeVolumeOuter(AUD_Channel* handle, float volume)
int AUD_setSoundVolume(AUD_Channel* handle, float volume)
{
if(handle)
assert(handle);
try
{
try
{
return AUD_device->setVolume(handle, volume);
}
catch(AUD_Exception&) {}
return (*handle)->setVolume(volume);
}
catch(AUD_Exception&) {}
return false;
}
int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
{
if(handle)
assert(handle);
try
{
try
{
return AUD_device->setPitch(handle, pitch);
}
catch(AUD_Exception&) {}
return (*handle)->setPitch(pitch);
}
catch(AUD_Exception&) {}
return false;
}
@@ -695,14 +737,17 @@ AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek)
try
{
AUD_Channel* handle = (*device)->play(*sound);
(*device)->seek(handle, seek);
return handle;
AUD_Channel channel = (*device)->play(*sound);
if(!channel.isNull())
{
channel->seek(seek);
return new AUD_Channel(channel);
}
}
catch(AUD_Exception&)
{
return NULL;
}
return NULL;
}
int AUD_setDeviceVolume(AUD_Device* device, float volume)
@@ -719,22 +764,6 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
return false;
}
int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
float volume)
{
if(handle)
{
assert(device);
try
{
return (*device)->setVolume(handle, volume);
}
catch(AUD_Exception&) {}
}
return false;
}
int AUD_readDevice(AUD_Device* device, data_t* buffer, int length)
{
assert(device);
@@ -821,7 +850,8 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
static void pauseSound(AUD_Channel* handle)
{
AUD_device->pause(handle);
assert(handle);
(*handle)->pause();
}
AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
@@ -829,16 +859,25 @@ AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
AUD_Reference<AUD_IFactory> silence = new AUD_SilenceFactory;
AUD_Reference<AUD_IFactory> limiter = new AUD_LimiterFactory(silence, 0, seconds);
AUD_device->lock();
try
{
AUD_Channel* channel = AUD_device->play(limiter);
AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
return channel;
AUD_Channel channel = AUD_device->play(limiter);
if(!channel.isNull())
{
channel->setStopCallback((stopCallback)pauseSound, handle);
AUD_device->unlock();
return new AUD_Channel(channel);
}
}
catch(AUD_Exception&)
{
return NULL;
}
AUD_device->unlock();
return NULL;
}
AUD_Sound* AUD_createSequencer(int muted, void* data, AUD_volumeFunction volume)
@@ -966,7 +1005,8 @@ void AUD_seekSequencer(AUD_Channel* handle, float time)
else
#endif
{
AUD_device->seek(handle, time);
assert(handle);
(*handle)->seek(time);
}
}
@@ -979,7 +1019,8 @@ float AUD_getSequencerPosition(AUD_Channel* handle)
else
#endif
{
return AUD_device->getPosition(handle);
assert(handle);
return (*handle)->getPosition();
}
}
@@ -1006,3 +1047,8 @@ AUD_Sound* AUD_copy(AUD_Sound* sound)
{
return new AUD_Reference<AUD_IFactory>(*sound);
}
void AUD_freeChannel(AUD_Channel* channel)
{
delete channel;
}

View File

@@ -417,17 +417,6 @@ extern int AUD_setDeviceVolume(AUD_Device* device, float volume);
*/
extern AUD_Channel* AUD_playDevice(AUD_Device* device, AUD_Sound* sound, float seek);
/**
* Sets the volume of a played back sound of a read device.
* \param device The read device.
* \param handle The handle to the sound.
* \param volume The new volume, must be between 0.0 and 1.0.
* \return Whether the action succeeded.
*/
extern int AUD_setDeviceSoundVolume(AUD_Device* device,
AUD_Channel* handle,
float volume);
/**
* Reads the next samples into the supplied buffer.
* \param device The read device.
@@ -498,6 +487,8 @@ extern int AUD_doesPlayback(void);
extern AUD_Sound* AUD_copy(AUD_Sound* sound);
extern void AUD_freeChannel(AUD_Channel* channel);
#ifdef WITH_PYTHON
extern PyObject* AUD_getPythonFactory(AUD_Sound* sound);

View File

@@ -35,8 +35,6 @@
#include "AUD_Space.h"
#include "AUD_3DMath.h"
struct AUD_Handle;
/**
* This class represents an output device for 3D sound.
*/
@@ -121,200 +119,6 @@ public:
* \param model distance model.
*/
virtual void setDistanceModel(AUD_DistanceModel model)=0;
/**
* Retrieves the location of a source.
* \param handle The handle of the source.
* \return The location.
*/
virtual AUD_Vector3 getSourceLocation(AUD_Handle* handle)=0;
/**
* Sets the location of a source.
* \param handle The handle of the source.
* \param location The new location.
* \return Whether the action succeeded.
*/
virtual bool setSourceLocation(AUD_Handle* handle, const AUD_Vector3& location)=0;
/**
* Retrieves the velocity of a source.
* \param handle The handle of the source.
* \return The velocity.
*/
virtual AUD_Vector3 getSourceVelocity(AUD_Handle* handle)=0;
/**
* Sets the velocity of a source.
* \param handle The handle of the source.
* \param velocity The new velocity.
* \return Whether the action succeeded.
*/
virtual bool setSourceVelocity(AUD_Handle* handle, const AUD_Vector3& velocity)=0;
/**
* Retrieves the orientation of a source.
* \param handle The handle of the source.
* \return The orientation as quaternion.
*/
virtual AUD_Quaternion getSourceOrientation(AUD_Handle* handle)=0;
/**
* Sets the orientation of a source.
* \param handle The handle of the source.
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
*/
virtual bool setSourceOrientation(AUD_Handle* handle, const AUD_Quaternion& orientation)=0;
/**
* Checks whether the source location, velocity and orientation are relative
* to the listener.
* \param handle The handle of the source.
* \return Whether the source is relative.
*/
virtual bool isRelative(AUD_Handle* handle)=0;
/**
* Sets whether the source location, velocity and orientation are relative
* to the listener.
* \param handle The handle of the source.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
*/
virtual bool setRelative(AUD_Handle* handle, bool relative)=0;
/**
* Retrieves the maximum volume of a source.
* \param handle The handle of the source.
* \return The maximum volume.
*/
virtual float getVolumeMaximum(AUD_Handle* handle)=0;
/**
* Sets the maximum volume of a source.
* \param handle The handle of the source.
* \param volume The new maximum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMaximum(AUD_Handle* handle, float volume)=0;
/**
* Retrieves the minimum volume of a source.
* \param handle The handle of the source.
* \return The minimum volume.
*/
virtual float getVolumeMinimum(AUD_Handle* handle)=0;
/**
* Sets the minimum volume of a source.
* \param handle The handle of the source.
* \param volume The new minimum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMinimum(AUD_Handle* handle, float volume)=0;
/**
* Retrieves the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \param handle The handle of the source.
* \return The maximum distance.
*/
virtual float getDistanceMaximum(AUD_Handle* handle)=0;
/**
* Sets the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \param handle The handle of the source.
* \param distance The new maximum distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceMaximum(AUD_Handle* handle, float distance)=0;
/**
* Retrieves the reference distance of a source.
* \param handle The handle of the source.
* \return The reference distance.
*/
virtual float getDistanceReference(AUD_Handle* handle)=0;
/**
* Sets the reference distance of a source.
* \param handle The handle of the source.
* \param distance The new reference distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceReference(AUD_Handle* handle, float distance)=0;
/**
* Retrieves the attenuation of a source.
* \param handle The handle of the source.
* \return The attenuation.
*/
virtual float getAttenuation(AUD_Handle* handle)=0;
/**
* Sets the attenuation of a source.
* This value is used for distance calculation.
* \param handle The handle of the source.
* \param factor The new attenuation.
* \return Whether the action succeeded.
*/
virtual bool setAttenuation(AUD_Handle* handle, float factor)=0;
/**
* Retrieves the outer angle of the cone of a source.
* \param handle The handle of the source.
* \return The outer angle of the cone.
*/
virtual float getConeAngleOuter(AUD_Handle* handle)=0;
/**
* Sets the outer angle of the cone of a source.
* \param handle The handle of the source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleOuter(AUD_Handle* handle, float angle)=0;
/**
* Retrieves the inner angle of the cone of a source.
* \param handle The handle of the source.
* \return The inner angle of the cone.
*/
virtual float getConeAngleInner(AUD_Handle* handle)=0;
/**
* Sets the inner angle of the cone of a source.
* \param handle The handle of the source.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleInner(AUD_Handle* handle, float angle)=0;
/**
* Retrieves the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \param handle The handle of the source.
* \return The outer volume of the cone.
*/
virtual float getConeVolumeOuter(AUD_Handle* handle)=0;
/**
* Sets the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \param handle The handle of the source.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeVolumeOuter(AUD_Handle* handle, float volume)=0;
};
#endif //AUD_I3DDEVICE

View File

@@ -0,0 +1,213 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_I3DHandle.h
* \ingroup audaspaceintern
*/
#ifndef AUD_I3DHANDLE
#define AUD_I3DHANDLE
#include "AUD_Space.h"
#include "AUD_3DMath.h"
/**
* This class represents an output device for 3D sound.
*/
class AUD_I3DHandle
{
public:
/**
* Retrieves the location of a source.
* \return The location.
*/
virtual AUD_Vector3 getSourceLocation()=0;
/**
* Sets the location of a source.
* \param location The new location.
* \return Whether the action succeeded.
*/
virtual bool setSourceLocation(const AUD_Vector3& location)=0;
/**
* Retrieves the velocity of a source.
* \return The velocity.
*/
virtual AUD_Vector3 getSourceVelocity()=0;
/**
* Sets the velocity of a source.
* \param velocity The new velocity.
* \return Whether the action succeeded.
*/
virtual bool setSourceVelocity(const AUD_Vector3& velocity)=0;
/**
* Retrieves the orientation of a source.
* \return The orientation as quaternion.
*/
virtual AUD_Quaternion getSourceOrientation()=0;
/**
* Sets the orientation of a source.
* \param orientation The new orientation as quaternion.
* \return Whether the action succeeded.
*/
virtual bool setSourceOrientation(const AUD_Quaternion& orientation)=0;
/**
* Checks whether the source location, velocity and orientation are relative
* to the listener.
* \return Whether the source is relative.
*/
virtual bool isRelative()=0;
/**
* Sets whether the source location, velocity and orientation are relative
* to the listener.
* \param relative Whether the source is relative.
* \return Whether the action succeeded.
*/
virtual bool setRelative(bool relative)=0;
/**
* Retrieves the maximum volume of a source.
* \return The maximum volume.
*/
virtual float getVolumeMaximum()=0;
/**
* Sets the maximum volume of a source.
* \param volume The new maximum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMaximum(float volume)=0;
/**
* Retrieves the minimum volume of a source.
* \return The minimum volume.
*/
virtual float getVolumeMinimum()=0;
/**
* Sets the minimum volume of a source.
* \param volume The new minimum volume.
* \return Whether the action succeeded.
*/
virtual bool setVolumeMinimum(float volume)=0;
/**
* Retrieves the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \return The maximum distance.
*/
virtual float getDistanceMaximum()=0;
/**
* Sets the maximum distance of a source.
* If a source is further away from the reader than this distance, the
* volume will automatically be set to 0.
* \param distance The new maximum distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceMaximum(float distance)=0;
/**
* Retrieves the reference distance of a source.
* \return The reference distance.
*/
virtual float getDistanceReference()=0;
/**
* Sets the reference distance of a source.
* \param distance The new reference distance.
* \return Whether the action succeeded.
*/
virtual bool setDistanceReference(float distance)=0;
/**
* Retrieves the attenuation of a source.
* \return The attenuation.
*/
virtual float getAttenuation()=0;
/**
* Sets the attenuation of a source.
* This value is used for distance calculation.
* \param factor The new attenuation.
* \return Whether the action succeeded.
*/
virtual bool setAttenuation(float factor)=0;
/**
* Retrieves the outer angle of the cone of a source.
* \return The outer angle of the cone.
*/
virtual float getConeAngleOuter()=0;
/**
* Sets the outer angle of the cone of a source.
* \param angle The new outer angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleOuter(float angle)=0;
/**
* Retrieves the inner angle of the cone of a source.
* \return The inner angle of the cone.
*/
virtual float getConeAngleInner()=0;
/**
* Sets the inner angle of the cone of a source.
* \param angle The new inner angle of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeAngleInner(float angle)=0;
/**
* Retrieves the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \return The outer volume of the cone.
*/
virtual float getConeVolumeOuter()=0;
/**
* Sets the outer volume of the cone of a source.
* The volume between inner and outer angle is interpolated between inner
* volume and this value.
* \param volume The new outer volume of the cone.
* \return Whether the action succeeded.
*/
virtual bool setConeVolumeOuter(float volume)=0;
};
#endif //AUD_I3DHANDLE

View File

@@ -36,13 +36,7 @@
#include "AUD_Reference.h"
class AUD_IFactory;
class AUD_IReader;
/// Handle structure, for inherition.
struct AUD_Handle
{
};
typedef void (*stopCallback)(void*);
class AUD_IHandle;
/**
* This class represents an output device for sound sources.
@@ -75,7 +69,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false)=0;
/**
* Plays a sound source.
@@ -87,87 +81,7 @@ public:
* \exception AUD_Exception Thrown if there's an unexpected (from the
* device side) error during creation of the reader.
*/
virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
* Pauses a played back sound.
* \param handle The handle returned by the play function.
* \return
* - true if the sound has been paused.
* - false if the sound isn't playing back or the handle is invalid.
*/
virtual bool pause(AUD_Handle* handle)=0;
/**
* Resumes a paused sound.
* \param handle The handle returned by the play function.
* \return
* - true if the sound has been resumed.
* - false if the sound isn't paused or the handle is invalid.
*/
virtual bool resume(AUD_Handle* handle)=0;
/**
* Stops a played back or paused sound. The handle is definitely invalid
* afterwards.
* \param handle The handle returned by the play function.
* \return
* - true if the sound has been stopped.
* - false if the handle is invalid.
*/
virtual bool stop(AUD_Handle* handle)=0;
/**
* Gets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \param handle The handle returned by the play function.
* \return
* - true if the source will be paused when it's end is reached
* - false if the handle won't kept or is invalid.
*/
virtual bool getKeep(AUD_Handle* handle)=0;
/**
* Sets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \param handle The handle returned by the play function.
* \param keep True when the source should be paused and not deleted.
* \return
* - true if the behaviour has been changed.
* - false if the handle is invalid.
*/
virtual bool setKeep(AUD_Handle* handle, bool keep)=0;
/**
* Seeks in a played back sound.
* \param handle The handle returned by the play function.
* \param position The new position from where to play back, in seconds.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
* \warning Whether the seek works or not depends on the sound source.
*/
virtual bool seek(AUD_Handle* handle, float position)=0;
/**
* Retrieves the current playback position of a sound.
* \param handle The handle returned by the play function.
* \return The playback position in seconds, or 0.0 if the handle is
* invalid.
*/
virtual float getPosition(AUD_Handle* handle)=0;
/**
* Returns the status of a played back sound.
* \param handle The handle returned by the play function.
* \return
* - AUD_STATUS_INVALID if the sound has stopped or the handle is
*. invalid
* - AUD_STATUS_PLAYING if the sound is currently played back.
* - AUD_STATUS_PAUSED if the sound is currently paused.
* \see AUD_Status
*/
virtual AUD_Status getStatus(AUD_Handle* handle)=0;
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false)=0;
/**
* Locks the device.
@@ -196,69 +110,6 @@ public:
* \param volume The overall device volume.
*/
virtual void setVolume(float volume)=0;
/**
* Retrieves the volume of a playing sound.
* \param handle The sound handle.
* \return The volume.
*/
virtual float getVolume(AUD_Handle* handle)=0;
/**
* Sets the volume of a playing sound.
* \param handle The sound handle.
* \param volume The volume.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setVolume(AUD_Handle* handle, float volume)=0;
/**
* Retrieves the pitch of a playing sound.
* \return The pitch.
*/
virtual float getPitch(AUD_Handle* handle)=0;
/**
* Sets the pitch of a playing sound.
* \param handle The sound handle.
* \param pitch The pitch.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setPitch(AUD_Handle* handle, float pitch)=0;
/**
* Retrieves the loop count of a playing sound.
* A negative value indicates infinity.
* \return The remaining loop count.
*/
virtual int getLoopCount(AUD_Handle* handle)=0;
/**
* Sets the loop count of a playing sound.
* A negative value indicates infinity.
* \param handle The sound handle.
* \param count The new loop count.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setLoopCount(AUD_Handle* handle, int count)=0;
/**
* Sets the callback function that's called when the end of a playing sound
* is reached.
* \param handle The sound handle.
* \param callback The callback function.
* \param data The data that should be passed to the callback function.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0)=0;
};
#endif //AUD_IDevice

View File

@@ -0,0 +1,181 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_IHandle.h
* \ingroup audaspaceintern
*/
#ifndef AUD_IHANDLE
#define AUD_IHANDLE
//#include "AUD_Space.h"
//#include "AUD_Reference.h"
typedef void (*stopCallback)(void*);
/**
* This class represents a playback handles for specific devices.
*/
class AUD_IHandle
{
public:
/**
* Destroys the device.
*/
virtual ~AUD_IHandle() {}
/**
* Pauses a played back sound.
* \return
* - true if the sound has been paused.
* - false if the sound isn't playing back or the handle is invalid.
*/
virtual bool pause()=0;
/**
* Resumes a paused sound.
* \return
* - true if the sound has been resumed.
* - false if the sound isn't paused or the handle is invalid.
*/
virtual bool resume()=0;
/**
* Stops a played back or paused sound. The handle is definitely invalid
* afterwards.
* \return
* - true if the sound has been stopped.
* - false if the handle is invalid.
*/
virtual bool stop()=0;
/**
* Gets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \return
* - true if the source will be paused when it's end is reached
* - false if the handle won't kept or is invalid.
*/
virtual bool getKeep()=0;
/**
* Sets the behaviour of the device for a played back sound when the sound
* doesn't return any more samples.
* \param keep True when the source should be paused and not deleted.
* \return
* - true if the behaviour has been changed.
* - false if the handle is invalid.
*/
virtual bool setKeep(bool keep)=0;
/**
* Seeks in a played back sound.
* \param position The new position from where to play back, in seconds.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
* \warning Whether the seek works or not depends on the sound source.
*/
virtual bool seek(float position)=0;
/**
* Retrieves the current playback position of a sound.
* \return The playback position in seconds, or 0.0 if the handle is
* invalid.
*/
virtual float getPosition()=0;
/**
* Returns the status of a played back sound.
* \return
* - AUD_STATUS_INVALID if the sound has stopped or the handle is
*. invalid
* - AUD_STATUS_PLAYING if the sound is currently played back.
* - AUD_STATUS_PAUSED if the sound is currently paused.
* \see AUD_Status
*/
virtual AUD_Status getStatus()=0;
/**
* Retrieves the volume of a playing sound.
* \return The volume.
*/
virtual float getVolume()=0;
/**
* Sets the volume of a playing sound.
* \param volume The volume.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setVolume(float volume)=0;
/**
* Retrieves the pitch of a playing sound.
* \return The pitch.
*/
virtual float getPitch()=0;
/**
* Sets the pitch of a playing sound.
* \param pitch The pitch.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setPitch(float pitch)=0;
/**
* Retrieves the loop count of a playing sound.
* A negative value indicates infinity.
* \return The remaining loop count.
*/
virtual int getLoopCount()=0;
/**
* Sets the loop count of a playing sound.
* A negative value indicates infinity.
* \param count The new loop count.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setLoopCount(int count)=0;
/**
* Sets the callback function that's called when the end of a playing sound
* is reached.
* \param callback The callback function.
* \param data The data that should be passed to the callback function.
* \return
* - true if the handle is valid.
* - false if the handle is invalid.
*/
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0)=0;
};
#endif //AUD_IHandle

View File

@@ -34,6 +34,7 @@
#include "AUD_NULLDevice.h"
#include "AUD_IReader.h"
#include "AUD_IFactory.h"
#include "AUD_IHandle.h"
AUD_NULLDevice::AUD_NULLDevice()
{
@@ -48,56 +49,16 @@ AUD_DeviceSpecs AUD_NULLDevice::getSpecs() const
return specs;
}
AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
return 0;
}
AUD_Handle* AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
AUD_Reference<AUD_IHandle> AUD_NULLDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return 0;
}
bool AUD_NULLDevice::pause(AUD_Handle* handle)
{
return false;
}
bool AUD_NULLDevice::resume(AUD_Handle* handle)
{
return false;
}
bool AUD_NULLDevice::stop(AUD_Handle* handle)
{
return false;
}
bool AUD_NULLDevice::getKeep(AUD_Handle* handle)
{
return false;
}
bool AUD_NULLDevice::setKeep(AUD_Handle* handle, bool keep)
{
return false;
}
bool AUD_NULLDevice::seek(AUD_Handle* handle, float position)
{
return false;
}
float AUD_NULLDevice::getPosition(AUD_Handle* handle)
{
return std::numeric_limits<float>::quiet_NaN();
}
AUD_Status AUD_NULLDevice::getStatus(AUD_Handle* handle)
{
return AUD_STATUS_INVALID;
}
void AUD_NULLDevice::lock()
{
}
@@ -114,38 +75,3 @@ float AUD_NULLDevice::getVolume() const
void AUD_NULLDevice::setVolume(float volume)
{
}
float AUD_NULLDevice::getVolume(AUD_Handle* handle)
{
return std::numeric_limits<float>::quiet_NaN();
}
bool AUD_NULLDevice::setVolume(AUD_Handle* handle, float volume)
{
return false;
}
float AUD_NULLDevice::getPitch(AUD_Handle* handle)
{
return std::numeric_limits<float>::quiet_NaN();
}
bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch)
{
return false;
}
int AUD_NULLDevice::getLoopCount(AUD_Handle* handle)
{
return 0;
}
bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count)
{
return false;
}
bool AUD_NULLDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
{
return false;
}

View File

@@ -47,27 +47,12 @@ public:
AUD_NULLDevice();
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Handle* play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual bool pause(AUD_Handle* handle);
virtual bool resume(AUD_Handle* handle);
virtual bool stop(AUD_Handle* handle);
virtual bool getKeep(AUD_Handle* handle);
virtual bool setKeep(AUD_Handle* handle, bool keep);
virtual bool seek(AUD_Handle* handle, float position);
virtual float getPosition(AUD_Handle* handle);
virtual AUD_Status getStatus(AUD_Handle* handle);
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Reference<AUD_IHandle> play(AUD_Reference<AUD_IFactory> factory, bool keep = false);
virtual void lock();
virtual void unlock();
virtual float getVolume() const;
virtual void setVolume(float volume);
virtual float getVolume(AUD_Handle* handle);
virtual bool setVolume(AUD_Handle* handle, float volume);
virtual float getPitch(AUD_Handle* handle);
virtual bool setPitch(AUD_Handle* handle, float pitch);
virtual int getLoopCount(AUD_Handle* handle);
virtual bool setLoopCount(AUD_Handle* handle, int count);
virtual bool setStopCallback(AUD_Handle* handle, stopCallback callback = 0, void* data = 0);
};
#endif //AUD_NULLDEVICE

View File

@@ -28,10 +28,41 @@
* \ingroup audaspaceintern
*/
#ifndef AUD_REFERENCE
#define AUD_REFERENCE
#include <map>
class AUD_ReferenceHandler
{
private:
static std::map<void*, int> m_references;
public:
static inline void incref(void* reference)
{
std::map<void*, int>::iterator result = m_references.find(reference);
if(result != m_references.end())
{
m_references[reference]++;
}
else
{
m_references[reference] = 1;
}
}
static inline bool decref(void* reference)
{
if(!--m_references[reference])
{
m_references.erase(reference);
return true;
}
return false;
}
};
template <class T>
/**
* This class provides reference counting functionality.
@@ -41,8 +72,7 @@ class AUD_Reference
private:
/// The reference.
T* m_reference;
/// The reference counter.
int* m_refcount;
void* m_original;
public:
/**
* Creates a new reference counter.
@@ -50,9 +80,8 @@ public:
*/
AUD_Reference(T* reference = 0)
{
m_reference = reference;
m_refcount = new int;
*m_refcount = 1;
m_original = m_reference = reference;
AUD_ReferenceHandler::incref(reference);
}
/**
@@ -61,9 +90,16 @@ public:
*/
AUD_Reference(const AUD_Reference& ref)
{
m_reference = ref.m_reference;
m_refcount = ref.m_refcount;
(*m_refcount)++;
m_original = m_reference = ref.m_reference;
AUD_ReferenceHandler::incref(m_reference);
}
template <class U>
explicit AUD_Reference(const AUD_Reference<U>& ref)
{
m_original = ref.get();
m_reference = dynamic_cast<T*>(ref.get());
AUD_ReferenceHandler::incref(m_original);
}
/**
@@ -72,12 +108,8 @@ public:
*/
~AUD_Reference()
{
(*m_refcount)--;
if(*m_refcount == 0)
{
if(AUD_ReferenceHandler::decref(m_original))
delete m_reference;
delete m_refcount;
}
}
/**
@@ -89,16 +121,12 @@ public:
if(&ref == this)
return *this;
(*m_refcount)--;
if(*m_refcount == 0)
{
if(AUD_ReferenceHandler::decref(m_original))
delete m_reference;
delete m_refcount;
}
m_original = ref.m_original;
m_reference = ref.m_reference;
m_refcount = ref.m_refcount;
(*m_refcount)++;
AUD_ReferenceHandler::incref(m_original);
return *this;
}
@@ -106,7 +134,7 @@ public:
/**
* Returns whether the reference is NULL.
*/
bool isNull() const
inline bool isNull() const
{
return m_reference == 0;
}
@@ -114,15 +142,20 @@ public:
/**
* Returns the reference.
*/
T* get() const
inline T* get() const
{
return m_reference;
}
inline void* getOriginal() const
{
return m_original;
}
/**
* Returns the reference.
*/
T& operator*() const
inline T& operator*() const
{
return *m_reference;
}
@@ -130,44 +163,22 @@ public:
/**
* Returns the reference.
*/
T* operator->() const
inline T* operator->() const
{
return m_reference;
}
template <class U>
explicit AUD_Reference(U* reference, int* refcount)
{
m_reference = dynamic_cast<T*>(reference);
if(m_reference)
{
m_refcount = refcount;
(*m_refcount)++;
}
else
{
m_refcount = new int;
*m_refcount = 1;
}
}
template <class U>
AUD_Reference<U> convert()
{
return AUD_Reference<U>(m_reference, m_refcount);
}
};
template<class T, class U>
bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
inline bool operator==(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
return a.get() == b.get();
return a.getOriginal() == b.getOriginal();
}
template<class T, class U>
bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
inline bool operator!=(const AUD_Reference<T>& a, const AUD_Reference<U>& b)
{
return a.get() == b.get();
return a.getOriginal() != b.getOriginal();
}
#endif // AUD_REFERENCE

View File

@@ -0,0 +1,33 @@
/*
* $Id$
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* Copyright 2009-2011 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* Audaspace is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Audaspace; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file audaspace/intern/AUD_Reference.cpp
* \ingroup audaspaceintern
*/
#include "AUD_Reference.h"
std::map<void*, int> AUD_ReferenceHandler::m_references;

View File

@@ -108,7 +108,7 @@ AUD_Reference<AUD_IReader> AUD_SequencerFactory::createReader()
m_volume);
m_readers.push_front(reader);
return reader.convert<AUD_IReader>();
return AUD_Reference<AUD_IReader>(reader);
}
void AUD_SequencerFactory::removeReader(AUD_Reference<AUD_SequencerReader> reader)

View File

@@ -37,29 +37,202 @@
#include <cstring>
#include <limits>
/// Saves the data for playback.
struct AUD_SoftwareHandle : AUD_Handle
typedef std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> >::iterator AUD_HandleIterator;
AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, bool keep) :
m_reader(reader), m_keep(keep), m_volume(1.0f), m_loopcount(0),
m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING), m_device(device)
{
/// The reader source.
AUD_Reference<AUD_IReader> reader;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::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);
if(m_device->m_playingSounds.empty())
m_device->playing(m_device->m_playback = false);
m_status = AUD_STATUS_PAUSED;
m_device->unlock();
return true;
}
m_device->unlock();
}
return false;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::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);
if(!m_device->m_playback)
m_device->playing(m_device->m_playback = true);
m_status = AUD_STATUS_PLAYING;
m_device->unlock();
return true;
}
m_device->unlock();
}
return false;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::stop()
{
if(!m_status)
return false;
m_device->lock();
if(m_status == AUD_STATUS_PLAYING)
{
m_device->m_playingSounds.remove(this);
if(m_device->m_playingSounds.empty())
m_device->playing(m_device->m_playback = false);
}
else
m_device->m_pausedSounds.remove(this);
m_device->unlock();
m_status = AUD_STATUS_INVALID;
return true;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::getKeep()
{
if(m_status)
return m_keep;
return false;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::setKeep(bool keep)
{
if(!m_status)
return false;
m_device->lock();
m_keep = keep;
m_device->unlock();
return true;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
{
if(!m_status)
return false;
m_device->lock();
m_reader->seek((int)(position * m_reader->getSpecs().rate));
m_device->unlock();
return true;
}
float AUD_SoftwareDevice::AUD_SoftwareHandle::getPosition()
{
if(!m_status)
return 0.0f;
m_device->lock();
float position = m_reader->getPosition() / (float)m_device->m_specs.rate;
m_device->unlock();
return position;
}
AUD_Status AUD_SoftwareDevice::AUD_SoftwareHandle::getStatus()
{
return m_status;
}
float AUD_SoftwareDevice::AUD_SoftwareHandle::getVolume()
{
return m_volume;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::setVolume(float volume)
{
if(!m_status)
return false;
m_volume = volume;
return true;
}
float AUD_SoftwareDevice::AUD_SoftwareHandle::getPitch()
{
return std::numeric_limits<float>::quiet_NaN();
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::setPitch(float pitch)
{
return false;
}
int AUD_SoftwareDevice::AUD_SoftwareHandle::getLoopCount()
{
if(!m_status)
return 0;
return m_loopcount;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
{
if(!m_status)
return false;
m_loopcount = count;
return true;
}
bool AUD_SoftwareDevice::AUD_SoftwareHandle::setStopCallback(stopCallback callback, void* data)
{
if(!m_status)
return false;
m_device->lock();
m_stop = callback;
m_stop_data = data;
m_device->unlock();
return true;
}
/// Whether to keep the source if end of it is reached.
bool keep;
/// The volume of the source.
float volume;
/// The loop count of the source.
int loopcount;
/// The stop callback.
stopCallback stop;
/// Stop callback data.
void* stop_data;
};
typedef std::list<AUD_SoftwareHandle*>::iterator AUD_HandleIterator;
void AUD_SoftwareDevice::create()
{
@@ -81,23 +254,11 @@ void AUD_SoftwareDevice::destroy()
if(m_playback)
playing(m_playback = false);
AUD_SoftwareHandle* handle;
// delete all playing sounds
while(!m_playingSounds.empty())
{
handle = m_playingSounds.front();
m_playingSounds.pop_front();
delete handle;
}
m_playingSounds.front()->stop();
// delete all paused sounds
while(!m_pausedSounds.empty())
{
handle = m_pausedSounds.front();
m_pausedSounds.pop_front();
delete handle;
}
m_pausedSounds.front()->stop();
pthread_mutex_destroy(&m_mutex);
}
@@ -109,11 +270,11 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
lock();
{
AUD_SoftwareHandle* sound;
AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound;
int len;
int pos;
bool eos;
std::list<AUD_SoftwareHandle*> stopSounds;
std::list<AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> > stopSounds;
sample_t* buf = m_buffer.getBuffer();
m_mixer->clear(length);
@@ -131,39 +292,38 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
pos = 0;
len = length;
sound->reader->read(len, eos, buf);
sound->m_reader->read(len, eos, buf);
// in case of looping
while(pos + len < length && sound->loopcount && eos)
while(pos + len < length && sound->m_loopcount && eos)
{
m_mixer->mix(buf, pos, len, sound->volume);
m_mixer->mix(buf, pos, len, sound->m_volume);
pos += len;
if(sound->loopcount > 0)
sound->loopcount--;
if(sound->m_loopcount > 0)
sound->m_loopcount--;
sound->reader->seek(0);
sound->m_reader->seek(0);
len = length - pos;
sound->reader->read(len, eos, buf);
sound->m_reader->read(len, eos, buf);
// prevent endless loop
if(!len)
break;
}
m_mixer->mix(buf, pos, len, sound->volume);
pos += len;
m_mixer->mix(buf, pos, len, sound->m_volume);
// in case the end of the sound is reached
if(eos && !sound->loopcount)
if(eos && !sound->m_loopcount)
{
if(sound->stop)
sound->stop(sound->stop_data);
if(sound->m_stop)
sound->m_stop(sound->m_stop_data);
if(sound->keep)
pause(sound);
if(sound->m_keep)
sound->pause();
else
stopSounds.push_back(sound);
}
@@ -177,32 +337,19 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
{
sound = stopSounds.front();
stopSounds.pop_front();
stop(sound);
sound->stop();
}
}
unlock();
}
bool AUD_SoftwareDevice::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;
}
AUD_DeviceSpecs AUD_SoftwareDevice::getSpecs() const
{
return m_specs;
}
AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool keep)
{
// prepare the reader
reader = m_mixer->prepare(reader);
@@ -210,13 +357,7 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool kee
return NULL;
// play sound
AUD_SoftwareHandle* sound = new AUD_SoftwareHandle;
sound->keep = keep;
sound->reader = reader;
sound->volume = 1.0f;
sound->loopcount = 0;
sound->stop = NULL;
sound->stop_data = NULL;
AUD_Reference<AUD_SoftwareDevice::AUD_SoftwareHandle> sound = new AUD_SoftwareDevice::AUD_SoftwareHandle(this, reader, keep);
lock();
m_playingSounds.push_back(sound);
@@ -225,204 +366,14 @@ AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IReader> reader, bool kee
playing(m_playback = true);
unlock();
return sound;
return AUD_Reference<AUD_IHandle>(sound);
}
AUD_Handle* AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
AUD_Reference<AUD_IHandle> AUD_SoftwareDevice::play(AUD_Reference<AUD_IFactory> factory, bool keep)
{
return play(factory->createReader(), keep);
}
bool AUD_SoftwareDevice::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);
m_playingSounds.erase(i);
if(m_playingSounds.empty())
playing(m_playback = false);
result = true;
break;
}
}
unlock();
return result;
}
bool AUD_SoftwareDevice::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);
m_pausedSounds.erase(i);
if(!m_playback)
playing(m_playback = true);
result = true;
break;
}
}
unlock();
return result;
}
bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
{
bool result = false;
lock();
for(AUD_HandleIterator i = m_playingSounds.begin();
i != m_playingSounds.end(); i++)
{
if(*i == handle)
{
delete *i;
m_playingSounds.erase(i);
if(m_playingSounds.empty())
playing(m_playback = false);
result = true;
break;
}
}
if(!result)
{
for(AUD_HandleIterator i = m_pausedSounds.begin();
i != m_pausedSounds.end(); i++)
{
if(*i == handle)
{
delete *i;
m_pausedSounds.erase(i);
result = true;
break;
}
}
}
unlock();
return result;
}
bool AUD_SoftwareDevice::getKeep(AUD_Handle* handle)
{
bool result = false;
lock();
if(isValid(handle))
result = ((AUD_SoftwareHandle*)handle)->keep;
unlock();
return result;
}
bool AUD_SoftwareDevice::setKeep(AUD_Handle* handle, bool keep)
{
bool result = false;
lock();
if(isValid(handle))
{
((AUD_SoftwareHandle*)handle)->keep = keep;
result = true;
}
unlock();
return result;
}
bool AUD_SoftwareDevice::seek(AUD_Handle* handle, float position)
{
lock();
bool result = false;
if(isValid(handle))
{
AUD_Reference<AUD_IReader> reader = ((AUD_SoftwareHandle*)handle)->reader;
reader->seek((int)(position * reader->getSpecs().rate));
result = true;
}
unlock();
return result;
}
float AUD_SoftwareDevice::getPosition(AUD_Handle* handle)
{
lock();
float position = 0.0f;
if(isValid(handle))
{
AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
position = h->reader->getPosition() / (float)m_specs.rate;
}
unlock();
return position;
}
AUD_Status AUD_SoftwareDevice::getStatus(AUD_Handle* handle)
{
AUD_Status status = AUD_STATUS_INVALID;
lock();
for(AUD_HandleIterator i = m_playingSounds.begin();
i != m_playingSounds.end(); i++)
{
if(*i == handle)
{
status = AUD_STATUS_PLAYING;
break;
}
}
if(status == AUD_STATUS_INVALID)
{
for(AUD_HandleIterator i = m_pausedSounds.begin();
i != m_pausedSounds.end(); i++)
{
if(*i == handle)
{
status = AUD_STATUS_PAUSED;
break;
}
}
}
unlock();
return status;
}
void AUD_SoftwareDevice::lock()
{
pthread_mutex_lock(&m_mutex);
@@ -442,67 +393,3 @@ void AUD_SoftwareDevice::setVolume(float volume)
{
m_volume = volume;
}
float AUD_SoftwareDevice::getVolume(AUD_Handle* handle)
{
lock();
float result = std::numeric_limits<float>::quiet_NaN();
if(isValid(handle))
result = ((AUD_SoftwareHandle*)handle)->volume;
unlock();
return result;
}
bool AUD_SoftwareDevice::setVolume(AUD_Handle* handle, float volume)
{
lock();
bool result = isValid(handle);
if(result)
((AUD_SoftwareHandle*)handle)->volume = volume;
unlock();
return result;
}
float AUD_SoftwareDevice::getPitch(AUD_Handle* handle)
{
return std::numeric_limits<float>::quiet_NaN();
}
bool AUD_SoftwareDevice::setPitch(AUD_Handle* handle, float pitch)
{
return false;
}
int AUD_SoftwareDevice::getLoopCount(AUD_Handle* handle)
{
lock();
int result = 0;
if(isValid(handle))
result = ((AUD_SoftwareHandle*)handle)->loopcount;
unlock();
return result;
}
bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int count)
{
lock();
bool result = isValid(handle);
if(result)
((AUD_SoftwareHandle*)handle)->loopcount = count;
unlock();
return result;
}
bool AUD_SoftwareDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
{
lock();
bool result = isValid(handle);
if(result)
{
AUD_SoftwareHandle* h = (AUD_SoftwareHandle*)handle;
h->stop = callback;
h->stop_data = data;
}
unlock();
return result;
}

View File

@@ -33,9 +33,9 @@
#define AUD_SOFTWAREDEVICE
#include "AUD_IDevice.h"
#include "AUD_IHandle.h"
#include "AUD_Mixer.h"
#include "AUD_Buffer.h"
struct AUD_SoftwareHandle;
#include <list>
#include <pthread.h>
@@ -51,6 +51,56 @@ struct AUD_SoftwareHandle;
class AUD_SoftwareDevice : public AUD_IDevice
{
protected:
/// Saves the data for playback.
class AUD_SoftwareHandle : public AUD_IHandle
{
public:
/// The reader source.
AUD_Reference<AUD_IReader> m_reader;
/// Whether to keep the source if end of it is reached.
bool m_keep;
/// The volume of the source.
float m_volume;
/// 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_SoftwareDevice* m_device;
public:
AUD_SoftwareHandle(AUD_SoftwareDevice* device, AUD_Reference<AUD_IReader> reader, bool keep);
virtual ~AUD_SoftwareHandle() {}
virtual bool pause();
virtual bool resume();
virtual bool stop();
virtual bool getKeep();
virtual bool setKeep(bool keep);
virtual bool seek(float position);
virtual float getPosition();
virtual AUD_Status getStatus();
virtual float getVolume();
virtual bool setVolume(float volume);
virtual float getPitch();
virtual bool setPitch(float pitch);
virtual int getLoopCount();
virtual bool setLoopCount(int count);
virtual bool setStopCallback(stopCallback callback = 0, void* data = 0);
};
/**
* The specification of the device.
*/
@@ -93,12 +143,12 @@ private:
/**
* The list of sounds that are currently playing.
*/
std::list<AUD_SoftwareHandle*> m_playingSounds;
std::list<AUD_Reference<AUD_SoftwareHandle> > m_playingSounds;
/**
* The list of sounds that are currently paused.
*/
std::list<AUD_SoftwareHandle*> m_pausedSounds;
std::list<AUD_Reference<AUD_SoftwareHandle> > m_pausedSounds;
/**
* Whether there is currently playback.
@@ -115,36 +165,14 @@ private:
*/
float m_volume;
/**
* Checks if a handle is valid.
* \param handle The handle to check.
* \return Whether the handle is valid.
*/
bool isValid(AUD_Handle* handle);
public:
virtual AUD_DeviceSpecs getSpecs() const;
virtual AUD_Handle* play(AUD_Reference<AUD_IReader> reader, bool keep = false);
virtual AUD_Handle* play(AUD_Reference<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);
};
#endif //AUD_SOFTWAREDEVICE

View File

@@ -51,7 +51,8 @@ static void sound_sync_callback(void* data, int mode, float time)
sound_play_scene(scene);
else
sound_stop_scene(scene);
AUD_seek(scene->sound_scene_handle, time);
if(scene->sound_scene_handle)
AUD_seek(scene->sound_scene_handle, time);
}
scene = scene->id.next;
}
@@ -345,7 +346,7 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start,
AUD_setDeviceVolume(mixdown, volume);
AUD_playDevice(mixdown, scene->sound_scene, start / FPS);
AUD_freeChannel(AUD_playDevice(mixdown, scene->sound_scene, start / FPS));
return mixdown;
}
@@ -353,12 +354,16 @@ AUD_Device* sound_mixdown(struct Scene *scene, AUD_DeviceSpecs specs, int start,
void sound_create_scene(struct Scene *scene)
{
scene->sound_scene = AUD_createSequencer(scene->audio.flag & AUDIO_MUTE, scene, (AUD_volumeFunction)&sound_get_volume);
scene->sound_scene_handle = NULL;
scene->sound_scrub_handle = NULL;
}
void sound_destroy_scene(struct Scene *scene)
{
if(scene->sound_scene_handle)
AUD_stop(scene->sound_scene_handle);
if(scene->sound_scrub_handle)
AUD_stop(scene->sound_scrub_handle);
if(scene->sound_scene)
AUD_destroySequencer(scene->sound_scene);
}
@@ -398,8 +403,10 @@ void sound_move_scene_sound(struct Scene *scene, void* handle, int startframe, i
static void sound_start_play_scene(struct Scene *scene)
{
scene->sound_scene_handle = AUD_play(scene->sound_scene, 1);
AUD_setLoop(scene->sound_scene_handle, -1);
if(scene->sound_scene_handle)
AUD_stop(scene->sound_scene_handle);
if((scene->sound_scene_handle = AUD_play(scene->sound_scene, 1)))
AUD_setLoop(scene->sound_scene_handle, -1);
}
void sound_play_scene(struct Scene *scene)
@@ -407,11 +414,17 @@ void sound_play_scene(struct Scene *scene)
AUD_Status status;
AUD_lock();
status = AUD_getStatus(scene->sound_scene_handle);
status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
if(status == AUD_STATUS_INVALID)
sound_start_play_scene(scene);
if(!scene->sound_scene_handle)
{
AUD_unlock();
return;
}
if(status != AUD_STATUS_PLAYING)
{
AUD_seek(scene->sound_scene_handle, CFRA / FPS);
@@ -426,10 +439,13 @@ void sound_play_scene(struct Scene *scene)
void sound_stop_scene(struct Scene *scene)
{
AUD_pause(scene->sound_scene_handle);
if(scene->sound_scene_handle)
{
AUD_pause(scene->sound_scene_handle);
if(scene->audio.flag & AUDIO_SYNC)
AUD_stopPlayback();
if(scene->audio.flag & AUDIO_SYNC)
AUD_stopPlayback();
}
}
void sound_seek_scene(struct bContext *C)
@@ -439,11 +455,18 @@ void sound_seek_scene(struct bContext *C)
AUD_lock();
status = AUD_getStatus(scene->sound_scene_handle);
status = scene->sound_scene_handle ? AUD_getStatus(scene->sound_scene_handle) : AUD_STATUS_INVALID;
if(status == AUD_STATUS_INVALID)
{
sound_start_play_scene(scene);
if(!scene->sound_scene_handle)
{
AUD_unlock();
return;
}
AUD_pause(scene->sound_scene_handle);
}
@@ -457,10 +480,14 @@ void sound_seek_scene(struct bContext *C)
else
AUD_seek(scene->sound_scene_handle, CFRA / FPS);
AUD_resume(scene->sound_scene_handle);
if(AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
if(scene->sound_scrub_handle && AUD_getStatus(scene->sound_scrub_handle) != AUD_STATUS_INVALID)
AUD_seek(scene->sound_scrub_handle, 0);
else
{
if(scene->sound_scrub_handle)
AUD_stop(scene->sound_scrub_handle);
scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
}
}
else
{
@@ -478,10 +505,14 @@ void sound_seek_scene(struct bContext *C)
float sound_sync_scene(struct Scene *scene)
{
if(scene->audio.flag & AUDIO_SYNC)
return AUD_getSequencerPosition(scene->sound_scene_handle);
else
return AUD_getPosition(scene->sound_scene_handle);
if(scene->sound_scene_handle)
{
if(scene->audio.flag & AUDIO_SYNC)
return AUD_getSequencerPosition(scene->sound_scene_handle);
else
return AUD_getPosition(scene->sound_scene_handle);
}
return 0.0f;
}
int sound_scene_playing(struct Scene *scene)

View File

@@ -75,7 +75,10 @@ KX_SoundActuator::~KX_SoundActuator()
void KX_SoundActuator::play()
{
if(m_handle)
{
AUD_stop(m_handle);
m_handle = NULL;
}
if(!m_sound)
return;
@@ -103,11 +106,16 @@ void KX_SoundActuator::play()
break;
}
m_handle = AUD_play(sound, 0);
if(sound2)
AUD_unload(sound2);
if(!m_handle)
return;
if(m_is3d)
{
// sound shall be played 3D
m_handle = AUD_play(sound, 0);
AUD_setRelative(m_handle, false);
AUD_setVolumeMaximum(m_handle, m_3d.max_gain);
AUD_setVolumeMinimum(m_handle, m_3d.min_gain);
@@ -118,17 +126,12 @@ void KX_SoundActuator::play()
AUD_setConeAngleOuter(m_handle, m_3d.cone_outer_angle);
AUD_setConeVolumeOuter(m_handle, m_3d.cone_outer_gain);
}
else
m_handle = AUD_play(sound, 0);
if(loop)
AUD_setLoop(m_handle, -1);
AUD_setSoundPitch(m_handle, m_pitch);
AUD_setSoundVolume(m_handle, m_volume);
m_isplaying = true;
if(sound2)
AUD_unload(sound2);
}
CValue* KX_SoundActuator::GetReplica()
@@ -160,7 +163,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
return false;
// actual audio device playing state
bool isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING;
bool isplaying = m_handle ? (AUD_getStatus(m_handle) == AUD_STATUS_PLAYING) : false;
if (bNegativeEvent)
{
@@ -174,7 +177,9 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
case KX_SOUNDACT_LOOPBIDIRECTIONAL_STOP:
{
// stop immediately
AUD_stop(m_handle);
if(m_handle)
AUD_stop(m_handle);
m_handle = NULL;
break;
}
case KX_SOUNDACT_PLAYEND:
@@ -186,7 +191,8 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
case KX_SOUNDACT_LOOPBIDIRECTIONAL:
{
// stop the looping so that the sound stops when it finished
AUD_setLoop(m_handle, 0);
if(m_handle)
AUD_setLoop(m_handle, 0);
break;
}
default:
@@ -212,7 +218,7 @@ bool KX_SoundActuator::Update(double curtime, bool frame)
play();
}
// verify that the sound is still playing
isplaying = AUD_getStatus(m_handle) == AUD_STATUS_PLAYING ? true : false;
isplaying = m_handle ? (AUD_getStatus(m_handle) == AUD_STATUS_PLAYING) : false;
if (isplaying)
{
@@ -301,15 +307,18 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, startSound,
"startSound()\n"
"\tStarts the sound.\n")
{
switch(AUD_getStatus(m_handle))
if(m_handle)
{
case AUD_STATUS_PLAYING:
break;
case AUD_STATUS_PAUSED:
AUD_resume(m_handle);
break;
default:
play();
switch(AUD_getStatus(m_handle))
{
case AUD_STATUS_PLAYING:
break;
case AUD_STATUS_PAUSED:
AUD_resume(m_handle);
break;
default:
play();
}
}
Py_RETURN_NONE;
}
@@ -318,7 +327,8 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, pauseSound,
"pauseSound()\n"
"\tPauses the sound.\n")
{
AUD_pause(m_handle);
if(m_handle)
AUD_pause(m_handle);
Py_RETURN_NONE;
}
@@ -326,7 +336,9 @@ KX_PYMETHODDEF_DOC_NOARGS(KX_SoundActuator, stopSound,
"stopSound()\n"
"\tStops the sound.\n")
{
AUD_stop(m_handle);
if(m_handle)
AUD_stop(m_handle);
m_handle = NULL;
Py_RETURN_NONE;
}