]> git.saurik.com Git - wxWidgets.git/blame - utils/wxMMedia2/lib/sndfile.cpp
Distrib file updates; test for bitmap presence in controls.cpp
[wxWidgets.git] / utils / wxMMedia2 / lib / sndfile.cpp
CommitLineData
526ddb13
GL
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// --------------------------------------------------------------------------
6c5e6376
GL
8#include <wx/wxprec.h>
9
10#ifndef WX_PRECOMP
526ddb13 11#include <wx/stream.h>
6c5e6376
GL
12#endif
13
526ddb13
GL
14#include "sndbase.h"
15#include "sndcodec.h"
16#include "sndfile.h"
17#include "sndcpcm.h"
18#include "sndulaw.h"
0662cd32 19#include "sndg72x.h"
526ddb13
GL
20
21// --------------------------------------------------------------------------
22// Sound codec router
27259273
GL
23// A very important class: it ensures that everybody is satisfied.
24// It is supposed to create as many codec as it is necessary to transform
25// a signal in a specific format in an another.
526ddb13 26// --------------------------------------------------------------------------
526ddb13
GL
27wxSoundRouterStream::wxSoundRouterStream(wxSoundStream& sndio)
28 : wxSoundStreamCodec(sndio)
29{
30 m_router = NULL;
31}
32
33wxSoundRouterStream::~wxSoundRouterStream()
34{
35 if (m_router)
36 delete m_router;
37}
38
27259273
GL
39// --------------------------------------------------------------------------
40// Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
41// for possible errors and behaviours ...
42// --------------------------------------------------------------------------
0662cd32 43wxSoundStream& wxSoundRouterStream::Read(void *buffer, wxUint32 len)
526ddb13
GL
44{
45 if (m_router) {
46 m_router->Read(buffer, len);
47 m_snderror = m_router->GetError();
48 m_lastcount = m_router->GetLastAccess();
49 } else {
50 m_sndio->Read(buffer, len);
51 m_snderror = m_sndio->GetError();
52 m_lastcount = m_sndio->GetLastAccess();
53 }
54 return *this;
55}
56
27259273
GL
57// --------------------------------------------------------------------------
58// Write(const void *buffer, wxUint32 len): It writes data synchronously
59// --------------------------------------------------------------------------
0662cd32 60wxSoundStream& wxSoundRouterStream::Write(const void *buffer, wxUint32 len)
526ddb13
GL
61{
62 if (m_router) {
63 m_router->Write(buffer, len);
64 m_snderror = m_router->GetError();
65 m_lastcount = m_router->GetLastAccess();
66 } else {
67 m_sndio->Write(buffer, len);
68 m_snderror = m_sndio->GetError();
69 m_lastcount = m_sndio->GetLastAccess();
70 }
71 return *this;
72}
73
27259273
GL
74// --------------------------------------------------------------------------
75// SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
76// sound driver using the specified format. If this fails, it uses personnal
77// codec converters: for the moment there is a PCM converter (PCM to PCM:
78// with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
79// converter (G72X to PCM). If nothing works, it returns FALSE.
80// --------------------------------------------------------------------------
526ddb13
GL
81bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase& format)
82{
83 if (m_router)
84 delete m_router;
85
86 if (m_sndio->SetSoundFormat(format)) {
87 wxSoundStream::SetSoundFormat(m_sndio->GetSoundFormat());
88 return TRUE;
89 }
90
91 switch(format.GetType()) {
92 case wxSOUND_NOFORMAT:
93 return FALSE;
94 case wxSOUND_PCM:
95 m_router = new wxSoundStreamPcm(*m_sndio);
96 m_router->SetSoundFormat(format);
97 break;
98 case wxSOUND_ULAW:
99 m_router = new wxSoundStreamUlaw(*m_sndio);
100 m_router->SetSoundFormat(format);
101 break;
0662cd32
GL
102 case wxSOUND_G72X:
103 m_router = new wxSoundStreamG72X(*m_sndio);
104 m_router->SetSoundFormat(format);
105 break;
526ddb13
GL
106 }
107 wxSoundStream::SetSoundFormat(m_router->GetSoundFormat());
108 return TRUE;
109}
110
27259273
GL
111// --------------------------------------------------------------------------
112// GetBestSize() returns the specific best buffer size a sound driver
113// can manage. It means that it will be easier for it to manage the buffer
114// and so it will be faster and in some case more accurate for real-time event.
115// --------------------------------------------------------------------------
56dc1ffd
GL
116wxUint32 wxSoundRouterStream::GetBestSize() const
117{
118 if (m_router)
119 return m_router->GetBestSize();
120 else
121 return m_sndio->GetBestSize();
122}
123
27259273
GL
124// --------------------------------------------------------------------------
125// StartProduction(int evt). See sndbase.h
126// --------------------------------------------------------------------------
526ddb13
GL
127bool wxSoundRouterStream::StartProduction(int evt)
128{
129 if (!m_router) {
130 if (m_sndio->StartProduction(evt))
131 return TRUE;
132
133 m_snderror = m_sndio->GetError();
134 m_lastcount = m_sndio->GetLastAccess();
135 return FALSE;
136 }
137
138 if (m_router->StartProduction(evt))
139 return TRUE;
140
141 m_snderror = m_router->GetError();
142 m_lastcount = m_router->GetLastAccess();
143 return FALSE;
144}
145
27259273
GL
146// --------------------------------------------------------------------------
147// StopProduction(). See sndbase.h
148// --------------------------------------------------------------------------
526ddb13
GL
149bool wxSoundRouterStream::StopProduction()
150{
151 if (!m_router) {
152 if (m_sndio->StopProduction())
153 return TRUE;
154
155 m_snderror = m_sndio->GetError();
156 m_lastcount = m_sndio->GetLastAccess();
157 return FALSE;
158 }
159
160 if (m_router->StopProduction())
161 return TRUE;
162
163 m_snderror = m_router->GetError();
164 m_lastcount = m_router->GetLastAccess();
165 return FALSE;
166}
167
168
169// --------------------------------------------------------------------------
170// wxSoundFileStream: generic reader
171// --------------------------------------------------------------------------
172
173wxSoundFileStream::wxSoundFileStream(wxInputStream& stream,
174 wxSoundStream& io_sound)
175 : m_codec(io_sound), m_sndio(&io_sound),
176 m_input(&stream), m_output(NULL), m_state(wxSOUND_FILE_STOPPED)
177{
178}
179
180wxSoundFileStream::wxSoundFileStream(wxOutputStream& stream,
181 wxSoundStream& io_sound)
182 : m_codec(io_sound), m_sndio(&io_sound),
183 m_input(NULL), m_output(&stream), m_state(wxSOUND_FILE_STOPPED)
184{
185}
186
187wxSoundFileStream::~wxSoundFileStream()
188{
189 if (m_state != wxSOUND_FILE_STOPPED)
190 Stop();
191}
192
193bool wxSoundFileStream::Play()
194{
195 if (m_state != wxSOUND_FILE_STOPPED)
196 return FALSE;
197
198 if (!PrepareToPlay())
199 return FALSE;
200
503aa33d
GL
201 m_state = wxSOUND_FILE_PLAYING;
202
526ddb13
GL
203 if (!StartProduction(wxSOUND_OUTPUT))
204 return FALSE;
205
526ddb13
GL
206 return TRUE;
207}
208
209bool wxSoundFileStream::Record(unsigned long time)
210{
211 if (m_state != wxSOUND_FILE_STOPPED)
212 return FALSE;
213
214 if (!PrepareToRecord(time))
215 return FALSE;
216
622e48cb 217 m_len = m_sndformat->GetBytesFromTime(time);
526ddb13 218
503aa33d 219 m_state = wxSOUND_FILE_RECORDING;
526ddb13
GL
220 if (!StartProduction(wxSOUND_INPUT))
221 return FALSE;
222
526ddb13
GL
223 return TRUE;
224}
225
226bool wxSoundFileStream::Stop()
227{
228 if (m_state == wxSOUND_FILE_STOPPED)
229 return FALSE;
230
231 if (!StopProduction())
232 return FALSE;
233
234 if (m_state == wxSOUND_FILE_RECORDING)
235 if (!FinishRecording()) {
236 m_state = wxSOUND_FILE_STOPPED;
237 return FALSE;
238 }
27259273
GL
239
240 if (m_input)
241 m_input->SeekI(0, wxFromStart);
242
243 if (m_output)
244 m_output->SeekO(0, wxFromStart);
526ddb13 245
526ddb13
GL
246 m_state = wxSOUND_FILE_STOPPED;
247 return TRUE;
248}
249
250bool wxSoundFileStream::Pause()
251{
252 if (m_state == wxSOUND_FILE_PAUSED || m_state == wxSOUND_FILE_STOPPED)
253 return FALSE;
254
255 if (!StopProduction())
256 return FALSE;
257
258 m_oldstate = m_state;
259 m_state = wxSOUND_FILE_PAUSED;
260 return TRUE;
261}
262
263bool wxSoundFileStream::Resume()
264{
265 if (m_state == wxSOUND_FILE_PLAYING || m_state == wxSOUND_FILE_RECORDING ||
266 m_state == wxSOUND_FILE_STOPPED)
267 return FALSE;
268
269 if (!StartProduction( (m_oldstate == wxSOUND_FILE_PLAYING) ?
270 wxSOUND_OUTPUT : wxSOUND_INPUT))
271 return FALSE;
272
273 m_state = m_oldstate;
274
275 return TRUE;
276}
277
0662cd32 278wxSoundStream& wxSoundFileStream::Read(void *buffer, wxUint32 len)
526ddb13
GL
279{
280 m_lastcount = GetData(buffer, len);
281 return *this;
282}
283
0662cd32 284wxSoundStream& wxSoundFileStream::Write(const void *buffer, wxUint32 len)
526ddb13
GL
285{
286 m_lastcount = PutData(buffer, len);
287 return *this;
288}
289
290void wxSoundFileStream::SetDuplexMode(bool duplex)
291{
292}
293
294bool wxSoundFileStream::StartProduction(int evt)
295{
296 m_sndio->SetEventHandler(this);
297
298 if (!m_codec.StartProduction(evt))
299 return FALSE;
300
301 return TRUE;
302}
303
304bool wxSoundFileStream::StopProduction()
305{
306 return m_codec.StopProduction();
307}
308
309void wxSoundFileStream::OnSoundEvent(int evt)
310{
56dc1ffd 311 wxUint32 len = m_codec.GetBestSize();
6c5e6376 312 char *buffer;
526ddb13 313
503aa33d 314 buffer = new char[len];
526ddb13
GL
315 wxSoundStream::OnSoundEvent(evt);
316
503aa33d
GL
317 while (!m_sndio->QueueFilled()) {
318 switch(evt) {
319 case wxSOUND_INPUT:
320 if (len > m_len)
321 len = m_len;
322
323 len = m_codec.Read(buffer, len).GetLastAccess();
324 PutData(buffer, len);
325 m_len -= len;
326 if (m_len == 0) {
327 Stop();
56dc1ffd 328 delete[] buffer;
503aa33d
GL
329 return;
330 }
331 break;
332 case wxSOUND_OUTPUT:
333 len = GetData(buffer, len);
334 if (len == 0) {
335 Stop();
56dc1ffd 336 delete[] buffer;
503aa33d
GL
337 return;
338 }
339 m_codec.Write(buffer, len);
340 break;
526ddb13 341 }
526ddb13 342 }
6c5e6376 343 delete[] buffer;
526ddb13
GL
344}
345
346bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase& format)
347{
348 wxSoundStream::SetSoundFormat(format);
349 return m_codec.SetSoundFormat(format);
350}