3 * Common code for Vorbis I encoder and decoder
4 * @author Denes Balatoni ( dbalatoni programozo hu )
6 * This file is part of FFmpeg.
8 * FFmpeg is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * FFmpeg 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 GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with FFmpeg; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
23 /* render_line and friend taken from ffmpeg (libavcodec/vorbis.c) */
27 static inline void render_line_unrolled(int x
, int y
, int x1
,
28 int sy
, int ady
, int adx
,
29 const ogg_int32_t
*lookup
, ogg_int32_t
*buf
)
39 buf
[x
] = MULT31_SHIFT15(buf
[x
],lookup
[y
]);
42 buf
[x
] = MULT31_SHIFT15(buf
[x
],lookup
[y
]);
47 buf
[x
] = MULT31_SHIFT15(buf
[x
],lookup
[y
]);
51 static inline void render_line(int x0
, int y0
, int x1
, int y1
,
52 const ogg_int32_t
*lookup
, ogg_int32_t
*buf
)
57 int sy
= dy
< 0 ? -1 : 1;
58 buf
[x0
] = MULT31_SHIFT15(buf
[x0
],lookup
[y0
]);
59 if (ady
*2 <= adx
) { // optimized common case
60 render_line_unrolled(x0
, y0
, x1
, sy
, ady
, adx
, lookup
, buf
);
66 ady
-= abs(base
) * adx
;
74 buf
[x
] = MULT31_SHIFT15(buf
[x
],lookup
[y
]);
79 #ifndef INCL_OPTIMIZED_VECTOR_FMUL_WINDOW
80 #define INCL_OPTIMIZED_VECTOR_FMUL_WINDOW
81 static inline void ff_vector_fmul_window_c(ogg_int32_t
*dst
, const ogg_int32_t
*src0
,
82 const ogg_int32_t
*src1
, const ogg_int32_t
*win
, int len
){
87 for(i
=-len
, j
=len
-1; i
<0; i
++, j
--) {
88 ogg_int32_t s0
= src0
[i
];
89 ogg_int32_t s1
= src1
[j
];
90 ogg_int32_t wi
= win
[i
];
91 ogg_int32_t wj
= win
[j
];
92 XNPROD31(s0
, s1
, wj
, wi
, &dst
[i
], &dst
[j
]);
94 dst[i] = MULT31(s0,wj) - MULT31(s1,wi);
95 dst[j] = MULT31(s0,wi) + MULT31(s1,wj);
101 static inline void copy_normalize(ogg_int32_t
*dst
, ogg_int32_t
*src
, int len
)
103 memcpy(dst
, src
, len
* sizeof(ogg_int32_t
));
106 static inline void window_overlap_add(unsigned int blocksize
, unsigned int lastblock
,
107 unsigned int bs0
, unsigned int bs1
, int ch
,
108 const ogg_int32_t
*win
, vorbis_dsp_state
*v
)
110 unsigned retlen
= (blocksize
+ lastblock
) / 4;
112 for (j
= 0; j
< ch
; j
++) {
113 ogg_int32_t
*residue
= v
->residues
[v
->ri
] + j
* blocksize
/ 2;
114 ogg_int32_t
*saved
= v
->saved_ptr
[j
];
115 ogg_int32_t
*ret
= v
->floors
+ j
* retlen
;
116 ogg_int32_t
*buf
= residue
;
119 ff_vector_fmul_window_c(ret
, saved
, buf
, win
, blocksize
/ 4);
120 } else if (v
->W
> v
->lW
) {
121 ff_vector_fmul_window_c(ret
, saved
, buf
, win
, bs0
/ 4);
122 copy_normalize(ret
+bs0
/2, buf
+bs0
/4, (bs1
-bs0
)/4);
124 copy_normalize(ret
, saved
, (bs1
- bs0
) / 4);
125 ff_vector_fmul_window_c(ret
+ (bs1
- bs0
) / 4, saved
+ (bs1
- bs0
) / 4, buf
, win
, bs0
/ 4);
127 if (v
->residues
[1] == NULL
) {
128 memcpy(saved
, buf
+ blocksize
/ 4, blocksize
/ 4 * sizeof(ogg_int32_t
));
129 v
->saved_ptr
[j
] = v
->saved
+ j
* bs1
/ 4;
131 v
->saved_ptr
[j
] = buf
+ blocksize
/ 4;
137 if (v
->residues
[1] != NULL
) {