~thopiekar/+junk/libav-0.8.10-emgd

« back to all changes in this revision

Viewing changes to libavcodec/celp_filters.c

  • Committer: Thomas-Karl Pietrowski
  • Date: 2014-02-25 09:24:26 UTC
  • Revision ID: thopiekar@googlemail.com-20140225092426-ovcn26knbumnu06a
initial release to build against libva-emgd-dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * various filters for ACELP-based codecs
 
3
 *
 
4
 * Copyright (c) 2008 Vladimir Voroshilov
 
5
 *
 
6
 * This file is part of Libav.
 
7
 *
 
8
 * Libav 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.
 
12
 *
 
13
 * Libav 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.
 
17
 *
 
18
 * You should have received a copy of the GNU Lesser General Public
 
19
 * License along with Libav; if not, write to the Free Software
 
20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
21
 */
 
22
 
 
23
#include <inttypes.h>
 
24
 
 
25
#include "avcodec.h"
 
26
#include "celp_filters.h"
 
27
 
 
28
void ff_celp_convolve_circ(int16_t* fc_out, const int16_t* fc_in,
 
29
                           const int16_t* filter, int len)
 
30
{
 
31
    int i, k;
 
32
 
 
33
    memset(fc_out, 0, len * sizeof(int16_t));
 
34
 
 
35
    /* Since there are few pulses over an entire subframe (i.e. almost
 
36
       all fc_in[i] are zero) it is faster to loop over fc_in first. */
 
37
    for (i = 0; i < len; i++) {
 
38
        if (fc_in[i]) {
 
39
            for (k = 0; k < i; k++)
 
40
                fc_out[k] += (fc_in[i] * filter[len + k - i]) >> 15;
 
41
 
 
42
            for (k = i; k < len; k++)
 
43
                fc_out[k] += (fc_in[i] * filter[      k - i]) >> 15;
 
44
        }
 
45
    }
 
46
}
 
47
 
 
48
void ff_celp_circ_addf(float *out, const float *in,
 
49
                       const float *lagged, int lag, float fac, int n)
 
50
{
 
51
    int k;
 
52
    for (k = 0; k < lag; k++)
 
53
        out[k] = in[k] + fac * lagged[n + k - lag];
 
54
    for (; k < n; k++)
 
55
        out[k] = in[k] + fac * lagged[    k - lag];
 
56
}
 
57
 
 
58
int ff_celp_lp_synthesis_filter(int16_t *out, const int16_t *filter_coeffs,
 
59
                                const int16_t *in, int buffer_length,
 
60
                                int filter_length, int stop_on_overflow,
 
61
                                int rounder)
 
62
{
 
63
    int i,n;
 
64
 
 
65
    for (n = 0; n < buffer_length; n++) {
 
66
        int sum = rounder;
 
67
        for (i = 1; i <= filter_length; i++)
 
68
            sum -= filter_coeffs[i-1] * out[n-i];
 
69
 
 
70
        sum = (sum >> 12) + in[n];
 
71
 
 
72
        if (sum + 0x8000 > 0xFFFFU) {
 
73
            if (stop_on_overflow)
 
74
                return 1;
 
75
            sum = (sum >> 31) ^ 32767;
 
76
        }
 
77
        out[n] = sum;
 
78
    }
 
79
 
 
80
    return 0;
 
81
}
 
82
 
 
83
void ff_celp_lp_synthesis_filterf(float *out, const float *filter_coeffs,
 
84
                                  const float* in, int buffer_length,
 
85
                                  int filter_length)
 
