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

📄 tonal.c

📁 MPEG 2的音频编码软件。喜欢多媒体的开发人员可以看看。
💻 C
📖 第 1 页 / 共 4 页
字号:
/**********************************************************************
 * ISO MPEG Audio Subgroup Software Simulation Group (1996)
 * ISO 13818-3 MPEG-2 Audio Multichannel Encoder
 *
 * $Id: tonal.c 1.8 1996/02/12 07:13:35 rowlands Exp $
 *
 * $Log: tonal.c $
 * Revision 1.8  1996/02/12 07:13:35  rowlands
 * Release following Munich meeting
 *
 * Revision 1.5.2.1  1995/11/06  04:19:12  rowlands
 * Received from Uwe Felderhoff (IRT)
 *
 * Revision 1.7  1995/08/14  08:06:37  tenkate
 * ML-LSF added Warner ten Kate 7/8/95 (Philips)
 * II_psycho_one() split into II_psycho_one() for audio data and
 * II_psycho_one_ml() for MultiLingual data.
 * Variables crit_band, cbound and sub_size has been made local to
 * these functions.
 * Tables "cb" and "th" are copied from LSF-directory.
 * ltg has found its ml counterpart.
 *
 * Revision 1.6  1995/07/31  07:47:50  tenkate
 * bugs correction (if center==1 in Psycho_One), 25/07/95 WtK
 *
 * Revision 1.4.2.1  1995/06/16  03:46:42  rowlands
 * Input from Susanne Ritscher (IRT)
 *
 **********************************************************************/

/**********************************************************************
 *   date   programmers         comment                               *
 * 2/25/91  Douglas Wong        start of version 1.1 records          *
 * 3/06/91  Douglas Wong        rename: setup.h to endef.h            *
 *                              updated I_psycho_one and II_psycho_one*
 * 3/11/91  W. J. Carter        Added Douglas Wong's updates dated    *
 *                              3/9/91 for I_Psycho_One() and for     *
 *                              II_Psycho_One().                      *
 * 5/10/91  W. Joseph Carter    Ported to Macintosh and Unix.         *
 *                              Located and fixed numerous software   *
 *                              bugs and table data errors.           *
 * 6/11/91  Davis Pan           corrected several bugs                *
 *                              based on comments from H. Fuchs       *
 * 01jul91  dpwe (Aware Inc.)   Made pow() args float                 *
 *                              Removed logical bug in I_tonal_label: *
 *                              Sometimes *tone returned == STOP      *
 * 7/10/91  Earle Jennings      no change necessary in port to MsDos  *
 * 11sep91  dpwe@aware.com      Subtracted 90.3dB from II_f_f_t peaks *
 * 10/1/91  Peter W. Farrett    Updated II_Psycho_One(),I_Psycho_One()*
 *				to include comments.		      *
 *11/29/91  Masahiro Iwadare    Bug fix regarding POWERNORM           *
 *                              fixed several other miscellaneous bugs*
 * 2/11/92  W. Joseph Carter    Ported new code to Macintosh.  Most   *
 *                              important fixes involved changing     *
 *                              16-bit ints to long or unsigned in    *
 *                              bit alloc routines for quant of 65535 *
 *                              and passing proper function args.     *
 *                              Removed "Other Joint Stereo" option   *
 *                              and made bitrate be total channel     *
 *                              bitrate, irrespective of the mode.    *
 *                              Fixed many small bugs & reorganized.  *
 * 2/12/92  Masahiro Iwadare    Fixed some potential bugs in          *
 *          Davis Pan           subsampling()                         *
 * 2/25/92  Masahiro Iwadare    Fixed some more potential bugs        *
 * 92-11-06 Soren H. Nielsen	Corrected power calculation in I_ and *
 *				II_f_f_t.		              *	
 **********************************************************************
 *                                                                    *
 *                                                                    *
 *  MPEG/audio Phase 2 coding/decoding multichannel                   *
 *                                                                    *
 *  7/27/93        Susanne Ritscher,  IRT Munich                      *
 *  8/27/93        Susanne Ritscher, IRT Munich                       *
 *                 Channel-Switching is working                       *
 *  9/1/93         Susanne Ritscher,  IRT Munich                      *
 *                 all channels normalized                            *
 *                                                                    *
 *  9/20/93        channel-switching is only performed at a           *
 *                 certain limit of TC_ALLOC dB, which is included    *
 *                 in encoder.h                                       *
 *                                                                    *
 * 10/18/93        seperated smr and ltmin                            *
 *                                                                    *
 *  Version 1.0                                                       *
 *                                                                    *
 *  07/12/94       Susanne Ritscher,  IRT Munich                      *
 *                 Tel: +49 89 32399 458                              *
 *                 Fax: +49 89 32399 415                              *
 *                                                                    *
 *  Version 1.1                                                       *
 *                                                                    *
 *  02/23/95	   Susanne Ritscher,  IRT Munich                      *
 *                 corrected some bugs                                *
 *                 extension bitstream is working                     *
 *                                                                    *
 **********************************************************************/
