]> git.saurik.com Git - wxWidgets.git/blob - contrib/src/mmedia/sndaiff.cpp
wxVariant support for icon and bitmap should work regardless wxBitmapBase.
[wxWidgets.git] / contrib / src / mmedia / sndaiff.cpp
1 // --------------------------------------------------------------------------
2 // Name: sndaiff.cpp
3 // Purpose:
4 // Date: 08/11/1999
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6 // CVSID: $Id$
7 // wxWindows licence
8 // --------------------------------------------------------------------------
9
10 #include "wx/wxprec.h"
11
12 #ifndef WX_PRECOMP
13 #include "wx/defs.h"
14 #endif
15
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19
20 #include "wx/stream.h"
21 #include "wx/datstrm.h"
22 #include "wx/filefn.h"
23
24 #include "wx/mmedia/sndbase.h"
25 #include "wx/mmedia/sndcodec.h"
26 #include "wx/mmedia/sndfile.h"
27 #include "wx/mmedia/sndpcm.h"
28 #include "wx/mmedia/sndaiff.h"
29
30 #define BUILD_SIGNATURE(a,b,c,d) (((wxUint32)a) | (((wxUint32)b) << 8) | (((wxUint32)c) << 16) | (((wxUint32)d) << 24))
31
32 #define FORM_SIGNATURE BUILD_SIGNATURE('F','O','R','M')
33 #define AIFF_SIGNATURE BUILD_SIGNATURE('A','I','F','F')
34 #define AIFC_SIGNATURE BUILD_SIGNATURE('A','I','F','C')
35 #define COMM_SIGNATURE BUILD_SIGNATURE('C','O','M','M')
36 #define SSND_SIGNATURE BUILD_SIGNATURE('S','S','N','D')
37
38 wxSoundAiff::wxSoundAiff(wxInputStream& stream, wxSoundStream& io_sound)
39 : wxSoundFileStream(stream, io_sound)
40 {
41 m_base_offset = wxInvalidOffset;
42 }
43
44 wxSoundAiff::wxSoundAiff(wxOutputStream& stream, wxSoundStream& io_sound)
45 : wxSoundFileStream(stream, io_sound)
46 {
47 m_base_offset = wxInvalidOffset;
48 }
49
50 wxSoundAiff::~wxSoundAiff()
51 {
52 }
53
54 wxString wxSoundAiff::GetCodecName() const
55 {
56 return wxT("wxSoundAiff codec");
57 }
58
59 bool wxSoundAiff::CanRead()
60 {
61 wxUint32 signature1, signature2, len;
62
63 if (m_input->Read(&signature1, 4).LastRead() != 4)
64 return false;
65
66 if (wxUINT32_SWAP_ON_BE(signature1) != FORM_SIGNATURE) {
67 m_input->Ungetch(&signature1, 4);
68 return false;
69 }
70
71 m_input->Read(&len, 4);
72 if (m_input->LastRead() != 4) {
73 m_input->Ungetch(&len, m_input->LastRead());
74 m_input->Ungetch(&signature1, 4);
75 return false;
76 }
77
78 if (m_input->Read(&signature2, 4).LastRead() != 4) {
79 m_input->Ungetch(&signature2, m_input->LastRead());
80 m_input->Ungetch(&len, 4);
81 m_input->Ungetch(&signature1, 4);
82 return false;
83 }
84
85 m_input->Ungetch(&signature2, 4);
86 m_input->Ungetch(&len, 4);
87 m_input->Ungetch(&signature1, 4);
88
89 if (
90 wxUINT32_SWAP_ON_BE(signature2) != AIFF_SIGNATURE &&
91 wxUINT32_SWAP_ON_BE(signature2) != AIFC_SIGNATURE)
92 return false;
93
94 return true;
95 }
96
97 #define FAIL_WITH(condition, err) if (condition) { m_snderror = err; return false; }
98
99 bool wxSoundAiff::PrepareToPlay()
100 {
101 wxDataInputStream data(*m_input);
102 wxUint32 signature, len, ssnd;
103 bool end_headers;
104
105 if (!m_input) {
106 m_snderror = wxSOUND_INVSTRM;
107 return false;
108 }
109 m_snderror = wxSOUND_NOERROR;
110
111 data.BigEndianOrdered(true);
112
113 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
114 FAIL_WITH(wxUINT32_SWAP_ON_BE(signature) != FORM_SIGNATURE, wxSOUND_INVSTRM);
115 // "FORM"
116
117 len = data.Read32();
118 wxUnusedVar(len);
119 FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
120 // dummy len
121
122 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
123 FAIL_WITH(
124 wxUINT32_SWAP_ON_BE(signature) != AIFF_SIGNATURE &&
125 wxUINT32_SWAP_ON_BE(signature) != AIFC_SIGNATURE, wxSOUND_INVSTRM);
126 // "AIFF" / "AIFC"
127
128 end_headers = false;
129 while (!end_headers) {
130 FAIL_WITH(m_input->Read(&signature, 4).LastRead() != 4, wxSOUND_INVSTRM);
131
132 len = data.Read32();
133 FAIL_WITH(m_input->LastRead() != 4, wxSOUND_INVSTRM);
134
135 switch (wxUINT32_SWAP_ON_BE(signature)) {
136 case COMM_SIGNATURE: { // "COMM"
137 wxUint16 channels, bps;
138 wxUint32 num_samples;
139 double srate;
140 wxSoundFormatPcm sndformat;
141
142 // Get sound data informations
143 data >> channels >> num_samples >> bps >> srate;
144
145 // Convert them in a wxSoundFormat object
146 sndformat.SetSampleRate((wxUint32) srate);
147 sndformat.SetBPS(bps);
148 sndformat.SetChannels(channels);
149 sndformat.Signed(false);
150 sndformat.SetOrder(wxBIG_ENDIAN);
151
152 if (!SetSoundFormat(sndformat))
153 return false;
154 // We pass all data left
155 m_input->SeekI(len-18, wxFromCurrent);
156 break;
157 }
158 case SSND_SIGNATURE: { // "SSND"
159 data >> ssnd;
160 // m_input->SeekI(4, wxFromCurrent); // Pass an INT32
161 // m_input->SeekI(len-4, wxFromCurrent); // Pass the rest
162 m_input->SeekI(ssnd + 4, wxFromCurrent);
163 m_base_offset = m_input->TellI();
164 // len-8 bytes of samples
165 FinishPreparation(len - 8);
166 end_headers = true;
167 break;
168 }
169 default:
170 m_input->SeekI(len, wxFromCurrent);
171 break;
172 }
173 }
174 return true;
175 }
176
177 bool wxSoundAiff::PrepareToRecord(wxUint32 WXUNUSED(time))
178 {
179 // TODO
180 return false;
181 }
182
183 bool wxSoundAiff::FinishRecording()
184 {
185 // TODO
186 return false;
187 }
188
189 bool wxSoundAiff::RepositionStream(wxUint32 WXUNUSED(position))
190 {
191 // If the stream is not seekable "TellI() returns wxInvalidOffset" we cannot reposition stream
192 if (m_base_offset == wxInvalidOffset)
193 return false;
194 m_input->SeekI(m_base_offset, wxFromStart);
195 return true;
196 }
197
198 wxUint32 wxSoundAiff::GetData(void *buffer, wxUint32 len)
199 {
200 return m_input->Read(buffer, len).LastRead();
201 }
202
203 wxUint32 wxSoundAiff::PutData(const void *buffer, wxUint32 len)
204 {
205 return m_output->Write(buffer, len).LastWrite();
206 }