Adding a new state for sound handles in audaspace: stopped.
Now sounds that stopped playing but are still kept in the device can be differentiated from paused sounds with this state. This should also fix the performance issues mentioned in [#36466] End of SequencerEntrys not set correctly. Please test if sound pausing, resuming and stopping works fine in the BGE and sequencer, my tests all worked fine, but there might be a use case that needs some fixing.
This commit is contained in:
@@ -67,6 +67,35 @@ static const char* queue_error = "AUD_OpenALDevice: Buffer couldn't be "
|
||||
static const char* bufferdata_error = "AUD_OpenALDevice: Buffer couldn't be "
|
||||
"filled with data.";
|
||||
|
||||
bool AUD_OpenALDevice::AUD_OpenALHandle::pause(bool keep)
|
||||
{
|
||||
if(m_status)
|
||||
{
|
||||
AUD_MutexLock lock(*m_device);
|
||||
|
||||
if(m_status == AUD_STATUS_PLAYING)
|
||||
{
|
||||
for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
|
||||
{
|
||||
if(it->get() == this)
|
||||
{
|
||||
boost::shared_ptr<AUD_OpenALHandle> This = *it;
|
||||
|
||||
m_device->m_playingSounds.erase(it);
|
||||
m_device->m_pausedSounds.push_back(This);
|
||||
|
||||
alSourcePause(m_source);
|
||||
|
||||
m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;}
|
||||
|
||||
AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, ALenum format, boost::shared_ptr<AUD_IReader> reader, bool keep) :
|
||||
m_isBuffered(false), m_reader(reader), m_keep(keep), m_format(format), m_current(0),
|
||||
m_eos(false), m_loopcount(0), m_stop(NULL), m_stop_data(NULL), m_status(AUD_STATUS_PLAYING),
|
||||
@@ -124,32 +153,7 @@ AUD_OpenALDevice::AUD_OpenALHandle::AUD_OpenALHandle(AUD_OpenALDevice* device, A
|
||||
|
||||
bool AUD_OpenALDevice::AUD_OpenALHandle::pause()
|
||||
{
|
||||
if(m_status)
|
||||
{
|
||||
AUD_MutexLock lock(*m_device);
|
||||
|
||||
if(m_status == AUD_STATUS_PLAYING)
|
||||
{
|
||||
for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
|
||||
{
|
||||
if(it->get() == this)
|
||||
{
|
||||
boost::shared_ptr<AUD_OpenALHandle> This = *it;
|
||||
|
||||
m_device->m_playingSounds.erase(it);
|
||||
m_device->m_pausedSounds.push_back(This);
|
||||
|
||||
alSourcePause(m_source);
|
||||
|
||||
m_status = AUD_STATUS_PAUSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return pause(false);
|
||||
}
|
||||
|
||||
bool AUD_OpenALDevice::AUD_OpenALHandle::resume()
|
||||
@@ -302,6 +306,9 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::seek(float position)
|
||||
}
|
||||
}
|
||||
|
||||
if(m_status == AUD_STATUS_STOPPED)
|
||||
m_status = AUD_STATUS_PAUSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -409,7 +416,12 @@ bool AUD_OpenALDevice::AUD_OpenALHandle::setLoopCount(int count)
|
||||
{
|
||||
if(!m_status)
|
||||
return false;
|
||||
|
||||
if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
|
||||
m_status = AUD_STATUS_PAUSED;
|
||||
|
||||
m_loopcount = count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -987,7 +999,7 @@ void AUD_OpenALDevice::updateStreams()
|
||||
}
|
||||
|
||||
for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
|
||||
(*it)->pause();
|
||||
(*it)->pause(true);
|
||||
|
||||
for(it = stopSounds.begin(); it != stopSounds.end(); it++)
|
||||
(*it)->stop();
|
||||
|
||||
@@ -96,6 +96,8 @@ private:
|
||||
/// Own device.
|
||||
AUD_OpenALDevice* m_device;
|
||||
|
||||
bool pause(bool keep);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
@@ -2908,6 +2908,7 @@ PyInit_aud(void)
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_INVALID);
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PAUSED);
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_PLAYING);
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_STATUS_STOPPED);
|
||||
// distance model constants
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT);
|
||||
PY_MODULE_ADD_CONSTANT(m, AUD_DISTANCE_MODEL_EXPONENT_CLAMPED);
|
||||
|
||||
@@ -113,6 +113,8 @@ public:
|
||||
*. invalid
|
||||
* - AUD_STATUS_PLAYING if the sound is currently played back.
|
||||
* - AUD_STATUS_PAUSED if the sound is currently paused.
|
||||
* - AUD_STATUS_STOPPED if the sound finished playing and is still
|
||||
* kept in the device.
|
||||
* \see AUD_Status
|
||||
*/
|
||||
virtual AUD_Status getStatus()=0;
|
||||
|
||||
@@ -57,6 +57,37 @@ typedef enum
|
||||
/********************** AUD_SoftwareHandle Handle Code ************************/
|
||||
/******************************************************************************/
|
||||
|
||||
bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause(bool keep)
|
||||
{
|
||||
if(m_status)
|
||||
{
|
||||
AUD_MutexLock lock(*m_device);
|
||||
|
||||
if(m_status == AUD_STATUS_PLAYING)
|
||||
{
|
||||
for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
|
||||
{
|
||||
if(it->get() == this)
|
||||
{
|
||||
boost::shared_ptr<AUD_SoftwareHandle> This = *it;
|
||||
|
||||
m_device->m_playingSounds.erase(it);
|
||||
m_device->m_pausedSounds.push_back(This);
|
||||
|
||||
if(m_device->m_playingSounds.empty())
|
||||
m_device->playing(m_device->m_playback = false);
|
||||
|
||||
m_status = keep ? AUD_STATUS_STOPPED : AUD_STATUS_PAUSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
AUD_SoftwareDevice::AUD_SoftwareHandle::AUD_SoftwareHandle(AUD_SoftwareDevice* device, boost::shared_ptr<AUD_IReader> reader, boost::shared_ptr<AUD_PitchReader> pitch, boost::shared_ptr<AUD_ResampleReader> resampler, boost::shared_ptr<AUD_ChannelMapperReader> mapper, bool keep) :
|
||||
m_reader(reader), m_pitch(pitch), m_resampler(resampler), m_mapper(mapper), m_keep(keep), m_user_pitch(1.0f), m_user_volume(1.0f), m_user_pan(0.0f), m_volume(1.0f), m_loopcount(0),
|
||||
m_relative(true), m_volume_max(1.0f), m_volume_min(0), m_distance_max(std::numeric_limits<float>::max()),
|
||||
@@ -225,33 +256,7 @@ void AUD_SoftwareDevice::AUD_SoftwareHandle::setSpecs(AUD_Specs specs)
|
||||
|
||||
bool AUD_SoftwareDevice::AUD_SoftwareHandle::pause()
|
||||
{
|
||||
if(m_status)
|
||||
{
|
||||
AUD_MutexLock lock(*m_device);
|
||||
|
||||
if(m_status == AUD_STATUS_PLAYING)
|
||||
{
|
||||
for(AUD_HandleIterator it = m_device->m_playingSounds.begin(); it != m_device->m_playingSounds.end(); it++)
|
||||
{
|
||||
if(it->get() == this)
|
||||
{
|
||||
boost::shared_ptr<AUD_SoftwareHandle> This = *it;
|
||||
|
||||
m_device->m_playingSounds.erase(it);
|
||||
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;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return pause(false);
|
||||
}
|
||||
|
||||
bool AUD_SoftwareDevice::AUD_SoftwareHandle::resume()
|
||||
@@ -360,6 +365,9 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::seek(float position)
|
||||
|
||||
m_reader->seek((int)(position * m_reader->getSpecs().rate));
|
||||
|
||||
if(m_status == AUD_STATUS_STOPPED)
|
||||
m_status = AUD_STATUS_PAUSED;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -429,7 +437,12 @@ bool AUD_SoftwareDevice::AUD_SoftwareHandle::setLoopCount(int count)
|
||||
{
|
||||
if(!m_status)
|
||||
return false;
|
||||
|
||||
if(m_status == AUD_STATUS_STOPPED && (count > m_loopcount || count < 0))
|
||||
m_status = AUD_STATUS_PAUSED;
|
||||
|
||||
m_loopcount = count;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -793,19 +806,14 @@ void AUD_SoftwareDevice::mix(data_t* buffer, int length)
|
||||
m_mixer->read(buffer, m_volume);
|
||||
|
||||
// cleanup
|
||||
while(!stopSounds.empty())
|
||||
{
|
||||
sound = stopSounds.front();
|
||||
stopSounds.pop_front();
|
||||
sound->stop();
|
||||
}
|
||||
for(it = pauseSounds.begin(); it != pauseSounds.end(); it++)
|
||||
(*it)->pause(true);
|
||||
|
||||
while(!pauseSounds.empty())
|
||||
{
|
||||
sound = pauseSounds.front();
|
||||
pauseSounds.pop_front();
|
||||
sound->pause();
|
||||
}
|
||||
for(it = stopSounds.begin(); it != stopSounds.end(); it++)
|
||||
(*it)->stop();
|
||||
|
||||
pauseSounds.clear();
|
||||
stopSounds.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -139,6 +139,8 @@ protected:
|
||||
/// Own device.
|
||||
AUD_SoftwareDevice* m_device;
|
||||
|
||||
bool pause(bool keep);
|
||||
|
||||
public:
|
||||
|
||||
/**
|
||||
|
||||
@@ -125,7 +125,8 @@ typedef enum
|
||||
{
|
||||
AUD_STATUS_INVALID = 0, /// Invalid handle. Maybe due to stopping.
|
||||
AUD_STATUS_PLAYING, /// Sound is playing.
|
||||
AUD_STATUS_PAUSED /// Sound is being paused.
|
||||
AUD_STATUS_PAUSED, /// Sound is being paused.
|
||||
AUD_STATUS_STOPPED /// Sound is stopped but kept in the device.
|
||||
} AUD_Status;
|
||||
|
||||
/// Error codes for exceptions (C++ library) or for return values (C API).
|
||||
|
||||
@@ -109,7 +109,7 @@ void KX_SoundActuator::play()
|
||||
|
||||
try
|
||||
{
|
||||
m_handle = AUD_getDevice()->play(sound, 0);
|
||||
m_handle = AUD_getDevice()->play(sound);
|
||||
}
|
||||
catch(AUD_Exception&)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user