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