annotate celp_filters.c @ 9473:e38284cd69dc libavcodec

Use memcpy instead of the very inefficient bytecopy where both are correct (i.e. no overlap of src and dst is possible).
author reimar
date Fri, 17 Apr 2009 17:20:48 +0000
parents d7554a5e3fd7
children 2838045383c5
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
1 /*
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
2 * various filters for ACELP-based codecs
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
3 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
4 * Copyright (c) 2008 Vladimir Voroshilov
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
5 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
6 * This file is part of FFmpeg.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
7 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
12 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
16 * Lesser General Public License for more details.
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
17 *
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
21 */
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
22
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
23 #include <inttypes.h>
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
24
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
25 #include "avcodec.h"
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
26 #include "celp_filters.h"
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
27
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
28 void ff_celp_convolve_circ(
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
29 int16_t* fc_out,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
30 const int16_t* fc_in,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
31 const int16_t* filter,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
32 int len)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
33 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
34 int i, k;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
35
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
36 memset(fc_out, 0, len * sizeof(int16_t));
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
37
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
38 /* Since there are few pulses over an entire subframe (i.e. almost
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
39 all fc_in[i] are zero) it is faster to loop over fc_in first. */
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
40 for(i=0; i<len; i++)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
41 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
42 if(fc_in[i])
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
43 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
44 for(k=0; k<i; k++)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
45 fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
46
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
47 for(k=i; k<len; k++)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
48 fc_out[k] += (fc_in[i] * filter[ k - i]) >> 15;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
49 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
50 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
51 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
52
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
53 int ff_celp_lp_synthesis_filter(
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
54 int16_t *out,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
55 const int16_t* filter_coeffs,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
56 const int16_t* in,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
57 int buffer_length,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
58 int filter_length,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
59 int stop_on_overflow,
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
60 int rounder)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
61 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
62 int i,n;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
63
9447
d7554a5e3fd7 [COSMETIC] Correct a minor nit. Should be clearer now.
reynaldo
parents: 9446
diff changeset
64 // Avoids a +1 in the inner loop.
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
65 filter_length++;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
66
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
67 for(n=0; n<buffer_length; n++)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
68 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
69 int sum = rounder;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
70 for(i=1; i<filter_length; i++)
9446
1a3865d1b049 Fix possibly harmful outbound addressing. Patch by Kenan Gillet.
reynaldo
parents: 9017
diff changeset
71 sum -= filter_coeffs[i-1] * out[n-i];
8049
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
72
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
73 sum = (sum >> 12) + in[n];
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
74
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
75 if(sum + 0x8000 > 0xFFFFU)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
76 {
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
77 if(stop_on_overflow)
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
78 return 1;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
79 sum = (sum >> 31) ^ 32767;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
80 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
81 out[n] = sum;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
82 }
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
83
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
84 return 0;
611a21e4b01b Split off celp_filters.[ch] from acelp_filters.[ch] for the QCELP decoder.
diego
parents:
diff changeset
85 }
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
86
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
87 void ff_celp_lp_synthesis_filterf(
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
88 float *out,
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
89 const float* filter_coeffs,
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
90 const float* in,
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
91 int buffer_length,
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
92 int filter_length)
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
93 {
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
94 int i,n;
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
95
9447
d7554a5e3fd7 [COSMETIC] Correct a minor nit. Should be clearer now.
reynaldo
parents: 9446
diff changeset
96 // Avoids a +1 in the inner loop.
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
97 filter_length++;
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
98
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
99 for(n=0; n<buffer_length; n++)
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
100 {
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
101 out[n] = in[n];
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
102 for(i=1; i<filter_length; i++)
9446
1a3865d1b049 Fix possibly harmful outbound addressing. Patch by Kenan Gillet.
reynaldo
parents: 9017
diff changeset
103 out[n] -= filter_coeffs[i-1] * out[n-i];
8091
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
104 }
4c95f44c4c23 Add a LPC filter
vitor
parents: 8049
diff changeset
105 }