]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia/sndaiff.cpp
fixed somebody's poorly done StreamSize-->GetSize transition
[wxWidgets.git] / utils / wxMMedia / sndaiff.cpp
1 ////////////////////////////////////////////////////////////////////////////////
2 // Name: sndaiff.cpp
3 // Purpose: wxMMedia
4 // Author: Guilhem Lavaux
5 // Created: 1997
6 // Updated: February 1998
7 // Copyright: (C) 1997, 1998, Guilhem Lavaux
8 // License: wxWindows license
9 ////////////////////////////////////////////////////////////////////////////////
10 #ifdef __GNUG__
11 #pragma implementation "sndaiff.h"
12 #endif
13
14 #ifdef WX_PRECOMP
15 #include "wx/wxprec.h"
16 #else
17 #include "wx/wx.h"
18 #endif
19 #include "wx/datstrm.h"
20 #include "sndaiff.h"
21 #include "sndpcm.h"
22
23 #ifdef __BORLANDC__
24 #pragma hdrstop
25 #endif
26
27 #define READ_DATA(n) m_istream->Read(tmp_buf,n)
28 #define WRITE_DATA(n) m_ostream->Write(tmp_buf,n)
29
30 #define READ_STRING(s,n) \
31 READ_DATA(n); \
32 tmp_buf[n] = 0; \
33 s = tmp_buf;
34
35 #define WRITE_STRING(s,n) WRITE_DATA((const char *)s, n)
36
37 #define READ32(i) \
38 READ_DATA(4); \
39 i = (unsigned long)tmp_buf[3] | \
40 ((unsigned long)tmp_buf[2] << 8) | \
41 ((unsigned long)tmp_buf[1] << 16) | \
42 ((unsigned long)tmp_buf[0] << 24);
43
44 #define WRITE32(i) \
45 tmp_buf[3] = i & 0xFF; \
46 tmp_buf[2] = (i >> 8) & 0xFF; \
47 tmp_buf[1] = (i >> 16) & 0xFF; \
48 tmp_buf[0] = (i >> 24) & 0xFF; \
49 WRITE_DATA(4);
50
51 #define READ16(i) \
52 READ_DATA(2); \
53 i = (unsigned short)tmp_buf[1] | \
54 ((unsigned short)tmp_buf[0] << 8);
55
56 wxSndAiffCodec::wxSndAiffCodec()
57 : wxSndFileCodec()
58 {
59 m_sndtime.hours = -1;
60 }
61
62 wxSndAiffCodec::wxSndAiffCodec(wxOutputStream& s, bool seekable)
63 : wxSndFileCodec(s, seekable)
64 {
65 if (!seekable)
66 CacheIO();
67 m_sndtime.hours = -1;
68 }
69
70 wxSndAiffCodec::wxSndAiffCodec(wxInputStream& s, bool preload, bool seekable)
71 : wxSndFileCodec(s, preload, seekable)
72 {
73 if (!seekable)
74 CacheIO();
75 m_sndtime.hours = -1;
76 }
77
78 wxSndAiffCodec::wxSndAiffCodec(const wxString& fname)
79 : wxSndFileCodec(fname)
80 {
81 m_sndtime.hours = -1;
82 }
83
84 wxUint32 wxSndAiffCodec::PrepareToPlay()
85 {
86 char tmp_buf[5];
87 wxString chunk_name;
88
89 wxSndFileCodec::m_mmerror = wxMMFILE_INVALID;
90
91 READ_STRING(chunk_name, 4);
92 if (chunk_name != "FORM")
93 return 0;
94 m_istream->SeekI(4, wxFromCurrent);
95
96 READ_STRING(chunk_name, 4);
97 if (chunk_name != "AIFF" && chunk_name != "AIFC")
98 return 0;
99
100 // To check whether the file is good
101 m_spos = 0;
102 m_slen = 0;
103 m_sndformat.SetSampleRate(0);
104 while (!m_spos || !m_sndformat.GetSampleRate()) {
105 READ_STRING(chunk_name, 4);
106 READ32(m_chunksize);
107
108 if (chunk_name == "SSND")
109 ParseSSND();
110 if (chunk_name == "COMM")
111 ParseCOMM();
112 else
113 m_istream->SeekI(m_chunksize, wxFromCurrent);
114 }
115
116 m_sndmode = wxSND_OUTPUT;
117
118 wxUint32 sec1 = m_slen / m_sndformat.GetCodec()->GetByteRate(),
119 sec2 = sec1 % 3600;
120
121 m_sndtime.hours = sec1 / 3600;
122 m_sndtime.minutes = sec2 / 60;
123 m_sndtime.seconds = sec2 % 60;
124
125 wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR;
126
127 m_istream->SeekI(m_spos, wxFromStart);
128 wxSndFileCodec::m_fstate = wxSFILE_PREPARED_TO_PLAY;
129
130 return m_slen;
131 }
132
133 void wxSndAiffCodec::ParseCOMM()
134 {
135 wxDataInputStream data_s(*m_istream);
136 char tmp_buf[10];
137 wxUint16 channels;
138 wxUint32 srate, num_samples;
139 wxUint16 bps;
140
141 READ16(channels);
142 READ32(num_samples);
143 READ16(bps);
144
145 srate = (wxUint32)data_s.ReadDouble();
146 m_sndformat.SetSampleRate(srate);
147 m_sndformat.SetBps(bps);
148 m_sndformat.SetChannels(channels);
149 m_sndformat.SetByteOrder(wxSND_SAMPLE_BE);
150 m_sndformat.SetSign(wxSND_SAMPLE_UNSIGNED);
151 ChangeCodec(WXSOUND_PCM);
152
153 m_istream->SeekI(m_chunksize-18, wxFromCurrent);
154 }
155
156 void wxSndAiffCodec::ParseSSND()
157 {
158 wxDataInputStream data_s(*m_istream);
159 char tmp_buf[10];
160
161 READ32(m_spos);
162 m_istream->SeekI(4, wxFromCurrent);
163
164 m_slen = m_chunksize - m_spos;
165 m_spos += m_istream->TellI();
166 }
167
168 wxSndAiffCodec::~wxSndAiffCodec()
169 {
170 }
171
172 bool wxSndAiffCodec::OnNeedData(char *buf, wxUint32 size)
173 {
174 m_istream->Read(buf, size);
175 return TRUE;
176 }
177
178 bool wxSndAiffCodec::OnWriteData(char *buf, wxUint32 size)
179 {
180 return ( !(m_ostream->Write(buf, size).LastError()) );
181 }
182
183 void wxSndAiffCodec::WriteCOMM()
184 {
185 /*
186 wxDataOutputStream data_s(*m_ostream);
187 char tmp_buf[10];
188 wxUint16 channels;
189 wxUint32 srate, num_samples;
190 wxUint16 bps;
191
192 m_chunksize = 18;
193 WRITE32(m_chunksize);
194 channels = m_sndformat.GetChannels();
195 srate = m_sndformat.GetSampleRate();
196 bps = m_sndformat.GetBps();
197
198 WRITE16(channels);
199 WRITE32(num_samples);
200 WRITE16(bps);
201
202 data_s.WriteDouble((double)srate);
203
204 m_sndformat.SetByteOrder(wxSND_SAMPLE_BE);
205 m_sndformat.SetSign(wxSND_SAMPLE_UNSIGNED);
206 ChangeCodec(WXSOUND_PCM);
207 */
208 }
209
210 void wxSndAiffCodec::WriteSSND(wxUint32 fsize)
211 {
212 /*
213 char tmp_buf[10];
214
215 WRITE32(m_spos);
216 // WRITE32(dummy ??);
217
218 m_slen = m_chunksize - m_spos;
219 m_spos += m_istream->TellI();
220 */
221 }
222
223
224 bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
225 {
226 wxUint32 total_size = m_fsize + 0;
227 char tmp_buf[10];
228
229 m_ostream->Write("FORM", 4);
230 WRITE32(total_size);
231
232 m_ostream->Write("AIFF", 4);
233
234 WriteCOMM();
235 WriteSSND(m_fsize);
236
237 return TRUE;
238 }
239
240 void wxSndAiffCodec::SetFile(wxInputStream& s, bool preload, bool seekable)
241 {
242 wxMMediaFile::SetFile(s, preload, seekable);
243 if (!seekable)
244 CacheIO();
245 }
246
247 void wxSndAiffCodec::SetFile(wxOutputStream& s, bool seekable)
248 {
249 wxMMediaFile::SetFile(s, seekable);
250 if (!seekable)
251 CacheIO();
252 }