📄 psych.c
字号:
/* input */
double sampling_rate, /*input3: sampling rate */
int no_of_chan, /* No. of audio channels */
double *p_time_signal[], //input2: newest iblen samples of signal
enum WINDOW_TYPE block_type[], //input1: from the FFT type, get the iblen
/* int qcSelect,
int frameLength, */
/* output */
CH_PSYCH_OUTPUT_LONG p_chpo_long[],
CH_PSYCH_OUTPUT_SHORT p_chpo_short[][MAX_SHORT_WINDOWS]
)
{
int ch, i, b;
SR_INFO *p_sri;
/* added by T. Araki (1997.07.10) */
static int flag = 0;
PSY_VARIABLE_LONG psy_var_long; /* variables for long block */
PSY_VARIABLE_SHORT psy_var_short; /* variables for short block */
memset(&psy_var_long, 0, sizeof(psy_var_long));
memset(&psy_var_short, 0, sizeof(psy_var_short));
/* added by T. Araki (1997.07.10) end */
p_sri = &sr_info_aac[0];
/* find correct sampling rate depending parameters */
while( p_sri->sampling_rate != (long)sampling_rate ) {
p_sri++;
}
/* added by T. Araki (1997.07.10) */
if( flag==0 ) {
psy_part_table_init(sampling_rate, &part_tbl_long, &part_tbl_short);
/* initializing Table B 2.1.*.a, B 2.1.*.b in N1650 */
flag = 1;
}
{
// ch = 0;
psy_step1(p_time_signal,sample, no_of_chan);
psy_step2(&sample[no_of_chan], &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &fft_tbl_long,
&fft_tbl_short, no_of_chan);
psy_step3(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short/*, ch*/);
psy_step4(&psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short/*, ch*/);
if (no_of_chan == 0) {
for (b = 0; b < NPART_LONG; b++)
psy_stvar_long[no_of_chan].save_cw[b] = psy_var_long.cw[b];
for (i = 0; i < MAX_SHORT_WINDOWS; i++)
for (b = 0; b < NPART_SHORT; b++)
psy_stvar_short[no_of_chan].save_cw[i][b] = psy_var_short.cw[i][b];
}
if (no_of_chan == 1) {
for (b = 0; b < NPART_LONG; b++)
psy_stvar_long[no_of_chan].save_cw[b] = min(psy_var_long.cw[b], psy_stvar_long[0].save_cw[b]);
for (i = 0; i < MAX_SHORT_WINDOWS; i++)
for (b = 0; b < NPART_SHORT; b++)
psy_stvar_short[no_of_chan].save_cw[i][b] = min(psy_var_short.cw[i][b], psy_stvar_short[0].save_cw[i][b]);
}
if (no_of_chan > 1) {
for (b = 0; b < NPART_LONG; b++)
psy_var_long.cw[b] = psy_stvar_long[1].save_cw[b];
for (i = 0; i < MAX_SHORT_WINDOWS; i++)
for (b = 0; b < NPART_SHORT; b++)
psy_var_short.cw[i][b] = psy_stvar_short[1].save_cw[i][b];
}
psy_step5(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
&psy_var_long, &psy_var_short/*, ch*/);
psy_step6(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
&psy_var_long, &psy_var_short);
psy_step7(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
if (no_of_chan < 2) {
for (b = 0; b < NPART_LONG; b++)
psy_stvar_long[no_of_chan].save_tb[b] = psy_var_long.tb[b];
for (i = 0; i < MAX_SHORT_WINDOWS; i++)
for (b = 0; b < NPART_SHORT; b++)
psy_stvar_short[no_of_chan].save_tb[i][b] = psy_var_short.tb[i][b];
} else {
for (b = 0; b < NPART_LONG; b++)
psy_var_long.tb[b] = psy_stvar_long[no_of_chan-2].save_tb[b];
for (i = 0; i < MAX_SHORT_WINDOWS; i++)
for (b = 0; b < NPART_SHORT; b++)
psy_var_short.tb[i][b] = psy_stvar_short[no_of_chan-2].save_tb[i][b];
}
psy_step8(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
psy_step9(&part_tbl_long, &part_tbl_short, &psy_var_long, &psy_var_short);
psy_step10(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
&psy_var_long, &psy_var_short/*, ch*/);
psy_step11andahalf(&part_tbl_long, &part_tbl_short, psy_stvar_long, psy_stvar_short, no_of_chan);
psy_step11(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan]/*, ch*/);
psy_step12(&part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan], &psy_stvar_short[no_of_chan],
&psy_var_long, &psy_var_short/*, ch*/);
psy_step13(&psy_var_long, block_type, no_of_chan);
// psy_step13(&psy_var_long, block_type, ch);
psy_step14(p_sri, &part_tbl_long, &part_tbl_short, &psy_stvar_long[no_of_chan],
&psy_stvar_short[no_of_chan], &psy_var_long, &psy_var_short/*, ch*/);
psy_step15(psy_stvar_long[no_of_chan].use_ms, psy_stvar_short[no_of_chan].use_ms, p_sri, &psy_stvar_long[0], &psy_stvar_short[0], &psy_var_long, &psy_var_short, no_of_chan);
}
/* for( ch=0; ch<no_of_chan; ch++ ) { */
{ /* Now performed for only one channel at a time, CL 97.01.10 */
int i;
p_chpo_long[no_of_chan].p_ratio = psy_stvar_long[no_of_chan].ismr;
p_chpo_long[no_of_chan].cb_width = p_sri->cb_width_long;
p_chpo_long[no_of_chan].no_of_cb = p_sri->num_cb_long;
if (no_of_chan == 1)
memcpy(p_chpo_long[no_of_chan].use_ms, psy_stvar_long[no_of_chan].use_ms, NSFB_LONG*sizeof(int));
for( i=0; i<MAX_SHORT_WINDOWS; i++ ) {
p_chpo_short[no_of_chan][i].p_ratio = psy_stvar_short[no_of_chan].ismr[i];
p_chpo_short[no_of_chan][i].cb_width = p_sri->cb_width_short;
p_chpo_short[no_of_chan][i].no_of_cb = p_sri->num_cb_short;
if (no_of_chan == 1)
memcpy(p_chpo_short[no_of_chan][i].use_ms, psy_stvar_short[no_of_chan].use_ms[i], NSFB_SHORT*sizeof(int));
}
}
}
void psy_step1(double* p_time_signal[],
double sample[][BLOCK_LEN_LONG*2],
int ch)
{
int i;
for(i = 0; i < BLOCK_LEN_LONG; i++){
sample[ch][i] = sample[ch][i+BLOCK_LEN_LONG];
sample[ch][i+BLOCK_LEN_LONG] = p_time_signal[0][i];
}
}
void psy_step2(double sample[][BLOCK_LEN_LONG*2],
PSY_STATVARIABLE_LONG *psy_stvar_long,
PSY_STATVARIABLE_SHORT *psy_stvar_short,
FFT_TABLE_LONG *fft_tbl_long,
FFT_TABLE_SHORT *fft_tbl_short,
int ch
)
{
int w,i,l,unscambled;
double t_re,t_im;
/* FFT for long */
psy_stvar_long->p_fft += BLOCK_LEN_LONG;
if(psy_stvar_long->p_fft == BLOCK_LEN_LONG * 3)
psy_stvar_long->p_fft = 0;
/* windowing */
for(i = 0; i < BLOCK_LEN_LONG*2; i++){
FFTarray[i].re = fft_tbl_long->hw[i] * (sample[ch][i]/32768);
FFTarray[i].im = 0.0;
}
pfftw_2048(FFTarray);
for(w = 0; w < BLOCK_LEN_LONG; w++){
unscambled = unscambled2048[w];
t_re = FFTarray[unscambled].re;
t_im = FFTarray[unscambled].im;
psy_stvar_long->fft_r[w+psy_stvar_long->p_fft]
= sqrt(t_re*t_re + t_im*t_im);
if( t_re > 0.0 ){
if( t_im >= 0.0 )
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( t_im / t_re );
else
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( t_im / t_re )+ M_PI * 2.0;
} else if( t_re < 0.0 ) {
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = atan( t_im / t_re ) + M_PI;
} else {
if( t_im > 0.0 )
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = M_PI * 0.5;
else if( t_im < 0.0 )
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = M_PI * 1.5;
else
psy_stvar_long->fft_f[w+psy_stvar_long->p_fft] = 0.0; /* tmp */
}
}
/* FFT for short */
for(l = 0; l < MAX_SHORT_WINDOWS; l++){
/* windowing */
for(i = 0; i < BLOCK_LEN_SHORT*2; i++){
FFTarray[i].re = fft_tbl_short->hw[i] * (sample[ch][/*OFFSET_FOR_SHORT +*/ BLOCK_LEN_SHORT * l *2+ i]/4096);
FFTarray[i].im = 0.0;
}
pfftw_256(FFTarray);
for(w = 0; w < BLOCK_LEN_SHORT; w++){
unscambled = unscambled256[w];
t_re = FFTarray[unscambled].re;
t_im = FFTarray[unscambled].im;
psy_stvar_short->fft_r[l][w]
= sqrt(t_re*t_re + t_im*t_im);
if( t_re > 0.0 ){
if( t_im >= 0.0 )
psy_stvar_short->fft_f[l][w] = atan( t_im / t_re );
else
psy_stvar_short->fft_f[l][w] = atan( t_im / t_re )+ M_PI * 2.0;
} else if( t_re < 0.0 ) {
psy_stvar_short->fft_f[l][w] = atan( t_im / t_re ) + M_PI;
} else {
if( t_im > 0.0 )
psy_stvar_short->fft_f[l][w] = M_PI * 0.5;
else if( t_im < 0.0 )
psy_stvar_short->fft_f[l][w] = M_PI * 1.5;
else
psy_stvar_short->fft_f[l][w] = 0.0; /* tmp */
}
}
}
}
void psy_step3(PSY_STATVARIABLE_LONG *psy_stvar_long,
PSY_STATVARIABLE_SHORT *psy_stvar_short,
PSY_VARIABLE_LONG *psy_var_long,
PSY_VARIABLE_SHORT *psy_var_short
/* int ch */
)
{
int w,i;
int p1_l,p2_l;
p1_l = psy_stvar_long->p_fft - BLOCK_LEN_LONG;
if( p1_l < 0 )
p1_l = BLOCK_LEN_LONG * 2;
p2_l = p1_l - BLOCK_LEN_LONG;
if( p2_l < 0 )
p2_l = BLOCK_LEN_LONG * 2;
for(w = 0; w < BLOCK_LEN_LONG; w++){
psy_var_long->r_pred[w] = 2.0 * psy_stvar_long->fft_r[p1_l + w] - psy_stvar_long->fft_r[p2_l + w];
psy_var_long->f_pred[w] = 2.0 * psy_stvar_long->fft_f[p1_l + w] - psy_stvar_long->fft_f[p2_l + w];
}
/* added by T. Araki (1997.10.16) */
for(w = 0; w < BLOCK_LEN_SHORT; w++){
psy_var_short->r_pred[0][w] = 2.0 * psy_stvar_short->last7_fft_r[w] - psy_stvar_short->last6_fft_r[w];
psy_var_short->f_pred[0][w] = 2.0 * psy_stvar_short->last7_fft_f[w] - psy_stvar_short->last6_fft_f[w];
psy_var_short->r_pred[1][w] = 2.0 * psy_stvar_short->fft_r[0][w] - psy_stvar_short->last7_fft_r[w];
psy_var_short->f_pred[1][w] = 2.0 * psy_stvar_short->fft_f[0][w] - psy_stvar_short->last7_fft_f[w];
}
for(i = 2; i < MAX_SHORT_WINDOWS; i++){
for(w = 0; w < BLOCK_LEN_SHORT; w++){
psy_var_short->r_pred[i][w] = 2.0 * psy_stvar_short->fft_r[i - 1][w] - psy_stvar_short->fft_r[i - 2][w];
psy_var_short->f_pred[i][w] = 2.0 * psy_stvar_short->fft_f[i - 1][w] - psy_stvar_short->fft_f[i - 2][w];
}
}
for(w = 0; w < BLOCK_LEN_SHORT; w++){
psy_stvar_short->last6_fft_r[w] = psy_stvar_short->fft_r[6][w];
psy_stvar_short->last6_fft_f[w] = psy_stvar_short->fft_f[6][w];
psy_stvar_short->last7_fft_r[w] = psy_stvar_short->fft_r[7][w];
psy_stvar_short->last7_fft_f[w] = psy_stvar_short->fft_f[7][w];
}
/* added by T. Araki (1997.10.16) end */
}
void psy_step4(PSY_STATVARIABLE_LONG *psy_stvar_long,
PSY_STATVARIABLE_SHORT *psy_stvar_short,
PSY_VARIABLE_LONG *psy_var_long,
PSY_VARIABLE_SHORT *psy_var_short
/*int ch*/
)
{
int w,i;
double r,f,rp,fp;
for(w = 0; w < BLOCK_LEN_LONG; w++){
r = psy_stvar_long->fft_r[psy_stvar_long->p_fft+w];
f = psy_stvar_long->fft_f[psy_stvar_long->p_fft+w];
rp = psy_var_long->r_pred[w];
fp = psy_var_long->f_pred[w];
if( r + fabs(rp) != 0.0 )
psy_var_long->c[w] = sqrt( psy_sqr(r*cos(f) - rp*cos(fp))
+psy_sqr(r*sin(f) - rp*sin(fp)) )/ ( r + fabs(rp) ) ;
else
psy_var_long->c[w] = 0.0; /* tmp */
}
/* added by T. Araki (1997.10.16) */
for(i = 0; i < MAX_SHORT_WINDOWS; i++){
for(w = 0; w < BLOCK_LEN_SHORT; w++){
r = psy_stvar_short->fft_r[i][w];
f = psy_stvar_short->fft_f[i][w];
rp = psy_var_short->r_pred[i][w];
fp = psy_var_short->f_pred[i][w];
if( r + fabs(rp) != 0.0 )
psy_var_short->c[i][w] = sqrt( psy_sqr(r*cos(f) - rp*cos(fp))
+psy_sqr(r*sin(f) - rp*sin(fp)) )/ ( r + fabs(rp) ) ;
else
psy_var_short->c[i][w] = 0.0; /* tmp */
}
}
/* added by T. Araki (1997.10.16) end */
}
void psy_step5(PARTITION_TABLE_LONG *part_tbl_long,
PARTITION_TABLE_SHORT *part_tbl_short,
PSY_STATVARIABLE_LONG *psy_stvar_long,
PSY_STATVARIABLE_SHORT *psy_stvar_short,
PSY_VARIABLE_LONG *psy_var_long,
PSY_VARIABLE_SHORT *psy_var_short
/* int ch*/
)
{
int b,w,i;
double tmp_cb;
for(b = 0; b < part_tbl_long->len; b++){
psy_var_long->e[b] = 0.0;
tmp_cb = 0.0;
/* added by T. Araki (1997.10.16) */
for(w = part_tbl_long->w_low[b]; w <= part_tbl_long->w_high[b]; w++){
psy_var_long->e[b] += psy_sqr(psy_stvar_long->fft_r[psy_stvar_long->p_fft+w]);
tmp_cb += psy_sqr(psy_stvar_long->fft_r[psy_stvar_long->p_fft+w]) * psy_var_long->c[w];
}
/* added by T. Araki (1997.10.16) end */
psy_var_long->c[b] = tmp_cb;
}
/* added by T. Araki (1997.10.16) */
for(i = 0; i < MAX_SHORT_WINDOWS; i++){
for(b = 0; b < part_tbl_short->len; b++){
psy_var_short->e[i][b] = 0.0;
tmp_cb = 0.0;
for(w = part_tbl_short->w_low[b]; w <= part_tbl_short->w_high[b]; w++){
psy_var_short->e[i][b] += psy_sqr(psy_stvar_short->fft_r[i][w]);
tmp_cb += psy_sqr(psy_stvar_short->fft_r[i][w]) * psy_var_short->c[i][w];
}
psy_var_short->c[i][b] = tmp_cb;
}
}
/* added by T. Araki (1997.10.16) end */
}
void psy_step6(PARTITION_TABLE_LONG *part_tbl_long,
PARTITION_TABLE_SHORT *part_tbl_short,
PSY_STATVARIABLE_LONG *psy_stvar_long,
PSY_STATVARIABLE_SHORT *psy_stvar_short,
PSY_VARIABLE_LONG *psy_var_long,
PSY_VARIABLE_SHORT *psy_var_short
)
{
int b,bb,i;
double ecb,ct;
double sprd;
for(b = 0; b < part_tbl_long->len; b++){
ecb = 0.0;
ct = 0.0;
for(bb = 0; bb < part_tbl_long->len; bb++){
//sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 0);
sprd = part_tbl_long->dyn->spreading[bb][b];
ecb += psy_var_long->e[bb] * sprd;
ct += psy_var_long->c[bb] * sprd;
}
if (ecb!=0.0) {
psy_var_long->cb[b] = ct / ecb;
} else {
psy_var_long->cb[b] = 0.0;
}
psy_stvar_long->en[b] = psy_var_long->en[b] = ecb * part_tbl_long->dyn->rnorm[b];
}
/* added by T. Araki (1997.10.16) */
for(i = 0; i < MAX_SHORT_WINDOWS; i++){
for(b = 0; b < part_tbl_short->len; b++){
ecb = 0.0;
ct = 0.0;
for(bb = 0; bb < part_tbl_short->len; bb++){
//sprd = sprdngf(part_tbl_long, part_tbl_short, bb, b, 1);
sprd = part_tbl_short->dyn->spreading[bb][b];
ecb += psy_var_short->e[i][bb] * sprd;
ct += psy_var_short->c[i][bb] * sprd;
}
if (ecb!=0.0) {
psy_var_short->cb[i][b] = ct / ecb;
} else {
psy_var_short->cb[i][b] = 0.0;
}
psy_stvar_short->en[i][b] = psy_var_short->en[i][b] = ecb * part_tbl_short->dyn->rnorm[b];
}
}
/* added by T. Araki (1997.10.16) end */
}
void psy_step7(PARTITION_TABLE_LONG *part_tbl_long,
PARTITION_TABLE_SHORT *part_tbl_short,
PSY_VARIABLE_LONG *psy_var_long,
PSY_VARIABLE_SHORT *psy_var_short)
{
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -