1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
8 // --------------------------------------------------------------------------
10 #pragma implementation "sndaiff.cpp"
13 #include "wx/wxprec.h"
23 #include "wx/stream.h"
24 #include "wx/datstrm.h"
25 #include "wx/filefn.h"
27 #include "wx/mmedia/sndbase.h"
28 #include "wx/mmedia/sndcodec.h"
29 #include "wx/mmedia/sndfile.h"
30 #include "wx/mmedia/sndpcm.h"
31 #include "wx/mmedia/sndaiff.h"
33 #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
35 #define FORM_SIGNATURE BUILD_SIGNATURE('F','O','R','M')
36 #define AIFF_SIGNATURE BUILD_SIGNATURE('A','I','F','F')
37 #define AIFC_SIGNATURE BUILD_SIGNATURE('A','I','F','C')
38 #define COMM_SIGNATURE BUILD_SIGNATURE('C','O','M','M')
39 #define SSND_SIGNATURE BUILD_SIGNATURE('S','S','N','D')
41 wxSoundAiff::wxSoundAiff(wxInputStream
& stream
, wxSoundStream
& io_sound
)
42 : wxSoundFileStream(stream
, io_sound
)
44 m_base_offset
= wxInvalidOffset
;
47 wxSoundAiff::wxSoundAiff(wxOutputStream
& stream
, wxSoundStream
& io_sound
)
48 : wxSoundFileStream(stream
, io_sound
)
50 m_base_offset
= wxInvalidOffset
;
53 wxSoundAiff::~wxSoundAiff()
57 wxString
wxSoundAiff::GetCodecName() const
59 return wxT("wxSoundAiff codec");
62 bool wxSoundAiff::CanRead()
64 wxUint32 signature1
, signature2
, len
;
66 if (m_input
->Read(&signature1
, 4).LastRead() != 4)
69 if (wxUINT32_SWAP_ON_BE(signature1
) != FORM_SIGNATURE
) {
70 m_input
->Ungetch(&signature1
, 4);
74 m_input
->Read(&len
, 4);
75 if (m_input
->LastRead() != 4) {
76 m_input
->Ungetch(&len
, m_input
->LastRead());
77 m_input
->Ungetch(&signature1
, 4);
81 if (m_input
->Read(&signature2
, 4).LastRead() != 4) {
82 m_input
->Ungetch(&signature2
, m_input
->LastRead());
83 m_input
->Ungetch(&len
, 4);
84 m_input
->Ungetch(&signature1
, 4);
88 m_input
->Ungetch(&signature2
, 4);
89 m_input
->Ungetch(&len
, 4);
90 m_input
->Ungetch(&signature1
, 4);
93 wxUINT32_SWAP_ON_BE(signature2
) != AIFF_SIGNATURE
&&
94 wxUINT32_SWAP_ON_BE(signature2
) != AIFC_SIGNATURE
)
100 #define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return false; }
102 bool wxSoundAiff::PrepareToPlay()
104 wxDataInputStream
data(*m_input
);
105 wxUint32 signature
, len
, ssnd
;
109 m_snderror
= wxSOUND_INVSTRM
;
112 m_snderror
= wxSOUND_NOERROR
;
114 data
.BigEndianOrdered(true);
116 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
117 FAIL_WITH(wxUINT32_SWAP_ON_BE(signature
) != FORM_SIGNATURE
, wxSOUND_INVSTRM
);
122 FAIL_WITH(m_input
->LastRead() != 4, wxSOUND_INVSTRM
);
125 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
127 wxUINT32_SWAP_ON_BE(signature
) != AIFF_SIGNATURE
&&
128 wxUINT32_SWAP_ON_BE(signature
) != AIFC_SIGNATURE
, wxSOUND_INVSTRM
);
132 while (!end_headers
) {
133 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
136 FAIL_WITH(m_input
->LastRead() != 4, wxSOUND_INVSTRM
);
138 switch (wxUINT32_SWAP_ON_BE(signature
)) {
139 case COMM_SIGNATURE
: { // "COMM"
140 wxUint16 channels
, bps
;
141 wxUint32 num_samples
;
143 wxSoundFormatPcm sndformat
;
145 // Get sound data informations
146 data
>> channels
>> num_samples
>> bps
>> srate
;
148 // Convert them in a wxSoundFormat object
149 sndformat
.SetSampleRate((wxUint32
) srate
);
150 sndformat
.SetBPS(bps
);
151 sndformat
.SetChannels(channels
);
152 sndformat
.Signed(false);
153 sndformat
.SetOrder(wxBIG_ENDIAN
);
155 if (!SetSoundFormat(sndformat
))
157 // We pass all data left
158 m_input
->SeekI(len
-18, wxFromCurrent
);
161 case SSND_SIGNATURE
: { // "SSND"
163 // m_input->SeekI(4, wxFromCurrent); // Pass an INT32
164 // m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
165 m_input
->SeekI(ssnd
+ 4, wxFromCurrent
);
166 m_base_offset
= m_input
->TellI();
167 // len-8 bytes of samples
168 FinishPreparation(len
- 8);
173 m_input
->SeekI(len
, wxFromCurrent
);
180 bool wxSoundAiff::PrepareToRecord(wxUint32
WXUNUSED(time
))
186 bool wxSoundAiff::FinishRecording()
192 bool wxSoundAiff::RepositionStream(wxUint32
WXUNUSED(position
))
194 // If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
195 if (m_base_offset
== wxInvalidOffset
)
197 m_input
->SeekI(m_base_offset
, wxFromStart
);
201 wxUint32
wxSoundAiff::GetData(void *buffer
, wxUint32 len
)
203 return m_input
->Read(buffer
, len
).LastRead();
206 wxUint32
wxSoundAiff::PutData(const void *buffer
, wxUint32 len
)
208 return m_output
->Write(buffer
, len
).LastWrite();