/*------------- Telecommunications & Signal Processing Lab ------------- McGill University Routine: void CPoptions (int argc, const char *argv[], int *Fformat, float *SfreqO, long int Lim[2], const char *NHparms[MAXIFILE], const char **Hinfo, float Chgain[MAXCHANO][MAXCHANI], long int *NchanO, const char *Fname[MAXFILE], int *Nfiles) Purpose: Decode options for CopyAudio Description: This routine decodes options for CopyAudio. Parameters: -> int argc Number of command line arguments -> const char *argv[] Array of pointers to argument strings <- int *Fformat Output file format code <- float *SfreqO Output file sampling frequency <- long int Lim[2] Sample limits, set to (0, -1) if not explicitly specified <- const char *NHparms[MAXIFILE] Parameters for headerless input files, default NULL <- const char **Hinfo Header information string, default NULL <- float Chgain[MAXCHANO][MAXCHANI] Array of channel gains. If NchanO is zero, Chgain[0][0] is the gain to be applied to all channels. <- long int *NchanO Number of output channels, zero if the individual channel gains have not been specified <- const char *Fname[MAXFILE] File names <- int *Nfiles Number of input file names Author / revision: P. Kabal Copyright (C) 1996 $Revision: 1.47 $ $Date: 1996/08/16 16:10:33 $ ----------------------------------------------------------------------*/ static char rcsid[] = "$Id: CPoptions.c 1.47 1996/08/16 AFsp-V2R1 $"; #include /* prototype for exit */ #include #include #include #include "CopyAudio.h" #include "AO.h" #ifndef EXIT_SUCCESS # define EXIT_SUCCESS 0 /* Normally in stdlib.h */ #endif #define ERRSTOP(text,par) UThalt ("%s: %s: \"%s\"", PROGRAM, text, par) #define NELEM(array) ((sizeof array) / (sizeof array[0])) /* Option tables and usage message */ #define CHST 8 /* Count for first channel gain option */ #define LOPT (NELEM (OptTable) / 2) static const char *nullTable[] = { NULL }; static const char *OptTable[] = { "-s#", "--sr*ate=", "-l#", "--l*imits=", "-D#", "--d*ata_format=", "-F#", "--f*ile_type=", "-P#", "--p*arameters=", "-I#", "--i*nfo=", "-g#", "--g*ain=", "-cA#", "--chanA=", "-cB#", "--chanB=", "-cC#", "--chanC=", "-cD#", "--chanD=", "-cE#", "--chanE=", "-cF#", "--chanF=", "-cG#", "--chanG=", "-cH#", "--chanH=", "-cI#", "--chanI=", "-cJ#", "--chanJ=", "-cK#", "--chanK=", "-cL#", "--chanL=", "-h", "--h*elp", "-v", "--v*ersion", "--", NULL }; static const char Usage[] = "\ Usage: %s [options] AFileI1 AFileI2 ... AFileO\n\ Options:\n\ -s SFREQ, --srate=SFREQ Sampling frequency for the output file.\n\ -l L:U, --limits=L:U Frame limits.\n\ -D DFORMAT, --data_format=DFORMAT Data format for the output file,\n\ \"mu-law\", \"A-law\", \"unsigned8\", \"integer8\",\n\ \"integer16\", \"float\", or \"text\".\n\ -F FTYPE, --file_type=FTYPE Output file type, \"AFsp\", \"WAVE\", \"AIFF-C\",\n\ \"raw\", or \"raw_swap\".\n\ -g GAIN, --gain=GAIN Gain factor for all input channels.\n\ -cA GAINS, --chanA=GAINS Gain factors for output channel A.\n\ ... ...\n\ -cL GAINS, --chanL=GAINS Gain factors for output channel L.\n\ -P PARMS, --parameters=PARMS Parameters for headerless input files.\n\ -I INFO, --info=INFO Header information string.\n\ -h, --help Print a list of options and exit.\n\ -v, --version Print the version number and exit."; static const char Ch[MAXCHANO+1] = "ABCDEFGHIJKL"; void CPoptions (argc, argv, Fformat, SfreqO, Lim, NHparms, Hinfo, Chgain, NchanO, Fname, Nfiles) int argc; const char *argv[]; int *Fformat; float *SfreqO; long int Lim[2]; const char *NHparms[MAXIFILE]; const char **Hinfo; float Chgain[MAXCHANO][MAXCHANI]; long int *NchanO; const char *Fname[MAXFILE]; int *Nfiles; { int Index; const char *OptArg; const char **optt; int nF, i, n, nn; int Chset[MAXCHANO]; float Sfreq; long int limL, limU; const char *NHp; int gainset; float gain; int Dformat, Ftype; long int Nchan; /* Consistency check */ if (LOPT - 2 != CHST + MAXCHANO) UThalt("CPoptions: Internal consistency check failed"); /* Defaults */ Sfreq = 0.0; NHp = NULL; gain = 1.0; gainset = 0; limL = 0; limU = -1; Dformat = FD_UNDEF; Ftype = FW_AFSP; *Hinfo = NULL; for (i = 0; i < MAXCHANO; ++i) { Chset[i] = 0; VRfZero (Chgain[i], MAXCHANI); if (i < MAXCHANI) Chgain[i][i] = 1.0; } /* Initialization */ UTsetProg (PROGRAM); nF = 0; /* Decode options */ Index = 1; optt = OptTable; while (Index < argc) { n = UTgetOption (&Index, argc, argv, optt, &OptArg); nn = ((n + 3) / 2) - 1; /* n = -2 ==> nn = -1 */ switch (nn) { case 0: /* Filename argument */ ++nF; if (nF <= MAXFILE) Fname[nF-1] = OptArg; else UThalt ("%s: Too many filenames specified", PROGRAM); if (nF < MAXIFILE) NHparms[nF-1] = NHp; break; case 1: /* Sampling rate */ if (STdec1float (OptArg, &Sfreq) || Sfreq <= 0.0) ERRSTOP ("Invalid sampling frequency", OptArg); break; case 2: /* Limits specification */ if (STdecLrange (OptArg, &limL, &limU) || limL > limU) ERRSTOP ("Invalid limits specification", OptArg); break; case 3: /* Data format */ Dformat = AOdecDFormat (OptArg); break; case 4: /* File types */ Ftype = AOdecFType (OptArg); break; case 5: /* Headerless input parameters */ NHp = OptArg; break; case 6: /* Header information string */ *Hinfo = OptArg; break; case 7: /* Gain for all channels */ if (STdec1float (OptArg, &gain)) ERRSTOP ("Invalid gain value", OptArg); gainset = 1; break; case CHST: case CHST+1: case CHST+2: case CHST+3: case CHST+4: case CHST+5: case CHST+6: case CHST+7: case CHST+8: case CHST+9: case CHST+10: case CHST+11: /* Channel gain expressions */ i = nn - CHST; CPdecChan (OptArg, Chgain[i]); Chset[i] = 1; break; case LOPT-2: /* Help */ UTwarn (Usage, PROGRAM); exit (EXIT_SUCCESS); break; case LOPT-1: /* Version */ printf ("%s: %s\n", PROGRAM, VERSION); exit (EXIT_SUCCESS); break; case LOPT: /* Stop interpreting options */ optt = nullTable; break; default: /* Option error */ UThalt (Usage, PROGRAM); break; } } /* Checks, add defaults */ if (nF < 2) UThalt ("%s: Too few files specified", PROGRAM); for (i = MAXCHANO - 1; i >= 0; --i) { if (Chset[i] != 0) break; } Nchan = i + 1; for (i = 0; i < Nchan - 1; ++i) { if (Chset[i] == 0) UThalt ("%s: No specification for output channel %c", PROGRAM, Ch[i]); } if (Nchan != 0 && gainset) UThalt ("%s: Global gain and channel gain options are incompatible"); if (gainset) Chgain[0][0] = gain; /* Set return values */ *Fformat = Dformat + Ftype; *SfreqO = Sfreq; Lim[0] = limL; Lim[1] = limU; *NchanO = Nchan; *Nfiles = nF; return; }