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

📄 decoder.c

📁 AAC音频解码算法程序
💻 C
字号:
#include "faad.h"
#include "all.h"
#include "block.h"
#include "dolby_def.h"
#include "nok_lt_prediction.h"
#include "transfo.h"

int binisopen = 0;

/* prediction */
NOK_LT_PRED_STATUS *nok_lt_status[Chans];


void
do_init(void)
{
#if (CChans > 0)
    init_cc();
#endif
    huffbookinit();
    predinit();
    MakeFFTOrder();

	winmap[0] = win_seq_info[ONLY_LONG_WINDOW];
	winmap[1] = win_seq_info[ONLY_LONG_WINDOW];
	winmap[2] = win_seq_info[EIGHT_SHORT_WINDOW];
	winmap[3] = win_seq_info[ONLY_LONG_WINDOW];
}

void
predinit(void)
{
    int ch;
    for (ch = 0; ch < Chans; ch++) {
      nok_init_lt_pred(nok_lt_status[ch]);
    }
}

void getfill(void)
{
    int i, cnt;

    if ((cnt = getbits(LEN_F_CNT)) == (1<<LEN_F_CNT)-1)
		cnt +=  getbits(LEN_F_ESC) - 1;
    for (i=0; i<cnt; i++)
		getbits(LEN_BYTE);
}

Float *coef[Chans], *data[Chans], *state[Chans];
byte hasmask[Winds], *mask[Winds], *group[Chans],
   wnd[Chans], max_sfb[Chans],
   *cb_map[Chans];
Wnd_Shape wnd_shape[Chans];
short *factors[Chans];
int *lpflag[Chans], *prstflag[Chans];
TNS_frame_info *tns[Chans];
#if (CChans > 0)
Float *cc_coef[CChans], *cc_gain[CChans][Chans];
byte cc_wnd[CChans];
Wnd_Shape cc_wnd_shape[CChans];
#if (ICChans > 0)
Float *cc_state[ICChans];
#endif
#endif
int i, j,  ch, wn, ele_id, d_tag, d_cnt;
int left, right;
Info *info;
MC_Info *mip = &mc_info;
Ch_Info *cip;

void extra_init(void)
{
	int i;
    for(i=0; i<Chans; i++){
		memset(state[i], 0, LN*sizeof(*state[i]));
		wnd_shape[i].prev_bk = 0;
    }
#if (CChans > 0)
    for(i=0; i<CChans; i++){
#if (ICChans > 0)
		if (i < ICChans) {
			memset(cc_state[i], 0, LN*sizeof(*cc_state[i]));
			cc_wnd_shape[i].prev_bk = 0;
		}
#endif
    }
#endif

	for(i = 0; i < Chans; i++){
		wnd_shape[i].prev_bk = 0;
		wnd_shape[i].this_bk = 0;
	}
}

