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