]> git.sesse.net Git - vlc/blob - plugins/downmix/ac3_downmix_3dn.c
* ALL: new module API. Makes a few things a lot simpler, and we gain
[vlc] / plugins / downmix / ac3_downmix_3dn.c
1 /*****************************************************************************
2  * ac3_downmix_3dn.c: accelerated 3D Now! ac3 downmix functions
3  *****************************************************************************
4  * Copyright (C) 1999, 2000, 2001 VideoLAN
5  * $Id: ac3_downmix_3dn.c,v 1.12 2002/07/31 20:56:51 sam Exp $
6  *
7  * Authors: Renaud Dartus <reno@videolan.org>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  * 
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28
29 #include "ac3_downmix.h"
30
31 static const float sqrt2_3dn __asm__ ("sqrt2_3dn") = 0.7071068;
32
33 void E_( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
34 {
35     __asm__ __volatile__ (
36     ".align 16\n"
37     "pushl %%ebx\n"
38     "movl  $128,  %%ebx\n"            /* loop counter */
39
40     "movd    (%%ecx), %%mm5\n"        /* unit */
41     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
42
43     "movd    4(%%ecx), %%mm6\n"        /* clev */
44     "punpckldq %%mm6, %%mm6\n"        /* clev | clev */
45
46     "movd    8(%%ecx), %%mm7\n"        /* slev */
47     "punpckldq %%mm7, %%mm7\n"        /* slev | slev */
48
49     ".align 16\n"
50 ".loop:\n"
51     "movq    (%%eax),     %%mm0\n"   /* left */
52     "movq    2048(%%eax), %%mm1\n"   /* right */
53     "movq   1024(%%eax), %%mm2\n"    /* center */
54     "movq    3072(%%eax), %%mm3\n"    /* leftsur */
55     "movq    4096(%%eax), %%mm4\n"    /* rightsur */
56     "pfmul    %%mm5, %%mm0\n"
57     "pfmul    %%mm5, %%mm1\n"
58     "pfmul    %%mm6, %%mm2\n"
59     "pfadd    %%mm2, %%mm0\n"
60     "pfadd     %%mm2, %%mm1\n"
61     "pfmul  %%mm7, %%mm3\n"
62     "pfmul    %%mm7, %%mm4\n"
63     "pfadd    %%mm3, %%mm0\n"
64     "pfadd    %%mm4, %%mm1\n"
65
66     "movq    %%mm0, (%%eax)\n"
67     "movq    %%mm1, 1024(%%eax)\n"
68
69     "addl    $8, %%eax\n"
70     "decl     %%ebx\n"
71     "jnz    .loop\n"
72     
73     "popl   %%ebx\n"
74     "femms\n"
75     : "=a" (samples)
76     : "a" (samples), "c" (dm_par));
77 }
78
79 void E_( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
80 {
81     __asm__ __volatile__ (
82     ".align 16\n"
83     "pushl %%ebx\n"
84     "movl  $128, %%ebx\n"       /* loop counter */
85
86     "movd  (%%ecx), %%mm5\n"    /* unit */
87     "punpckldq %%mm5, %%mm5\n"  /* unit | unit */
88
89     "movd    8(%%ecx), %%mm7\n"    /* slev */
90     "punpckldq %%mm7, %%mm7\n"    /* slev | slev */
91
92     ".align 16\n"
93 ".loop3:\n"
94     "movq   (%%eax), %%mm0\n"       /* left */
95     "movq   1024(%%eax), %%mm1\n"   /* right */
96     "movq   2048(%%eax), %%mm3\n"    /* leftsur */
97     "movq   3072(%%eax), %%mm4\n"    /* rightsur */
98     "pfmul    %%mm5, %%mm0\n"
99     "pfmul    %%mm5, %%mm1\n"
100     "pfmul    %%mm7, %%mm3\n"
101     "pfmul    %%mm7, %%mm4\n"
102     "pfadd    %%mm3, %%mm0\n"
103     "pfadd    %%mm4, %%mm1\n"
104
105     "movq    %%mm0, (%%eax)\n"
106     "movq    %%mm1, 1024(%%eax)\n"
107
108     "addl    $8, %%eax\n"
109     "decl     %%ebx\n"
110     "jnz    .loop3\n"
111
112     "popl    %%ebx\n"
113     "femms\n"
114     : "=a" (samples)
115     : "a" (samples), "c" (dm_par));
116 }
117
118 void E_( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
119 {
120     __asm__ __volatile__ (
121     ".align 16\n"
122     "pushl    %%ebx\n"
123     "movl    $128, %%ebx\n"            /* loop counter */
124
125     "movd    (%%ecx), %%mm5\n"        /* unit */
126     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
127
128     "movd    4(%%ecx), %%mm6\n"        /* clev */
129     "punpckldq %%mm6, %%mm6\n"        /* clev | clev */
130
131     "movd    8(%%ecx), %%mm7\n"        /* slev */
132     "punpckldq %%mm7, %%mm7\n"      /* slev | slev */
133
134     ".align 16\n"
135 ".loop4:\n"
136     "movq    (%%eax), %%mm0\n"       /* left */
137     "movq    2048(%%eax), %%mm1\n"   /* right */
138     "movq    1024(%%eax), %%mm2\n"    /* center */
139     "movq    3072(%%eax), %%mm3\n"    /* sur */
140     "pfmul    %%mm5, %%mm0\n"
141     "pfmul    %%mm5, %%mm1\n"
142     "pfmul    %%mm6, %%mm2\n"
143     "pfadd    %%mm2, %%mm0\n"
144     "pfmul    %%mm7, %%mm3\n"
145     "pfadd     %%mm2, %%mm1\n"
146     "pfsub    %%mm3, %%mm0\n"
147     "pfadd    %%mm3, %%mm1\n"
148
149     "movq    %%mm0, (%%eax)\n"
150     "movq    %%mm1, 1024(%%eax)\n"
151
152     "addl    $8, %%eax\n"
153     "decl     %%ebx\n"
154     "jnz    .loop4\n"
155
156     "popl    %%ebx\n"
157     "femms\n"
158     : "=a" (samples)
159     : "a" (samples), "c" (dm_par));
160 }
161
162 void E_( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
163 {
164     __asm__ __volatile__ (
165     ".align 16\n"
166     "pushl    %%ebx\n"
167     "movl    $128, %%ebx\n"            /* loop counter */
168
169     "movd    (%%ecx), %%mm5\n"        /* unit */
170     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
171
172     "movd    8(%%ecx), %%mm7\n"        /* slev */
173     "punpckldq %%mm7, %%mm7\n"      /* slev | slev */
174
175     ".align 16\n"
176 ".loop5:\n"
177     "movq    (%%eax), %%mm0\n"       /* left */
178     "movq    1024(%%eax), %%mm1\n"   /* right */
179     "movq    2048(%%eax), %%mm3\n"    /* sur */
180     "pfmul    %%mm5, %%mm0\n"
181     "pfmul    %%mm5, %%mm1\n"
182     "pfmul    %%mm7, %%mm3\n"
183     "pfsub    %%mm3, %%mm0\n"
184     "pfadd    %%mm3, %%mm1\n"
185
186     "movq    %%mm0, (%%eax)\n"
187     "movq    %%mm1, 1024(%%eax)\n"
188
189     "addl    $8, %%eax\n"
190     "decl     %%ebx\n"
191     "jnz    .loop5\n"
192
193     "popl    %%ebx\n"
194     "femms\n"
195     : "=a" (samples)
196     : "a" (samples), "c" (dm_par));
197 }
198
199 void E_( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
200 {
201     __asm__ __volatile__ (
202     ".align 16\n"
203     "pushl    %%ebx\n"
204     "movl    $128, %%ebx\n"            /* loop counter */
205
206     "movd    (%%ecx), %%mm5\n"        /* unit */
207     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
208
209     "movd    4(%%ecx), %%mm6\n"        /* clev */
210     "punpckldq %%mm6, %%mm6\n"      /* clev | clev */
211
212     ".align 16\n"
213 ".loop6:\n"
214     "movq    (%%eax), %%mm0\n"       /*left */
215     "movq    2048(%%eax), %%mm1\n"   /* right */
216     "movq   1024(%%eax), %%mm2\n"   /* center */
217     "pfmul    %%mm5, %%mm0\n"
218     "pfmul    %%mm5, %%mm1\n"
219     "pfmul    %%mm6, %%mm2\n"
220     "pfadd    %%mm2, %%mm0\n"
221     "pfadd     %%mm2, %%mm1\n"
222
223     "movq    %%mm0, (%%eax)\n"
224     "movq    %%mm1, 1024(%%eax)\n"
225
226     "addl    $8, %%eax\n"
227     "decl     %%ebx\n"
228     "jnz    .loop6\n"
229
230     "popl    %%ebx\n"
231     "femms\n"
232     : "=a" (samples)
233     : "a" (samples), "c" (dm_par));
234 }
235
236 void E_( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
237 {
238     __asm__ __volatile__ (
239     ".align 16\n"
240     "pushl %%ebx\n"
241     "pushl %%edx\n"
242
243     "movl   $sqrt2_3dn, %%edx\n"
244     "movd  (%%edx), %%mm7\n"
245     "punpckldq %%mm7, %%mm7\n"   /* sqrt2 | sqrt2 */
246     "movl $128, %%ebx\n"
247
248     ".align 16\n"
249 ".loop2:\n"
250     "movq (%%ecx), %%mm0\n"        /* c1 | c0 */
251     "pfmul   %%mm7, %%mm0\n"
252
253     "pf2id %%mm0, %%mm0\n"        /* c1 c0 --> mm0, int_32 */
254
255     "packssdw %%mm0, %%mm0\n"        /* c1 c1 c0 c0 --> mm0, int_16 */
256
257     "movq %%mm0, (%%eax)\n"
258     "addl $8, %%eax\n"
259     "addl $8, %%ecx\n"
260
261     "decl %%ebx\n"
262     "jnz .loop2\n"
263
264     "popl %%edx\n"
265     "popl %%ebx\n"
266     "femms\n"
267     : "=a" (s16_samples), "=c" (left)
268     : "a" (s16_samples), "c" (left));
269 }
270
271 void E_( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
272 {
273
274     __asm__ __volatile__ (
275     ".align 16\n"
276     "pushl %%ebx\n"
277     "movl $128, %%ebx\n"
278
279     ".align 16\n"
280 ".loop1:\n"
281     "movq  (%%ecx), %%mm0\n"    /* l1 | l0 */
282     "movq  (%%edx), %%mm1\n"    /* r1 | r0 */
283     "movq   %%mm0,  %%mm2\n"    /* l1 | l0 */
284     "punpckldq %%mm1, %%mm0\n"    /* r0 | l0 */
285     "punpckhdq %%mm1, %%mm2\n"    /* r1 | l1 */
286
287     "pf2id    %%mm0, %%mm0\n"    /* r0 l0 --> mm0, int_32 */
288     "pf2id    %%mm2, %%mm2\n"    /* r0 l0 --> mm0, int_32 */
289     
290     "packssdw %%mm2, %%mm0\n"    /* r1 l1 r0 l0 --> mm0, int_16 */
291
292     "movq %%mm0, (%%eax)\n"
293     "movq %%mm2, 8(%%eax)\n"
294     "addl $8, %%eax\n"
295     "addl $8, %%ecx\n"
296     "addl $8, %%edx\n"
297
298     "decl %%ebx\n"
299     "jnz .loop1\n"
300
301     "popl %%ebx\n"
302     "femms\n"
303     : "=a" (s16_samples), "=c" (left), "=d" (right)
304     : "a" (s16_samples), "c" (left), "d" (right));
305     
306 }
307