Mercurial > libavcodec.hg
annotate lpc.c @ 11352:6e0af2cfdcfe libavcodec
Do MC and IDCT in coding (hilbert) order
This increases the slice size to 64 pixels, due to having to decode an
entire chroma superblock row per slice.
This can be up to 6% slower depending on clip and CPU, but is necessary
for future optimizations that gain significantly more than was lost.
author | conrad |
---|---|
date | Wed, 03 Mar 2010 23:27:40 +0000 |
parents | 94595d0e617c |
children | fdafbcef52f5 |
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 | 22 #include "libavutil/lls.h" |
5737 | 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 /** |
94595d0e617c
Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents:
8826
diff
changeset
|
55 * Calculates autocorrelation data from audio samples |
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 | 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 | 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 | 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 | 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 | 137 lpc_out[i] = av_clip(lrintf(error), -qmax, qmax); |
3464 | 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 | 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 | 147 est = min_order; |
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 | 166 const int32_t *samples, int blocksize, int min_order, |
167 int max_order, int precision, | |
168 int32_t coefs[][MAX_LPC_ORDER], int *shift, int use_lpc, | |
169 int omethod, int max_shift, int zero_shift) | |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
170 { |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
171 double autoc[MAX_LPC_ORDER+1]; |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
172 double ref[MAX_LPC_ORDER]; |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
173 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
|
174 int i, j, pass; |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
175 int opt_order; |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
176 |
8825
51274aff81fe
Assert that ff_lpc_calc_coefs() is called with a valid LPC method.
jbr
parents:
8824
diff
changeset
|
177 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER && use_lpc > 0); |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
178 |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
179 if(use_lpc == 1){ |
10424
94595d0e617c
Move autocorrelation function from flacenc.c to lpc.c. Also rename the
jbr
parents:
8826
diff
changeset
|
180 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
|
181 |
7788
ffd4b1364b62
Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents:
7753
diff
changeset
|
182 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
|
183 |
ffd4b1364b62
Avoid duplicating compute_lpc_coefs() function in both the RA288 and AAC decoders.
vitor
parents:
7753
diff
changeset
|
184 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
|
185 ref[i] = fabs(lpc[i][i]); |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
186 }else{ |
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
187 LLSModel m[2]; |
8826
bffe8e6cb10e
lpc: Remove false positive compilation warning about weight being
jbr
parents:
8825
diff
changeset
|
188 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
|
189 |
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
190 for(pass=0; pass<use_lpc-1; pass++){ |
3470 | 191 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
|
192 |
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
|
193 weight=0; |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
194 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
|
195 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
|
196 var[j]= samples[i-j]; |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
197 |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
198 if(pass){ |
5743 | 199 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
|
200 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
|
201 eval= (512>>pass) + fabs(eval - var[0]); |
5743 | 202 inv = 1/eval; |
203 rinv = sqrt(inv); | |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
204 for(j=0; j<=max_order; j++) |
5743 | 205 var[j] *= rinv; |
206 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
|
207 }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
|
208 weight++; |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
209 |
3467
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
210 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
|
211 } |
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
|
212 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
|
213 } |
33af013504d5
optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients
michael
parents:
3464
diff
changeset
|
214 |
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
|
215 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
|
216 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
|
217 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
|
218 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
|
219 } |
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 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
|
221 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
|
222 } |
3477
30ac8a424448
Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents:
3473
diff
changeset
|
223 opt_order = max_order; |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
224 |
3477
30ac8a424448
Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents:
3473
diff
changeset
|
225 if(omethod == ORDER_METHOD_EST) { |
7593 | 226 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
|
227 i = opt_order-1; |
7588
f6a1bff47a3b
flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents:
7451
diff
changeset
|
228 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
|
229 } else { |
7591
7dfb28d3ccd1
use limited range of lpc orders when quantizing coefficients
jbr
parents:
7590
diff
changeset
|
230 for(i=min_order-1; i<max_order; i++) { |
7588
f6a1bff47a3b
flacenc: Allow more flexible shift calculation in LPC.
ramiro
parents:
7451
diff
changeset
|
231 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
|
232 } |
30ac8a424448
Add lpc order search. This creates new compression levels 6 to 12.
jbr
parents:
3473
diff
changeset
|
233 } |
3385
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
234 |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
235 return opt_order; |
340e5d35b326
flac-lpc patch by (Justin Ruggles jruggle earthlink net)
michael
parents:
3384
diff
changeset
|
236 } |