562
|
1 /*
|
|
2 decode_i386.c: decode for i386 (really faster?)
|
|
3
|
|
4 copyright 1995-2006 by the mpg123 project - free software under the terms of the LGPL 2.1
|
|
5 see COPYING and AUTHORS files in distribution or http://mpg123.org
|
|
6 initially written by Michael Hipp
|
|
7
|
|
8 slighlty optimized for machines without autoincrement/decrement.
|
|
9 The performance is highly compiler dependend. Maybe
|
|
10 the decode.c version for 'normal' processor may be faster
|
|
11 even for Intel processors.
|
|
12 */
|
|
13
|
|
14 #include "mpg123lib_intern.h"
|
|
15
|
|
16 int synth_1to1_8bit_i386(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
17 {
|
|
18 short samples_tmp[64];
|
|
19 short *tmp1 = samples_tmp + channel;
|
|
20 int i,ret;
|
|
21
|
|
22 unsigned char *samples = fr->buffer.data;
|
|
23 int pnt = fr->buffer.fill;
|
|
24 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
25 fr->buffer.fill = 0;
|
|
26 ret = opt_synth_1to1(fr)(bandPtr, channel, fr , 0);
|
|
27 fr->buffer.data = samples;
|
|
28
|
|
29 samples += channel + pnt;
|
|
30 for(i=0;i<32;i++) {
|
|
31 *samples = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
32 samples += 2;
|
|
33 tmp1 += 2;
|
|
34 }
|
|
35 fr->buffer.fill = pnt + (final ? 64 : 0 );
|
|
36
|
|
37 return ret;
|
|
38 }
|
|
39
|
|
40 int synth_1to1_8bit_mono_i386(real *bandPtr, mpg123_handle *fr)
|
|
41 {
|
|
42 short samples_tmp[64];
|
|
43 short *tmp1 = samples_tmp;
|
|
44 int i,ret;
|
|
45
|
|
46 unsigned char *samples = fr->buffer.data;
|
|
47 int pnt = fr->buffer.fill;
|
|
48 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
49 fr->buffer.fill = 0;
|
|
50 ret = opt_synth_1to1(fr)(bandPtr, 0, fr, 0);
|
|
51 fr->buffer.data = samples;
|
|
52
|
|
53 samples += pnt;
|
|
54 for(i=0;i<32;i++) {
|
|
55 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
56 tmp1+=2;
|
|
57 }
|
|
58 fr->buffer.fill = pnt + 32;
|
|
59
|
|
60 return ret;
|
|
61 }
|
|
62
|
|
63 int synth_1to1_8bit_mono2stereo_i386(real *bandPtr, mpg123_handle *fr)
|
|
64 {
|
|
65 short samples_tmp[64];
|
|
66 short *tmp1 = samples_tmp;
|
|
67 int i,ret;
|
|
68
|
|
69 unsigned char *samples = fr->buffer.data;
|
|
70 int pnt = fr->buffer.fill;
|
|
71 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
72 fr->buffer.fill = 0;
|
|
73 ret = opt_synth_1to1(fr)(bandPtr, 0, fr, 0);
|
|
74 fr->buffer.data = samples;
|
|
75
|
|
76 samples += pnt;
|
|
77 for(i=0;i<32;i++) {
|
|
78 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
79 *samples++ = fr->conv16to8[*tmp1>>AUSHIFT];
|
|
80 tmp1 += 2;
|
|
81 }
|
|
82 fr->buffer.fill = pnt + 64;
|
|
83
|
|
84 return ret;
|
|
85 }
|
|
86
|
|
87 int synth_1to1_mono_i386(real *bandPtr, mpg123_handle *fr)
|
|
88 {
|
|
89 short samples_tmp[64];
|
|
90 short *tmp1 = samples_tmp;
|
|
91 int i,ret;
|
|
92
|
|
93 unsigned char *samples = fr->buffer.data;
|
|
94 int pnt = fr->buffer.fill;
|
|
95 fr->buffer.data = (unsigned char*) samples_tmp;
|
|
96 fr->buffer.fill = 0;
|
|
97 ret = opt_synth_1to1(fr)(bandPtr, 0, fr, 0);
|
|
98 fr->buffer.data = samples;
|
|
99
|
|
100 samples += pnt;
|
|
101 for(i=0;i<32;i++) {
|
|
102 *( (short *) samples) = *tmp1;
|
|
103 samples += 2;
|
|
104 tmp1 += 2;
|
|
105 }
|
|
106 fr->buffer.fill = pnt + 64;
|
|
107
|
|
108 return ret;
|
|
109 }
|
|
110
|
|
111
|
|
112 int synth_1to1_mono2stereo_i386(real *bandPtr, mpg123_handle *fr)
|
|
113 {
|
|
114 int i,ret;
|
|
115 unsigned char *samples = fr->buffer.data;
|
|
116
|
|
117 ret = opt_synth_1to1(fr)(bandPtr, 0, fr, 1);
|
|
118 samples += fr->buffer.fill - 128;
|
|
119
|
|
120 for(i=0;i<32;i++) {
|
|
121 ((short *)samples)[1] = ((short *)samples)[0];
|
|
122 samples+=4;
|
|
123 }
|
|
124
|
|
125 return ret;
|
|
126 }
|
|
127
|
|
128 /* needed for i386, i486 */
|
|
129 #ifdef OPT_I386_SYNTH
|
|
130 int synth_1to1_i386(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
131 {
|
|
132 static const int step = 2;
|
|
133 short *samples = (short *) (fr->buffer.data + fr->buffer.fill);
|
|
134
|
|
135 real *b0, **buf;
|
|
136 int clip = 0;
|
|
137 int bo1;
|
|
138
|
|
139 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
140
|
|
141 if(!channel) {
|
|
142 fr->bo[0]--;
|
|
143 fr->bo[0] &= 0xf;
|
|
144 buf = fr->real_buffs[0];
|
|
145 }
|
|
146 else {
|
|
147 samples++;
|
|
148 buf = fr->real_buffs[1];
|
|
149 }
|
|
150
|
|
151 if(fr->bo[0] & 0x1) {
|
|
152 b0 = buf[0];
|
|
153 bo1 = fr->bo[0];
|
|
154 dct64_i386(buf[1]+((fr->bo[0]+1)&0xf),buf[0]+fr->bo[0],bandPtr);
|
|
155 }
|
|
156 else {
|
|
157 b0 = buf[1];
|
|
158 bo1 = fr->bo[0]+1;
|
|
159 dct64_i386(buf[0]+fr->bo[0],buf[1]+fr->bo[0]+1,bandPtr);
|
|
160 }
|
|
161
|
|
162 {
|
|
163 register int j;
|
|
164 real *window = opt_decwin(fr) + 16 - bo1;
|
|
165
|
|
166 for (j=16;j;j--,b0+=0x10,window+=0x20,samples+=step)
|
|
167 {
|
|
168 real sum;
|
|
169 sum = window[0x0] * b0[0x0];
|
|
170 sum -= window[0x1] * b0[0x1];
|
|
171 sum += window[0x2] * b0[0x2];
|
|
172 sum -= window[0x3] * b0[0x3];
|
|
173 sum += window[0x4] * b0[0x4];
|
|
174 sum -= window[0x5] * b0[0x5];
|
|
175 sum += window[0x6] * b0[0x6];
|
|
176 sum -= window[0x7] * b0[0x7];
|
|
177 sum += window[0x8] * b0[0x8];
|
|
178 sum -= window[0x9] * b0[0x9];
|
|
179 sum += window[0xA] * b0[0xA];
|
|
180 sum -= window[0xB] * b0[0xB];
|
|
181 sum += window[0xC] * b0[0xC];
|
|
182 sum -= window[0xD] * b0[0xD];
|
|
183 sum += window[0xE] * b0[0xE];
|
|
184 sum -= window[0xF] * b0[0xF];
|
|
185
|
|
186 WRITE_SAMPLE(samples,sum,clip);
|
|
187 }
|
|
188
|
|
189 {
|
|
190 real sum;
|
|
191 sum = window[0x0] * b0[0x0];
|
|
192 sum += window[0x2] * b0[0x2];
|
|
193 sum += window[0x4] * b0[0x4];
|
|
194 sum += window[0x6] * b0[0x6];
|
|
195 sum += window[0x8] * b0[0x8];
|
|
196 sum += window[0xA] * b0[0xA];
|
|
197 sum += window[0xC] * b0[0xC];
|
|
198 sum += window[0xE] * b0[0xE];
|
|
199 WRITE_SAMPLE(samples,sum,clip);
|
|
200 b0-=0x10,window-=0x20,samples+=step;
|
|
201 }
|
|
202 window += bo1<<1;
|
|
203
|
|
204 for (j=15;j;j--,b0-=0x10,window-=0x20,samples+=step)
|
|
205 {
|
|
206 real sum;
|
|
207 sum = -window[-0x1] * b0[0x0];
|
|
208 sum -= window[-0x2] * b0[0x1];
|
|
209 sum -= window[-0x3] * b0[0x2];
|
|
210 sum -= window[-0x4] * b0[0x3];
|
|
211 sum -= window[-0x5] * b0[0x4];
|
|
212 sum -= window[-0x6] * b0[0x5];
|
|
213 sum -= window[-0x7] * b0[0x6];
|
|
214 sum -= window[-0x8] * b0[0x7];
|
|
215 sum -= window[-0x9] * b0[0x8];
|
|
216 sum -= window[-0xA] * b0[0x9];
|
|
217 sum -= window[-0xB] * b0[0xA];
|
|
218 sum -= window[-0xC] * b0[0xB];
|
|
219 sum -= window[-0xD] * b0[0xC];
|
|
220 sum -= window[-0xE] * b0[0xD];
|
|
221 sum -= window[-0xF] * b0[0xE];
|
|
222 sum -= window[-0x0] * b0[0xF];
|
|
223
|
|
224 WRITE_SAMPLE(samples,sum,clip);
|
|
225 }
|
|
226 }
|
|
227 if(final) fr->buffer.fill += 128;
|
|
228
|
|
229 return clip;
|
|
230 }
|
|
231 #endif
|
|
232
|
|
233 #ifdef OPT_PENTIUM
|
|
234 int synth_1to1_i586(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
235 {
|
|
236 int ret;
|
|
237 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
238
|
|
239 /* this is in asm, can be dither or not */
|
|
240 /* uh, is this return from pointer correct? */
|
|
241 ret = (int) opt_synth_1to1_i586_asm(fr)(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, fr->bo, fr->decwin);
|
|
242 if(final) fr->buffer.fill += 128;
|
|
243 return ret;
|
|
244 }
|
|
245 #endif
|
|
246
|
|
247 #ifdef OPT_3DNOW
|
|
248 int synth_1to1_3dnow(real *bandPtr,int channel, mpg123_handle *fr, int final)
|
|
249 {
|
|
250 int ret;
|
|
251
|
|
252 if(fr->have_eq_settings) do_equalizer_3dnow(bandPtr,channel,fr->equalizer);
|
|
253
|
|
254 /* this is in asm, can be dither or not */
|
|
255 /* uh, is this return from pointer correct? */
|
|
256 ret = (int) synth_1to1_3dnow_asm(bandPtr, channel, fr->buffer.data+fr->buffer.fill, fr->rawbuffs, fr->bo, fr->decwin);
|
|
257 if(final) fr->buffer.fill += 128;
|
|
258 return ret;
|
|
259 }
|
|
260 #endif
|
|
261
|
|
262 #ifdef OPT_MMX
|
|
263 /* wrapper for da interface */
|
|
264 int synth_1to1_mmx(real *bandPtr, int channel, mpg123_handle *fr, int final)
|
|
265 {
|
|
266 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
267
|
|
268 /* in asm */
|
|
269 synth_1to1_MMX(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, fr->bo, fr->decwins);
|
|
270 if(final) fr->buffer.fill += 128;
|
|
271 return 0;
|
|
272 }
|
|
273 #endif
|
|
274
|
|
275 #ifdef OPT_SSE
|
|
276 int synth_1to1_sse(real *bandPtr, int channel, mpg123_handle *fr, int final)
|
|
277 {
|
|
278 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
279
|
|
280 synth_1to1_sse_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, fr->bo, fr->decwins);
|
|
281 if(final) fr->buffer.fill += 128;
|
|
282 return 0;
|
|
283 }
|
|
284 #endif
|
|
285
|
|
286 #ifdef OPT_3DNOWEXT
|
|
287 int synth_1to1_3dnowext(real *bandPtr, int channel, mpg123_handle *fr, int final)
|
|
288 {
|
|
289 if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer);
|
|
290
|
|
291 synth_1to1_3dnowext_asm(bandPtr, channel, (short*) (fr->buffer.data+fr->buffer.fill), (short *) fr->rawbuffs, fr->bo, fr->decwins);
|
|
292 if(final) fr->buffer.fill += 128;
|
|
293 return 0;
|
|
294 }
|
|
295 #endif
|