📄 enc_tf.c
字号:
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 + -