3 * Copyright (c) 2006 Justin Ruggles <justin.ruggles@gmail.com>
5 * This file is part of FFmpeg.
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 #include "libavutil/lls.h"
25 #define LPC_USE_DOUBLE
30 * Quantize LPC coefficients
32 static void quantize_lpc_coefs(double *lpc_in
, int order
, int precision
,
33 int32_t *lpc_out
, int *shift
, int max_shift
, int zero_shift
)
40 /* define maximum levels */
41 qmax
= (1 << (precision
- 1)) - 1;
43 /* find maximum coefficient value */
45 for(i
=0; i
<order
; i
++) {
46 cmax
= FFMAX(cmax
, fabs(lpc_in
[i
]));
49 /* if maximum value quantizes to zero, return all zeros */
50 if(cmax
* (1 << max_shift
) < 1.0) {
52 memset(lpc_out
, 0, sizeof(int32_t) * order
);
56 /* calculate level shift which scales max coeff to available bits */
58 while((cmax
* (1 << sh
) > qmax
) && (sh
> 0)) {
62 /* since negative shift values are unsupported in decoder, scale down
63 coefficients instead */
64 if(sh
== 0 && cmax
> qmax
) {
65 double scale
= ((double)qmax
) / cmax
;
66 for(i
=0; i
<order
; i
++) {
71 /* output quantized coefficients and level shift */
73 for(i
=0; i
<order
; i
++) {
74 error
-= lpc_in
[i
] * (1 << sh
);
75 lpc_out
[i
] = av_clip(lrintf(error
), -qmax
, qmax
);
81 static int estimate_best_order(double *ref
, int min_order
, int max_order
)
86 for(i
=max_order
-1; i
>=min_order
-1; i
--) {
96 * Calculate LPC coefficients for multiple orders
98 * @param use_lpc LPC method for determining coefficients
99 * 0 = LPC with fixed pre-defined coeffs
100 * 1 = LPC with coeffs determined by Levinson-Durbin recursion
101 * 2+ = LPC with coeffs determined by Cholesky factorization using (use_lpc-1) passes.
103 int ff_lpc_calc_coefs(DSPContext
*s
,
104 const int32_t *samples
, int blocksize
, int min_order
,
105 int max_order
, int precision
,
106 int32_t coefs
[][MAX_LPC_ORDER
], int *shift
, int use_lpc
,
107 int omethod
, int max_shift
, int zero_shift
)
109 double autoc
[MAX_LPC_ORDER
+1];
110 double ref
[MAX_LPC_ORDER
];
111 double lpc
[MAX_LPC_ORDER
][MAX_LPC_ORDER
];
115 assert(max_order
>= MIN_LPC_ORDER
&& max_order
<= MAX_LPC_ORDER
&& use_lpc
> 0);
118 s
->flac_compute_autocorr(samples
, blocksize
, max_order
, autoc
);
120 compute_lpc_coefs(autoc
, max_order
, &lpc
[0][0], MAX_LPC_ORDER
, 0, 1);
122 for(i
=0; i
<max_order
; i
++)
123 ref
[i
] = fabs(lpc
[i
][i
]);
126 double var
[MAX_LPC_ORDER
+1], av_uninit(weight
);
128 for(pass
=0; pass
<use_lpc
-1; pass
++){
129 av_init_lls(&m
[pass
&1], max_order
);
132 for(i
=max_order
; i
<blocksize
; i
++){
133 for(j
=0; j
<=max_order
; j
++)
134 var
[j
]= samples
[i
-j
];
137 double eval
, inv
, rinv
;
138 eval
= av_evaluate_lls(&m
[(pass
-1)&1], var
+1, max_order
-1);
139 eval
= (512>>pass
) + fabs(eval
- var
[0]);
142 for(j
=0; j
<=max_order
; j
++)
148 av_update_lls(&m
[pass
&1], var
, 1.0);
150 av_solve_lls(&m
[pass
&1], 0.001, 0);
153 for(i
=0; i
<max_order
; i
++){
154 for(j
=0; j
<max_order
; j
++)
155 lpc
[i
][j
]=-m
[(pass
-1)&1].coeff
[i
][j
];
156 ref
[i
]= sqrt(m
[(pass
-1)&1].variance
[i
] / weight
) * (blocksize
- max_order
) / 4000;
158 for(i
=max_order
-1; i
>0; i
--)
159 ref
[i
] = ref
[i
-1] - ref
[i
];
161 opt_order
= max_order
;
163 if(omethod
== ORDER_METHOD_EST
) {
164 opt_order
= estimate_best_order(ref
, min_order
, max_order
);
166 quantize_lpc_coefs(lpc
[i
], i
+1, precision
, coefs
[i
], &shift
[i
], max_shift
, zero_shift
);
168 for(i
=min_order
-1; i
<max_order
; i
++) {
169 quantize_lpc_coefs(lpc
[i
], i
+1, precision
, coefs
[i
], &shift
[i
], max_shift
, zero_shift
);