FS#104 - Fix crash when destroying a SoundBuffer used by a Sound
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1370 4e206d99-4929-0410-ac5d-dfc041789085
This commit is contained in:
parent
6341b569db
commit
362f374732
@ -288,6 +288,15 @@ public :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
Sound& operator =(const Sound& Other);
|
Sound& operator =(const Sound& Other);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Reset the internal buffer
|
||||||
|
///
|
||||||
|
/// This function is for internal use only, you don't have
|
||||||
|
/// to use it.
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void ResetBuffer();
|
||||||
|
|
||||||
private :
|
private :
|
||||||
|
|
||||||
friend class SoundStream;
|
friend class SoundStream;
|
||||||
|
@ -32,10 +32,13 @@
|
|||||||
#include <SFML/Audio/AudioResource.hpp>
|
#include <SFML/Audio/AudioResource.hpp>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
|
||||||
namespace sf
|
namespace sf
|
||||||
{
|
{
|
||||||
|
class Sound;
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// SoundBuffer is the low-level for loading and manipulating
|
/// SoundBuffer is the low-level for loading and manipulating
|
||||||
/// sound buffers
|
/// sound buffers
|
||||||
@ -174,12 +177,34 @@ private :
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
bool Update(unsigned int ChannelsCount, unsigned int SampleRate);
|
bool Update(unsigned int ChannelsCount, unsigned int SampleRate);
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Add a sound to the list of sounds that use this buffer
|
||||||
|
///
|
||||||
|
/// \param Instance : Sound object to attach
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void AttachSound(Sound* Instance) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Remove a sound from the list of sounds that use this buffer
|
||||||
|
///
|
||||||
|
/// \param Instance : Sound object to detach
|
||||||
|
///
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void DetachSound(Sound* Instance) const;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Types
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
typedef std::set<Sound*> SoundList; ///< Set of unique sound instances
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
// Member data
|
// Member data
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
unsigned int myBuffer; ///< OpenAL buffer identifier
|
unsigned int myBuffer; ///< OpenAL buffer identifier
|
||||||
std::vector<Int16> mySamples; ///< Samples buffer
|
std::vector<Int16> mySamples; ///< Samples buffer
|
||||||
float myDuration; ///< Sound duration, in seconds
|
float myDuration; ///< Sound duration, in seconds
|
||||||
|
mutable SoundList mySounds; ///< List of sounds that are using this buffer
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -90,6 +90,7 @@ Sound::~Sound()
|
|||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
ALCheck(alSourcei(mySource, AL_BUFFER, 0));
|
ALCheck(alSourcei(mySource, AL_BUFFER, 0));
|
||||||
|
myBuffer->DetachSound(this);
|
||||||
}
|
}
|
||||||
ALCheck(alDeleteSources(1, &mySource));
|
ALCheck(alDeleteSources(1, &mySource));
|
||||||
}
|
}
|
||||||
@ -129,7 +130,8 @@ void Sound::Stop()
|
|||||||
void Sound::SetBuffer(const SoundBuffer& Buffer)
|
void Sound::SetBuffer(const SoundBuffer& Buffer)
|
||||||
{
|
{
|
||||||
myBuffer = &Buffer;
|
myBuffer = &Buffer;
|
||||||
ALCheck(alSourcei(mySource, AL_BUFFER, myBuffer ? myBuffer->myBuffer : 0));
|
myBuffer->AttachSound(this);
|
||||||
|
ALCheck(alSourcei(mySource, AL_BUFFER, myBuffer->myBuffer));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -360,4 +362,18 @@ Sound& Sound::operator =(const Sound& Other)
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Reset the internal buffer
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void Sound::ResetBuffer()
|
||||||
|
{
|
||||||
|
// First stop the sound in case it is playing
|
||||||
|
Stop();
|
||||||
|
|
||||||
|
// Detach the buffer
|
||||||
|
ALCheck(alSourcei(mySource, AL_BUFFER, 0));
|
||||||
|
myBuffer = 0;
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
#include <SFML/Audio/SoundBuffer.hpp>
|
#include <SFML/Audio/SoundBuffer.hpp>
|
||||||
#include <SFML/Audio/SoundFile.hpp>
|
#include <SFML/Audio/SoundFile.hpp>
|
||||||
|
#include <SFML/Audio/Sound.hpp>
|
||||||
#include <SFML/Audio/AudioDevice.hpp>
|
#include <SFML/Audio/AudioDevice.hpp>
|
||||||
#include <SFML/Audio/OpenAL.hpp>
|
#include <SFML/Audio/OpenAL.hpp>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
@ -55,7 +56,8 @@ AudioResource (Copy),
|
|||||||
Resource<SoundBuffer>(Copy),
|
Resource<SoundBuffer>(Copy),
|
||||||
myBuffer (0),
|
myBuffer (0),
|
||||||
mySamples (Copy.mySamples),
|
mySamples (Copy.mySamples),
|
||||||
myDuration (Copy.myDuration)
|
myDuration (Copy.myDuration),
|
||||||
|
mySounds () // don't copy the attached sounds
|
||||||
{
|
{
|
||||||
// Create the buffer
|
// Create the buffer
|
||||||
ALCheck(alGenBuffers(1, &myBuffer));
|
ALCheck(alGenBuffers(1, &myBuffer));
|
||||||
@ -70,6 +72,11 @@ myDuration (Copy.myDuration)
|
|||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
SoundBuffer::~SoundBuffer()
|
SoundBuffer::~SoundBuffer()
|
||||||
{
|
{
|
||||||
|
// First detach the buffer from the sounds that use it (to avoid OpenAL errors)
|
||||||
|
for (SoundList::const_iterator it = mySounds.begin(); it != mySounds.end(); ++it)
|
||||||
|
(*it)->ResetBuffer();
|
||||||
|
|
||||||
|
// Destroy the buffer
|
||||||
if (myBuffer)
|
if (myBuffer)
|
||||||
ALCheck(alDeleteBuffers(1, &myBuffer));
|
ALCheck(alDeleteBuffers(1, &myBuffer));
|
||||||
}
|
}
|
||||||
@ -268,9 +275,10 @@ SoundBuffer& SoundBuffer::operator =(const SoundBuffer& Other)
|
|||||||
{
|
{
|
||||||
SoundBuffer Temp(Other);
|
SoundBuffer Temp(Other);
|
||||||
|
|
||||||
mySamples.swap(Temp.mySamples);
|
std::swap(mySamples, Temp.mySamples);
|
||||||
std::swap(myBuffer, Temp.myBuffer);
|
std::swap(myBuffer, Temp.myBuffer);
|
||||||
std::swap(myDuration, Temp.myDuration);
|
std::swap(myDuration, Temp.myDuration);
|
||||||
|
std::swap(mySounds, Temp.mySounds); // swap sounds too, so that they are detached when Temp is destroyed
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -305,4 +313,22 @@ bool SoundBuffer::Update(unsigned int ChannelsCount, unsigned int SampleRate)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Add a sound to the list of sounds that use this buffer
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void SoundBuffer::AttachSound(Sound* Instance) const
|
||||||
|
{
|
||||||
|
mySounds.insert(Instance);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
/// Remove a sound from the list of sounds that use this buffer
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
void SoundBuffer::DetachSound(Sound* Instance) const
|
||||||
|
{
|
||||||
|
mySounds.erase(Instance);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace sf
|
} // namespace sf
|
||||||
|
Loading…
Reference in New Issue
Block a user