comparison Plugins/Input/mpg123/psycho.c @ 1090:09eb2c83097a trunk

[svn] Psychoaccoustics support (to disable, temporarily add -UPSYCHO to your CFLAGS.): This commit brings psychoaccoustics support (as used in mp3surround decoders) to libmpgdec. For example, we can now almost fully compensate for lack of bandwidth in ISO compliant MP3 encodings. In addition, further inaccuracies with pitch and the lack of reverb feeling that some MP3s have are detected and automatically compensated for.
author nenolod
date Sat, 20 May 2006 20:36:10 -0700
parents
children 5b6fcb22f3c4
comparison
equal deleted inserted replaced
1089:e75c7856fbea 1090:09eb2c83097a
1 /* libmpgdec: An advanced MPEG layer 1/2/3 decoder.
2 * psycho.c: Psychoaccoustic modeling.
3 *
4 * Copyright (C) 2005-2006 William Pitcock <nenolod@nenolod.net>
5 * Portions copyright (C) 2001 Rafal Bosak <gyver@fanthom.irc.pl>
6 * Portions copyright (C) 1999 Michael Hipp
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <math.h>
26
27 #include "common.h"
28
29 int bext_level;
30 int echo_level;
31 int stereo_level;
32 int filter_level;
33 int feedback_level;
34 int harmonics_level;
35 int bext_sfactor;
36 int echo_sfactor;
37 int stereo_sfactor;
38 int feedback_sfactor;
39 int harmonics_sfactor;
40 int enable_plugin = 1;
41 int lsine[65536];
42 int rsine[65536];
43
44 /*
45 * Initialize and configure the psychoaccoustics engine.
46 */
47 void psycho_init(void)
48 {
49 int i, x;
50 double lsum;
51 double rsum;
52
53 bext_level = 28;
54 echo_level = echo_sfactor = 11;
55 stereo_level = stereo_sfactor = 11;
56 filter_level = 3;
57 feedback_level = 30;
58 harmonics_level = harmonics_sfactor = 43;
59
60 bext_sfactor = (float)(((float)16384 * 10) / (float)(bext_level + 1)) + (float)(102 - bext_level) * 128;
61 feedback_sfactor = (feedback_level * 3) / 2;
62
63 #define COND 0
64 /* calculate sinetables */
65 for (i = 0; i < 32768; ++i)
66 {
67 lsum = rsum = 0;
68 if (COND || i < 32768 )lsum+= ((cos((double)i * 3.141592535 / 32768/2 )) + 0) / 2;
69 if (COND || i < 16384 )rsum-= ((cos((double)i * 3.141592535 / 16384/2 )) + 0) / 4;
70 rsum = lsum;
71
72 if (COND || i < 8192 ) lsum += ((cos((double)i * 3.141592535 / 8192/2 )) + 0) / 8;
73 if (COND || i < 5641 ) rsum += ((cos((double)i * 3.141592535 / 5641.333333/2)) + 0) / 8;
74
75 lsine[32768 + i] = (double)(lsum - 0.5) * 32768 * 1.45;
76 lsine[32768 - i] = lsine[32768 + i];
77 rsine[32768 + i] = (double)(rsum - 0.5) * 32768 * 1.45;
78 rsine[32768 - i] = rsine[32768 + i];
79
80 x = i;
81 }
82 }
83
84 /*
85 * This routine computes a reverb for the track.
86 */
87
88 #define DELAY2 21000
89 #define DELAY1 35000
90 #define DELAY3 14000
91 #define DELAY4 5
92
93 #define BUF_SIZE DELAY1+DELAY2+DELAY3+DELAY4
94
95 void echo3d(gint16 *data, int datasize)
96 {
97 int x;
98 int left, right, dif, left0, right0, left1, right1, left2, right2, left3, right3, left4, right4, leftc, rightc, lsf, rsf;
99 static int left0p = 0, right0p = 0;
100 static int rangeErrorsUp = 0;
101 static int rangeErrorsDown = 0;
102 gint16 *dataptr;
103 static int l0, l1, l2, r0, r1, r2, ls, rs, ls1, rs1;
104 static int ll0, ll1, ll2, rr0, rr1, rr2;
105 static int lharmb = 0, rharmb = 0, lhfb = 0, rhfb = 0;
106 int lharm0, rharm0;
107 static gint16 buf[BUF_SIZE];
108 static int bufPos = BUF_SIZE - 1;
109 static int bufPos1 = 1 + BUF_SIZE - DELAY1;
110 static int bufPos2 = 1 + BUF_SIZE - DELAY1 - DELAY2;
111 static int bufPos3 = 1 + BUF_SIZE - DELAY1 - DELAY2 - DELAY3;
112 static int bufPos4 = 1 + BUF_SIZE - DELAY1 - DELAY2 - DELAY3 - DELAY4;
113 dataptr = data;
114
115 for (x = 0; x < datasize; x += 4) {
116
117 // ************ load sample **********
118 left0 = dataptr[0];
119 right0 = dataptr[1];
120
121 // ************ slightly expand stereo for direct input **********
122 ll0=left0;rr0=right0;
123 dif = (ll0+ll1+ll2 - rr0-rr1-rr2) * stereo_sfactor / 256;
124 left0 += dif;
125 right0 -= dif;
126 ll2= ll1; ll1= ll0;
127 rr2= rr1; rr1= rr0;
128
129 // ************ echo from buffer - first echo **********
130 // ************ **********
131 left1 = buf[bufPos1++];
132 if (bufPos1 == BUF_SIZE)
133 bufPos1 = 0;
134 right1 = buf[bufPos1++];
135 if (bufPos1 == BUF_SIZE)
136 bufPos1 = 0;
137
138 // ************ highly expand stereo for first echo **********
139 dif = (left1 - right1);
140 left1 = left1 + dif;
141 right1 = right1 - dif;
142
143 // ************ second echo **********
144 left2 = buf[bufPos2++];
145 if (bufPos2 == BUF_SIZE)
146 bufPos2 = 0;
147 right2 = buf[bufPos2++];
148 if (bufPos2 == BUF_SIZE)
149 bufPos2 = 0;
150
151 // ************ expand stereo for second echo **********
152 dif = (left2 - right2);
153 left2 = left2 - dif;
154 right2 = right2 - dif;
155
156 // ************ third echo **********
157 left3 = buf[bufPos3++];
158 if (bufPos3 == BUF_SIZE)
159 bufPos3 = 0;
160 right3 = buf[bufPos3++];
161 if (bufPos3 == BUF_SIZE)
162 bufPos3 = 0;
163
164 // ************ fourth echo **********
165 left4 = buf[bufPos4++];
166 if (bufPos4 == BUF_SIZE)
167 bufPos4 = 0;
168 right4 = buf[bufPos4++];
169 if (bufPos4 == BUF_SIZE)
170 bufPos4 = 0;
171
172 left3 = (left4+left3) / 2;
173 right3 = (right4+right3) / 2;
174
175 // ************ expand stereo for second echo **********
176 dif = (left4 - right4);
177 left3 = left3 - dif;
178 right3 = right3 - dif;
179
180 // ************ a weighted sum taken from reverb buffer **********
181 leftc = left1 / 9 + right2 /8 + left3 / 8;
182 rightc = right1 / 11 + left2 / 9 + right3 / 10;
183
184 left = left0p + leftc * echo_sfactor / 16;
185 right = right0p + rightc * echo_sfactor / 16;
186
187 l0 = leftc + left0 / 2;
188 r0 = rightc + right0 / 2;
189
190 ls = l0 + l1 + l2; // do not reverb high frequencies (filter)
191 rs = r0 + r1 + r2; //
192
193 buf[bufPos++] = ls * feedback_sfactor / 256;
194 if (bufPos == BUF_SIZE)
195 bufPos = 0;
196 buf[bufPos++] = rs * feedback_sfactor / 256;
197 if (bufPos == BUF_SIZE)
198 bufPos = 0;
199
200 // ************ add some extra even harmonics **********
201 // ************ or rather specific nonlinearity
202
203 lhfb = lhfb + (ls * 32768 - lhfb) / 32;
204 rhfb = rhfb + (rs * 32768 - rhfb) / 32;
205
206 lsf = ls - lhfb / 32768;
207 rsf = rs - rhfb / 32768;
208
209 lharm0 = 0
210 + ((lsf + 10000) * ((((lsine[((lsf/4) + 32768 + 65536) % 65536] * harmonics_sfactor)) / 64))) / 32768
211 - ((lsine[((lsf/4) + 32768 +65536) % 65536]) * harmonics_sfactor) / 128
212 ;
213
214 rharm0 =
215 + ((rsf + 10000) * ((((lsine[((rsf/4) + 32768 + 65536) % 65536] * harmonics_sfactor)) / 64))) / 32768
216 - ((rsine[((rsf/4) + 32768 +65536) % 65536]) * harmonics_sfactor) / 128
217 ;
218
219 lharmb = lharmb + (lharm0 * 32768 - lharmb) / 16384;
220 rharmb = rharmb + (rharm0 * 32768 - rharmb) / 16384;
221
222 // ************ for convolution filters **********
223 l2= l1; r2= r1;
224 l1 = l0; r1 = r0;
225 ls1 = ls; rs1 = rs;
226
227 left = 0 + lharm0 - lharmb / 32768 + left;
228 right = 0 + rharm0 - rharmb / 32768 + right;
229
230 left0p = left0;
231 right0p = right0;
232
233
234 // ************ limiter **********
235 if (left < -32768) {
236 left = -32768; // limit
237 rangeErrorsDown++;
238 }
239 else if (left > 32767) {
240 left = 32767;
241 rangeErrorsUp++;
242 }
243 if (right < -32768) {
244 right = -32768;
245 rangeErrorsDown++;
246 }
247 else if (right > 32767) {
248 right = 32767;
249 rangeErrorsUp++;
250 }
251 // ************ store sample **********
252 dataptr[0] = left;
253 dataptr[1] = right;
254 dataptr += 2;
255
256 }
257 }
258
259 /*
260 * simple pith shifter, plays short fragments at 1.5 speed
261 */
262 void pitchShifter(const int lin, const int rin, int *lout, int *rout)
263 {
264 #define SH_BUF_SIZE 100 * 3
265 static gint16 shBuf[SH_BUF_SIZE];
266 static int shBufPos = SH_BUF_SIZE - 6;
267 static int shBufPos1 = SH_BUF_SIZE - 6;
268 static int cond;
269
270 shBuf[shBufPos++] = lin;
271 shBuf[shBufPos++] = rin;
272
273 if (shBufPos == SH_BUF_SIZE) shBufPos = 0;
274
275 switch (cond){
276 case 1:
277 *lout = (shBuf[shBufPos1 + 0] * 2 + shBuf[shBufPos1 + 2])/4;
278 *rout = (shBuf[shBufPos1 + 1] * 2 + shBuf[shBufPos1 + 3])/4;
279 break;
280 case 0:
281 *lout = (shBuf[shBufPos1 + 4] * 2 + shBuf[shBufPos1 + 2])/4;
282 *rout = (shBuf[shBufPos1 + 5] * 2 + shBuf[shBufPos1 + 3])/4;
283 cond = 2;
284 shBufPos1 += 6;
285 if (shBufPos1 == SH_BUF_SIZE) {
286 shBufPos1 = 0;
287 }
288 break;
289 }
290 cond--;
291 }
292
293
294 struct Interpolation{
295 int acount; // counter
296 int lval, rval; // value
297 int sal, sar; // sum
298 int al, ar;
299 int a1l, a1r;
300 };
301
302 /*
303 * interpolation routine for ampliude and "energy"
304 */
305 static inline void interpolate(struct Interpolation *s, int l, int r)
306 {
307 #define AMPL_COUNT 64
308 int a0l, a0r, dal = 0, dar = 0;
309
310 if (l < 0) l = -l;
311 if (r < 0) r = -r;
312
313 s->lval += l / 8;
314 s->rval += r / 8;
315
316 s->lval = (s->lval * 120) / 128;
317 s->rval = (s->rval * 120) / 128;
318
319 s->sal += s->lval;
320 s->sar += s->rval;
321
322 s->acount++;
323 if (s->acount == AMPL_COUNT){
324 s->acount = 0;
325 a0l = s->a1l;
326 a0r = s->a1r;
327 s->a1l = s->sal / AMPL_COUNT;
328 s->a1r = s->sar / AMPL_COUNT;
329 s->sal = 0;
330 s->sar = 0;
331 dal = s->a1l - a0l;
332 dar = s->a1r - a0r;
333 s->al = a0l * AMPL_COUNT;
334 s->ar = a0r * AMPL_COUNT;
335 }
336
337 s->al += dal;
338 s->ar += dar;
339 }
340
341 /*
342 * calculate scalefactor for mixer
343 */
344 inline int calc_scalefactor(int a, int e)
345 {
346 int x;
347
348 if (a > 8192) a = 8192;
349 else if (a < 0) a = 0;
350
351 if (e > 8192) e = 8192;
352 else if (e < 0) e = 0;
353
354 x = ((e+500) * 4096 )/ (a + 300) + e;
355
356 if (x > 16384) x = 16384;
357 else if (x < 0) x = 0;
358 return x;
359 }
360
361 static struct Interpolation bandext_energy;
362 static struct Interpolation bandext_amplitude;
363
364 /*
365 * exact bandwidth extender ("exciter") routine
366 */
367 static void bandext(gint16 *data, const int datasize)
368 {
369
370 int x;
371 static int saw; // test stuff
372 int left, right;
373 gint16 *dataptr = data;
374 static int lprev0, rprev0, lprev1, rprev1, lprev2, rprev2;
375 int left0, right0, left1, right1, left2, right2, left3, right3;
376 static int lamplUp, lamplDown;
377 static int ramplUp, ramplDown;
378 int lampl, rampl;
379 int tmp;
380
381 for (x = 0; x < datasize; x += 4) {
382
383 // ************ load sample **********
384 left0 = dataptr[0];
385 right0 = dataptr[1];
386
387 // ************ highpass filter part 1 **********
388 left1 = (left0 - lprev0) * 56880 / 65536;
389 right1 = (right0 - rprev0) * 56880 / 65536;
390
391 left2 = (left1 - lprev1) * 56880 / 65536;
392 right2 = (right1 - rprev1) * 56880 / 65536;
393
394 left3 = (left2 - lprev2) * 56880 / 65536;
395 right3 = (right2 - rprev2) * 56880 / 65536;
396
397 switch (filter_level){
398 case 1:
399 pitchShifter(left1, right1, &left, &right);
400 break;
401 case 2:
402 pitchShifter(left2, right2, &left, &right);
403 break;
404 case 3:
405 pitchShifter(left3, right3, &left, &right);
406 break;
407 }
408
409 // ************ amplitude detector ************
410 tmp = left1 + lprev1;
411 if (tmp * 16 > lamplUp ) lamplUp += (tmp - lamplUp );
412 else if (tmp * 16 < lamplDown) lamplDown += (tmp - lamplDown);
413 lamplUp = (lamplUp * 1000) /1024;
414 lamplDown = (lamplDown * 1000) /1024;
415 lampl = lamplUp - lamplDown;
416
417 tmp = right1 + rprev1;
418 if (tmp * 16 > ramplUp ) ramplUp += (tmp - ramplUp );
419 else if (tmp * 16 < ramplDown) ramplDown += (tmp - ramplDown);
420 ramplUp = (ramplUp * 1000) /1024;
421 ramplDown = (ramplDown * 1000) /1024;
422 rampl = ramplUp - ramplDown;
423
424 interpolate(&bandext_amplitude, lampl, rampl);
425
426 // ************ "sound energy" detector (approx. spectrum complexity) ***********
427 interpolate(&bandext_energy, left0 - lprev0, right0 - rprev0);
428
429 // ************ mixer ***********
430 left = left0 + left * calc_scalefactor(bandext_amplitude.lval, bandext_energy.lval) / bext_sfactor;
431 right = right0 + right * calc_scalefactor(bandext_amplitude.rval, bandext_energy.rval) / bext_sfactor; //16384
432
433 saw = (saw + 2048) & 0x7fff;
434
435 lprev0 = left0;
436 rprev0 = right0;
437 lprev1 = left1;
438 rprev1 = right1;
439 lprev2 = left2;
440 rprev2 = right2;
441
442 if (left < -32768) left = -32768;
443 else if (left > 32767) left = 32767;
444 if (right < -32768) right = -32768;
445 else if (right > 32767) right = 32767;
446
447 dataptr[0] = left;
448 dataptr[1] = right;
449 dataptr += 2;
450 }
451 }
452
453 int psycho_process(void *data, int length, int nch)
454 {
455 if (nch != 2)
456 return length; /* XXX: we cant process mono yet */
457
458 echo3d((gint16 *)data, length);
459 bandext((gint16 *)data, length);
460 return length;
461 }
462