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

📄 enc_tf.c

📁 jpeg and mpeg 编解码技术源代码
💻 C
📖 第 1 页 / 共 2 页
字号:

#include <windows.h>
#include <math.h>
#include "bitstream.h"
#include "interface.h" 
#include "enc.h"
#include "block.h"
#include "tf_main.h"
#include "psych.h"
#include "common.h"	/* common module */
#include "aac_back_pred.h"
#include "mc_enc.h"
#include "ms.h"
#include "is.h"
#include "winswitch.h"


/* AAC 表 */


int max_sfb_s[/*bitrate_idx*/][/*srate_idx*/12] = {
   /* 96  88  64  48  44  32  24  22  16  12  11   8 kHz */
	{ 12, 12, 12, 13, 12, 13, 15, 15, 15, 15, 15, 15 }, /*  64000 bps */
	{ 12, 12, 12, 13, 12, 13, 15, 15, 15, 15, 15, 15 }, /*  80000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /*  96000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 112000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 128000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 160000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 192000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }, /* 224000 bps */
	{ 12, 12, 12, 13, 13, 13, 15, 15, 15, 15, 15, 15 }  /* 256000 bps */
};
int max_sfb_l[/*bitrate_idx*/][/*srate_idx*/12] = {
   /* 96  88  64  48  44  32  24  22  16  12  11   8 kHz */
	{ 49, 49, 47, 48, 42, 51, 47, 47, 43, 43, 43, 40 }, /*  64000 bps */
	{ 49, 49, 47, 48, 42, 51, 47, 47, 43, 43, 43, 40 }, /*  80000 bps */
	{ 49, 49, 47, 48, 45, 51, 47, 47, 43, 43, 43, 40 }, /*  96000 bps */
	{ 49, 49, 47, 48, 45, 51, 47, 47, 43, 43, 43, 40 }, /* 112000 bps */
	{ 49, 49, 47, 48, 48, 51, 47, 47, 43, 43, 43, 40 }, /* 128000 bps */
	{ 49, 49, 47, 48, 48, 51, 47, 47, 43, 43, 43, 40 }, /* 160000 bps */
	{ 49, 49, 47, 48, 48, 51, 47, 47, 43, 43, 43, 40 }, /* 192000 bps */
	{ 49, 49, 47, 48, 48, 51, 47, 47, 43, 43, 43, 40 }, /* 224000 bps */
	{ 49, 49, 47, 48, 48, 51, 47, 47, 43, 43, 43, 40 }  /* 256000 bps */
};

/* Table for cut-off frequencies */
/* for most bitrates this is simply the Nyquist frequency */
/* Only changed is 44.1kHz, and they correspond quite well with wath max_sfb
   does, so this may be unneeded. */
int cut_off[/*bitrate_idx*/][/*srate_idx*/12] = {
	{ 48000, 44100, 32000, 24000, 16000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 16000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 18000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 18000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 20000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 20000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 20000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 20000, 16000, 12000, 11025, 8000, 5512, 4000 },
	{ 48000, 44100, 32000, 24000, 20000, 16000, 12000, 11025, 8000, 5512, 4000 },
};

/* other aac */
#include "aac_qc.h"
#include "all.h"
#include "aac_se_enc.h"
static int     block_size_samples = 1024;  /* nr of samples per block in one! audio channel */
static int     short_win_in_long  = 8;
static int     max_ch;    /* no of of audio channels */
static double *spectral_line_vector[MAX_TIME_CHANNELS];
static double *reconstructed_spectrum[MAX_TIME_CHANNELS];
static double *overlap_buffer[MAX_TIME_CHANNELS];
static double *DTimeSigBuf[MAX_TIME_CHANNELS];
static double *DTimeSigLookAheadBuf[MAX_TIME_CHANNELS];

/* static variables used by the T/F mapping */
static enum QC_MOD_SELECT qc_select = AAC_QC;                   /* later f(encPara) */
static enum AAC_PROFILE profile = MAIN;

/* Additional variables for AAC */
static int aacAllowScalefacs = 1;              /* Allow AAC scalefactors to be nonconstant */
static TNS_INFO tnsInfo[MAX_TIME_CHANNELS];

AACQuantInfo quantInfo[MAX_TIME_CHANNELS];               /* Info structure for AAC quantization and coding */

/* Channel information */
Ch_Info channelInfo[MAX_TIME_CHANNELS];

/* AAC shorter windows 960-480-120 */
static int useShortWindows=0;  /* don't use shorter windows */

// TEMPORARY HACK

int srate_idx;
int bitrate_idx;

