⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tonal.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 3 页
字号:
 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(&ltg, info->lay, info->sampling_frequency);
    } else {
      read_cbound(info->lay, info->sampling_frequency + 4);
      read_freq_band(&ltg, 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, &ltmin[k][0], sblimit);
    II_smr(&ltmin[k][0], &spike[k][0], &scale[k][0], sblimit);        
 }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -