Added wxSound for Windows support (successful WAV playback on VC++ 5)
[wxWidgets.git] / utils / wxMMedia2 / lib / sndfile.cpp
1 // --------------------------------------------------------------------------
2 // Name: sndfile.cpp
3 // Purpose:
4 // Date: 08/11/1999
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6 // CVSID: $Id$
7 // --------------------------------------------------------------------------
8 #include <wx/wxprec.h>
9
10 #ifndef WX_PRECOMP
11 #include <wx/stream.h>
12 #endif
13
14 #include "sndbase.h"
15 #include "sndcodec.h"
16 #include "sndfile.h"
17 #include "sndcpcm.h"
18 #include "sndulaw.h"
19
20 // --------------------------------------------------------------------------
21 // Sound codec router
22 // --------------------------------------------------------------------------
23
24 wxSoundRouterStream::wxSoundRouterStream(wxSoundStream& sndio)
25 : wxSoundStreamCodec(sndio)
26 {
27 m_router = NULL;
28 }
29
30 wxSoundRouterStream::~wxSoundRouterStream()
31 {
32 if (m_router)
33 delete m_router;
34 }
35
36 wxSoundStream& wxSoundRouterStream::Read(void *buffer, size_t len)
37 {
38 if (m_router) {
39 m_router->Read(buffer, len);
40 m_snderror = m_router->GetError();
41 m_lastcount = m_router->GetLastAccess();
42 } else {
43 m_sndio->Read(buffer, len);
44 m_snderror = m_sndio->GetError();
45 m_lastcount = m_sndio->GetLastAccess();
46 }
47 return *this;
48 }
49
50 wxSoundStream& wxSoundRouterStream::Write(const void *buffer, size_t len)
51 {
52 if (m_router) {
53 m_router->Write(buffer, len);
54 m_snderror = m_router->GetError();
55 m_lastcount = m_router->GetLastAccess();
56 } else {
57 m_sndio->Write(buffer, len);
58 m_snderror = m_sndio->GetError();
59 m_lastcount = m_sndio->GetLastAccess();
60 }
61 return *this;
62 }
63
64 bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
65 {
66 if (m_router)
67 delete m_router;
68
69 if (m_sndio->SetSoundFormat(format)) {
70 wxSoundStream::SetSoundFormat(m_sndio->GetSoundFormat());
71 return TRUE;
72 }
73
74 switch(format.GetType()) {
75 case wxSOUND_NOFORMAT:
76 return FALSE;
77 case wxSOUND_PCM:
78 m_router = new wxSoundStreamPcm(*m_sndio);
79 m_router->SetSoundFormat(format);
80 break;
81 case wxSOUND_ULAW:
82 m_router = new wxSoundStreamUlaw(*m_sndio);
83 m_router->SetSoundFormat(format);
84 break;
85 }
86 wxSoundStream::SetSoundFormat(m_router->GetSoundFormat());
87 return TRUE;
88 }
89
90 bool wxSoundRouterStream::StartProduction(int evt)
91 {
92 if (!m_router) {
93 if (m_sndio->StartProduction(evt))
94 return TRUE;
95
96 m_snderror = m_sndio->GetError();
97 m_lastcount = m_sndio->GetLastAccess();
98 return FALSE;
99 }
100
101 if (m_router->StartProduction(evt))
102 return TRUE;
103
104 m_snderror = m_router->GetError();
105 m_lastcount = m_router->GetLastAccess();
106 return FALSE;
107 }
108
109 bool wxSoundRouterStream::StopProduction()
110 {
111 if (!m_router) {
112 if (m_sndio->StopProduction())
113 return TRUE;
114
115 m_snderror = m_sndio->GetError();
116 m_lastcount = m_sndio->GetLastAccess();
117 return FALSE;
118 }
119
120 if (m_router->StopProduction())
121 return TRUE;
122
123 m_snderror = m_router->GetError();
124 m_lastcount = m_router->GetLastAccess();
125 return FALSE;
126 }
127
128
129 // --------------------------------------------------------------------------
130 // wxSoundFileStream: generic reader
131 // --------------------------------------------------------------------------
132
133 wxSoundFileStream::wxSoundFileStream(wxInputStream& stream,
134 wxSoundStream& io_sound)
135 : m_codec(io_sound), m_sndio(&io_sound),
136 m_input(&stream), m_output(NULL), m_state(wxSOUND_FILE_STOPPED)
137 {
138 }
139
140 wxSoundFileStream::wxSoundFileStream(wxOutputStream& stream,
141 wxSoundStream& io_sound)
142 : m_codec(io_sound), m_sndio(&io_sound),
143 m_input(NULL), m_output(&stream), m_state(wxSOUND_FILE_STOPPED)
144 {
145 }
146
147 wxSoundFileStream::~wxSoundFileStream()
148 {
149 if (m_state != wxSOUND_FILE_STOPPED)
150 Stop();
151 }
152
153 bool wxSoundFileStream::Play()
154 {
155 if (m_state != wxSOUND_FILE_STOPPED)
156 return FALSE;
157
158 if (!PrepareToPlay())
159 return FALSE;
160
161 m_state = wxSOUND_FILE_PLAYING;
162
163 if (!StartProduction(wxSOUND_OUTPUT))
164 return FALSE;
165
166 return TRUE;
167 }
168
169 bool wxSoundFileStream::Record(unsigned long time)
170 {
171 if (m_state != wxSOUND_FILE_STOPPED)
172 return FALSE;
173
174 if (!PrepareToRecord(time))
175 return FALSE;
176
177 m_len = m_sndformat->GetBytesFromTime(time);
178
179 m_state = wxSOUND_FILE_RECORDING;
180 if (!StartProduction(wxSOUND_INPUT))
181 return FALSE;
182
183 return TRUE;
184 }
185
186 bool wxSoundFileStream::Stop()
187 {
188 if (m_state == wxSOUND_FILE_STOPPED)
189 return FALSE;
190
191 if (!StopProduction())
192 return FALSE;
193
194 if (m_state == wxSOUND_FILE_RECORDING)
195 if (!FinishRecording()) {
196 m_state = wxSOUND_FILE_STOPPED;
197 return FALSE;
198 }
199
200 // TODO reset counter
201 m_state = wxSOUND_FILE_STOPPED;
202 return TRUE;
203 }
204
205 bool wxSoundFileStream::Pause()
206 {
207 if (m_state == wxSOUND_FILE_PAUSED || m_state == wxSOUND_FILE_STOPPED)
208 return FALSE;
209
210 if (!StopProduction())
211 return FALSE;
212
213 m_oldstate = m_state;
214 m_state = wxSOUND_FILE_PAUSED;
215 return TRUE;
216 }
217
218 bool wxSoundFileStream::Resume()
219 {
220 if (m_state == wxSOUND_FILE_PLAYING || m_state == wxSOUND_FILE_RECORDING ||
221 m_state == wxSOUND_FILE_STOPPED)
222 return FALSE;
223
224 if (!StartProduction( (m_oldstate == wxSOUND_FILE_PLAYING) ?
225 wxSOUND_OUTPUT : wxSOUND_INPUT))
226 return FALSE;
227
228 m_state = m_oldstate;
229
230 return TRUE;
231 }
232
233 wxSoundStream& wxSoundFileStream::Read(void *buffer, size_t len)
234 {
235 m_lastcount = GetData(buffer, len);
236 return *this;
237 }
238
239 wxSoundStream& wxSoundFileStream::Write(const void *buffer, size_t len)
240 {
241 m_lastcount = PutData(buffer, len);
242 return *this;
243 }
244
245 void wxSoundFileStream::SetDuplexMode(bool duplex)
246 {
247 }
248
249 bool wxSoundFileStream::StartProduction(int evt)
250 {
251 m_sndio->SetEventHandler(this);
252
253 if (!m_codec.StartProduction(evt))
254 return FALSE;
255
256 return TRUE;
257 }
258
259 bool wxSoundFileStream::StopProduction()
260 {
261 return m_codec.StopProduction();
262 }
263
264 void wxSoundFileStream::OnSoundEvent(int evt)
265 {
266 size_t len = m_sndio->GetBestSize();
267 char *buffer;
268
269 buffer = new char[len];
270 wxSoundStream::OnSoundEvent(evt);
271
272 while (!m_sndio->QueueFilled()) {
273 switch(evt) {
274 case wxSOUND_INPUT:
275 if (len > m_len)
276 len = m_len;
277
278 len = m_codec.Read(buffer, len).GetLastAccess();
279 PutData(buffer, len);
280 m_len -= len;
281 if (m_len == 0) {
282 Stop();
283 return;
284 }
285 break;
286 case wxSOUND_OUTPUT:
287 len = GetData(buffer, len);
288 if (len == 0) {
289 Stop();
290 return;
291 }
292 m_codec.Write(buffer, len);
293 break;
294 }
295 }
296 delete[] buffer;
297 }
298
299 bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase& format)
300 {
301 wxSoundStream::SetSoundFormat(format);
302 return m_codec.SetSoundFormat(format);
303 }