annotate lpc.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents e59926e2c50c
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
1 /**
7589
8b695a99e8df flacenc, lpc: Move LPC code from flacenc.c to new lpc.[ch] files.
ramiro
parents: 7588
diff changeset
2 * LPC utility code
7594
cd6217c9ce92 update my email address to one which does not depend on my service provider
jbr
parents: 7593
diff changeset
3 * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com>
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
4 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
5 * This file is part of FFmpeg.
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
6 *
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
11 *
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
15 * Lesser General Public License for more details.
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
16 *
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
3947
c8c591fe26f8 Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents: 3481
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
3353
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
20 */
5b901881d6ed first rudimentary version of (Justin Ruggles jruggle earthlink net) flac encoder
michael
parents:
diff changeset
21
6763
f7cbb7733146 Use full path for #includes from another directory.
diego
parents: 6710
diff changeset
22 #include "libavutil/lls.h"
5737
efa3c1f9259a sse2 version of compute_autocorr().
lorenm
parents: 5733
diff changeset
23 #include "dsputil.h"
7788
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
24
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
25 #define LPC_USE_DOUBLE
7589
8b695a99e8df flacenc, lpc: Move LPC code from flacenc.c to new lpc.[ch] files.
ramiro
parents: 7588
diff changeset
26 #include "lpc.h"
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
27
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
28
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
29 /**
10424
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
30 * Apply Welch window function to audio block
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
31 */
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
32 static void apply_welch_window(const int32_t *data, int len, double *w_data)
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
33 {
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
34 int i, n2;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
35 double w;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
36 double c;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
37
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
38 assert(!(len&1)); //the optimization in r11881 does not support odd len
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
39 //if someone wants odd len extend the change in r11881
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
40
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
41 n2 = (len >> 1);
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
42 c = 2.0 / (len - 1.0);
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
43
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
44 w_data+=n2;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
45 data+=n2;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
46 for(i=0; i<n2; i++) {
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
47 w = c - n2 + i;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
48 w = 1.0 - (w * w);
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
49 w_data[-i-1] = data[-i-1] * w;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
50 w_data[+i ] = data[+i ] * w;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
51 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
52 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
53
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
54 /**
12024
fdafbcef52f5 Fix grammar errors in documentation
mru
parents: 10424
diff changeset
55 * Calculate autocorrelation data from audio samples
10424
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
56 * A Welch window function is applied before calculation.
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
57 */
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
58 void ff_lpc_compute_autocorr(const int32_t *data, int len, int lag,
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
59 double *autoc)
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
60 {
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
61 int i, j;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
62 double tmp[len + lag + 1];
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
63 double *data1= tmp + lag;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
64
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
65 apply_welch_window(data, len, data1);
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
66
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
67 for(j=0; j<lag; j++)
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
68 data1[j-lag]= 0.0;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
69 data1[len] = 0.0;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
70
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
71 for(j=0; j<lag; j+=2){
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
72 double sum0 = 1.0, sum1 = 1.0;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
73 for(i=j; i<len; i++){
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
74 sum0 += data1[i] * data1[i-j];
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
75 sum1 += data1[i] * data1[i-j-1];
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
76 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
77 autoc[j ] = sum0;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
78 autoc[j+1] = sum1;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
79 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
80
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
81 if(j==lag){
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
82 double sum = 1.0;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
83 for(i=j-1; i<len; i+=2){
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
84 sum += data1[i ] * data1[i-j ]
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
85 + data1[i+1] * data1[i-j+1];
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
86 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
87 autoc[j] = sum;
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
88 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
89 }
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
90
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
91 /**
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
92 * Quantize LPC coefficients
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
93 */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
94 static void quantize_lpc_coefs(double *lpc_in, int order, int precision,
7588
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
95 int32_t *lpc_out, int *shift, int max_shift, int zero_shift)
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
96 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
97 int i;
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
98 double cmax, error;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
99 int32_t qmax;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
100 int sh;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
101
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
102 /* define maximum levels */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
103 qmax = (1 << (precision - 1)) - 1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
104
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
105 /* find maximum coefficient value */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
106 cmax = 0.0;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
107 for(i=0; i<order; i++) {
3389
de8cdb05117f simplify
michael
parents: 3388
diff changeset
108 cmax= FFMAX(cmax, fabs(lpc_in[i]));
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
109 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
110
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
111 /* if maximum value quantizes to zero, return all zeros */
7588
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
112 if(cmax * (1 << max_shift) < 1.0) {
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
113 *shift = zero_shift;
3389
de8cdb05117f simplify
michael
parents: 3388
diff changeset
114 memset(lpc_out, 0, sizeof(int32_t) * order);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
115 return;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
116 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
117
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
118 /* calculate level shift which scales max coeff to available bits */
7588
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
119 sh = max_shift;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
120 while((cmax * (1 << sh) > qmax) && (sh > 0)) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
121 sh--;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
122 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
123
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
124 /* since negative shift values are unsupported in decoder, scale down
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
125 coefficients instead */
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
126 if(sh == 0 && cmax > qmax) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
127 double scale = ((double)qmax) / cmax;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
128 for(i=0; i<order; i++) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
129 lpc_in[i] *= scale;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
130 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
131 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
132
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
133 /* output quantized coefficients and level shift */
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
134 error=0;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
135 for(i=0; i<order; i++) {
7788
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
136 error -= lpc_in[i] * (1 << sh);
4594
a96d905dcbaa Add av_ prefix to clip functions
reimar
parents: 4149
diff changeset
137 lpc_out[i] = av_clip(lrintf(error), -qmax, qmax);
3464
9cda085ab7cc dither lpc cpeffs
michael
parents: 3442
diff changeset
138 error -= lpc_out[i];
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
139 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
140 *shift = sh;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
141 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
142
7593
9687dcb225e9 use range of lpc orders in ORDER_METHOD_EST
jbr
parents: 7592
diff changeset
143 static int estimate_best_order(double *ref, int min_order, int max_order)
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
144 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
145 int i, est;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
146
7593
9687dcb225e9 use range of lpc orders in ORDER_METHOD_EST
jbr
parents: 7592
diff changeset
147 est = min_order;
9687dcb225e9 use range of lpc orders in ORDER_METHOD_EST
jbr
parents: 7592
diff changeset
148 for(i=max_order-1; i>=min_order-1; i--) {
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
149 if(ref[i] > 0.10) {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
150 est = i+1;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
151 break;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
152 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
153 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
154 return est;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
155 }
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
156
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
157 /**
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
158 * Calculate LPC coefficients for multiple orders
8824
9f929379bbca lpc: Document the use_lpc parameter to ff_lpc_calc_coefs().
jbr
parents: 7788
diff changeset
159 *
9f929379bbca lpc: Document the use_lpc parameter to ff_lpc_calc_coefs().
jbr
parents: 7788
diff changeset
160 * @param use_lpc LPC method for determining coefficients
9f929379bbca lpc: Document the use_lpc parameter to ff_lpc_calc_coefs().
jbr
parents: 7788
diff changeset
161 * 0 = LPC with fixed pre-defined coeffs
9f929379bbca lpc: Document the use_lpc parameter to ff_lpc_calc_coefs().
jbr
parents: 7788
diff changeset
162 * 1 = LPC with coeffs determined by Levinson-Durbin recursion
9f929379bbca lpc: Document the use_lpc parameter to ff_lpc_calc_coefs().
jbr
parents: 7788
diff changeset
163 * 2+ = LPC with coeffs determined by Cholesky factorization using (use_lpc-1) passes.
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
164 */
7589
8b695a99e8df flacenc, lpc: Move LPC code from flacenc.c to new lpc.[ch] files.
ramiro
parents: 7588
diff changeset
165 int ff_lpc_calc_coefs(DSPContext *s,
7592
377fddcc6288 cosmetics: adjust line breaks and vertical alignment
jbr
parents: 7591
diff changeset
166 const int32_t *samples, int blocksize, int min_order,
377fddcc6288 cosmetics: adjust line breaks and vertical alignment
jbr
parents: 7591
diff changeset
167 int max_order, int precision,
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
168 int32_t coefs[][MAX_LPC_ORDER], int *shift,
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
169 enum AVLPCType lpc_type, int lpc_passes,
7592
377fddcc6288 cosmetics: adjust line breaks and vertical alignment
jbr
parents: 7591
diff changeset
170 int omethod, int max_shift, int zero_shift)
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
171 {
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
172 double autoc[MAX_LPC_ORDER+1];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
173 double ref[MAX_LPC_ORDER];
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
174 double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
175 int i, j, pass;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
176 int opt_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
177
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
178 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER &&
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
179 lpc_type > AV_LPC_TYPE_FIXED);
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
180
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
181 if (lpc_type == AV_LPC_TYPE_LEVINSON) {
10424
94595d0e617c Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents: 8826
diff changeset
182 s->lpc_compute_autocorr(samples, blocksize, max_order, autoc);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
183
7788
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
184 compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1);
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
185
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
186 for(i=0; i<max_order; i++)
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
187 ref[i] = fabs(lpc[i][i]);
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
188 } else if (lpc_type == AV_LPC_TYPE_CHOLESKY) {
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
189 LLSModel m[2];
8826
bffe8e6cb10e lpc: Remove false positive compilation warning about weight being
jbr
parents: 8825
diff changeset
190 double var[MAX_LPC_ORDER+1], av_uninit(weight);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
191
12139
e59926e2c50c Add AVCodecContext.lpc_type and Add AVCodecContext.lpc_passes fields.
jbr
parents: 12024
diff changeset
192 for(pass=0; pass<lpc_passes; pass++){
3470
c6071e607062 cleanup
michael
parents: 3467
diff changeset
193 av_init_lls(&m[pass&1], max_order);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
194
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
195 weight=0;
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
196 for(i=max_order; i<blocksize; i++){
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
197 for(j=0; j<=max_order; j++)
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
198 var[j]= samples[i-j];
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
199
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
200 if(pass){
5743
8ce32ae71c01 div -> mul
lorenm
parents: 5742
diff changeset
201 double eval, inv, rinv;
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
202 eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
203 eval= (512>>pass) + fabs(eval - var[0]);
5743
8ce32ae71c01 div -> mul
lorenm
parents: 5742
diff changeset
204 inv = 1/eval;
8ce32ae71c01 div -> mul
lorenm
parents: 5742
diff changeset
205 rinv = sqrt(inv);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
206 for(j=0; j<=max_order; j++)
5743
8ce32ae71c01 div -> mul
lorenm
parents: 5742
diff changeset
207 var[j] *= rinv;
8ce32ae71c01 div -> mul
lorenm
parents: 5742
diff changeset
208 weight += inv;
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
209 }else
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
210 weight++;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
211
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
212 av_update_lls(&m[pass&1], var, 1.0);
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
213 }
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
214 av_solve_lls(&m[pass&1], 0.001, 0);
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
215 }
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
216
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
217 for(i=0; i<max_order; i++){
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
218 for(j=0; j<max_order; j++)
7788
ffd4b1364b62 Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents: 7753
diff changeset
219 lpc[i][j]=-m[(pass-1)&1].coeff[i][j];
3473
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
220 ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000;
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
221 }
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
222 for(i=max_order-1; i>0; i--)
fa545ed305c9 calculate all coefficients for several orders during cholesky factorization, the resulting coefficients are not strictly optimal though as there is a small difference in the autocorrelation matrixes which is ignored for the smaller orders
michael
parents: 3470
diff changeset
223 ref[i] = ref[i-1] - ref[i];
3467
33af013504d5 optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents: 3464
diff changeset
224 }
3477
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
225 opt_order = max_order;
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
226
3477
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
227 if(omethod == ORDER_METHOD_EST) {
7593
9687dcb225e9 use range of lpc orders in ORDER_METHOD_EST
jbr
parents: 7592
diff changeset
228 opt_order = estimate_best_order(ref, min_order, max_order);
3477
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
229 i = opt_order-1;
7588
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
230 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
3477
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
231 } else {
7591
7dfb28d3ccd1 use limited range of lpc orders when quantizing coefficients
jbr
parents: 7590
diff changeset
232 for(i=min_order-1; i<max_order; i++) {
7588
f6a1bff47a3b flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents: 7451
diff changeset
233 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift);
3477
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
234 }
30ac8a424448 Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents: 3473
diff changeset
235 }
3385
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
236
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
237 return opt_order;
340e5d35b326 flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents: 3384
diff changeset
238 }