annotate acelp_filters.c @ 6920:d02af7474bff libavcodec

Prevent 128*1<<trellis from becoming 0 and creating 0 sized arrays. fixes CID84 RUN2 CID85 RUN2 CID86 RUN2 CID87 RUN2 CID88 RUN2 CID89 RUN2 CID90 RUN2 CID91 RUN2 CID92 RUN2 CID93 RUN2 CID94 RUN2 CID95 RUN2 CID96 RUN2 CID97 RUN2 CID98 RUN2 CID99 RUN2 CID100 RUN2 CID101 RUN2 CID102 RUN2 CID103 RUN2 CID104 RUN2 CID105 RUN2 CID106 RUN2
author michael
date Wed, 28 May 2008 11:59:41 +0000
parents 94465a2c3b34
children 2b763a495c07
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
1 /*
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
2 * various filters for ACELP-based codecs
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
3 *
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
4 * Copyright (c) 2008 Vladimir Voroshilov
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
5 *
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
6 * This file is part of FFmpeg.
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
7 *
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
12 *
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
16 * Lesser General Public License for more details.
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
17 *
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
21 */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
22
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
23 #include <inttypes.h>
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
24
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
25 #include "avcodec.h"
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
26 #include "acelp_filters.h"
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
27 #define FRAC_BITS 13
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
28 #include "mathops.h"
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
29
6856
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
30 const int16_t ff_acelp_interp_filter[61] =
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
31 { /* (0.15) */
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
32 29443, 28346, 25207, 20449, 14701, 8693,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
33 3143, -1352, -4402, -5865, -5850, -4673,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
34 -2783, -672, 1211, 2536, 3130, 2991,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
35 2259, 1170, 0, -1001, -1652, -1868,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
36 -1666, -1147, -464, 218, 756, 1060,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
37 1099, 904, 550, 135, -245, -514,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
38 -634, -602, -451, -231, 0, 191,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
39 308, 340, 296, 198, 78, -36,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
40 -120, -163, -165, -132, -79, -19,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
41 34, 73, 91, 89, 70, 38,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
42 0,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
43 };
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
44
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
45 void ff_acelp_interpolate(
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
46 int16_t* out,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
47 const int16_t* in,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
48 const int16_t* filter_coeffs,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
49 int precision,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
50 int pitch_delay_frac,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
51 int filter_length,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
52 int length)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
53 {
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
54 int n, i;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
55
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
56 assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision);
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
57
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
58 for(n=0; n<length; n++)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
59 {
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
60 int idx = 0;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
61 int v = 0x4000;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
62
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
63 for(i=0; i<filter_length;)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
64 {
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
65
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
66 /* The reference G.729 and AMR fixed point code performs clipping after
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
67 each of the two following accumulations.
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
68 Since clipping affects only the synthetic OVERFLOW test without
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
69 causing an int type overflow, it was moved outside the loop. */
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
70
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
71 /* R(x):=ac_v[-k+x]
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
72 v += R(n-i)*ff_acelp_interp_filter(t+6i)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
73 v += R(n+i+1)*ff_acelp_interp_filter(6-t+6i) */
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
74
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
75 v += in[n + i] * filter_coeffs[idx + pitch_delay_frac];
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
76 idx += precision;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
77 i++;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
78 v += in[n - i] * filter_coeffs[idx - pitch_delay_frac];
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
79 }
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
80 out[n] = av_clip_int16(v >> 15);
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
81 }
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
82 }
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
83
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
84 void ff_acelp_convolve_circ(
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
85 int16_t* fc_out,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
86 const int16_t* fc_in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
87 const int16_t* filter,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
88 int subframe_size)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
89 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
90 int i, k;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
91
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
92 memset(fc_out, 0, subframe_size * sizeof(int16_t));
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
93
6775
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
94 /* Since there are few pulses over an entire subframe (i.e. almost
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
95 all fc_in[i] are zero) it is faster to swap two loops and process
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
96 non-zero samples only. In the case of G.729D the buffer contains
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
97 two non-zero samples before the call to ff_acelp_enhance_harmonics
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
98 and, due to pitch_delay being bounded by [20; 143], a maximum
1f02f929b9ff Update comment to version, negotiated with Diego, and
voroshil
parents: 6772
diff changeset
99 of four non-zero samples for a total of 40 after the call. */
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
100 for(i=0; i<subframe_size; i++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
101 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
102 if(fc_in[i])
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
103 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
104 for(k=0; k<i; k++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
105 fc_out[k] += (fc_in[i] * filter[subframe_size + k - i]) >> 15;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
106
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
107 for(k=i; k<subframe_size; k++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
108 fc_out[k] += (fc_in[i] * filter[k - i]) >> 15;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
109 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
110 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
111 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
112
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
113 int ff_acelp_lp_synthesis_filter(
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
114 int16_t *out,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
115 const int16_t* filter_coeffs,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
116 const int16_t* in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
117 int buffer_length,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
118 int filter_length,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
119 int stop_on_overflow)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
120 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
121 int i,n;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
122
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
123 for(n=0; n<buffer_length; n++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
124 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
125 int sum = 0x800;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
126 for(i=1; i<filter_length; i++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
127 sum -= filter_coeffs[i] * out[n-i];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
128
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
129 sum = (sum >> 12) + in[n];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
130
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
131 /* Check for overflow */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
132 if(sum + 0x8000 > 0xFFFFU)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
133 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
134 if(stop_on_overflow)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
135 return 1;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
136 sum = (sum >> 31) ^ 32767;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
137 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
138 out[n] = sum;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
139 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
140
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
141 return 0;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
142 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
143
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
144 void ff_acelp_weighted_filter(
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
145 int16_t *out,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
146 const int16_t* in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
147 const int16_t *weight_pow,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
148 int filter_length)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
149 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
150 int n;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
151 for(n=0; n<filter_length; n++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
152 out[n] = (in[n] * weight_pow[n] + 0x4000) >> 15; /* (3.12) = (0.15) * (3.12) with rounding */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
153 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
154
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
155 void ff_acelp_high_pass_filter(
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
156 int16_t* out,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
157 int hpf_f[2],
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
158 const int16_t* in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
159 int length)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
160 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
161 int i;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
162 int tmp;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
163
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
164 for(i=0; i<length; i++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
165 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
166 tmp = MULL(hpf_f[0], 15836); /* (14.13) = (13.13) * (1.13) */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
167 tmp += MULL(hpf_f[1], -7667); /* (13.13) = (13.13) * (0.13) */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
168 tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]); /* (14.13) = (0.13) * (14.0) */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
169
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
170 /* Multiplication by 2 with rounding can cause short type
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
171 overflow, thus clipping is required. */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
172
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
173 out[i] = av_clip_int16((tmp + 0x800) >> 12); /* (15.0) = 2 * (13.13) = (14.13) */
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
174
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
175 hpf_f[1] = hpf_f[0];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
176 hpf_f[0] = tmp;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
177 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
178 }