]>
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"
21 #include "wx/mmedia/sndmsad.h"
23 // --------------------------------------------------------------------------
25 // A very important class: it ensures that everybody is satisfied.
26 // It is supposed to create as many codec as it is necessary to transform
27 // a signal in a specific format in an another.
28 // --------------------------------------------------------------------------
29 wxSoundRouterStream::wxSoundRouterStream(wxSoundStream
& sndio
)
30 : wxSoundStreamCodec(sndio
)
35 wxSoundRouterStream::~wxSoundRouterStream()
41 // --------------------------------------------------------------------------
42 // Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
43 // for possible errors and behaviours ...
44 // --------------------------------------------------------------------------
45 wxSoundStream
& wxSoundRouterStream::Read(void *buffer
, wxUint32 len
)
48 m_router
->Read(buffer
, len
);
49 m_snderror
= m_router
->GetError();
50 m_lastcount
= m_router
->GetLastAccess();
52 m_sndio
->Read(buffer
, len
);
53 m_snderror
= m_sndio
->GetError();
54 m_lastcount
= m_sndio
->GetLastAccess();
59 // --------------------------------------------------------------------------
60 // Write(const void *buffer, wxUint32 len): It writes data synchronously
61 // --------------------------------------------------------------------------
62 wxSoundStream
& wxSoundRouterStream::Write(const void *buffer
, wxUint32 len
)
65 m_router
->Write(buffer
, len
);
66 m_snderror
= m_router
->GetError();
67 m_lastcount
= m_router
->GetLastAccess();
69 m_sndio
->Write(buffer
, len
);
70 m_snderror
= m_sndio
->GetError();
71 m_lastcount
= m_sndio
->GetLastAccess();
76 // --------------------------------------------------------------------------
77 // SetSoundFormat(const wxSoundFormatBase& format) first tries to setup the
78 // sound driver using the specified format. If this fails, it uses personnal
79 // codec converters: for the moment there is a PCM converter (PCM to PCM:
80 // with optional resampling, ...), an ULAW converter (ULAW to PCM), a G72X
81 // converter (G72X to PCM). If nothing works, it returns false.
82 // --------------------------------------------------------------------------
83 bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase
& format
)
88 // First, we try to setup the sound device
89 if (m_sndio
->SetSoundFormat(format
)) {
90 // We are lucky, it is working.
91 wxSoundStream::SetSoundFormat(m_sndio
->GetSoundFormat());
95 switch(format
.GetType()) {
96 case wxSOUND_NOFORMAT
:
99 m_router
= new wxSoundStreamPcm(*m_sndio
);
100 m_router
->SetSoundFormat(format
);
103 m_router
= new wxSoundStreamUlaw(*m_sndio
);
104 m_router
->SetSoundFormat(format
);
107 m_router
= new wxSoundStreamG72X(*m_sndio
);
108 m_router
->SetSoundFormat(format
);
110 case wxSOUND_MSADPCM
:
111 m_router
= new wxSoundStreamMSAdpcm(*m_sndio
);
112 m_router
->SetSoundFormat(format
);
118 wxSoundStream::SetSoundFormat(m_router
->GetSoundFormat());
122 // --------------------------------------------------------------------------
123 // GetBestSize() returns the specific best buffer size a sound driver
124 // can manage. It means that it will be easier for it to manage the buffer
125 // and so it will be faster and in some case more accurate for real-time event.
126 // --------------------------------------------------------------------------
127 wxUint32
wxSoundRouterStream::GetBestSize() const
130 return m_router
->GetBestSize();
132 return m_sndio
->GetBestSize();
135 // --------------------------------------------------------------------------
136 // StartProduction(int evt). See sndbase.h
137 // --------------------------------------------------------------------------
138 bool wxSoundRouterStream::StartProduction(int evt
)
141 if (m_sndio
->StartProduction(evt
))
144 m_snderror
= m_sndio
->GetError();
145 m_lastcount
= m_sndio
->GetLastAccess();
149 if (m_router
->StartProduction(evt
))
152 m_snderror
= m_router
->GetError();
153 m_lastcount
= m_router
->GetLastAccess();
157 // --------------------------------------------------------------------------
158 // StopProduction(). See sndbase.h
159 // --------------------------------------------------------------------------
160 bool wxSoundRouterStream::StopProduction()
163 if (m_sndio
->StopProduction())
166 m_snderror
= m_sndio
->GetError();
167 m_lastcount
= m_sndio
->GetLastAccess();
171 if (m_router
->StopProduction())
174 m_snderror
= m_router
->GetError();
175 m_lastcount
= m_router
->GetLastAccess();
179 // --------------------------------------------------------------------------
180 // wxSoundFileStream: generic reader
181 // --------------------------------------------------------------------------
183 wxSoundFileStream::wxSoundFileStream(wxInputStream
& stream
,
184 wxSoundStream
& io_sound
)
185 : m_codec(io_sound
), m_sndio(&io_sound
),
186 m_input(&stream
), m_output(NULL
), m_state(wxSOUND_FILE_STOPPED
)
193 wxSoundFileStream::wxSoundFileStream(wxOutputStream
& stream
,
194 wxSoundStream
& io_sound
)
195 : m_codec(io_sound
), m_sndio(&io_sound
),
196 m_input(NULL
), m_output(&stream
), m_state(wxSOUND_FILE_STOPPED
)
203 wxSoundFileStream::~wxSoundFileStream()
205 if (m_state
!= wxSOUND_FILE_STOPPED
)
209 bool wxSoundFileStream::Play()
211 if (m_state
!= wxSOUND_FILE_STOPPED
)
215 if (!PrepareToPlay())
218 m_state
= wxSOUND_FILE_PLAYING
;
220 if (!StartProduction(wxSOUND_OUTPUT
))
226 bool wxSoundFileStream::Record(wxUint32 time
)
228 if (m_state
!= wxSOUND_FILE_STOPPED
)
231 if (!PrepareToRecord(time
))
234 FinishPreparation(m_sndformat
->GetBytesFromTime(time
));
236 m_state
= wxSOUND_FILE_RECORDING
;
237 if (!StartProduction(wxSOUND_INPUT
))
243 bool wxSoundFileStream::Stop()
245 if (m_state
== wxSOUND_FILE_STOPPED
)
248 if (!StopProduction())
253 if (m_state
== wxSOUND_FILE_RECORDING
)
254 if (!FinishRecording()) {
255 m_state
= wxSOUND_FILE_STOPPED
;
260 m_input
->SeekI(0, wxFromStart
);
263 m_output
->SeekO(0, wxFromStart
);
265 m_state
= wxSOUND_FILE_STOPPED
;
269 bool wxSoundFileStream::Pause()
271 if (m_state
== wxSOUND_FILE_PAUSED
|| m_state
== wxSOUND_FILE_STOPPED
)
274 if (!StopProduction())
277 m_oldstate
= m_state
;
278 m_state
= wxSOUND_FILE_PAUSED
;
282 bool wxSoundFileStream::Resume()
284 if (m_state
== wxSOUND_FILE_PLAYING
|| m_state
== wxSOUND_FILE_RECORDING
||
285 m_state
== wxSOUND_FILE_STOPPED
)
288 if (!StartProduction( (m_oldstate
== wxSOUND_FILE_PLAYING
) ?
289 wxSOUND_OUTPUT
: wxSOUND_INPUT
))
292 m_state
= m_oldstate
;
297 wxSoundStream
& wxSoundFileStream::Read(void *buffer
, wxUint32 len
)
299 if (!m_prepared
|| m_state
!= wxSOUND_FILE_PLAYING
) {
300 m_snderror
= wxSOUND_NOTSTARTED
;
304 m_lastcount
= GetData(buffer
, len
);
308 wxSoundStream
& wxSoundFileStream::Write(const void *buffer
, wxUint32 len
)
310 if (!m_prepared
|| m_state
!= wxSOUND_FILE_RECORDING
) {
311 m_snderror
= wxSOUND_NOTSTARTED
;
315 m_lastcount
= PutData(buffer
, len
);
319 bool wxSoundFileStream::StartProduction(int evt
)
321 m_sndio
->SetEventHandler(this);
323 if (!m_codec
.StartProduction(evt
))
329 bool wxSoundFileStream::StopProduction()
331 return m_codec
.StopProduction();
334 void wxSoundFileStream::FinishPreparation(wxUint32 len
)
336 m_bytes_left
= m_length
= len
;
340 wxString
wxSoundFileStream::GetCodecName() const
342 return wxString(wxT("wxSoundFileStream base codec"));
345 wxUint32
wxSoundFileStream::GetLength()
347 if (m_input
&& !m_prepared
&& GetError() == wxSOUND_NOERROR
)
348 return (PrepareToPlay()) ? m_length
: 0;
353 wxUint32
wxSoundFileStream::GetPosition()
355 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
358 return m_length
-m_bytes_left
;
361 wxUint32
wxSoundFileStream::SetPosition(wxUint32 new_position
)
363 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERROR
)
369 if (!RepositionStream(new_position
))
370 return m_length
-m_bytes_left
;
372 if (new_position
>= m_length
) {
377 m_bytes_left
= m_length
-new_position
;
381 void wxSoundFileStream::OnSoundEvent(int evt
)
383 wxUint32 len
= m_codec
.GetBestSize();
386 buffer
= new char[len
];
387 wxSoundStream::OnSoundEvent(evt
);
389 while (!m_sndio
->QueueFilled()) {
392 if (len
> m_bytes_left
)
395 len
= m_codec
.Read(buffer
, len
).GetLastAccess();
396 PutData(buffer
, len
);
398 if (m_bytes_left
== 0) {
405 if (len
> m_bytes_left
)
408 len
= GetData(buffer
, len
);
410 if (m_bytes_left
== 0) {
415 m_codec
.Write(buffer
, len
);
422 bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase
& format
)
424 wxSoundStream::SetSoundFormat(format
);
425 return m_codec
.SetSoundFormat(format
);