]> git.saurik.com Git - wxWidgets.git/blobdiff - src/mac/carbon/wave.cpp
- Moved wxApp::SendIdleEvents and wxApp::ProcessIdle into common code.
[wxWidgets.git] / src / mac / carbon / wave.cpp
index c25681858c1ff36786d670c8a5d2366a617c25a2..35accb91670fa30805afea67f65bf90a326b5dc5 100644 (file)
@@ -1,12 +1,12 @@
 /////////////////////////////////////////////////////////////////////////////
 // Name:        wave.cpp
 // Purpose:     wxWave class implementation: optional
-// Author:      AUTHOR
+// Author:      Stefan Csomor
 // Modified by:
-// Created:     ??/??/98
+// Created:     1998-01-01
 // RCS-ID:      $Id$
-// Copyright:   (c) AUTHOR
-// Licence:    wxWindows licence
+// Copyright:   (c) Stefan Csomor
+// Licence:       wxWindows licence
 /////////////////////////////////////////////////////////////////////////////
 
 #ifdef __GNUG__
 
 #include "wx/object.h"
 #include "wx/string.h"
-#include "wx/stubs/wave.h"
+#include "wx/wave.h"
+
+#if wxUSE_WAVE
+
+#ifdef __WXMAC__
+#include "wx/mac/private.h"
+#ifndef __DARWIN__
+#include <Sound.h>
+#endif
+#endif
 
 wxWave::wxWave()
-  : m_waveData(NULL), m_waveLength(0), m_isResource(FALSE)
+  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
 {
 }
 
 wxWave::wxWave(const wxString& sFileName, bool isResource)
-  : m_waveData(NULL), m_waveLength(0), m_isResource(FALSE)
+  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
 {
     Create(sFileName, isResource);
 }
@@ -31,31 +40,204 @@ wxWave::wxWave(const wxString& sFileName, bool isResource)
 
 wxWave::~wxWave()
 {
-    Free();
+    FreeData();
+}
+
+wxWave::wxWave(int size, const wxByte* data)
+  : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false)
+{
+    //TODO convert data
 }
 
 bool wxWave::Create(const wxString& fileName, bool isResource)
 {
-    Free();
+    bool ret = false;
+    m_sndname = fileName;
+    m_isResource = isResource;
+
+    if (m_isResource)
+        ret = true;
+    else
+    { /*
+        if (sndChan)
+        {                                                                    // we're playing
+            FSClose(SndRefNum);
+            SndRefNum = 0;
+            SndDisposeChannel(sndChan, TRUE);
+            free(sndChan);
+            sndChan = 0;
+            KillTimer(0,timerID);
+        }
+
+        if (!lpSnd)
+            return true;
+
+        if (_access(lpSnd,0))                            // no file, no service
+            return false;
+
+        // Allocate SndChannel
+        sndChan = (SndChannelPtr) malloc (sizeof(SndChannel));
 
-    // TODO
+        if (!sndChan)
+            return false;
 
-    return FALSE;
+        sndChan->qLength = 128;
+
+        if (noErr != SndNewChannel (&sndChan, sampledSynth, initMono | initNoInterp, 0))
+        {
+            free(sndChan);
+            sndChan = 0;
+            return false;
+        }
+
+        if (!(SndRefNum = MacOpenSndFile ((char *)lpSnd)))
+        {
+            SndDisposeChannel(sndChan, TRUE);
+            free(sndChan);
+            sndChan = 0;
+
+            return false;
+        }
+
+        bool async = false;
+
+        if (fdwSound & SND_ASYNC)
+            async = true;
+
+        if (SndStartFilePlay(sndChan, SndRefNum, 0, 81920, 0, 0, 0, async) != noErr)
+        {
+            FSClose (SndRefNum);
+            SndRefNum = 0;
+            SndDisposeChannel (sndChan, TRUE);
+            free (sndChan);
+            sndChan = 0;
+            return false;
+        }
+
+        if (async)
+        {  // haven't finish yet
+            timerID = SetTimer(0, 0, 250, TimerCallBack);
+        }
+        else
+        {
+            FSClose (SndRefNum);
+            SndRefNum = 0;
+            SndDisposeChannel (sndChan, TRUE);
+            free (sndChan);
+            sndChan = 0;
+        }*/
+    }
+
+    return ret;
 }
 
+
+//don't know what to do with looped, wth
 bool wxWave::Play(bool async, bool looped) const
 {
-    if (!IsOk())
-        return FALSE;
+    bool ret = false;
+
+    if (m_isResource)
+    {
+       Str255 snd ;
+       wxMacStringToPascal( m_sndname , snd ) ;
+       SndListHandle hSnd;
+
+       hSnd = (SndListHandle) GetNamedResource('snd ', snd);
+
+       if ((hSnd != NULL) && (SndPlay((SndChannelPtr)m_sndChan, (SndListHandle) hSnd, async) == noErr))
+               ret = true;
+    }
+
+    return ret;
+}
+
+
+bool wxWave::FreeData()
+{
+    bool ret = false;
 
-    // TODO
-    return FALSE;
+    if (m_isResource)
+    {
+        m_sndname.Empty();
+        ret = true;
+    }
+    else
+    {
+        //TODO,
+    }
+
+    return ret;
 }
 
-bool wxWave::Free()
+
+//code below is from an old implementation used for telinfo with MSVC crossplatform support
+//technology proceeds, so it would be the wisest to drop this code, but it's left here just
+//for the sake of a reference. BTW: Wave files can now be played with QT, starting from V3
+
+/*static short MacOpenSndFile (char * path)
 {
-    // TODO
-    return FALSE;
+    VolumeParam vp;
+    FSSpec fspec;
+    Str255 name;
+    char *c;
+
+    // first, get the volume reference number for the file.  Start by
+    // making a Pstring with just the volume name
+    strcpy ((char *) name, path);
+    if (c = strchr ((char *) name, ':'))
+    {
+        c++;
+        *c = '\0';
+    }
+
+    c2pstr ((char *) name);
+    vp.ioCompletion = 0;
+    vp.ioVolIndex    = -1;
+    vp.ioNamePtr    = name;
+    vp.ioVRefNum    = 0;
+
+    if (PBGetVInfo((ParamBlockRec *)&vp, 0) != noErr)
+        return 0;
+
+    // next, buld an FSSpec for the file
+    strcpy ((char *) name, path);
+    c2pstr ((char *) name);
+    if (FSMakeFSSpec (vp.ioVRefNum, 0, name, &fspec) != noErr)
+        return 0;
+
+    short frefnum;
+    // now open the file, and return it's reference number
+    if (FSpOpenDF(&fspec, fsRdPerm, &frefnum) != noErr)
+        return 0;
+
+    return frefnum;
 }
 
 
+void TimerCallBack(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime)
+{
+    if(!sndChan)
+    {
+        KillTimer(0,timerID);
+        return;
+    }
+
+    SCStatus    scstat;
+
+    if (noErr == SndChannelStatus (sndChan, sizeof (SCStatus), &scstat)) {
+        if (scstat.scChannelPaused || scstat.scChannelBusy)
+            return;                            // not done yet
+    }
+
+    // either error or done.
+    FSClose (SndRefNum);
+    SndRefNum = 0;
+    SndDisposeChannel (sndChan, TRUE);
+    free (sndChan);
+    sndChan = 0;
+    KillTimer(0,timerID);
+}*/
+
+
+#endif