]> git.saurik.com Git - wxWidgets.git/blobdiff - src/unix/sound.cpp
Add new wxCommandLinkButton class.
[wxWidgets.git] / src / unix / sound.cpp
index fbd980238369c95ecb1ccf271164dadcb1ca212a..500e8617182a2694fcdf62ac833096034204e19d 100644 (file)
@@ -1,5 +1,5 @@
 /////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////
-// Name:        sound.cpp
+// Name:        src/unix/sound.cpp
 // Purpose:     wxSound
 // Author:      Marcel Rasche, Vaclav Slavik
 // Modified by:
 // Purpose:     wxSound
 // Author:      Marcel Rasche, Vaclav Slavik
 // Modified by:
 // for compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
 // for compilers that support precompilation, includes "wx.h".
 #include "wx/wxprec.h"
 
-#include "wx/setup.h"
-
 #if defined(__BORLANDC__)
 #if defined(__BORLANDC__)
-#pragma hdrstop
+    #pragma hdrstop
 #endif
 
 #if wxUSE_SOUND
 #endif
 
 #if wxUSE_SOUND
     #include "wx/event.h"
     #include "wx/intl.h"
     #include "wx/log.h"
     #include "wx/event.h"
     #include "wx/intl.h"
     #include "wx/log.h"
+    #include "wx/module.h"
 #endif
 
 #include "wx/thread.h"
 #include "wx/file.h"
 #endif
 
 #include "wx/thread.h"
 #include "wx/file.h"
-#include "wx/module.h"
 #include "wx/sound.h"
 #include "wx/dynlib.h"
 
 #include "wx/sound.h"
 #include "wx/dynlib.h"
 
