Subversion Repositories Kolibri OS

Rev

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
}