2 decode_i586_dither: asm synth with dither noise
4 copyright ?-2007 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 Stefan Bieschewski as decode_i586.s without dither
8 This version uses "circular" 64k dither noise.
9 (Patch by Adrian <adrian.bacon@xs4all.nl>)
11 Thomas learned something about assembler and the stack while making this one thread safe (removing static data).
28 /* int synth_1to1_i586_asm_dither(real *bandPtr, int channel, unsigned char *out, unsigned char *buffs, int bo_and_ditherindex[2], real *decwin, real* dithernoise); */
29 .globl ASM_NAME(synth_1to1_i586_asm_dither)
30 ASM_NAME(synth_1to1_i586_asm_dither):
36 /* stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
37 #define BANDPTR 36(%esp)
38 #define CHANNEL 40(%esp)
40 #define BUFFS 48(%esp)
42 #define DECWIN 56(%esp)
43 #define DITHERNOISE 60(%esp)
44 /*#define DITHERNOISE $(ASM_NAME(dithernoise))*/
48 #define DITHERINDEX 28(%esp)
49 /* During application of the dithering, we need the shifted locations because there's an additional value on the stack. */
50 #define DITHERNOISE2 64(%esp)
51 #define DITHERINDEX2 32(%esp)
56 movl (%ebx),%ebp /* get bo value */
57 movl 4(%ebx),%edi; /* get the ditherindex behind bo */
64 movl %ebp,(%ebx) /* save bo back */
68 /* In stereo mode , "rewind" dither pointer 32 samples , so 2nd channel */
69 /* has same dither values. Tested OK for mono and stereo MP2 and MP3 */
70 subl $128,DITHERINDEX /* better move to %edi for the two calculations? */
71 andl $0x0003fffc,DITHERINDEX
76 /* now the call of dct64 is prepared, stuff pushed to the stack, but soon after it's removed again */
83 leal (%ebx,%edx,4),%eax
88 leal 1088(,%eax,4),%eax
96 leal 1092(%ecx,%ebp,4),%eax
98 leal (%ecx,%ebp,4),%eax
101 call ASM_NAME(dct64_i386)
103 /* Now removed the parameters.
104 stack: 0(%esp)=%ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo 56=decwin 60=dithernoise */
107 /* movl ASM_VALUE(decwin)+64,%eax */
180 andl $0x0003fffc,DITHERINDEX2
181 movl DITHERNOISE2,%edi
182 addl DITHERINDEX2,%edi
186 /* fistpl and popl as a unit keep the stack unchanged */
195 1: movw $32767,(%esi)
197 2: movw $-32768,(%esi)
240 andl $0x0003fffc,DITHERINDEX2
241 movl DITHERNOISE2,%edi
242 addl DITHERINDEX2,%edi
245 /* fistpl and popl as a unit keep the stack unchanged */
254 1: movw $32767,(%esi)
256 2: movw $-32768,(%esi)
264 leal -128(%ecx,%edx,8),%ecx
334 andl $0x0003fffc,DITHERINDEX2
335 movl DITHERNOISE2,%edi
336 addl DITHERINDEX2,%edi
339 /* fistpl and popl as a unit keep the stack unchanged */
348 1: movw $32767,(%esi)
350 2: movw $-32768,(%esi)
360 /* return ipv edi 0 in eax */
362 /* save ditherindex */
364 movl DITHERINDEX,%esi
366 /* stack: 0=ebx 4=esi 8=edi 12=ebp 16,20,24,28=local 32=back 36=bandptr 40=channel 44=out 48=buffs 52=bo */
372 /* The stack must be now: 0=back 4=bandptr 8=channel 12=out 16=buffs 20=bo */