comparison flacenc.c @ 3467:33af013504d5 libavcodec

optionally (use_lpc=2) support Cholesky factorization for finding the lpc coeficients this will find the coefficients which minimize the sum of the squared errors, levinson-durbin recursion OTOH is only strictly correct if the autocorrelation matrix is a toeplitz matrix which it is only if the blocksize is infinite, this is also why applying a window (like the welch winodw we currently use) improves the lpc coefficients generated by levinson-durbin recursion ... optionally (use_lpc>2) support iterative linear least abs() solver using cholesky factorization with adjusted weights in each iteration compression gain for both is small, and multiple passes are of course dead slow
author michael
date Fri, 14 Jul 2006 18:48:38 +0000
parents 9cda085ab7cc
children c6071e607062
comparison
equal deleted inserted replaced
3466:af598a3e2340 3467:33af013504d5
19 19
20 #include "avcodec.h" 20 #include "avcodec.h"
21 #include "bitstream.h" 21 #include "bitstream.h"
22 #include "crc.h" 22 #include "crc.h"
23 #include "golomb.h" 23 #include "golomb.h"
24 #include "lls.h"
24 25
25 #define FLAC_MAX_CH 8 26 #define FLAC_MAX_CH 8
26 #define FLAC_MIN_BLOCKSIZE 16 27 #define FLAC_MIN_BLOCKSIZE 16
27 #define FLAC_MAX_BLOCKSIZE 65535 28 #define FLAC_MAX_BLOCKSIZE 65535
28 29
234 s->options.min_partition_order = ((int[]){ 2, 2, 0, 0, 0, 0})[level]; 235 s->options.min_partition_order = ((int[]){ 2, 2, 0, 0, 0, 0})[level];
235 s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8})[level]; 236 s->options.max_partition_order = ((int[]){ 2, 2, 3, 3, 3, 8})[level];
236 237
237 /* set compression option overrides from AVCodecContext */ 238 /* set compression option overrides from AVCodecContext */
238 if(avctx->use_lpc >= 0) { 239 if(avctx->use_lpc >= 0) {
239 s->options.use_lpc = !!avctx->use_lpc; 240 s->options.use_lpc = clip(avctx->use_lpc, 0, 11);
240 } 241 }
241 av_log(avctx, AV_LOG_DEBUG, " use lpc: %s\n", 242 if(s->options.use_lpc == 1)
242 s->options.use_lpc? "yes" : "no"); 243 av_log(avctx, AV_LOG_DEBUG, " use lpc: Levinson-Durbin recursion with Welch window\n");
244 else if(s->options.use_lpc > 1)
245 av_log(avctx, AV_LOG_DEBUG, " use lpc: Cholesky factorization\n");
243 246
244 if(avctx->min_prediction_order >= 0) { 247 if(avctx->min_prediction_order >= 0) {
245 if(s->options.use_lpc) { 248 if(s->options.use_lpc) {
246 if(avctx->min_prediction_order < MIN_LPC_ORDER || 249 if(avctx->min_prediction_order < MIN_LPC_ORDER ||
247 avctx->min_prediction_order > MAX_LPC_ORDER) { 250 avctx->min_prediction_order > MAX_LPC_ORDER) {
723 /** 726 /**
724 * Calculate LPC coefficients for multiple orders 727 * Calculate LPC coefficients for multiple orders
725 */ 728 */
726 static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order, 729 static int lpc_calc_coefs(const int32_t *samples, int blocksize, int max_order,
727 int precision, int32_t coefs[][MAX_LPC_ORDER], 730 int precision, int32_t coefs[][MAX_LPC_ORDER],
728 int *shift) 731 int *shift, int use_lpc)
729 { 732 {
730 double autoc[MAX_LPC_ORDER+1]; 733 double autoc[MAX_LPC_ORDER+1];
731 double ref[MAX_LPC_ORDER]; 734 double ref[MAX_LPC_ORDER];
732 double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; 735 double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER];
733 int i; 736 int i, j, pass;
734 int opt_order; 737 int opt_order;
735 738
736 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER); 739 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER);
737 740
738 compute_autocorr(samples, blocksize, max_order+1, autoc); 741 if(use_lpc == 1){
739 742 compute_autocorr(samples, blocksize, max_order+1, autoc);
740 compute_lpc_coefs(autoc, max_order, lpc, ref); 743
741 744 compute_lpc_coefs(autoc, max_order, lpc, ref);
742 opt_order = estimate_best_order(ref, max_order); 745
746 opt_order = estimate_best_order(ref, max_order);
747 }else{
748 LLSModel m[2];
749 double var[MAX_LPC_ORDER+1], eval;
750
751 for(pass=0; pass<use_lpc-1; pass++){
752 av_init_lls(&m[pass&1], max_order/*3*/);
753
754 for(i=max_order; i<blocksize; i++){
755 for(j=0; j<=max_order; j++)
756 var[j]= samples[i-j];
757
758 if(pass){
759 eval= av_evaluate_lls(&m[(pass-1)&1], var+1);
760 eval= (512>>pass) + fabs(eval - var[0]);
761 for(j=0; j<=max_order; j++)
762 var[j]= samples[i-j] / sqrt(eval);
763 }
764
765 av_update_lls(&m[pass&1], var, 1.0);
766 }
767 av_solve_lls(&m[pass&1], 0.001);
768 opt_order= max_order; //FIXME
769 }
770
771 for(i=0; i<opt_order; i++)
772 lpc[opt_order-1][i]= m[(pass-1)&1].coeff[i];
773 }
743 774
744 i = opt_order-1; 775 i = opt_order-1;
745 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i]); 776 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i]);
746 777
747 return opt_order; 778 return opt_order;
863 } 894 }
864 return bits[sub->order]; 895 return bits[sub->order];
865 } 896 }
866 897
867 /* LPC */ 898 /* LPC */
868 sub->order = lpc_calc_coefs(smp, n, max_order, precision, coefs, shift); 899 sub->order = lpc_calc_coefs(smp, n, max_order, precision, coefs, shift, ctx->options.use_lpc);
869 sub->type = FLAC_SUBFRAME_LPC; 900 sub->type = FLAC_SUBFRAME_LPC;
870 sub->type_code = sub->type | (sub->order-1); 901 sub->type_code = sub->type | (sub->order-1);
871 sub->shift = shift[sub->order-1]; 902 sub->shift = shift[sub->order-1];
872 for(i=0; i<sub->order; i++) { 903 for(i=0; i<sub->order; i++) {
873 sub->coefs[i] = coefs[sub->order-1][i]; 904 sub->coefs[i] = coefs[sub->order-1][i];