// C++ muziek programma
#define DATUM "26 februari 1996"


#include <stdio.h>
#include <dos.h>
#include <string.h>

#define  false 0
#define  true  1

char fgetch(FILE *stream)
{ char ch;
  ch=fgetc(stream);
  while(ch==' ') ch=fgetc(stream);
  if (ch>='a' && ch<='z') ch+='A'-'a';
  return ch;
}

int geluid=true;
int writebatch=false;
int lala=false;

char command[25] ="beep";
char infile[50] ="infile.msk";
char lalala[50] ="la";
int main(int argc,char *argv[])
{ FILE *in;
  if (argc == 1)
    { printf("gebruik: %s [-options] <infile> [ > <outfile>] \n"
             "formaat: %s ? \n"
             "versie : %s ",argv[0],argv[0],DATUM);
      printf("\n\n opties:\n"
             " -n     : niet spelen\n"
             " -w     : output als batchfile \n"
             " -c???  : beep-commando (beep)\n"
             " -k???  : met korte tonen (+lengte)\n"
             " -l[???]: lala (la)");
      return 1;
    }

 for (int i=1; i<argc; i++)
  {if (argv[i][0]=='?')
      { printf(" Maakt van een 'muziek-file' een batch-file (naar std. output)\n"
               " formaat muziekfile: \n\n"
               " noten:             CDEFGAB of cdefgab \n"
               " pause:             p\n"
               " kruis/mol:         #/@ dus A# = B@  = a# = b@\n"
               " lengte instellen:  A#4 wordt: beep 466 4\n"
               " oktaaf instellen:  A+1#=A+# : beep 932 4\n"
               " standaard oktaaf:  o5 of bijv o-5\n"
               " standaard lengte:  l4 of bijv l8 etc.\n"
               " snelheid:          s100 (gewoon) of bijv. s50, s200 \n"
               " versnelling:       ss0 (gewoon) of bijv ss10, ss-10 \n"
               " commentaar:        :....\n"
               " echo's             *...*\n"
               " \n (zie ook voorbeelden)");
        return 1;
     }
  if ((argv[i][0]=='-') || (argv[i][0]=='/'))
     { // command line options
       switch(argv[i][1])
         { case 'n': geluid=false; break;
           case 'w': writebatch=true; break;
           case 'c': strcpy(command,&(argv[i][2])); break;
           case 'l': { lala=true;
                       if(argv[i][2]!='\0') strcpy(lalala,&(argv[i][2]));
                       break;
                    }
         }
     }
  else
     { strcpy(infile,argv[i]);
     }
  }

       // in-file openen
       if ( (in = fopen(infile,"rt")) == NULL)
        { printf("Cannot open input file");
          return 1;
        }

if (writebatch) printf("@echo off\n");
if (writebatch) printf(":bron :%s ",infile);

 char ch;
 float factor=1.0594631;  // 2^ 1/12
 unsigned frequenties[7];

 frequenties[0]=440;  //  A
 frequenties[1]=494;  //  B
 frequenties[2]=262;  //  C
 frequenties[3]=294;  //  D
 frequenties[4]=330;  //  E
 frequenties[5]=349;  //  F
 frequenties[6]=392;  //  G

 unsigned frequentie;
 float defaultlengte=4;  //
 float lengte;
 unsigned defaultsnelheid=100;
 float snelheid=100;
 signed versnelling=0;
 int min;
 int oktaaf=0;
 int beep=false;

 ch=fgetch(in);
 do
   { if (ch=='O')
	{ ch=fgetch(in);
	  oktaaf=0;
	  if (ch=='-')
	     { ch=fgetch(in);
	       if (ch>='0' && ch<='9') { oktaaf=-(ch-'0'); ch=fgetch(in); }
	     }
	  if (ch>='0' && ch<='9') { oktaaf=ch-'0'; ch=fgetch(in); }
	} else
     if (ch=='L')
	{ ch=fgetch(in);
	  defaultlengte=4;
	  if ('1' <=ch && ch<='9') { defaultlengte=ch-'0';
				     ch=fgetc(in);
				     while ('0' <=ch && ch<='9')
          { defaultlengte=defaultlengte*10+ch-'0';
					  ch=fgetc(in);
					}
				   }


	} else
     if (ch=='S')
	{ ch=fgetch(in);
    if (ch==' ') snelheid=float(defaultsnelheid);
    if ('0' <=ch && ch<='9')
           { snelheid=ch-'0';
             ch=fgetc(in);
             while ('0' <=ch && ch<='9')
              { snelheid=snelheid*10+ch-'0';
                ch=fgetc(in);
              }
				   }
   if (ch=='S')
       { versnelling=0;
         ch=fgetch(in);
         min=(ch=='-');
         if (min) ch=fgetch(in);
         if ('0'<=ch && ch<='9')
            { versnelling=ch-'0';
              ch=fgetc(in);
              while ('0' <=ch && ch<='9')
               { versnelling=10*versnelling+ch-'0';
                 ch=fgetc(in);
               }
            }
        if (min) versnelling=-versnelling;
      }
	} else
     if ( (ch>='A' && ch<='G') || ch=='P')
	{ if (ch!='P') frequentie = frequenties[ch-'A'];
          if (ch=='P') frequentie = 0;
	  lengte = defaultlengte;
	  if (oktaaf>0) for (i=0; i<oktaaf; i++) frequentie*=2;
    if (oktaaf<0) for (i=0; i<-oktaaf; i++) frequentie/=2;

 if (writebatch) if (beep==false) {printf("\n%s ",command); beep=true; }

    ch=fgetch(in);
	  if (ch == '-')
	     { ch=fgetch(in);
               if ('0'<=ch && ch<='9') { for (i=0; i<(ch-'0'); i++) frequentie/=2;
					 ch=fgetch(in);
				       } else frequentie/=2;
	     }
    if (ch == '+')
	     { ch=fgetch(in);
	       if ('0'<=ch && ch<='9'){ for (i=0; i<(ch-'0'); i++) frequentie*=2;
					ch=fgetch(in);
				      } else frequentie*=2;
	     }

	  if (ch=='#') { frequentie*=factor; ch=fgetch(in); }
	  if (ch=='@') { frequentie/=factor; ch=fgetch(in); }

	  if ('1' <=ch && ch<='9') { lengte=ch-'0';
				     ch=fgetc(in);
				     while ('0' <=ch && ch<='9')
					{ lengte=lengte*10+ch-'0';
					  ch=fgetc(in);
					}
				   }

if (writebatch) printf("%i %2.2f ",frequentie,(lengte * defaultsnelheid /snelheid ));
if (geluid)    { if (lala) printf("%s ",lalala); sound(frequentie); delay(lengte*50*defaultsnelheid/snelheid); nosound();}
snelheid+=versnelling*lengte/100;
	} else
        if (ch==':')  // commentaar
        { if (writebatch) printf("\n:");
          while ( ch=fgetc(in), ch!='\n' ) if (writebatch) printf("%c",ch);
        } else
        if (ch=='*')  // commentaar
        { if (writebatch) printf("\n echo. ");
          while ( ch=fgetc(in), ((ch!='\n') && (ch!='*')) ) printf("%c",ch);
          printf("\n");
          beep=false;
          ch=fgetch(in);
        } else ch=fgetch(in);
if (writebatch) if (ch=='\n') if ((ch=fgetch(in))!=EOF) { beep=false; }

   } while (ch != EOF);
 fclose(in);
}
