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