Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
1905 | serge | 1 | /* |
2 | synth.h: generic synth functions |
||
3 | |||
4 | copyright 1995-2008 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, generalized by Thomas Orgis |
||
7 | |||
8 | This header is used multiple times to create different variants of these functions. |
||
9 | See decode.c and friends. |
||
10 | Hint: BLOCK, MONO_NAME, MONO2STEREO_NAME, SYNTH_NAME and SAMPLE_T as well as WRITE_SAMPLE do vary. |
||
11 | |||
12 | Thomas looked closely at the decode_1to1, decode_2to1 and decode_4to1 contents, seeing that they are too similar to be separate files. |
||
13 | This is what resulted... |
||
14 | |||
15 | Basically, you need one set of these functions for each output sample type. |
||
16 | That currently means signed short, 8bit or float/double; though unsigned short may come, too. |
||
17 | |||
18 | Define NO_AUTOINCREMENT i386 code that shall not rely on autoincrement. |
||
19 | Actual benefit of this has to be examined; may apply to specific (old) compilers, only. |
||
20 | */ |
||
21 | |||
22 | |||
23 | /* Main synth function, uses the plain dct64 or dct64_i386. */ |
||
24 | int SYNTH_NAME(real *bandPtr, int channel, mpg123_handle *fr, int final) |
||
25 | { |
||
26 | #ifndef NO_AUTOINCREMENT |
||
27 | #define BACKPEDAL 0x10 /* We use autoincrement and thus need this re-adjustment for window/b0. */ |
||
28 | #define MY_DCT64 dct64 |
||
29 | #else |
||
30 | #define BACKPEDAL 0x00 /* i386 code does not need that. */ |
||
31 | #define MY_DCT64 dct64_i386 |
||
32 | #endif |
||
33 | static const int step = 2; |
||
34 | SAMPLE_T *samples = (SAMPLE_T *) (fr->buffer.data + fr->buffer.fill); |
||
35 | |||
36 | real *b0, **buf; /* (*buf)[0x110]; */ |
||
37 | int clip = 0; |
||
38 | int bo1; |
||
39 | |||
40 | if(fr->have_eq_settings) do_equalizer(bandPtr,channel,fr->equalizer); |
||
41 | |||
42 | if(!channel) |
||
43 | { |
||
44 | fr->bo--; |
||
45 | fr->bo &= 0xf; |
||
46 | buf = fr->real_buffs[0]; |
||
47 | } |
||
48 | else |
||
49 | { |
||
50 | #ifdef USE_DITHER |
||
51 | /* We always go forward 32 dither points (and back again for the second channel), |
||
52 | (re)sampling the noise the same way as the original signal. */ |
||
53 | fr->ditherindex -= 32; |
||
54 | #endif |
||
55 | samples++; |
||
56 | buf = fr->real_buffs[1]; |
||
57 | } |
||
58 | #ifdef USE_DITHER |
||
59 | /* We check only once for the overflow of dither index here ... |
||
60 | this wraps differently than the original i586 dither code, in theory (but when DITHERSIZE % BLOCK/2 == 0 it's the same). */ |
||
61 | if(DITHERSIZE-fr->ditherindex < 32) fr->ditherindex = 0; |
||
62 | /* And we define a macro for the dither action... */ |
||
63 | #define ADD_DITHER(fr,sum) sum+=fr->dithernoise[fr->ditherindex]; fr->ditherindex += 64/BLOCK; |
||
64 | #else |
||
65 | #define ADD_DITHER(fr,sum) |
||
66 | #endif |
||
67 | |||
68 | if(fr->bo & 0x1) |
||
69 | { |
||
70 | b0 = buf[0]; |
||
71 | bo1 = fr->bo; |
||
72 | MY_DCT64(buf[1]+((fr->bo+1)&0xf),buf[0]+fr->bo,bandPtr); |
||
73 | } |
||
74 | else |
||
75 | { |
||
76 | b0 = buf[1]; |
||
77 | bo1 = fr->bo+1; |
||
78 | MY_DCT64(buf[0]+fr->bo,buf[1]+fr->bo+1,bandPtr); |
||
79 | } |
||
80 | |||
81 | { |
||
82 | register int j; |
||
83 | real *window = fr->decwin + 16 - bo1; |
||
84 | |||
85 | for(j=(BLOCK/4); j; j--, b0+=0x400/BLOCK-BACKPEDAL, window+=0x800/BLOCK-BACKPEDAL, samples+=step) |
||
86 | { |
||
87 | real sum; |
||
88 | #ifndef NO_AUTOINCREMENT |
||
89 | sum = REAL_MUL_SYNTH(*window++, *b0++); |
||
90 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
91 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
92 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
93 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
94 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
95 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
96 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
97 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
98 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
99 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
100 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
101 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
102 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
103 | sum += REAL_MUL_SYNTH(*window++, *b0++); |
||
104 | sum -= REAL_MUL_SYNTH(*window++, *b0++); |
||
105 | #else |
||
106 | sum = REAL_MUL_SYNTH(window[0x0], b0[0x0]); |
||
107 | sum -= REAL_MUL_SYNTH(window[0x1], b0[0x1]); |
||
108 | sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]); |
||
109 | sum -= REAL_MUL_SYNTH(window[0x3], b0[0x3]); |
||
110 | sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]); |
||
111 | sum -= REAL_MUL_SYNTH(window[0x5], b0[0x5]); |
||
112 | sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]); |
||
113 | sum -= REAL_MUL_SYNTH(window[0x7], b0[0x7]); |
||
114 | sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]); |
||
115 | sum -= REAL_MUL_SYNTH(window[0x9], b0[0x9]); |
||
116 | sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]); |
||
117 | sum -= REAL_MUL_SYNTH(window[0xB], b0[0xB]); |
||
118 | sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]); |
||
119 | sum -= REAL_MUL_SYNTH(window[0xD], b0[0xD]); |
||
120 | sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]); |
||
121 | sum -= REAL_MUL_SYNTH(window[0xF], b0[0xF]); |
||
122 | #endif |
||
123 | |||
124 | ADD_DITHER(fr,sum) |
||
125 | WRITE_SAMPLE(samples,sum,clip); |
||
126 | } |
||
127 | |||
128 | { |
||
129 | real sum; |
||
130 | sum = REAL_MUL_SYNTH(window[0x0], b0[0x0]); |
||
131 | sum += REAL_MUL_SYNTH(window[0x2], b0[0x2]); |
||
132 | sum += REAL_MUL_SYNTH(window[0x4], b0[0x4]); |
||
133 | sum += REAL_MUL_SYNTH(window[0x6], b0[0x6]); |
||
134 | sum += REAL_MUL_SYNTH(window[0x8], b0[0x8]); |
||
135 | sum += REAL_MUL_SYNTH(window[0xA], b0[0xA]); |
||
136 | sum += REAL_MUL_SYNTH(window[0xC], b0[0xC]); |
||
137 | sum += REAL_MUL_SYNTH(window[0xE], b0[0xE]); |
||
138 | |||
139 | ADD_DITHER(fr,sum) |
||
140 | WRITE_SAMPLE(samples,sum,clip); |
||
141 | samples += step; |
||
142 | b0-=0x400/BLOCK; |
||
143 | window-=0x800/BLOCK; |
||
144 | } |
||
145 | window += bo1<<1; |
||
146 | |||
147 | for(j=(BLOCK/4)-1; j; j--, b0-=0x400/BLOCK+BACKPEDAL, window-=0x800/BLOCK-BACKPEDAL, samples+=step) |
||
148 | { |
||
149 | real sum; |
||
150 | #ifndef NO_AUTOINCREMENT |
||
151 | sum = -REAL_MUL_SYNTH(*(--window), *b0++); |
||
152 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
153 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
154 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
155 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
156 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
157 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
158 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
159 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
160 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
161 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
162 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
163 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
164 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
165 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
166 | sum -= REAL_MUL_SYNTH(*(--window), *b0++); |
||
167 | #else |
||
168 | sum = -REAL_MUL_SYNTH(window[-0x1], b0[0x0]); |
||
169 | sum -= REAL_MUL_SYNTH(window[-0x2], b0[0x1]); |
||
170 | sum -= REAL_MUL_SYNTH(window[-0x3], b0[0x2]); |
||
171 | sum -= REAL_MUL_SYNTH(window[-0x4], b0[0x3]); |
||
172 | sum -= REAL_MUL_SYNTH(window[-0x5], b0[0x4]); |
||
173 | sum -= REAL_MUL_SYNTH(window[-0x6], b0[0x5]); |
||
174 | sum -= REAL_MUL_SYNTH(window[-0x7], b0[0x6]); |
||
175 | sum -= REAL_MUL_SYNTH(window[-0x8], b0[0x7]); |
||
176 | sum -= REAL_MUL_SYNTH(window[-0x9], b0[0x8]); |
||
177 | sum -= REAL_MUL_SYNTH(window[-0xA], b0[0x9]); |
||
178 | sum -= REAL_MUL_SYNTH(window[-0xB], b0[0xA]); |
||
179 | sum -= REAL_MUL_SYNTH(window[-0xC], b0[0xB]); |
||
180 | sum -= REAL_MUL_SYNTH(window[-0xD], b0[0xC]); |
||
181 | sum -= REAL_MUL_SYNTH(window[-0xE], b0[0xD]); |
||
182 | sum -= REAL_MUL_SYNTH(window[-0xF], b0[0xE]); |
||
183 | sum -= REAL_MUL_SYNTH(window[-0x0], b0[0xF]); /* Is that right? 0x0? Just wondering... */ |
||
184 | #endif |
||
185 | ADD_DITHER(fr,sum) |
||
186 | WRITE_SAMPLE(samples,sum,clip); |
||
187 | } |
||
188 | } |
||
189 | |||
190 | if(final) fr->buffer.fill += BLOCK*sizeof(SAMPLE_T); |
||
191 | |||
192 | return clip; |
||
193 | #undef ADD_DITHER |
||
194 | #undef BACKPEDAL |
||
195 | #undef MY_DCT64 |
||
196 | }1; |