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_fstate
!= wxSFILE_PREPARED_TO_PLAY
)
64 if (!(m_fsize
= PrepareToPlay()))
68 m_fstate
= wxSFILE_PLAYING
;
70 Set(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
71 snd
.QueueBuffer(*this);
74 void wxSndFileCodec::Stop(wxSound
& snd
)
76 if (m_fstate
== wxSFILE_STOPPED
)
79 snd
.UnqueueBuffer(*this);
80 Clear(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
81 m_fstate
= wxSFILE_STOPPED
;
84 void wxSndFileCodec::Record(wxSound
& snd
,
85 const wxSoundDataFormat
& format
,
90 if (m_fstate
!= wxSFILE_STOPPED
)
94 byterate
= m_sndformat
.GetCodec()->GetByteRate();
96 m_fsize
= seconds
*byterate
;
97 if (!PrepareToRecord(m_fsize
))
99 if (IsSet(wxSND_BUFLOCKED
))
102 wxUint32 sec1
= m_fsize
/ byterate
,
105 m_sndtime
.hours
= sec1
/ 3600;
106 m_sndtime
.minutes
= sec2
/ 60;
107 m_sndtime
.seconds
= sec2
% 60;
109 m_fdone
= m_fpos
= 0;
110 m_fstate
= wxSFILE_RECORDING
;
112 m_sndmode
= wxSND_INPUT
;
114 Set(wxSND_BUFREADY
| wxSND_KEEPQUEUED
);
115 snd
.QueueBuffer(*this);
118 void wxSndFileCodec::OnNeedOutputData(char *data
, wxUint32
& size
)
120 wxUint32 datas_left
= m_fsize
-m_fpos
;
122 if (m_fstate
!= wxSFILE_PLAYING
) {
130 m_fstate
= wxSFILE_STOPPED
;
131 Clear(wxSND_KEEPQUEUED
);
135 if (size
> datas_left
)
138 if (!OnNeedData(data
, size
)) {
141 m_fstate
= wxSFILE_STOPPED
;
142 Clear(wxSND_KEEPQUEUED
);
149 void wxSndFileCodec::OnBufferInFinished(char *iobuf
, wxUint32
& size
)
151 wxUint32 datas_left
= m_fsize
-m_fdone
;
153 if (m_fstate
!= wxSFILE_RECORDING
) {
160 Clear(wxSND_KEEPQUEUED
); // To be sure.
164 if (size
> datas_left
)
167 OnWriteData(iobuf
, size
);
171 wxMMtime
wxSndFileCodec::GetPosition()
177 byterate
= m_sndformat
.GetCodec()->GetByteRate();
179 if (m_fpos
&& byterate
) {
180 sec1
= m_fpos
/ byterate
;
182 mm_time
.hours
= sec1
/ 3600;
183 mm_time
.minutes
= sec2
/ 60;
184 mm_time
.seconds
= sec2
% 60;
194 wxMMtime
wxSndFileCodec::GetLength()
196 if (m_sndtime
.hours
== -1 && m_istream
)
197 m_fsize
= PrepareToPlay();
202 bool wxSndFileCodec::TranslateBuffer(wxSndBuffer
& buf
)
204 #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
)