]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/mmedia/sndfile.cpp
1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
8 // --------------------------------------------------------------------------
13 #include <wx/stream.h>
16 #include "wx/mmedia/sndbase.h"
17 #include "wx/mmedia/sndcodec.h"
18 #include "wx/mmedia/sndfile.h"
19 #include "wx/mmedia/sndcpcm.h"
20 #include "wx/mmedia/sndulaw.h"
21 #include "wx/mmedia/sndg72x.h"
22 #include "wx/mmedia/sndmsad.h"
24 // --------------------------------------------------------------------------
26 // A very important class: it ensures that everybody is satisfied.
27 // It is supposed to create as many codec as it is necessary to transform
28 // a signal in a specific format in an another.
29 // --------------------------------------------------------------------------
30 wxSoundRouterStream::wxSoundRouterStream(wxSoundStream
& sndio
)
31 : wxSoundStreamCodec(sndio
)
36 wxSoundRouterStream::~wxSoundRouterStream()
42 // --------------------------------------------------------------------------
43 // Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
44 // for possible errors and behaviours ...
45 // --------------------------------------------------------------------------
46 wxSoundStream
& wxSoundRouterStream::Read(void *buffer
, wxUint32 len
)
49 m_router
->Read(buffer
, len
);
50 m_snderror
= m_router
->GetError();
51 m_lastcount
= m_router
->GetLastAccess();
53 m_sndio
->Read(buffer
, len
);
54 m_snderror
= m_sndio
->GetError();
55 m_lastcount
= m_sndio
->GetLastAccess();
60 // --------------------------------------------------------------------------
61 // Write(const void *buffer, wxUint32 len): It writes data synchronously
62 // --------------------------------------------------------------------------
63 wxSoundStream
& wxSoundRouterStream::Write(const void *buffer
, wxUint32 len
)
66 m_router
->Write(buffer
, len
);
67 m_snderror
= m_router
->GetError();
68 m_lastcount
= m_router
->GetLastAccess();
70 m_sndio
->Write(buffer
, len
);
71 m_snderror
= m_sndio
->GetError();
72 m_lastcount
= m_sndio
->GetLastAccess();
77 // --------------------------------------------------------------------------
78 // SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
79 // sound driver using the specified format. If this fails, it uses personnal
80 // codec converters: for the moment there is a PCM converter (PCM to PCM:
81 // with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
82 // converter (G72X to PCM). If nothing works, it returns false.
83 // --------------------------------------------------------------------------
84 bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase
& format
)
89 // First, we try to setup the sound device
90 if (m_sndio
->SetSoundFormat(format
)) {
91 // We are lucky, it is working.
92 wxSoundStream::SetSoundFormat(m_sndio
->GetSoundFormat());
96 switch(format
.GetType()) {
97 case wxSOUND_NOFORMAT
:
100 m_router
= new wxSoundStreamPcm(*m_sndio
);
101 m_router
->SetSoundFormat(format
);
104 m_router
= new wxSoundStreamUlaw(*m_sndio
);
105 m_router
->SetSoundFormat(format
);
108 m_router
= new wxSoundStreamG72X(*m_sndio
);
109 m_router
->SetSoundFormat(format
);
111 case wxSOUND_MSADPCM
:
112 m_router
= new wxSoundStreamMSAdpcm(*m_sndio
);
113 m_router
->SetSoundFormat(format
);
119 wxSoundStream::SetSoundFormat(m_router
->GetSoundFormat());
123 // --------------------------------------------------------------------------
124 // GetBestSize() returns the specific best buffer size a sound driver
125 // can manage. It means that it will be easier for it to manage the buffer
126 // and so it will be faster and in some case more accurate for real-time event.
127 // --------------------------------------------------------------------------
128 wxUint32
wxSoundRouterStream::GetBestSize() const
131 return m_router
->GetBestSize();
133 return m_sndio
->GetBestSize();
136 // --------------------------------------------------------------------------
137 // StartProduction(int evt). See sndbase.h
138 // --------------------------------------------------------------------------
139 bool wxSoundRouterStream::StartProduction(int evt
)
142 if (m_sndio
->StartProduction(evt
))
145 m_snderror
= m_sndio
->GetError();
146 m_lastcount
= m_sndio
->GetLastAccess();
150 if (m_router
->StartProduction(evt
))
153 m_snderror
= m_router
->GetError();
154 m_lastcount
= m_router
->GetLastAccess();
158 // --------------------------------------------------------------------------
159 // StopProduction(). See sndbase.h
160 // --------------------------------------------------------------------------
161 bool wxSoundRouterStream::StopProduction()
164 if (m_sndio
->StopProduction())
167 m_snderror
= m_sndio
->GetError();
168 m_lastcount
= m_sndio
->GetLastAccess();
172 if (m_router
->StopProduction())
175 m_snderror
= m_router
->GetError();
176 m_lastcount
= m_router
->GetLastAccess();
180 // --------------------------------------------------------------------------
181 // wxSoundFileStream: generic reader
182 // --------------------------------------------------------------------------
184 wxSoundFileStream::wxSoundFileStream(wxInputStream
& stream
,
185 wxSoundStream
& io_sound
)
186 : m_codec(io_sound
), m_sndio(&io_sound
),
187 m_input(&stream
), m_output(NULL
), m_state(wxSOUND_FILE_STOPPED
)
194 wxSoundFileStream::wxSoundFileStream(wxOutputStream
& stream
,
195 wxSoundStream
& io_sound
)
196 : m_codec(io_sound
), m_sndio(&io_sound
),
197 m_input(NULL
), m_output(&stream
), m_state(wxSOUND_FILE_STOPPED
)
204 wxSoundFileStream::~wxSoundFileStream()
206 if (m_state
!= wxSOUND_FILE_STOPPED
)
210 bool wxSoundFileStream::Play()
212 if (m_state
!= wxSOUND_FILE_STOPPED
)
216 if (!PrepareToPlay())
219 m_state
= wxSOUND_FILE_PLAYING
;
221 if (!StartProduction(wxSOUND_OUTPUT
))
227 bool wxSoundFileStream::Record(wxUint32 time
)
229 if (m_state
!= wxSOUND_FILE_STOPPED
)
232 if (!PrepareToRecord(time
))
235 FinishPreparation(m_sndformat
->GetBytesFromTime(time
));
237 m_state
= wxSOUND_FILE_RECORDING
;
238 if (!StartProduction(wxSOUND_INPUT
))
244 bool wxSoundFileStream::Stop()
246 if (m_state
== wxSOUND_FILE_STOPPED
)
249 if (!StopProduction())
254 if (m_state
== wxSOUND_FILE_RECORDING
)
255 if (!FinishRecording()) {
256 m_state
= wxSOUND_FILE_STOPPED
;
261 m_input
->SeekI(0, wxFromStart
);
264 m_output
->SeekO(0, wxFromStart
);
266 m_state
= wxSOUND_FILE_STOPPED
;
270 bool wxSoundFileStream::Pause()
272 if (m_state
== wxSOUND_FILE_PAUSED
|| m_state
== wxSOUND_FILE_STOPPED
)
275 if (!StopProduction())
278 m_oldstate
= m_state
;
279 m_state
= wxSOUND_FILE_PAUSED
;
283 bool wxSoundFileStream::Resume()
285 if (m_state
== wxSOUND_FILE_PLAYING
|| m_state
== wxSOUND_FILE_RECORDING
||
286 m_state
== wxSOUND_FILE_STOPPED
)
289 if (!StartProduction( (m_oldstate
== wxSOUND_FILE_PLAYING
) ?
290 wxSOUND_OUTPUT
: wxSOUND_INPUT
))
293 m_state
= m_oldstate
;
298 wxSoundStream
& wxSoundFileStream::Read(void *buffer
, wxUint32 len
)
300 if (!m_prepared
|| m_state
!= wxSOUND_FILE_PLAYING
) {
301 m_snderror
= wxSOUND_NOTSTARTED
;
305 m_lastcount
= GetData(buffer
, len
);
309 wxSoundStream
& wxSoundFileStream::Write(const void *buffer
, wxUint32 len
)
311 if (!m_prepared
|| m_state
!= wxSOUND_FILE_RECORDING
) {
312 m_snderror
= wxSOUND_NOTSTARTED
;
316 m_lastcount
= PutData(buffer
, len
);
320 bool wxSoundFileStream::StartProduction(int evt
)
322 m_sndio
->SetEventHandler(this);
324 if (!m_codec
.StartProduction(evt
))
330 bool wxSoundFileStream::StopProduction()
332 return m_codec
.StopProduction();
335 void wxSoundFileStream::FinishPreparation(wxUint32 len
)
337 m_bytes_left
= m_length
= len
;
341 wxString
wxSoundFileStream::GetCodecName() const
343 return wxString(wxT("wxSoundFileStream base codec"));
346 wxUint32
wxSoundFileStream::GetLength()
348 if (m_input
&& !m_prepared
&& GetError() == wxSOUND_NOERROR
)
349 return (PrepareToPlay()) ? m_length
: 0;
354 wxUint32
wxSoundFileStream::GetPosition()
356 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
359 return m_length
-m_bytes_left
;
362 wxUint32
wxSoundFileStream::SetPosition(wxUint32 new_position
)
364 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
370 if (!RepositionStream(new_position
))
371 return m_length
-m_bytes_left
;
373 if (new_position
>= m_length
) {
378 m_bytes_left
= m_length
-new_position
;
382 void wxSoundFileStream::OnSoundEvent(int evt
)
384 wxUint32 len
= m_codec
.GetBestSize();
387 buffer
= new char[len
];
388 wxSoundStream::OnSoundEvent(evt
);
390 while (!m_sndio
->QueueFilled()) {
393 if (len
> m_bytes_left
)
396 len
= m_codec
.Read(buffer
, len
).GetLastAccess();
397 PutData(buffer
, len
);
399 if (m_bytes_left
== 0) {
406 if (len
> m_bytes_left
)
409 len
= GetData(buffer
, len
);
411 if (m_bytes_left
== 0) {
416 m_codec
.Write(buffer
, len
);
423 bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase
& format
)
425 wxSoundStream::SetSoundFormat(format
);
426 return m_codec
.SetSoundFormat(format
);