/////////////////////////////////////////////////////////////////////////////
-// 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
#endif
-#if wxUSE_WAVE && wxUSE_LIBSDL
+#if wxUSE_SOUND && wxUSE_LIBSDL
#include <SDL.h>
public:
DECLARE_DYNAMIC_CLASS(wxSoundBackendSDLNotification)
wxSoundBackendSDLNotification();
- wxEvent *Clone() const { return new wxSoundBackendSDLNotification(*this); }
+ wxEvent *Clone() const { return new wxSoundBackendSDLNotification(*this); }
};
typedef void (wxEvtHandler::*wxSoundBackendSDLNotificationFunction)
DECLARE_EVENT_TABLE_ENTRY(wxEVT_SOUND_BACKEND_SDL_NOTIFICATION, \
-1, \
-1, \
- (wxObjectEventFunction) \
- (wxSoundBackendSDLNotificationFunction)& func, \
+ (wxObjectEventFunction) wxStaticCastEvent( wxSoundBackendSDLNotificationFunction, & func ), \
(wxObject *) NULL ),
IMPLEMENT_DYNAMIC_CLASS(wxSoundBackendSDLNotification, wxEvtHandler)
class wxSoundBackendSDL : public wxSoundBackend
{
public:
- wxSoundBackendSDL()
+ wxSoundBackendSDL()
: m_initialized(false), m_playing(false), m_audioOpen(false),
m_data(NULL), m_evtHandler(NULL) {}
virtual ~wxSoundBackendSDL();
-
+
wxString GetName() const { return _T("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:
{
wxLogTrace(_T("sound"),
_T("received playback status change notification"));
- m_backend->Stop();
+ m_backend->FinishedPlayback();
}
wxSoundBackendSDL *m_backend;
}
}
+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(_T("sound"), _T("opening SDL audio..."));
if (SDL_OpenAudio(&m_spec, NULL) >= 0)
{
#if wxUSE_LOG_DEBUG
char driver[256];
- SDL_AudioDriverName(driver, 256);
+ SDL_AudioDriverName(driver, 256);
wxLogTrace(_T("sound"), _T("opened audio, driver '%s'"),
wxString(driver, wxConvLocal).c_str());
#endif
}
}
-bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags)
+bool wxSoundBackendSDL::Play(wxSoundData *data, unsigned flags,
+ volatile wxSoundPlaybackStatus *WXUNUSED(status))
{
+ Stop();
+
int format;
if (data->m_bitsPerSample == 8)
format = AUDIO_U8;
format = AUDIO_S16LSB;
else
return false;
-
- SDL_LockAudio();
bool needsOpen = true;
if (m_audioOpen)
CloseAudio();
}
}
-
- Stop();
-
+
if (needsOpen)
{
m_spec.format = format;
m_spec.freq = data->m_samplingRate;
m_spec.channels = data->m_channels;
if (!OpenAudio())
- {
- SDL_UnlockAudio();
return false;
- }
}
+ SDL_LockAudio();
+ wxLogTrace(_T("sound"), _T("playing new sound"));
m_playing = true;
m_pos = 0;
m_loop = (flags & wxSOUND_LOOP);
m_data = data;
data->IncRef();
+ SDL_UnlockAudio();
SDL_PauseAudio(0);
- SDL_UnlockAudio();
// 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)
+ while (m_playing && m_data == data)
{
#if wxUSE_THREADS
// give the playback thread a chance to add event to pending
if (wxThread::IsMain())
wxMutexGuiLeave();
#endif
- wxUsleep(10);
+ wxMilliSleep(10);
#if wxUSE_THREADS
if (wxThread::IsMain())
wxMutexGuiEnter();
{
SDL_LockAudio();
SDL_PauseAudio(1);
+ m_playing = false;
if (m_data)
{
m_data->DecRef();
return new wxSoundBackendSDL();
}
-#endif // wxUSE_WAVE && wxUSE_LIBSDL
+#endif // wxUSE_SOUND && wxUSE_LIBSDL