int sampling_rate;
int bit_rate;

// END OF HACK


/* EncTfFree() */
/* Free memory allocated by t/f-based encoder core. */

void EncTfFree ()
{
	int chanNum;

	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
		if (DTimeSigBuf[chanNum]) free(DTimeSigBuf[chanNum]);
		if (DTimeSigLookAheadBuf[chanNum]) free(DTimeSigLookAheadBuf[chanNum]);
		if (spectral_line_vector[chanNum]) free(spectral_line_vector[chanNum]);

		if (reconstructed_spectrum[chanNum]) free(reconstructed_spectrum[chanNum]);
		if (overlap_buffer[chanNum]) free(overlap_buffer[chanNum]);
	}
}


/*****************************************************************************************
 ***
 *** Function: EncTfInit
 ***
 *** Purpose:  Initialize the T/F-part and the macro blocks of the T/F part of the VM
 ***
 *** Description:
 *** 
 ***
 *** Parameters:
 ***
 ***
 *** Return Value:
 ***
 *** **** MPEG-4 VM ****
 ***
 ****************************************************************************************/

void EncTfInit (
  int         numChannel,	 /* in: num audio channels */
  float       sampling_rate_f,   /* in: sampling frequancy [Hz] */         
  float       bit_rate_f,        /* in: bit rate [bit/sec] */
  int aacProfile,
  int quality,
  int WriteADIFHeader,
  int         varBitRate        /* in : equals 1 if variable bit rate, else 0 */
  )
{
	int chanNum, i;
	int SampleRates[] = {
		96000,88200,64000,48000,44100,32000,24000,22050,16000,12000,11025,8000,0
	};
	int BitRates[] = {
		64000,80000,96000,112000,128000,160000,192000,224000,256000,0
	};

	sampling_rate = (int)(sampling_rate_f+.5);
	if (varBitRate) {
		bit_rate = 128000;
	} else {
		bit_rate = (int)(bit_rate_f+.5);
	}

	for (i = 0; ; i++)
	{
		if (SampleRates[i] == sampling_rate) {
			srate_idx = i;
			break;
		}
	}
	for (i = 0; ; i++)
	{
		if (BitRates[i] == bit_rate) {
			bitrate_idx = i;
			break;
		}
	}

	profile = MAIN;
	qc_select = AAC_PRED;           /* enable prediction */

	if (aacProfile == LOW) {
		profile = LOW;
		qc_select = AAC_QC;          /* disable prediction */
	}

	/* set the return values */
	max_ch = numChannel;

	/* some global initializations */
	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
		DTimeSigBuf[chanNum]            = (double*)malloc(block_size_samples*sizeof(double));
		DTimeSigLookAheadBuf[chanNum]   = (double*)malloc(block_size_samples*sizeof(double));
		spectral_line_vector[chanNum]   = (double*)malloc(2*block_size_samples*sizeof(double));

		reconstructed_spectrum[chanNum] = (double*)malloc(block_size_samples*sizeof(double));
	}

	/* initialize psychoacoustic module */
	EncTf_psycho_acoustic_init();

	winSwitchInit(max_ch);

	/* initialize t/f mapping */
	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
		overlap_buffer[chanNum] = (double*)malloc(sizeof(double)*block_size_samples);
	}

#if 0 // no prediction
	PredInit();
#endif

	/* initialize spectrum processing */
	/* initialize quantization and coding */
	tf_init_encode_spectrum_aac( quality );

	/* Init TNS */
	for (chanNum=0;chanNum<MAX_TIME_CHANNELS;chanNum++) {
		TnsInit(sampling_rate,profile,&tnsInfo[chanNum]);
		quantInfo[chanNum].tnsInfo = &tnsInfo[chanNum];         /* Set pointer to TNS data */
	}
}

/*****************************************************************************************
 ***
 *** Function:    EncTfFrame
 ***
 *** Purpose:     processes a block of time signal input samples into a bitstream
 ***              based on T/F encoding 
 ***
 *** Description:
 *** 
 ***
 *** Parameters:
 ***
 ***
 *** Return Value:  returns the number of used bits
 ***
 *** **** MPEG-4 VM ****
 ***
 ****************************************************************************************/

