/*% cc -g -o # % -lmidi -lsun */ #include #include #include #include int midi, IgnoreSpace = 0, /* if true, don't play white space */ SilentSpace = 0, /* if true, play white space as silence */ Fold = 1, /* fold lower case to upper */ PunctuationTempo = 12, /* how long (in hertz) a punct note lasts */ Tempo = 7, /* how long a normal note lasts */ Echo = 1, /* echo the notes as they are played */ RunOn = 0, /* repeated notes are held */ BracketVoice = -1, /* if > -1, the current voice is taken to * be 'BracketVoice', and is incremented * or decremented with every grouping * symbol */ BracketTempo = -1, /* if != 0, tempo is incremented by this * when we enter a bracketed group */ BracketBoost = 15, /* amount by which grouped text (...) is amplified; if 0, do nothing */ BaseVolume = 100, /* default volume level */ MaxVolume = 127, MinVolume = 10, Crescendo = 0; /* amount to crescendo for each line */ #define bracket(c) (index("()[]{}<>",c)) #define Lbracket(c) (index("({[<",c)) #define Rbracket(c) (index(")}]>",c)) note(n){ /* play note 'n' */ static int v=0, length = 0; static int prevn = 0; ++length; if (n == '\n') length = 0; if (!v) v = BaseVolume? BaseVolume : MaxVolume; if (Crescendo) v = length? v + Crescendo : BaseVolume; if (Echo) printf("%c",n),fflush(stdout); if (Fold && islower(n)) n = toupper(n); if (isspace(n)) { if (IgnoreSpace) return prevn = n; if (SilentSpace) return nap(Tempo), prevn = n; } if bracket(n){ if (BracketBoost) { /* raise or lower note amplitude */ if Lbracket(n) v += BracketBoost; if Rbracket(n) v -= BracketBoost; } if (BracketVoice>0){ int v = BracketVoice; if Lbracket(n) v++; if Rbracket(n) v--; if (v<0) v=0; if (v>31) v=31; if (v != BracketVoice) BracketVoice = v, dx7SetVoice(midi,v); } if (BracketTempo){ int i = Lbracket(n)? BracketTempo : - BracketTempo; Tempo += i; if (Tempo < 0) Tempo = 0; if (Tempo > 60) Tempo = 60; if (PunctuationTempo){ PunctuationTempo += i; if (PunctuationTempo < 0) PunctuationTempo = 0; if (PunctuationTempo > 60) PunctuationTempo = 60; } } } if (v < MinVolume) v = MinVolume; if (v > MaxVolume) v = MaxVolume; if (RunOn && prevn == n) ; else NoteOn(midi,0,n,v); if (PunctuationTempo && ispunct(n)) nap(PunctuationTempo); else nap(Tempo); if (RunOn && (nextn() == n)) ; else NoteOff(midi,0,n); prevn = n; } char buf[200] = ""; char *bp = buf; nextn(){ char c = *bp? *(bp+1) : *bp; if (Fold && islower(c)) c = toupper(c); return c; } muzak(f) FILE *f; { /* read chars from 'f' and play them to a synth */ if (!f) return; while (fgets(buf,sizeof buf,f)){ bp = buf; while (*bp) { note(*bp); bp++; } } fclose(f); } FILE * Open(s) char *s; { /* fopen(f) and complain if necessary */ FILE *f = fopen(s,"r"); if (!f) perror(s); return f; } e(a,b){ fprintf(stderr,a,b),fprintf(stderr,"\n");} #define dont(s) s? "don't " : "" use(){ e("Use: %s [-efsr] [-[cptTvbB]#] [files]",av0); e(" -e %secho notes while playing them",dont(Echo)); e(" -f %sfold upper case to lower",dont(Fold)); e(" -s %signore white space",dont(IgnoreSpace)); e(" -S %splay white space as silence",dont(SilentSpace)); e(" -r %shold strings of notes",dont(RunOn)); e(" -c# crescendo by +# (%d) for each note to the end of each line",Crescendo); e(" -p# duration of punctuation notes = # (%d)",PunctuationTempo); e(" -t# note duration = # (%d)",Tempo); e(" -T# {in,de}crement tempo by # (%d) in bracketed groups ([]{}<>())", BracketTempo); e("durations are '#' 60th's of a second."); e(" -v# volume is # (%d)",BaseVolume); e(" -b# boost volume of bracketed groups ([]{}<>()) by # (%d)",BracketBoost); e(" -B# {in,de}crement voice in bracketed groups ([]{}<>())"); e(" starting at # (%d)",BracketVoice); e("eg, \"cat muzak.c | muzak -t5 -p12\""); exit(1); } main(ac,av) char *av[]; { int i; for_each_argument { Case 'e': toggle(Echo); Case 'f': toggle(Fold); Case 's': toggle(IgnoreSpace); Case 'S': toggle(SilentSpace); Case 'p': PunctuationTempo = atoi(argument); Case 't': Tempo = atoi(argument); Case 'c': Crescendo = atoi(argument); Case 'v': BaseVolume = atoi(argument); Case 'b': BracketBoost = atoi(argument); Case 'B': BracketVoice = atoi(argument); Case 'T': BracketTempo = atoi(argument); Case 'r': toggle(RunOn); Default : use(); } midi = open("/dev/mpu0",2); if (midi == -1) perror("no midi -- bleagh"), exit(1); MpuSend(midi, MPU_RESET, 0); if (ac == i) muzak(stdin); else for (;i