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

📄 tonal.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (!init)
    {
	/* calculate window function for the Fourier transform */
	window = (double *) mem_alloc (sizeof (DFFT), "window");
	sqrt_8_over_3 = pow (8.0 / 3.0, 0.5);
	for (i = 0; i < FFT_SIZE; i++)
	{
	    /* Hann window formula */
	    window[i] = sqrt_8_over_3 * 0.5 * (1 - cos (2.0*PI*i / (FFT_SIZE-1))) / FFT_SIZE;
	}
	init = 1;
    }

    for (i = 0; i < FFT_SIZE; i++)
	sample[i] *= window[i];
}

/*******************************************************************/
/*
/*        This function finds the maximum spectral component in each
/* subband and return them to the encoder for time-domain threshold
/* determination.
/*
/*******************************************************************/

void II_pick_max (mask *power, double *spike)
{
 double max;
 int i,j;

 for(i=0;i<HAN_SIZE;spike[i>>4] = max, i+=16)      /* calculate the      */
 for(j=0, max = DBMIN;j<16;j++)                    /* maximum spectral   */
    max = (max>power[i+j].x) ? max : power[i+j].x; /* component in each  */
}                                                  /* subband from bound */
                                                   /* 4-16               */

/****************************************************************/
/*
/*        This function labels the tonal component in the power
/* spectrum.
/*
/****************************************************************/

