1///////////////////////////////////////////////////////////////////////////// 2// Name: src/mac/classic/sound.cpp 3// Purpose: wxSound class implementation: optional 4// Author: Stefan Csomor 5// Modified by: 6// Created: 1998-01-01 7// RCS-ID: $Id: sound.cpp 38885 2006-04-24 08:46:59Z ABX $ 8// Copyright: (c) Stefan Csomor 9// Licence: wxWindows licence 10///////////////////////////////////////////////////////////////////////////// 11 12// For compilers that support precompilation, includes "wx.h". 13#include "wx/wxprec.h" 14 15#if wxUSE_SOUND 16 17#include "wx/sound.h" 18 19#ifndef WX_PRECOMP 20 #include "wx/object.h" 21 #include "wx/string.h" 22#endif 23 24#ifdef __WXMAC__ 25#include "wx/mac/private.h" 26#ifndef __DARWIN__ 27#include <Sound.h> 28#endif 29#endif 30 31wxSound::wxSound() 32 : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true) 33{ 34} 35 36wxSound::wxSound(const wxString& sFileName, bool isResource) 37 : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(true) 38{ 39 Create(sFileName, isResource); 40} 41 42 43wxSound::~wxSound() 44{ 45 FreeData(); 46} 47 48wxSound::wxSound(int size, const wxByte* data) 49 : m_sndChan(0), m_hSnd(NULL), m_waveLength(0), m_isResource(false) 50{ 51 //TODO convert data 52} 53 54bool wxSound::Create(const wxString& fileName, bool isResource) 55{ 56 bool ret = false; 57 m_sndname = fileName; 58 m_isResource = isResource; 59 60 if (m_isResource) 61 ret = true; 62 else 63 { /* 64 if (sndChan) 65 { // we're playing 66 FSClose(SndRefNum); 67 SndRefNum = 0; 68 SndDisposeChannel(sndChan, TRUE); 69 free(sndChan); 70 sndChan = 0; 71 KillTimer(0,timerID); 72 } 73 74 if (!lpSnd) 75 return true; 76 77 if (_access(lpSnd,0)) // no file, no service 78 return false; 79 80 // Allocate SndChannel 81 sndChan = (SndChannelPtr) malloc (sizeof(SndChannel)); 82 83 if (!sndChan) 84 return false; 85 86 sndChan->qLength = 128; 87 88 if (noErr != SndNewChannel (&sndChan, sampledSynth, initMono | initNoInterp, 0)) 89 { 90 free(sndChan); 91 sndChan = 0; 92 return false; 93 } 94 95 if (!(SndRefNum = MacOpenSndFile ((char *)lpSnd))) 96 { 97 SndDisposeChannel(sndChan, TRUE); 98 free(sndChan); 99 sndChan = 0; 100 101 return false; 102 } 103 104 bool async = false; 105 106 if (fdwSound & SND_ASYNC) 107 async = true; 108 109 if (SndStartFilePlay(sndChan, SndRefNum, 0, 81920, 0, 0, 0, async) != noErr) 110 { 111 FSClose (SndRefNum); 112 SndRefNum = 0; 113 SndDisposeChannel (sndChan, TRUE); 114 free (sndChan); 115 sndChan = 0; 116 return false; 117 } 118 119 if (async) 120 { // haven't finish yet 121 timerID = SetTimer(0, 0, 250, TimerCallBack); 122 } 123 else 124 { 125 FSClose (SndRefNum); 126 SndRefNum = 0; 127 SndDisposeChannel (sndChan, TRUE); 128 free (sndChan); 129 sndChan = 0; 130 }*/ 131 } 132 133 return ret; 134} 135 136 137//don't know what to do with looped, wth 138bool wxSound::DoPlay(unsigned flags) const 139{ 140 bool ret = false; 141 142 if (m_isResource) 143 { 144 Str255 snd ; 145 wxMacStringToPascal( m_sndname , snd ) ; 146 SndListHandle hSnd; 147 148 hSnd = (SndListHandle) GetNamedResource('snd ', snd); 149 150 if ((hSnd != NULL) && (SndPlay((SndChannelPtr)m_sndChan, (SndListHandle) hSnd, (flags & wxSOUND_ASYNC)) == noErr)) 151 ret = true; 152 } 153 154 return ret; 155} 156 157 158bool wxSound::FreeData() 159{ 160 bool ret = false; 161 162 if (m_isResource) 163 { 164 m_sndname.Empty(); 165 ret = true; 166 } 167 else 168 { 169 //TODO, 170 } 171 172 return ret; 173} 174 175 176//code below is from an old implementation used for telinfo with MSVC crossplatform support 177//technology proceeds, so it would be the wisest to drop this code, but it's left here just 178//for the sake of a reference. BTW: Wave files can now be played with QT, starting from V3 179 180/*static short MacOpenSndFile (char * path) 181{ 182 VolumeParam vp; 183 FSSpec fspec; 184 Str255 name; 185 char *c; 186 187 // first, get the volume reference number for the file. Start by 188 // making a Pstring with just the volume name 189 strcpy ((char *) name, path); 190 if (c = strchr ((char *) name, ':')) 191 { 192 c++; 193 *c = '\0'; 194 } 195 196 c2pstr ((char *) name); 197 vp.ioCompletion = 0; 198 vp.ioVolIndex = -1; 199 vp.ioNamePtr = name; 200 vp.ioVRefNum = 0; 201 202 if (PBGetVInfo((ParamBlockRec *)&vp, 0) != noErr) 203 return 0; 204 205 // next, buld an FSSpec for the file 206 strcpy ((char *) name, path); 207 c2pstr ((char *) name); 208 if (FSMakeFSSpec (vp.ioVRefNum, 0, name, &fspec) != noErr) 209 return 0; 210 211 short frefnum; 212 // now open the file, and return it's reference number 213 if (FSpOpenDF(&fspec, fsRdPerm, &frefnum) != noErr) 214 return 0; 215 216 return frefnum; 217} 218 219 220void TimerCallBack(HWND hwnd,UINT uMsg,UINT idEvent,DWORD dwTime) 221{ 222 if(!sndChan) 223 { 224 KillTimer(0,timerID); 225 return; 226 } 227 228 SCStatus scstat; 229 230 if (noErr == SndChannelStatus (sndChan, sizeof (SCStatus), &scstat)) { 231 if (scstat.scChannelPaused || scstat.scChannelBusy) 232 return; // not done yet 233 } 234 235 // either error or done. 236 FSClose (SndRefNum); 237 SndRefNum = 0; 238 SndDisposeChannel (sndChan, TRUE); 239 free (sndChan); 240 sndChan = 0; 241 KillTimer(0,timerID); 242}*/ 243 244#endif // wxUSE_SOUND 245