1 ////////////////////////////////////////////////////////////////////////////////
4 // Author: Guilhem Lavaux
7 // Copyright: (C) 1997, 1998, Guilhem Lavaux
8 // License: wxWindows license
9 ////////////////////////////////////////////////////////////////////////////////
11 #pragma implementation "sndfile.h"
17 #include <wx/wxprec.h>
21 #include <wx/module.h>
28 wxSndFileCodec::wxSndFileCodec()
29 : wxMMediaFile(), wxSndBuffer(),
30 m_fstate(wxSFILE_STOPPED
)
34 wxSndFileCodec::wxSndFileCodec(wxOutputStream
& s
, bool seekable
)
35 : wxMMediaFile(s
, seekable
),
37 m_fstate(wxSFILE_STOPPED
)
41 wxSndFileCodec::wxSndFileCodec(wxInputStream
& s
, bool preload
, bool seekable
)
42 : wxMMediaFile(s
, preload
, seekable
),
44 m_fstate(wxSFILE_STOPPED
)
48 wxSndFileCodec::wxSndFileCodec(const wxString
& fname
)
49 : wxMMediaFile(fname
), wxSndBuffer(),
50 m_fstate(wxSFILE_STOPPED
)
54 wxSndFileCodec::~wxSndFileCodec()
58 void wxSndFileCodec::Play(wxSound
& snd
)
60 if (m_fstate
!= wxSFILE_STOPPED
|| IsSet(wxSND_BUFLOCKED
))
63 if (!(m_fsize
= PrepareToPlay()))
67 m_fstate
= wxSFILE_PLAYING
;
69 Set(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
70 snd
.QueueBuffer(*this);
73 void wxSndFileCodec::Stop(wxSound
& snd
)
75 if (m_fstate
== wxSFILE_STOPPED
)
78 snd
.UnqueueBuffer(*this);
79 Clear(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
80 m_fstate
= wxSFILE_STOPPED
;
83 void wxSndFileCodec::Record(wxSound
& snd
,
84 const wxSoundDataFormat
& format
,
89 if (m_fstate
!= wxSFILE_STOPPED
)
93 byterate
= m_sndformat
.GetCodec()->GetByteRate();
95 m_fsize
= seconds
*byterate
;
96 if (!PrepareToRecord(m_fsize
))
98 if (IsSet(wxSND_BUFLOCKED
))
101 wxUint32 sec1
= m_fsize
/ byterate
,
104 m_sndtime
.hours
= sec1
/ 3600;
105 m_sndtime
.minutes
= sec2
/ 60;
106 m_sndtime
.seconds
= sec2
% 60;
108 m_fdone
= m_fpos
= 0;
109 m_fstate
= wxSFILE_RECORDING
;
111 m_sndmode
= wxSND_INPUT
;
113 Set(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
114 snd
.QueueBuffer(*this);
117 void wxSndFileCodec::OnNeedOutputData(char *data
, wxUint32
& size
)
119 wxUint32 datas_left
= m_fsize
-m_fpos
;
121 if (m_fstate
!= wxSFILE_PLAYING
) {
129 m_fstate
= wxSFILE_STOPPED
;
130 Clear(wxSND_KEEPQUEUED
);
134 if (size
> datas_left
)
137 if (!OnNeedData(data
, size
)) {
140 m_fstate
= wxSFILE_STOPPED
;
141 Clear(wxSND_KEEPQUEUED
);
148 void wxSndFileCodec::OnBufferInFinished(char *iobuf
, wxUint32
& size
)
150 wxUint32 datas_left
= m_fsize
-m_fdone
;
152 if (m_fstate
!= wxSFILE_RECORDING
) {
159 Clear(wxSND_KEEPQUEUED
); // To be sure.
163 if (size
> datas_left
)
166 OnWriteData(iobuf
, size
);
170 wxMMtime
wxSndFileCodec::GetPosition()
176 byterate
= m_sndformat
.GetCodec()->GetByteRate();
178 if (m_fpos
&& byterate
) {
179 sec1
= m_fpos
/ byterate
;
181 mm_time
.hours
= sec1
/ 3600;
182 mm_time
.minutes
= sec2
/ 60;
183 mm_time
.seconds
= sec2
% 60;
193 wxMMtime
wxSndFileCodec::GetLength()
195 if (m_sndtime
.hours
== -1 && m_istream
)
201 bool wxSndFileCodec::TranslateBuffer(wxSndBuffer
& buf
)
203 #define TMP_BUFSIZE 10240
206 wxStreamBuffer
*tmp_buf
;
207 wxSoundCodec
*codec_in
, *codec_out
;
208 wxSoundDataFormat std_format
;
210 if (!m_ostream
|| !buf
.RestartBuffer(wxSND_OUTPUT
))
213 m_sndformat
= buf
.GetFormat();
214 codec_in
= buf
.GetCurrentCodec();
218 if (!PrepareToRecord(m_fsize
))
221 codec_out
= GetCurrentCodec();
222 m_fsize
= (int)(((float)buf
.GetSize() / codec_in
->GetByteRate()) *
223 codec_out
->GetByteRate());
225 if (!PrepareToRecord(m_fsize
))
228 codec_out
= GetCurrentCodec();
229 codec_in
->InitIO(m_sndformat
);
230 codec_out
->InitIO(m_sndformat
);
232 tmp_buf
= new wxStreamBuffer(wxStreamBuffer::read_write
);
233 tmp_buf
->Fixed(TRUE
);
234 tmp_buf
->Flushable(FALSE
);
235 tmp_buf
->SetBufferIO(TMP_BUFSIZE
);
237 m_fstate
= wxSFILE_RECORDING
;
239 while (m_fdone
< m_fsize
) {
240 tmp_buf
->ResetBuffer();
241 codec_in
->SetOutStream(tmp_buf
);
244 tmp_buf
->ResetBuffer();
245 codec_out
->SetInStream(tmp_buf
);
248 buf
.OnBufferOutFinished();
252 m_fstate
= wxSFILE_STOPPED
;
257 bool wxSndFileCodec::RestartBuffer(wxSndMode mode
)
259 if (IsSet(wxSND_BUFLOCKED
))
265 if (mode
== wxSND_OUTPUT
&& m_istream
) {
266 m_fsize
= PrepareToPlay();
267 m_fstate
= wxSFILE_PLAYING
;
270 if (mode
== wxSND_INPUT
&& m_ostream
) {
272 m_fstate
= wxSFILE_RECORDING
;
279 wxUint32
wxSndFileCodec::GetSize() const
284 wxUint32
wxSndFileCodec::Available() const
286 if (m_fstate
== wxSFILE_STOPPED
)
288 return m_fsize
-m_fpos
;
294 static wxSoundDevice
*dev_snd
= NULL
;
296 bool wxSndFileCodec::StartPlay()
299 dev_snd
= new wxSoundDevice
;
306 void wxSndFileCodec::StopPlay()
315 class wxSoundModule
: public wxModule
{
316 DECLARE_DYNAMIC_CLASS(wxSoundModule
)
318 virtual bool OnInit() { return TRUE
; }
319 virtual void OnExit() {
325 IMPLEMENT_DYNAMIC_CLASS(wxSoundModule
, wxModule
)