Audaspace Refactor:

* Removed whole Capabilities System
* Fixed Py API error strings
* Improved some Py API properties
* Minor other changes
This commit is contained in:
Joerg Mueller
2010-07-28 12:43:59 +00:00
parent 7296600434
commit 3ff872bf59
13 changed files with 395 additions and 469 deletions

View File

@@ -27,7 +27,6 @@
#include "AUD_IFactory.h"
#include "AUD_IReader.h"
#include "AUD_ConverterReader.h"
#include "AUD_SourceCaps.h"
#include <cstring>
#include <limits>
@@ -762,6 +761,20 @@ bool AUD_OpenALDevice::stop(AUD_Handle* handle)
return result;
}
bool AUD_OpenALDevice::getKeep(AUD_Handle* handle)
{
bool result = false;
lock();
if(isValid(handle))
result = ((AUD_OpenALHandle*)handle)->keep;
unlock();
return result;
}
bool AUD_OpenALDevice::setKeep(AUD_Handle* handle, bool keep)
{
bool result = false;
@@ -910,214 +923,178 @@ void AUD_OpenALDevice::unlock()
pthread_mutex_unlock(&m_mutex);
}
/******************************************************************************/
/**************************** Capabilities Code *******************************/
/******************************************************************************/
bool AUD_OpenALDevice::checkCapability(int capability)
float AUD_OpenALDevice::getVolume() const
{
return capability == AUD_CAPS_3D_DEVICE ||
capability == AUD_CAPS_VOLUME ||
capability == AUD_CAPS_SOURCE_VOLUME ||
capability == AUD_CAPS_SOURCE_PITCH ||
capability == AUD_CAPS_BUFFERED_FACTORY;
}
bool AUD_OpenALDevice::setCapability(int capability, void *value)
{
bool result = false;
switch(capability)
{
case AUD_CAPS_VOLUME:
alListenerf(AL_GAIN, *((float*)value));
return true;
case AUD_CAPS_SOURCE_VOLUME:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_GAIN, caps->value);
result = true;
}
unlock();
}
break;
case AUD_CAPS_SOURCE_PITCH:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
alSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_PITCH, caps->value);
result = true;
}
unlock();
}
break;
case AUD_CAPS_BUFFERED_FACTORY:
{
AUD_IFactory* factory = (AUD_IFactory*) value;
// load the factory into an OpenAL buffer
if(factory)
{
// check if the factory is already buffered
lock();
for(AUD_BFIterator i = m_bufferedFactories->begin();
i != m_bufferedFactories->end(); i++)
{
if((*i)->factory == factory)
{
result = true;
break;
}
}
unlock();
if(result)
return result;
AUD_IReader* reader = factory->createReader();
if(reader == NULL)
return false;
AUD_DeviceSpecs specs = m_specs;
specs.specs = reader->getSpecs();
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
ALenum format;
if(!getFormat(format, specs.specs))
{
delete reader;
return false;
}
// load into a buffer
lock();
alcSuspendContext(m_context);
AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
bf->factory = factory;
try
{
alGenBuffers(1, &bf->buffer);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
try
{
sample_t* buf;
int length = reader->getLength();
reader->read(length, buf);
alBufferData(bf->buffer, format, buf,
length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
}
catch(AUD_Exception&)
{
alDeleteBuffers(1, &bf->buffer);
throw;
}
}
catch(AUD_Exception&)
{
delete bf;
delete reader;
alcProcessContext(m_context);
unlock();
return false;
}
m_bufferedFactories->push_back(bf);
alcProcessContext(m_context);
unlock();
}
else
{
// stop all playing and paused buffered sources
lock();
alcSuspendContext(m_context);
AUD_OpenALHandle* sound;
AUD_HandleIterator it = m_playingSounds->begin();
while(it != m_playingSounds->end())
{
sound = *it;
++it;
if(sound->isBuffered)
stop(sound);
}
alcProcessContext(m_context);
while(!m_bufferedFactories->empty())
{
alDeleteBuffers(1,
&(*(m_bufferedFactories->begin()))->buffer);
delete *m_bufferedFactories->begin();
m_bufferedFactories->erase(m_bufferedFactories->begin());
}
unlock();
}
return true;
}
break;
}
float result;
alGetListenerf(AL_GAIN, &result);
return result;
}
bool AUD_OpenALDevice::getCapability(int capability, void *value)
void AUD_OpenALDevice::setVolume(float volume)
{
bool result = false;
switch(capability)
{
case AUD_CAPS_VOLUME:
alGetListenerf(AL_GAIN, (float*)value);
return true;
case AUD_CAPS_SOURCE_VOLUME:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_GAIN, &caps->value);
result = true;
}
unlock();
}
break;
case AUD_CAPS_SOURCE_PITCH:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
alGetSourcef(((AUD_OpenALHandle*)caps->handle)->source,
AL_PITCH, &caps->value);
result = true;
}
unlock();
}
break;
}
alListenerf(AL_GAIN, volume);
}
float AUD_OpenALDevice::getVolume(AUD_Handle* handle)
{
lock();
float result = std::numeric_limits<float>::quiet_NaN();
if(isValid(handle))
alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_GAIN, &result);
unlock();
return result;
}
bool AUD_OpenALDevice::setVolume(AUD_Handle* handle, float volume)
{
lock();
bool result = isValid(handle);
if(result)
alSourcef(((AUD_OpenALHandle*)handle)->source, AL_GAIN, volume);
unlock();
return result;
}
float AUD_OpenALDevice::getPitch(AUD_Handle* handle)
{
lock();
float result = std::numeric_limits<float>::quiet_NaN();
if(isValid(handle))
alGetSourcef(((AUD_OpenALHandle*)handle)->source,AL_PITCH, &result);
unlock();
return result;
}
bool AUD_OpenALDevice::setPitch(AUD_Handle* handle, float pitch)
{
lock();
bool result = isValid(handle);
if(result)
alSourcef(((AUD_OpenALHandle*)handle)->source, AL_PITCH, pitch);
unlock();
return result;
}
/* AUD_XXX Temorary disabled
bool AUD_OpenALDevice::bufferFactory(void *value)
{
bool result = false;
AUD_IFactory* factory = (AUD_IFactory*) value;
// load the factory into an OpenAL buffer
if(factory)
{
// check if the factory is already buffered
lock();
for(AUD_BFIterator i = m_bufferedFactories->begin();
i != m_bufferedFactories->end(); i++)
{
if((*i)->factory == factory)
{
result = true;
break;
}
}
unlock();
if(result)
return result;
AUD_IReader* reader = factory->createReader();
if(reader == NULL)
return false;
AUD_DeviceSpecs specs = m_specs;
specs.specs = reader->getSpecs();
if(m_specs.format != AUD_FORMAT_FLOAT32)
reader = new AUD_ConverterReader(reader, m_specs);
ALenum format;
if(!getFormat(format, specs.specs))
{
delete reader;
return false;
}
// load into a buffer
lock();
alcSuspendContext(m_context);
AUD_OpenALBufferedFactory* bf = new AUD_OpenALBufferedFactory;
bf->factory = factory;
try
{
alGenBuffers(1, &bf->buffer);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
try
{
sample_t* buf;
int length = reader->getLength();
reader->read(length, buf);
alBufferData(bf->buffer, format, buf,
length * AUD_DEVICE_SAMPLE_SIZE(specs),
specs.rate);
if(alGetError() != AL_NO_ERROR)
AUD_THROW(AUD_ERROR_OPENAL);
}
catch(AUD_Exception&)
{
alDeleteBuffers(1, &bf->buffer);
throw;
}
}
catch(AUD_Exception&)
{
delete bf;
delete reader;
alcProcessContext(m_context);
unlock();
return false;
}
m_bufferedFactories->push_back(bf);
alcProcessContext(m_context);
unlock();
}
else
{
// stop all playing and paused buffered sources
lock();
alcSuspendContext(m_context);
AUD_OpenALHandle* sound;
AUD_HandleIterator it = m_playingSounds->begin();
while(it != m_playingSounds->end())
{
sound = *it;
++it;
if(sound->isBuffered)
stop(sound);
}
alcProcessContext(m_context);
while(!m_bufferedFactories->empty())
{
alDeleteBuffers(1,
&(*(m_bufferedFactories->begin()))->buffer);
delete *m_bufferedFactories->begin();
m_bufferedFactories->erase(m_bufferedFactories->begin());
}
unlock();
}
return true;
}*/
/******************************************************************************/
/**************************** 3D Device Code **********************************/
/******************************************************************************/

