]> git.saurik.com Git - wxWidgets.git/blame - utils/wxMMedia/sndpcm.cpp
* Fixes.
[wxWidgets.git] / utils / wxMMedia / sndpcm.cpp
CommitLineData
4d6306eb
GL
1#ifdef __GNUG__
2#pragma implementation "sndpcm.h"
3#endif
4#include "sndsnd.h"
5#include "sndpcm.h"
6#include <dmalloc.h>
7
8#define WX_BIG_ENDIAN 0
9
10wxSoundPcmCodec::wxSoundPcmCodec()
11 : wxSoundCodec()
12{
13 m_orig_format.SetCodecCreate(FALSE);
14 m_orig_format.SetCodecNo(1);
15 m_char_bool = FALSE;
16}
17
18wxSoundPcmCodec::~wxSoundPcmCodec()
19{
20}
21
22size_t wxSoundPcmCodec::GetByteRate() const
23{
24 return (m_orig_format.GetBps()/8)*
25 m_orig_format.GetSampleRate()*
26 m_orig_format.GetChannels();
27}
28
29wxSoundDataFormat wxSoundPcmCodec::GetPreferredFormat(int codec) const
30{
31 wxSoundDataFormat prefFormat;
32
33 prefFormat = m_orig_format;
34 prefFormat.SetCodecNo(WXSOUND_PCM);
35 return prefFormat;
36}
37
38// ---------------------------------------------------------------------------
39// Main part of the decoder
40// ---------------------------------------------------------------------------
41
42void wxSoundPcmCodec::Decode()
43{
44 InitMode(DECODING);
45 if (m_io_format == m_orig_format) {
46 CopyToOutput();
47 ExitMode();
48 return;
49 }
50
51 // Swap bytes
52 switch (m_io_format.GetBps()) {
53 case 8:
54 InputSign8();
55 break;
56 case 16:
57 InputSwapAndSign16();
58 break;
59 case 32:
60 case 64:
61 default:
62 break;
63 }
64 ExitMode();
65}
66
67// ---------------------------------------------------------------------------
68// Change the sign of a 8-bit sample.
69
70#define GET() (m_in_sound->GetChar())
71#define PUT(c) (m_out_sound->PutChar(c))
72#define OUT_ERROR() (out->LastError() == wxStream_NOERROR)
73#define IN_ERROR() (in->LastError() == wxStream_NOERROR)
74
75void wxSoundPcmCodec::InputSign8()
76{
77 unsigned char signer = 0;
78 wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
79
80 if (m_io_format.GetSign() != m_orig_format.GetSign())
81 signer = 128;
82
83 while (IN_ERROR() && OUT_ERROR())
84 PUT(GET() + signer);
85
86}
87
88// ---------------------------------------------------------------------------
89// Swap bytes and change the sign of a 16-bit sample.
90
91void wxSoundPcmCodec::InputSwapAndSign16()
92{
93 unsigned short signer1 = 0, signer2 = 0;
94 wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
95 bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
96 char temp;
97
98 if (m_io_format.GetSign() != m_orig_format.GetSign()) {
99 if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
100 signer2 = 0x80;
101 else
102 signer1 = 0x80;
103 }
104
105 if (swap) {
106 while (IN_ERROR() && OUT_ERROR()) {
107 temp = GET() ^ signer1;
108 PUT(GET() ^ signer2);
109 if (OUT_ERROR()) {
110 m_char_bool = TRUE;
111 m_char_stack = temp;
112 break;
113 }
114 PUT(temp);
115 }
116 } else {
117 while (IN_ERROR() && OUT_ERROR()) {
118 PUT(GET() ^ signer1);
119 if (OUT_ERROR()) {
120 m_char_bool = TRUE;
121 m_char_stack = temp;
122 break;
123 }
124 PUT(GET() ^ signer2);
125 }
126 }
127}
128
129// ---------------------------------------------------------------------------
130// Encoder part.
131// ---------------------------------------------------------------------------
132
133void wxSoundPcmCodec::OutputSign8()
134{
135 wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
136 unsigned char signer = 0;
137
138 if (m_io_format.GetSign() != m_orig_format.GetSign())
139 signer = 128;
140
141 while (IN_ERROR() && OUT_ERROR())
142 PUT((char)(GET() + signer));
143}
144
145// ---------------------------------------------------------------------------
146
147void wxSoundPcmCodec::OutputSwapAndSign16()
148{
149 bool swap = (m_io_format.GetByteOrder() != m_orig_format.GetByteOrder());
150 unsigned short signer1 = 0, signer2 = 0;
151 char temp;
152 wxStreamBase *in = m_out_sound->Stream(), *out = m_in_sound->Stream();
153
154 if (m_char_bool) {
155 PUT(GET());
156 PUT(m_char_stack);
157 m_char_bool = FALSE;
158 }
159
160 if (m_io_format.GetSign() != m_orig_format.GetSign())
161 if (m_io_format.GetByteOrder() == wxSND_SAMPLE_LE)
162 signer1 = 0x80;
163 else
164 signer2 = 0x80;
165
166 if (swap) {
167 while (IN_ERROR()) {
168 temp = GET();
169 PUT(GET() ^ signer1);
170 if (OUT_ERROR()) {
171 m_char_stack = temp ^ signer2;
172 m_char_bool = TRUE;
173 break;
174 }
175 PUT(temp ^ signer2);
176 }
177 } else {
178 while (IN_ERROR()) {
179 PUT(GET() ^ signer1);
180 if (!OUT_ERROR()) {
181 m_char_stack = GET() ^ signer2;
182 m_char_bool = TRUE;
183 break;
184 }
185 PUT(GET() ^ signer2);
186 }
187 }
188
189}
190
191// ---------------------------------------------------------------------------
192
193void wxSoundPcmCodec::Encode()
194{
195 InitMode(ENCODING);
196 if (m_io_format == m_orig_format) {
197 CopyToOutput();
198 ExitMode();
199 return;
200 }
201
202 // Swap bytes
203 switch (m_io_format.GetBps()) {
204 case 8:
205 OutputSign8();
206 break;
207 case 16:
208 OutputSwapAndSign16();
209 break;
210 case 32:
211 case 64:
212 default:
213 break;
214 }
215 ExitMode();
216}