#define TONAL_WIDTH 0.1 /* When more than one tonal component is within
                           this width in Bark, the weaker one(s) are
                           eliminated */


#include "common.h"
#include "encoder.h"

/**********************************************************************/
/*
/*        This module implements the psychoacoustic model I for the
/* MPEG encoder layer II. It uses simplified tonal and noise masking
/* threshold analysis to generate SMR for the encoder bit allocation
/* routine.
/*
/**********************************************************************/

int read_crit_band(int lay, int freq) 
{
 int crit_band;
 FILE *fp;
 char r[16], t[80];

 strcpy(r, "2cb1");
 r[0] = (char) lay + '0';
 r[3] = (char) freq + '0';
 if( !(fp = OpenTableFile(r)) ){       /* check boundary values */
    printf("Please check %s boundary table\n",r);
    exit(0);
 }
 fgets(t,80,fp);
 sscanf(t,"%d\n",&crit_band);
 fclose(fp);
 return(crit_band);
}        

void read_cbound(int lay, int freq, int crit_band, int *cbound) 
 /* this function reads in critical band boundaries */
{
 int i,j,k;
 FILE *fp;
 char r[16], t[80];

 strcpy(r, "2cb1");
 r[0] = (char) lay + '0';
 r[3] = (char) freq + '0';
 if( !(fp = OpenTableFile(r)) ){       /* check boundary values */
    printf("Please check %s boundary table\n",r);
    exit(0);
 }
 fgets(t,80,fp);               /* skip input for critical bands */
 sscanf(t,"%d\n",&k);
 for(i=0;i<crit_band;i++){ 
    fgets(t,80,fp);
    sscanf(t,"%d %d\n",&j, &k);
    if(i==j) cbound[j] = k;
    else {                     /* error */
       printf("Please check index %d in cbound table %s\n",i,r);
       exit(0);
    }
 }
 fclose(fp);
}        

void read_freq_band(int *sub_size, g_ptr *ltg, int lay, int freq) 
  /* this function reads in frequency bands and bark values  */
{
 int i,j, k;
 double a,b,c;
 FILE *fp;
 char r[16], t[80];

 strcpy(r, "2th1");
 r[0] = (char) lay + '0';
 r[3] = (char) freq + '0';
 if( !(fp = OpenTableFile(r)) ){   /* check freq. values  */
    printf("Please check frequency and cband table %s\n",r);
    exit(0);
 }
 fgets(t,80,fp);              /* read input for freq. subbands */
 sscanf(t,"%d\n",sub_size);
 *ltg = (g_ptr) mem_alloc (sizeof(g_thres) * (*sub_size), "ltg");
 (*ltg)[0].line = 0;          /* initialize global masking threshold */
 (*ltg)[0].bark = 0;
 (*ltg)[0].hear = 0;
 for(i=1;i<(*sub_size);i++){    /* continue to read freq. subband */
    fgets(t,80,fp);          /* and assign                     */
    sscanf(t,"%d %d %lf %lf\n",&j, &k, &b, &c);
    if(i == j){
       (*ltg)[j].line = k;
       (*ltg)[j].bark = b;
       (*ltg)[j].hear = c;
    }
    else {                   /* error */
       printf("Please check index %d in freq-cb table %s\n",i,r);
       exit(0);
    }
 }
 fclose(fp);
}

void make_map (int sub_size, mask *power, g_thres *ltg)
/* this function calculates the global masking threshold */
{
    int i, j;
   
    for (i = 1; i < sub_size; i++)
	for (j = ltg[i-1].line; j <= ltg[i].line; j++)
	    power[j].map = i;
}

double add_db(double a, double b)
{
 a = pow(10.0,a/10.0);
 b = pow(10.0,b/10.0);
 return 10 * log10(a+b);
}

/****************************************************************/
/*
/*        Fast Fourier transform of the input samples.
/*
/****************************************************************/

