diff --git a/include/wx/osx/sound.h b/include/wx/osx/sound.h index 10a781caf9..7b0329bdec 100644 --- a/include/wx/osx/sound.h +++ b/include/wx/osx/sound.h @@ -30,6 +30,9 @@ public : virtual void Stop(); // can be called by a timer for repeated tasks during playback virtual void SoundTask(); + // mark this to be deleted + virtual void MarkForDeletion(); + virtual bool IsMarkedForDeletion() const { return m_markedForDeletion; } // does the true work of stopping and cleaning up virtual void DoStop() = 0; @@ -38,6 +41,7 @@ protected : unsigned int m_flags; wxSoundTimer* m_pTimer; + bool m_markedForDeletion; } ; class WXDLLIMPEXP_ADV wxSound : public wxSoundBase diff --git a/src/osx/carbon/sound.cpp b/src/osx/carbon/sound.cpp index 6de5ccd27e..39bb269856 100644 --- a/src/osx/carbon/sound.cpp +++ b/src/osx/carbon/sound.cpp @@ -100,6 +100,9 @@ void wxOSXSoundManagerSoundData::DoStop() m_pSndChannel = NULL; wxSound::SoundStopped(this); } + + if (IsMarkedForDeletion()) + delete this; } bool wxOSXSoundManagerSoundData::Play(unsigned flags) diff --git a/src/osx/core/sound.cpp b/src/osx/core/sound.cpp index fd9d6d4b76..8d6c883af6 100644 --- a/src/osx/core/sound.cpp +++ b/src/osx/core/sound.cpp @@ -68,6 +68,9 @@ wxOSXAudioToolboxSoundData::CompletionCallback(SystemSoundID WXUNUSED(mySSID), wxOSXAudioToolboxSoundData* data = (wxOSXAudioToolboxSoundData*) soundRef; data->SoundCompleted(); + + if (data->IsMarkedForDeletion()) + delete data; } void wxOSXAudioToolboxSoundData::SoundCompleted() diff --git a/src/osx/sound_osx.cpp b/src/osx/sound_osx.cpp index 141552e29a..1155660e46 100644 --- a/src/osx/sound_osx.cpp +++ b/src/osx/sound_osx.cpp @@ -39,12 +39,14 @@ public: virtual ~wxSoundTimer() { Stop(); - m_sound->DoStop(); + if (m_sound) + m_sound->DoStop(); } void Notify() { - m_sound->SoundTask(); + if (m_sound) + m_sound->SoundTask(); } protected: @@ -56,12 +58,18 @@ wxVector s_soundsPlaying; wxSoundData::wxSoundData() { m_pTimer = NULL; + m_markedForDeletion = false; } wxSoundData::~wxSoundData() { } +void wxSoundData::MarkForDeletion() +{ + m_markedForDeletion = true; +} + void wxSoundData::Stop() { DoStop(); @@ -105,7 +113,24 @@ wxSound::wxSound(int size, const wxByte* data) wxSound::~wxSound() { - delete m_data; + // if the sound is in a playing state, just mark it to be deleted and + // delete it after it plays. Otherwise, async sounds created on the stack + // may never get the chance to play. + bool isPlaying = false; + for ( wxVector::reverse_iterator s = s_soundsPlaying.rbegin(); + s != s_soundsPlaying.rend(); ++s ) + { + if (*s == m_data) + { + isPlaying = true; + break; + } + } + + if (isPlaying) + m_data->MarkForDeletion(); + else + delete m_data; } void wxSound::Init()