-
Notifications
You must be signed in to change notification settings - Fork 0
/
options.c
222 lines (197 loc) · 6.68 KB
/
options.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <getopt.h>
#include "main.h"
#include "options.h"
/*
* Processes the command-line options.
*/
void options(int argc, char *argv[], ga_settings *settings)
{
int c;
int fail = 0;
// Default settings
settings->device_id = -1;
settings->input_type = INPUT_NONE;
for (;;)
{
// Create the options struct
static struct option long_options[] =
{
{"device", required_argument, NULL, 'd'},
{"stdin", no_argument, NULL, 256},
{"file", required_argument, NULL, 257},
{"port", required_argument, NULL, 'p'},
{"spc", required_argument, NULL, 'a'},
{"batchsize", required_argument, NULL, 'b'},
{"bins", required_argument, NULL, 'n'},
{"loops", required_argument, NULL, 'g'},
{"encoding", required_argument, NULL, 'e'},
{"channels", required_argument, NULL, 'c'},
{NULL, 0, NULL, 0}
};
int option_index = 0;
c = getopt_long(argc, argv, "d:p:a:b:n:g:e:c:", long_options,
&option_index);
// No more options, exit the loop
if (c == -1)
{
break;
}
// Set the variables in the opt struct
switch (c)
{
case 'd':
settings->device_id = atoi(optarg);
break;
case 256:
if (settings->input_type != INPUT_NONE)
{
fprintf(stderr, "Input type has been specified multiple "
"times\n");
exit(EXIT_FAILURE);
}
settings->input_type = INPUT_STDIN;
break;
case 257:
if (settings->input_type != INPUT_NONE)
{
fprintf(stderr, "Input type has been specified multiple "
"times\n");
exit(EXIT_FAILURE);
}
settings->input_type = INPUT_FILE;
settings->input_file = malloc(strlen(optarg)+1);
strcpy(settings->input_file, optarg);
break;
case 'p':
if (settings->input_type != INPUT_NONE)
{
fprintf(stderr, "Input type has been specified multiple "
"times\n");
exit(EXIT_FAILURE);
}
settings->input_type = INPUT_NETWORK;
settings->port = atoi(optarg);
break;
case 'a':
settings->spc = 1 << atoi(optarg);
break;
case 'b':
settings->batch_size = 1 << atoi(optarg);
break;
case 'n':
settings->bins = 1 << atoi(optarg);
break;
case 'g':
settings->loops = atoi(optarg);
break;
case 'e':
if (strcmp(optarg, "vlba") == 0 || strcmp(optarg, "VLBA") == 0)
{
settings->encoding = ENC_VLBA;
}
else if (strcmp(optarg, "at") == 0 ||
strcmp(optarg, "AT") == 0)
{
settings->encoding = ENC_AT;
}
else
{
fprintf(stderr, "Encoding must be one of: vlba, at\n");
exit(EXIT_FAILURE);
}
break;
case 'c':
settings->channels = atoi(optarg);
break;
case '?':
default:
fail = 1;
break;
}
}
// In the event of invalid options, print an error and exit
if (fail)
{
fprintf(stderr, "Invalid command-line options supplied\n");
exit(EXIT_FAILURE);
}
// If there is an extra argument
if (optind == argc-1)
{
// If the input type has already been specified
if (settings->input_type != INPUT_NONE)
{
fprintf(stderr, "Input type has been specified multiple times\n");
exit(EXIT_FAILURE);
}
// Take the extra argument as the input filename
settings->input_type = INPUT_FILE;
settings->input_file = malloc(strlen(argv[optind])+1);
strcpy(settings->input_file, argv[optind]);
}
else if(optind < argc-1)
{
// No support for multiple input files
fprintf(stderr, "Only one input file may be specified\n");
exit(EXIT_FAILURE);
}
if (settings->input_type == INPUT_NONE)
{
// If no input type specified, assume input type is stdin
settings->input_type = INPUT_STDIN;
}
// Ensure spc, batch_size and bins are all specified
if (settings->spc != 0 && settings->batch_size != 0 && settings->bins != 0)
{
// If all three are specified, but incorrectly
if (settings->spc != (settings->bins)*(settings->batch_size))
{
fprintf(stderr, "Samples per channel != bins * batch size\n");
exit(EXIT_FAILURE);
}
}
else if (settings->spc == 0)
{
// Determine the number of samples per channel
settings->spc = (settings->bins)*(settings->batch_size);
}
else if (settings->batch_size == 0)
{
// Determine the batch size
settings->batch_size = (settings->spc)/(settings->bins);
}
else if (settings->bins == 0)
{
// Determine the number of FFT bins
settings->bins = (settings->spc)/(settings->batch_size);
}
// If one or more is still equal to zero
if (settings->spc == 0 || settings->batch_size == 0 || settings->bins == 0)
{
fprintf(stderr, "Must specify at least two of options: -a, -b, -n\n");
exit(EXIT_FAILURE);
}
// Ensure spc > batch_size and bins
if (settings->spc < settings->batch_size)
{
fprintf(stderr, "Samples per channel must be greater than batch "
"size\n");
exit(EXIT_FAILURE);
}
else if (settings->spc < settings->bins)
{
fprintf(stderr, "Samples per channel must be greater than the number "
"of FFT bins\n");
exit(EXIT_FAILURE);
}
// TODO: If not specified, make sure they're determined from the header
settings->bps = 2;
// settings->channels = 8; (specified with -c for the moment)
// Calculate some other useful variables (requires the above variables)
settings->n = (settings->spc)*(settings->channels);
settings->bytes = (settings->n)*(settings->bps)/8;
settings->output_length = (settings->bins)/2*(settings->channels);
}