void II_f_f_t (double *sample, mask *power) /* this function calculates an */
					    /* FFT analysis for the freq.  */
					    /* domain                      */
{
    int i,j,k,ll,l=0;
    int ip, le, le1;
    double t_r, t_i, u_r, u_i;
    static int M, MM1, init = 0, N, NV2, NM1;
    double *x_r, *x_i, *energy;
    static int *rev;
    static double *w_r, *w_i;

    x_r = (double *) mem_alloc (sizeof (DFFT), "x_r");
    x_i = (double *) mem_alloc (sizeof (DFFT), "x_i");
    energy = (double *) mem_alloc (sizeof (DFFT), "energy");

    if (!init)
    {
	rev = (int *) mem_alloc (sizeof (IFFT), "rev");
	w_r = (double *) mem_alloc (sizeof (D10), "w_r");
	w_i = (double *) mem_alloc (sizeof (D10), "w_i");
	M = 10;
	MM1 = 9;
	N = FFT_SIZE;
	NV2 = FFT_SIZE >> 1;
	NM1 = FFT_SIZE - 1;
	for (ll = 0; ll < M; ll++)
	{
	    le = 1 << (M-ll);
	    le1 = le >> 1;
	    w_r[ll] = cos (PI / le1);
	    w_i[ll] = -sin (PI / le1);
	}
	for (i = 0; i < FFT_SIZE; rev[i] = l, i++)
	    for (j = 0, l = 0; j < 10; j++)
	    {
		k = (i >> j) & 1;
		l |= (k << 9 - j);                
	    }
	init = 1;
    }

    for (i = 0; i < FFT_SIZE; i++)
    {
       x_r[i] = sample[i];
       x_i[i] = energy[i] = 0;
    }
/*
    memcpy ((char *) x_r, (char *) sample, sizeof (double) * FFT_SIZE);
*/
    for (ll = 0; ll < MM1; ll++)
    {
	le = 1 << (M - ll);
	le1 = le >> 1;
	u_r = 1;
	u_i = 0;
	for (j = 0; j < le1; j++)
	{
	    for (i = j; i < N; i += le)
	    {
		ip = i + le1;
		t_r = x_r[i] + x_r[ip];
		t_i = x_i[i] + x_i[ip];
		x_r[ip] = x_r[i] - x_r[ip];
		x_i[ip] = x_i[i] - x_i[ip];
		x_r[i] = t_r;
		x_i[i] = t_i;
		t_r = x_r[ip];
		x_r[ip] = x_r[ip] * u_r - x_i[ip] * u_i;
		x_i[ip] = x_i[ip] * u_r + t_r * u_i;
	    }
	    t_r = u_r;
	    u_r = u_r * w_r[ll] - u_i * w_i[ll];
	    u_i = u_i * w_r[ll] + t_r * w_i[ll];
	}
    }
    for (i = 0; i < N; i += 2)
    {
	ip = i + 1;
	t_r = x_r[i] + x_r[ip];
	t_i = x_i[i] + x_i[ip];
	x_r[ip] = x_r[i] - x_r[ip];
	x_i[ip] = x_i[i] - x_i[ip];
	x_r[i] = t_r;
	x_i[i] = t_i;
	energy[i] = x_r[i] * x_r[i] + x_i[i] * x_i[i];
    }
    for (i = 0; i < FFT_SIZE; i++)
	if (i < rev[i])
	{
	    t_r = energy[i];
	    energy[i] = energy[rev[i]];
	    energy[rev[i]] = t_r;
	}
    for (i = 0; i < HAN_SIZE; i++)
    {
	/* calculate power density spectrum */
	if (energy[i] < 1E-20)
	    energy[i] = 1E-20;
	/* power calculation corrected with a factor 4, both positive
	   and negative frequencies exist, 1992-11-06 shn */
	power[i].x = 10 * log10 (energy[i] * 4.0) + POWERNORM;
	power[i].next = STOP;
	power[i].type = FALSE;
    }

    mem_free ((void **) &x_r);
    mem_free ((void **) &x_i);
    mem_free ((void **) &energy);

}

/****************************************************************/
/*
/*         Window the incoming audio signal.
/*
/****************************************************************/

void II_hann_win (double *sample)   /* this function calculates a  */
				    /* Hann window for PCM (input) */
{				    /* samples for a 1024-pt. FFT  */
    register int i;
    register double sqrt_8_over_3;
    static int init = 0;
    static double *window;
    

⌨️ 快捷键说明

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