⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 huffdec2.c

📁 AAC音频解码算法程序
💻 C
📖 第 1 页 / 共 2 页
字号:
    }

    /*
	* tns data
	*/
    if (getbits(LEN_TNS_PRES)) {
		get_tns(info, tns);
    }
    else {
		clr_tns(info, tns);
    }

    /*
	* Sony gain control
    */
    if (getbits(LEN_GAIN_PRES)) {
		CommonExit(1, "Gain control not implemented");
    }

    return huffspec(info, nsect, sect, factors, coef);
}

/*
 * read the codebook and boundaries
 */
int
huffcb(byte *sect, int *sectbits, int tot_sfb, int sfb_per_sbk, byte max_sfb)
{
    int nsect, n, base, bits, len;

    bits = sectbits[0];
    len = (1 << bits) - 1;
    nsect = 0;
    for(base = 0; base < tot_sfb && nsect < tot_sfb; ){
	*sect++ = (byte)getbits(LEN_CB);

	n = getbits(bits);
	while(n == len && base < tot_sfb){
	    base += len;
	    n = getbits(bits);
	}
	base += n;
	*sect++ = base;
	nsect++;

	/* insert a zero section for regions above max_sfb for each group */
	if ((sect[-1] % sfb_per_sbk) == max_sfb) {
	    base += (sfb_per_sbk - max_sfb);
	    *sect++ = 0;
	    *sect++ = base;
	    nsect++;
	}
    }

    if(base != tot_sfb || nsect > tot_sfb)
	return 0;
    return nsect;
}

/* 
 * get scale factors
 */
int
hufffac(Info *info, byte *group, int nsect, byte *sect,
		short global_gain, short *factors)
{
    Hcb *hcb;
    Huffman *hcw;
    int i, b, bb, t, n, sfb, top, fac, is_pos;
    int factor_transmitted[MAXBANDS], *fac_trans;
    int noise_pcm_flag = 1;
    int noise_nrg;

    /* clear array for the case of max_sfb == 0 */
	memset(factor_transmitted, 0, MAXBANDS*sizeof(*factor_transmitted));
	memset(factors, 0, MAXBANDS*sizeof(*factors));

    sfb = 0;
    fac_trans = factor_transmitted;
    for(i = 0; i < nsect; i++){
		top = sect[1];		/* top of section in sfb */
		t = sect[0];		/* codebook for this section */
		sect += 2;
		for(; sfb < top; sfb++) {
			fac_trans[sfb] = t;
		}
    }

    /* scale factors are dpcm relative to global gain
	* intensity positions are dpcm relative to zero
	*/
    fac = global_gain;
    is_pos = 0;
    noise_nrg = global_gain - NOISE_OFFSET;

    /* get scale factors */
    hcb = &book[BOOKSCL];
    hcw = hcb->hcw;
    bb = 0;
    for(b = 0; b < info->nsbk; ){
		n = info->sfb_per_sbk[b];
		b = *group++;
		for(i = 0; i < n; i++){
			switch (fac_trans[i]) {
			case ZERO_HCB:	    /* zero book */
				break;
			default:		    /* spectral books */
				/* decode scale factor */
				t = decode_huff_cw(hcw);
				fac += t - MIDFAC;    /* 1.5 dB */
				if(fac >= 2*TEXP || fac < 0)
					return 0;
				factors[i] = fac;
				break;
			case BOOKSCL:	    /* invalid books */
				return 0;
			case INTENSITY_HCB:	    /* intensity books */
			case INTENSITY_HCB2:
				/* decode intensity position */
				t = decode_huff_cw(hcw);
				is_pos += t - MIDFAC;
				factors[i] = is_pos;
				break;
			case NOISE_HCB:	    /* noise books */
                /* decode noise energy */
                if (noise_pcm_flag) {
					noise_pcm_flag = 0;
					t = getbits( NOISE_PCM_BITS ) - NOISE_PCM_OFFSET;
                }
                else
					t = decode_huff_cw(hcw) - MIDFAC;
                noise_nrg += t;
                factors[i] = noise_nrg;
                break;
			}
		}

		/* expand short block grouping */
		if (!(info->islong)) {
			for(bb++; bb < b; bb++) {
				for (i=0; i<n; i++) {
					factors[i+n] = factors[i];
				}
				factors += n;
			}
		}
		fac_trans += n;
		factors += n;
    }
    return 1;
}

/* rm2 inverse quantization
 * escape books need ftn call
 * other books done via macro
 */
