Mercurial > libavcodec.hg
comparison flacenc.c @ 7589:8b695a99e8df libavcodec
flacenc, lpc: Move LPC code from flacenc.c to new lpc.[ch] files.
author | ramiro |
---|---|
date | Sat, 16 Aug 2008 17:18:20 +0000 |
parents | f6a1bff47a3b |
children | 7dfb28d3ccd1 |
comparison
equal
deleted
inserted
replaced
7588:f6a1bff47a3b | 7589:8b695a99e8df |
---|---|
23 #include "libavutil/lls.h" | 23 #include "libavutil/lls.h" |
24 #include "avcodec.h" | 24 #include "avcodec.h" |
25 #include "bitstream.h" | 25 #include "bitstream.h" |
26 #include "dsputil.h" | 26 #include "dsputil.h" |
27 #include "golomb.h" | 27 #include "golomb.h" |
28 #include "lpc.h" | |
28 | 29 |
29 #define FLAC_MAX_CH 8 | 30 #define FLAC_MAX_CH 8 |
30 #define FLAC_MIN_BLOCKSIZE 16 | 31 #define FLAC_MIN_BLOCKSIZE 16 |
31 #define FLAC_MAX_BLOCKSIZE 65535 | 32 #define FLAC_MAX_BLOCKSIZE 65535 |
32 | 33 |
39 #define FLAC_CHMODE_LEFT_RIGHT 1 | 40 #define FLAC_CHMODE_LEFT_RIGHT 1 |
40 #define FLAC_CHMODE_LEFT_SIDE 8 | 41 #define FLAC_CHMODE_LEFT_SIDE 8 |
41 #define FLAC_CHMODE_RIGHT_SIDE 9 | 42 #define FLAC_CHMODE_RIGHT_SIDE 9 |
42 #define FLAC_CHMODE_MID_SIDE 10 | 43 #define FLAC_CHMODE_MID_SIDE 10 |
43 | 44 |
44 #define ORDER_METHOD_EST 0 | |
45 #define ORDER_METHOD_2LEVEL 1 | |
46 #define ORDER_METHOD_4LEVEL 2 | |
47 #define ORDER_METHOD_8LEVEL 3 | |
48 #define ORDER_METHOD_SEARCH 4 | |
49 #define ORDER_METHOD_LOG 5 | |
50 | |
51 #define FLAC_STREAMINFO_SIZE 34 | 45 #define FLAC_STREAMINFO_SIZE 34 |
52 | 46 |
53 #define MIN_LPC_ORDER 1 | |
54 #define MAX_LPC_ORDER 32 | |
55 #define MAX_FIXED_ORDER 4 | 47 #define MAX_FIXED_ORDER 4 |
56 #define MAX_PARTITION_ORDER 8 | 48 #define MAX_PARTITION_ORDER 8 |
57 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) | 49 #define MAX_PARTITIONS (1 << MAX_PARTITION_ORDER) |
58 #define MAX_LPC_PRECISION 15 | 50 #define MAX_LPC_PRECISION 15 |
59 #define MAX_LPC_SHIFT 15 | 51 #define MAX_LPC_SHIFT 15 |
631 sum += data1[i ] * data1[i-j ] | 623 sum += data1[i ] * data1[i-j ] |
632 + data1[i+1] * data1[i-j+1]; | 624 + data1[i+1] * data1[i-j+1]; |
633 } | 625 } |
634 autoc[j] = sum; | 626 autoc[j] = sum; |
635 } | 627 } |
636 } | |
637 | |
638 /** | |
639 * Levinson-Durbin recursion. | |
640 * Produces LPC coefficients from autocorrelation data. | |
641 */ | |
642 static void compute_lpc_coefs(const double *autoc, int max_order, | |
643 double lpc[][MAX_LPC_ORDER], double *ref) | |
644 { | |
645 int i, j, i2; | |
646 double r, err, tmp; | |
647 double lpc_tmp[MAX_LPC_ORDER]; | |
648 | |
649 for(i=0; i<max_order; i++) lpc_tmp[i] = 0; | |
650 err = autoc[0]; | |
651 | |
652 for(i=0; i<max_order; i++) { | |
653 r = -autoc[i+1]; | |
654 for(j=0; j<i; j++) { | |
655 r -= lpc_tmp[j] * autoc[i-j]; | |
656 } | |
657 r /= err; | |
658 ref[i] = fabs(r); | |
659 | |
660 err *= 1.0 - (r * r); | |
661 | |
662 i2 = (i >> 1); | |
663 lpc_tmp[i] = r; | |
664 for(j=0; j<i2; j++) { | |
665 tmp = lpc_tmp[j]; | |
666 lpc_tmp[j] += r * lpc_tmp[i-1-j]; | |
667 lpc_tmp[i-1-j] += r * tmp; | |
668 } | |
669 if(i & 1) { | |
670 lpc_tmp[j] += lpc_tmp[j] * r; | |
671 } | |
672 | |
673 for(j=0; j<=i; j++) { | |
674 lpc[i][j] = -lpc_tmp[j]; | |
675 } | |
676 } | |
677 } | |
678 | |
679 /** | |
680 * Quantize LPC coefficients | |
681 */ | |
682 static void quantize_lpc_coefs(double *lpc_in, int order, int precision, | |
683 int32_t *lpc_out, int *shift, int max_shift, int zero_shift) | |
684 { | |
685 int i; | |
686 double cmax, error; | |
687 int32_t qmax; | |
688 int sh; | |
689 | |
690 /* define maximum levels */ | |
691 qmax = (1 << (precision - 1)) - 1; | |
692 | |
693 /* find maximum coefficient value */ | |
694 cmax = 0.0; | |
695 for(i=0; i<order; i++) { | |
696 cmax= FFMAX(cmax, fabs(lpc_in[i])); | |
697 } | |
698 | |
699 /* if maximum value quantizes to zero, return all zeros */ | |
700 if(cmax * (1 << max_shift) < 1.0) { | |
701 *shift = zero_shift; | |
702 memset(lpc_out, 0, sizeof(int32_t) * order); | |
703 return; | |
704 } | |
705 | |
706 /* calculate level shift which scales max coeff to available bits */ | |
707 sh = max_shift; | |
708 while((cmax * (1 << sh) > qmax) && (sh > 0)) { | |
709 sh--; | |
710 } | |
711 | |
712 /* since negative shift values are unsupported in decoder, scale down | |
713 coefficients instead */ | |
714 if(sh == 0 && cmax > qmax) { | |
715 double scale = ((double)qmax) / cmax; | |
716 for(i=0; i<order; i++) { | |
717 lpc_in[i] *= scale; | |
718 } | |
719 } | |
720 | |
721 /* output quantized coefficients and level shift */ | |
722 error=0; | |
723 for(i=0; i<order; i++) { | |
724 error += lpc_in[i] * (1 << sh); | |
725 lpc_out[i] = av_clip(lrintf(error), -qmax, qmax); | |
726 error -= lpc_out[i]; | |
727 } | |
728 *shift = sh; | |
729 } | |
730 | |
731 static int estimate_best_order(double *ref, int max_order) | |
732 { | |
733 int i, est; | |
734 | |
735 est = 1; | |
736 for(i=max_order-1; i>=0; i--) { | |
737 if(ref[i] > 0.10) { | |
738 est = i+1; | |
739 break; | |
740 } | |
741 } | |
742 return est; | |
743 } | |
744 | |
745 /** | |
746 * Calculate LPC coefficients for multiple orders | |
747 */ | |
748 static int lpc_calc_coefs(DSPContext *s, | |
749 const int32_t *samples, int blocksize, int max_order, | |
750 int precision, int32_t coefs[][MAX_LPC_ORDER], | |
751 int *shift, int use_lpc, int omethod, int max_shift, int zero_shift) | |
752 { | |
753 double autoc[MAX_LPC_ORDER+1]; | |
754 double ref[MAX_LPC_ORDER]; | |
755 double lpc[MAX_LPC_ORDER][MAX_LPC_ORDER]; | |
756 int i, j, pass; | |
757 int opt_order; | |
758 | |
759 assert(max_order >= MIN_LPC_ORDER && max_order <= MAX_LPC_ORDER); | |
760 | |
761 if(use_lpc == 1){ | |
762 s->flac_compute_autocorr(samples, blocksize, max_order, autoc); | |
763 | |
764 compute_lpc_coefs(autoc, max_order, lpc, ref); | |
765 }else{ | |
766 LLSModel m[2]; | |
767 double var[MAX_LPC_ORDER+1], weight; | |
768 | |
769 for(pass=0; pass<use_lpc-1; pass++){ | |
770 av_init_lls(&m[pass&1], max_order); | |
771 | |
772 weight=0; | |
773 for(i=max_order; i<blocksize; i++){ | |
774 for(j=0; j<=max_order; j++) | |
775 var[j]= samples[i-j]; | |
776 | |
777 if(pass){ | |
778 double eval, inv, rinv; | |
779 eval= av_evaluate_lls(&m[(pass-1)&1], var+1, max_order-1); | |
780 eval= (512>>pass) + fabs(eval - var[0]); | |
781 inv = 1/eval; | |
782 rinv = sqrt(inv); | |
783 for(j=0; j<=max_order; j++) | |
784 var[j] *= rinv; | |
785 weight += inv; | |
786 }else | |
787 weight++; | |
788 | |
789 av_update_lls(&m[pass&1], var, 1.0); | |
790 } | |
791 av_solve_lls(&m[pass&1], 0.001, 0); | |
792 } | |
793 | |
794 for(i=0; i<max_order; i++){ | |
795 for(j=0; j<max_order; j++) | |
796 lpc[i][j]= m[(pass-1)&1].coeff[i][j]; | |
797 ref[i]= sqrt(m[(pass-1)&1].variance[i] / weight) * (blocksize - max_order) / 4000; | |
798 } | |
799 for(i=max_order-1; i>0; i--) | |
800 ref[i] = ref[i-1] - ref[i]; | |
801 } | |
802 opt_order = max_order; | |
803 | |
804 if(omethod == ORDER_METHOD_EST) { | |
805 opt_order = estimate_best_order(ref, max_order); | |
806 i = opt_order-1; | |
807 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); | |
808 } else { | |
809 for(i=0; i<max_order; i++) { | |
810 quantize_lpc_coefs(lpc[i], i+1, precision, coefs[i], &shift[i], max_shift, zero_shift); | |
811 } | |
812 } | |
813 | |
814 return opt_order; | |
815 } | 628 } |
816 | 629 |
817 | 630 |
818 static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n) | 631 static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n) |
819 { | 632 { |
1040 } | 853 } |
1041 return bits[sub->order]; | 854 return bits[sub->order]; |
1042 } | 855 } |
1043 | 856 |
1044 /* LPC */ | 857 /* LPC */ |
1045 opt_order = lpc_calc_coefs(&ctx->dsp, smp, n, max_order, precision, coefs, | 858 opt_order = ff_lpc_calc_coefs(&ctx->dsp, smp, n, max_order, precision, coefs, |
1046 shift, ctx->options.use_lpc, omethod, MAX_LPC_SHIFT, 0); | 859 shift, ctx->options.use_lpc, omethod, MAX_LPC_SHIFT, 0); |
1047 | 860 |
1048 if(omethod == ORDER_METHOD_2LEVEL || | 861 if(omethod == ORDER_METHOD_2LEVEL || |
1049 omethod == ORDER_METHOD_4LEVEL || | 862 omethod == ORDER_METHOD_4LEVEL || |
1050 omethod == ORDER_METHOD_8LEVEL) { | 863 omethod == ORDER_METHOD_8LEVEL) { |