View File

@@ -145,15 +145,19 @@ public:
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 void lock();
virtual void unlock();
virtual bool checkCapability(int capability);
virtual bool setCapability(int capability, void *value);
virtual bool getCapability(int capability, void *value);
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 AUD_Handle* play3D(AUD_IFactory* factory, bool keep = false);
virtual bool updateListener(AUD_3DData &data);

View File

@@ -27,7 +27,6 @@
#include "structmember.h"
#include "AUD_NULLDevice.h"
#include "AUD_SourceCaps.h"
#include "AUD_DelayFactory.h"
#include "AUD_DoubleFactory.h"
#include "AUD_FaderFactory.h"
@@ -1039,7 +1038,9 @@ Handle_update(Handle *self, PyObject *args)
if(device)
{
if(device->updateSource(self->handle, data))
{
Py_RETURN_TRUE;
}
}
else
{
@@ -1104,21 +1105,42 @@ Handle_set_position(Handle *self, PyObject* args, void* nothing)
try
{
if(device->device->seek(self->handle, position))
{
return 0;
}
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't seek the sound!");
}
PyErr_SetString(AUDError, "Couldn't seek the sound!");
return -1;
}
PyDoc_STRVAR(M_aud_Handle_keep_doc,
"Whether the sound should be kept paused in the device when its end is reached.");
static PyObject *
Handle_get_keep(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
if(device->device->getKeep(self->handle))
{
Py_RETURN_TRUE;
}
else
{
Py_RETURN_FALSE;
}
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't retrieve the status of the sound!");
return NULL;
}
}
static int
Handle_set_keep(Handle *self, PyObject* args, void* nothing)
{
@@ -1134,15 +1156,13 @@ Handle_set_keep(Handle *self, PyObject* args, void* nothing)
try
{
if(device->device->setKeep(self->handle, keep))
{
return 0;
}
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
}
PyErr_SetString(AUDError, "Couldn't set keep of the sound!");
return -1;
}
@@ -1175,21 +1195,13 @@ Handle_get_volume(Handle *self, void* nothing)
try
{
AUD_SourceCaps caps;
caps.handle = self->handle;
caps.value = 1.0f;
if(device->device->getCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
{
return Py_BuildValue("f", caps.value);
}
return Py_BuildValue("f", device->device->getVolume(self->handle));
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't get the sound volume!");
return NULL;
}
Py_RETURN_NAN;
}
static int
@@ -1204,25 +1216,36 @@ Handle_set_volume(Handle *self, PyObject* args, void* nothing)
try
{
AUD_SourceCaps caps;
caps.handle = self->handle;
caps.value = volume;
if(device->device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps))
{
if(device->device->setVolume(self->handle, volume))
return 0;
}
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
}
PyErr_SetString(AUDError, "Couldn't set the sound volume!");
return -1;
}
PyDoc_STRVAR(M_aud_Handle_pitch_doc,
"The pitch of the sound.");
static PyObject *
Handle_get_pitch(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
return Py_BuildValue("f", device->device->getPitch(self->handle));
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't get the sound pitch!");
return NULL;
}
}
static int
Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
{
@@ -1235,25 +1258,37 @@ Handle_set_pitch(Handle *self, PyObject* args, void* nothing)
try
{
AUD_SourceCaps caps;
caps.handle = self->handle;
caps.value = pitch;
if(device->device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps))
{
if(device->device->setPitch(self->handle, pitch))
return 0;
}
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
}
PyErr_SetString(AUDError, "Couldn't set the sound pitch!");
return -1;
}
PyDoc_STRVAR(M_aud_Handle_loop_count_doc,
"The (remaining) loop count of the sound. A negative value indicates infinity.");
static PyObject *
Handle_get_loop_count(Handle *self, void* nothing)
{
Device* device = (Device*)self->device;
try
{
// AUD_XXX will come soon; return Py_BuildValue("f", device->device->getPitch(self->handle));
AUD_THROW(AUD_ERROR_FACTORY);
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't get the loop count!");
return NULL;
}
}
static int
Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
{
@@ -1277,9 +1312,9 @@ Handle_set_loop_count(Handle *self, PyObject* args, void* nothing)
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't set the loop count!");
}
PyErr_SetString(AUDError, "Couldn't set the loop count!");
return -1;
}
@@ -1339,9 +1374,7 @@ Handle_set_relative(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1398,9 +1431,7 @@ Handle_set_min_gain(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1457,9 +1488,7 @@ Handle_set_max_gain(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1516,9 +1545,7 @@ Handle_set_reference_distance(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1553,7 +1580,8 @@ Handle_get_max_distance(Handle *self, void* nothing)
{
PyErr_SetString(AUDError, "Couldn't retrieve the maximum distance of the sound!");
return NULL;
}}
}
}
static int
Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
@@ -1574,9 +1602,7 @@ Handle_set_max_distance(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1633,9 +1659,7 @@ Handle_set_rolloff_factor(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1692,9 +1716,7 @@ Handle_set_cone_inner_angle(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1751,9 +1773,7 @@ Handle_set_cone_outer_angle(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1810,9 +1830,7 @@ Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -1825,15 +1843,15 @@ Handle_set_cone_outer_gain(Handle *self, PyObject* args, void* nothing)
static PyGetSetDef Handle_properties[] = {
{(char*)"position", (getter)Handle_get_position, (setter)Handle_set_position,
M_aud_Handle_position_doc, NULL },
{(char*)"keep", NULL, (setter)Handle_set_keep,
{(char*)"keep", (getter)Handle_get_keep, (setter)Handle_set_keep,
M_aud_Handle_keep_doc, NULL },
{(char*)"status", (getter)Handle_get_status, NULL,
M_aud_Handle_status_doc, NULL },
{(char*)"volume", (getter)Handle_get_volume, (setter)Handle_set_volume,
M_aud_Handle_volume_doc, NULL },
{(char*)"pitch", NULL, (setter)Handle_set_pitch,
{(char*)"pitch", (getter)Handle_get_pitch, (setter)Handle_set_pitch,
M_aud_Handle_pitch_doc, NULL },
{(char*)"loop_count", NULL, (setter)Handle_set_loop_count,
{(char*)"loop_count", (getter)Handle_get_loop_count, (setter)Handle_set_loop_count,
M_aud_Handle_loop_count_doc, NULL },
{(char*)"relative", (getter)Handle_get_relative, (setter)Handle_set_relative,
M_aud_Handle_relative_doc, NULL },
@@ -2278,17 +2296,13 @@ Device_get_volume(Device *self, void* nothing)
{
try
{
float volume = 0.0;
if(self->device->getCapability(AUD_CAPS_VOLUME, &volume))
return Py_BuildValue("f", volume);
return Py_BuildValue("f", self->device->getVolume());
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't retrieve device volume!");
return NULL;
}
Py_RETURN_NAN;
}
static int
@@ -2301,15 +2315,14 @@ Device_set_volume(Device *self, PyObject* args, void* nothing)
try
{
if(self->device->setCapability(AUD_CAPS_VOLUME, &volume))
return 0;
self->device->setVolume(volume);
return 0;
}
catch(AUD_Exception&)
{
PyErr_SetString(AUDError, "Couldn't set device volume!");
return -1;
}
return -1;
}
PyDoc_STRVAR(M_aud_Device_speed_of_sound_doc,
@@ -2355,9 +2368,7 @@ Device_set_speed_of_sound(Device *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -2410,9 +2421,7 @@ Device_set_doppler_factor(Device *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{
@@ -2465,9 +2474,7 @@ Device_set_distance_model(Device *self, PyObject* args, void* nothing)
return 0;
}
else
{
PyErr_SetString(AUDError, "Device is not a 3D device!");
}
}
catch(AUD_Exception&)
{

View File

@@ -58,7 +58,6 @@ bool g_pyinitialized = false;
#include "AUD_ChannelMapperFactory.h"
#include "AUD_Buffer.h"
#include "AUD_ReadDevice.h"
#include "AUD_SourceCaps.h"
#include "AUD_IReader.h"
#include "AUD_SequencerFactory.h"
@@ -139,8 +138,7 @@ int AUD_init(AUD_DeviceType device, AUD_DeviceSpecs specs, int buffersize)
}
AUD_device = dev;
if(AUD_device->checkCapability(AUD_CAPS_3D_DEVICE))
AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
AUD_3ddevice = dynamic_cast<AUD_I3DDevice*>(AUD_device);
#ifdef WITH_PYTHON
if(g_pyinitialized)
@@ -570,13 +568,10 @@ int AUD_setSoundVolume(AUD_Channel* handle, float volume)
if(handle)
{
assert(AUD_device);
AUD_SourceCaps caps;
caps.handle = handle;
caps.value = volume;
try
{
return AUD_device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
return AUD_device->setVolume(handle, volume);
}
catch(AUD_Exception&) {}
}
@@ -588,13 +583,10 @@ int AUD_setSoundPitch(AUD_Channel* handle, float pitch)
if(handle)
{
assert(AUD_device);
AUD_SourceCaps caps;
caps.handle = handle;
caps.value = pitch;
try
{
return AUD_device->setCapability(AUD_CAPS_SOURCE_PITCH, &caps);
return AUD_device->setPitch(handle, pitch);
}
catch(AUD_Exception&) {}
}
@@ -636,7 +628,8 @@ int AUD_setDeviceVolume(AUD_Device* device, float volume)
try
{
return device->setCapability(AUD_CAPS_VOLUME, &volume);
device->setVolume(volume);
return true;
}
catch(AUD_Exception&) {}
@@ -649,13 +642,10 @@ int AUD_setDeviceSoundVolume(AUD_Device* device, AUD_Channel* handle,
if(handle)
{
assert(device);
AUD_SourceCaps caps;
caps.handle = handle;
caps.value = volume;
try
{
return device->setCapability(AUD_CAPS_SOURCE_VOLUME, &caps);
return device->setVolume(handle, volume);
}
catch(AUD_Exception&) {}
}

View File

@@ -75,5 +75,5 @@ AUD_IReader* AUD_FileFactory::createReader() const
catch(AUD_Exception&) {}
#endif
AUD_THROW(AUD_ERROR_FILE)
AUD_THROW(AUD_ERROR_FILE);
}

View File

@@ -30,8 +30,6 @@
/**
* This class represents an output device for 3D sound.
* Whether a normal device supports this or not can be checked with the
* AUD_CAPS_3D_DEVICE capability.
*/
class AUD_I3DDevice
{

View File

@@ -95,6 +95,16 @@ public:
*/
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.
@@ -153,29 +163,50 @@ public:
virtual void unlock()=0;
/**
* Checks if a specific capability as available on a device.
* \param capability The capability.
* \return Whether it is available or not.
* Retrieves the overall device volume.
* \return The overall device volume.
*/
virtual bool checkCapability(int capability)=0;
virtual float getVolume() const=0;
/**
* Set a value of a capability. The data behind the pointer depends on the
* capability.
* \param capability The capability.
* \param value The value.
* \return Whether the action succeeded or not.
* Sets the overall device volume.
* \param handle The sound handle.
* \param volume The overall device volume.
*/
virtual bool setCapability(int capability, void *value)=0;
virtual void setVolume(float volume)=0;
/**
* Retrieves a value of a capability. The data behind the pointer depends on
* the capability.
* \param capability The capability.
* \param value The value.
* \return Whether the action succeeded or not.
* Retrieves the volume of a playing sound.
* \param handle The sound handle.
* \return The volume.
*/
virtual bool getCapability(int capability, void *value)=0;
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;
};
#endif //AUD_IDevice

View File

@@ -62,6 +62,11 @@ 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;
@@ -90,17 +95,31 @@ void AUD_NULLDevice::unlock()
{
}
bool AUD_NULLDevice::checkCapability(int capability)
float AUD_NULLDevice::getVolume() const
{
return 0;
}
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;
}
bool AUD_NULLDevice::setCapability(int capability, void *value)
float AUD_NULLDevice::getPitch(AUD_Handle* handle)
{
return false;
return std::numeric_limits<float>::quiet_NaN();
}
bool AUD_NULLDevice::getCapability(int capability, void *value)
bool AUD_NULLDevice::setPitch(AUD_Handle* handle, float pitch)
{
return false;
}

View File

@@ -44,15 +44,19 @@ public:
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 void lock();
virtual void unlock();
virtual bool checkCapability(int capability);
virtual bool setCapability(int capability, void *value);
virtual bool getCapability(int capability, void *value);
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);
};
#endif //AUD_NULLDEVICE

View File

@@ -27,9 +27,9 @@
#include "AUD_IReader.h"
#include "AUD_DefaultMixer.h"
#include "AUD_IFactory.h"
#include "AUD_SourceCaps.h"
#include <cstring>
#include <limits>
/// Saves the data for playback.
struct AUD_SoftwareHandle : AUD_Handle
@@ -281,6 +281,20 @@ bool AUD_SoftwareDevice::stop(AUD_Handle* handle)
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;
@@ -376,77 +390,42 @@ void AUD_SoftwareDevice::unlock()
pthread_mutex_unlock(&m_mutex);
}
bool AUD_SoftwareDevice::checkCapability(int capability)
float AUD_SoftwareDevice::getVolume() const
{
return capability == AUD_CAPS_SOFTWARE_DEVICE ||
capability == AUD_CAPS_VOLUME ||
capability == AUD_CAPS_SOURCE_VOLUME;
return m_volume;
}
bool AUD_SoftwareDevice::setCapability(int capability, void *value)
void AUD_SoftwareDevice::setVolume(float volume)
{
bool result = false;
switch(capability)
{
case AUD_CAPS_VOLUME:
lock();
m_volume = *((float*)value);
if(m_volume > 1.0f)
m_volume = 1.0f;
else if(m_volume < 0.0f)
m_volume = 0.0f;
unlock();
return true;
case AUD_CAPS_SOURCE_VOLUME:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
AUD_SoftwareHandle* handle = (AUD_SoftwareHandle*)caps->handle;
handle->volume = caps->value;
if(handle->volume > 1.0f)
handle->volume = 1.0f;
else if(handle->volume < 0.0f)
handle->volume = 0.0f;
result = true;
}
unlock();
}
break;
}
return result;;
m_volume = volume;
}
bool AUD_SoftwareDevice::getCapability(int capability, void *value)
float AUD_SoftwareDevice::getVolume(AUD_Handle* handle)
{
bool result = false;
switch(capability)
{
case AUD_CAPS_VOLUME:
lock();
*((float*)value) = m_volume;
unlock();
return true;
case AUD_CAPS_SOURCE_VOLUME:
{
AUD_SourceCaps* caps = (AUD_SourceCaps*) value;
lock();
if(isValid(caps->handle))
{
caps->value = ((AUD_SoftwareHandle*)caps->handle)->volume;
result = true;
}
unlock();
}
break;
}
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;
}

View File

@@ -116,15 +116,19 @@ public:
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 void lock();
virtual void unlock();
virtual bool checkCapability(int capability);
virtual bool setCapability(int capability, void *value);
virtual bool getCapability(int capability, void *value);
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);
};
#endif //AUD_SOFTWAREDEVICE

View File

@@ -1,41 +0,0 @@
/*
* $Id$
*
* ***** BEGIN LGPL LICENSE BLOCK *****
*
* Copyright 2009 Jörg Hermann Müller
*
* This file is part of AudaSpace.
*
* AudaSpace is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* AudaSpace is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
*
* ***** END LGPL LICENSE BLOCK *****
*/
#ifndef AUD_SOURCECAPS
#define AUD_SOURCECAPS
#include "AUD_IDevice.h"
/// The structure for source capabilities.
typedef struct
{
/// The source to apply the capability on.
AUD_Handle* handle;
/// The value for the capability.
float value;
} AUD_SourceCaps;
#endif //AUD_SOURCECAPS

View File

@@ -47,52 +47,6 @@
/// The default playback buffer size of a device.
#define AUD_DEFAULT_BUFFER_SIZE 1024
// Capability defines
/// This capability checks whether a device is a 3D device. See AUD_I3DDevice.h.
#define AUD_CAPS_3D_DEVICE 0x0001
/**
* This capability checks whether a device is a software device. See
* AUD_SoftwareDevice.
*/
#define AUD_CAPS_SOFTWARE_DEVICE 0x0002
/**
* This capability enables the user to set the overall volume of the device.
* You can set and get it with the pointer pointing to a float value between
* 0.0 (muted) and 1.0 (maximum volume).
*/
#define AUD_CAPS_VOLUME 0x0101
/**
* This capability enables the user to set the volume of a source.
* You can set and get it with the pointer pointing to a AUD_SourceValue
* structure defined in AUD_SourceCaps.h.
*/
#define AUD_CAPS_SOURCE_VOLUME 0x1001
/**
* This capability enables the user to set the pitch of a source.
* You can set and get it with the pointer pointing to a AUD_SourceValue
* structure defined in AUD_SourceCaps.h.
*/
#define AUD_CAPS_SOURCE_PITCH 0x1002
/**
* This capability enables the user to buffer a factory into the device.
* Setting with the factory as pointer loads the factory into a device internal
* buffer. Play function calls with the buffered factory as argument result in
* the internal buffer being played back, so there's no reader created, what
* also results in not being able to send messages to that handle.
* A repeated call with the same factory doesn't do anything.
* A set call with a NULL pointer results in all buffered factories being
* deleted.
* \note This is only possible with factories that create readers of the buffer
* type.
*/
#define AUD_CAPS_BUFFERED_FACTORY 0x2001
/**
* The format of a sample.
* The last 4 bit save the byte count of the format.