1 /* Handle uade.conf file
2
3 Copyright (C) 2005 Heikki Orsila <heikki.orsila@iki.fi>
4
5 This source code module is dual licensed under GPL and Public Domain.
6 Hence you may use _this_ module (not another code module) in any way you
7 want in your projects.
8 */
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <ctype.h>
13 #include <string.h>
14 #include <assert.h>
15 #include <limits.h>
16 #include <unistd.h>
17 #include <sys/stat.h>
18 #include <sys/types.h>
19 #include <unistd.h>
20
21 #include "ossupport.h"
22 #include "uadeconf.h"
23 #include "uadeconfig.h"
24 #include "amigafilter.h"
25 #include "uadeconstants.h"
26 #include "songdb.h"
27 #include "uadeutils.h"
28 #include "support.h"
29
30 static int uade_set_silence_timeout(struct uade_config *uc, const char *value);
31 static int uade_set_subsong_timeout(struct uade_config *uc, const char *value);
32 static int uade_set_timeout(struct uade_config *uc, const char *value);
33
34
35 struct uade_conf_opts {
36 char *str;
37 int l;
38 enum uade_option e;
39 };
40
41 /* List of uade.conf options. The list includes option name, minimum
42 string match length for the option name and its enum code. */
43 static const struct uade_conf_opts uadeconfopts[] = {
44 {.str = "action_keys", .l = 2, .e = UC_ACTION_KEYS},
45 {.str = "ao_option", .l = 2, .e = UC_AO_OPTION},
46 {.str = "buffer_time", .l = 1, .e = UC_BUFFER_TIME},
47 {.str = "cygwin", .l = 1, .e = UC_CYGWIN_DRIVE_WORKAROUND},
48 {.str = "detect_format_by_detection", .l = 18, .e = UC_CONTENT_DETECTION},
49 {.str = "disable_timeout", .l = 1, .e = UC_DISABLE_TIMEOUTS},
50 {.str = "enable_timeout", .l = 2, .e = UC_ENABLE_TIMEOUTS},
51 {.str = "ep_option", .l = 2, .e = UC_EAGLEPLAYER_OPTION},
52 {.str = "filter_type", .l = 2, .e = UC_FILTER_TYPE},
53 {.str = "force_led_off", .l = 12, .e = UC_FORCE_LED_OFF},
54 {.str = "force_led_on", .l = 12, .e = UC_FORCE_LED_ON},
55 {.str = "force_led", .l = 9, .e = UC_FORCE_LED},
56 {.str = "frequency", .l = 2, .e = UC_FREQUENCY},
57 {.str = "gain", .l = 1, .e = UC_GAIN},
58 {.str = "headphones", .l = 11, .e = UC_HEADPHONES},
59 {.str = "headphones2", .l = 11, .e = UC_HEADPHONES2},
60 {.str = "headphone", .l = 11, .e = UC_HEADPHONES},
61 {.str = "ignore_player_check", .l = 2, .e = UC_IGNORE_PLAYER_CHECK},
62 {.str = "interpolator", .l = 2, .e = UC_RESAMPLER},
63 {.str = "magic_detection", .l = 1, .e = UC_CONTENT_DETECTION},
64 {.str = "no_ep_end_detect", .l = 4, .e = UC_NO_EP_END},
65 {.str = "no_filter", .l = 4, .e = UC_NO_FILTER},
66 {.str = "no_song_end", .l = 4, .e = UC_NO_EP_END},
67 {.str = "normalise", .l = 1, .e = UC_NORMALISE},
68 {.str = "ntsc", .l = 2, .e = UC_NTSC},
69 {.str = "one_subsong", .l = 1, .e = UC_ONE_SUBSONG},
70 {.str = "pal", .l = 3, .e = UC_PAL},
71 {.str = "panning_value", .l = 3, .e = UC_PANNING_VALUE},
72 {.str = "random_play", .l = 3, .e = UC_RANDOM_PLAY},
73 {.str = "recursive_mode", .l = 3, .e = UC_RECURSIVE_MODE},
74 {.str = "resampler", .l = 3, .e = UC_RESAMPLER},
75 {.str = "silence_timeout_value", .l = 2, .e = UC_SILENCE_TIMEOUT_VALUE},
76 {.str = "song_title", .l = 2, .e = UC_SONG_TITLE},
77 {.str = "speed_hack", .l = 2, .e = UC_SPEED_HACK},
78 {.str = "subsong_timeout_value", .l = 2, .e = UC_SUBSONG_TIMEOUT_VALUE},
79 {.str = "timeout_value", .l = 1, .e = UC_TIMEOUT_VALUE},
80 {.str = "verbose", .l = 1, .e = UC_VERBOSE},
81 {.str = NULL} /* END OF LIST */
82 };
83
84
85 /* Map an uade.conf option to an enum */
map_str_to_option(const char * key)86 static enum uade_option map_str_to_option(const char *key)
87 {
88 size_t i;
89
90 for (i = 0; uadeconfopts[i].str != NULL; i++) {
91 if (strncmp(key, uadeconfopts[i].str, uadeconfopts[i].l) == 0)
92 return uadeconfopts[i].e;
93 }
94
95 return 0;
96 }
97
98 /* The function sets the default options. No *_set variables are set because
99 we don't want any option to become mergeable by default. See
100 uade_merge_configs(). */
uade_config_set_defaults(struct uade_config * uc)101 void uade_config_set_defaults(struct uade_config *uc)
102 {
103 memset(uc, 0, sizeof(*uc));
104 uc->action_keys = 1;
105 strlcpy(uc->basedir.name, UADE_CONFIG_BASE_DIR, sizeof uc->basedir.name);
106 uade_set_filter_type(uc, NULL);
107 uc->frequency = UADE_DEFAULT_FREQUENCY;
108 uc->gain = 1.0;
109 uc->panning = 0.7;
110 uc->silence_timeout = 20;
111 uc->subsong_timeout = 512;
112 uc->timeout = -1;
113 uc->use_timeouts = 1;
114 }
115
uade_convert_to_double(const char * value,double def,double low,double high,const char * type)116 double uade_convert_to_double(const char *value, double def, double low,
117 double high, const char *type)
118 {
119 char *endptr, *newvalue;
120 char newseparator;
121 double v;
122
123 if (value == NULL)
124 return def;
125
126 v = strtod(value, &endptr);
127
128 /* Decimal separator conversion, if needed */
129 if (*endptr == ',' || *endptr == '.') {
130 newvalue = strdup(value);
131 if (newvalue == NULL)
132 uade_error("Out of memory\n");
133
134 newseparator = (*endptr == ',') ? '.' : ',';
135
136 newvalue[(intptr_t) endptr - (intptr_t) value] = newseparator;
137
138 v = strtod(newvalue, &endptr);
139 free(newvalue);
140 }
141
142 if (*endptr != 0 || v < low || v > high) {
143 fprintf(stderr, "Invalid %s value: %s\n", type, value);
144 v = def;
145 }
146
147 return v;
148 }
149
uade_add_ep_option(struct uade_ep_options * opts,const char * s)150 static void uade_add_ep_option(struct uade_ep_options *opts, const char *s)
151 {
152 size_t freespace = sizeof(opts->o) - opts->s;
153
154 if (strlcpy(&opts->o[opts->s], s, freespace) >= freespace) {
155 fprintf(stderr, "Warning: uade eagleplayer option overflow: %s\n", s);
156 return;
157 }
158
159 opts->s += strlen(s) + 1;
160 }
161
handle_attributes(struct uade_config * uc,struct uade_song * us,char * playername,size_t playernamelen,int flags,struct uade_attribute * attributelist)162 static int handle_attributes(struct uade_config *uc, struct uade_song *us,
163 char *playername, size_t playernamelen,
164 int flags, struct uade_attribute *attributelist)
165 {
166 struct uade_attribute *a;
167 size_t i;
168
169 for (i = 0; epconf[i].s != NULL; i++) {
170
171 if (epconf[i].o == 0)
172 continue;
173
174 if ((flags & epconf[i].e) == 0)
175 continue;
176
177 uade_set_config_option(uc, epconf[i].o, epconf[i].c);
178 }
179
180 if (flags & ES_NEVER_ENDS)
181 fprintf(stderr, "uade: ES_NEVER_ENDS is not implemented. What should it do?\n");
182
183 if (flags & ES_REJECT)
184 return -1;
185
186 a = attributelist;
187
188 while (a != NULL) {
189
190 switch (a->type) {
191 case ES_EP_OPTION:
192 if (uc->verbose)
193 fprintf(stderr, "Using eagleplayer option %s\n", a->s);
194 uade_add_ep_option(&us->ep_options, a->s);
195 break;
196
197 case ES_GAIN:
198 uade_set_config_option(uc, UC_GAIN, a->s);
199 break;
200
201 case ES_RESAMPLER:
202 uade_set_config_option(uc, UC_RESAMPLER, a->s);
203 break;
204
205 case ES_PANNING:
206 uade_set_config_option(uc, UC_PANNING_VALUE, a->s);
207 break;
208
209 case ES_PLAYER:
210 if (playername) {
211 snprintf(playername, playernamelen, "%s/players/%s", uc->basedir.name, a->s);
212 } else {
213 fprintf(stderr, "Error: attribute handling was given playername == NULL.\n");
214 }
215 break;
216
217 case ES_SILENCE_TIMEOUT:
218 uade_set_config_option(uc, UC_SILENCE_TIMEOUT_VALUE, a->s);
219 break;
220
221 case ES_SUBSONGS:
222 fprintf(stderr, "Subsongs not implemented.\n");
223 break;
224
225 case ES_SUBSONG_TIMEOUT:
226 uade_set_config_option(uc, UC_SUBSONG_TIMEOUT_VALUE, a->s);
227 break;
228
229 case ES_TIMEOUT:
230 uade_set_config_option(uc, UC_TIMEOUT_VALUE, a->s);
231 break;
232
233 default:
234 fprintf(stderr, "Unknown song attribute integer: 0x%x\n", a->type);
235 break;
236 }
237
238 a = a->next;
239 }
240
241 return 0;
242 }
243
uade_set_song_attributes(struct uade_state * state,char * playername,size_t playernamelen)244 int uade_set_song_attributes(struct uade_state *state,
245 char *playername, size_t playernamelen)
246 {
247 struct uade_song *us = state->song;
248 struct uade_config *uc = &state->config;
249
250 if (us->normalisation)
251 uade_set_config_option(uc, UC_NORMALISE, us->normalisation);
252
253 return handle_attributes(uc, us, playername, playernamelen,
254 us->flags, us->songattributes);
255 }
256
uade_load_config(struct uade_config * uc,const char * filename)257 int uade_load_config(struct uade_config *uc, const char *filename)
258 {
259 char line[256];
260 FILE *f;
261 char *key, *value;
262 int linenumber = 0;
263 enum uade_option opt;
264
265 if ((f = fopen(filename, "r")) == NULL)
266 return 0;
267
268 uade_config_set_defaults(uc);
269
270 while (xfgets(line, sizeof(line), f) != NULL) {
271 linenumber++;
272
273 /* Skip comment lines */
274 if (line[0] == '#')
275 continue;
276
277 if (!get_two_ws_separated_fields(&key, &value, line))
278 continue; /* Skip an empty line */
279
280 opt = map_str_to_option(key);
281
282 if (opt) {
283 uade_set_config_option(uc, opt, value);
284 } else {
285 fprintf(stderr, "Unknown config key in %s on line %d: %s\n", filename, linenumber, key);
286 }
287 }
288
289 fclose(f);
290 return 1;
291 }
292
uade_load_initial_config(char * uadeconfname,size_t maxlen,struct uade_config * uc,struct uade_config * ucbase)293 int uade_load_initial_config(char *uadeconfname, size_t maxlen,
294 struct uade_config *uc, struct uade_config *ucbase)
295 {
296 int loaded;
297 char *home;
298
299 assert(maxlen > 0);
300 uadeconfname[0] = 0;
301
302 uade_config_set_defaults(uc);
303
304 loaded = 0;
305
306 /* First try to load from forced base dir (testing mode) */
307 if (ucbase != NULL && ucbase->basedir_set) {
308 snprintf(uadeconfname, maxlen, "%s/uade.conf",
309 ucbase->basedir.name);
310 loaded = uade_load_config(uc, uadeconfname);
311 }
312
313 home = uade_open_create_home();
314
315 /* Second, try to load config from ~/.uade2/uade.conf */
316 if (loaded == 0 && home != NULL) {
317 snprintf(uadeconfname, maxlen, "%s/.uade2/uade.conf", home);
318 loaded = uade_load_config(uc, uadeconfname);
319 }
320
321 /* Third, try to load from install path */
322 if (loaded == 0) {
323 snprintf(uadeconfname, maxlen, "%s/uade.conf",
324 uc->basedir.name);
325 loaded = uade_load_config(uc, uadeconfname);
326 }
327
328 return loaded;
329 }
330
uade_load_initial_song_conf(char * songconfname,size_t maxlen,struct uade_config * uc,struct uade_config * ucbase)331 int uade_load_initial_song_conf(char *songconfname, size_t maxlen,
332 struct uade_config *uc,
333 struct uade_config *ucbase)
334 {
335 int loaded = 0;
336 char *home;
337
338 assert(maxlen > 0);
339 songconfname[0] = 0;
340
341 /* Used for testing */
342 if (ucbase != NULL && ucbase->basedir_set) {
343 snprintf(songconfname, maxlen, "%s/song.conf",
344 ucbase->basedir.name);
345 loaded = uade_read_song_conf(songconfname);
346 }
347
348 /* Avoid unwanted home directory creation for test mode */
349 if (loaded)
350 return loaded;
351
352 home = uade_open_create_home();
353
354 /* Try to load from home dir */
355 if (loaded == 0 && home != NULL) {
356 snprintf(songconfname, maxlen, "%s/.uade2/song.conf", home);
357 loaded = uade_read_song_conf(songconfname);
358 }
359
360 /* No? Try install path */
361 if (loaded == 0) {
362 snprintf(songconfname, maxlen, "%s/song.conf",
363 uc->basedir.name);
364 loaded = uade_read_song_conf(songconfname);
365 }
366
367 return loaded;
368 }
369
uade_merge_configs(struct uade_config * ucd,const struct uade_config * ucs)370 void uade_merge_configs(struct uade_config *ucd, const struct uade_config *ucs)
371 {
372 #define MERGE_OPTION(y) do { if (ucs->y##_set) ucd->y = ucs->y; } while (0)
373
374 MERGE_OPTION(action_keys);
375 MERGE_OPTION(ao_options);
376 MERGE_OPTION(basedir);
377 MERGE_OPTION(buffer_time);
378 MERGE_OPTION(content_detection);
379 MERGE_OPTION(cygwin_drive_workaround);
380 MERGE_OPTION(ep_options);
381 MERGE_OPTION(filter_type);
382 MERGE_OPTION(frequency);
383 MERGE_OPTION(gain);
384 MERGE_OPTION(gain_enable);
385 MERGE_OPTION(headphones);
386 MERGE_OPTION(headphones2);
387 MERGE_OPTION(ignore_player_check);
388 MERGE_OPTION(led_forced);
389 MERGE_OPTION(led_state);
390 MERGE_OPTION(no_ep_end);
391 MERGE_OPTION(no_filter);
392 MERGE_OPTION(no_postprocessing);
393
394 /* Special merge -> don't use MERGE_OPTION macro */
395 if (ucs->normalise_set && ucs->normalise) {
396 ucd->normalise = 1;
397 if (ucs->normalise_parameter != NULL)
398 ucd->normalise_parameter = ucs->normalise_parameter;
399 }
400
401 MERGE_OPTION(one_subsong);
402 MERGE_OPTION(panning);
403 MERGE_OPTION(panning_enable);
404 MERGE_OPTION(random_play);
405 MERGE_OPTION(recursive_mode);
406 MERGE_OPTION(resampler);
407 MERGE_OPTION(silence_timeout);
408 MERGE_OPTION(song_title);
409 MERGE_OPTION(speed_hack);
410 MERGE_OPTION(subsong_timeout);
411
412 MERGE_OPTION(timeout);
413 MERGE_OPTION(use_timeouts);
414 if (ucs->timeout_set) {
415 ucd->use_timeouts = 1;
416 ucd->use_timeouts_set = 1;
417 }
418
419 MERGE_OPTION(use_text_scope);
420 MERGE_OPTION(use_ntsc);
421 MERGE_OPTION(verbose);
422 }
423
uade_open_create_home(void)424 char *uade_open_create_home(void)
425 {
426 /* Create ~/.uade2 directory if it does not exist */
427 char *home = getenv("HOME");
428 if (home) {
429 char name[PATH_MAX];
430 struct stat st;
431 snprintf(name, sizeof name, "%s/.uade2", home);
432 if (stat(name, &st) != 0)
433 mkdir(name, S_IRUSR | S_IWUSR | S_IXUSR);
434 }
435
436 return home;
437 }
438
uade_parse_subsongs(int ** subsongs,char * option)439 int uade_parse_subsongs(int **subsongs, char *option)
440 {
441 char substr[256];
442 char *sp, *str;
443 size_t pos;
444 int nsubsongs;
445
446 nsubsongs = 0;
447 *subsongs = NULL;
448
449 if (strlcpy(substr, option, sizeof subsongs) >= sizeof subsongs) {
450 fprintf(stderr, "Too long a subsong option: %s\n", option);
451 return -1;
452 }
453
454 sp = substr;
455 while ((str = strsep(&sp, ",")) != NULL) {
456 if (*str == 0)
457 continue;
458 nsubsongs++;
459 }
460
461 *subsongs = malloc((nsubsongs + 1) * sizeof((*subsongs)[0]));
462 if (*subsongs == NULL) {
463 fprintf(stderr, "No memory for subsongs.\n");
464 return -1;
465 }
466
467 strlcpy(substr, option, sizeof subsongs);
468
469 pos = 0;
470 sp = substr;
471 while ((str = strsep(&sp, ",")) != NULL) {
472 if (*str == 0)
473 continue;
474 (*subsongs)[pos] = atoi(str);
475 pos++;
476 }
477
478 (*subsongs)[pos] = -1;
479 assert(pos == nsubsongs);
480
481 return nsubsongs;
482 }
483
uade_set_effects(struct uade_state * state)484 void uade_set_effects(struct uade_state *state)
485 {
486 struct uade_effect *effects = &state->effects;
487 struct uade_config *uc = &state->config;
488
489 uade_effect_set_defaults(effects);
490
491 if (uc->no_postprocessing)
492 uade_effect_disable(effects, UADE_EFFECT_ALLOW);
493
494 if (uc->gain_enable) {
495 uade_effect_gain_set_amount(effects, uc->gain);
496 uade_effect_enable(effects, UADE_EFFECT_GAIN);
497 }
498
499 if (uc->headphones)
500 uade_effect_enable(effects, UADE_EFFECT_HEADPHONES);
501
502 if (uc->headphones2)
503 uade_effect_enable(effects, UADE_EFFECT_HEADPHONES2);
504
505 if (uc->normalise) {
506 uade_effect_normalise_unserialise(uc->normalise_parameter);
507 uade_effect_enable(effects, UADE_EFFECT_NORMALISE);
508 }
509
510 if (uc->panning_enable) {
511 uade_effect_pan_set_amount(effects, uc->panning);
512 uade_effect_enable(effects, UADE_EFFECT_PAN);
513 }
514
515 uade_effect_set_sample_rate(effects, uc->frequency);
516 }
517
uade_set_config_option(struct uade_config * uc,enum uade_option opt,const char * value)518 void uade_set_config_option(struct uade_config *uc, enum uade_option opt,
519 const char *value)
520 {
521 char *endptr;
522 long x;
523
524 #define SET_OPTION(opt, value) do { uc->opt = (value); uc->opt##_set = 1; } while (0)
525
526 switch (opt) {
527 case UC_ACTION_KEYS:
528 if (value != NULL) {
529 uc->action_keys_set = 1;
530 if (!strcasecmp(value, "on") || !strcmp(value, "1")) {
531 uc->action_keys = 1;
532 } else if (!strcasecmp(value, "off") ||
533 !strcmp(value, "0")) {
534 uc->action_keys = 0;
535 } else {
536 fprintf(stderr,
537 "uade.conf: Unknown setting for action keys: %s\n",
538 value);
539 }
540 }
541 break;
542
543 case UC_AO_OPTION:
544 strlcat(uc->ao_options.o, value, sizeof uc->ao_options.o);
545 strlcat(uc->ao_options.o, "\n", sizeof uc->ao_options.o);
546 uc->ao_options_set = 1;
547 break;
548
549 case UC_BASE_DIR:
550 if (value != NULL) {
551 strlcpy(uc->basedir.name, value,
552 sizeof uc->basedir.name);
553 uc->basedir_set = 1;
554 } else {
555 fprintf(stderr, "uade: Passed NULL to UC_BASE_DIR.\n");
556 }
557 break;
558
559 case UC_BUFFER_TIME:
560 if (value != NULL) {
561 uc->buffer_time_set = 1;
562 uc->buffer_time = strtol(value, &endptr, 10);
563 if (uc->buffer_time <= 0 || *endptr != 0) {
564 fprintf(stderr, "Invalid buffer_time: %s\n",
565 value);
566 uc->buffer_time = 0;
567 }
568 } else {
569 fprintf(stderr,
570 "uade: Passed NULL to UC_BUFFER_TIME.\n");
571 }
572 break;
573
574 case UC_CONTENT_DETECTION:
575 SET_OPTION(content_detection, 1);
576 break;
577
578 case UC_CYGWIN_DRIVE_WORKAROUND:
579 SET_OPTION(cygwin_drive_workaround, 1);
580 break;
581
582 case UC_DISABLE_TIMEOUTS:
583 SET_OPTION(use_timeouts, 0);
584 break;
585
586 case UC_ENABLE_TIMEOUTS:
587 SET_OPTION(use_timeouts, 1);
588 break;
589
590 case UC_EAGLEPLAYER_OPTION:
591 if (value != NULL) {
592 uade_add_ep_option(&uc->ep_options, value);
593 uc->ep_options_set = 1;
594 } else {
595 fprintf(stderr,
596 "uade: Passed NULL to UC_EAGLEPLAYER_OPTION.\n");
597 }
598 break;
599
600 case UC_FILTER_TYPE:
601 SET_OPTION(no_filter, 0);
602
603 if (value != NULL) {
604 if (strcasecmp(value, "none") != 0) {
605 /* Filter != NONE */
606 uade_set_filter_type(uc, value);
607 uc->filter_type_set = 1;
608 } else {
609 /* Filter == NONE */
610 uc->no_filter = 1;
611 }
612 }
613 break;
614
615 case UC_FORCE_LED:
616 if (value == NULL) {
617 fprintf(stderr, "uade: UC_FORCE_LED value is NULL\n");
618 break;
619 }
620 if (strcasecmp(value, "off") == 0 || strcmp(value, "0") == 0) {
621 uc->led_state = 0;
622 } else if (strcasecmp(value, "on") == 0
623 || strcmp(value, "1") == 0) {
624 uc->led_state = 1;
625 } else {
626 fprintf(stderr, "Unknown force led argument: %s\n",
627 value);
628 break;
629 }
630 uc->led_state_set = 1;
631
632 SET_OPTION(led_forced, 1);
633 break;
634
635 case UC_FORCE_LED_OFF:
636 SET_OPTION(led_forced, 1);
637 SET_OPTION(led_state, 0);
638 break;
639
640 case UC_FORCE_LED_ON:
641 SET_OPTION(led_forced, 1);
642 SET_OPTION(led_state, 1);
643 break;
644
645 case UC_FREQUENCY:
646 if (value == NULL) {
647 fprintf(stderr, "uade: UC_FREQUENCY value is NULL\n");
648 break;
649 }
650 x = strtol(value, &endptr, 10);
651 if (*endptr != 0) {
652 fprintf(stderr, "Invalid frequency number: %s\n",
653 value);
654 break;
655 }
656 /* The upper bound is NTSC Amigas bus freq */
657 if (x < 1 || x > 3579545) {
658 fprintf(stderr, "Frequency out of bounds: %ld\n", x);
659 x = UADE_DEFAULT_FREQUENCY;
660 }
661 SET_OPTION(frequency, x);
662 break;
663
664 case UC_GAIN:
665 if (value == NULL) {
666 fprintf(stderr, "uade: UC_GAIN value is NULL\n");
667 break;
668 }
669 SET_OPTION(gain_enable, 1);
670 SET_OPTION(gain, uade_convert_to_double(value, 1.0, 0.0, 128.0, "gain"));
671 break;
672
673 case UC_HEADPHONES:
674 SET_OPTION(headphones, 1);
675 break;
676
677 case UC_HEADPHONES2:
678 SET_OPTION(headphones2, 1);
679 break;
680
681 case UC_IGNORE_PLAYER_CHECK:
682 SET_OPTION(ignore_player_check, 1);
683 break;
684
685 case UC_RESAMPLER:
686 if (value == NULL) {
687 fprintf(stderr, "uade.conf: No resampler given.\n");
688 break;
689 }
690 uc->resampler = strdup(value);
691 if (uc->resampler != NULL) {
692 uc->resampler_set = 1;
693 } else {
694 fprintf(stderr, "uade.conf: no memory for resampler.\n");
695 }
696 break;
697
698 case UC_NO_EP_END:
699 SET_OPTION(no_ep_end, 1);
700 break;
701
702 case UC_NO_FILTER:
703 SET_OPTION(no_filter, 1);
704 break;
705
706 case UC_NO_HEADPHONES:
707 SET_OPTION(headphones, 0);
708 SET_OPTION(headphones2, 0);
709 break;
710
711 case UC_NO_PANNING:
712 SET_OPTION(panning_enable, 0);
713 break;
714
715 case UC_NO_POSTPROCESSING:
716 SET_OPTION(no_postprocessing, 1);
717 break;
718
719 case UC_NORMALISE:
720 if (value == NULL) {
721 fprintf(stderr, "uade: UC_NORMALISE is NULL\n");
722 break;
723 }
724 SET_OPTION(normalise, 1);
725 uc->normalise_parameter = (char *) value;
726 break;
727
728 case UC_NTSC:
729 SET_OPTION(use_ntsc, 1);
730 break;
731
732 case UC_ONE_SUBSONG:
733 SET_OPTION(one_subsong, 1);
734 break;
735
736 case UC_PAL:
737 SET_OPTION(use_ntsc, 0);
738 break;
739
740 case UC_PANNING_VALUE:
741 if (value == NULL) {
742 fprintf(stderr, "uade: UC_PANNING_VALUE is NULL\n");
743 break;
744 }
745 SET_OPTION(panning_enable, 1);
746 SET_OPTION(panning, uade_convert_to_double(value, 0.0, 0.0, 2.0, "panning"));
747 break;
748
749 case UC_RANDOM_PLAY:
750 SET_OPTION(random_play, 1);
751 break;
752
753 case UC_RECURSIVE_MODE:
754 SET_OPTION(recursive_mode, 1);
755 break;
756
757 case UC_SILENCE_TIMEOUT_VALUE:
758 if (value == NULL) {
759 fprintf(stderr,
760 "uade: UC_SILENCE_TIMEOUT_VALUE is NULL\n");
761 break;
762 }
763 uade_set_silence_timeout(uc, value);
764 break;
765
766 case UC_SONG_TITLE:
767 if (value == NULL) {
768 fprintf(stderr, "uade: No song_title format given.\n");
769 break;
770 }
771 if ((uc->song_title = strdup(value)) == NULL) {
772 fprintf(stderr, "No memory for song title format\n");
773 } else {
774 uc->song_title_set = 1;
775 }
776 break;
777
778 case UC_SPEED_HACK:
779 SET_OPTION(speed_hack, 1);
780 break;
781
782 case UC_SUBSONG_TIMEOUT_VALUE:
783 if (value == NULL) {
784 fprintf(stderr,
785 "uade: UC_SUBSONG_TIMEOUT_VALUE is NULL\n");
786 break;
787 }
788 uade_set_subsong_timeout(uc, value);
789 break;
790
791 case UC_TIMEOUT_VALUE:
792 if (value == NULL) {
793 fprintf(stderr, "uade: UC_TIMEOUT_VALUE is NULL\n");
794 break;
795 }
796 uade_set_timeout(uc, value);
797 break;
798
799 case UC_USE_TEXT_SCOPE:
800 SET_OPTION(use_text_scope, 1);
801 break;
802
803 case UC_VERBOSE:
804 SET_OPTION(verbose, 1);
805 break;
806
807 default:
808 fprintf(stderr, "uade_set_config_option(): unknown enum: %d\n",
809 opt);
810 exit(1);
811 }
812 }
813
uade_set_ep_attributes(struct uade_state * state)814 void uade_set_ep_attributes(struct uade_state *state)
815 {
816 handle_attributes(&state->config, state->song, NULL, 0, state->ep->flags, state->ep->attributelist);
817 }
818
uade_set_filter_type(struct uade_config * uc,const char * model)819 void uade_set_filter_type(struct uade_config *uc, const char *model)
820 {
821 uc->filter_type = FILTER_MODEL_A500;
822
823 if (model == NULL)
824 return;
825
826 /* a500 and a500e are the same */
827 if (strncasecmp(model, "a500", 4) == 0) {
828 uc->filter_type = FILTER_MODEL_A500;
829
830 /* a1200 and a1200e are the same */
831 } else if (strncasecmp(model, "a1200", 5) == 0) {
832 uc->filter_type = FILTER_MODEL_A1200;
833
834 } else {
835 fprintf(stderr, "Unknown filter model: %s\n", model);
836 }
837 }
838
uade_set_silence_timeout(struct uade_config * uc,const char * value)839 static int uade_set_silence_timeout(struct uade_config *uc, const char *value)
840 {
841 char *endptr;
842 int t;
843 if (value == NULL) {
844 return -1;
845 }
846 t = strtol(value, &endptr, 10);
847 if (*endptr != 0 || t < -1) {
848 fprintf(stderr, "Invalid silence timeout value: %s\n", value);
849 return -1;
850 }
851 uc->silence_timeout = t;
852 uc->silence_timeout_set = 1;
853 return 0;
854 }
855
uade_set_subsong_timeout(struct uade_config * uc,const char * value)856 static int uade_set_subsong_timeout(struct uade_config *uc, const char *value)
857 {
858 char *endptr;
859 int t;
860 if (value == NULL) {
861 return -1;
862 }
863 t = strtol(value, &endptr, 10);
864 if (*endptr != 0 || t < -1) {
865 fprintf(stderr, "Invalid subsong timeout value: %s\n", value);
866 return -1;
867 }
868 uc->subsong_timeout = t;
869 uc->subsong_timeout_set = 1;
870 return 0;
871 }
872
uade_set_timeout(struct uade_config * uc,const char * value)873 static int uade_set_timeout(struct uade_config *uc, const char *value)
874 {
875 char *endptr;
876 int t;
877 if (value == NULL) {
878 return -1;
879 }
880 t = strtol(value, &endptr, 10);
881 if (*endptr != 0 || t < -1) {
882 fprintf(stderr, "Invalid timeout value: %s\n", value);
883 return -1;
884 }
885 uc->timeout = t;
886 uc->timeout_set = 1;
887 return 0;
888 }
889