3
* Cfg file reader, Greg Lee, 8/93.
4
* Adapted from Adagio for KMidi 12/99.
5
* $Id: cfg.l,v 1.8 2000/08/08 17:32:37 faure Exp $
21
#define YY_ALWAYS_INTERACTIVE 0
22
#define YY_NEVER_INTERACTIVE 1
24
#define YY_INPUT(buf,result,max_size) \
25
result = fread( buf, 1, max_size, yyin );
27
extern int set_play_mode(char *cp);
28
static int prescanning;
29
static char doing_drums = 0;
30
static char doing_sf = 0;
31
static int patchno = -1;
33
static char *patchname;
34
static char cfg_flag = 1;
36
static void set_patchno(char *m);
38
static char *s_dirname = 0;
39
static char *sfname = 0;
41
static int current_toneset = 0;
42
static int current_drumset = 0;
44
static int cfg_condition = -1;
46
static ToneBank *bank=0;
48
static int rcf_count=1;
49
static int font_type=FONT_NORMAL;
52
#define MAX_INCLUDE_DEPTH 40
53
static YY_BUFFER_STATE include_stack[MAX_INCLUDE_DEPTH];
54
static int include_stack_ptr = 0;
56
static void new_toneset(int n);
57
static void new_patch(const char *vname, int num);
68
nm ([^ \t\n\r\"#]+|\"[^\"\n]+\")
76
^{owh}"if"{wh}[0-9]+ {
78
while (isspace(yytext[i])) i++;
80
cfg_condition = atoi(yytext+i);
85
^{owh}("sf"|"sbk"){wh}{nm}{owh}[0-9]* {
86
int sf_oldbank, sf_newbank = banknum;
88
while (isspace(yytext[i])) i++;
89
if (yytext[i+1] == 'f') i += 2;
91
while (isspace(yytext[i])) i++;
92
if (yytext[i] == '"') {
94
for (j = i; j < yyleng && yytext[j] != '"'; j++) ;
97
else for (j = i; j < yyleng && !isspace(yytext[j]); j++) ;
98
sfname = strncpy( (char *)malloc(j-i+1), yytext+i, j-i );
100
if (doing_drums) sf_newbank += 256;
101
sf_oldbank = sf_newbank;
103
while (j < yyleng && isspace(yytext[j])) j++;
104
if (j < yyleng && isdigit(yytext[j])) sf_oldbank = atoi(yytext+j);
106
init_soundfont(sfname, sf_oldbank, sf_newbank, rcf_count);
108
^{owh}("dir"|"PatchDir:"){wh}{nm} {
110
while (isspace(yytext[i])) i++;
111
if (yytext[i] == 'd') i += 3;
113
while (isspace(yytext[i])) i++;
114
s_dirname = strcpy( (char *)malloc(strlen(yytext+i)+1), yytext+i );
115
add_to_pathlist(s_dirname, rcf_count);
118
^{owh}"source"{wh}{nm} {
123
while (isspace(yytext[i])) i++;
125
while (isspace(yytext[i])) i++;
127
if (prescanning && cfg_condition >= 0 && cfg_condition < 30 &&
128
rcf_count==1 && !cfg_names[cfg_condition])
130
cfg_names[cfg_condition] = (char *)safe_malloc(strlen(yytext+i)+1);
131
strcpy(cfg_names[cfg_condition], yytext+i);
134
if (!prescanning && (cfg_condition < 0 || cfg_condition == cfg_select)) {
137
if ( include_stack_ptr >= MAX_INCLUDE_DEPTH ) {
138
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
139
"Probable source loop in configuration files");
142
include_stack[include_stack_ptr++] =
145
fname = strcpy( (char *)malloc(strlen(yytext+i)+1), yytext+i );
150
yyin = open_file(fname, 1, OF_VERBOSE, rcf_count);
153
ctl->cmsg(CMSG_ERROR, VERB_NORMAL,
154
"Source file %s not found\n", fname);
158
if (yyin == NULL) yyin = save_yyin;
163
yy_create_buffer( yyin, YY_BUF_SIZE ) );
170
if ( --include_stack_ptr < 0 ) {
174
if (yyin) close_file(yyin);
175
yy_delete_buffer( YY_CURRENT_BUFFER );
178
include_stack[include_stack_ptr] );
182
^{owh}"drumset"{wh}[0-9]+{wh}("sf"|"sbk"){wh}{nm} {
183
char *bank_name = NULL;
185
while (isspace(yytext[i])) i++;
187
current_drumset = atoi(yytext+i);
190
new_toneset(current_drumset);
193
while (isspace(yytext[i])) i++;
194
while (isdigit(yytext[i])) i++;
195
while (isspace(yytext[i])) i++;
196
if (yytext[i+1] == 'f') i += 2; else i += 3;
197
while (isspace(yytext[i])) i++;
198
patchname = yytext + i;
199
if (patchname[0] == '"') {
200
bank_name = strncpy( (char *)malloc(strlen(patchname)-1), patchname + 1, strlen(patchname)-1 );
201
bank_name[strlen(patchname)-2] = '\0';
203
else bank_name = strcpy( (char *)malloc(strlen(patchname)+1), patchname );
204
bank->name = bank_name;
208
^{owh}"drumset"{wh}[0-9]+{wh}("sf"|"sbk") {
210
while (isspace(yytext[i])) i++;
212
current_drumset = atoi(yytext+i);
215
new_toneset(current_drumset);
218
^{owh}"drumset"{wh}[0-9]+{wh}{nm} {
219
char *bank_name = NULL;
221
while (isspace(yytext[i])) i++;
223
current_drumset = atoi(yytext+i);
226
new_toneset(current_drumset);
227
font_type=FONT_NORMAL;
229
while (isspace(yytext[i])) i++;
230
while (isdigit(yytext[i])) i++;
231
while (isspace(yytext[i])) i++;
232
patchname = yytext + i;
233
if (patchname[0] == '"') {
234
bank_name = strncpy( (char *)malloc(strlen(patchname)-1), patchname + 1, strlen(patchname)-1 );
235
bank_name[strlen(patchname)-2] = '\0';
237
else bank_name = strcpy( (char *)malloc(strlen(patchname)+1), patchname );
238
bank->name = bank_name;
241
^{owh}"drumset"{wh}[0-9]+ {
243
while (isspace(yytext[i])) i++;
245
current_drumset = atoi(yytext+i);
248
new_toneset(current_drumset);
249
font_type=FONT_NORMAL;
251
^{owh}"bank"{wh}[0-9]+{wh}("sf"|"sbk") {
253
while (isspace(yytext[i])) i++;
255
current_toneset = atoi(yytext+i);
258
new_toneset(current_toneset);
261
^{owh}"bank"{wh}[0-9]+ {
263
while (isspace(yytext[i])) i++;
265
current_toneset = atoi(yytext+i);
268
new_toneset(current_toneset);
269
font_type=FONT_NORMAL;
272
current_toneset = SFXBANK;
275
new_toneset(current_toneset);
276
font_type=FONT_NORMAL;
279
current_drumset = SFXDRUM1;
282
new_toneset(current_toneset);
283
font_type=FONT_NORMAL;
284
bank->name = "drumsfx1";
287
current_drumset = SFXDRUM2;
290
new_toneset(current_toneset);
291
font_type=FONT_NORMAL;
292
bank->name = "drumsfx2";
295
^{owh}"[Melodic Patches]" {
298
^{owh}"[Drum Patches]" {
300
current_drumset = current_toneset;
303
^{owh}[0-9,]+("="|{wh}){nm} {
304
const char *gm_name = NULL;
305
char *vc_name = NULL;
306
patchno = atoi(yytext);
310
while (isspace(yytext[i])) i++;
311
while (isdigit(yytext[i])) i++;
312
if (yytext[i] == ',') {
314
tone_bank = atoi(yytext + i);
315
while (isdigit(yytext[i])) i++;
318
if (doing_drums) tone_bank = current_drumset;
319
else tone_bank = current_toneset;
321
new_toneset(tone_bank);
323
while (isspace(yytext[i])) i++;
324
if (!cfg_flag && yytext[i] == '=') i++;
325
if ( (patchname = strrchr(yytext + i, '\\')) == NULL)
326
patchname = yytext + i;
328
if (patchname[0] == '"') {
329
vc_name = strncpy( (char *)malloc(strlen(patchname)-1), patchname + 1, strlen(patchname)-1 );
330
vc_name[strlen(patchname)-2] = '\0';
332
else vc_name = strcpy( (char *)malloc(strlen(patchname)+1), patchname );
333
if (patchno < 128) gm_name = gm_voice[doing_drums? patchno+128 : patchno].vname;
335
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Bad patch number %d in cfg file.", patchno);
337
if (gm_name == NULL) gm_name = (doing_drums)? "drum":"instr";
339
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "config: voice %s[%d,%d] = patch %s",
340
gm_name, patchno, tone_bank, vc_name);
342
new_patch(vc_name, patchno);
348
^{owh}[A-Z][^\n\r\t\=,#]+(","{owh}[0-9]+)?{owh}"="{owh}{nm} {
349
const char *gm_name = NULL;
350
char *vc_name = NULL;
356
while (yytext[i] != '=' && yytext[i] != ',') i++;
357
if (yytext[i] == ',') {
359
tone_bank = atoi(yytext + i);
362
if (doing_drums) tone_bank = current_drumset;
363
else tone_bank = current_toneset;
366
while (yytext[i] != '=') i++;
368
while (isspace(yytext[i])) i++;
369
if ( (patchname = strrchr(yytext + i, '\\')) == NULL)
370
patchname = yytext + i;
372
if (patchname[0] == '"') {
373
vc_name = strncpy( (char *)malloc(strlen(patchname)-1), patchname + 1, strlen(patchname)-1 );
374
vc_name[strlen(patchname)-2] = '\0';
376
else vc_name = strcpy( (char *)malloc(strlen(patchname)+1), patchname );
377
gm_name = gm_voice[patchno].vname;
378
if (gm_name == NULL) gm_name = (doing_drums)? "drum":"instr";
380
ctl->cmsg(CMSG_INFO, VERB_DEBUG, "config: voice %s[%d,%d] = patch %s",
381
gm_name, patchno, tone_bank, vc_name);
385
ctl->cmsg(CMSG_ERROR, VERB_NORMAL, "Bad line \"%s ...\" in cfg file.", yytext);
387
new_patch(vc_name, patchno);
392
^{owh}"-p"{owh}[0-9]+ { if (prescanning) {
393
i=0; while(isspace(yytext[i])) i++;
394
j = atoi(yytext+i+2);
395
if (j > 1 && j < MAX_VOICES) voices = j;
397
^{owh}"-A"{wh}[0-9]+ { if (prescanning) {
398
i=0; while(isspace(yytext[i])) i++;
399
j = atoi(yytext+i+2);
400
if (j > 1 && j < MAX_AMPLIFICATION) amplification = j;
402
^{owh}"-C"{owh}[0-9]+ { if (prescanning) {
403
i=0; while(isspace(yytext[i])) i++;
404
j = atoi(yytext+i+2);
405
if (j > 1 && j < MAX_CONTROL_RATIO) control_ratio = j;
407
^{owh}"-s"{owh}[0-9]+ { if (prescanning) {
408
i=0; while(isspace(yytext[i])) i++;
409
j = atoi(yytext+i+2);
410
if (j < 100) j *= 1000;
411
if (j > MIN_OUTPUT_RATE && j < MAX_OUTPUT_RATE) play_mode->rate = j;
413
^{owh}"-r"{owh}[0-9]+ { if (prescanning) {
414
i=0; while(isspace(yytext[i])) i++;
415
j = atoi(yytext+i+2);
416
max_patch_memory = j * 1000000;
418
^{owh}"-k"{owh}[0-9]+ { if (prescanning) {
419
i=0; while(isspace(yytext[i])) i++;
420
j = atoi(yytext+i+2);
421
if (j >= 0 && j <= 3) current_interpolation = j;
423
^{owh}"-X"{owh}[0-9]+ { if (prescanning) {
424
i=0; while(isspace(yytext[i])) i++;
425
j = atoi(yytext+i+2);
426
if (j >= 0 && j <= 2) opt_expression_curve = j;
428
^{owh}"-V"{owh}[0-9]+ { if (prescanning) {
429
i=0; while(isspace(yytext[i])) i++;
430
j = atoi(yytext+i+2);
431
if (j >= 0 && j <= 2) opt_volume_curve = j;
433
^{owh}"-O"{owh}[a-zA-Z] { if (prescanning) {
434
i=0; while(isspace(yytext[i])) i++;
436
while(isspace(yytext[i])) i++;
437
if (set_play_mode(yytext+i)) /* error */;
440
<P>{owh}"amp"{owh}"="{owh}[0-9]+ {
442
while (yytext[i] != '=') i++;
443
bank->tone[patchno].amp = atoi(yytext+i+1);
446
<P>{owh}"note"{owh}"="{owh}[0-9]+ {
448
while (yytext[i] != '=') i++;
449
bank->tone[patchno].note = atoi(yytext+i+1);
452
<P>{owh}"tuning"{owh}"="{owh}("+"|"-")[0-9]+ {
454
while (yytext[i] != '=') i++;
455
bank->tone[patchno].tuning = atoi(yytext+i+1);
458
<P>{owh}"keep"{owh}"=" BEGIN(K);
459
<P>{owh}"strip"{owh}"=" BEGIN(S);
462
bank->tone[patchno].strip_loop=0;
466
bank->tone[patchno].strip_tail=0;
470
bank->tone[patchno].strip_envelope=0;
474
bank->tone[patchno].strip_loop=1;
478
bank->tone[patchno].strip_tail=1;
482
bank->tone[patchno].strip_envelope=1;
485
^{owh}[A-Z][^\n\r\t\:#]+{owh}":"{owh}"poly" {
487
if (patchno < 256) gm_voice[patchno].flags &= ~SOLO_MASK;
489
^{owh}[A-Z][^\n\r\t\:#]+{owh}":"{owh}"solo" {
491
if (patchno < 256) gm_voice[patchno].flags |= SOLO_MASK;
501
static void new_toneset(int n)
507
tonebank[n]=(ToneBank *)safe_malloc(sizeof(ToneBank));
508
memset(tonebank[n], 0, sizeof(ToneBank));
514
drumset[n]=(ToneBank *)safe_malloc(sizeof(ToneBank));
515
memset(drumset[n], 0, sizeof(ToneBank));
521
static void new_patch(const char *vname, int num)
523
if (bank->tone[num].name) return;
524
bank->tone[num].name=vname;
525
bank->tone[num].note=bank->tone[num].amp=bank->tone[num].pan=
526
bank->tone[num].strip_loop=bank->tone[num].strip_envelope=
527
bank->tone[num].sf_ix=
528
bank->tone[num].strip_tail=bank->tone[num].last_used=-1;
529
bank->tone[num].font_type=font_type;
530
bank->tone[num].tuning=0;
531
bank->tone[num].layer=0;
534
static void set_patchno(char *m)
539
while (isspace(m[w])) w++;
540
for (i = 0; i < 256; i++) {
541
vn = gm_voice[i].vname;
542
if (vn == NULL) continue;
543
for (j = 0; m[j+w] && vn[j+y] && m[j+w] == vn[j+y]; j++)
544
if (vn[j+y+1] && isspace(vn[j+y+1]) && m[j+w+1] && !isspace(m[j+w+1]) ) y++ ;
545
if (!m[j+w] || m[j+w] == '=' || m[j+w] == ',' || m[j+w] == ':') break;
546
if (!vn[j+y] && isspace(m[j+w])) break;
548
if (i < 256 && vn != NULL) patchno = i;
553
char *current_config_file = 0;
555
int read_config_file(const char *name, int prescan)
558
prescanning = prescan;
559
include_stack_ptr = 0;
563
current_config_file = (char *)safe_malloc(strlen(name)+1);
564
strcpy(current_config_file, name);
567
yyin = open_file(name, 1, OF_VERBOSE, rcf_count);
568
if (!yyin) return -1;
570
current_toneset = current_drumset = 0;
571
doing_drums = doing_sf = 0;
572
if (!(retvalue = yylex())) {
573
if (prescan) got_a_configuration = 1;
574
else got_a_configuration = 2;