X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/64f4500a4a6905623685e67efc65b0d856aff393..c200f9a3b7003a6ef27f079672b7d165b04a59b7:/src/unix/sound_sdl.cpp diff --git a/src/unix/sound_sdl.cpp b/src/unix/sound_sdl.cpp index eb1e563766..3962e6dc72 100644 --- a/src/unix/sound_sdl.cpp +++ b/src/unix/sound_sdl.cpp @@ -1,24 +1,22 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: sound_sdl.cpp +// Name: src/unix/sound_sdl.cpp // Purpose: wxSound backend using SDL // Author: Vaclav Slavik // Modified by: // Created: 2004/01/31 // RCS-ID: $Id$ -// Copyright: (c) 2004, Vaclav Slavik -// Licence: wxWindows licence +// Copyright: (c) 2004, Open Source Applications Foundation +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// // for compilers that support precompilation, includes "wx.h". #include "wx/wxprec.h" -#include "wx/setup.h" - #if defined(__BORLANDC__) -#pragma hdrstop + #pragma hdrstop #endif -#if wxUSE_WAVE && wxUSE_LIBSDL +#if wxUSE_SOUND && wxUSE_LIBSDL #include @@ -27,10 +25,10 @@ #include "wx/intl.h" #include "wx/log.h" #include "wx/utils.h" + #include "wx/module.h" #endif #include "wx/thread.h" -#include "wx/module.h" #include "wx/sound.h" // ---------------------------------------------------------------------------- @@ -42,26 +40,23 @@ class wxSoundBackendSDLNotification : public wxEvent public: DECLARE_DYNAMIC_CLASS(wxSoundBackendSDLNotification) wxSoundBackendSDLNotification(); - wxEvent *Clone() const { return new wxSoundBackendSDLNotification(*this); } + wxEvent *Clone() const { return new wxSoundBackendSDLNotification(*this); } }; typedef void (wxEvtHandler::*wxSoundBackendSDLNotificationFunction) (wxSoundBackendSDLNotification&); -BEGIN_DECLARE_EVENT_TYPES() - DECLARE_LOCAL_EVENT_TYPE(wxEVT_SOUND_BACKEND_SDL_NOTIFICATION, -1) -END_DECLARE_EVENT_TYPES() +wxDECLARE_EVENT(wxEVT_SOUND_BACKEND_SDL_NOTIFICATION, wxSoundBackendSDLNotification); #define EVT_SOUND_BACKEND_SDL_NOTIFICATON(func) \ DECLARE_EVENT_TABLE_ENTRY(wxEVT_SOUND_BACKEND_SDL_NOTIFICATION, \ -1, \ -1, \ - (wxObjectEventFunction) \ - (wxSoundBackendSDLNotificationFunction)& func, \ - (wxObject *) NULL ), + wxEVENT_HANDLER_CAST( wxSoundBackendSDLNotificationFunction, func ), \ + NULL ), IMPLEMENT_DYNAMIC_CLASS(wxSoundBackendSDLNotification, wxEvtHandler) -DEFINE_EVENT_TYPE(wxEVT_SOUND_BACKEND_SDL_NOTIFICATION) +wxDEFINE_EVENT( wxEVT_SOUND_BACKEND_SDL_NOTIFICATION, wxSoundBackendSDLNotification ); wxSoundBackendSDLNotification::wxSoundBackendSDLNotification() { @@ -73,22 +68,28 @@ class wxSoundBackendSDLEvtHandler; class wxSoundBackendSDL : public wxSoundBackend { public: - wxSoundBackendSDL() + wxSoundBackendSDL() : m_initialized(false), m_playing(false), m_audioOpen(false), - m_evtHandler(NULL) {} + m_data(NULL), m_evtHandler(NULL) {} virtual ~wxSoundBackendSDL(); - - wxString GetName() const { return _T("Simple DirectMedia Layer"); } + + wxString GetName() const { return wxT("Simple DirectMedia Layer"); } int GetPriority() const { return 9; } bool IsAvailable() const; bool HasNativeAsyncPlayback() const { return true; } - bool Play(wxSoundData *data, unsigned flags); + bool Play(wxSoundData *data, unsigned flags, + volatile wxSoundPlaybackStatus *status); void FillAudioBuffer(Uint8 *stream, int len); + void FinishedPlayback(); + void Stop(); bool IsPlaying() const { return m_playing; } - + private: + bool OpenAudio(); + void CloseAudio(); + bool m_initialized; bool m_playing, m_audioOpen; // playback information: @@ -108,9 +109,9 @@ public: private: void OnNotify(wxSoundBackendSDLNotification& WXUNUSED(event)) { - wxLogTrace(_T("sound"), - _T("received playback status change notification")); - m_backend->Stop(); + wxLogTrace(wxT("sound"), + wxT("received playback status change notification")); + m_backend->FinishedPlayback(); } wxSoundBackendSDL *m_backend; @@ -124,6 +125,7 @@ END_EVENT_TABLE() wxSoundBackendSDL::~wxSoundBackendSDL() { Stop(); + CloseAudio(); delete m_evtHandler; } @@ -137,7 +139,7 @@ bool wxSoundBackendSDL::IsAvailable() const return false; } wxConstCast(this, wxSoundBackendSDL)->m_initialized = true; - wxLogTrace(_T("sound"), _T("initialized SDL audio subsystem")); + wxLogTrace(wxT("sound"), wxT("initialized SDL audio subsystem")); return true; } @@ -187,8 +189,62 @@ void wxSoundBackendSDL::FillAudioBuffer(Uint8 *stream, int len) } } -bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags) +void wxSoundBackendSDL::FinishedPlayback() +{ + if (!m_playing) + Stop(); +} + +bool wxSoundBackendSDL::OpenAudio() +{ + if (!m_audioOpen) + { + if (!m_evtHandler) + m_evtHandler = new wxSoundBackendSDLEvtHandler(this); + + m_spec.silence = 0; + m_spec.samples = 4096; + m_spec.size = 0; + m_spec.callback = wx_sdl_audio_callback; + m_spec.userdata = (void*)this; + + wxLogTrace(wxT("sound"), wxT("opening SDL audio...")); + if (SDL_OpenAudio(&m_spec, NULL) >= 0) + { +#if wxUSE_LOG_DEBUG + char driver[256]; + SDL_AudioDriverName(driver, 256); + wxLogTrace(wxT("sound"), wxT("opened audio, driver '%s'"), + wxString(driver, wxConvLocal).c_str()); +#endif + m_audioOpen = true; + return true; + } + else + { + wxString err(SDL_GetError(), wxConvLocal); + wxLogError(_("Couldn't open audio: %s"), err.c_str()); + return false; + } + } + return true; +} + +void wxSoundBackendSDL::CloseAudio() +{ + if (m_audioOpen) + { + SDL_CloseAudio(); + wxLogTrace(wxT("sound"), wxT("closed audio")); + m_audioOpen = false; + } +} + +bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags, + volatile wxSoundPlaybackStatus *WXUNUSED(status)) { + Stop(); + int format; if (data->m_bitsPerSample == 8) format = AUDIO_U8; @@ -196,18 +252,10 @@ bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags) format = AUDIO_S16LSB; else return false; - - SDL_LockAudio(); - - if (!m_evtHandler) - m_evtHandler = new wxSoundBackendSDLEvtHandler(this); - - data->IncRef(); bool needsOpen = true; if (m_audioOpen) { - wxLogTrace(_T("sound"), _T("another sound playing, will be stopped")); if (format == m_spec.format && m_spec.freq == (int)data->m_samplingRate && m_spec.channels == data->m_channels) @@ -216,62 +264,35 @@ bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags) } else { - SDL_CloseAudio(); - m_audioOpen = false; - wxLogTrace(_T("sound"), _T("closed audio")); + CloseAudio(); } - m_data->DecRef(); } - - m_playing = true; - m_data = data; - m_pos = 0; - m_loop = (flags & wxSOUND_LOOP); - wxLogTrace(_T("sound"), _T("prepared sound for playback")); - - bool status = true; if (needsOpen) { m_spec.format = format; m_spec.freq = data->m_samplingRate; m_spec.channels = data->m_channels; - m_spec.silence = 0; - m_spec.samples = 4096; - m_spec.size = 0; - m_spec.callback = wx_sdl_audio_callback; - m_spec.userdata = (void*)this; - - wxLogTrace(_T("sound"), _T("opening SDL audio...")); - status = (SDL_OpenAudio(&m_spec, NULL) >= 0); - if (status) - { -#if wxUSE_LOG_DEBUG - char driver[256]; - SDL_AudioDriverName(driver, 256); - wxLogTrace(_T("sound"), _T("opened audio, driver '%s'"), - wxString(driver, wxConvLocal).c_str()); -#endif - m_audioOpen = true; - SDL_PauseAudio(0); - } - else - { - wxString err(SDL_GetError(), wxConvLocal); - wxLogError(_("Couldn't open audio: %s"), err.c_str()); - } + if (!OpenAudio()) + return false; } + SDL_LockAudio(); + wxLogTrace(wxT("sound"), wxT("playing new sound")); + m_playing = true; + m_pos = 0; + m_loop = (flags & wxSOUND_LOOP); + m_data = data; + data->IncRef(); SDL_UnlockAudio(); - if (!status) - return false; + SDL_PauseAudio(0); // wait until playback finishes if called in sync mode: if (!(flags & wxSOUND_ASYNC)) { - wxLogTrace(_T("sound"), _T("waiting for sample to finish")); - while (m_playing) + wxLogTrace(wxT("sound"), wxT("waiting for sample to finish")); + while (m_playing && m_data == data) { #if wxUSE_THREADS // give the playback thread a chance to add event to pending @@ -279,13 +300,13 @@ bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags) if (wxThread::IsMain()) wxMutexGuiLeave(); #endif - wxUsleep(10); + wxMilliSleep(10); #if wxUSE_THREADS if (wxThread::IsMain()) wxMutexGuiEnter(); #endif } - wxLogTrace(_T("sound"), _T("sample finished")); + wxLogTrace(wxT("sound"), wxT("sample finished")); } return true; @@ -294,15 +315,13 @@ bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags) void wxSoundBackendSDL::Stop() { SDL_LockAudio(); - - if (m_audioOpen) + SDL_PauseAudio(1); + m_playing = false; + if (m_data) { - SDL_CloseAudio(); - m_audioOpen = false; - wxLogTrace(_T("sound"), _T("closed audio")); m_data->DecRef(); + m_data = NULL; } - SDL_UnlockAudio(); } @@ -311,4 +330,4 @@ extern "C" wxSoundBackend *wxCreateSoundBackendSDL() return new wxSoundBackendSDL(); } -#endif // wxUSE_WAVE && wxUSE_LIBSDL +#endif // wxUSE_SOUND && wxUSE_LIBSDL