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