Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
576 | serge | 1 | /* |
2 | decode_i486.c: i486 decode |
||
3 | |||
4 | copyright 1998-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.de |
||
6 | initially written by Fabrice Bellard |
||
7 | */ |
||
8 | |||
9 | /* |
||
10 | * Subband Synthesis for MPEG Audio. |
||
11 | * |
||
12 | * Version optimized for 80486 by using integer arithmetic, |
||
13 | * multiplications by shift and add, and by increasing locality in |
||
14 | * order to fit the 8KB L1 cache. This code should be compiled with gcc |
||
15 | * 2.7.2 or higher. |
||
16 | * |
||
17 | * Note: this version does not guaranty a good accuracy. The filter |
||
18 | * coefficients are quantified on 14 bits. |
||
19 | * |
||
20 | * (c) 1998 Fabrice Bellard |
||
21 | */ |
||
22 | |||
23 | //#include |
||
24 | #include "mpg123.h" |
||
25 | |||
26 | #define FIR_SIZE 16 |
||
27 | |||
28 | #define FIR16_1(pos,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15) \ |
||
29 | {\ |
||
30 | int sum;\ |
||
31 | sum=(c0)*b0[0]+(c1)*b0[1]+(c2)*b0[2]+(c3)*b0[3]+\ |
||
32 | (c4)*b0[4]+(c5)*b0[5]+(c6)*b0[6]+(c7)*b0[7]+\ |
||
33 | (c8)*b0[8]+(c9)*b0[9]+(c10)*b0[10]+(c11)*b0[11]+\ |
||
34 | (c12)*b0[12]+(c13)*b0[13]+(c14)*b0[14]+(c15)*b0[15];\ |
||
35 | sum=(sum+(1 << 13))>>14;\ |
||
36 | if (sum<-32768) sum=-32768;\ |
||
37 | else if (sum>32767) sum=32767;\ |
||
38 | samples[2*(pos)]=sum;\ |
||
39 | b0+=FIR_BUFFER_SIZE;\ |
||
40 | } |
||
41 | |||
42 | #define FIR16_2(pos1,c0,c1,c2,c3,c4,c5,c6,c7,c8,c9,c10,c11,c12,c13,c14,c15,\ |
||
43 | pos2,d0,d1,d2,d3,d4,d5,d6,d7,d8,d9,d10,d11,d12,d13,d14,d15) \ |
||
44 | {\ |
||
45 | int sum1,sum2,v;\ |
||
46 | \ |
||
47 | v=b0[0];\ |
||
48 | sum1=(c0)*v;\ |
||
49 | sum2=(d0)*v;\ |
||
50 | v=b0[1];\ |
||
51 | sum1+=(c1)*v;\ |
||
52 | sum2+=(d1)*v;\ |
||
53 | v=b0[2];\ |
||
54 | sum1+=(c2)*v;\ |
||
55 | sum2+=(d2)*v;\ |
||
56 | v=b0[3];\ |
||
57 | sum1+=(c3)*v;\ |
||
58 | sum2+=(d3)*v;\ |
||
59 | v=b0[4];\ |
||
60 | sum1+=(c4)*v;\ |
||
61 | sum2+=(d4)*v;\ |
||
62 | v=b0[5];\ |
||
63 | sum1+=(c5)*v;\ |
||
64 | sum2+=(d5)*v;\ |
||
65 | v=b0[6];\ |
||
66 | sum1+=(c6)*v;\ |
||
67 | sum2+=(d6)*v;\ |
||
68 | v=b0[7];\ |
||
69 | sum1+=(c7)*v;\ |
||
70 | sum2+=(d7)*v;\ |
||
71 | v=b0[8];\ |
||
72 | sum1+=(c8)*v;\ |
||
73 | sum2+=(d8)*v;\ |
||
74 | v=b0[9];\ |
||
75 | sum1+=(c9)*v;\ |
||
76 | sum2+=(d9)*v;\ |
||
77 | v=b0[10];\ |
||
78 | sum1+=(c10)*v;\ |
||
79 | sum2+=(d10)*v;\ |
||
80 | v=b0[11];\ |
||
81 | sum1+=(c11)*v;\ |
||
82 | sum2+=(d11)*v;\ |
||
83 | v=b0[12];\ |
||
84 | sum1+=(c12)*v;\ |
||
85 | sum2+=(d12)*v;\ |
||
86 | v=b0[13];\ |
||
87 | sum1+=(c13)*v;\ |
||
88 | sum2+=(d13)*v;\ |
||
89 | v=b0[14];\ |
||
90 | sum1+=(c14)*v;\ |
||
91 | sum2+=(d14)*v;\ |
||
92 | v=b0[15];\ |
||
93 | sum1+=(c15)*v;\ |
||
94 | sum2+=(d15)*v;\ |
||
95 | \ |
||
96 | sum1=(sum1+(1<<13))>>14;\ |
||
97 | sum2=(sum2+(1<<13))>>14;\ |
||
98 | \ |
||
99 | if (sum1<-32768) sum1=-32768;\ |
||
100 | else if (sum1>32767) sum1=32767;\ |
||
101 | samples[(pos1)*2]=sum1;\ |
||
102 | \ |
||
103 | if (sum2<-32768) sum2=-32768;\ |
||
104 | else if (sum2>32767) sum2=32767;\ |
||
105 | samples[(pos2)*2]=sum2;\ |
||
106 | b0+=FIR_BUFFER_SIZE;\ |
||
107 | } |
||
108 | |||
109 | int synth_1to1_486(real *bandPtr,int channel,unsigned char *out,int nb_blocks) |
||
110 | { |
||
111 | static int buffs[2][2][17*FIR_BUFFER_SIZE]; |
||
112 | static int bo[2] = { FIR_SIZE-1, FIR_SIZE-1 }; |
||
113 | short *samples = (short *) out; |
||
114 | int *b0,(*buf)[17*FIR_BUFFER_SIZE]; |
||
115 | int clip = 0; |
||
116 | int block,b,bo_start; |
||
117 | |||
118 | /* samples address */ |
||
119 | samples+=channel; |
||
120 | |||
121 | bo_start=bo[channel]; |
||
122 | buf = buffs[channel]; |
||
123 | |||
124 | b=bo_start; |
||
125 | for(block=0;block |
||
126 | |||
127 | /* FIR offset */ |
||
128 | b++; |
||
129 | if (b >= FIR_BUFFER_SIZE) { |
||
130 | int *p,*q; |
||
131 | int c,i,j; |
||
132 | |||
133 | /* we shift the buffers */ |
||
134 | for(c=0;c<2;c++) { |
||
135 | p=&buf[c][0]+1; |
||
136 | q=p+(FIR_BUFFER_SIZE-FIR_SIZE); |
||
137 | for(i=0;i<17;i++) { |
||
138 | for(j=0;j |
||
139 | p+=FIR_BUFFER_SIZE; |
||
140 | q+=FIR_BUFFER_SIZE; |
||
141 | } |
||
142 | } |
||
143 | /* we update 'bo' accordingly */ |
||
144 | b=bo[channel]=FIR_SIZE; |
||
145 | } |
||
146 | |||
147 | if(b & 1) { |
||
148 | dct64_486(buf[1]+b,buf[0]+b,bandPtr); |
||
149 | } else { |
||
150 | dct64_486(buf[0]+b,buf[1]+b,bandPtr); |
||
151 | } |
||
152 | bandPtr+=32; |
||
153 | } |
||
154 | bo[channel]=b; |
||
155 | |||
156 | /* filter bank: part 1 */ |
||
157 | b=bo_start; |
||
158 | for(block=0;block |
||
159 | b++; |
||
160 | if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE; |
||
161 | if(b & 1) { |
||
162 | b0 = buf[0] + b - (FIR_SIZE-1); |
||
163 | } else { |
||
164 | b0 = buf[1] + b - (FIR_SIZE-1); |
||
165 | } |
||
166 | |||
167 | FIR16_1(0,-7,53,-114,509,-1288,1643,-9372,18759,9372,1643,1288,509,114,53,7,0); |
||
168 | FIR16_2(1,-6,52,-100,515,-1197,1783,-8910,18748,9834,1489,1379,500,129,54,7,0, |
||
169 | 31,0,-7,54,-129,500,-1379,1489,-9834,18748,8910,1783,1197,515,100,52,6); |
||
170 | FIR16_2(2,-6,50,-86,520,-1106,1910,-8447,18714,10294,1322,1469,488,145,55,8,0, |
||
171 | 30,0,-8,55,-145,488,-1469,1322,-10294,18714,8447,1910,1106,520,86,50,6); |
||
172 | FIR16_2(3,-5,49,-73,521,-1015,2023,-7986,18657,10751,1140,1559,473,161,56,9,0, |
||
173 | 29,0,-9,56,-161,473,-1559,1140,-10751,18657,7986,2023,1015,521,73,49,5); |
||
174 | samples+=64; |
||
175 | } |
||
176 | samples-=64*nb_blocks; |
||
177 | |||
178 | /* filter bank: part 2 */ |
||
179 | |||
180 | b=bo_start; |
||
181 | for(block=0;block |
||
182 | b++; |
||
183 | if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE; |
||
184 | if(b & 1) { |
||
185 | b0 = buf[0] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE; |
||
186 | } else { |
||
187 | b0 = buf[1] + b - (FIR_SIZE-1) + 4*FIR_BUFFER_SIZE; |
||
188 | } |
||
189 | |||
190 | FIR16_2(4,-4,47,-61,521,-926,2123,-7528,18578,11205,944,1647,455,177,56,10,0, |
||
191 | 28,0,-10,56,-177,455,-1647,944,-11205,18578,7528,2123,926,521,61,47,4); |
||
192 | FIR16_2(5,-4,45,-49,518,-837,2210,-7072,18477,11654,733,1733,434,194,57,11,0, |
||
193 | 27,0,-11,57,-194,434,-1733,733,-11654,18477,7072,2210,837,518,49,45,4); |
||
194 | FIR16_2(6,-4,44,-38,514,-751,2284,-6620,18353,12097,509,1817,411,212,57,12,0, |
||
195 | 26,0,-12,57,-212,411,-1817,509,-12097,18353,6620,2284,751,514,38,44,4); |
||
196 | FIR16_2(7,-3,42,-27,508,-665,2347,-6173,18208,12534,270,1899,383,229,56,13,0, |
||
197 | 25,0,-13,56,-229,383,-1899,270,-12534,18208,6173,2347,665,508,27,42,3); |
||
198 | |||
199 | samples+=64; |
||
200 | } |
||
201 | samples-=64*nb_blocks; |
||
202 | |||
203 | /* filter bank: part 3 */ |
||
204 | |||
205 | b=bo_start; |
||
206 | for(block=0;block |
||
207 | b++; |
||
208 | if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE; |
||
209 | if(b & 1) { |
||
210 | b0 = buf[0] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE; |
||
211 | } else { |
||
212 | b0 = buf[1] + b - (FIR_SIZE-1) + 8*FIR_BUFFER_SIZE; |
||
213 | } |
||
214 | |||
215 | FIR16_2(8,-3,40,-18,500,-582,2398,-5732,18042,12963,17,1977,353,247,56,14,0, |
||
216 | 24,0,-14,56,-247,353,-1977,17,-12963,18042,5732,2398,582,500,18,40,3); |
||
217 | FIR16_2(9,-2,38,-9,490,-501,2437,-5297,17855,13383,-249,2052,320,266,55,15,0, |
||
218 | 23,0,-15,55,-266,320,-2052,-249,-13383,17855,5297,2437,501,490,9,38,2); |
||
219 | FIR16_2(10,-2,36,0,479,-423,2465,-4869,17647,13794,-530,2122,282,284,53,17,0, |
||
220 | 22,0,-17,53,-284,282,-2122,-530,-13794,17647,4869,2465,423,479,0,36,2); |
||
221 | FIR16_2(11,-2,34,7,467,-347,2483,-4449,17419,14194,-825,2188,242,302,52,18,0, |
||
222 | 21,0,-18,52,-302,242,-2188,-825,-14194,17419,4449,2483,347,467,-7,34,2); |
||
223 | |||
224 | samples+=64; |
||
225 | } |
||
226 | samples-=64*nb_blocks; |
||
227 | |||
228 | /* filter bank: part 4 */ |
||
229 | |||
230 | b=bo_start; |
||
231 | for(block=0;block |
||
232 | b++; |
||
233 | if (b >= FIR_BUFFER_SIZE) b=FIR_SIZE; |
||
234 | if(b & 1) { |
||
235 | b0 = buf[0] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE; |
||
236 | } else { |
||
237 | b0 = buf[1] + b - (FIR_SIZE-1) + 12*FIR_BUFFER_SIZE; |
||
238 | } |
||
239 | |||
240 | FIR16_2(12,-2,33,14,454,-273,2491,-4038,17173,14583,-1133,2249,198,320,50,19,0, |
||
241 | 20,0,-19,50,-320,198,-2249,-1133,-14583,17173,4038,2491,273,454,-14,33,2); |
||
242 | FIR16_2(13,-1,31,20,439,-203,2489,-3637,16907,14959,-1454,2304,151,339,47,21,-1, |
||
243 | 19,-1,-21,47,-339,151,-2304,-1454,-14959,16907,3637,2489,203,439,-20,31,1); |
||
244 | FIR16_2(14,-1,29,26,424,-136,2479,-3245,16623,15322,-1788,2354,100,357,44,22,-1, |
||
245 | 18,-1,-22,44,-357,100,-2354,-1788,-15322,16623,3245,2479,136,424,-26,29,1); |
||
246 | FIR16_2(15,-1,27,31,408,-72,2459,-2863,16322,15671,-2135,2396,46,374,40,24,-1, |
||
247 | 17,-1,-24,40,-374,46,-2396,-2135,-15671,16322,2863,2459,72,408,-31,27,1); |
||
248 | FIR16_1(16,-1,0,36,0,-11,0,-2493,0,16004,0,2431,0,391,0,26,0); |
||
249 | |||
250 | samples+=64; |
||
251 | } |
||
252 | |||
253 | return clip; |
||
254 | }17;i++)>2;c++)>-32768)>-32768)>13))><13))>13))><13))>-32768)>><> |
||
255 |