@*Intro. This program is sort of an inverse to {\mc XSTtoTXT}: It takes a human-readable description of combination settings (|stdin|) and produces a corresponding file that could be stored in a USB stick and loaded into the automated sequencing system of Organ Acusticum. The first line of input should have the title of the piece, enclosed in left-and-right single quotes. For example, the first line might be $$\.{Combination settings for `foo' by R. J. Drofnats}$$ in which case the title displayed on the setter would be \.{foo}. Subsequent lines of input specify the combinations. Each combination has a four-digit number, from 0000 to 9999. To specify it, you first put the number on a line by itself, followed by a colon. Then you specify each of its stops on separate lines by themselves, preceded by a space; each stop is identified by its console number, which is between 1 and 208. (This stop number can optionally be followed by a description of the stop, but this description is ignored and it need not be correct.) For example, the lines $$\vcenter{\halign{\tt#\hfil\cr 0013:\cr \ 175 II Salicional 8\cr \ 48\cr \ 149 II Nachthorn 4\cr \ 33 II->I\cr \ 34 III->I\cr \ 111 Bordun 8\cr}}$$ specify that combination 0013 is supposed to contain stops 33, 34, 48, 111, 149, and 175. The fact that stop 48 is the 16-foot Gedackt on the Pedal is irrelevant; so is the fact that stop 149 is really `Cor de nuit 8' in the R\'ecit division! Only the stop numbers are examined by this program. If you want to see the exact stop names, you can apply {\mc XSTtoTXT} to this program's output. The stop numbers 101 (`MIDI') and 104 (`Crescendo') are illegal. So are the unused numbers that are blank on the console, such as 31. The combinations and stops need not be specified in any particular order. If you specify the same combination twice, the second specification overrides the first, and a warning message is printed. A warning is also given if you specify a stop twice within the same combination. Input lines may also contain optional comments, which begin with the character `\.{\char`\%}'. @d bufsize 80 @c #include #include #include unsigned long long data[10000][4]; char buf[bufsize]; char title[bufsize]; int codepos[209]=@; main() { register d,i,j,k,s,t,count; @; @; } @ @= @; for (d=-1,i++;;i++) { if (!fgets(buf,bufsize,stdin)) break; if (buf[0]=='%') continue; if (buf[0]>='0' && buf[0]<='9') @@; else if (buf[0]==' ') @@; else { fprintf(stderr,"Input line %d was ignored", i); fprintf(stderr," because it doesn't begin with %% or digit or space:\n%s", buf); } } @ @= for (i=1;;i++) { if (!fgets(buf,bufsize,stdin)) { fprintf(stderr,"The input ended without any title line!\n"); exit(-666); } if (buf[0]!='%') break; } for (k=0;buf[k] && buf[k]!='\n' && buf[k]!='`';k++) ; if (buf[k]!='`') { fprintf(stderr, "Error: The first noncomment line should contain the `title',\n"); fprintf(stderr," but line %d doesn't:\n%s", i,buf); exit(-1); } for (j=0,k++;buf[k] && buf[k]!='\n' && buf[k]!='\'';j++,k++) title[j]=buf[k]; if (buf[k]!='\'') { fprintf(stderr, "Error: The first noncomment line should contain the `title',"); fprintf(stderr," but line %d doesn't:\n%s", i,buf); exit(-2); } @ @= { for (d=buf[0]-'0',k=1;buf[k]>='0' && buf[k]<='9';k++) d=10*d+buf[k]-'0'; if (k!=4 || buf[4]!=':') { fprintf(stderr,"Error: A combination must be four digits followed by colon,"); fprintf(stderr," buf line %d isn't:\n%s", i,buf); exit(-3); } if (data[d][0]) fprintf(stderr, "(Warning: The previous specification of combination %04d is overridden)\n", d); else count++; data[d][0]=0xffffffffffff0000,data[d][1]=data[d][2]=data[d][3]=0; } @ @= { if (buf[1]<'0' || buf[1]>'9') fprintf(stderr, "I'm ignoring line %d because it has no digit after the initial space\n", i); else { for (s=buf[1]-'0',k=2;buf[k]>='0' && buf[k]<='9';k++) s=10*s+buf[k]-'0'; if (s>208) t=-1;@+else t=codepos[s]; if (t<0) fprintf(stderr,"Error on line %d, stop number %d is illegal:\n%s", i,s,buf); else if (d<0) { fprintf(stderr,"Error! Line %d specifies stop %d,", i,s); fprintf(stderr," but no combination number has been given\n"); exit(-5); }@+else if (data[d][t>>6]&(1LL<<(t&0x3f))) fprintf(stderr, "(Warning: Line %d respecifies stop %d in combination %d)\n", i,s,d); else data[d][t>>6]+=1LL<<(t&0x3f); } } @ @= { -1,@/ 8,9,10,11,12,13,15,14,@/ 0,1,2,3,4,5,6,7,@/ 120,121,122,123,124,125,126,127,@/ 112,113,114,115,116,117,-1,-1,@/ 104,105,106,107,108,109,110,111,@/ 96,97,98,99,100,101,102,103,@/ 88,89,90,91,92,93,94,95,@/ 80,81,82,83,84,85,86,87,@/ 72,73,74,75,76,77,78,79,@/ 64,65,66,67,68,69,70,71,@/ 184,185,186,187,-1,-1,190,191,@/ 176,177,178,179,180,181,182,183,@/ 168,169,170,171,-1,173,174,-1,@/ 160,161,162,163,164,165,166,167,@/ 152,153,154,155,156,157,158,159,@/ 144,145,146,147,148,149,150,-1,@/ -1,-1,138,139,-1,141,142,143,@/ -1,-1,-1,131,132,133,134,135,@/ 248,249,250,251,252,253,254,255,@/ 240,241,242,243,244,245,246,-1,@/ 232,233,234,235,236,237,238,-1,@/ -1,225,226,227,228,229,230,231,@/ 216,217,218,219,220,221,222,223,@/ 208,209,210,211,212,213,214,215,@/ 200,201,-1,203,204,205,206,207,@/ 192,-1,194,195,196,197,198,199 } @ @= printf("\n"); printf("\n"); printf(" <NAME>%s</NAME>\n", title); printf(" <COUNT>%d</COUNT>\n", count); for (d=0;d<10000;d++) if (data[d][0]) { printf(" <CMB>\n"); printf(" <ID>%d</ID>\n", d); printf(" <REGLEN>26</REGLEN>\n"); printf(" <REG>%04llx%016llx%016llx%016llx</REG>\n", data[d][0]&0xffff,data[d][1],data[d][2],data[d][3]); printf(" </CMB>\n"); } printf("\n"); fprintf(stderr,"OK, I've specified %d combinations for `%s'.\n", count,title); @*Index.