home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Da Capo
/
da_capo_vol1.bin
/
programs
/
amiga
/
misc
/
mpegaudio
/
tonal.c
< prev
Wrap
C/C++ Source or Header
|
1994-03-21
|
37KB
|
1,035 lines
/**********************************************************************
Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
tonal.c
**********************************************************************/
/**********************************************************************
* MPEG/audio coding/decoding software, work in progress *
* NOT for public distribution until verified and approved by the *
* MPEG/audio committee. For further information, please contact *
* Davis Pan, 508-493-2241, e-mail: pan@3d.enet.dec.com *
* *
* VERSION 3.9t *
* changes made since last update: *
* 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 *
* 6/24/92 Tan Ah Peng Modified window for FFT *
* (denominator N-1 to N) *
* Updated all critical band rate & *
* absolute threshold tables and critical*
* boundaries for use with Layer I & II *
* Corrected boundary limits for tonal *
* component computation *
* Placement of non-tonal component at *
* geometric mean of critical band *
* (previous placement method commented *
* out - can be used if desired) *
* 3/01/93 Mike Li Infinite looping fix in noise_label() *
* 3/19/93 Jens Spille fixed integer overflow problem in *
* psychoacoutic model 1 *
* 3/19/93 Giorgio Dimino modifications to better account for *
* tonal and non-tonal components *
* 5/28/93 Sriram Jayasimha "London" mod. to psychoacoustic model1*
* 8/05/93 Masahiro Iwadare noise_label modification "option" *
**********************************************************************/
#include "common.h"
#include "encoder.h"
#define LONDON /* enable "LONDON" modification */
#define MAKE_SENSE /* enable "MAKE_SENSE" modification */
#define MI_OPTION /* enable "MI_OPTION" modification */
/**********************************************************************/
/*
/* 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 crit_band;
int FAR *cbound;
int sub_size;
void read_cbound(lay,freq) /* this function reads in critical */
int lay, freq; /* 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(1);
}
fgets(t,80,fp); /* read input for critical bands */
sscanf(t,"%d\n",&crit_band);
cbound = (int FAR *) mem_alloc(sizeof(int) * crit_band, "cbound");
for(i=0;i<crit_band;i++){ /* continue to read input for */
fgets(t,80,fp); /* critical band boundaries */
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(1);
}
}
fclose(fp);
}
void read_freq_band(ltg,lay,freq) /* this function reads in */
int lay, freq; /* frequency bands and bark */
g_ptr FAR *ltg; /* values */
{
int i,j, k;
double 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(1);
}
fgets(t,80,fp); /* read input for freq. subbands */
sscanf(t,"%d\n",&sub_size);
*ltg = (g_ptr FAR ) 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(1);
}
}
fclose(fp);
}
void make_map(power, ltg) /* this function calculates the */
mask FAR power[HAN_SIZE]; /* global masking threshold */
g_thres FAR *ltg;
{
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(a,b)
double a,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(sample, power) /* this function calculates an */
double FAR sample[FFT_SIZE]; /* FFT analysis for the freq. */
mask FAR power[HAN_SIZE]; /* domain */
{
int i,j,k,L,l=0;
int ip, le, le1;
double t_r, t_i, u_r, u_i;
static int M, MM1, init = 0, N;
double *x_r, *x_i, *energy;
static int *rev;
static dou