annotate acelp_filters.c @ 7855:9a135b6a1dc7 libavcodec

Correct order of parsing for pulse scalefactor band and offset to match the specification. Patch by Alex Converse (alex converse gmail com)
author superdump
date Sat, 13 Sep 2008 18:47:43 +0000
parents 76cf62255b28
children 611a21e4b01b
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
6856
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
28 const int16_t ff_acelp_interp_filter[61] =
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
29 { /* (0.15) */
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
30 29443, 28346, 25207, 20449, 14701, 8693,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
31 3143, -1352, -4402, -5865, -5850, -4673,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
32 -2783, -672, 1211, 2536, 3130, 2991,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
33 2259, 1170, 0, -1001, -1652, -1868,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
34 -1666, -1147, -464, 218, 756, 1060,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
35 1099, 904, 550, 135, -245, -514,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
36 -634, -602, -451, -231, 0, 191,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
37 308, 340, 296, 198, 78, -36,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
38 -120, -163, -165, -132, -79, -19,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
39 34, 73, 91, 89, 70, 38,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
40 0,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
41 };
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
42
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
43 void ff_acelp_interpolate(
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
44 int16_t* out,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
45 const int16_t* in,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
46 const int16_t* filter_coeffs,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
47 int precision,
7649
8c5d7ede9c96 rename pitch_delay_frac in ff_acelp_interpolate()
michael
parents: 7641
diff changeset
48 int frac_pos,
6856
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
49 int filter_length,
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
50 int length)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
51 {
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
52 int n, i;
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 assert(pitch_delay_frac >= 0 && pitch_delay_frac < precision);
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 for(n=0; n<length; n++)
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 int idx = 0;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
59 int v = 0x4000;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
60
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
61 for(i=0; i<filter_length;)
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
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
64 /* 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
65 each of the two following accumulations.
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
66 Since clipping affects only the synthetic OVERFLOW test without
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
67 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
68
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
69 /* R(x):=ac_v[-k+x]
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
70 v += R(n-i)*ff_acelp_interp_filter(t+6i)
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
71 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
72
7649
8c5d7ede9c96 rename pitch_delay_frac in ff_acelp_interpolate()
michael
parents: 7641
diff changeset
73 v += in[n + i] * filter_coeffs[idx + frac_pos];
6856
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
74 idx += precision;
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
75 i++;
7649
8c5d7ede9c96 rename pitch_delay_frac in ff_acelp_interpolate()
michael
parents: 7641
diff changeset
76 v += in[n - i] * filter_coeffs[idx - frac_pos];
6856
94465a2c3b34 Move pitch vector interpolation code to acelp_filters
voroshil
parents: 6775
diff changeset
77 }
7692
3ced4fb23342 Replace cliping in ff_acelp_interpolate() by a check&av_log, this should be the
michael
parents: 7653
diff changeset
78 if(av_clip_int16(v>>15) != (v>>15))
3ced4fb23342 Replace cliping in ff_acelp_interpolate() by a check&av_log, this should be the
michael
parents: 7653
diff changeset
79 av_log(NULL, AV_LOG_WARNING, "overflow that would need cliping in ff_acelp_interpolate()\n");
3ced4fb23342 Replace cliping in ff_acelp_interpolate() by a check&av_log, this should be the
michael
parents: 7653
diff changeset
80 out[n] = v >> 15;
6856
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,
7650
1e4ae5de68a4 Rename subframe_size to a name that is not specific to some specific use
michael
parents: 7649
diff changeset
88 int len)
6772
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
7650
1e4ae5de68a4 Rename subframe_size to a name that is not specific to some specific use
michael
parents: 7649
diff changeset
92 memset(fc_out, 0, len * sizeof(int16_t));
6772
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
7641
73f5625538d3 Document code, do not document difference to a irrelevant reference implementation.
michael
parents: 7640
diff changeset
95 all fc_in[i] are zero) it is faster to loop over fc_in first. */
7650
1e4ae5de68a4 Rename subframe_size to a name that is not specific to some specific use
michael
parents: 7649
diff changeset
96 for(i=0; i<len; i++)
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
97 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
98 if(fc_in[i])
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
99 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
100 for(k=0; k<i; k++)
7650
1e4ae5de68a4 Rename subframe_size to a name that is not specific to some specific use
michael
parents: 7649
diff changeset
101 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
102
7650
1e4ae5de68a4 Rename subframe_size to a name that is not specific to some specific use
michael
parents: 7649
diff changeset
103 for(k=i; k<len; k++)
7652
9896f3cb1500 vertical align
michael
parents: 7651
diff changeset
104 fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
105 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
106 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
107 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
108
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
109 int ff_acelp_lp_synthesis_filter(
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
110 int16_t *out,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
111 const int16_t* filter_coeffs,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
112 const int16_t* in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
113 int buffer_length,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
114 int filter_length,
7161
2b763a495c07 Add a rounding parameter to ff_acelp_lp_synthesis_filter()
vitor
parents: 6856
diff changeset
115 int stop_on_overflow,
2b763a495c07 Add a rounding parameter to ff_acelp_lp_synthesis_filter()
vitor
parents: 6856
diff changeset
116 int rounder)
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
117 {
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
118 int i,n;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
119
7211
d1e6d44fab47 Typo in a comment: s/two avoid/to avoid/
vitor
parents: 7164
diff changeset
120 // These two lines are to avoid a -1 subtraction in the main loop
7164
3c7f3265f970 Make ff_acelp_lp_synthesis_filter() receives a pointer to the actual filter coefficients and not the pointer minus one
vitor
parents: 7161
diff changeset
121 filter_length++;
3c7f3265f970 Make ff_acelp_lp_synthesis_filter() receives a pointer to the actual filter coefficients and not the pointer minus one
vitor
parents: 7161
diff changeset
122 filter_coeffs--;
3c7f3265f970 Make ff_acelp_lp_synthesis_filter() receives a pointer to the actual filter coefficients and not the pointer minus one
vitor
parents: 7161
diff changeset
123
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
124 for(n=0; n<buffer_length; n++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
125 {
7161
2b763a495c07 Add a rounding parameter to ff_acelp_lp_synthesis_filter()
vitor
parents: 6856
diff changeset
126 int sum = rounder;
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
127 for(i=1; i<filter_length; i++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
128 sum -= filter_coeffs[i] * out[n-i];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
129
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
130 sum = (sum >> 12) + in[n];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
131
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_high_pass_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 int hpf_f[2],
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
147 const int16_t* in,
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
148 int 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 i;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
151 int tmp;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
152
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
153 for(i=0; i<length; i++)
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
154 {
7695
073847371624 (cosmetics) Remove wrong comments.
voroshil
parents: 7692
diff changeset
155 tmp = (hpf_f[0]* 15836LL)>>13;
073847371624 (cosmetics) Remove wrong comments.
voroshil
parents: 7692
diff changeset
156 tmp += (hpf_f[1]* -7667LL)>>13;
073847371624 (cosmetics) Remove wrong comments.
voroshil
parents: 7692
diff changeset
157 tmp += 7699 * (in[i] - 2*in[i-1] + in[i-2]);
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
158
7696
76cf62255b28 (cosmetics) Describe for which tests clipping is required.
voroshil
parents: 7695
diff changeset
159 /* With "+0x800" rounding, clipping is needed
76cf62255b28 (cosmetics) Describe for which tests clipping is required.
voroshil
parents: 7695
diff changeset
160 for ALGTHM and SPEECH tests. */
7695
073847371624 (cosmetics) Remove wrong comments.
voroshil
parents: 7692
diff changeset
161 out[i] = av_clip_int16((tmp + 0x800) >> 12);
6772
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
162
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
163 hpf_f[1] = hpf_f[0];
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
164 hpf_f[0] = tmp;
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
165 }
695f4ab2db4c various filters for ACELP-based codecs
voroshil
parents:
diff changeset
166 }