1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
7 // --------------------------------------------------------------------------
9 #pragma implementation "sndaiff.cpp"
12 #include <wx/wxprec.h>
14 #include <wx/stream.h>
15 #include <wx/datstrm.h>
16 #include <wx/filefn.h>
23 #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
25 #define FORM_SIGNATURE BUILD_SIGNATURE('F','O','R','M')
26 #define AIFF_SIGNATURE BUILD_SIGNATURE('A','I','F','F')
27 #define AIFC_SIGNATURE BUILD_SIGNATURE('A','I','F','C')
28 #define COMM_SIGNATURE BUILD_SIGNATURE('C','O','M','M')
29 #define SSND_SIGNATURE BUILD_SIGNATURE('S','S','N','D')
31 wxSoundAiff::wxSoundAiff(wxInputStream
& stream
, wxSoundStream
& io_sound
)
32 : wxSoundFileStream(stream
, io_sound
)
34 m_base_offset
= wxInvalidOffset
;
37 wxSoundAiff::wxSoundAiff(wxOutputStream
& stream
, wxSoundStream
& io_sound
)
38 : wxSoundFileStream(stream
, io_sound
)
40 m_base_offset
= wxInvalidOffset
;
43 wxSoundAiff::~wxSoundAiff()
47 wxString
wxSoundAiff::GetCodecName() const
49 return "wxSoundAiff codec";
52 bool wxSoundAiff::CanRead()
54 wxUint32 signature1
, signature2
, len
;
56 if (m_input
->Read(&signature1
, 4).LastRead() != 4)
59 if (wxUINT32_SWAP_ON_BE(signature1
) != FORM_SIGNATURE
) {
60 m_input
->Ungetch(&signature1
, 4);
64 m_input
->Read(&len
, 4);
65 if (m_input
->LastRead() != 4) {
66 m_input
->Ungetch(&len
, m_input
->LastRead());
67 m_input
->Ungetch(&signature1
, 4);
71 if (m_input
->Read(&signature2
, 4).LastRead() != 4) {
72 m_input
->Ungetch(&signature2
, m_input
->LastRead());
73 m_input
->Ungetch(&len
, 4);
74 m_input
->Ungetch(&signature1
, 4);
78 m_input
->Ungetch(&signature2
, 4);
79 m_input
->Ungetch(&len
, 4);
80 m_input
->Ungetch(&signature1
, 4);
83 wxUINT32_SWAP_ON_BE(signature2
) != AIFF_SIGNATURE
&&
84 wxUINT32_SWAP_ON_BE(signature2
) != AIFC_SIGNATURE
)
90 #define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return FALSE; }
92 bool wxSoundAiff::PrepareToPlay()
94 wxDataInputStream
data(*m_input
);
95 wxUint32 signature
, len
, ssnd
;
99 m_snderror
= wxSOUND_INVSTRM
;
102 m_snderror
= wxSOUND_NOERROR
;
104 data
.BigEndianOrdered(TRUE
);
106 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
107 FAIL_WITH(wxUINT32_SWAP_ON_BE(signature
) != FORM_SIGNATURE
, wxSOUND_INVSTRM
);
111 FAIL_WITH(m_input
->LastRead() != 4, wxSOUND_INVSTRM
);
114 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
116 wxUINT32_SWAP_ON_BE(signature
) != AIFF_SIGNATURE
&&
117 wxUINT32_SWAP_ON_BE(signature
) != AIFC_SIGNATURE
, wxSOUND_INVSTRM
);
121 while (!end_headers
) {
122 FAIL_WITH(m_input
->Read(&signature
, 4).LastRead() != 4, wxSOUND_INVSTRM
);
125 FAIL_WITH(m_input
->LastRead() != 4, wxSOUND_INVSTRM
);
127 switch (wxUINT32_SWAP_ON_BE(signature
)) {
128 case COMM_SIGNATURE
: { // "COMM"
129 wxUint16 channels
, bps
;
130 wxUint32 num_samples
;
132 wxSoundFormatPcm sndformat
;
134 // Get sound data informations
135 data
>> channels
>> num_samples
>> bps
>> srate
;
137 // Convert them in a wxSoundFormat object
138 sndformat
.SetSampleRate((wxUint32
) srate
);
139 sndformat
.SetBPS(bps
);
140 sndformat
.SetChannels(channels
);
141 sndformat
.Signed(FALSE
);
142 sndformat
.SetOrder(wxBIG_ENDIAN
);
144 if (!SetSoundFormat(sndformat
))
146 // We pass all data left
147 m_input
->SeekI(len
-18, wxFromCurrent
);
150 case SSND_SIGNATURE
: { // "SSND"
152 // m_input->SeekI(4, wxFromCurrent); // Pass an INT32
153 // m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
154 m_input
->SeekI(ssnd
+ 4, wxFromCurrent
);
155 m_base_offset
= m_input
->TellI();
156 // len-8 bytes of samples
157 FinishPreparation(len
- 8);
162 m_input
->SeekI(len
, wxFromCurrent
);
169 bool wxSoundAiff::PrepareToRecord(wxUint32 time
)
175 bool wxSoundAiff::FinishRecording()
181 bool wxSoundAiff::RepositionStream(wxUint32 position
)
183 // If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
184 if (m_base_offset
== wxInvalidOffset
)
186 m_input
->SeekI(m_base_offset
, wxFromStart
);
190 wxUint32
wxSoundAiff::GetData(void *buffer
, wxUint32 len
)
192 return m_input
->Read(buffer
, len
).LastRead();
195 wxUint32
wxSoundAiff::PutData(const void *buffer
, wxUint32 len
)
197 return m_output
->Write(buffer
, len
).LastWrite();