@@ -106,7 +104,7 @@ public:
 class wxSoundBackendOSS : public wxSoundBackend
 {
 public:
 class wxSoundBackendOSS : public wxSoundBackend
 {
 public:
-    wxString GetName() const { return _T("Open Sound System"); }
+    wxString GetName() const { return wxT("Open Sound System"); }
     int GetPriority() const { return 10; }
     bool IsAvailable() const;
     bool HasNativeAsyncPlayback() const { return false; }
     int GetPriority() const { return 10; }
     bool IsAvailable() const;
     bool HasNativeAsyncPlayback() const { return false; }
@@ -154,7 +152,7 @@ bool wxSoundBackendOSS::Play(wxSoundData *data, unsigned flags,
         {
             if (status->m_stopRequested)
             {
         {
             if (status->m_stopRequested)
             {
-                wxLogTrace(_T("sound"), _T("playback stopped"));
+                wxLogTrace(wxT("sound"), wxT("playback stopped"));
                 close(dev);
                 return true;
             }
                 close(dev);
                 return true;
             }
@@ -197,7 +195,7 @@ bool wxSoundBackendOSS::InitDSP(int dev, const wxSoundData *data)
     // Reset the dsp
     if (ioctl(dev, SNDCTL_DSP_RESET, 0) < 0)
     {
     // Reset the dsp
     if (ioctl(dev, SNDCTL_DSP_RESET, 0) < 0)
     {
-        wxLogTrace(_T("sound"), _T("unable to reset dsp"));
+        wxLogTrace(wxT("sound"), wxT("unable to reset dsp"));
         return false;
     }
 
         return false;
     }
 
@@ -206,13 +204,13 @@ bool wxSoundBackendOSS::InitDSP(int dev, const wxSoundData *data)
     tmp = data->m_bitsPerSample;
     if (ioctl(dev, SNDCTL_DSP_SAMPLESIZE, &tmp) < 0)
     {
     tmp = data->m_bitsPerSample;
     if (ioctl(dev, SNDCTL_DSP_SAMPLESIZE, &tmp) < 0)
     {
-        wxLogTrace(_T("sound"), _T("IOCTL failure (SNDCTL_DSP_SAMPLESIZE)"));
+        wxLogTrace(wxT("sound"), wxT("IOCTL failure (SNDCTL_DSP_SAMPLESIZE)"));
         return false;
     }
     if (tmp != data->m_bitsPerSample)
     {
         return false;
     }
     if (tmp != data->m_bitsPerSample)
     {
-        wxLogTrace(_T("sound"),
-                   _T("Unable to set DSP sample size to %d (wants %d)"),
+        wxLogTrace(wxT("sound"),
+                   wxT("Unable to set DSP sample size to %d (wants %d)"),
                    data->m_bitsPerSample, tmp);
         m_needConversion = true;
     }
                    data->m_bitsPerSample, tmp);
         m_needConversion = true;
     }
@@ -221,19 +219,19 @@ bool wxSoundBackendOSS::InitDSP(int dev, const wxSoundData *data)
     tmp = stereo;
     if (ioctl(dev, SNDCTL_DSP_STEREO, &tmp) < 0)
     {
     tmp = stereo;
     if (ioctl(dev, SNDCTL_DSP_STEREO, &tmp) < 0)
     {
-        wxLogTrace(_T("sound"), _T("IOCTL failure (SNDCTL_DSP_STEREO)"));
+        wxLogTrace(wxT("sound"), wxT("IOCTL failure (SNDCTL_DSP_STEREO)"));
         return false;
     }
     if (tmp != stereo)
     {
         return false;
     }
     if (tmp != stereo)
     {
-        wxLogTrace(_T("sound"), _T("Unable to set DSP to %s."), stereo?  _T("stereo"):_T("mono"));
+        wxLogTrace(wxT("sound"), wxT("Unable to set DSP to %s."), stereo?  wxT("stereo"):wxT("mono"));
         m_needConversion = true;
     }
 
     tmp = data->m_samplingRate;
     if (ioctl(dev, SNDCTL_DSP_SPEED, &tmp) < 0)
     {
         m_needConversion = true;
     }
 
     tmp = data->m_samplingRate;
     if (ioctl(dev, SNDCTL_DSP_SPEED, &tmp) < 0)
     {
-        wxLogTrace(_T("sound"), _T("IOCTL failure (SNDCTL_DSP_SPEED)"));
+        wxLogTrace(wxT("sound"), wxT("IOCTL failure (SNDCTL_DSP_SPEED)"));
        return false;
     }
     if (tmp != data->m_samplingRate)
        return false;
     }
     if (tmp != data->m_samplingRate)
@@ -246,8 +244,8 @@ bool wxSoundBackendOSS::InitDSP(int dev, const wxSoundData *data)
         // file rates for something that we can't hear anyways.
         if (data->m_samplingRate - tmp > (tmp * .01) ||
             tmp - data->m_samplingRate > (tmp * .01)) {
         // file rates for something that we can't hear anyways.
         if (data->m_samplingRate - tmp > (tmp * .01) ||
             tmp - data->m_samplingRate > (tmp * .01)) {
-            wxLogTrace(_T("sound"),
-                       _T("Unable to set DSP sampling rate to %d (wants %d)"),
+            wxLogTrace(wxT("sound"),
+                       wxT("Unable to set DSP sampling rate to %d (wants %d)"),
                        data->m_samplingRate, tmp);
             m_needConversion = true;
         }
                        data->m_samplingRate, tmp);
             m_needConversion = true;
         }
@@ -257,7 +255,7 @@ bool wxSoundBackendOSS::InitDSP(int dev, const wxSoundData *data)
     // the sampling rate, etc.
     if (ioctl(dev, SNDCTL_DSP_GETBLKSIZE, &m_DSPblkSize) < 0)
     {
     // the sampling rate, etc.
     if (ioctl(dev, SNDCTL_DSP_GETBLKSIZE, &m_DSPblkSize) < 0)
     {
-        wxLogTrace(_T("sound"), _T("IOCTL failure (SNDCTL_DSP_GETBLKSIZE)"));
+        wxLogTrace(wxT("sound"), wxT("IOCTL failure (SNDCTL_DSP_GETBLKSIZE)"));
         return false;
     }
     return true;
         return false;
     }
     return true;
@@ -298,7 +296,7 @@ class wxSoundSyncOnlyAdaptor : public wxSoundBackend
 public:
     wxSoundSyncOnlyAdaptor(wxSoundBackend *backend)
         : m_backend(backend), m_playing(false) {}
 public:
     wxSoundSyncOnlyAdaptor(wxSoundBackend *backend)
         : m_backend(backend), m_playing(false) {}
-    ~wxSoundSyncOnlyAdaptor()
+    virtual ~wxSoundSyncOnlyAdaptor()
     {
         delete m_backend;
     }
     {
         delete m_backend;
     }
@@ -346,7 +344,7 @@ wxThread::ExitCode wxSoundAsyncPlaybackThread::Entry()
     m_data->DecRef();
     m_adapt->m_playing = false;
     m_adapt->m_mutexRightToPlay.Unlock();
     m_data->DecRef();
     m_adapt->m_playing = false;
     m_adapt->m_mutexRightToPlay.Unlock();
-    wxLogTrace(_T("sound"), _T("terminated async playback thread"));
+    wxLogTrace(wxT("sound"), wxT("terminated async playback thread"));
     return 0;
 }
 #endif
     return 0;
 }
 #endif
@@ -365,7 +363,7 @@ bool wxSoundSyncOnlyAdaptor::Play(wxSoundData *data, unsigned flags,
         wxThread *th = new wxSoundAsyncPlaybackThread(this, data, flags);
         th->Create();
         th->Run();
         wxThread *th = new wxSoundAsyncPlaybackThread(this, data, flags);
         th->Create();
         th->Run();
-        wxLogTrace(_T("sound"), _T("launched async playback thread"));
+        wxLogTrace(wxT("sound"), wxT("launched async playback thread"));
         return true;
 #else
         wxLogError(_("Unable to play sound asynchronously."));
         return true;
 #else
         wxLogError(_("Unable to play sound asynchronously."));
@@ -387,7 +385,7 @@ bool wxSoundSyncOnlyAdaptor::Play(wxSoundData *data, unsigned flags,
 
 void wxSoundSyncOnlyAdaptor::Stop()
 {
 
 void wxSoundSyncOnlyAdaptor::Stop()
 {
-    wxLogTrace(_T("sound"), _T("asking audio to stop"));
+    wxLogTrace(wxT("sound"), wxT("asking audio to stop"));
 
 #if wxUSE_THREADS
     // tell the player thread (if running) to stop playback ASAP:
 
 #if wxUSE_THREADS
     // tell the player thread (if running) to stop playback ASAP:
@@ -399,7 +397,7 @@ void wxSoundSyncOnlyAdaptor::Stop()
     // our request to interrupt playback):
     m_mutexRightToPlay.Lock();
     m_mutexRightToPlay.Unlock();
     // our request to interrupt playback):
     m_mutexRightToPlay.Lock();
     m_mutexRightToPlay.Unlock();
-    wxLogTrace(_T("sound"), _T("audio was stopped"));
+    wxLogTrace(wxT("sound"), wxT("audio was stopped"));
 #endif
 }
 
 #endif
 }
 
@@ -451,7 +449,7 @@ bool wxSound::Create(const wxString& fileName,
                      bool WXUNUSED_UNLESS_DEBUG(isResource))
 {
     wxASSERT_MSG( !isResource,
                      bool WXUNUSED_UNLESS_DEBUG(isResource))
 {
     wxASSERT_MSG( !isResource,
-             _T("Loading sound from resources is only supported on Windows") );
+             wxT("Loading sound from resources is only supported on Windows") );
 
     Free();
 
 
     Free();
 
@@ -469,12 +467,14 @@ bool wxSound::Create(const wxString& fileName,
     wxUint8 *data = new wxUint8[len];
     if ( fileWave.Read(data, len) != lenOrig )
     {
     wxUint8 *data = new wxUint8[len];
     if ( fileWave.Read(data, len) != lenOrig )
     {
+        delete [] data;
         wxLogError(_("Couldn't load sound data from '%s'."), fileName.c_str());
         return false;
     }
 
     if (!LoadWAV(data, len, false))
     {
         wxLogError(_("Couldn't load sound data from '%s'."), fileName.c_str());
         return false;
     }
 
     if (!LoadWAV(data, len, false))
     {
+        delete [] data;
         wxLogError(_("Sound file '%s' is in unsupported format."),
                    fileName.c_str());
         return false;
         wxLogError(_("Sound file '%s' is in unsupported format."),
                    fileName.c_str());
         return false;
@@ -509,12 +509,12 @@ bool wxSound::Create(int size, const wxByte* data)
             ms_backend = wxCreateSoundBackendSDL();
 #else
             wxString dllname;
             ms_backend = wxCreateSoundBackendSDL();
 #else
             wxString dllname;
-            dllname.Printf(_T("%s/%s"),
+            dllname.Printf(wxT("%s/%s"),
                 wxDynamicLibrary::GetPluginsDirectory().c_str(),
                 wxDynamicLibrary::CanonicalizePluginName(
                 wxDynamicLibrary::GetPluginsDirectory().c_str(),
                 wxDynamicLibrary::CanonicalizePluginName(
-                    _T("sound_sdl"), wxDL_PLUGIN_BASE).c_str());
-            wxLogTrace(_T("sound"),
-                       _T("trying to load SDL plugin from '%s'..."),
+                    wxT("sound_sdl"), wxDL_PLUGIN_BASE).c_str());
+            wxLogTrace(wxT("sound"),
+                       wxT("trying to load SDL plugin from '%s'..."),
                        dllname.c_str());
             wxLogNull null;
             ms_backendSDL = new wxDynamicLibrary(dllname, wxDL_NOW);
                        dllname.c_str());
             wxLogNull null;
             ms_backendSDL = new wxDynamicLibrary(dllname, wxDL_NOW);
@@ -557,8 +557,8 @@ bool wxSound::Create(int size, const wxByte* data)
         if (!ms_backend->HasNativeAsyncPlayback())
             ms_backend = new wxSoundSyncOnlyAdaptor(ms_backend);
 
         if (!ms_backend->HasNativeAsyncPlayback())
             ms_backend = new wxSoundSyncOnlyAdaptor(ms_backend);
 
-        wxLogTrace(_T("sound"),
-                   _T("using backend '%s'"), ms_backend->GetName().c_str());
+        wxLogTrace(wxT("sound"),
+                   wxT("using backend '%s'"), ms_backend->GetName().c_str());
     }
 }
 
     }
 }
 
@@ -566,12 +566,11 @@ bool wxSound::Create(int size, const wxByte* data)
 {
     if (ms_backend)
     {
 {
     if (ms_backend)
     {
-        wxLogTrace(_T("sound"), _T("unloading backend"));
+        wxLogTrace(wxT("sound"), wxT("unloading backend"));
 
         Stop();
 
 
         Stop();
 
-        delete ms_backend;
-        ms_backend = NULL;
+        wxDELETE(ms_backend);
 #if wxUSE_LIBSDL && wxUSE_PLUGINS
         delete ms_backendSDL;
 #endif
 #if wxUSE_LIBSDL && wxUSE_PLUGINS
         delete ms_backendSDL;
 #endif
@@ -580,7 +579,7 @@ bool wxSound::Create(int size, const wxByte* data)
 
 bool wxSound::DoPlay(unsigned flags) const
 {
 
 bool wxSound::DoPlay(unsigned flags) const
 {
-    wxCHECK_MSG( IsOk(), false, _T("Attempt to play invalid wave data") );
+    wxCHECK_MSG( IsOk(), false, wxT("Attempt to play invalid wave data") );
 
     EnsureBackend();
     wxSoundPlaybackStatus status;
 
     EnsureBackend();
     wxSoundPlaybackStatus status;
@@ -626,12 +625,30 @@ typedef struct
 
 bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
 {
 
 bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
 {
-    WAVEFORMAT waveformat;
-    wxUint32 ul;
-
-    if (length < 32 + sizeof(WAVEFORMAT))
+    // the simplest wave file header consists of 44 bytes:
+    //
+    //      0   "RIFF"
+    //      4   file size - 8
+    //      8   "WAVE"
+    //
+    //      12  "fmt "
+    //      16  chunk size                  |
+    //      20  format tag                  |
+    //      22  number of channels          |
+    //      24  sample rate                 | WAVEFORMAT
+    //      28  average bytes per second    |
+    //      32  bytes per frame             |
+    //      34  bits per sample             |
+    //
+    //      36  "data"
+    //      40  number of data bytes
+    //      44  (wave signal) data
+    //
+    // so check that we have at least as much
+    if ( length < 44 )
         return false;
 
         return false;
 
+    WAVEFORMAT waveformat;
     memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT));
     waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize);
     waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag);
     memcpy(&waveformat, &data[FMT_INDEX + 4], sizeof(WAVEFORMAT));
     waveformat.uiSize = wxUINT32_SWAP_ON_BE(waveformat.uiSize);
     waveformat.uiFormatTag = wxUINT16_SWAP_ON_BE(waveformat.uiFormatTag);
@@ -641,6 +658,14 @@ bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
     waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign);
     waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample);
 
     waveformat.uiBlockAlign = wxUINT16_SWAP_ON_BE(waveformat.uiBlockAlign);
     waveformat.uiBitsPerSample = wxUINT16_SWAP_ON_BE(waveformat.uiBitsPerSample);
 
+    // get the sound data size
+    wxUint32 ul;
+    memcpy(&ul, &data[FMT_INDEX + waveformat.uiSize + 12], 4);
+    ul = wxUINT32_SWAP_ON_BE(ul);
+
+    if ( length < ul + FMT_INDEX + waveformat.uiSize + 16 )
+        return false;
+
     if (memcmp(data, "RIFF", 4) != 0)
         return false;
     if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0)
     if (memcmp(data, "RIFF", 4) != 0)
         return false;
     if (memcmp(&data[WAVE_INDEX], "WAVE", 4) != 0)
@@ -649,12 +674,6 @@ bool wxSound::LoadWAV(const wxUint8 *data, size_t length, bool copyData)
         return false;
     if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0)
         return false;
         return false;
     if (memcmp(&data[FMT_INDEX + waveformat.uiSize + 8], "data", 4) != 0)
         return false;
-    memcpy(&ul,&data[FMT_INDEX + waveformat.uiSize + 12], 4);
-    ul = wxUINT32_SWAP_ON_BE(ul);
-
-    //WAS: if (ul + FMT_INDEX + waveformat.uiSize + 16 != length)
-    if (ul + FMT_INDEX + waveformat.uiSize + 16 > length)
-        return false;
 
     if (waveformat.uiFormatTag != WAVE_FORMAT_PCM)
         return false;
 
     if (waveformat.uiFormatTag != WAVE_FORMAT_PCM)
         return false;