]> git.saurik.com Git - wxWidgets.git/blame - contrib/src/mmedia/sndg72x.cpp
corrected version number extraction
[wxWidgets.git] / contrib / src / mmedia / sndg72x.cpp
CommitLineData
e8482f24
GL
1// --------------------------------------------------------------------------
2// Name: sndg72x.cpp
3// Purpose:
4// Date: 08/26/1999
5// Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
6// CVSID: $Id$
58b9c9ba 7// wxWindows licence
e8482f24
GL
8// --------------------------------------------------------------------------
9#ifdef __GNUG__
10#pragma implementation "sndg72x.cpp"
11#endif
12
92a19c2e 13#include "wx/wxprec.h"
e8482f24
GL
14
15#ifndef WX_PRECOMP
16 #include "wx/defs.h"
17#endif
18
19#include "wx/mmedia/sndbase.h"
20#include "wx/mmedia/sndfile.h"
21#include "wx/mmedia/sndpcm.h"
22#include "wx/mmedia/sndg72x.h"
23#include "wx/mmedia/internal/g72x.h"
24
25// --------------------------------------------------------------------------
26// wxSoundFormatG72X
27// --------------------------------------------------------------------------
28
29wxSoundFormatG72X::wxSoundFormatG72X()
30 : m_srate(22050)
31{
32}
33
34wxSoundFormatG72X::~wxSoundFormatG72X()
35{
36}
37
38void wxSoundFormatG72X::SetSampleRate(wxUint32 srate)
39{
40 m_srate = srate;
41}
42
43wxUint32 wxSoundFormatG72X::GetSampleRate() const
44{
45 return m_srate;
46}
47
48void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type)
49{
50 m_g72x_type = type;
51}
52
53wxSoundFormatBase *wxSoundFormatG72X::Clone() const
54{
55 wxSoundFormatG72X *g72x = new wxSoundFormatG72X();
56
57 g72x->m_srate = m_srate;
58 g72x->m_g72x_type = m_g72x_type;
59 return g72x;
60}
61
62wxUint32 wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes) const
63{
64 int n_bits;
65
66 switch (m_g72x_type) {
67 case wxSOUND_G721:
68 n_bits = 4;
69 break;
70 case wxSOUND_G723_24:
71 n_bits = 3;
72 break;
73 case wxSOUND_G723_40:
74 n_bits = 5;
75 break;
76 default:
77 n_bits = 0;
78 break;
79 }
80 return (wxUint32)((bytes / m_srate) * n_bits) / 8;
81}
82
83wxUint32 wxSoundFormatG72X::GetBytesFromTime(wxUint32 time) const
84{
85 int n_bits;
86
87 switch (m_g72x_type) {
88 case wxSOUND_G721:
89 n_bits = 4;
90 break;
91 case wxSOUND_G723_24:
92 n_bits = 3;
93 break;
94 case wxSOUND_G723_40:
95 n_bits = 5;
96 break;
97 default:
98 n_bits = 0;
99 }
100 return (wxUint32)((time * m_srate * n_bits) / 8);
101}
102
103bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase& frmt2) const
104{
105 wxSoundFormatG72X *g72x = (wxSoundFormatG72X *)&frmt2;
106
107 if (frmt2.GetType() != wxSOUND_G72X)
dea7e44a 108 return true;
e8482f24
GL
109
110 return (g72x->m_srate != m_srate || g72x->m_g72x_type != m_g72x_type);
111}
112
113// --------------------------------------------------------------------------
114// wxSoundStreamG72X
115// --------------------------------------------------------------------------
116
117wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream& sndio)
118 : wxSoundStreamCodec(sndio)
119{
120 // PCM converter
121 m_router = new wxSoundRouterStream(sndio);
122 m_state = new g72state;
123 g72x_init_state(m_state);
124}
125
126wxSoundStreamG72X::~wxSoundStreamG72X()
127{
128 delete m_router;
129}
130
131wxSoundStream& wxSoundStreamG72X::Read(void *buffer, wxUint32 len)
132{
133 wxUint16 *old_linear;
134 register wxUint16 *linear_buffer;
135 register wxUint32 real_len;
136 register wxUint32 countdown = len;
137
138 real_len = (len * 8 / m_n_bits);
139
140 old_linear = linear_buffer = new wxUint16[real_len];
141
142 m_router->Read(linear_buffer, real_len);
143
144 real_len = (wxUint32)(m_router->GetLastAccess() * ((float)m_n_bits / 8));
145 if (!real_len)
146 return *m_router;
147
148 m_io_buffer = (wxUint8 *)buffer;
149 m_current_b_pos = 0;
150
151 while (countdown != 0) {
152 PutBits(m_coder(*linear_buffer++, AUDIO_ENCODING_LINEAR, m_state));
153 countdown--;
154 }
155 m_lastcount = real_len;
156 m_snderror = m_router->GetError();
157
158 delete[] old_linear;
159
160 return *this;
161}
162
163wxSoundStream& wxSoundStreamG72X::Write(const void *buffer, wxUint32 len)
164{
165 wxUint16 *old_linear;
166 register wxUint16 *linear_buffer;
167 register wxUint32 countdown = len;
168 register wxUint32 real_len;
169
170 // Compute the real length (PCM format) to sendt to the sound card
171 real_len = (len * m_n_bits / 8);
172
173 // Allocate a temporary buffer
174 old_linear = linear_buffer = new wxUint16[real_len];
175
176 // Bad, we override the const
177 m_io_buffer = (wxUint8 *)buffer;
178 m_current_b_pos = 0;
179
180 // Decode the datas
181 while (countdown != 0) {
182 *linear_buffer++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR, m_state);
183 countdown--;
184 }
185 m_lastcount = len;
186
187 // Send them to the sound card
188 m_router->Write(old_linear, real_len);
189
190 // Destroy the temporary buffer
191 delete[] old_linear;
192
193 return *m_router;
194}
195
196bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase& format)
197{
198 if (format.GetType() != wxSOUND_G72X) {
199 m_snderror = wxSOUND_INVFRMT;
dea7e44a 200 return false;
e8482f24
GL
201 }
202
203 wxSoundFormatPcm pcm;
204 wxSoundFormatG72X *g72x;
205
206 wxSoundStreamCodec::SetSoundFormat(format);
207
208 g72x = (wxSoundFormatG72X *)m_sndformat;
209
210 // Set PCM as the output format of the codec
211 pcm.SetSampleRate(g72x->GetSampleRate());
212 pcm.SetBPS(16);
213 pcm.SetChannels(1); // Only mono supported
dea7e44a 214 pcm.Signed(true);
e8482f24
GL
215 pcm.SetOrder(wxBYTE_ORDER);
216
217 // Look for the correct codec to use and set its bit width
218 switch (g72x->GetG72XType()) {
219 case wxSOUND_G721:
220 m_n_bits = 4;
221 m_coder = g721_encoder;
222 m_decoder = g721_decoder;
223 break;
224 case wxSOUND_G723_24:
225 m_n_bits = 3;
226 m_coder = g723_24_encoder;
227 m_decoder = g723_24_decoder;
228 break;
229 case wxSOUND_G723_40:
230 m_n_bits = 5;
231 m_coder = g723_40_encoder;
232 m_decoder = g723_40_decoder;
233 break;
234 }
235
236 // Let the router finish the work
237 m_router->SetSoundFormat(pcm);
238
dea7e44a 239 return true;
e8482f24
GL
240}
241
242#define BYTE_SIZE 8
243
244wxUint8 wxSoundStreamG72X::GetBits()
245{
246 register wxUint8 bits;
247
248 // We have two bytes to compute
249 if (m_current_b_pos < m_n_bits) {
250 register wxUint8 b_left;
251
252 // TRANSLATE the mask
253 m_current_mask >>= m_current_b_pos;
254
255 // GET the last bits: 0001..1
256 bits = (m_current_byte & m_current_mask) << (m_n_bits - m_current_b_pos);
257
258 // GEN: 1. n times .1000
259 b_left = BYTE_SIZE-m_n_bits;
260 m_current_mask = ((1 << m_n_bits) - 1) << b_left;
261
262 // GET the next byte
263 m_current_byte = *m_io_buffer++;
264
265 register wxUint8 tmp_mask;
266
267 // COMPUTE a new temporary mask to get the last bits
268 b_left = m_n_bits - b_left;
269 tmp_mask = (1 << b_left) - 1;
270 // TRANSLATE the old mask to get ready for the next time
271 m_current_mask >>= b_left;
272
273 // COMPUTE the new bit position
274 b_left = BYTE_SIZE - b_left;
275 m_current_b_pos = b_left;
276 tmp_mask <<= b_left;
277
278 // GET the last bits
279 bits |= (m_current_byte & tmp_mask) >> b_left;
280 } else {
281 m_current_mask >>= m_n_bits;
282 m_current_b_pos -= m_n_bits;
283 bits = (m_current_byte & m_current_mask) >> m_current_b_pos;
284 }
285 return bits;
286}
287
288void wxSoundStreamG72X::PutBits(wxUint8 bits)
289{
290 if (m_current_b_pos < m_n_bits) {
291 register wxUint8 tmp_mask;
292 register wxUint8 diff;
293
294 diff = m_n_bits - m_current_b_pos;
295 // Pack bits and put the byte in the buffer
296 m_current_byte |= bits >> diff;
297 *m_io_buffer++ = m_current_byte;
298
299 // Gen a mask
300 tmp_mask = ~((1 << diff) - 1);
301
302 m_current_b_pos = BYTE_SIZE - (m_n_bits - m_current_b_pos);
303
304 m_current_byte = (bits & (tmp_mask)) << m_current_b_pos;
305 } else {
306 m_current_b_pos -= m_n_bits;
307 bits <<= m_current_b_pos;
308 m_current_byte |= bits;
309 }
310}