void aac_decode_init(faadAACInfo *fInfo, char *fn)
{
	FILE *input_file;
	int i, file_length;
	char adif_id[5];
	static int SampleRates[] = {96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000};

    for(i=0; i<Chans; i++){
		coef[i] = (Float *)malloc(LN2*sizeof(*coef[0]));
		data[i] = (Float *)malloc(LN2*sizeof(*data[0]));
		state[i] = (Float *)malloc(LN*sizeof(*state[0]));
		factors[i] = (short *)malloc(MAXBANDS*sizeof(*factors[0]));
		cb_map[i] = (byte *)malloc( MAXBANDS*sizeof(*cb_map[0]));
		group[i] = (byte *)malloc( NSHORT*sizeof(group[0]));
		lpflag[i] = (int *)malloc( MAXBANDS*sizeof(*lpflag[0]));
		prstflag[i] = (int *)malloc( (LEN_PRED_RSTGRP+1)*sizeof(*prstflag[0]));
		tns[i] = (TNS_frame_info *)malloc( sizeof(*tns[0]));
		nok_lt_status[i]  = (NOK_LT_PRED_STATUS *)malloc(sizeof(*nok_lt_status[0]));
		nok_lt_status[i]->delay =  (int*)malloc(MAX_SHORT_WINDOWS*sizeof(int));

		memset(coef[i],0,LN2*sizeof(*coef[0]));
		memset(data[i],0,LN2*sizeof(*data[0]));
		memset(state[i],0,LN*sizeof(*state[0]));
		memset(factors[i],0,MAXBANDS*sizeof(*factors[0]));
		memset(cb_map[i],0,MAXBANDS*sizeof(*cb_map[0]));
		memset(group[i],0,NSHORT*sizeof(group[0]));
		memset(lpflag[i],0,MAXBANDS*sizeof(*lpflag[0]));
		memset(prstflag[i],0,(LEN_PRED_RSTGRP+1)*sizeof(*prstflag[0]));
		memset(tns[i],0,sizeof(*tns[0]));
	}
    for(i=0; i<Winds; i++) {
		mask[i] = (byte *)malloc( MAXBANDS*sizeof(mask[0]));
		memset(mask[i],0,MAXBANDS*sizeof(mask[0]));
    }
#if (CChans > 0)
    for(i=0; i<CChans; i++){
		cc_coef[i] = (Float *)malloc( LN2*sizeof(*cc_coef[0]));
		for(j=0; j<Chans; j++)
			cc_gain[i][j] = (Float *)malloc( MAXBANDS*sizeof(*cc_gain[0][0]));
#if (ICChans > 0)
		if (i < ICChans) {
			cc_state[i] = (Float *)malloc( LN*sizeof(*state[0]));  /* changed LN4 to LN 1/97 mfd */
		}
#endif
    }
#endif

	stop_now = 0;

	input_file = fopen(fn, "rb");

	fseek(input_file, 0, SEEK_END);
	file_length = ftell(input_file);
	fseek(input_file, 0, SEEK_SET);

	for (i=0; i<LEN_ADIF_ID; i++)
		adif_id[i] = fgetc(input_file);
	adif_id[i] = 0;
	if (strncmp(adif_id, "ADIF", 4) == 0) {
		adif_header_present = 1;
	} else adif_header_present = 0;

	fclose(input_file);

    initio(fn);
    restarttio();

//	if(!startblock())
//		CommonExit(1,"2028: Error finding start of block");
	startblock();

	fInfo->bit_rate = 128000;
	fInfo->sampling_rate = 44100;
	fInfo->channels = 2;

	if (adif_header_present)
	{
		fInfo->bit_rate = adif_header.bitrate;
		fInfo->sampling_rate = SampleRates[prog_config.sampling_rate_idx];
	}

	fInfo->length = (int)((file_length/(((fInfo->bit_rate*8)/1000)*16))*1000);

	do_init();
}

void aac_decode_free(void)
{
	if (binisopen) {
		//fclose(bin);
		CloseInputFile();
		binisopen = 0;
	}

    for(i=0; i<Chans; i++){
		if (coef[i]) free(coef[i]);
		if (data[i]) free(data[i]);
		if (state[i]) free(state[i]);
		if (factors[i]) free(factors[i]);
		if (cb_map[i]) free(cb_map[i]);
		if (group[i]) free(group[i]);
		if (lpflag[i]) free(lpflag[i]);
		if (prstflag[i]) free(prstflag[i]);
		if (tns[i]) free(tns[i]);
		if (nok_lt_status[i]) free(nok_lt_status[i]);
    }
    for(i=0; i<Winds; i++) {
		if (mask[i]) free(mask[i]);
    }
#if (CChans > 0)
    for(i=0; i<CChans; i++){
		if (cc_coef[i]) free(cc_coef[i]);
		for(j=0; j<Chans; j++)
			if (cc_gain[i][j]) free(cc_gain[i][j]);
#if (ICChans > 0)
		if (i < ICChans) {
			if (cc_state[i]) free(cc_state[i]);
		}
#endif
    }
#endif
}

