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