diff options
author | Sean Bartell <wingedtachikoma@gmail.com> | 2011-06-25 21:32:25 -0400 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2012-04-25 22:13:20 +0200 |
commit | f40bfc9267b13b54e6379dfe7539447662879d24 (patch) | |
tree | 9b20069d5e62809ff434061ad730096836f916f2 /lib/rbcodec/codecs/libwmavoice/acelp_vectors.c | |
parent | a0009907de7a0107d49040d8a180f140e2eff299 (diff) | |
download | rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.tar.gz rockbox-f40bfc9267b13b54e6379dfe7539447662879d24.zip |
Add codecs to librbcodec.
Change-Id: Id7f4717d51ed02d67cb9f9cb3c0ada4a81843f97
Reviewed-on: http://gerrit.rockbox.org/137
Reviewed-by: Nils Wallménius <nils@rockbox.org>
Tested-by: Nils Wallménius <nils@rockbox.org>
Diffstat (limited to 'lib/rbcodec/codecs/libwmavoice/acelp_vectors.c')
-rw-r--r-- | lib/rbcodec/codecs/libwmavoice/acelp_vectors.c | 270 |
1 files changed, 270 insertions, 0 deletions
diff --git a/lib/rbcodec/codecs/libwmavoice/acelp_vectors.c b/lib/rbcodec/codecs/libwmavoice/acelp_vectors.c new file mode 100644 index 0000000000..e41e5facb6 --- /dev/null +++ b/lib/rbcodec/codecs/libwmavoice/acelp_vectors.c | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * adaptive and fixed codebook vector operations for ACELP-based codecs | ||
3 | * | ||
4 | * Copyright (c) 2008 Vladimir Voroshilov | ||
5 | * | ||
6 | * This file is part of FFmpeg. | ||
7 | * | ||
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. | ||
12 | * | ||
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. | ||
17 | * | ||
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 | ||
21 | */ | ||
22 | |||
23 | #include <inttypes.h> | ||
24 | #include "avcodec.h" | ||
25 | #include "acelp_vectors.h" | ||
26 | #include "celp_math.h" | ||
27 | |||
28 | const uint8_t ff_fc_2pulses_9bits_track1[16] = | ||
29 | { | ||
30 | 1, 3, | ||
31 | 6, 8, | ||
32 | 11, 13, | ||
33 | 16, 18, | ||
34 | 21, 23, | ||
35 | 26, 28, | ||
36 | 31, 33, | ||
37 | 36, 38 | ||
38 | }; | ||
39 | const uint8_t ff_fc_2pulses_9bits_track1_gray[16] = | ||
40 | { | ||
41 | 1, 3, | ||
42 | 8, 6, | ||
43 | 18, 16, | ||
44 | 11, 13, | ||
45 | 38, 36, | ||
46 | 31, 33, | ||
47 | 21, 23, | ||
48 | 28, 26, | ||
49 | }; | ||
50 | |||
51 | const uint8_t ff_fc_2pulses_9bits_track2_gray[32] = | ||
52 | { | ||
53 | 0, 2, | ||
54 | 5, 4, | ||
55 | 12, 10, | ||
56 | 7, 9, | ||
57 | 25, 24, | ||
58 | 20, 22, | ||
59 | 14, 15, | ||
60 | 19, 17, | ||
61 | 36, 31, | ||
62 | 21, 26, | ||
63 | 1, 6, | ||
64 | 16, 11, | ||
65 | 27, 29, | ||
66 | 32, 30, | ||
67 | 39, 37, | ||
68 | 34, 35, | ||
69 | }; | ||
70 | |||
71 | const uint8_t ff_fc_4pulses_8bits_tracks_13[16] = | ||
72 | { | ||
73 | 0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, | ||
74 | }; | ||
75 | |||
76 | const uint8_t ff_fc_4pulses_8bits_track_4[32] = | ||
77 | { | ||
78 | 3, 4, | ||
79 | 8, 9, | ||
80 | 13, 14, | ||
81 | 18, 19, | ||
82 | 23, 24, | ||
83 | 28, 29, | ||
84 | 33, 34, | ||
85 | 38, 39, | ||
86 | 43, 44, | ||
87 | 48, 49, | ||
88 | 53, 54, | ||
89 | 58, 59, | ||
90 | 63, 64, | ||
91 | 68, 69, | ||
92 | 73, 74, | ||
93 | 78, 79, | ||
94 | }; | ||
95 | |||
96 | #if 0 | ||
97 | static uint8_t gray_decode[32] = | ||
98 | { | ||
99 | 0, 1, 3, 2, 7, 6, 4, 5, | ||
100 | 15, 14, 12, 13, 8, 9, 11, 10, | ||
101 | 31, 30, 28, 29, 24, 25, 27, 26, | ||
102 | 16, 17, 19, 18, 23, 22, 20, 21 | ||
103 | }; | ||
104 | #endif | ||
105 | |||
106 | const float ff_pow_0_7[10] = { | ||
107 | 0.700000, 0.490000, 0.343000, 0.240100, 0.168070, | ||
108 | 0.117649, 0.082354, 0.057648, 0.040354, 0.028248 | ||
109 | }; | ||
110 | |||
111 | const float ff_pow_0_75[10] = { | ||
112 | 0.750000, 0.562500, 0.421875, 0.316406, 0.237305, | ||
113 | 0.177979, 0.133484, 0.100113, 0.075085, 0.056314 | ||
114 | }; | ||
115 | |||
116 | const float ff_pow_0_55[10] = { | ||
117 | 0.550000, 0.302500, 0.166375, 0.091506, 0.050328, | ||
118 | 0.027681, 0.015224, 0.008373, 0.004605, 0.002533 | ||
119 | }; | ||
120 | |||
121 | const float ff_b60_sinc[61] = { | ||
122 | 0.898529 , 0.865051 , 0.769257 , 0.624054 , 0.448639 , 0.265289 , | ||
123 | 0.0959167 , -0.0412598 , -0.134338 , -0.178986 , -0.178528 , -0.142609 , | ||
124 | -0.0849304 , -0.0205078 , 0.0369568 , 0.0773926 , 0.0955200 , 0.0912781 , | ||
125 | 0.0689392 , 0.0357056 , 0. , -0.0305481 , -0.0504150 , -0.0570068 , | ||
126 | -0.0508423 , -0.0350037 , -0.0141602 , 0.00665283, 0.0230713 , 0.0323486 , | ||
127 | 0.0335388 , 0.0275879 , 0.0167847 , 0.00411987, -0.00747681, -0.0156860 , | ||
128 | -0.0193481 , -0.0183716 , -0.0137634 , -0.00704956, 0. , 0.00582886 , | ||
129 | 0.00939941, 0.0103760 , 0.00903320, 0.00604248, 0.00238037, -0.00109863 , | ||
130 | -0.00366211, -0.00497437, -0.00503540, -0.00402832, -0.00241089, -0.000579834, | ||
131 | 0.00103760, 0.00222778, 0.00277710, 0.00271606, 0.00213623, 0.00115967 , | ||
132 | 0. | ||
133 | }; | ||
134 | |||
135 | void ff_acelp_fc_pulse_per_track( | ||
136 | int16_t* fc_v, | ||
137 | const uint8_t *tab1, | ||
138 | const uint8_t *tab2, | ||
139 | int pulse_indexes, | ||
140 | int pulse_signs, | ||
141 | int pulse_count, | ||
142 | int bits) | ||
143 | { | ||
144 | int mask = (1 << bits) - 1; | ||
145 | int i; | ||
146 | |||
147 | for(i=0; i<pulse_count; i++) | ||
148 | { | ||
149 | fc_v[i + tab1[pulse_indexes & mask]] += | ||
150 | (pulse_signs & 1) ? 8191 : -8192; // +/-1 in (2.13) | ||
151 | |||
152 | pulse_indexes >>= bits; | ||
153 | pulse_signs >>= 1; | ||
154 | } | ||
155 | |||
156 | fc_v[tab2[pulse_indexes]] += (pulse_signs & 1) ? 8191 : -8192; | ||
157 | } | ||
158 | |||
159 | void ff_decode_10_pulses_35bits(const int16_t *fixed_index, | ||
160 | AMRFixed *fixed_sparse, | ||
161 | const uint8_t *gray_decode, | ||
162 | int half_pulse_count, int bits) | ||
163 | { | ||
164 | int i; | ||
165 | int mask = (1 << bits) - 1; | ||
166 | |||
167 | fixed_sparse->no_repeat_mask = 0; | ||
168 | fixed_sparse->n = 2 * half_pulse_count; | ||
169 | for (i = 0; i < half_pulse_count; i++) { | ||
170 | const int pos1 = gray_decode[fixed_index[2*i+1] & mask] + i; | ||
171 | const int pos2 = gray_decode[fixed_index[2*i ] & mask] + i; | ||
172 | const float sign = (fixed_index[2*i+1] & (1 << bits)) ? -1.0 : 1.0; | ||
173 | fixed_sparse->x[2*i+1] = pos1; | ||
174 | fixed_sparse->x[2*i ] = pos2; | ||
175 | fixed_sparse->y[2*i+1] = sign; | ||
176 | fixed_sparse->y[2*i ] = pos2 < pos1 ? -sign : sign; | ||
177 | } | ||
178 | } | ||
179 | |||
180 | void ff_acelp_weighted_vector_sum( | ||
181 | int16_t* out, | ||
182 | const int16_t *in_a, | ||
183 | const int16_t *in_b, | ||
184 | int16_t weight_coeff_a, | ||
185 | int16_t weight_coeff_b, | ||
186 | int16_t rounder, | ||
187 | int shift, | ||
188 | int length) | ||
189 | { | ||
190 | int i; | ||
191 | |||
192 | // Clipping required here; breaks OVERFLOW test. | ||
193 | for(i=0; i<length; i++) | ||
194 | out[i] = av_clip_int16(( | ||
195 | in_a[i] * weight_coeff_a + | ||
196 | in_b[i] * weight_coeff_b + | ||
197 | rounder) >> shift); | ||
198 | } | ||
199 | |||
200 | void ff_weighted_vector_sumf(float *out, const float *in_a, const float *in_b, | ||
201 | float weight_coeff_a, float weight_coeff_b, int length) | ||
202 | { | ||
203 | int i; | ||
204 | |||
205 | for(i=0; i<length; i++) | ||
206 | out[i] = weight_coeff_a * in_a[i] | ||
207 | + weight_coeff_b * in_b[i]; | ||
208 | } | ||
209 | |||
210 | void ff_adaptive_gain_control(float *out, const float *in, float speech_energ, | ||
211 | int size, float alpha, float *gain_mem) | ||
212 | { | ||
213 | int i; | ||
214 | float postfilter_energ = ff_dot_productf(in, in, size); | ||
215 | float gain_scale_factor = 1.0; | ||
216 | float mem = *gain_mem; | ||
217 | |||
218 | if (postfilter_energ) | ||
219 | gain_scale_factor = sqrt(speech_energ / postfilter_energ); | ||
220 | |||
221 | gain_scale_factor *= 1.0 - alpha; | ||
222 | |||
223 | for (i = 0; i < size; i++) { | ||
224 | mem = alpha * mem + gain_scale_factor; | ||
225 | out[i] = in[i] * mem; | ||
226 | } | ||
227 | |||
228 | *gain_mem = mem; | ||
229 | } | ||
230 | |||
231 | void ff_scale_vector_to_given_sum_of_squares(float *out, const float *in, | ||
232 | float sum_of_squares, const int n) | ||
233 | { | ||
234 | int i; | ||
235 | float scalefactor = ff_dot_productf(in, in, n); | ||
236 | if (scalefactor) | ||
237 | scalefactor = sqrt(sum_of_squares / scalefactor); | ||
238 | for (i = 0; i < n; i++) | ||
239 | out[i] = in[i] * scalefactor; | ||
240 | } | ||
241 | |||
242 | void ff_set_fixed_vector(float *out, const AMRFixed *in, float scale, int size) | ||
243 | { | ||
244 | int i; | ||
245 | |||
246 | for (i=0; i < in->n; i++) { | ||
247 | int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); | ||
248 | float y = in->y[i] * scale; | ||
249 | |||
250 | do { | ||
251 | out[x] += y; | ||
252 | y *= in->pitch_fac; | ||
253 | x += in->pitch_lag; | ||
254 | } while (x < size && repeats); | ||
255 | } | ||
256 | } | ||
257 | |||
258 | void ff_clear_fixed_vector(float *out, const AMRFixed *in, int size) | ||
259 | { | ||
260 | int i; | ||
261 | |||
262 | for (i=0; i < in->n; i++) { | ||
263 | int x = in->x[i], repeats = !((in->no_repeat_mask >> i) & 1); | ||
264 | |||
265 | do { | ||
266 | out[x] = 0.0; | ||
267 | x += in->pitch_lag; | ||
268 | } while (x < size && repeats); | ||
269 | } | ||
270 | } | ||