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