text: /////////////////////////////////////////////////////////////////////////////
  // Name:        sound.cpp
  // Purpose:     wxSound class implementation: optional
  // Author:      Stefan Csomor
  // Modified by:
  // Created:     1998-01-01
  // RCS-ID:      $Id: sound.cpp,v 1.3 2004/05/23 20:52:41 JS Exp $
  // Copyright:   (c) Stefan Csomor
  // Licence:       wxWindows licence
  /////////////////////////////////////////////////////////////////////////////
  
  #ifdef __GNUG__
  #pragma implementation "sound.h"
  #endif
  
  #include "wx/object.h"
  #include "wx/string.h"
  #include "wx/sound.h"
  
  #if wxUSE_SOUND
  
  #ifdef __WXMAC__
  #include "wx/mac/private.h"
  #ifndef __DARWIN__
  #include <Sound.h>
  #endif
  #endif
  
  wxSound::wxSound()
    : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
  {
  }
  
  wxSound::wxSound(const wxString& sFileName, bool isResource)
    : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true)
  {
      Create(sFileName, isResource);
  }
  
  
  wxSound::~wxSound()
  {
      FreeData();
  }
  
  wxSound::wxSound(int size, const wxByte* data)
    : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false)
  {
      //TODO convert data
  }
  
  bool wxSound::Create(const wxString& fileName, bool isResource)
  {
      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));
  
          if (!sndChan)
              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 wxSound::DoPlay(unsigned flags) const
  {
      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, (flags & wxSOUND_ASYNC)) == noErr))
          	ret = true;
      }
  
      return ret;
  }
  
  
  bool wxSound::FreeData()
  {
      bool ret = false;
  
      if (m_isResource)
      {
          m_sndname.Empty();
          ret = true;
      }
      else
      {
          //TODO,
      }
  
      return ret;
  }
  
  
  //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)
  {
      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
  