]>
git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia2/lib/sndfile.cpp
1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
7 // --------------------------------------------------------------------------
11 #include <wx/stream.h>
21 // --------------------------------------------------------------------------
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.
26 // --------------------------------------------------------------------------
27 wxSoundRouterStream::wxSoundRouterStream(wxSoundStream
& sndio
)
28 : wxSoundStreamCodec(sndio
)
33 wxSoundRouterStream::~wxSoundRouterStream()
39 // --------------------------------------------------------------------------
40 // Read(void *buffer, wxUint32 len): It reads data synchronously. See sndbase.h
41 // for possible errors and behaviours ...
42 // --------------------------------------------------------------------------
43 wxSoundStream
& wxSoundRouterStream::Read(void *buffer
, wxUint32 len
)
46 m_router
->Read(buffer
, len
);
47 m_snderror
= m_router
->GetError();
48 m_lastcount
= m_router
->GetLastAccess();
50 m_sndio
->Read(buffer
, len
);
51 m_snderror
= m_sndio
->GetError();
52 m_lastcount
= m_sndio
->GetLastAccess();
57 // --------------------------------------------------------------------------
58 // Write(const void *buffer, wxUint32 len): It writes data synchronously
59 // --------------------------------------------------------------------------
60 wxSoundStream
& wxSoundRouterStream::Write(const void *buffer
, wxUint32 len
)
63 m_router
->Write(buffer
, len
);
64 m_snderror
= m_router
->GetError();
65 m_lastcount
= m_router
->GetLastAccess();
67 m_sndio
->Write(buffer
, len
);
68 m_snderror
= m_sndio
->GetError();
69 m_lastcount
= m_sndio
->GetLastAccess();
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 // --------------------------------------------------------------------------
81 bool wxSoundRouterStream::SetSoundFormat(const wxSoundFormatBase
& format
)
86 if (m_sndio
->SetSoundFormat(format
)) {
87 wxSoundStream::SetSoundFormat(m_sndio
->GetSoundFormat());
91 switch(format
.GetType()) {
92 case wxSOUND_NOFORMAT
:
95 m_router
= new wxSoundStreamPcm(*m_sndio
);
96 m_router
->SetSoundFormat(format
);
99 m_router
= new wxSoundStreamUlaw(*m_sndio
);
100 m_router
->SetSoundFormat(format
);
103 m_router
= new wxSoundStreamG72X(*m_sndio
);
104 m_router
->SetSoundFormat(format
);
107 wxSoundStream::SetSoundFormat(m_router
->GetSoundFormat());
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 // --------------------------------------------------------------------------
116 wxUint32
wxSoundRouterStream::GetBestSize() const
119 return m_router
->GetBestSize();
121 return m_sndio
->GetBestSize();
124 // --------------------------------------------------------------------------
125 // StartProduction(int evt). See sndbase.h
126 // --------------------------------------------------------------------------
127 bool wxSoundRouterStream::StartProduction(int evt
)
130 if (m_sndio
->StartProduction(evt
))
133 m_snderror
= m_sndio
->GetError();
134 m_lastcount
= m_sndio
->GetLastAccess();
138 if (m_router
->StartProduction(evt
))
141 m_snderror
= m_router
->GetError();
142 m_lastcount
= m_router
->GetLastAccess();
146 // --------------------------------------------------------------------------
147 // StopProduction(). See sndbase.h
148 // --------------------------------------------------------------------------
149 bool wxSoundRouterStream::StopProduction()
152 if (m_sndio
->StopProduction())
155 m_snderror
= m_sndio
->GetError();
156 m_lastcount
= m_sndio
->GetLastAccess();
160 if (m_router
->StopProduction())
163 m_snderror
= m_router
->GetError();
164 m_lastcount
= m_router
->GetLastAccess();
169 // --------------------------------------------------------------------------
170 // wxSoundFileStream: generic reader
171 // --------------------------------------------------------------------------
173 wxSoundFileStream::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
)
183 wxSoundFileStream::wxSoundFileStream(wxOutputStream
& stream
,
184 wxSoundStream
& io_sound
)
185 : m_codec(io_sound
), m_sndio(&io_sound
),
186 m_input(NULL
), m_output(&stream
), m_state(wxSOUND_FILE_STOPPED
)
193 wxSoundFileStream::~wxSoundFileStream()
195 if (m_state
!= wxSOUND_FILE_STOPPED
)
199 bool wxSoundFileStream::Play()
201 if (m_state
!= wxSOUND_FILE_STOPPED
)
205 if (!PrepareToPlay())
208 m_state
= wxSOUND_FILE_PLAYING
;
210 if (!StartProduction(wxSOUND_OUTPUT
))
216 bool wxSoundFileStream::Record(unsigned long time
)
218 if (m_state
!= wxSOUND_FILE_STOPPED
)
221 if (!PrepareToRecord(time
))
224 FinishPreparation(m_sndformat
->GetBytesFromTime(time
));
226 m_state
= wxSOUND_FILE_RECORDING
;
227 if (!StartProduction(wxSOUND_INPUT
))
233 bool wxSoundFileStream::Stop()
235 if (m_state
== wxSOUND_FILE_STOPPED
)
238 if (!StopProduction())
243 if (m_state
== wxSOUND_FILE_RECORDING
)
244 if (!FinishRecording()) {
245 m_state
= wxSOUND_FILE_STOPPED
;
250 m_input
->SeekI(0, wxFromStart
);
253 m_output
->SeekO(0, wxFromStart
);
255 m_state
= wxSOUND_FILE_STOPPED
;
259 bool wxSoundFileStream::Pause()
261 if (m_state
== wxSOUND_FILE_PAUSED
|| m_state
== wxSOUND_FILE_STOPPED
)
264 if (!StopProduction())
267 m_oldstate
= m_state
;
268 m_state
= wxSOUND_FILE_PAUSED
;
272 bool wxSoundFileStream::Resume()
274 if (m_state
== wxSOUND_FILE_PLAYING
|| m_state
== wxSOUND_FILE_RECORDING
||
275 m_state
== wxSOUND_FILE_STOPPED
)
278 if (!StartProduction( (m_oldstate
== wxSOUND_FILE_PLAYING
) ?
279 wxSOUND_OUTPUT
: wxSOUND_INPUT
))
282 m_state
= m_oldstate
;
287 wxSoundStream
& wxSoundFileStream::Read(void *buffer
, wxUint32 len
)
289 m_lastcount
= GetData(buffer
, len
);
293 wxSoundStream
& wxSoundFileStream::Write(const void *buffer
, wxUint32 len
)
295 m_lastcount
= PutData(buffer
, len
);
299 void wxSoundFileStream::SetDuplexMode(bool duplex
)
303 bool wxSoundFileStream::StartProduction(int evt
)
305 m_sndio
->SetEventHandler(this);
307 if (!m_codec
.StartProduction(evt
))
313 bool wxSoundFileStream::StopProduction()
315 return m_codec
.StopProduction();
318 void wxSoundFileStream::FinishPreparation(wxUint32 len
)
320 m_bytes_left
= m_length
= len
;
324 wxUint32
wxSoundFileStream::GetLength()
326 if (m_input
&& !m_prepared
&& GetError() == wxSOUND_NOERR
)
327 return (PrepareToPlay()) ? m_length
: 0;
332 wxUint32
wxSoundFileStream::GetPosition()
334 if (!m_prepared
&& m_input
!= NULL
&& GetError() == wxSOUND_NOERR
)
337 return m_length
-m_bytes_left
;
340 void wxSoundFileStream::OnSoundEvent(int evt
)
342 wxUint32 len
= m_codec
.GetBestSize();
345 buffer
= new char[len
];
346 wxSoundStream::OnSoundEvent(evt
);
348 while (!m_sndio
->QueueFilled()) {
351 if (len
> m_bytes_left
)
354 len
= m_codec
.Read(buffer
, len
).GetLastAccess();
355 PutData(buffer
, len
);
357 if (m_bytes_left
== 0) {
364 if (len
> m_bytes_left
)
367 len
= GetData(buffer
, len
);
369 if (m_bytes_left
== 0) {
374 m_codec
.Write(buffer
, len
);
381 bool wxSoundFileStream::SetSoundFormat(const wxSoundFormatBase
& format
)
383 wxSoundStream::SetSoundFormat(format
);
384 return m_codec
.SetSoundFormat(format
);