]> git.sesse.net Git - vlc/blob - plugins/downmix/ac3_downmix_3dn.c
* AC3 IMDCT and downmix functions are now in plugins, --imdct and
[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.1 2001/05/15 16:19:42 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 #define MODULE_NAME downmix3dn
25 #include "modules_inner.h"
26
27 /*****************************************************************************
28  * Preamble
29  *****************************************************************************/
30 #include "defs.h"
31
32 #include "config.h"
33 #include "common.h"
34 #include "threads.h"
35 #include "mtime.h"
36 #include "tests.h"
37
38 #include "ac3_downmix.h"
39
40 void sqrt2_3dn (void)
41 {
42     __asm__ (".float 0f0.7071068");
43 }
44
45 void _M( downmix_3f_2r_to_2ch ) (float * samples, dm_par_t * dm_par)
46 {
47     __asm__ __volatile__ (
48     "pushl %%ecx\n"
49     "movl  $128,  %%ecx\n"            /* loop counter */
50
51     "movd    (%%ebx), %%mm5\n"        /* unit */
52     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
53
54     "movd    4(%%ebx), %%mm6\n"        /* clev */
55     "punpckldq %%mm6, %%mm6\n"        /* clev | clev */
56
57     "movd    8(%%ebx), %%mm7\n"        /* slev */
58     "punpckldq %%mm7, %%mm7\n"        /* slev | slev */
59
60 ".loop:\n"
61     "movq    (%%eax),     %%mm0\n"   /* left */
62     "movq    2048(%%eax), %%mm1\n"   /* right */
63     "movq   1024(%%eax), %%mm2\n"    /* center */
64     "movq    3072(%%eax), %%mm3\n"    /* leftsur */
65     "movq    4096(%%eax), %%mm4\n"    /* rightsur */
66     "pfmul    %%mm5, %%mm0\n"
67     "pfmul    %%mm5, %%mm1\n"
68     "pfmul    %%mm6, %%mm2\n"
69     "pfadd    %%mm2, %%mm0\n"
70     "pfadd     %%mm2, %%mm1\n"
71     "pfmul  %%mm7, %%mm3\n"
72     "pfmul    %%mm7, %%mm4\n"
73     "pfadd    %%mm3, %%mm0\n"
74     "pfadd    %%mm4, %%mm1\n"
75
76     "movq    %%mm0, (%%eax)\n"
77     "movq    %%mm1, 1024(%%eax)\n"
78
79     "addl    $8, %%eax\n"
80     "decl     %%ecx\n"
81     "jnz    .loop\n"
82     
83     "popl   %%ecx\n"
84     "femms\n"
85     : "=a" (samples)
86     : "a" (samples), "b" (dm_par));
87 }
88
89 void _M( downmix_2f_2r_to_2ch ) (float *samples, dm_par_t * dm_par)
90 {
91     __asm__ __volatile__ (
92     "pushl %%ecx\n"
93     "movl  $128, %%ecx\n"       /* loop counter */
94
95     "movd  (%%ebx), %%mm5\n"    /* unit */
96     "punpckldq %%mm5, %%mm5\n"  /* unit | unit */
97
98     "movd    8(%%ebx), %%mm7\n"    /* slev */
99     "punpckldq %%mm7, %%mm7\n"    /* slev | slev */
100
101 ".loop3:\n"
102     "movq   (%%eax), %%mm0\n"       /* left */
103     "movq   1024(%%eax), %%mm1\n"   /* right */
104     "movq   2048(%%eax), %%mm3\n"    /* leftsur */
105     "movq   3072(%%eax), %%mm4\n"    /* rightsur */
106     "pfmul    %%mm5, %%mm0\n"
107     "pfmul    %%mm5, %%mm1\n"
108     "pfmul    %%mm7, %%mm3\n"
109     "pfmul    %%mm7, %%mm4\n"
110     "pfadd    %%mm3, %%mm0\n"
111     "pfadd    %%mm4, %%mm1\n"
112
113     "movq    %%mm0, (%%eax)\n"
114     "movq    %%mm1, 1024(%%eax)\n"
115
116     "addl    $8, %%eax\n"
117     "decl     %%ecx\n"
118     "jnz    .loop3\n"
119
120     "popl    %%ecx\n"
121     "femms\n"
122     : "=a" (samples)
123     : "a" (samples), "b" (dm_par));
124 }
125
126 void _M( downmix_3f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
127 {
128     __asm__ __volatile__ (
129
130     "pushl    %%ecx\n"
131     "movl    $128, %%ecx\n"            /* loop counter */
132
133     "movd    (%%ebx), %%mm5\n"        /* unit */
134     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
135
136     "movd    4(%%ebx), %%mm6\n"        /* clev */
137     "punpckldq %%mm6, %%mm6\n"        /* clev | clev */
138
139     "movd    8(%%ebx), %%mm7\n"        /* slev */
140     "punpckldq %%mm7, %%mm7\n"      /* slev | slev */
141
142 ".loop4:\n"
143     "movq    (%%eax), %%mm0\n"       /* left */
144     "movq    2048(%%eax), %%mm1\n"   /* right */
145     "movq    1024(%%eax), %%mm2\n"    /* center */
146     "movq    3072(%%eax), %%mm3\n"    /* sur */
147     "pfmul    %%mm5, %%mm0\n"
148     "pfmul    %%mm5, %%mm1\n"
149     "pfmul    %%mm6, %%mm2\n"
150     "pfadd    %%mm2, %%mm0\n"
151     "pfmul    %%mm7, %%mm3\n"
152     "pfadd     %%mm2, %%mm1\n"
153     "pfsub    %%mm3, %%mm0\n"
154     "pfadd    %%mm3, %%mm1\n"
155
156     "movq    %%mm0, (%%eax)\n"
157     "movq    %%mm1, 1024(%%eax)\n"
158
159     "addl    $8, %%eax\n"
160     "decl     %%ecx\n"
161     "jnz    .loop4\n"
162
163     "popl    %%ecx\n"
164     "femms\n"
165     : "=a" (samples)
166     : "a" (samples), "b" (dm_par));
167 }
168
169 void _M( downmix_2f_1r_to_2ch ) (float *samples, dm_par_t * dm_par)
170 {
171     __asm__ __volatile__ (
172     "pushl    %%ecx\n"
173     "movl    $128, %%ecx\n"            /* loop counter */
174
175     "movd    (%%ebx), %%mm5\n"        /* unit */
176     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
177
178     "movd    8(%%ebx), %%mm7\n"        /* slev */
179     "punpckldq %%mm7, %%mm7\n"      /* slev | slev */
180
181 ".loop5:\n"
182     "movq    (%%eax), %%mm0\n"       /* left */
183     "movq    1024(%%eax), %%mm1\n"   /* right */
184     "movq    2048(%%eax), %%mm3\n"    /* sur */
185     "pfmul    %%mm5, %%mm0\n"
186     "pfmul    %%mm5, %%mm1\n"
187     "pfmul    %%mm7, %%mm3\n"
188     "pfsub    %%mm3, %%mm0\n"
189     "pfadd    %%mm3, %%mm1\n"
190
191     "movq    %%mm0, (%%eax)\n"
192     "movq    %%mm1, 1024(%%eax)\n"
193
194     "addl    $8, %%eax\n"
195     "decl     %%ecx\n"
196     "jnz    .loop5\n"
197
198     "popl    %%ecx\n"
199     "femms\n"
200     : "=a" (samples)
201     : "a" (samples), "b" (dm_par));
202 }
203
204 void _M( downmix_3f_0r_to_2ch ) (float *samples, dm_par_t * dm_par)
205 {
206     __asm__ __volatile__ (
207     "pushl    %%ecx\n"
208     "movl    $128, %%ecx\n"            /* loop counter */
209
210     "movd    (%%ebx), %%mm5\n"        /* unit */
211     "punpckldq %%mm5, %%mm5\n"        /* unit | unit */
212
213     "movd    4(%%ebx), %%mm6\n"        /* clev */
214     "punpckldq %%mm6, %%mm6\n"      /* clev | clev */
215
216 ".loop6:\n"
217     "movq    (%%eax), %%mm0\n"       /*left */
218     "movq    2048(%%eax), %%mm1\n"   /* right */
219     "movq   1024(%%eax), %%mm2\n"   /* center */
220     "pfmul    %%mm5, %%mm0\n"
221     "pfmul    %%mm5, %%mm1\n"
222     "pfmul    %%mm6, %%mm2\n"
223     "pfadd    %%mm2, %%mm0\n"
224     "pfadd     %%mm2, %%mm1\n"
225
226     "movq    %%mm0, (%%eax)\n"
227     "movq    %%mm1, 1024(%%eax)\n"
228
229     "addl    $8, %%eax\n"
230     "decl     %%ecx\n"
231     "jnz    .loop6\n"
232
233     "popl    %%ecx\n"
234     "femms\n"
235     : "=a" (samples)
236     : "a" (samples), "b" (dm_par));
237 }
238
239 void _M( stream_sample_1ch_to_s16 ) (s16 *s16_samples, float *left)
240 {
241     __asm__ __volatile__ (
242     "pushl %%ecx\n"
243     "pushl %%edx\n"
244
245     "movl   $sqrt2_3dn, %%edx\n"
246     "movd  (%%edx), %%mm7\n"
247     "punpckldq %%mm7, %%mm7\n"   /* sqrt2 | sqrt2 */
248     "movl $128, %%ecx\n"
249
250 ".loop2:\n"
251     "movq (%%ebx), %%mm0\n"        /* c1 | c0 */
252     "pfmul   %%mm7, %%mm0\n"
253
254     "pf2id %%mm0, %%mm0\n"        /* c1 c0 --> mm0, int_32 */
255
256     "packssdw %%mm0, %%mm0\n"        /* c1 c1 c0 c0 --> mm0, int_16 */
257
258     "movq %%mm0, (%%eax)\n"
259     "addl $8, %%eax\n"
260     "addl $8, %%ebx\n"
261
262     "decl %%ecx\n"
263     "jnz .loop2\n"
264
265     "popl %%edx\n"
266     "popl %%ecx\n"
267     "femms\n"
268     : "=a" (s16_samples), "=b" (left)
269     : "a" (s16_samples), "b" (left));
270 }
271
272 void _M( stream_sample_2ch_to_s16 ) (s16 *s16_samples, float *left, float *right)
273 {
274
275     __asm__ __volatile__ (
276     "pushl %%ecx\n"
277     "movl $128, %%ecx\n"
278
279 ".loop1:\n"
280     "movq  (%%ebx), %%mm0\n"    /* l1 | l0 */
281     "movq  (%%edx), %%mm1\n"    /* r1 | r0 */
282     "movq   %%mm0,  %%mm2\n"    /* l1 | l0 */
283     "punpckldq %%mm1, %%mm0\n"    /* r0 | l0 */
284     "punpckhdq %%mm1, %%mm2\n"    /* r1 | l1 */
285
286     "pf2id    %%mm0, %%mm0\n"    /* r0 l0 --> mm0, int_32 */
287     "pf2id    %%mm2, %%mm2\n"    /* r0 l0 --> mm0, int_32 */
288     
289     "packssdw %%mm2, %%mm0\n"    /* r1 l1 r0 l0 --> mm0, int_16 */
290
291     "movq %%mm0, (%%eax)\n"
292     "movq %%mm2, 8(%%eax)\n"
293     "addl $8, %%eax\n"
294     "addl $8, %%ebx\n"
295     "addl $8, %%edx\n"
296
297     "decl %%ecx\n"
298     "jnz .loop1\n"
299
300     "popl %%ecx\n"
301     "femms\n"
302     : "=a" (s16_samples), "=b" (left), "=d" (right)
303     : "a" (s16_samples), "b" (left), "d" (right));
304     
305 }
306