?? common.c
字號:
/**********************************************************************
Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reserved
common.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, 708-538-5671, e-mail: pan@ukraine.corp.mot.com *
* *
* VERSION 4.3 *
* changes made since last update: *
* date programmers comment *
* 2/25/91 Doulas Wong, start of version 1.0 records *
* Davis Pan *
* 5/10/91 W. Joseph Carter Created this file for all common *
* functions and global variables. *
* Ported to Macintosh and Unix. *
* Added Jean-Georges Fritsch's *
* "bitstream.c" package. *
* Added routines to handle AIFF PCM *
* sound files. *
* Added "mem_alloc()" and "mem_free()" *
* routines for memory allocation *
* portability. *
* Added routines to convert between *
* Apple SANE extended floating point *
* format and IEEE double precision *
* floating point format. For AIFF. *
* 02jul91 dpwe (Aware Inc) Moved allocation table input here; *
* Tables read from subdir TABLES_PATH. *
* Added some debug printout fns (Write*)*
* 7/10/91 Earle Jennings replacement of the one float by FLOAT *
* port to MsDos from MacIntosh version *
* 8/ 5/91 Jean-Georges Fritsch fixed bug in open_bit_stream_r() *
*10/ 1/91 S.I. Sudharsanan, Ported to IBM AIX platform. *
* Don H. Lee, *
* Peter W. Farrett *
*10/3/91 Don H. Lee implemented CRC-16 error protection *
* newly introduced functions are *
* I_CRC_calc, II_CRC_calc and *
* update_CRC. Additions and revisions *
* are marked with dhl for clarity *
*10/18/91 Jean-Georges Fritsch fixed bug in update_CRC(), *
* II_CRC_calc() and I_CRC_calc() *
* 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. *
* 3/20/92 Jean-Georges Fritsch fixed bug in start-of-frame search *
* 6/15/92 Juan Pineda added refill_buffer(bs) "n" *
* initialization *
* 7/08/92 Susanne Ritscher MS-DOS, MSC6.0 port fixes *
* 7/27/92 Mike Li (re-)Port to MS-DOS *
* 8/19/92 Soren H. Nielsen Fixed bug in I_CRC_calc and in *
* II_CRC_calc. Added function: new_ext *
* for better MS-DOS compatability *
* 3/10/93 Kevin Peterson changed aiff_read_headers to handle *
* chunks in any order. now returns *
* position of sound data in file. *
* 3/31/93 Jens Spille changed IFF_* string compares to use *
* strcmp() *
* 5/30/93 Masahiro Iwadare removed the previous modification *
* for UNIX. *
* 8/27/93 Seymour Shlien, Fixes in Unix and MSDOS ports, *
* Daniel Lauzon, and *
* Bill Truerniet *
*--------------------------------------------------------------------*
* 8/24/93 Masahiro Iwadare Included IS modification in Layer III.*
* Changed for 1 pass decoding. *
* 9/07/93 Toshiyuki Ishino Integrated Layer III with Ver 3.9. *
*--------------------------------------------------------------------*
* 11/20/93 Masahiro Iwadare Integrated Layer III with Ver 4.0. *
*--------------------------------------------------------------------*
* 7/14/94 Juergen Koller rewind of bitbuffer added *
**********************************************************************/
/***********************************************************************
*
* Global Include Files
*
***********************************************************************/
#include "common.h"
#ifdef MACINTOSH
#include <SANE.h>
#include <pascal.h>
#endif
#include <ctype.h>
/***********************************************************************
*
* Global Variable Definitions
*
***********************************************************************/
char *mode_names[4] = { "stereo", "j-stereo", "dual-ch", "single-ch" };
char *layer_names[3] = { "I", "II", "III" };
double s_freq[4] = {44.1, 48, 32, 0};
int bitrate[3][15] = {
{0,32,64,96,128,160,192,224,256,288,320,352,384,416,448},
{0,32,48,56,64,80,96,112,128,160,192,224,256,320,384},
{0,32,40,48,56,64,80,96,112,128,160,192,224,256,320}
};
double FAR multiple[64] = {
2.00000000000000, 1.58740105196820, 1.25992104989487,
1.00000000000000, 0.79370052598410, 0.62996052494744, 0.50000000000000,
0.39685026299205, 0.31498026247372, 0.25000000000000, 0.19842513149602,
0.15749013123686, 0.12500000000000, 0.09921256574801, 0.07874506561843,
0.06250000000000, 0.04960628287401, 0.03937253280921, 0.03125000000000,
0.02480314143700, 0.01968626640461, 0.01562500000000, 0.01240157071850,
0.00984313320230, 0.00781250000000, 0.00620078535925, 0.00492156660115,
0.00390625000000, 0.00310039267963, 0.00246078330058, 0.00195312500000,
0.00155019633981, 0.00123039165029, 0.00097656250000, 0.00077509816991,
0.00061519582514, 0.00048828125000, 0.00038754908495, 0.00030759791257,
0.00024414062500, 0.00019377454248, 0.00015379895629, 0.00012207031250,
0.00009688727124, 0.00007689947814, 0.00006103515625, 0.00004844363562,
0.00003844973907, 0.00003051757813, 0.00002422181781, 0.00001922486954,
0.00001525878906, 0.00001211090890, 0.00000961243477, 0.00000762939453,
0.00000605545445, 0.00000480621738, 0.00000381469727, 0.00000302772723,
0.00000240310869, 0.00000190734863, 0.00000151386361, 0.00000120155435,
1E-20
};
/***********************************************************************
*
* Global Function Definitions
*
***********************************************************************/
/* The system uses a variety of data files. By opening them via this
function, we can accommodate various locations. */
FILE *OpenTableFile(name)
char *name;
{
char fulname[80];
char *envdir;
FILE *f;
fulname[0] = '\0';
#ifdef TABLES_PATH
strcpy(fulname, TABLES_PATH); /* default relative path for tables */
#endif /* TABLES_PATH */ /* (includes terminal path seperator */
#ifdef UNIX /* envir. variables for UNIX only */
{
char *getenv();
envdir = getenv(MPEGTABENV); /* check for environment */
if(envdir != NULL)
strcpy(fulname, envdir);
strcat(fulname, PATH_SEPARATOR); /* add a "/" on the end */
}
#endif /* UNIX */
strcat(fulname, name);
if( (f=fopen(fulname,"r"))==NULL ) {
fprintf(stderr,"OpenTable: could not find %s\n", fulname);
#ifdef UNIX
if(envdir != NULL)
fprintf(stderr,"Check %s directory '%s'\n",MPEGTABENV, envdir);
else
fprintf(stderr,"Check local directory './%s' or setenv %s\n",
TABLES_PATH, MPEGTABENV);
#else /* not unix : no environment variables */
#ifdef TABLES_PATH
fprintf(stderr,"Check local directory './%s'\n",TABLES_PATH);
#endif /* TABLES_PATH */
#endif /* UNIX */
}
return f;
}
/***********************************************************************
/*
/* Read one of the data files ("alloc_*") specifying the bit allocation/
/* quatization parameters for each subband in layer II encoding
/*
/**********************************************************************/
int read_bit_alloc(table, alloc) /* read in table, return # subbands */
int table;
al_table *alloc;
{
unsigned int a, b, c, d, i, j;
FILE *fp;
char name[16], t[80];
int sblim;
strcpy(name, "alloc_0");
switch (table) {
case 0 : name[6] = '0'; break;
case 1 : name[6] = '1'; break;
case 2 : name[6] = '2'; break;
case 3 : name[6] = '3'; break;
default : name[6] = '0';
}
if (!(fp = OpenTableFile(name))) {
printf("Please check bit allocation table %s\n", name);
exit(1);
}
printf("using bit allocation table %s\n", name);
fgets(t, 80, fp);
sscanf(t, "%d\n", &sblim);
while (!feof(fp)) {
fgets(t, 80, fp);
sscanf(t, "%d %d %d %d %d %d\n", &i, &j, &a, &b, &c, &d);
(*alloc)[i][j].steps = a;
(*alloc)[i][j].bits = b;
(*alloc)[i][j].group = c;
(*alloc)[i][j].quant = d;
}
fclose(fp);
return sblim;
}
/***********************************************************************
/*
/* Using the decoded info the appropriate possible quantization per
/* subband table is loaded
/*
/**********************************************************************/
int pick_table(fr_ps) /* choose table, load if necess, return # sb's */
frame_params *fr_ps;
{
int table, lay, ws, bsp, br_per_ch, sfrq;
int sblim = fr_ps->sblimit; /* return current value if no load */
lay = fr_ps->header->lay - 1;
bsp = fr_ps->header->bitrate_index;
br_per_ch = bitrate[lay][bsp] / fr_ps->stereo;
ws = fr_ps->header->sampling_frequency;
sfrq = s_freq[ws];
/* decision rules refer to per-channel bitrates (kbits/sec/chan) */
if ((sfrq == 48 && br_per_ch >= 56) ||
(br_per_ch >= 56 && br_per_ch <= 80)) table = 0;
else if (sfrq != 48 && br_per_ch >= 96) table = 1;
else if (sfrq != 32 && br_per_ch <= 48) table = 2;
else table = 3;
if (fr_ps->tab_num != table) {
if (fr_ps->tab_num >= 0)
mem_free((void **)&(fr_ps->alloc));
fr_ps->alloc = (al_table FAR *) mem_alloc(sizeof(al_table),
"alloc");
sblim = read_bit_alloc(fr_ps->tab_num = table, fr_ps->alloc);
}
return sblim;
}
int js_bound(lay, m_ext)
int lay, m_ext;
{
static int jsb_table[3][4] = { { 4, 8, 12, 16 }, { 4, 8, 12, 16},
{ 0, 4, 8, 16} }; /* lay+m_e -> jsbound */
if(lay<1 || lay >3 || m_ext<0 || m_ext>3) {
fprintf(stderr, "js_bound bad layer/modext (%d/%d)\n", lay, m_ext);
exit(1);
}
return(jsb_table[lay-1][m_ext]);
}
void hdr_to_frps(fr_ps) /* interpret data in hdr str to fields in fr_ps */
frame_params *fr_ps;
{
layer *hdr = fr_ps->header; /* (or pass in as arg?) */
fr_ps->actual_mode = hdr->mode;
fr_ps->stereo = (hdr->mode == MPG_MD_MONO) ? 1 : 2;
if (hdr->lay == 2) fr_ps->sblimit = pick_table(fr_ps);
else fr_ps->sblimit = SBLIMIT;
if(hdr->mode == MPG_MD_JOINT_STEREO)
fr_ps->jsbound = js_bound(hdr->lay, hdr->mode_ext);
else
fr_ps->jsbound = fr_ps->sblimit;
/* alloc, tab_num set in pick_table */
}
void WriteHdr(fr_ps, s)
frame_params *fr_ps;
FILE *s;
{
layer *info = fr_ps->header;
fprintf(s, "HDR: s=FFF, id=%X, l=%X, ep=%X, br=%X, sf=%X, pd=%X, ",
info->version, info->lay, !info->error_protection,
info->bitrate_index, info->sampling_frequency, info->padding);
fprintf(s, "pr=%X, m=%X, js=%X, c=%X, o=%X, e=%X\n",
info->extension, info->mode, info->mode_ext,
info->copyright, info->original, info->emphasis);
fprintf(s, "layer=%s, tot bitrate=%d, sfrq=%.1f, mode=%s, ",
layer_names[info->lay-1], bitrate[info->lay-1][info->bitrate_index],
s_freq[info->sampling_frequency], mode_names[info->mode]);
fprintf(s, "sblim=%d, jsbd=%d, ch=%d\n",
fr_ps->sblimit, fr_ps->jsbound, fr_ps->stereo);
fflush(s);
}
void WriteBitAlloc(bit_alloc, f_p, s)
unsigned int bit_alloc[2][SBLIMIT];
frame_params *f_p;
FILE *s;
{
int i,j;
int st = f_p->stereo;
int sbl = f_p->sblimit;
int jsb = f_p->jsbound;
fprintf(s, "BITA ");
for(i=0; i<sbl; ++i) {
if(i == jsb) fprintf(s,"-");
for(j=0; j<st; ++j)
fprintf(s, "%1x", bit_alloc[j][i]);
}
fprintf(s, "\n"); fflush(s);
}
void WriteScale(bit_alloc, scfsi, scalar, fr_ps, s)
unsigned int bit_alloc[2][SBLIMIT], scfsi[2][SBLIMIT], scalar[2][3][SBLIMIT];
frame_params *fr_ps;
FILE *s;
{
int stereo = fr_ps->stereo;
int sblimit = fr_ps->sblimit;
int lay = fr_ps->header->lay;
int i,j,k;
if(lay == 2) {
fprintf(s, "SFSI ");
for (i=0;i<sblimit;i++) for (k=0;k<stereo;k++)
if (bit_alloc[k][i]) fprintf(s,"%d",scfsi[k][i]);
fprintf(s, "\nSCFs ");
for (k=0;k<stereo;k++) {
for (i=0;i<sblimit;i++)
if (bit_alloc[k][i])
switch (scfsi[k][i]) {
case 0: for (j=0;j<3;j++)
fprintf(s,"%2d%c",scalar[k][j][i],
(j==2)?';':'-');
break;
case 1:
case 3: fprintf(s,"%2d-",scalar[k][0][i]);
fprintf(s,"%2d;",scalar[k][2][i]);
break;
case 2: fprintf(s,"%2d;",scalar[k][0][i]);
}
fprintf(s, "\n");
}
}
else{ /* lay == 1 */
fprintf(s, "SCFs ");
for (i=0;i<sblimit;i++) for (k=0;k<stereo;k++)
if (bit_alloc[k][i]) fprintf(s,"%2d;",scalar[k][0][i]);
fprintf(s, "\n");
}
}
void WriteSamples(ch, sample, bit_alloc, fr_ps, s)
int ch;
unsigned int FAR sample[SBLIMIT];
unsigned int bit_alloc[SBLIMIT];
frame_params *fr_ps;
FILE *s;
{
int i;
int stereo = fr_ps->stereo;
int sblimit = fr_ps->sblimit;
fprintf(s, "SMPL ");
for (i=0;i<sblimit;i++)
if ( bit_alloc[i] != 0)
fprintf(s, "%d:", sample[i]);
if(ch==(stereo-1) ) fprintf(s, "\n");
else fprintf(s, "\t");
}
int NumericQ(s) /* see if a string lookd like a numeric argument */
char *s;
{
char c;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -