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

📄 enc_tf.c

📁 JPEG-MPEG編解碼技術書集的代碼
💻 C
📖 第 1 页 / 共 2 页
字号:
			for (ismp=0; ismp<block_size_samples; ismp++){
				sig_tmp[ismp+block_size_samples*max_ch+top] =
					DTimeSigLookAheadBuf[i_ch][ismp];
			}
		}
		/* automatic switching module */
		winSwitch(sig_tmp, &block_type[0], ntt_InitFlag);
		for (ismp=0; ismp<block_size_samples*2*max_ch; ismp++){
			sig_tmp[ismp-block_size_samples*max_ch] = sig_tmp[ismp];
		}
		ntt_InitFlag = 0;
	}

	/* Multiple channels not really supported yet. */
	block_type[1] = block_type[0];

	{
		int chanNum;

		for (chanNum=0;chanNum<max_ch;chanNum++) {

			/* Set window shape paremeter in quantInfo */
			quantInfo[chanNum].window_shape = WS_FHG;

			switch( block_type[chanNum] ) {
			case ONLY_SHORT_WINDOW  :
				no_sub_win   = short_win_in_long;
				sub_win_size = block_size_samples/short_win_in_long;
				quantInfo[chanNum].max_sfb = max_sfb_s[bitrate_idx][srate_idx];
				quantInfo[chanNum].num_window_groups = 4;
				quantInfo[chanNum].window_group_length[0] = 1;
				quantInfo[chanNum].window_group_length[1] = 2;
				quantInfo[chanNum].window_group_length[2] = 3;
				quantInfo[chanNum].window_group_length[3] = 2;
				break;
				
			default:
				no_sub_win   = 1;
				sub_win_size = block_size_samples;
				quantInfo[chanNum].max_sfb = max_sfb_l[bitrate_idx][srate_idx];
				quantInfo[chanNum].num_window_groups = 1;
				quantInfo[chanNum].window_group_length[0]=1;
				break;
			}
		}
	}

	{
		int chanNum;
		for (chanNum=0;chanNum<max_ch;chanNum++) {

			/* Count number of bits used for gain_control_data */
			used_bits += WriteGainControlData(&quantInfo[chanNum],     /* quantInfo contains packed gain control data */
				NULL,           /* NULL BsBitStream.  Only counting bits, no need to write yet */
				0);             /* Zero write flag means don't write */
		}
	}



	/******************************************************************************************************************************
	*
	* T/F mapping
	*
	******************************************************************************************************************************/

	{
		int chanNum, i, b;
		double cut_div = sampling_rate/2/cut_off[bitrate_idx][srate_idx];
		int cut_bin = (int)BLOCK_LEN_LONG/cut_div+0.5;
		int cut_bin_s = (int)BLOCK_LEN_SHORT/cut_div+0.5;
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			buffer2freq(
				DTimeSigBuf[chanNum],
				spectral_line_vector[chanNum],
				overlap_buffer[chanNum],
				block_type[chanNum],
				quantInfo[chanNum].window_shape,
				block_size_samples,
				block_size_samples/2,
				block_size_samples/short_win_in_long,
				MOVERLAPPED
				);
			/* Frequency cut-off. */
			if (block_type[chanNum] == ONLY_SHORT_WINDOW) {
				for (b = 0; b < 8; b++)
					for (i = cut_bin_s; i < 128; i++)
						spectral_line_vector[chanNum][(b*128)+i] = 0.0;
			} else {
				for (i = cut_bin; i < 1024; i++)
					spectral_line_vector[chanNum][i] = 0.0;
			}
		}
	}

	/******************************************************************************************************************************
	*
	* adapt ratios of psychoacoustic module to codec scale factor bands
	*
	******************************************************************************************************************************/
	{
		int chanNum;
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			
			/* Save p_ratio from psychoacoustic model for next frame.  */
			/* Psycho model is using a look-ahead window for block switching */

			memcpy( (char*)p_ratio_long[!psychNum][chanNum], (char*)chpo_long[chanNum].p_ratio, (NSFB_LONG)*sizeof(double) );
			memcpy( (char*)p_ratio_short[!psychNum][chanNum],(char*)chpo_short[chanNum][0].p_ratio,(MAX_SHORT_WINDOWS*NSFB_SHORT)*sizeof(double) );
			
		}
	}

	{
		int par_set;
		int chanNum;
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			par_set = 0;
			switch( block_type[chanNum] ) {
			case ONLY_LONG_WINDOW :
				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
				nr_of_sfb[chanNum] = chpo_long[chanNum].no_of_cb;
				p_ratio[chanNum]   = p_ratio_long[psychNum][chanNum];
				par_set = 1;
				break;
			case LONG_SHORT_WINDOW :
				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
				nr_of_sfb[chanNum] = chpo_long[chanNum].no_of_cb;
				p_ratio[chanNum]   = p_ratio_long[psychNum][chanNum];
				par_set = 1;
				break;
			case ONLY_SHORT_WINDOW :
				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_short[chanNum][0].cb_width, (NSFB_SHORT+1)*sizeof(int) );
				nr_of_sfb[chanNum] = chpo_short[chanNum][0].no_of_cb;
				p_ratio[chanNum]   = p_ratio_short[psychNum][chanNum];
				par_set = 1;
				break;
			case SHORT_LONG_WINDOW :
				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
				nr_of_sfb[chanNum] = chpo_long[chanNum].no_of_cb;
				p_ratio[chanNum]   = p_ratio_long[psychNum][chanNum];
				par_set = 1;
				break;
			default:
				break;
			}

			/* to prevent undefined ptr just use a meaningful value to allow for experiments with the mechanism above */
			if( !par_set) {   
				memcpy( (char*)sfb_width_table[chanNum], (char*)chpo_long[chanNum].cb_width, (NSFB_LONG+1)*sizeof(int) );
				nr_of_sfb[chanNum]  = chpo_long[chanNum].no_of_cb;
				p_ratio[chanNum]   = p_ratio_long[psychNum][chanNum];
			}
		}
	}

	{
		int chanNum;   
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			/* Construct sf band offset table */
			int offset=0;
			int sfb;
			for (sfb=0;sfb<nr_of_sfb[chanNum];sfb++) {
				sfb_offset_table[chanNum][sfb] = offset;
				offset+=sfb_width_table[chanNum][sfb];
			}
			sfb_offset_table[chanNum][nr_of_sfb[chanNum]]=offset;
		}
	}


	/******************************************************************************************************************************
	*
	* quantization and coding
	*
	******************************************************************************************************************************/
	{ 
		int padding_limit = max_bitreservoir_bits;
		int maxNumBitsByteAligned;
		int chanNum;   
		int numWindows;
		int windowLength;
		int j,w;
		int bandNumber;
		int numFillBits;
		int bitsLeftAfterFill;

		/* bit budget */
		num_bits_available = (long)(average_bits + available_bitreservoir_bits - used_bits);
		
		/* find the largest byte-aligned section with fewer bits than num_bits_available */
		maxNumBitsByteAligned = ((num_bits_available >> 3) << 3);

		/* Compute how many reservoir bits can be used and still be able to byte */
		/* align without exceeding num_bits_available, and have room for an ID_END marker   */
		available_bitreservoir_bits = maxNumBitsByteAligned - LEN_SE_ID - average_bits;

#if 0 // Not needed now, there are no SMR values anyway
		for (chanNum=0;chanNum<max_ch;chanNum++) {

			/* Compute energy in each scalefactor band of each window */
			numWindows = (block_type[chanNum]==ONLY_SHORT_WINDOW) ?	short_win_in_long : 1;
			windowLength = block_size_samples/numWindows;
			bandNumber=0;
			for (w=0;w<numWindows;w++) {
				int offset=0;
				int sfb;
				j = w*windowLength;


				/* Only compute energy up to max_sfb */
				for(sfb=0; sfb< quantInfo[chanNum].max_sfb; sfb++ ) {
					/* calculate scale factor band energy */
					int width,i;
					energy[chanNum][bandNumber] = 0.0;
					width=sfb_width_table[chanNum][sfb];
					for(i=offset; i<(offset+width); i++ ) {
						double dtmp = spectral_line_vector[chanNum][j++];   
						energy[chanNum][bandNumber] += dtmp*dtmp;
					}
					bandNumber++;
					offset+=width;
				}  
			}
		}  /* for (chanNum... */
#endif

		/******************************************/
		/* Perform TNS analysis and filtering     */
		/******************************************/
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			error = TnsEncode(nr_of_sfb[chanNum],            /* Number of bands per window */
				quantInfo[chanNum].max_sfb,              /* max_sfb */
				block_type[chanNum],
				sfb_offset_table[chanNum],
				spectral_line_vector[chanNum],
				&tnsInfo[chanNum]);
			if (error == MBERROR)
				return MBERROR;
		}

		/***********************************************************************/
		/* If prediction is used, compute predictor info and residual spectrum */
		/***********************************************************************/
		for (chanNum=0;chanNum<max_ch;chanNum++) {      
#if 0 // No prediction, gives no big gain.
			if (qc_select == AAC_PRED) {
				int numPredBands;
				max_pred_sfb = 40;
				numPredBands = min(max_pred_sfb,nr_of_sfb[chanNum]);
				PredCalcPrediction( spectral_line_vector[chanNum],
					reconstructed_spectrum[chanNum],
					(int)block_type[chanNum],
					numPredBands,
					sfb_width_table[chanNum],
					&(quantInfo[chanNum].pred_global_flag),
					quantInfo[chanNum].pred_sfb_flag,
					&(quantInfo[chanNum].reset_group_number),
					chanNum);
			} else
#endif
			{
				quantInfo[chanNum].pred_global_flag = 0;
			}
		} /* for(chanNum... */

		/************************************************/
		/* Call the AAC quantization and coding module. */
		/************************************************/
		for (chanNum = 0; chanNum < max_ch; chanNum++) {

			int bitsToUse; 
			bitsToUse = (int)((average_bits - used_bits)/max_ch);
			bitsToUse += (int)(0.2*available_bitreservoir_bits/max_ch);

			error = tf_encode_spectrum_aac( &spectral_line_vector[chanNum],
				&p_ratio[chanNum],
				&allowed_distortion[chanNum],
				&energy[chanNum],
				&block_type[chanNum],
				&sfb_width_table[chanNum],
				&nr_of_sfb[chanNum],
				bitsToUse,
				available_bitreservoir_bits,
				padding_limit,
				fixed_stream, /*tmp_stream,*/
				NULL,
				1,                        /* nr of audio channels */
				&reconstructed_spectrum[chanNum],
				useShortWindows,
				aacAllowScalefacs,
				&quantInfo[chanNum],
				&(channelInfo[chanNum]),
				varBitRate,
				bit_rate);
			if (error == MBERROR)
				return error;
		}

