comparison cook.c @ 4639:33fc84eae7c3 libavcodec

Simplify gain block handling. Patch by Ian Braithwaite <ian at braithwaite dot dk>
author banan
date Thu, 08 Mar 2007 20:43:51 +0000
parents 9f74306d4ac7
children 31bf54d9353d
comparison
equal deleted inserted replaced
4638:9f74306d4ac7 4639:33fc84eae7c3
63 63
64 #define SUBBAND_SIZE 20 64 #define SUBBAND_SIZE 20
65 //#define COOKDEBUG 65 //#define COOKDEBUG
66 66
67 typedef struct { 67 typedef struct {
68 int size; 68 int *now;
69 int loccode[8]; 69 int *previous;
70 int levcode[8]; 70 } cook_gains;
71 } COOKgain;
72 71
73 typedef struct { 72 typedef struct {
74 GetBitContext gb; 73 GetBitContext gb;
75 /* stream data */ 74 /* stream data */
76 int nb_channels; 75 int nb_channels;
100 int fft_size; 99 int fft_size;
101 int fft_order; 100 int fft_order;
102 int mlt_size; //modulated lapped transform size 101 int mlt_size; //modulated lapped transform size
103 102
104 /* gain buffers */ 103 /* gain buffers */
105 COOKgain *gain_ptr1[2]; 104 cook_gains gains1;
106 COOKgain *gain_ptr2[2]; 105 cook_gains gains2;
107 COOKgain gain_1; 106 int gain_1[9];
108 COOKgain gain_2; 107 int gain_2[9];
109 COOKgain gain_3; 108 int gain_3[9];
110 COOKgain gain_4; 109 int gain_4[9];
111 110
112 /* VLC data */ 111 /* VLC data */
113 int js_vlc_bits; 112 int js_vlc_bits;
114 VLC envelope_quant_index[13]; 113 VLC envelope_quant_index[13];
115 VLC sqvh[7]; //scalar quantization 114 VLC sqvh[7]; //scalar quantization
337 336
338 return 0; 337 return 0;
339 } 338 }
340 339
341 /** 340 /**
342 * Fill the COOKgain structure for the timedomain quantization. 341 * Fill the gain array for the timedomain quantization.
343 * 342 *
344 * @param q pointer to the COOKContext 343 * @param q pointer to the COOKContext
345 * @param gaininfo pointer to the COOKgain 344 * @param gaininfo[9] array of gain indices
346 */ 345 */
347 346
348 static void decode_gain_info(GetBitContext *gb, COOKgain* gaininfo) { 347 static void decode_gain_info(GetBitContext *gb, int *gaininfo)
349 int i; 348 {
349 int i, n;
350 350
351 while (get_bits1(gb)) {} 351 while (get_bits1(gb)) {}
352 352 n = get_bits_count(gb) - 1; //amount of elements*2 to update
353 gaininfo->size = get_bits_count(gb) - 1; //amount of elements*2 to update 353
354 354 i = 0;
355 if (get_bits_count(gb) - 1 <= 0) return; 355 while (n--) {
356 356 int index = get_bits(gb, 3);
357 for (i=0 ; i<gaininfo->size ; i++){ 357 int gain = get_bits1(gb) ? get_bits(gb, 4) - 7 : -1;
358 gaininfo->loccode[i] = get_bits(gb,3); 358
359 if (get_bits1(gb)) { 359 while (i <= index) gaininfo[i++] = gain;
360 gaininfo->levcode[i] = get_bits(gb,4) - 7; //convert to signed 360 }
361 } else { 361 while (i <= 8) gaininfo[i++] = 0;
362 gaininfo->levcode[i] = -1;
363 }
364 }
365 } 362 }
366 363
367 /** 364 /**
368 * Create the quant index table needed for the envelope. 365 * Create the quant index table needed for the envelope.
369 * 366 *
782 } 779 }
783 return; 780 return;
784 } 781 }
785 } 782 }
786 783
787 /** 784
788 * timedomain requantization of the timedomain samples 785 /**
786 * mlt overlapping and buffer management
789 * 787 *
790 * @param q pointer to the COOKContext 788 * @param q pointer to the COOKContext
791 * @param buffer pointer to the timedomain buffer 789 * @param gains_ptr current and previous gains
792 * @param gain_now current gain structure
793 * @param gain_previous previous gain structure
794 */
795
796 static void gain_window(COOKContext *q, float* buffer, COOKgain* gain_now,
797 COOKgain* gain_previous){
798 int i, index;
799 int gain_index[9];
800 int tmp_gain_index;
801
802 gain_index[8]=0;
803 index = gain_previous->size;
804 for (i=7 ; i>=0 ; i--) {
805 if(index && gain_previous->loccode[index-1]==i) {
806 gain_index[i] = gain_previous->levcode[index-1];
807 index--;
808 } else {
809 gain_index[i]=gain_index[i+1];
810 }
811 }
812 /* This is applied to the to be previous data buffer. */
813 for(i=0;i<8;i++){
814 interpolate(q, &buffer[q->samples_per_channel+q->gain_size_factor*i],
815 gain_index[i], gain_index[i+1]);
816 }
817
818 tmp_gain_index = gain_index[0];
819 index = gain_now->size;
820 for (i=7 ; i>=0 ; i--) {
821 if(index && gain_now->loccode[index-1]==i) {
822 gain_index[i]= gain_now->levcode[index-1];
823 index--;
824 } else {
825 gain_index[i]=gain_index[i+1];
826 }
827 }
828
829 /* This is applied to the to be current block. */
830 for(i=0;i<8;i++){
831 interpolate(q, &buffer[i*q->gain_size_factor],
832 tmp_gain_index+gain_index[i],
833 tmp_gain_index+gain_index[i+1]);
834 }
835 }
836
837
838 /**
839 * mlt overlapping and buffer management
840 *
841 * @param q pointer to the COOKContext
842 * @param buffer pointer to the timedomain buffer
843 * @param gain_now current gain structure
844 * @param gain_previous previous gain structure
845 * @param previous_buffer pointer to the previous buffer to be used for overlapping 790 * @param previous_buffer pointer to the previous buffer to be used for overlapping
846 * 791 */
847 */ 792
848 793 static void gain_compensate(COOKContext *q, cook_gains *gains_ptr,
849 static void gain_compensate(COOKContext *q, float* buffer, COOKgain* gain_now, 794 float* previous_buffer)
850 COOKgain* gain_previous, float* previous_buffer) { 795 {
796 const float fc = q->pow2tab[gains_ptr->previous[0] + 63];
797 float *buffer = q->mono_mdct_output;
851 int i; 798 int i;
852 if((gain_now->size || gain_previous->size)) {
853 gain_window(q, buffer, gain_now, gain_previous);
854 }
855 799
856 /* Overlap with the previous block. */ 800 /* Overlap with the previous block. */
857 for(i=0 ; i<q->samples_per_channel ; i++) buffer[i]+=previous_buffer[i]; 801 for(i=0 ; i<q->samples_per_channel ; i++) {
802 buffer[i] *= fc;
803 buffer[i] += previous_buffer[i];
804 }
805
806 /* Apply gain profile */
807 for (i = 0; i < 8; i++) {
808 if (gains_ptr->now[i] || gains_ptr->now[i + 1])
809 interpolate(q, &buffer[q->gain_size_factor * i],
810 gains_ptr->now[i], gains_ptr->now[i + 1]);
811 }
858 812
859 /* Save away the current to be previous block. */ 813 /* Save away the current to be previous block. */
860 memcpy(previous_buffer, buffer+q->samples_per_channel, 814 memcpy(previous_buffer, buffer+q->samples_per_channel,
861 sizeof(float)*q->samples_per_channel); 815 sizeof(float)*q->samples_per_channel);
862 } 816 }
954 * @param gain_ptr array of current/prev gain pointers 908 * @param gain_ptr array of current/prev gain pointers
955 */ 909 */
956 910
957 static inline void 911 static inline void
958 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer, 912 decode_bytes_and_gain(COOKContext *q, uint8_t *inbuffer,
959 COOKgain *gain_ptr[]) 913 cook_gains *gains_ptr)
960 { 914 {
961 int offset; 915 int offset;
962 916
963 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer, 917 offset = decode_bytes(inbuffer, q->decoded_bytes_buffer,
964 q->bits_per_subpacket/8); 918 q->bits_per_subpacket/8);
965 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset, 919 init_get_bits(&q->gb, q->decoded_bytes_buffer + offset,
966 q->bits_per_subpacket); 920 q->bits_per_subpacket);
967 decode_gain_info(&q->gb, gain_ptr[0]); 921 decode_gain_info(&q->gb, gains_ptr->now);
968 922
969 /* Swap current and previous gains */ 923 /* Swap current and previous gains */
970 FFSWAP(COOKgain *, gain_ptr[0], gain_ptr[1]); 924 FFSWAP(int *, gains_ptr->now, gains_ptr->previous);
971 } 925 }
972 926
973 /** 927 /**
974 * Final part of subpacket decoding: 928 * Final part of subpacket decoding:
975 * Apply modulated lapped transform, gain compensation, 929 * Apply modulated lapped transform, gain compensation,
983 * @param chan 0: left or single channel, 1: right channel 937 * @param chan 0: left or single channel, 1: right channel
984 */ 938 */
985 939
986 static inline void 940 static inline void
987 mlt_compensate_output(COOKContext *q, float *decode_buffer, 941 mlt_compensate_output(COOKContext *q, float *decode_buffer,
988 COOKgain *gain_ptr[], float *previous_buffer, 942 cook_gains *gains, float *previous_buffer,
989 int16_t *out, int chan) 943 int16_t *out, int chan)
990 { 944 {
991 int j; 945 int j;
992 946
993 cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp); 947 cook_imlt(q, decode_buffer, q->mono_mdct_output, q->mlt_tmp);
994 gain_compensate(q, q->mono_mdct_output, gain_ptr[0], 948 gain_compensate(q, gains, previous_buffer);
995 gain_ptr[1], previous_buffer);
996 949
997 /* Clip and convert floats to 16 bits. 950 /* Clip and convert floats to 16 bits.
998 */ 951 */
999 for (j = 0; j < q->samples_per_channel; j++) { 952 for (j = 0; j < q->samples_per_channel; j++) {
1000 out[chan + q->nb_channels * j] = 953 out[chan + q->nb_channels * j] =
1020 // for (i=0 ; i<sub_packet_size ; i++) { 973 // for (i=0 ; i<sub_packet_size ; i++) {
1021 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]); 974 // av_log(NULL, AV_LOG_ERROR, "%02x", inbuffer[i]);
1022 // } 975 // }
1023 // av_log(NULL, AV_LOG_ERROR, "\n"); 976 // av_log(NULL, AV_LOG_ERROR, "\n");
1024 977
1025 decode_bytes_and_gain(q, inbuffer, q->gain_ptr1); 978 decode_bytes_and_gain(q, inbuffer, &q->gains1);
1026 979
1027 if (q->joint_stereo) { 980 if (q->joint_stereo) {
1028 joint_decode(q, q->decode_buffer_1, q->decode_buffer_2); 981 joint_decode(q, q->decode_buffer_1, q->decode_buffer_2);
1029 } else { 982 } else {
1030 mono_decode(q, q->decode_buffer_1); 983 mono_decode(q, q->decode_buffer_1);
1031 984
1032 if (q->nb_channels == 2) { 985 if (q->nb_channels == 2) {
1033 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, 986 decode_bytes_and_gain(q, inbuffer + sub_packet_size/2, &q->gains2);
1034 q->gain_ptr2);
1035 mono_decode(q, q->decode_buffer_2); 987 mono_decode(q, q->decode_buffer_2);
1036 } 988 }
1037 } 989 }
1038 990
1039 mlt_compensate_output(q, q->decode_buffer_1, q->gain_ptr1, 991 mlt_compensate_output(q, q->decode_buffer_1, &q->gains1,
1040 q->mono_previous_buffer1, outbuffer, 0); 992 q->mono_previous_buffer1, outbuffer, 0);
1041 993
1042 if (q->nb_channels == 2) { 994 if (q->nb_channels == 2) {
1043 if (q->joint_stereo) { 995 if (q->joint_stereo) {
1044 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr1, 996 mlt_compensate_output(q, q->decode_buffer_2, &q->gains1,
1045 q->mono_previous_buffer2, outbuffer, 1); 997 q->mono_previous_buffer2, outbuffer, 1);
1046 } else { 998 } else {
1047 mlt_compensate_output(q, q->decode_buffer_2, q->gain_ptr2, 999 mlt_compensate_output(q, q->decode_buffer_2, &q->gains2,
1048 q->mono_previous_buffer2, outbuffer, 1); 1000 q->mono_previous_buffer2, outbuffer, 1);
1049 } 1001 }
1050 } 1002 }
1051 return q->samples_per_frame * sizeof(int16_t); 1003 return q->samples_per_frame * sizeof(int16_t);
1052 } 1004 }
1223 + FF_INPUT_BUFFER_PADDING_SIZE); 1175 + FF_INPUT_BUFFER_PADDING_SIZE);
1224 } 1176 }
1225 if (q->decoded_bytes_buffer == NULL) 1177 if (q->decoded_bytes_buffer == NULL)
1226 return -1; 1178 return -1;
1227 1179
1228 q->gain_ptr1[0] = &q->gain_1; 1180 q->gains1.now = q->gain_1;
1229 q->gain_ptr1[1] = &q->gain_2; 1181 q->gains1.previous = q->gain_2;
1230 q->gain_ptr2[0] = &q->gain_3; 1182 q->gains2.now = q->gain_3;
1231 q->gain_ptr2[1] = &q->gain_4; 1183 q->gains2.previous = q->gain_4;
1232 1184
1233 /* Initialize transform. */ 1185 /* Initialize transform. */
1234 if ( init_cook_mlt(q) == 0 ) 1186 if ( init_cook_mlt(q) == 0 )
1235 return -1; 1187 return -1;
1236 1188