#define iquant( q ) ( q >= 0 ) ? \
	(Float)iq_exp_tbl[ q ] : (Float)(-iq_exp_tbl[ - q ])

Float
esc_iquant(int q)
{
    if (q > 0) {
		if (q < MAX_IQ_TBL) {
			return((Float)iq_exp_tbl[q]);
		}
		else {
			return((float)pow(q, 4./3.));
		}
    }
    else {
		q = -q;
		if (q < MAX_IQ_TBL) {
			return((Float)(-iq_exp_tbl[q]));
		}
		else {
			return((float)(-pow(q, 4./3.)));
		}
    }
}



int
huffspec(Info *info, int nsect, byte *sect, short *factors, Float *coef)
{
    Hcb *hcb;
    Huffman *hcw;
    int i, j, k, table, step, temp, stop, bottom, top;
    short *bands, *bandp;
    int quant[LN2], *qp;	    /* probably could be short */

    int tmp_spec[LN2];

	memset(quant, 0, LN2*sizeof(*quant));

    bands = info->bk_sfb_top;
    bottom = 0;
    k = 0;
    bandp = bands;
    for(i = nsect; i; i--) {
		table = sect[0];
		top = sect[1];
		sect += 2;
		if( (table == 0) || (table == NOISE_HCB) ||
			(table == INTENSITY_HCB) || (table == INTENSITY_HCB2) ) {
			bandp = bands+top;
			k = bandp[-1];
			bottom = top;
			continue;
		}
		if(table < BY4BOOKS+1) {
			step = 4;
		}
		else {
			step = 2;
		}	hcb = &book[table];
		hcw = hcb->hcw;
		qp = quant+k;
//		kstart=k;
		for(j=bottom; j<top; j++) {
			stop = *bandp++;
			while(k < stop) {
				temp = decode_huff_cw(hcw);
				unpack_idx(qp, temp, hcb);

				if (!hcb->signed_cb)
					get_sign_bits(qp, step);
				if(table == ESCBOOK){
					qp[0] = getescape(qp[0]);
					qp[1] = getescape(qp[1]);
				}
				qp += step;
				k += step;
			}
		}
		bottom = top;
    }

    /* NEC noisless coding reconstruction */
    if ( (info->islong) && (nec_info.pulse_data_present) )
		nec_nc(quant, &nec_info);

    if (!info->islong) {
		deinterleave (quant,tmp_spec,
			(short)info->num_groups,   
			info->group_len,
			info->sfb_per_sbk,
			info->sfb_width_128);
		memcpy(quant,tmp_spec,sizeof(tmp_spec));
    }

    /* inverse quantization */
    for (i=0; i<info->bins_per_bk; i++) {
		coef[i] = esc_iquant(quant[i]);
    }

    /* rescaling */
    {
		int sbk, nsbk, sfb, nsfb, fac, top;
		Float *fp, scale;

		i = 0;
		fp = coef;
		nsbk = info->nsbk;
		for (sbk=0; sbk<nsbk; sbk++) {
			nsfb = info->sfb_per_sbk[sbk];
			k=0;
			for (sfb=0; sfb<nsfb; sfb++) {
				top = info->sbk_sfb_top[sbk][sfb];
				fac = factors[i++]-SF_OFFSET;

				if (fac >= 0 && fac < TEXP) {
					scale = exptable[fac];
				}
				else {
					if (fac == -SF_OFFSET) {
						scale = 0;
					}
					else {
						scale = (float)pow( 2.0,  0.25*fac );
					}
				}
				for ( ; k<top; k++) {
					*fp++ *= scale;
				}
			}
		}
    }
    return 1;
}

int byte_align(void)
{
    int i=0;

    if(nbits <= 16){
		cword = (cword<<16) | getshort();
		nbits += 16;
    }

    while (nbits & ((1<<3)-1)) {
		nbits -= 1;
		i += 1;
    }
    return(i);
}

long getbits(int n)
{
    if(nbits <= 16){
		cword = (cword<<16) | getshort();
		nbits += 16;
    }

    nbits -= n;
    return (cword>>nbits) & ((1<<n)-1);
}

int getescape(int q)
{
    int i, off, neg;

    if(q < 0){
		if(q != -16)
			return q;
		neg = 1;
    } else{
		if(q != +16)
			return q;
		neg = 0;
    }

    for(i=4;; i++){
		if(getbits(1) == 0)
			break;
    }

    if(i > 16){
		off = getbits(i-16) << 16;
		off |= getbits(16);
    } else
		off = getbits(i);

    i = off + (1<<i);
    if(neg)
		i = -i;
    return i;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -