1 /*------------- Telecommunications & Signal Processing Lab -------------
2                            McGill University
3 
4 Routine:
5   int AOdecFO (struct AO_FOpar *FO)
6 
7 Purpose:
8   Decode output audio file options for audio utilities
9 
10 Description:
11   This routine decodes an option for an output audio file.  The routine
12   AOinitOpt must be called first to initialize the option arguments.  If this
13   routine fails to find an input audio file option, the argument pointer is
14   reset to allow another routine to try to decode the option.
15 
16 Parameters:
17   <-  int AOdecFO
18          -1 - End of arguments/options
19           0 - Option not found
20         >=1 - Option code
21   <-> struct AO_FOpar *FO
22       Output file parameters
23 
24 Author / revision:
25   P. Kabal  Copyright (C) 2003
26   $Revision: 1.18 $  $Date: 2003/11/04 12:50:33 $
27 
28 ----------------------------------------------------------------------*/
29 
30 #include <string.h>
31 
32 #include <libtsp.h>
33 #define AF_DATA_LENGTHS
34 #include <libtsp/AFpar.h>
35 #include <AO.h>
36 
37 #define ROUTINE		"AOdecFO"
38 #define PGM		((UTgetProg ())[0] == '\0' ? ROUTINE : UTgetProg ())
39 #define ERRSTOP(text,par)	UThalt ("%s: %s: \"%s\"", PGM, text, par)
40 #define NELEM(array)	((sizeof array) / (sizeof array[0]))
41 
42 #define RET_ERROR	-2
43 #define RET_END		-1
44 
45 static const char *OTFO[] = {
46   "-n#", "--n*umber_samples=",
47   "-s#", "--sr*ate=",
48   "-D#", "--d*ata_format=",
49   "-F#", "--f*ile_type=",
50   "-S#", "--sp*eakers=",
51   "-I#", "--i*nfo=",
52   "**",
53   NULL
54 };
55 
56 static struct AO_dformat
57 AO_decDFormat (const char string[]);
58 static int
59 AO_decFType (const char string[]);
60 
61 /*
62   For certain options, the corresponding item in the audio file options
63   structure is set.  These options will be picked up when an output file
64   is opened.
65     Speaker locations: The corresponding audio file option is set, viz.
66       (AFoptions())->SpkrConfig
67     Data format, number of bits/sample: The corresponding audio file option
68     is set, viz.
69       (AFoptions())->NbS
70     Information string: The corresponding audio file option is set, viz.
71       (AFoptions())->InfoS
72 */
73 
74 
75 int
AOdecFO(struct AO_FOpar * FO)76 AOdecFO (struct AO_FOpar *FO)
77 
78 {
79   const char *OptArg;
80   int n, Sindex;
81   double Nv, Dv;
82   struct AO_CmdArg *Carg;
83   struct AF_opt *AFopt;
84 
85   Carg = AOArgs ();
86   AFopt = AFoptions ();
87 
88   if (Carg->EndOptions)
89     return 0;
90 
91   /* Decode output file options */
92   Sindex = Carg->Index;
93   n = UTgetOption (&Carg->Index, Carg->Argc, Carg->Argv, OTFO, &OptArg);
94 
95   switch (n) {
96   case RET_END:
97     break;
98   case RET_ERROR:
99     UThalt ("%s: %s", PGM, AOM_BadOption);
100     break;
101   case 1:
102   case 2:
103     /* Number of frames */
104     if (STdec1long (OptArg, &FO->Nframe) || FO->Nframe <= 0L)
105       ERRSTOP (AOM_BadNFrame, OptArg);
106     break;
107   case 3:
108   case 4:
109     /* Sampling rate */
110     if (STdecDfrac (OptArg, &Nv, &Dv) || Nv / Dv <= 0.0)
111       ERRSTOP (AOM_BadSFreq, OptArg);
112     FO->Sfreq = Nv / Dv;
113     break;
114   case 5:
115   case 6:
116     /* Data format */
117     FO->DFormat = AO_decDFormat (OptArg);
118     AFopt->NbS = FO->DFormat.NbS;
119     break;
120   case 7:
121   case 8:
122     /* File types */
123     FO->Ftype = AO_decFType (OptArg);
124     break;
125   case 9:
126   case 10:
127     /* Speaker positions */
128     if (AFsetSpeaker (OptArg))
129       ERRSTOP (AOM_BadSpkr, OptArg);
130     if (AFopt->SpkrConfig != NULL) {
131       UTfree (FO->SpkrConfig);
132       FO->SpkrConfig = (unsigned char *)
133 	UTmalloc (strlen ((const char *) AFopt->SpkrConfig) + 1);
134       strcpy ((char *) FO->SpkrConfig, (const char *) AFopt->SpkrConfig);
135     }
136     break;
137   case 11:
138   case 12:
139     /* Information string */
140     FO->Info = OptArg;
141     AFsetInfo (OptArg);
142     break;
143   default:
144     Carg->Index = Sindex;		/* Reset the index */
145     n = 0;
146     break;
147   }
148 
149   return n;
150 }
151 
152 /*-------------- Telecommunications & Signal Processing Lab ---------------
153                              McGill University
154 
155 Routine:
156   int AO_decFType (const char string[])
157 
158 Purpose:
159   Decode an audio file type specification
160 
161 Description:
162   This routine decodes an audio file type specification, returning the
163   corresponding file type code.  In the case of an invalid specification, this
164   routine stops with an error message.  For use in the error message, the
165   program name should be set using the routine UTsetProg.
166 
167 Parameters:
168   <-  int AO_decFType
169       File type code
170    -> const char string[]
171       Input audio file type specifier
172 
173 Author / revision:
174   P. Kabal  Copyright (C) 2003
175   $Revision: 1.18 $  $Date: 2003/11/04 12:50:33 $
176 
177 -------------------------------------------------------------------------*/
178 
179 static const char *FTypeTab[] = {
180   "AU", "au", "AFsp", "Sun", "sun",
181   "W*AVE", "w*ave",
182   "WAVE-NOEX", "wave-noex",
183   "AIFF", "aiff",
184   "AI*FF-C", "ai*ff-c",	/* Short forms go to AIFF-C rather than AIFF */
185   "nohead*er_native",
186   "noheader_s*wap",
187   "noheader_b*ig-endian",
188   "noheader_l*ittle-endian",
189   NULL
190 };
191 #define NFTYPE		(NELEM (FTypeTab) - 1)
192 static const int FTypeCode[NFTYPE] = {
193   FTW_AU, FTW_AU, FTW_AU, FTW_AU, FTW_AU,
194   FTW_WAVE, FTW_WAVE,
195   FTW_WAVE_NOEX, FTW_WAVE_NOEX,
196   FTW_AIFF, FTW_AIFF,
197   FTW_AIFF_C, FTW_AIFF_C,
198   FTW_NH_NATIVE,
199   FTW_NH_SWAP,
200   FTW_NH_EB,
201   FTW_NH_EL
202 };
203 
204 
205 static int
AO_decFType(const char string[])206 AO_decFType (const char string[])
207 
208 {
209   int n;
210 
211   n = STkeyMatch (string, FTypeTab);
212   if (n < 0)
213     UThalt ("%s: %s: \"%s\"", PGM, AOM_BadFType, string);
214 
215   return FTypeCode[n];
216 }
217 
218 /*-------------- Telecommunications & Signal Processing Lab ---------------
219                              McGill University
220 
221 Routine:
222   struct AO_dformat AO_decDFormat (const char string[])
223 
224 Purpose:
225   Decode an audio file data format specification
226 
227 Description:
228   This routine decodes an audio file data format specification, returning the
229   corresponding data format code.  In the case of an invalid specification,
230   this routine stops with an error message.  For use in the error message, the
231   program name should be set using the routine UTsetProg.
232 
233 Parameters:
234   <-  struct AO_dformat AOdecDFormat
235       Data format structure
236    -> const char string[]
237       Input data format specifier
238 
239 Author / revision:
240   P. Kabal  Copyright (C) 2003
241   $Revision: 1.18 $  $Date: 2003/11/04 12:50:33 $
242 
243 -------------------------------------------------------------------------*/
244 
245 static const char *DFormatTab[NFD] = {
246   "m*u-law8",
247   "A*-law8",
248   "u*nsigned8",
249   "integer8",
250   "i*nteger16",
251   "integer24",
252   "integer32",
253   "f*loat32",
254   "float64",
255   "t*ext",
256   NULL
257 };
258 static const int DFormatCode[NFD-1] = {
259   FD_MULAW8,
260   FD_ALAW8,
261   FD_UINT8,
262   FD_INT8,
263   FD_INT16,
264   FD_INT24,
265   FD_INT32,
266   FD_FLOAT32,
267   FD_FLOAT64,
268   FD_TEXT
269 };
270 
271 static struct AO_dformat
AO_decDFormat(const char string[])272 AO_decDFormat (const char string[])
273 
274 {
275   int n, Format, Res, NbS;
276   char *Par;
277   struct AO_dformat DFormat;
278 
279   Par = (char *) UTmalloc (strlen (string));
280   n = STkeyXpar (string, "/", "", DFormatTab, Par);
281   if (n < 0)
282     UThalt ("%s: %s: \"%s\"", PGM, AOM_BadData, string);
283   Format = DFormatCode[n];
284 
285   Res = 8 * AF_DL[Format];
286   NbS = Res;
287   if (strlen (Par) > 0) {
288     STdec1int (Par, &NbS);
289     if (NbS <= 0 || NbS > Res)
290       UThalt ("%s: %s: \"%s\"", PGM, AOM_InvNbS, NbS);
291   }
292 
293   DFormat.Format = Format;
294   DFormat.NbS = NbS;
295 
296   UTfree (Par);
297 
298   return DFormat;
299 }
300