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