📄 tonal.c
字号:
while(first != LAST){ /* the conditions for the tonal */
if(first<3 || first>500) run = 0;/* otherwise k+/-j will be out of bounds */
else if(first<63) run = 2; /* components in layer II, which */
else if(first<127) run = 3; /* are the boundaries for calc. */
else if(first<255) run = 6; /* the tonal components */
else run = 12;
max = power[first].x - 7; /* after calculation of tonal */
for(j=2;j<=run;j++) /* components, set to local max */
if(max < power[first-j].x || max < power[first+j].x){
power[first].type = FALSE;
break;
}
if(power[first].type == TONE){ /* extract tonal components */
int help=first;
if(*tone==LAST) *tone = first;
while((power[help].next!=LAST)&&(power[help].next-first)<=run)
help=power[help].next;
help=power[help].next;
power[first].next=help;
if((first-last)<=run){
if(last_but_one != LAST) power[last_but_one].next=first;
}
if(first>1 && first<500){ /* calculate the sum of the */
double tmp; /* powers of the components */
tmp = add_db(power[first-1].x, power[first+1].x);
power[first].x = add_db(power[first].x, tmp);
}
for(j=1;j<=run;j++){
power[first-j].x = power[first+j].x = DBMIN;
power[first-j].next = power[first+j].next = STOP;
power[first-j].type = power[first+j].type = FALSE;
}
last_but_one=last;
last = first;
first = power[first].next;
}
else {
int ll;
if(last == LAST); /* *tone = power[first].next; dpwe */
else power[last].next = power[first].next;
ll = first;
first = power[first].next;
power[ll].next = STOP;
}
}
}
/****************************************************************
*
* This function groups all the remaining non-tonal
* spectral lines into critical band where they are replaced by
* one single line.
*
****************************************************************/
void noise_label(power, noise, ltg)
g_thres FAR *ltg;
mask FAR *power;
int *noise;
{
int i,j, centre, last = LAST;
double index, weight, sum;
/* calculate the remaining spectral */
for(i=0;i<crit_band-1;i++){ /* lines for non-tonal components */
for(j=cbound[i],weight = 0.0,sum = DBMIN;j<cbound[i+1];j++){
if(power[j].type != TONE){
if(power[j].x != DBMIN){
sum = add_db(power[j].x,sum);
/* the line below and others under the "MAKE_SENSE" condition are an alternate
interpretation of "geometric mean". This approach may make more sense but
it has not been tested with hardware. */
#ifdef MAKE_SENSE
/* weight += pow(10.0, power[j].x/10.0) * (ltg[power[j].map].bark-i);
bad code [SS] 21-1-93
*/
weight += pow(10.0,power[j].x/10.0) * (double) (j-cbound[i]) /
(double) (cbound[i+1]-cbound[i]); /* correction */
#endif
power[j].x = DBMIN;
}
} /* check to see if the spectral line is low dB, and if */
} /* so replace the center of the critical band, which is */
/* the center freq. of the noise component */
#ifdef MAKE_SENSE
if(sum <= DBMIN) centre = (cbound[i+1]+cbound[i]) /2;
else {
index = weight/pow(10.0,sum/10.0);
centre = cbound[i] + (int) (index * (double) (cbound[i+1]-cbound[i]) );
}
#else
index = (double)( ((double)cbound[i]) * ((double)(cbound[i+1]-1)) );
centre = (int)(pow(index,0.5)+0.5);
#endif
/* locate next non-tonal component until finished; */
/* add to list of non-tonal components */
#ifdef MI_OPTION
/* Masahiro Iwadare's fix for infinite looping problem? */
if(power[centre].type == TONE)
if (power[centre+1].type == TONE) centre++; else centre--;
#else
/* Mike Li's fix for infinite looping problem */
if(power[centre].type == FALSE) centre++;
if(power[centre].type == NOISE){
if(power[centre].x >= ltg[power[i].map].hear){
if(sum >= ltg[power[i].map].hear) sum = add_db(power[j].x,sum);
else
sum = power[centre].x;
}
}
#endif
if(last == LAST) *noise = centre;
else {
power[centre].next = LAST;
power[last].next = centre;
}
power[centre].x = sum;
power[centre].type = NOISE;
last = centre;
}
}
/****************************************************************
*
* This function reduces the number of noise and tonal
* component for further threshold analysis.
*
****************************************************************/
void subsampling(power, ltg, tone, noise)
mask FAR power[HAN_SIZE];
g_thres FAR *ltg;
int *tone, *noise;
{
int i, old;
i = *tone; old = STOP; /* calculate tonal components for */
while(i!=LAST){ /* reduction of spectral lines */
if(power[i].x < ltg[power[i].map].hear){
power[i].type = FALSE;
power[i].x = DBMIN;
if(old == STOP) *tone = power[i].next;
else power[old].next = power[i].next;
}
else old = i;
i = power[i].next;
}
i = *noise; old = STOP; /* calculate non-tonal components for */
while(i!=LAST){ /* reduction of spectral lines */
if(power[i].x < ltg[power[i].map].hear){
power[i].type = FALSE;
power[i].x = DBMIN;
if(old == STOP) *noise = power[i].next;
else power[old].next = power[i].next;
}
else old = i;
i = power[i].next;
}
i = *tone; old = STOP;
while(i != LAST){ /* if more than one */
if(power[i].next == LAST)break; /* tonal component */
if(ltg[power[power[i].next].map].bark - /* is less than .5 */
ltg[power[i].map].bark < 0.5) { /* bark, take the */
if(power[power[i].next].x > power[i].x ){/* maximum */
if(old == STOP) *tone = power[i].next;
else power[old].next = power[i].next;
power[i].type = FALSE;
power[i].x = DBMIN;
i = power[i].next;
}
else {
power[power[i].next].type = FALSE;
power[power[i].next].x = DBMIN;
power[i].next = power[power[i].next].next;
old = i;
}
}
else {
old = i;
i = power[i].next;
}
}
}
/****************************************************************
*
* This function calculates the individual threshold and
* sum with the quiet threshold to find the global threshold.
*
****************************************************************/
void threshold(power, ltg, tone, noise, bit_rate)
mask FAR power[HAN_SIZE];
g_thres FAR *ltg;
int *tone, *noise, bit_rate;
{
int k, t;
double dz, tmps, vf;
for(k=1;k<sub_size;k++){
ltg[k].x = DBMIN;
t = *tone; /* calculate individual masking threshold for */
while(t != LAST){ /* components in order to find the global */
if(ltg[k].bark-ltg[power[t].map].bark >= -3.0 && /*threshold (LTG)*/
ltg[k].bark-ltg[power[t].map].bark <8.0){
dz = ltg[k].bark-ltg[power[t].map].bark; /* distance of bark value*/
tmps = -1.525-0.275*ltg[power[t].map].bark - 4.5 + power[t].x;
/* masking function for lower & upper slopes */
if(-3<=dz && dz<-1) vf = 17*(dz+1)-(0.4*power[t].x +6);
else if(-1<=dz && dz<0) vf = (0.4 *power[t].x + 6) * dz;
else if(0<=dz && dz<1) vf = (-17*dz);
else if(1<=dz && dz<8) vf = -(dz-1) * (17-0.15 *power[t].x) - 17;
tmps += vf;
ltg[k].x = add_db(ltg[k].x, tmps);
}
t = power[t].next;
}
t = *noise; /* calculate individual masking threshold */
while(t != LAST){ /* for non-tonal components to find LTG */
if(ltg[k].bark-ltg[power[t].map].bark >= -3.0 &&
ltg[k].bark-ltg[power[t].map].bark <8.0){
dz = ltg[k].bark-ltg[power[t].map].bark; /* distance of bark value */
tmps = -1.525-0.175*ltg[power[t].map].bark -0.5 + power[t].x;
/* masking function for lower & upper slopes */
if(-3<=dz && dz<-1) vf = 17*(dz+1)-(0.4*power[t].x +6);
else if(-1<=dz && dz<0) vf = (0.4 *power[t].x + 6) * dz;
else if(0<=dz && dz<1) vf = (-17*dz);
else if(1<=dz && dz<8) vf = -(dz-1) * (17-0.15 *power[t].x) - 17;
tmps += vf;
ltg[k].x = add_db(ltg[k].x, tmps);
}
t = power[t].next;
}
if(bit_rate<96)ltg[k].x = add_db(ltg[k].hear, ltg[k].x);
else ltg[k].x = add_db(ltg[k].hear-12.0, ltg[k].x);
}
}
/****************************************************************
*
* This function finds the minimum masking threshold and
* return the value to the encoder.
*
****************************************************************/
void II_minimum_mask(ltg,ltmin,sblimit)
g_thres FAR *ltg;
double FAR ltmin[SBLIMIT];
int sblimit;
{
double min;
int i,j;
j=1;
for(i=0;i<sblimit;i++)
if(j>=sub_size-1) /* check subband limit, and */
ltmin[i] = ltg[sub_size-1].hear; /* calculate the minimum masking */
else { /* level of LTMIN for each subband*/
min = ltg[j].x;
while(ltg[j].line>>4 == i && j < sub_size){
if(min>ltg[j].x) min = ltg[j].x;
j++;
}
ltmin[i] = min;
}
}
/*****************************************************************
*
* This procedure is called in musicin to pick out the
* smaller of the scalefactor or threshold.
*
*****************************************************************/
void II_smr(ltmin, spike, scale, sblimit)
double FAR spike[SBLIMIT], scale[SBLIMIT], ltmin[SBLIMIT];
int sblimit;
{
int i;
double max;
for(i=0;i<sblimit;i++){ /* determine the signal */
max = 20 * log10(scale[i] * 32768) - 10; /* level for each subband */
if(spike[i]>max) max = spike[i]; /* for the maximum scale */
max -= ltmin[i]; /* factors */
ltmin[i] = max;
}
}
/****************************************************************
*
* This procedure calls all the necessary functions to
* complete the psychoacoustic analysis.
*
****************************************************************/
void II_Psycho_One(buffer, scale, ltmin, fr_ps)
short FAR buffer[2][1152];
double FAR scale[2][SBLIMIT], ltmin[2][SBLIMIT];
frame_params *fr_ps;
{
layer *info = fr_ps->header;
int stereo = fr_ps->stereo;
int sblimit = fr_ps->sblimit;
int k,i, tone=0, noise=0;
static char init = 0;
static int off[2] = {256,256};
double *sample;
DSBL *spike;
static D1408 *fft_buf;
static mask_ptr FAR power;
static g_ptr FAR ltg;
sample = (double *) mem_alloc(sizeof(DFFT), "sample");
spike = (DSBL *) mem_alloc(sizeof(D2SBL), "spike");
/* call functions for critical boundaries, freq. */
if(!init){ /* bands, bark values, and mapping */
fft_buf = (D1408 *) mem_alloc((long) sizeof(D1408) * 2, "fft_buf");
power = (mask_ptr FAR ) mem_alloc(sizeof(mask) * HAN_SIZE, "power");
if (info->version == MPEG_AUDIO_ID) {
read_cbound(info->lay, info->sampling_frequency);
read_freq_band(<g, info->lay, info->sampling_frequency);
} else {
read_cbound(info->lay, info->sampling_frequency + 4);
read_freq_band(<g, info->lay, info->sampling_frequency + 4);
}
make_map(power,ltg);
for (i=0;i<1408;i++) fft_buf[0][i] = fft_buf[1][i] = 0;
init = 1;
}
for(k=0;k<stereo;k++){ /* check pcm input for 3 blocks of 384 samples */
for(i=0;i<1152;i++) fft_buf[k][(i+off[k])%1408]= (double)buffer[k][i]/SCALE;
for(i=0;i<FFT_SIZE;i++) sample[i] = fft_buf[k][(i+1216+off[k])%1408];
off[k] += 1152;
off[k] %= 1408;
/* call functions for windowing PCM samples,*/
II_hann_win(sample); /* location of spectral components in each */
for(i=0;i<HAN_SIZE;i++) power[i].x = DBMIN; /*subband with labeling*/
II_f_f_t(sample, power); /*locate remaining non-*/
II_pick_max(power, &spike[k][0]); /*tonal sinusoidals, */
II_tonal_label(power, &tone); /*reduce noise & tonal */
noise_label(power, &noise, ltg); /*components, find */
subsampling(power, ltg, &tone, &noise); /*global & minimal */
threshold(power, ltg, &tone, &noise, /*threshold, and sgnl- */
bitrate[info->version][info->lay-1][info->bitrate_index]/stereo); /*to-mask ratio*/
II_minimum_mask(ltg, <min[k][0], sblimit);
II_smr(<min[k][0], &spike[k][0], &scale[k][0], sblimit);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -