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:
2013-08-14 21:21:00 +00:00
parent 9e42f76bab
commit c8f75fb5b1
8 changed files with 96 additions and 68 deletions

View File

@@ -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();

View File

@@ -96,6 +96,8 @@ private:
/// Own device.
AUD_OpenALDevice* m_device;
bool pause(bool keep);
public:
/**

View File

@@ -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);

View File

@@ -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;

View File

@@ -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();
}
}

View File

@@ -139,6 +139,8 @@ protected:
/// Own device.
AUD_SoftwareDevice* m_device;
bool pause(bool keep);
public:
/**

View File

@@ -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).

View File

@@ -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&)
{