#if 0 // No prediction
		/* If short window, reconstruction not needed for prediction */
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			if ((block_type[chanNum]==ONLY_SHORT_WINDOW)) {
				int sind;
				for (sind=0;sind<1024;sind++) {
					reconstructed_spectrum[chanNum][sind]=0.0;
				}
			}
		}
#endif

		/**********************************/
		/* Write out all encoded channels */
		/**********************************/
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			if (channelInfo[chanNum].present) {
				/* Write out a single_channel_element */
				if (!channelInfo[chanNum].cpe) {
					/* Write out sce */ /* BugFix by YT  '+=' sould be '=' */
					used_bits = WriteSCE(&quantInfo[chanNum],   /* Quantization information */
						channelInfo[chanNum].tag,
						fixed_stream,           /* Bitstream */
						1);                     /* Write flag, 1 means write */
				} else {
					if (channelInfo[chanNum].ch_is_left) {
						/* Write out cpe */
						used_bits = WriteCPE(&quantInfo[chanNum],   /* Quantization information,left */
							&quantInfo[channelInfo[chanNum].paired_ch],   /* Right */
							channelInfo[chanNum].tag,
							channelInfo[chanNum].common_window,    /* common window */
							&(channelInfo[chanNum].ms_info),
							fixed_stream,           /* Bitstream */
							1);                     /* Write flag, 1 means write */
					}
				}  /* if (!channelInfo[chanNum].cpe)  else */
			} /* if (chann...*/
		} /* for (chanNum...*/

		/* Compute how many fill bits are needed to avoid overflowing bit reservoir */
		/* Save room for ID_END terminator */
		if (used_bits < (minBitsNoOverflow - LEN_SE_ID) ) {
			numFillBits = minBitsNoOverflow - LEN_SE_ID - used_bits;
		} else {
			numFillBits = 0;
		}
		
		/* Write AAC fill_elements, smallest fill element is 7 bits. */
		/* Function may leave up to 6 bits left after fill, so tell it to fill a few extra */
		numFillBits += 6;
		bitsLeftAfterFill=WriteAACFillBits(fixed_stream,numFillBits);
		used_bits += (numFillBits - bitsLeftAfterFill);

		/* Write ID_END terminator */
		BsPutBit(fixed_stream,ID_END,LEN_SE_ID);
		used_bits += LEN_SE_ID;
		
		/* Now byte align the bitstream */
		used_bits += ByteAlign(fixed_stream);

	} /* Quantization and coding block */
	return MBNO_ERROR;
}

⌨️ 快捷键说明

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