int aac_decode_frame(short *sample_buffer)
{
	framebits = 0;
	byte_align();

	reset_mc_info(mip);
	while ((ele_id=getbits(LEN_SE_ID)) != ID_END) {
		/* get audio syntactic element */

		switch (ele_id) {
		case ID_SCE:		/* single channel */
		case ID_CPE:		/* channel pair */
		case ID_LFE:		/* low freq effects channel */
			if (huffdecode(ele_id, mip, wnd, wnd_shape,
				cb_map, factors, 
				group, hasmask, mask, max_sfb,
				lpflag, prstflag
				, nok_lt_status
				, tns, coef) < 0)
				return 0;
				//CommonExit(1,"2022: Error in huffman decoder");
			break;
#if (CChans > 0)
		case ID_CCE:		/* coupling channel */
			if (getcc(mip, cc_wnd, cc_wnd_shape, cc_coef, cc_gain) < 0)
				return 0;
//				CommonExit(1,"2023: Error in coupling channel");
			break;
#endif				
		case ID_PCE:		/* program config element */
			get_prog_config(&prog_config);
			break;
		case ID_FIL:		/* fill element */
			getfill();
			break;
		default:
//			CommonWarning("Element not supported");
			return 0;
		}
	}
	check_mc_info(mip, (bno==0 && default_config));

#if (ICChans > 0)
	/* transform independently switched coupling channels */
	ind_coupling(mip, wnd, wnd_shape, cc_wnd, cc_wnd_shape, cc_coef,
		cc_state);
#endif	

	/* m/s stereo */
	for (ch=0; ch<Chans; ch++) {
		cip = &mip->ch_info[ch];
		if ((cip->present) && (cip->cpe) && (cip->ch_is_left)) {
			wn = cip->widx;
			if(hasmask[wn]) {
				left = ch;
				right = cip->paired_ch;
				info = winmap[wnd[wn]];
				if (hasmask[wn] == 1)
					map_mask(info, group[wn], mask[wn], cb_map[right]);
				synt(info, group[wn], mask[wn], coef[right], coef[left]);
			}
		}
	}

	/* intensity stereo and prediction */
	for (ch=0; ch<Chans; ch++) {
		if (!(mip->ch_info[ch].present)) continue;
		wn = mip->ch_info[ch].widx;
		info = winmap[wnd[wn]];
		pns( mip, info, wn, ch,
			group[wn], cb_map[ch], factors[ch], 
			lpflag[wn], coef );
		intensity(mip, info, wn, ch, 
			group[wn], cb_map[ch], factors[ch], 
			lpflag[wn], coef);
		nok_lt_predict (mip->profile, info, wnd[ch], &wnd_shape[ch],
			nok_lt_status[ch]->sbk_prediction_used,
			nok_lt_status[ch]->sfb_prediction_used,
			nok_lt_status[ch], nok_lt_status[ch]->weight,
			nok_lt_status[ch]->delay, coef[ch],
			BLOCK_LEN_LONG, 0, BLOCK_LEN_SHORT);
	}

	for (ch=0; ch<Chans; ch++) {
		if (!(mip->ch_info[ch].present)) continue;
		wn = mip->ch_info[ch].widx;
		info = winmap[wnd[wn]];

#if (CChans > 0)
		/* if cc_domain indicates before TNS */
		coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, !CC_IND);
#endif

		/* tns */
		for (i=j=0; i<tns[ch]->n_subblocks; i++) {

			tns_decode_subblock(&coef[ch][j],
				max_sfb[wn],
				info->sbk_sfb_top[i],
				info->islong,
				&(tns[ch]->info[i]) );

			j += info->bins_per_sbk[i];
		}

#if (CChans > 0)
		/* if cc_domain indicated after TNS */
		coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, !CC_IND);
#endif

		/* inverse transform */
		freq2time_adapt (wnd [wn], &wnd_shape [wn], coef [ch], state [ch], data [ch]);

#if (CChans > 0)
		/* independently switched coupling */
		coupling(info, mip, coef, cc_coef, cc_gain, ch, CC_DOM, CC_IND);
#endif
	}

	/*
	for (j = 0; j < 2; j++)
		for (i = 0; i < 1024; i++)
		{
			float tmp = data[j][i];
			if (tmp < 0) {
				tmp -= .5;
				if(tmp < -0x7fff)
					tmp = (float) -0x7fff;
			}
			else
			{
				tmp += .5;
				if(tmp > 0x7fff)
					tmp = (float) 0x7fff;
			}
			sample_buffer[j*1024 + i] = tmp;
		}
	*/

	// Copy output to a standard PCM buffer

	for(i=0, j=0; i < 2048; i += 2, j++)
	{
		for (ch=0; ch < mip->nch; ch++)
		{
			if(data[ch][j] > 32767)
				sample_buffer[i+ch] = 32767;
			else if(data[ch][j] < -32768)
				sample_buffer[i+ch] = -32768;
			else
				sample_buffer[i+ch] = (short)(data[ch][j]+0.5);
		}
	}

	bno++;

	if (stop_now)
		return 0;
	return framebits;
}

#ifndef PLUGIN
void CommonWarning(char *message)
{
  printf("warning: %s\n", message);
}

void CommonExit(int errorcode, char *message)
{
  printf("%s\n", message);
  exit(errorcode);
}
#endif

⌨️ 快捷键说明

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