📄 common.c
字号:
/**********************************************************************Copyright (c) 1991 MPEG/audio software simulation group, All Rights Reservedcommon.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 * * Chad Fogg email: <cfogg@xenon.com> * * * * VERSION 4.1 * * 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 + -