]>
git.saurik.com Git - wxWidgets.git/blob - contrib/src/mmedia/sndg72x.cpp
1 // --------------------------------------------------------------------------
5 // Author: Guilhem Lavaux <lavaux@easynet.fr> (C) 1999
8 // --------------------------------------------------------------------------
10 #pragma implementation "sndg72x.cpp"
13 #include "wx/wxprec.h"
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"
25 // --------------------------------------------------------------------------
27 // --------------------------------------------------------------------------
29 wxSoundFormatG72X::wxSoundFormatG72X()
34 wxSoundFormatG72X::~wxSoundFormatG72X()
38 void wxSoundFormatG72X::SetSampleRate(wxUint32 srate
)
43 wxUint32
wxSoundFormatG72X::GetSampleRate() const
48 void wxSoundFormatG72X::SetG72XType(wxSoundG72XType type
)
53 wxSoundFormatBase
*wxSoundFormatG72X::Clone() const
55 wxSoundFormatG72X
*g72x
= new wxSoundFormatG72X();
57 g72x
->m_srate
= m_srate
;
58 g72x
->m_g72x_type
= m_g72x_type
;
62 wxUint32
wxSoundFormatG72X::GetTimeFromBytes(wxUint32 bytes
) const
66 switch (m_g72x_type
) {
80 return (wxUint32
)((bytes
/ m_srate
) * n_bits
) / 8;
83 wxUint32
wxSoundFormatG72X::GetBytesFromTime(wxUint32 time
) const
87 switch (m_g72x_type
) {
100 return (wxUint32
)((time
* m_srate
* n_bits
) / 8);
103 bool wxSoundFormatG72X::operator !=(const wxSoundFormatBase
& frmt2
) const
105 wxSoundFormatG72X
*g72x
= (wxSoundFormatG72X
*)&frmt2
;
107 if (frmt2
.GetType() != wxSOUND_G72X
)
110 return (g72x
->m_srate
!= m_srate
|| g72x
->m_g72x_type
!= m_g72x_type
);
113 // --------------------------------------------------------------------------
115 // --------------------------------------------------------------------------
117 wxSoundStreamG72X::wxSoundStreamG72X(wxSoundStream
& sndio
)
118 : wxSoundStreamCodec(sndio
)
121 m_router
= new wxSoundRouterStream(sndio
);
122 m_state
= new g72state
;
123 g72x_init_state(m_state
);
126 wxSoundStreamG72X::~wxSoundStreamG72X()
131 wxSoundStream
& wxSoundStreamG72X::Read(void *buffer
, wxUint32 len
)
133 wxUint16
*old_linear
;
134 register wxUint16
*linear_buffer
;
135 register wxUint32 real_len
;
136 register wxUint32 countdown
= len
;
138 real_len
= (len
* 8 / m_n_bits
);
140 old_linear
= linear_buffer
= new wxUint16
[real_len
];
142 m_router
->Read(linear_buffer
, real_len
);
144 real_len
= (wxUint32
)(m_router
->GetLastAccess() * ((float)m_n_bits
/ 8));
148 m_io_buffer
= (wxUint8
*)buffer
;
151 while (countdown
!= 0) {
152 PutBits(m_coder(*linear_buffer
++, AUDIO_ENCODING_LINEAR
, m_state
));
155 m_lastcount
= real_len
;
156 m_snderror
= m_router
->GetError();
163 wxSoundStream
& wxSoundStreamG72X::Write(const void *buffer
, wxUint32 len
)
165 wxUint16
*old_linear
;
166 register wxUint16
*linear_buffer
;
167 register wxUint32 countdown
= len
;
168 register wxUint32 real_len
;
170 // Compute the real length (PCM format) to sendt to the sound card
171 real_len
= (len
* m_n_bits
/ 8);
173 // Allocate a temporary buffer
174 old_linear
= linear_buffer
= new wxUint16
[real_len
];
176 // Bad, we override the const
177 m_io_buffer
= (wxUint8
*)buffer
;
181 while (countdown
!= 0) {
182 *linear_buffer
++ = m_decoder(GetBits(), AUDIO_ENCODING_LINEAR
, m_state
);
187 // Send them to the sound card
188 m_router
->Write(old_linear
, real_len
);
190 // Destroy the temporary buffer
196 bool wxSoundStreamG72X::SetSoundFormat(const wxSoundFormatBase
& format
)
198 if (format
.GetType() != wxSOUND_G72X
) {
199 m_snderror
= wxSOUND_INVFRMT
;
203 wxSoundFormatPcm pcm
;
204 wxSoundFormatG72X
*g72x
;
206 wxSoundStreamCodec::SetSoundFormat(format
);
208 g72x
= (wxSoundFormatG72X
*)m_sndformat
;
210 // Set PCM as the output format of the codec
211 pcm
.SetSampleRate(g72x
->GetSampleRate());
213 pcm
.SetChannels(1); // Only mono supported
215 pcm
.SetOrder(wxBYTE_ORDER
);
217 // Look for the correct codec to use and set its bit width
218 switch (g72x
->GetG72XType()) {
221 m_coder
= g721_encoder
;
222 m_decoder
= g721_decoder
;
224 case wxSOUND_G723_24
:
226 m_coder
= g723_24_encoder
;
227 m_decoder
= g723_24_decoder
;
229 case wxSOUND_G723_40
:
231 m_coder
= g723_40_encoder
;
232 m_decoder
= g723_40_decoder
;
236 // Let the router finish the work
237 m_router
->SetSoundFormat(pcm
);
244 wxUint8
wxSoundStreamG72X::GetBits()
246 register wxUint8 bits
;
248 // We have two bytes to compute
249 if (m_current_b_pos
< m_n_bits
) {
250 register wxUint8 b_left
;
252 // TRANSLATE the mask
253 m_current_mask
>>= m_current_b_pos
;
255 // GET the last bits: 0001..1
256 bits
= (m_current_byte
& m_current_mask
) << (m_n_bits
- m_current_b_pos
);
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
;
263 m_current_byte
= *m_io_buffer
++;
265 register wxUint8 tmp_mask
;
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
;
273 // COMPUTE the new bit position
274 b_left
= BYTE_SIZE
- b_left
;
275 m_current_b_pos
= b_left
;
279 bits
|= (m_current_byte
& tmp_mask
) >> b_left
;
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
;
288 void wxSoundStreamG72X::PutBits(wxUint8 bits
)
290 if (m_current_b_pos
< m_n_bits
) {
291 register wxUint8 tmp_mask
;
292 register wxUint8 diff
;
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
;
300 tmp_mask
= ~((1 << diff
) - 1);
302 m_current_b_pos
= BYTE_SIZE
- (m_n_bits
- m_current_b_pos
);
304 m_current_byte
= (bits
& (tmp_mask
)) << m_current_b_pos
;
306 m_current_b_pos
-= m_n_bits
;
307 bits
<<= m_current_b_pos
;
308 m_current_byte
|= bits
;