86
{
 
87
    int i,n;
 
88
 
 
89
#if 0 // Unoptimized code path for improved readability
 
90
    for (n = 0; n < buffer_length; n++) {
 
91
        out[n] = in[n];
 
92
        for (i = 1; i <= filter_length; i++)
 
93
            out[n] -= filter_coeffs[i-1] * out[n-i];
 
94
    }
 
95
#else
 
96
    float out0, out1, out2, out3;
 
97
    float old_out0, old_out1, old_out2, old_out3;
 
98
    float a,b,c;
 
99
 
 
100
    a = filter_coeffs[0];
 
101
    b = filter_coeffs[1];
 
102
    c = filter_coeffs[2];
 
103
    b -= filter_coeffs[0] * filter_coeffs[0];
 
104
    c -= filter_coeffs[1] * filter_coeffs[0];
 
105
    c -= filter_coeffs[0] * b;
 
106
 
 
107
    old_out0 = out[-4];
 
108
    old_out1 = out[-3];
 
109
    old_out2 = out[-2];
 
110
    old_out3 = out[-1];
 
111
    for (n = 0; n <= buffer_length - 4; n+=4) {
 
112
        float tmp0,tmp1,tmp2;
 
113
        float val;
 
114
 
 
115
        out0 = in[0];
 
116
        out1 = in[1];
 
117
        out2 = in[2];
 
118
        out3 = in[3];
 
119
 
 
120
        out0 -= filter_coeffs[2] * old_out1;
 
121
        out1 -= filter_coeffs[2] * old_out2;
 
122
        out2 -= filter_coeffs[2] * old_out3;
 
123
 
 
124
        out0 -= filter_coeffs[1] * old_out2;
 
125
        out1 -= filter_coeffs[1] * old_out3;
 
126
 
 
127
        out0 -= filter_coeffs[0] * old_out3;
 
128
 
 
129
        val = filter_coeffs[3];
 
130
 
 
131
        out0 -= val * old_out0;
 
132
        out1 -= val * old_out1;
 
133
        out2 -= val * old_out2;
 
134
        out3 -= val * old_out3;
 
135
 
 
136
        for (i = 5; i <= filter_length; i += 2) {
 
137
            old_out3 = out[-i];
 
138
            val = filter_coeffs[i-1];
 
139
 
 
140
            out0 -= val * old_out3;
 
141
            out1 -= val * old_out0;
 
142
            out2 -= val * old_out1;
 
143
            out3 -= val * old_out2;
 
144
 
 
145
            old_out2 = out[-i-1];
 
146
 
 
147
            val = filter_coeffs[i];
 
148
 
 
149
            out0 -= val * old_out2;
 
150
            out1 -= val * old_out3;
 
151
            out2 -= val * old_out0;
 
152
            out3 -= val * old_out1;
 
153
 
 
154
            FFSWAP(float, old_out0, old_out2);
 
155
            old_out1 = old_out3;
 
156
        }
 
157
 
 
158
        tmp0 = out0;
 
159
        tmp1 = out1;
 
160
        tmp2 = out2;
 
161
 
 
162
        out3 -= a * tmp2;
 
163
        out2 -= a * tmp1;
 
164
        out1 -= a * tmp0;
 
165
 
 
166
        out3 -= b * tmp1;
 
167
        out2 -= b * tmp0;
 
168
 
 
169
        out3 -= c * tmp0;
 
170
 
 
171
 
 
172
        out[0] = out0;
 
173
        out[1] = out1;
 
174
        out[2] = out2;
 
175
        out[3] = out3;
 
176
 
 
177
        old_out0 = out0;
 
178
        old_out1 = out1;
 
179
        old_out2 = out2;
 
180
        old_out3 = out3;
 
181
 
 
182
        out += 4;
 
183
        in  += 4;
 
184
    }
 
185
 
 
186
    out -= n;
 
187
    in -= n;
 
188
    for (; n < buffer_length; n++) {
 
189
        out[n] = in[n];
 
190
        for (i = 1; i <= filter_length; i++)
 
191
            out[n] -= filter_coeffs[i-1] * out[n-i];
 
192
    }
 
193
#endif
 
194
}
 
195
 
 
196
void ff_celp_lp_zero_synthesis_filterf(float *out, const float *filter_coeffs,
 
197
                                       const float *in, int buffer_length,
 
198
                                       int filter_length)
 
199
{
 
200
    int i,n;
 
201
 
 
202
    for (n = 0; n < buffer_length; n++) {
 
203
        out[n] = in[n];
 
204
        for (i = 1; i <= filter_length; i++)
 
205
            out[n] += filter_coeffs[i-1] * in[n-i];
 
206
    }
 
207
}