]> git.saurik.com Git - wxWidgets.git/blame_incremental - utils/wxMMedia/sndaiff.cpp
mbstowcs hack for CodeWarrior's MSL
[wxWidgets.git] / utils / wxMMedia / sndaiff.cpp
... / ...
CommitLineData
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
56wxSndAiffCodec::wxSndAiffCodec()
57 : wxSndFileCodec()
58{
59 m_sndtime.hours = -1;
60}
61
62wxSndAiffCodec::wxSndAiffCodec(wxOutputStream& s, bool seekable)
63 : wxSndFileCodec(s, seekable)
64{
65 if (!seekable)
66 CacheIO();
67 m_sndtime.hours = -1;
68}
69
70wxSndAiffCodec::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
78wxSndAiffCodec::wxSndAiffCodec(const wxString& fname)
79 : wxSndFileCodec(fname)
80{
81 m_sndtime.hours = -1;
82}
83
84wxUint32 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 (!m_spos || !m_sndformat.GetSampleRate()) {
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
118 m_sndmode = wxSND_OUTPUT;
119
120 wxUint32 sec1 = m_slen / m_sndformat.GetCodec()->GetByteRate(),
121 sec2 = sec1 % 3600;
122
123 m_sndtime.hours = sec1 / 3600;
124 m_sndtime.minutes = sec2 / 60;
125 m_sndtime.seconds = sec2 % 60;
126
127 wxSndFileCodec::m_mmerror = wxMMFILE_NOERROR;
128
129 m_istream->SeekI(m_spos, wxFromStart);
130 return m_slen;
131}
132
133void 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
156void 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
168wxSndAiffCodec::~wxSndAiffCodec()
169{
170}
171
172bool wxSndAiffCodec::OnNeedData(char *buf, wxUint32 size)
173{
174 m_istream->Read(buf, size);
175 return TRUE;
176}
177
178bool wxSndAiffCodec::OnWriteData(char *buf, wxUint32 size)
179{
180 return ( !(m_ostream->Write(buf, size).LastError()) );
181}
182
183void 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
210void 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
224bool 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
240void wxSndAiffCodec::SetFile(wxInputStream& s, bool preload, bool seekable)
241{
242 wxMMediaFile::SetFile(s, preload, seekable);
243 if (!seekable)
244 CacheIO();
245}
246
247void wxSndAiffCodec::SetFile(wxOutputStream& s, bool seekable)
248{
249 wxMMediaFile::SetFile(s, seekable);
250 if (!seekable)
251 CacheIO();
252}