Audaspace:
* Added a stopCallback function that is called when the end of a sound is reached. * Fixed the scrubbing not working. * Minor SoundActuator cleanup.
This commit is contained in:
parent
bce3a49e2e
commit
86fc34b924
|
@ -68,6 +68,12 @@ struct AUD_OpenALHandle : AUD_Handle
|
|||
|
||||
/// The loop count of the source.
|
||||
int loopcount;
|
||||
|
||||
/// The stop callback.
|
||||
stopCallback stop;
|
||||
|
||||
/// Stop callback data.
|
||||
void* stop_data;
|
||||
};
|
||||
|
||||
struct AUD_OpenALBufferedFactory
|
||||
|
@ -131,13 +137,9 @@ void AUD_OpenALDevice::updateStreams()
|
|||
|
||||
{
|
||||
// for all sounds
|
||||
AUD_HandleIterator it = m_playingSounds->begin();
|
||||
while(it != m_playingSounds->end())
|
||||
for(AUD_HandleIterator it = m_playingSounds->begin(); it != m_playingSounds->end(); it++)
|
||||
{
|
||||
sound = *it;
|
||||
// increment the iterator to make sure it's valid,
|
||||
// in case the sound gets deleted after stopping
|
||||
++it;
|
||||
|
||||
// is it a streamed sound?
|
||||
if(!sound->isBuffered)
|
||||
|
@ -227,12 +229,21 @@ void AUD_OpenALDevice::updateStreams()
|
|||
// if it really stopped
|
||||
if(sound->data_end)
|
||||
{
|
||||
if(sound->stop)
|
||||
sound->stop(sound->stop_data);
|
||||
|
||||
// increment the iterator to the next value,
|
||||
// because the sound gets deleted in the list here.
|
||||
++it;
|
||||
// pause or
|
||||
if(sound->keep)
|
||||
pause(sound);
|
||||
// stop
|
||||
else
|
||||
stop(sound);
|
||||
// decrement again, so that we get the next sound in the
|
||||
// next loop run
|
||||
--it;
|
||||
}
|
||||
// continue playing
|
||||
else
|
||||
|
@ -1012,6 +1023,20 @@ bool AUD_OpenALDevice::setLoopCount(AUD_Handle* handle, int count)
|
|||
return result;
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
|
||||
{
|
||||
lock();
|
||||
bool result = isValid(handle);
|
||||
if(result)
|
||||
{
|
||||
AUD_OpenALHandle* h = (AUD_OpenALHandle*)handle;
|
||||
h->stop = callback;
|
||||
h->stop_data = data;
|
||||
}
|
||||
unlock();
|
||||
return result;
|
||||
}
|
||||
|
||||
/* AUD_XXX Temorary disabled
|
||||
|
||||
bool AUD_OpenALDevice::bufferFactory(void *value)
|
||||
|
|
|
@ -160,6 +160,7 @@ public:
|
|||
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);
|
||||
|
|
|
@ -60,6 +60,7 @@ bool g_pyinitialized = false;
|
|||
#include "AUD_ReadDevice.h"
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_SequencerFactory.h"
|
||||
#include "AUD_SilenceFactory.h"
|
||||
|
||||
#ifdef WITH_SDL
|
||||
#include "AUD_SDLDevice.h"
|
||||
|
@ -845,6 +846,32 @@ float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
|||
return result;
|
||||
}
|
||||
|
||||
static void pauseSound(AUD_Channel* handle)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
AUD_device->pause(handle);
|
||||
}
|
||||
|
||||
AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds)
|
||||
{
|
||||
assert(AUD_device);
|
||||
|
||||
AUD_SilenceFactory silence;
|
||||
AUD_LimiterFactory limiter(&silence, 0, seconds);
|
||||
|
||||
try
|
||||
{
|
||||
AUD_Channel* channel = AUD_device->play(&limiter);
|
||||
AUD_device->setStopCallback(channel, (stopCallback)pauseSound, handle);
|
||||
return channel;
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume)
|
||||
{
|
||||
/* AUD_XXX should be this: but AUD_createSequencer is called before the device
|
||||
|
|
|
@ -463,6 +463,14 @@ extern float* AUD_readSoundBuffer(const char* filename, float low, float high,
|
|||
float sthreshold, int samplerate,
|
||||
int* length);
|
||||
|
||||
/**
|
||||
* Pauses a playing sound after a specific amount of time.
|
||||
* \param handle The handle to the sound.
|
||||
* \param time The time in seconds.
|
||||
* \return The silence handle.
|
||||
*/
|
||||
extern AUD_Channel* AUD_pauseAfter(AUD_Channel* handle, float seconds);
|
||||
|
||||
extern AUD_Sound* AUD_createSequencer(void* data, AUD_volumeFunction volume);
|
||||
|
||||
extern void AUD_destroySequencer(AUD_Sound* sequencer);
|
||||
|
|
|
@ -34,6 +34,8 @@ struct AUD_Handle
|
|||
{
|
||||
};
|
||||
|
||||
typedef void (*stopCallback)(void*);
|
||||
|
||||
/**
|
||||
* This class represents an output device for sound sources.
|
||||
* Output devices may be several backends such as plattform independand like
|
||||
|
@ -225,6 +227,18 @@ public:
|
|||
* - 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
|
||||
|
|
|
@ -133,3 +133,8 @@ bool AUD_NULLDevice::setLoopCount(AUD_Handle* handle, int count)
|
|||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AUD_NULLDevice::setStopCallback(AUD_Handle* handle, stopCallback callback, void* data)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -59,6 +59,7 @@ public:
|
|||
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
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SilenceFactory.h"
|
||||
#include "AUD_SilenceReader.h"
|
||||
#include "AUD_Space.h"
|
||||
|
||||
AUD_SilenceFactory::AUD_SilenceFactory()
|
||||
{
|
||||
}
|
||||
|
||||
AUD_IReader* AUD_SilenceFactory::createReader() const
|
||||
{
|
||||
return new AUD_SilenceReader();
|
||||
}
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* $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_SILENCEFACTORY
|
||||
#define AUD_SILENCEFACTORY
|
||||
|
||||
#include "AUD_IFactory.h"
|
||||
|
||||
/**
|
||||
* This factory creates a reader that plays a sine tone.
|
||||
*/
|
||||
class AUD_SilenceFactory : public AUD_IFactory
|
||||
{
|
||||
private:
|
||||
// hide copy constructor and operator=
|
||||
AUD_SilenceFactory(const AUD_SilenceFactory&);
|
||||
AUD_SilenceFactory& operator=(const AUD_SilenceFactory&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new silence factory.
|
||||
*/
|
||||
AUD_SilenceFactory();
|
||||
|
||||
virtual AUD_IReader* createReader() const;
|
||||
};
|
||||
|
||||
#endif //AUD_SILENCEFACTORY
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* $Id$
|
||||
*
|
||||
* ***** BEGIN LGPL LICENSE BLOCK *****
|
||||
*
|
||||
* Copyright 2009 Jörg Hermann Müller
|
||||
*
|
||||
* This file is part of AudaSpace.
|
||||
*
|
||||
* AudaSpace is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AudaSpace is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with AudaSpace. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* ***** END LGPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "AUD_SilenceReader.h"
|
||||
|
||||
#include <cstring>
|
||||
|
||||
AUD_SilenceReader::AUD_SilenceReader() :
|
||||
m_position(0)
|
||||
{
|
||||
}
|
||||
|
||||
bool AUD_SilenceReader::isSeekable() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
void AUD_SilenceReader::seek(int position)
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
int AUD_SilenceReader::getLength() const
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
int AUD_SilenceReader::getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
AUD_Specs AUD_SilenceReader::getSpecs() const
|
||||
{
|
||||
AUD_Specs specs;
|
||||
specs.rate = AUD_RATE_44100;
|
||||
specs.channels = AUD_CHANNELS_MONO;
|
||||
return specs;
|
||||
}
|
||||
|
||||
void AUD_SilenceReader::read(int & length, sample_t* & buffer)
|
||||
{
|
||||
// resize if necessary
|
||||
if(m_buffer.getSize() < length * sizeof(sample_t))
|
||||
{
|
||||
m_buffer.resize(length * sizeof(sample_t));
|
||||
memset(m_buffer.getBuffer(), 0, m_buffer.getSize());
|
||||
}
|
||||
|
||||
buffer = m_buffer.getBuffer();
|
||||
m_position += length;
|
||||
}
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* $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_SILENCEREADER
|
||||
#define AUD_SILENCEREADER
|
||||
|
||||
#include "AUD_IReader.h"
|
||||
#include "AUD_Buffer.h"
|
||||
|
||||
/**
|
||||
* This class is used for sine tone playback.
|
||||
* The output format is in the 16 bit format and stereo, the sample rate can be
|
||||
* specified.
|
||||
* As the two channels both play the same the output could also be mono, but
|
||||
* in most cases this will result in having to resample for output, so stereo
|
||||
* sound is created directly.
|
||||
*/
|
||||
class AUD_SilenceReader : public AUD_IReader
|
||||
{
|
||||
private:
|
||||
/**
|
||||
* The current position in samples.
|
||||
*/
|
||||
int m_position;
|
||||
|
||||
/**
|
||||
* The playback buffer.
|
||||
*/
|
||||
AUD_Buffer m_buffer;
|
||||
|
||||
// hide copy constructor and operator=
|
||||
AUD_SilenceReader(const AUD_SilenceReader&);
|
||||
AUD_SilenceReader& operator=(const AUD_SilenceReader&);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Creates a new reader.
|
||||
*/
|
||||
AUD_SilenceReader();
|
||||
|
||||
virtual bool isSeekable() const;
|
||||
virtual void seek(int position);
|
||||
virtual int getLength() const;
|
||||
virtual int getPosition() const;
|
||||
virtual AUD_Specs getSpecs() const;
|
||||
virtual void read(int & length, sample_t* & buffer);
|
||||
};
|
||||
|
||||
#endif //AUD_SILENCEREADER
|
|
@ -45,6 +45,12 @@ struct AUD_SoftwareHandle : AUD_Handle
|
|||
|
||||
/// 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;
|
||||
|
@ -151,6 +157,9 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
|||
// in case the end of the sound is reached
|
||||
if(pos < length)
|
||||
{
|
||||
if(sound->stop)
|
||||
sound->stop(sound->stop_data);
|
||||
|
||||
if(sound->keep)
|
||||
pause(sound);
|
||||
else
|
||||
|
@ -488,3 +497,17 @@ bool AUD_SoftwareDevice::setLoopCount(AUD_Handle* handle, int 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;
|
||||
}
|
||||
|
|
|
@ -132,6 +132,7 @@ public:
|
|||
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
|
||||
|
|
|
@ -438,6 +438,10 @@ 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)
|
||||
AUD_seek(scene->sound_scrub_handle, 0);
|
||||
else
|
||||
scene->sound_scrub_handle = AUD_pauseAfter(scene->sound_scene_handle, 1 / FPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -797,6 +797,7 @@ typedef struct Scene {
|
|||
|
||||
void *sound_scene;
|
||||
void *sound_scene_handle;
|
||||
void *sound_scrub_handle;
|
||||
|
||||
void *fps_info; /* (runtime) info/cache used for presenting playback framerate info to the user */
|
||||
|
||||
|
|
|
@ -107,14 +107,12 @@ public:
|
|||
static int pyattr_set_audposition(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
static int pyattr_set_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value);
|
||||
|
||||
static PyObject* pyattr_get_3d_property(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_audposition(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_gain(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_pitch(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_rollOffFactor(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
static PyObject* pyattr_get_type(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef);
|
||||
|
||||
#endif // DISABLE_PYTHON
|
||||
|
|
Loading…
Reference in New Issue