📄 nok_ltp_enc.c
字号:
References: 1.) buffer2freq
2.) freq2buffer
3.) double_to_int
Explanation: -
Author(s): Juha Ojanpera
*************************************************************************/
void
nok_ltp_reconstruct(double *p_spectrum, enum WINDOW_TYPE win_type,
Window_shape win_shape,
int block_size_long, int block_size_medium,
int block_size_short, int *sfb_offset, int num_of_sfb,
NOK_LT_PRED_STATUS *lt_status)
{
int i, j, last_band;
double predicted_samples[2 * NOK_MAX_BLOCK_LEN_LONG];
double overlap_buffer[2 * NOK_MAX_BLOCK_LEN_LONG];
switch(win_type)
{
case ONLY_LONG_WINDOW:
case LONG_SHORT_WINDOW:
case SHORT_LONG_WINDOW:
last_band = (num_of_sfb < NOK_MAX_LT_PRED_LONG_SFB) ? num_of_sfb : NOK_MAX_LT_PRED_LONG_SFB;
if(lt_status->global_pred_flag)
for (i = 0; i < sfb_offset[last_band]; i++)
p_spectrum[i] += lt_status->pred_mdct[i];
/* Finally update the time domain history buffer. */
freq2buffer (p_spectrum, predicted_samples, overlap_buffer, win_type,
block_size_long, block_size_medium, block_size_short,
win_shape, MNON_OVERLAPPED);
for (i = 0; i < NOK_LT_BLEN - block_size_long; i++)
lt_status->buffer[i] = lt_status->buffer[i + block_size_long];
j = NOK_LT_BLEN - 2 * block_size_long;
for (i = 0; i < block_size_long; i++)
{
lt_status->buffer[i + j] =
double_to_int (predicted_samples[i] + lt_status->buffer[i + j]);
lt_status->buffer[NOK_LT_BLEN - block_size_long + i] =
double_to_int (predicted_samples[i + block_size_long]);
}
break;
case ONLY_SHORT_WINDOW:
#if 0
for (i = 0; i < NOK_LT_BLEN - block_size_long; i++)
lt_status->buffer[i] = lt_status->buffer[i + block_size_long];
for (i = NOK_LT_BLEN - block_size_long; i < NOK_LT_BLEN; i++)
lt_status->buffer[i] = 0;
for (i = 0; i < block_size_long; i++)
overlap_buffer[i] = 0;
/* Finally update the time domain history buffer. */
freq2buffer (p_spectrum, predicted_samples, overlap_buffer, win_type, block_size_long,
block_size_medium, block_size_short, win_shape, MNON_OVERLAPPED);
for(sw = 0; sw < MAX_SHORT_WINDOWS; sw++)
{
i = NOK_LT_BLEN - 2 * block_size_long + SHORT_SQ_OFFSET + sw * block_size_short;
for (j = 0; j < 2 * block_size_short; j++)
lt_status->buffer[i + j] = double_to_int (predicted_samples[sw * block_size_short * 2 + j] +
lt_status->buffer[i + j]);
}
#endif
break;
}
return;
}
/**************************************************************************
Title: nok_ltp_encode
Purpose: Writes LTP parameters to the bit stream.
Usage: nok_ltp_encode (bs, win_type, num_of_sfb, lt_status)
Input: bs - bit stream
win_type - window sequence (frame, block) type
num_of_sfb - number of scalefactor bands
lt_status - side_info:
1, if prediction not used in this frame
>1 otherwise
- weight_idx :
3 bit number indicating the LTP coefficient in
the codebook
- sfb_prediction_used:
1 bit for each scalefactor band (sfb) where LTP
can be used indicating whether LTP is switched
on (1) /off (0) in that sfb.
- delay: LTP lag
Output: -
References: 1.) BsPutBit
Explanation: -
Author(s): Juha Ojanpera
*************************************************************************/
int nok_ltp_encode (BsBitStream *bs, enum WINDOW_TYPE win_type, int num_of_sfb,
NOK_LT_PRED_STATUS *lt_status, int write_flag)
{
int i, last_band;
int first_subblock;
int prev_subblock;
int bit_count = 0;
bit_count += 1;
if (lt_status->side_info > 1)
{
if(write_flag)
BsPutBit (bs, 1, 1); /* LTP used */
switch(win_type)
{
case ONLY_LONG_WINDOW:
case LONG_SHORT_WINDOW:
case SHORT_LONG_WINDOW:
bit_count += LEN_LTP_LAG;
bit_count += LEN_LTP_COEF;
if(write_flag)
{
BsPutBit (bs, lt_status->delay[0], LEN_LTP_LAG);
BsPutBit (bs, lt_status->weight_idx, LEN_LTP_COEF);
}
last_band = (num_of_sfb < NOK_MAX_LT_PRED_LONG_SFB) ? num_of_sfb : NOK_MAX_LT_PRED_LONG_SFB;
bit_count += last_band;
if(write_flag)
{
for (i = 0; i < last_band; i++)
BsPutBit (bs, lt_status->sfb_prediction_used[i], LEN_LTP_LONG_USED);
}
break;
case ONLY_SHORT_WINDOW:
for(i=0; i < MAX_SHORT_WINDOWS; i++)
{
if(lt_status->sbk_prediction_used[i])
{
first_subblock = i;
break;
}
}
bit_count += LEN_LTP_LAG;
bit_count += LEN_LTP_COEF;
if(write_flag)
{
BsPutBit (bs, lt_status->delay[first_subblock], LEN_LTP_LAG);
BsPutBit (bs, lt_status->weight_idx, LEN_LTP_COEF);
}
prev_subblock = first_subblock;
for(i = 0; i < MAX_SHORT_WINDOWS; i++)
{
bit_count += LEN_LTP_SHORT_USED;
if(write_flag)
BsPutBit (bs, lt_status->sbk_prediction_used[i], LEN_LTP_SHORT_USED);
if(lt_status->sbk_prediction_used[i])
{
if(i > first_subblock)
{
int diff;
diff = lt_status->delay[prev_subblock] - lt_status->delay[i];
if(diff)
{
bit_count += 1;
bit_count += LEN_LTP_SHORT_LAG;
if(write_flag)
{
BsPutBit (bs, 1, 1);
BsPutBit (bs, diff + NOK_LTP_LAG_OFFSET, LEN_LTP_SHORT_LAG);
}
}
else
{
bit_count += 1;
if(write_flag)
BsPutBit (bs, 0, 1);
}
}
}
}
break;
default:
// CommonExit(1, "nok_ltp_encode : unsupported window sequence %i", win_type);
break;
}
}
else
if(write_flag)
BsPutBit (bs, 0, 1); /* LTP not used */
return (bit_count);
}
/**************************************************************************
Title: double_to_int
Purpose: Converts floating point format to integer (16-bit).
Usage: y = double_to_int(sig_in)
Input: sig_in - floating point number
Output: y - integer number
References: -
Explanation: -
Author(s): Juha Ojanpera
*************************************************************************/
short
double_to_int (double sig_in)
{
short sig_out;
if (sig_in > 32767)
sig_out = 32767;
else if (sig_in < -32768)
sig_out = -32768;
else if (sig_in > 0.0)
sig_out = (short) (sig_in + 0.5);
else if (sig_in <= 0.0)
sig_out = (short) (sig_in - 0.5);
return (sig_out);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -