📄 cook.c
字号:
expbits_tab[exp_index1[index]+1]; ++exp_index1[index]; } else { /* <--- */ int min = 999999; index=-1; for (i=0 ; i<q->total_subbands ; i++){ if(exp_index2[i] > 0){ v = (-2*exp_index2[i])-quant_index_table[i]+bias; if ( v < min) { min = v; index = i; } } } if(index == -1)break; tmp_categorize_array[--tmp_categorize_array2_idx] = index; tmpbias2 -= expbits_tab[exp_index2[index]] - expbits_tab[exp_index2[index]-1]; --exp_index2[index]; } } for(i=0 ; i<q->total_subbands ; i++) category[i] = exp_index2[i]; for(i=0 ; i<q->numvector_size-1 ; i++) category_index[i] = tmp_categorize_array[tmp_categorize_array2_idx++];}/** * Expand the category vector. * * @param q pointer to the COOKContext * @param category pointer to the category array * @param category_index pointer to the category_index array */static inline void expand_category(COOKContext *q, int* category, int* category_index){ int i; for(i=0 ; i<q->num_vectors ; i++){ ++category[category_index[i]]; }}/** * The real requantization of the mltcoefs * * @param q pointer to the COOKContext * @param index index * @param quant_index quantisation index * @param subband_coef_index array of indexes to quant_centroid_tab * @param subband_coef_sign signs of coefficients * @param mlt_p pointer into the mlt buffer */static void scalar_dequant_float(COOKContext *q, int index, int quant_index, int* subband_coef_index, int* subband_coef_sign, CookFFTSample * mlt_p){ int i; CookFFTSample fix_f1; for(i=0 ; i<SUBBAND_SIZE ; i++) { if (subband_coef_index[i]) { fix_f1 = quant_centroid_tab[index][subband_coef_index[i]]; if (subband_coef_sign[i]) fix_f1 = -fix_f1; } else { /* noise coding if subband_coef_index[i] == 0 */ fix_f1 = dither_tab[index]; if (av_random(&q->random_state) < 0x80000000) fix_f1 = -fix_f1; } if(quant_index > 0){ if(quant_index % 2 == 0){ mlt_p[i] = fix_f1 << (quant_index>>1); }else{ fix_f1 = fix_f1 << (quant_index/2); mlt_p[i] = MUL(FIX_31_SQRT2, fix_f1); } }else if(quant_index <0){ if(quant_index % 2 == 0){ mlt_p[i] = fix_f1 >> (abs(quant_index)>>1); }else{ fix_f1 = fix_f1 >> (abs(quant_index)/2); mlt_p[i] = MUL((FIX_31_SQRT2>>1), fix_f1); } }else{//quant_index == 0 mlt_p[i] = fix_f1; } }}/** * Unpack the subband_coef_index and subband_coef_sign vectors. * * @param q pointer to the COOKContext * @param category pointer to the category array * @param subband_coef_index array of indexes to quant_centroid_tab * @param subband_coef_sign signs of coefficients */static int unpack_SQVH(COOKContext *q, int category, int* subband_coef_index, int* subband_coef_sign) { int i,j; int vlc, vd ,tmp, result; vd = vd_tab[category]; result = 0; for(i=0 ; i<vpr_tab[category] ; i++){ vlc = get_vlc2(&q->gb, q->sqvh[category].table, q->sqvh[category].bits, 3); if (q->bits_per_subpacket < get_bits_count(&q->gb)){ vlc = 0; result = 1; } for(j=vd-1 ; j>=0 ; j--){ tmp = (vlc * invradix_tab[category])/0x100000; subband_coef_index[vd*i+j] = vlc - tmp * (kmax_tab[category]+1); vlc = tmp; } for(j=0 ; j<vd ; j++){ if (subband_coef_index[i*vd + j]) { if(get_bits_count(&q->gb) < q->bits_per_subpacket){ subband_coef_sign[i*vd+j] = get_bits1(&q->gb); } else { result=1; subband_coef_sign[i*vd+j]=0; } } else { subband_coef_sign[i*vd+j]=0; } } } return result;}/** * Fill the mlt_buffer with mlt coefficients. * * @param q pointer to the COOKContext * @param category pointer to the category array * @param quant_index_table pointer to the array * @param mlt_buffer pointer to mlt coefficients */static void decode_vectors(COOKContext* q, int* category, int *quant_index_table,CookFFTSample * mlt_buffer){ /* A zero in this table means that the subband coefficient is random noise coded. */ int subband_coef_index[SUBBAND_SIZE]; /* A zero in this table means that the subband coefficient is a positive multiplicator. */ int subband_coef_sign[SUBBAND_SIZE]; int band, j; int index=0; for(band=0 ; band<q->total_subbands ; band++){ index = category[band]; if(category[band] < 7){ if(unpack_SQVH(q, category[band], subband_coef_index, subband_coef_sign)){ index=7; for(j=0 ; j<q->total_subbands ; j++) category[band+j]=7; } } if(index==7) { memset(subband_coef_index, 0, sizeof(subband_coef_index)); memset(subband_coef_sign, 0, sizeof(subband_coef_sign)); } q->scalar_dequant(q, index, quant_index_table[band], subband_coef_index, subband_coef_sign, &mlt_buffer[band * SUBBAND_SIZE]); } if(q->total_subbands*SUBBAND_SIZE >= q->samples_per_channel){ return; } /* FIXME: should this be removed, or moved into loop above? */}/** * function for decoding mono data * * @param q pointer to the COOKContext * @param mlt_buffer pointer to mlt coefficients */static void mono_decode(COOKContext *q,CookFFTSample * mlt_buffer) { int category_index[128]; int quant_index_table[102]; int category[128]; memset(&category, 0, 128*sizeof(int)); memset(&category_index, 0, 128*sizeof(int)); decode_envelope(q, quant_index_table); q->num_vectors = get_bits(&q->gb,q->log2_numvector_size); categorize(q, quant_index_table, category, category_index); expand_category(q, category, category_index); decode_vectors(q, category, quant_index_table, mlt_buffer);}/** * the actual requantization of the timedomain samples * * @param q pointer to the COOKContext * @param buffer pointer to the timedomain buffer * @param gain_index index for the block multiplier * @param gain_index_next index for the next block multiplier */static void interpolate_float(COOKContext *q, CookFFTSample* buffer, int gain_index, int gain_index_next){ int i; int fc2_fix, fc2_tmp_fix; if(gain_index == gain_index_next){ for(i = 0; i < q->gain_size_factor;i++){ if(gain_index > 0){ buffer[i] <<= gain_index; }else{ buffer[i] >>= abs(gain_index); } } return; }else{ fc2_fix = q->gain_table[11+(gain_index_next - gain_index)]; if(gain_index > 0){ buffer[0] <<= gain_index; }else{ buffer[0] >>= abs(gain_index); } fc2_tmp_fix = fc2_fix; for(i = 1; i < q->gain_size_factor; i++){ buffer[i] = MUL(buffer[i], fc2_tmp_fix); if(gain_index > 0){ buffer[i] <<= gain_index; }else{ buffer[i] >>= abs(gain_index); } fc2_tmp_fix = MUL(fc2_tmp_fix, fc2_fix); } return; }}/** * Apply transform window, overlap buffers. * * @param q pointer to the COOKContext * @param inbuffer pointer to the mltcoefficients * @param gains_ptr current and previous gains * @param previous_buffer pointer to the previous buffer to be used for overlapping */static void imlt_window_float (COOKContext *q, CookFFTSample *buffer1, cook_gains *gains_ptr, CookFFTSample *previous_buffer){ int i; /* The weird thing here, is that the two halves of the time domain * buffer are swapped. Also, the newest data, that we save away for * next frame, has the wrong sign. Hence the subtraction below. * Almost sounds like a complex conjugate/reverse data/FFT effect. */ for(i = 0; i < q->samples_per_channel; i++){ if(gains_ptr->previous[0] > 0){ buffer1[i] = MUL(buffer1[i],q->mlt_window[i])<< gains_ptr->previous[0]; }else{ buffer1[i] = MUL(buffer1[i],q->mlt_window[i])>> abs(gains_ptr->previous[0]); } buffer1[i] -= MUL(previous_buffer[i], q->mlt_window[q->samples_per_channel - 1 - i]); }}/** * The modulated lapped transform, this takes transform coefficients * and transforms them into timedomain samples. * Apply transform window, overlap buffers, apply gain profile * and buffer management. * * @param q pointer to the COOKContext * @param inbuffer pointer to the mltcoefficients * @param gains_ptr current and previous gains * @param previous_buffer pointer to the previous buffer to be used for overlapping */static void imlt_gain(COOKContext *q, CookFFTSample *inbuffer, cook_gains *gains_ptr,CookFFTSample * previous_buffer){ CookFFTSample *buffer0 = q->mono_mdct_output; CookFFTSample *buffer1 = q->mono_mdct_output + q->samples_per_channel; int i;#if 0 /* Inverse modified discrete cosine transform */ q->mdct_ctx.fft.imdct_calc(&q->mdct_ctx, q->mono_mdct_output, inbuffer, q->mdct_tmp);#else cook_imdct_calc(&q->mdct_ctx,buffer0, inbuffer, q->mdct_tmp);#endif q->imlt_window (q, buffer1, gains_ptr, previous_buffer); /* Apply gain profile */ for (i = 0; i < 8; i++) { if (gains_ptr->now[i] || gains_ptr->now[i + 1]) q->interpolate(q, &buffer1[q->gain_size_factor * i], gains_ptr->now[i], gains_ptr->now[i + 1]); } /* Save away the current to be previous block. */ memcpy(previous_buffer, buffer0, sizeof(CookFFTSample)*q->samples_per_channel);}/** * function for getting the jointstereo coupling information * * @param q pointer to the COOKContext * @param decouple_tab decoupling array * */static void decouple_info(COOKContext *q, int* decouple_tab){ int length, i; if(get_bits1(&q->gb)) { if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; for (i=0 ; i<length ; i++) { decouple_tab[cplband[q->js_subband_start] + i] = get_vlc2(&q->gb, q->ccpl.table, q->ccpl.bits, 2); } return; } if(cplband[q->js_subband_start] > cplband[q->subbands-1]) return; length = cplband[q->subbands-1] - cplband[q->js_subband_start] + 1; for (i=0 ; i<length ; i++) { decouple_tab[cplband[q->js_subband_start] + i] = get_bits(&q->gb, q->js_vlc_bits); } return;}/* * function decouples a pair of signals from a single signal via multiplication. * * @param q pointer to the COOKContext * @param subband index of the current subband * @param f1 multiplier for channel 1 extraction * @param f2 multiplier for channel 2 extraction * @param decode_buffer input buffer * @param mlt_buffer1 pointer to left channel mlt coefficients * @param mlt_buffer2 pointer to right channel mlt coefficients */static void decouple_float (COOKContext *q, int subband, CookFFTSample f1, CookFFTSample f2, CookFFTSample *decode_buffer, CookFFTSample *mlt_buffer1, CookFFTSample *mlt_buffer2){ int j, tmp_idx; int de_fix; for (j=0 ; j<SUBBAND_SIZE ; j++) { tmp_idx = ((q->js_subband_start + subband)*SUBBAND_SIZE)+j; de_fix = decode_buffer[tmp_idx]; mlt_buffer1[SUBBAND_SIZE*subband + j] = MUL(f1, de_fix); mlt_buffer2[SUBBAND_SIZE*subband + j] = MUL(f2, de_fix); }}/** * function for decoding joint stereo data * * @param q pointer to the COOKContext * @param mlt_buffer1 pointer to left channel mlt coefficients * @param mlt_buffer2 pointer to right channel mlt coefficients */static void joint_decode(COOKContext *q,CookFFTSample * mlt_buffer1, CookFFTSample * mlt_buffer2){ int i,j; int decouple_tab[SUBBAND_SIZE]; CookFFTSample *decode_buffer = q->decode_buffer_0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -