]> git.saurik.com Git - wxWidgets.git/blob - utils/wxMMedia/sndpcm.cpp
a1c5be0cf07e428d4902b5eb93b7ee2563464ace
[wxWidgets.git] / utils / wxMMedia / sndpcm.cpp
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
10 wxSoundPcmCodec::wxSoundPcmCodec()
11 : wxSoundCodec()
12 {
13 m_orig_format.SetCodecCreate(FALSE);
14 m_orig_format.SetCodecNo(1);
15 m_char_bool = FALSE;
16 }
17
18 wxSoundPcmCodec::~wxSoundPcmCodec()
19 {
20 }
21
22 size_t wxSoundPcmCodec::GetByteRate() const
23 {
24 return (m_orig_format.GetBps()/8)*
25 m_orig_format.GetSampleRate()*
26 m_orig_format.GetChannels();
27 }
28
29 wxSoundDataFormat 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
42 void 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
75 void 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
91 void 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
133 void 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
147 void 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
193 void 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 }