]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia/sndaiff.cpp
Added test for sprintf and vsnprintf to fix string.cpp for non-GNU systems.
[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 m_istream->SeekI(0, wxFromStart);
90
91 wxSndFileCodec::m_mmerror = wxMMFILE_INVALID;
92
93 READ_STRING(chunk_name, 4);
94 if (chunk_name != "FORM")
95 return 0;
96 m_istream->SeekI(4, wxFromCurrent);
97
98 READ_STRING(chunk_name, 4);
99 if (chunk_name != "AIFF" && chunk_name != "AIFC")
100 return 0;
101
102 // To check whether the file is good
103 m_spos = 0;
104 m_slen = 0;
105 m_sndformat.SetSampleRate(0);
106 while (1) {
107 READ_STRING(chunk_name, 4);
108 READ32(m_chunksize);
109
110 if (chunk_name == "SSND")
111 ParseSSND();
112 if (chunk_name == "COMM")
113 ParseCOMM();
114 else
115 m_istream->SeekI(m_chunksize, wxFromCurrent);
116
117 if (m_spos && m_sndformat.GetSampleRate())
118 break;
119 }
120
121 m_sndmode = wxSND_OUTPUT;
122
123 wxUint32 sec1 = m_slen / m_sndformat.GetCodec()->GetByteRate(),
124 sec2 = sec1 % 3600;
125
126 m_sndtime.hours = sec1 / 3600;
127 m_sndtime.minutes = sec2 / 60;
128 m_sndtime.seconds = sec2 % 60;
129
130 wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR;
131
132 m_istream->SeekI(m_spos, wxFromStart);
133 return m_slen;
134 }
135
136 void wxSndAiffCodec::ParseCOMM()
137 {
138 wxDataInputStream data_s(*m_istream);
139 char tmp_buf[10];
140 wxUint16 channels;
141 wxUint32 srate, num_samples;
142 wxUint16 bps;
143
144 READ16(channels);
145 READ32(num_samples);
146 READ16(bps);
147
148 srate = (wxUint32)data_s.ReadDouble();
149 m_sndformat.SetSampleRate(srate);
150 m_sndformat.SetBps(bps);
151 m_sndformat.SetChannels(channels);
152 m_sndformat.SetByteOrder(wxSND_SAMPLE_BE);
153 m_sndformat.SetSign(wxSND_SAMPLE_UNSIGNED);
154 ChangeCodec(WXSOUND_PCM);
155
156 m_istream->SeekI(m_chunksize-18, wxFromCurrent);
157 }
158
159 void wxSndAiffCodec::ParseSSND()
160 {
161 wxDataInputStream data_s(*m_istream);
162 char tmp_buf[10];
163
164 READ32(m_spos);
165 m_istream->SeekI(4, wxFromCurrent);
166
167 m_slen = m_chunksize - m_spos;
168 m_spos += m_istream->TellI();
169 }
170
171 wxSndAiffCodec::~wxSndAiffCodec()
172 {
173 }
174
175 bool wxSndAiffCodec::OnNeedData(char *buf, wxUint32 size)
176 {
177 m_istream->Read(buf, size);
178 return TRUE;
179 }
180
181 bool wxSndAiffCodec::OnWriteData(char *buf, wxUint32 size)
182 {
183 return ( !(m_ostream->Write(buf, size).LastError()) );
184 }
185
186 bool wxSndAiffCodec::PrepareToRecord(wxUint32 m_fsize)
187 {
188 /*
189 wxUint32 total_size;
190 char tmp_buf[10];
191
192 m_ostream->SeekO(0, wxBeginPosition);
193
194 m_ostream->Write("FORM", 4);
195 WRITE32(total_size);
196
197 m_ostream->Write("AIFF", 4);
198
199 WriteCOMM();
200 WriteSSND(m_fsize);
201
202 */
203 return TRUE;
204 }
205
206 void wxSndAiffCodec::SetFile(wxInputStream& s, bool preload, bool seekable)
207 {
208 wxMMediaFile::SetFile(s, preload, seekable);
209 if (!seekable)
210 CacheIO();
211 }
212
213 void wxSndAiffCodec::SetFile(wxOutputStream& s, bool seekable)
214 {
215 wxMMediaFile::SetFile(s, seekable);
216 if (!seekable)
217 CacheIO();
218 }