]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/mmedia/sndfile.cpp
1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999, 2000
7 // --------------------------------------------------------------------------
12 #include <wx/stream.h>
15 #include "wx/mmedia/sndbase.h"
16 #include "wx/mmedia/sndcodec.h"
17 #include "wx/mmedia/sndfile.h"
18 #include "wx/mmedia/sndcpcm.h"
19 #include "wx/mmedia/sndulaw.h"
20 #include "wx/mmedia/sndg72x.h"
22 // --------------------------------------------------------------------------
24 // A very important class: it ensures that everybody is satisfied.
25 // It is supposed to create as many codec as it is necessary to transform
26 // a signal in a specific format in an another.
27 // --------------------------------------------------------------------------
28 wxSoundRouterStream::wxSoundRouterStream(wxSoundStream
& sndio
)
29 : wxSoundStreamCodec(sndio
)
34 wxSoundRouterStream::~wxSoundRouterStream()
40 // --------------------------------------------------------------------------
41 // Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
42 // for possible errors and behaviours ...
43 // --------------------------------------------------------------------------
44 wxSoundStream
& wxSoundRouterStream::Read(void *buffer
, wxUint32 len
)
47 m_router
->Read(buffer
, len
);
48 m_snderror
= m_router
->GetError();
49 m_lastcount
= m_router
->GetLastAccess();
51 m_sndio
->Read(buffer
, len
);
52 m_snderror
= m_sndio
->GetError();
53 m_lastcount
= m_sndio
->GetLastAccess();
58 // --------------------------------------------------------------------------
59 // Write(const void *buffer, wxUint32 len): It writes data synchronously
60 // --------------------------------------------------------------------------
61 wxSoundStream
& wxSoundRouterStream::Write(const void *buffer
, wxUint32 len
)
64 m_router
->Write(buffer
, len
);
65 m_snderror
= m_router
->GetError();
66 m_lastcount
= m_router
->GetLastAccess();
68 m_sndio
->Write(buffer
, len
);
69 m_snderror
= m_sndio
->GetError();
70 m_lastcount
= m_sndio
->GetLastAccess();
75 // --------------------------------------------------------------------------
76 // SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
77 // sound driver using the specified format. If this fails, it uses personnal
78 // codec converters: for the moment there is a PCM converter (PCM to PCM:
79 // with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
80 // converter (G72X to PCM). If nothing works, it returns FALSE.
81 // --------------------------------------------------------------------------
82 bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase
& format
)
87 // First, we try to setup the sound device
88 if (m_sndio
->SetSoundFormat(format
)) {
89 // We are lucky, it is working.
90 wxSoundStream::SetSoundFormat(m_sndio
->GetSoundFormat());
94 switch(format
.GetType()) {
95 case wxSOUND_NOFORMAT
:
98 m_router
= new wxSoundStreamPcm(*m_sndio
);
99 m_router
->SetSoundFormat(format
);
102 m_router
= new wxSoundStreamUlaw(*m_sndio
);
103 m_router
->SetSoundFormat(format
);
106 m_router
= new wxSoundStreamG72X(*m_sndio
);
107 m_router
->SetSoundFormat(format
);
113 wxSoundStream::SetSoundFormat(m_router
->GetSoundFormat());
117 // --------------------------------------------------------------------------
118 // GetBestSize() returns the specific best buffer size a sound driver
119 // can manage. It means that it will be easier for it to manage the buffer
120 // and so it will be faster and in some case more accurate for real-time event.
121 // --------------------------------------------------------------------------
122 wxUint32
wxSoundRouterStream::GetBestSize() const
125 return m_router
->GetBestSize();
127 return m_sndio
->GetBestSize();
130 // --------------------------------------------------------------------------
131 // StartProduction(int evt). See sndbase.h
132 // --------------------------------------------------------------------------
133 bool wxSoundRouterStream::StartProduction(int evt
)
136 if (m_sndio
->StartProduction(evt
))
139 m_snderror
= m_sndio
->GetError();
140 m_lastcount
= m_sndio
->GetLastAccess();
144 if (m_router
->StartProduction(evt
))
147 m_snderror
= m_router
->GetError();
148 m_lastcount
= m_router
->GetLastAccess();
152 // --------------------------------------------------------------------------
153 // StopProduction(). See sndbase.h
154 // --------------------------------------------------------------------------
155 bool wxSoundRouterStream::StopProduction()
158 if (m_sndio
->StopProduction())
161 m_snderror
= m_sndio
->GetError();
162 m_lastcount
= m_sndio
->GetLastAccess();
166 if (m_router
->StopProduction())
169 m_snderror
= m_router
->GetError();
170 m_lastcount
= m_router
->GetLastAccess();
174 // --------------------------------------------------------------------------
175 // wxSoundFileStream: generic reader
176 // --------------------------------------------------------------------------
178 wxSoundFileStream::wxSoundFileStream(wxInputStream
& stream
,
179 wxSoundStream
& io_sound
)
180 : m_codec(io_sound
), m_sndio(&io_sound
),
181 m_input(&stream
), m_output(NULL
), m_state(wxSOUND_FILE_STOPPED
)
188 wxSoundFileStream::wxSoundFileStream(wxOutputStream
& stream
,
189 wxSoundStream
& io_sound
)
190 : m_codec(io_sound
), m_sndio(&io_sound
),
191 m_input(NULL
), m_output(&stream
), m_state(wxSOUND_FILE_STOPPED
)
198 wxSoundFileStream::~wxSoundFileStream()
200 if (m_state
!= wxSOUND_FILE_STOPPED
)
204 bool wxSoundFileStream::Play()
206 if (m_state
!= wxSOUND_FILE_STOPPED
)
210 if (!PrepareToPlay())
213 m_state
= wxSOUND_FILE_PLAYING
;
215 if (!StartProduction(wxSOUND_OUTPUT
))
221 bool wxSoundFileStream::Record(wxUint32 time
)
223 if (m_state
!= wxSOUND_FILE_STOPPED
)
226 if (!PrepareToRecord(time
))
229 FinishPreparation(m_sndformat
->GetBytesFromTime(time
));
231 m_state
= wxSOUND_FILE_RECORDING
;
232 if (!StartProduction(wxSOUND_INPUT
))
238 bool wxSoundFileStream::Stop()
240 if (m_state
== wxSOUND_FILE_STOPPED
)
243 if (!StopProduction())
248 if (m_state
== wxSOUND_FILE_RECORDING
)
249 if (!FinishRecording()) {
250 m_state
= wxSOUND_FILE_STOPPED
;
255 m_input
->SeekI(0, wxFromStart
);
258 m_output
->SeekO(0, wxFromStart
);
260 m_state
= wxSOUND_FILE_STOPPED
;
264 bool wxSoundFileStream::Pause()
266 if (m_state
== wxSOUND_FILE_PAUSED
|| m_state
== wxSOUND_FILE_STOPPED
)
269 if (!StopProduction())
272 m_oldstate
= m_state
;
273 m_state
= wxSOUND_FILE_PAUSED
;
277 bool wxSoundFileStream::Resume()
279 if (m_state
== wxSOUND_FILE_PLAYING
|| m_state
== wxSOUND_FILE_RECORDING
||
280 m_state
== wxSOUND_FILE_STOPPED
)
283 if (!StartProduction( (m_oldstate
== wxSOUND_FILE_PLAYING
) ?
284 wxSOUND_OUTPUT
: wxSOUND_INPUT
))
287 m_state
= m_oldstate
;
292 wxSoundStream
& wxSoundFileStream::Read(void *buffer
, wxUint32 len
)
294 if (!m_prepared
|| m_state
!= wxSOUND_FILE_PLAYING
) {
295 m_snderror
= wxSOUND_NOTSTARTED
;
299 m_lastcount
= GetData(buffer
, len
);
303 wxSoundStream
& wxSoundFileStream::Write(const void *buffer
, wxUint32 len
)
305 if (!m_prepared
|| m_state
!= wxSOUND_FILE_RECORDING
) {
306 m_snderror
= wxSOUND_NOTSTARTED
;
310 m_lastcount
= PutData(buffer
, len
);
314 bool wxSoundFileStream::StartProduction(int evt
)
316 m_sndio
->SetEventHandler(this);
318 if (!m_codec
.StartProduction(evt
))
324 bool wxSoundFileStream::StopProduction()
326 return m_codec
.StopProduction();
329 void wxSoundFileStream::FinishPreparation(wxUint32 len
)
331 m_bytes_left
= m_length
= len
;
335 wxString
wxSoundFileStream::GetCodecName() const
337 return wxString(wxT("wxSoundFileStream base codec"));
340 wxUint32
wxSoundFileStream::GetLength()
342 if (m_input
&& !m_prepared
&& GetError() == wxSOUND_NOERROR
)
343 return (PrepareToPlay()) ? m_length
: 0;
348 wxUint32
wxSoundFileStream::GetPosition()
350 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
353 return m_length
-m_bytes_left
;
356 wxUint32
wxSoundFileStream::SetPosition(wxUint32 new_position
)
358 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
364 if (!RepositionStream(new_position
))
365 return m_length
-m_bytes_left
;
367 if (new_position
>= m_length
) {
372 m_bytes_left
= m_length
-new_position
;
376 void wxSoundFileStream::OnSoundEvent(int evt
)
378 wxUint32 len
= m_codec
.GetBestSize();
381 buffer
= new char[len
];
382 wxSoundStream::OnSoundEvent(evt
);
384 while (!m_sndio
->QueueFilled()) {
387 if (len
> m_bytes_left
)
390 len
= m_codec
.Read(buffer
, len
).GetLastAccess();
391 PutData(buffer
, len
);
393 if (m_bytes_left
== 0) {
400 if (len
> m_bytes_left
)
403 len
= GetData(buffer
, len
);
405 if (m_bytes_left
== 0) {
410 m_codec
.Write(buffer
, len
);
417 bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase
& format
)
419 wxSoundStream::SetSoundFormat(format
);
420 return m_codec
.SetSoundFormat(format
);