📄 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 + -