1 /*------------- Telecommunications & Signal Processing Lab -------------
2                            McGill University
3 
4 Routine:
5   void PQoptions (int argc, const char *argv[], struct PQ_Opt *Opt,
6                   struct PQ_FIpar FI[2])
7 
8 Purpose:
9   Decode options for PQevalAudio
10 
11 Description:
12   This routine decodes options for PQevalAudio.
13 
14 Parameters:
15    -> int argc
16       Number of command line arguments
17    -> const char *argv[]
18       Array of pointers to argument strings
19   <-  struct PQ_Opt *Opt
20       Processing options
21   <-  struct PQ_FIpar FI[2]
22       Input file parameters
23 
24 Author / revision:
25   P. Kabal  Copyright (C) 2003
26   $Revision: 1.9 $  $Date: 2003/05/13 01:12:06 $
27 
28 ----------------------------------------------------------------------*/
29 
30 #include <assert.h>
31 #include <string.h>
32 
33 #include <libtsp.h>
34 #include <AO.h>
35 #include "PQevalAudio.h"
36 
37 #define ERRSTOP(text,par)	UThalt ("%s: %s: \"%s\"", PROGRAM, text, par)
38 
39 static void
40 PQ_decOpt (const char String[], struct PQ_Opt *PQopt);
41 
42 /* Option table */
43 static const char *OptTable[] = {
44   "-L#", "--lev*elSPL=",
45   "-i#", "--i*nfo=",
46   "-o#", "--opt*ions=",
47   NULL
48 };
49 
50 
51 void
PQoptions(int argc,const char * argv[],struct PQ_Opt * PQopt,struct PQ_FIpar FI[2])52 PQoptions (int argc, const char *argv[], struct PQ_Opt *PQopt,
53 	   struct PQ_FIpar FI[2])
54 
55 {
56   struct PQ_FIpar FIx;
57   int n, nF, FIParSet;
58   const char *OptArg;
59 
60 /* Input file defaults */
61   FIParSet = 0;
62   FIpar_INIT (&FIx);
63 
64 /* Option defaults */
65   OPTIONS_INIT (PQopt);
66 
67 /* Initialization */
68   UTsetProg (PROGRAM);
69   nF = 0;
70 
71 /* Decode options */
72   AOinitOpt (argc, argv);
73   while (1) {
74 
75     /* Decode input file options */
76     n = AOdecFI (&FIx);
77     if (n >= 1) {
78       FIParSet = nF;
79       continue;
80     }
81 
82     /* Decode help options */
83     n = AOdecHelp (VERSION, PQMF_Usage);
84     if (n >= 1)
85       continue;
86 
87     /* Decode program options */
88     n = AOdecOpt (OptTable, &OptArg);
89     if (n == -1)
90       break;
91 
92     switch (n) {
93     case -2:
94       UThalt (PQMF_Usage, PROGRAM);
95       break;
96     case 0:
97       /* Filename argument */
98       ++nF;
99       if (nF > 2)
100 	UThalt ("%s: %s", PROGRAM, PQM_XFName);
101       STcopyMax (OptArg, FIx.Fname, FILENAME_MAX-1);
102       FI[nF-1] = FIx;
103       break;
104     case 1:
105     case 2:
106       /* Listening level */
107       if (STdec1double (OptArg, &PQopt->Lp))
108 	ERRSTOP (PQM_BadLevel, OptArg);
109       break;
110     case 3:
111     case 4:
112       /* Frame info */
113       if (STdec1int (OptArg, &PQopt->Ni))
114 	ERRSTOP (PQM_BadInfo, OptArg);
115       break;
116     case 5:
117     case 6:
118       /* Options */
119       PQ_decOpt (OptArg, PQopt);
120       break;
121     default:
122       assert (0);
123       break;
124     }
125   }
126 
127 /* Error checks */
128   if (nF == 0)
129     UThalt ("%s: %s", PROGRAM, PQM_NoFName);
130   if (FIParSet >= nF)
131     UThalt ("%s: %s", PROGRAM, PQM_LateFPar);
132 
133 /* Check for too many stdin specs */
134   AOstdin (FI, nF);
135 
136 /* Return values */
137   if (nF == 1)
138     FI[1].Fname[0] = '\0';
139 
140   return;
141 }
142 
143 /* Decode options keywords */
144 
145 #define WS_STRIP	1
146 
147 
148 static void
PQ_decOpt(const char String[],struct PQ_Opt * PQopt)149 PQ_decOpt (const char String[], struct PQ_Opt *PQopt)
150 
151 {
152   int ind, nt;
153   const char *p;
154   char *token;
155 
156   static const char *keytable [] = {
157     "clip*_MOV",
158     "no_clip*_MOV",
159     "PC*_init",
160     "PD*_factor",
161     "overlap*_delay",
162     "no_overlap*_delay",
163     "data*_bounds",
164     "no_data*_bounds",
165     "end*_min",
166     "EHS*_lag_start",
167     NULL
168   };
169 
170 /* Allocate temporary storage */
171   nt = strlen (String);
172   token = (char *) UTmalloc (nt + 1);
173 
174 /* Separate the parameters */
175   p = String;
176   while (p != NULL) {
177     p = STfindToken (p, ",", "\"\"", token, WS_STRIP, nt);
178     if (token[0] != '\0') {
179 
180       /* Decode the parameter values */
181       ind = STkeyXpar (token, "=", "\"\"", keytable, token);
182       if (ind < 0)
183 	ERRSTOP (PQM_BadKey, token);
184 
185       switch (ind) {
186 
187       /* clip_MOV */
188       case 0:
189 	PQopt->ClipMOV = 1;
190 	break;
191 
192       /* no_clip_MOV */
193       case 1:
194 	PQopt->ClipMOV = 0;
195 	break;
196 
197       /* PC_init = */
198       case 2:
199 	if (STdec1double (token, &PQopt->PCinit))
200 	  ERRSTOP (PQM_BadPCinit, token);
201 	break;
202 
203       /*  PD_factor = */
204       case 3:
205 	if (STdec1double (token, &PQopt->PDfactor))
206 	  ERRSTOP (PQM_BadPDfactor, token);
207 	break;
208 
209       /* overlap_delay */
210       case 4:
211 	PQopt->OverlapDelay = 1;
212 	break;
213 
214       /* no_overlap_delay */
215       case 5:
216 	PQopt->OverlapDelay = 0;
217 	break;
218 
219       /* data_bounds */
220       case 6:
221 	PQopt->DataBounds = 1;
222 	break;
223 
224       /* no_data_bounds */
225       case 7:
226 	PQopt->DataBounds = 0;
227 	break;
228 
229       /* end_min */
230       case 8:
231 	if (STdec1int (token, &PQopt->EndMin) ||
232 	    PQopt->EndMin <=0 || PQopt->EndMin > PQ_NF)
233 	  ERRSTOP (PQM_BadEndMin, token);
234 	break;
235 
236       /* EHS_lag_start */
237       case 9:
238 	if (STdec1int (token, &PQopt->EHSLagStart) ||
239 	    PQopt->EHSLagStart < 0 || PQopt->EHSLagStart > 1)
240 	  ERRSTOP (PQM_BadEHSStart, token);
241 	break;
242       }
243     }
244   }
245   UTfree ((void *) token);
246 
247   return;
248 }
249