int EncTfFrame (float *p_time_signal[MAX_TIME_CHANNELS],   /* array of pointers to the modulo time 
															signal input buffers for each channel */
				 BsBitStream  *fixed_stream,             /* bits before bitres size ptr */
				 int frameAvailNumBit,	           			/* in: total num bits available for 
															this frame (incl. bit reservoir) */
				 int frameNumBit,							/* in: average num bits per frame */
                 int minBitsNoOverflow,                     /* in: minimum number of bits needed to be used
                                                               to avoid overflowing the bit reservoir */
				 int frameMaxNumBit,		            /* in: max num bits per frame */
				 int varBitRate
		 )
{
	int used_bits;
	int error;

	/* Energy array (computed before prediction for long windows) */
	double energy[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];

	/* determine the function parameters used earlier:   HP 21-aug-96 */
	int          average_bits = frameNumBit;
	int          available_bitreservoir_bits = frameAvailNumBit-frameNumBit;

	/* actual amount of bits currently in the bit reservoir */
	/* it is the job of this module to determine 
	the no of bits to use in addition to average_block_bits
	max. available: average_block_bits + available_bitreservoir_bits */
	int max_bitreservoir_bits = frameMaxNumBit-frameNumBit;

	/* max. allowed amount of bits in the reservoir  (used to avoid padding bits) */
	long num_bits_available;

	double *p_ratio[MAX_TIME_CHANNELS], allowed_distortion[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
	static double p_ratio_long[2][MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
	static double p_ratio_short[2][MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
	int    nr_of_sfb[MAX_TIME_CHANNELS], sfb_width_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS];
	int sfb_offset_table[MAX_TIME_CHANNELS][MAX_SCFAC_BANDS+1];
	enum WINDOW_TYPE block_type[MAX_TIME_CHANNELS];

	int no_sub_win, sub_win_size;

	/* structures holding the output of the psychoacoustic model */
	CH_PSYCH_OUTPUT chpo_long[MAX_TIME_CHANNELS];
	CH_PSYCH_OUTPUT chpo_short[MAX_TIME_CHANNELS][MAX_SHORT_WINDOWS];
	static int psychNum=0;
	psychNum = !psychNum;      /* Toggle psychNum, psycho model using look-ahead buffer */

	if (fixed_stream == NULL)
		return MBNO_ERROR; /* quick'n'dirty fix for encoder startup    HP 21-aug-96 */

	{ /* convert float input to double, which is the internal format */
		/* store input data in look ahead buffer which may be necessary for the window switching decision */
		int i;
		int chanNum;
		
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			for( i=0; i<block_size_samples; i++ ) {
				/* last frame input data are encoded now */
				DTimeSigBuf[chanNum][i]          = DTimeSigLookAheadBuf[chanNum][i];
				DTimeSigLookAheadBuf[chanNum][i] = (double)p_time_signal[chanNum][i];
			} /* end for(i ..) */
		} /* end for(chanNum ... ) */
	}


	/* Keep track of number of bits used */
	used_bits = 0;

	/***********************************************************************/
	/* Determine channel elements      */
	/***********************************************************************/
	DetermineChInfo(channelInfo,max_ch);

	/******************************************************************************************************************************
	*
	* psychoacoustic
	*
	******************************************************************************************************************************/
	/* Heavily modified, no ismr's are calculated here, the psycho module that
	   was used wasn't that bad, it is just the quantizer that doesn't do it's
	   job correctly. 
	   Take a look at psych.c for more info. It is quite easy to start using
	   the ismr's again, just remove a #if 1 in aac_qc.c and enable the old 
	   psych.c module from the ISO distribution again. */
	{
		int chanNum;
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			EncTf_psycho_acoustic(
				sampling_rate,
				chanNum,
				&DTimeSigLookAheadBuf[chanNum],
				NULL,
				(int)qc_select,
				block_size_samples,
				&chpo_long[chanNum],
				&chpo_short[chanNum]
				);
		}
	}

	/******************************************************************************************************************************
	*
	* block_switch processing 
	*
	******************************************************************************************************************************/
	/* Window switching taken from the NTT source code in the MPEG4 VM. */
	{
		static int ntt_InitFlag = 1;
		static double *sig_tmptmp, *sig_tmp;
		int ismp, i_ch, top;
		/* initialize */
		if (ntt_InitFlag){
			sig_tmptmp = malloc(max_ch*block_size_samples*3*sizeof(double));
			sig_tmp = sig_tmptmp + block_size_samples * max_ch;
			for (i_ch=0; i_ch<max_ch; i_ch++){
				top = i_ch * block_size_samples;
				for (ismp=0; ismp<block_size_samples; ismp++){
					sig_tmp[ismp+top] = DTimeSigBuf[i_ch][ismp];
				}
			}
		}
		for (i_ch=0; i_ch<max_ch; i_ch++){
			top = i_ch * block_size_samples;

⌨️ 快捷键说明

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