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

📄 enc_tf.c

📁 AAC音频解码算法程序
💻 C
📖 第 1 页 / 共 2 页
字号:
				quantInfo[chanNum].window_group_length[6] = 0;
				quantInfo[chanNum].window_group_length[7] = 0;
#endif
				break;

			default:
				no_sub_win   = 1;
				sub_win_size = block_size_samples;
				quantInfo[chanNum].max_sfb = max_sfb_l[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, k;
		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
				);

			if (block_type[chanNum] == ONLY_SHORT_WINDOW) {  
				for (k = 0; k < 8; k++) {
					specFilter(spectral_line_vector[chanNum]+k*BLOCK_LEN_SHORT, spectral_line_vector[chanNum]+k*BLOCK_LEN_SHORT, as->out_sampling_rate, as->cut_off, BLOCK_LEN_SHORT); 
				}
			} else {
				specFilter(spectral_line_vector[chanNum], spectral_line_vector[chanNum], as->out_sampling_rate, as->cut_off, BLOCK_LEN_LONG);
			}
		}
	}

	/******************************************************************************************************************************
	*
	* adapt ratios of psychoacoustic module to codec scale factor bands
	*
	******************************************************************************************************************************/

	{
		int chanNum;
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			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[chanNum];
				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[chanNum];
				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[chanNum];
				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[chanNum];
				break;
			}
		}
	}

	MSPreprocess(p_ratio_long, p_ratio_short, chpo_long, chpo_short,
		channelInfo, block_type, quantInfo, as->use_MS, max_ch);

	MSEnergy(spectral_line_vector, energy, chpo_long, chpo_short, sfb_width_table,
		channelInfo, block_type, quantInfo, as->use_MS, max_ch);

	{
		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 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;

		/******************************************/
		/* 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],
				as->use_TNS);
			if (error == FERROR)
				return FERROR;
		}

		/******************************************/
		/* Apply Intensity Stereo                 */
		/******************************************/
		if (as->use_IS) {
			ISEncode(spectral_line_vector,
				channelInfo,
				sfb_offset_table,
				block_type,
				quantInfo,
				max_ch);
		}

		/*******************************************************************************/
		/* If LTP prediction is used, compute LTP predictor info and residual spectrum */
		/*******************************************************************************/
		for(chanNum=0;chanNum<max_ch;chanNum++) 
		{
			if(as->use_LTP && (block_type[chanNum] != ONLY_SHORT_WINDOW)) 
			{
				if(channelInfo[chanNum].cpe)
				{
					if(channelInfo[chanNum].ch_is_left) 
					{
						int i;
						int leftChan=chanNum;
						int rightChan=channelInfo[chanNum].paired_ch;
                   
						nok_ltp_enc(spectral_line_vector[leftChan], 
							nok_tmp_DTimeSigBuf[leftChan], 
							block_type[leftChan], 
							WS_FHG,
							block_size_samples,
							1,
							block_size_samples/short_win_in_long, 
							&sfb_offset_table[leftChan][0], 
							nr_of_sfb[leftChan],
							&nok_lt_status[leftChan]);

						nok_lt_status[rightChan].global_pred_flag = 
							nok_lt_status[leftChan].global_pred_flag;
						for(i = 0; i < NOK_MAX_BLOCK_LEN_LONG; i++)
							nok_lt_status[rightChan].pred_mdct[i] = 
							nok_lt_status[leftChan].pred_mdct[i];
						for(i = 0; i < MAX_SCFAC_BANDS; i++)
							nok_lt_status[rightChan].sfb_prediction_used[i] = 
							nok_lt_status[leftChan].sfb_prediction_used[i];
						nok_lt_status[rightChan].weight = nok_lt_status[leftChan].weight;
						nok_lt_status[rightChan].delay[0] = nok_lt_status[leftChan].delay[0];

						if (!channelInfo[leftChan].common_window) {
							nok_ltp_enc(spectral_line_vector[rightChan],
							nok_tmp_DTimeSigBuf[rightChan], 
							block_type[rightChan], 
							WS_FHG,
							block_size_samples,
							1,
							block_size_samples/short_win_in_long, 
							&sfb_offset_table[rightChan][0], 
							nr_of_sfb[rightChan],
							&nok_lt_status[rightChan]);
						}
					} /* if(channelInfo[chanNum].ch_is_left) */
				} /* if(channelInfo[chanNum].cpe) */
				else
					nok_ltp_enc(spectral_line_vector[chanNum], 
					nok_tmp_DTimeSigBuf[chanNum], 
					block_type[chanNum], 
					WS_FHG,
					block_size_samples,
					1,
					block_size_samples/short_win_in_long, 
					&sfb_offset_table[chanNum][0], 
					nr_of_sfb[chanNum],
					&nok_lt_status[chanNum]);

			} /* if(channelInfo[chanNum].present... */
			else
				quantInfo[chanNum].ltpInfo->global_pred_flag = 0;
		} /* for(chanNum... */

		/******************************************/
		/* Apply MS stereo                        */
		/******************************************/
		if (as->use_MS == 1) {
			MSEncode(spectral_line_vector,
				channelInfo,
				sfb_offset_table,
				block_type,
				quantInfo,
				max_ch);
		} else if (as->use_MS == 0) {
			MSEncodeSwitch(spectral_line_vector,
				channelInfo,
				sfb_offset_table,
				block_type,
				quantInfo,
				max_ch);
		}

		/************************************************/
		/* 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,
				NULL,
				1,                        /* nr of audio channels */
				&reconstructed_spectrum[chanNum],
				useShortWindows,
				aacAllowScalefacs,
				&quantInfo[chanNum],
				&(channelInfo[chanNum]),
				0/*no vbr*/,
				bit_rate);
			if (error == FERROR)
				return error;
		}

		/**********************************************************/
		/* Reconstruct MS Stereo bands for prediction            */
		/**********************************************************/
		if (as->use_MS != -1) {
			MSReconstruct(reconstructed_spectrum,
				channelInfo,
				sfb_offset_table,
				block_type,
				quantInfo,
				max_ch);
		}

		/**********************************************************/
		/* Reconstruct Intensity Stereo bands for prediction     */
		/**********************************************************/
		if (as->use_IS && (pns_sfb_start > 51)) {  /* do intensity only if pns is off  */
			ISReconstruct(reconstructed_spectrum,
				channelInfo,
				sfb_offset_table,
				block_type,
				quantInfo,
				max_ch);
		}

		/**********************************************************/
		/* Update LTP history buffer                              */
		/**********************************************************/
		for (chanNum=0;chanNum<max_ch;chanNum++) {
			nok_ltp_reconstruct(reconstructed_spectrum[chanNum], 
				block_type[chanNum], 
				WS_FHG, block_size_samples,
				block_size_samples/2,
				block_size_samples/short_win_in_long, 
				&sfb_offset_table[chanNum][0], 
				nr_of_sfb[chanNum],
				&nok_lt_status[chanNum]);
		}

		/**********************************/
		/* 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 < (8 - LEN_SE_ID) ) {
			numFillBits = 8 - 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 FNO_ERROR;
}

⌨️ 快捷键说明

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