void II_tonal_label(mask *power, int *tone) /* this function extracts (tonal) */
					    /* sinusoidals from the spectrum  */
{
 int i,j, last = LAST, first, run, last_but_one = LAST; /* dpwe */
 double max;

 *tone = LAST;
 for(i=2;i<HAN_SIZE-12;i++){
    if(power[i].x>power[i-1].x && power[i].x>=power[i+1].x){
       power[i].type = TONE;
       power[i].next = LAST;
       if(last != LAST) power[last].next = i;
       else first = *tone = i;
       last = i;
    }
 }
 last = LAST;
 first = *tone;
 *tone = LAST;
 while(first != LAST){               /* the conditions for the tonal          */
    if(first<2 || first>499) run = 0;/* otherwise k+/-j will be out of bounds */
    else if(first<62) run = 2;       /* components in layer II, which         */
    else if(first<126) run = 3;      /* are the boundaries for calc.          */
    else if(first<254) 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<255){     /* 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(int crit_band, int *cbound, mask *power, int *noise, g_thres *ltg)
{
 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);
              weight += pow(10.0, power[j].x/10.0) * (ltg[power[j].map].bark-i);
              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              */
     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]) );
     }     /* locate next non-tonal component until finished; */
           /* add to list of non-tonal components             */
     if(power[centre].type == TONE) centre++;
     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 (mask *power, g_thres *ltg, int *tone, int *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 < TONAL_WIDTH)
	{
	    /* 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;
	    }
	    else
	    {
		power[power[i].next].type = FALSE;
		power[power[i].next].x = DBMIN;
		power[i].next = power[power[i].next].next;
	    }
	}
	else
	    old = i;
	i = power[i].next;
    }
}


/* ----------------------------------------------------------------------------
The masking function parameters are here set according to the parameters in
the IRT real time implementation. The constant definitions are for convenience.
1993-07-23 shn
---------------------------------------------------------------------------- */

#define AV_TONAL_K    -9.0 /* Masking index, tonal, constant part  [dB] */
#define AV_NOISE_K    -5.0 /* Masking index, noisy, constant part  [dB] */
#define AV_TONAL_DZ   -0.3 /* Masking index, tonal, CBR dependence [dB/Bark] */
#define AV_NOISE_DZ   -0.3 /* Masking index, noisy, CBR dependence [dB/Bark] */

#define LOW_LIM_1     -1.0 /* 1st lower slope from 0         to LOW_LIM_1 [Bark] */
#define LOW_LIM_2     -3.0 /* 2nd lower slope from LOW_LIM_1 to LOW_LIM_2 [Bark] */

#define LOW_DZ_K_1     6.0 /* 1st lower slope, constant part [dB/Bark] */
#define LOW_DZ_SPL_1   0.4 /* 1st lower slope, SPL dependence [dB/(Bark*dB)] */
#define LOW_DZ_MIN_1  17.0 /* 1st lower slope, minimum value [dB/Bark] */
#define LOW_DZ_2      17.0 /* 2nd lower slope [dB/Bark] */

#define UP_LIM_1       1.0 /* 1st upper slope from 0        to UP_LIM_1 [Bark] */
#define UP_LIM_2       8.0 /* 2nd upper slope from UP_LIM_1 to UP_LIM_2 [Bark] */

#define UP_DZ_1      -18.0 /* 1st upper slope, constant part [dB/Bark] */
#define UP_SPL_1       0.0 /* 1st upper slope, SPL dependence [dB/(Bark*dB)] */
#define UP_DZ_2      -17.0 /* 2nd upper slope, constant part [dB/Bark] */
#define UP_SPL_2      -0.1 /* 2nd upper slope, SPL dependence [dB/(Bark*dB)] */

#define H_THR_OFFSET -12.0 /* Hearing threshold offset [dB] */
#define H_THR_OS_BR    0 /*96*/   /* Minimum datarate for offset, [kbit/s per channel] */

#define MASK_ADD       2.0 /* Addition of maskers	                [dB] */
#define QUIET_ADD      3.0 /* Addition of masker and threshold in quiet [dB] */

/****************************************************************
*
*        This function calculates the individual threshold and
* sum with the quiet threshold to find the global threshold.
*
****************************************************************/

void threshold(int sub_size, mask *power, g_thres *ltg, int *tone, int *noise, int bit_rate)
{
  int k, t;
  double z, dz, spl, vf, tmps;

  for (k=1; k<sub_size; k++) /* Target frequencies */
  {
    ltg[k].x = DBMIN;
    t = *tone;          /* calculate individual masking threshold  */
    while(t != LAST)    /* for tonal components, t,  to find LTG   */
    {
      z   = ltg[power[t].map].bark; /* critical band rate of masker */
      dz  = ltg[k].bark - z ;       /* distance of bark value*/
      spl = power[t].x;             /* sound pressure level of masker */

      if (dz >= LOW_LIM_2 && dz <  UP_LIM_2)
      {
        tmps = spl + AV_TONAL_K + AV_TONAL_DZ * z;

        /* masking function for lower & upper slopes */
        if (LOW_LIM_2<=dz && dz<LOW_LIM_1)
          if (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1 > LOW_DZ_MIN_1)
            vf = LOW_DZ_2 * (dz - LOW_LIM_1) + 
                (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1) * LOW_LIM_1;
          else
            vf = LOW_DZ_2 * (dz - LOW_LIM_1) + LOW_DZ_MIN_1 * LOW_LIM_1;
        else if (LOW_LIM_1<=dz && dz<0)
          if (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1 > LOW_DZ_MIN_1)
            vf = (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1) * dz;
          else
            vf = LOW_DZ_MIN_1 * dz;
        else if (0<=dz && dz<UP_LIM_1)
          vf = (UP_DZ_1 * dz);
        else if (UP_LIM_1<=dz && dz<UP_LIM_2)
          vf = (dz - UP_LIM_1) * (UP_DZ_2 - UP_SPL_2 * spl) +
               UP_DZ_1 * UP_LIM_1;
        tmps += vf;        
        ltg[k].x = non_lin_add(ltg[k].x, tmps, MASK_ADD);
      }
      t = power[t].next;
    } /* while */

    t = *noise;        /* calculate individual masking threshold   */
    while(t != LAST)   /* for non-tonal components, t, to find LTG */
    {
      z   = ltg[power[t].map].bark; /* critical band rate of masker */
      dz  = ltg[k].bark - z ;       /* distance of bark value*/
      spl = power[t].x;             /* sound pressure level of masker */

      if (dz >= LOW_LIM_2 && dz <  UP_LIM_2)
      {
        tmps = spl + AV_NOISE_K + AV_NOISE_DZ * z;

        /* masking function for lower & upper slopes */
        if (LOW_LIM_2<=dz && dz<LOW_LIM_1)
          if (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1 > LOW_DZ_MIN_1)
            vf = LOW_DZ_2 * (dz - LOW_LIM_1) + 
                (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1) * LOW_LIM_1;
          else
            vf = LOW_DZ_2 * (dz - LOW_LIM_1) + LOW_DZ_MIN_1 * LOW_LIM_1;
        else if (LOW_LIM_1<=dz && dz<0)
          if (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1 > LOW_DZ_MIN_1)
            vf = (LOW_DZ_SPL_1 * spl + LOW_DZ_K_1) * dz;
          else
            vf = LOW_DZ_MIN_1 * dz;
        else if (0<=dz && dz<UP_LIM_1)
          vf = (UP_DZ_1 * dz);
        else if (UP_LIM_1<=dz && dz<UP_LIM_2)
          vf = (dz - UP_LIM_1) * (UP_DZ_2 - UP_SPL_2 * spl) +
               UP_DZ_1 * UP_LIM_1;
       tmps += vf;        

⌨️ 快捷键说明

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