*/ # ifdef HAVE_CONFIG_H # include "config.h" # endif # include "global.h" # include <string.h> # include "resample.h" # include "mad.h" static mad_fixed_t const resample_table[9][9] = { /* 48000 */ { MAD_F(0x10000000) /* 1.000000000 */, MAD_F(0x116a3b36) /* 1.088435374 */, MAD_F(0x18000000) /* 1.500000000 */, MAD_F(0x20000000) /* 2.000000000 */, MAD_F(0x22d4766c) /* 2.176870748 */, MAD_F(0x30000000) /* 3.000000000 */, MAD_F(0x40000000) /* 4.000000000 */, MAD_F(0x45a8ecd8) /* 4.353741497 */, MAD_F(0x60000000) /* 6.000000000 */ }, /* 44100 */ { MAD_F(0x0eb33333) /* 0.918750000 */, MAD_F(0x10000000) /* 1.000000000 */, MAD_F(0x160ccccd) /* 1.378125000 */, MAD_F(0x1d666666) /* 1.837500000 */, MAD_F(0x20000000) /* 2.000000000 */, MAD_F(0x2c19999a) /* 2.756250000 */,
/* * scalefactor table * used in both Layer I and Layer II decoding */ static mad_fixed_t const sf_table[64] = { # include "sf_table.dat" }; /* --- Layer I ------------------------------------------------------------- */ /* linear scaling table */ static mad_fixed_t const linear_table[14] = { MAD_F(0x15555555), /* 2^2 / (2^2 - 1) == 1.33333333333333 */ MAD_F(0x12492492), /* 2^3 / (2^3 - 1) == 1.14285714285714 */ MAD_F(0x11111111), /* 2^4 / (2^4 - 1) == 1.06666666666667 */ MAD_F(0x10842108), /* 2^5 / (2^5 - 1) == 1.03225806451613 */ MAD_F(0x10410410), /* 2^6 / (2^6 - 1) == 1.01587301587302 */ MAD_F(0x10204081), /* 2^7 / (2^7 - 1) == 1.00787401574803 */ MAD_F(0x10101010), /* 2^8 / (2^8 - 1) == 1.00392156862745 */ MAD_F(0x10080402), /* 2^9 / (2^9 - 1) == 1.00195694716243 */ MAD_F(0x10040100), /* 2^10 / (2^10 - 1) == 1.00097751710655 */ MAD_F(0x10020040), /* 2^11 / (2^11 - 1) == 1.00048851978505 */ MAD_F(0x10010010), /* 2^12 / (2^12 - 1) == 1.00024420024420 */ MAD_F(0x10008004), /* 2^13 / (2^13 - 1) == 1.00012208521548 */ MAD_F(0x10004001), /* 2^14 / (2^14 - 1) == 1.00006103888177 */ MAD_F(0x10002000) /* 2^15 / (2^15 - 1) == 1.00003051850948 */ };
/**************************************************************************** * Command-line arguments parsing. We use two methods and two command-line * * formats depending on the system type. On unix system we apply the good * * old getopt() method, other system are offered a really primitive options * * interface. * ****************************************************************************/ static int ParseArgs(int argc, char * const argv[]) { int DoPhoneFilter=0, i; double AmpFactor; mad_fixed_t Amp=MAD_F_ONE; #ifdef HAVE_GETOPT /* This version is for Unix systems. */ int Option; /* Parse the command line. */ while((Option=getopt(argc,argv,"a:p"))!=-1) switch(Option) { /* {5} Set the amplification/attenuation factor, expressed * in dB. */ case 'a': /* If the current linear amplification factor is not * one (MAD_F_ONE) then is was already set. Setting it * again is not permitted. */ if(Amp!=MAD_F_ONE) { fprintf(stderr,"%s: the amplification/attenuation factor " "was set several times.\n",ProgName); return(1); } /* The decibel value is converted to a linear factor. * That factor is checked against the maximum value * that can be stored in a mad_fixed_t. The upper * bound is MAD_F_MAX, it is converted to a double * value with mad_f_todouble() for comparison. */ AmpFactor=pow(10.,atof(optarg)/20); if(AmpFactor>mad_f_todouble(MAD_F_MAX)) { fprintf(stderr,"%s: amplification out of range.\n", ProgName); return(1); } /* Eventually the amplification factor is converted * from double to fixed point with mad_f_tofixed(). */ Amp=mad_f_tofixed(AmpFactor); break; /* {6} The output is filtered through a telephone wire. */ case 'p': /* Only one occurrence of the option is permitted. */ if(DoPhoneFilter) { fprintf(stderr,"%s: the phone-line simulation option " "was already set.\n",ProgName); return(1); } /* The output will be filtered through a band-pass * filter simulating a phone line transmission. */ DoPhoneFilter=1; break; /* Print usage guide for invalid options. */ case '?': default: PrintUsage(); return(1); } #else /* HAVE_GETOPT */ /* This other version is for non-Unix systems. */ /* Scan all command-line arguments. */ for(i=1;i<argc;i++) { /* Set the amplification factor if the current argument looks * like a number. Look at the comment of the case marked {5} * in the Unix section for details. */ if(*argv[i]=='+' || *argv[i]=='-' || isdigit(*argv[i])) { if(Amp!=MAD_F_ONE) { fprintf(stderr,"%s: the amplification/attenuation factor " "was set several times.\n",ProgName); return(1); } AmpFactor=pow(10.,atof(argv[i])/20); if(AmpFactor>mad_f_todouble(MAD_F_MAX)) { fprintf(stderr,"%s: amplification out of range.\n", ProgName); return(1); } Amp=mad_f_tofixed(AmpFactor); } else /* Use the phone-like filter if the argument is the * * 'phone' string. Look at the comment of the case marked * {6} in the Unix section for details. */ if(strcmp(argv[i],"phone")==0) { if(DoPhoneFilter) { fprintf(stderr,"%s: the phone-line simulation option " "was already set.\n",ProgName); return(1); } DoPhoneFilter=1; } else { /* The argument is not a recognized one. Print the * usage guidelines and stop there. */ PrintUsage(); return(1); } } #endif /* HAVE_GETOPT */ /* Initialize the subband-domain filter coefficients to one if * filtering is requested. */ if(Amp!=MAD_F_ONE || DoPhoneFilter) for(i=0;i<32;i++) Filter[i]=MAD_F_ONE; /* The amplification/attenuation is applied to the subband-domain * filter definition. */ if(Amp!=MAD_F_ONE) { DoFilter=1; for(i=0;i<32;i++) Filter[i]=Amp; } /* The telephone-like filter is applied to the subband-domain * filter definition. All subbands are set to zero except bands 2 * to 6. This programs author has no access to the MPEG audio * specification, he does not know the frequencies bands covered * by the MPEG subbands. */ if(DoPhoneFilter) { DoFilter=1; Filter[0]=MAD_F(0); for(i=5;i<32;i++) Filter[i]=MAD_F(0); } /* Command-line arguments are okay. */ return(0); }