/* ** PLAY -- Play midi data ** Mike Hawley, mercilessly hacked by psl */ #include #include #include #include char *Mididev = MPU_DEV_0; int Simultaneous = 0; /* if true, play files at the same time */ int Sync = 'i'; /* clock sync spec */ int Record = 0; /* if true, record (overdub) while playing */ int otty = 0; /* if true, output is to a tty */ int DX7 = 0; /* if true, send DX7 init & reset sequences */ int midi; FILE *F[8]; FILE *Open(), *OpenTune(); #d Close(i) sclose(F[i]), f[i] = -1, F[i] = (FILE *)0 main(ac, av) char *av[]; { char *init_file = NULL; Int i, tracks=1, mode = MPU_START_PLAY; int f[8], n=0, FromPipe = !isatty(0), Wait=0; void interrupt(); signal(SIGINT, interrupt); for_each_argument { Case '7': DX7 = 1; Case 'b': MpuSet(MPU_METRO_MEAS), MpuSet(atoi(argument)); Case 'c': init_file = argument; Case 'M': MpuSet(MPU_METRO_ACC); Case 'm': MpuSet(MPU_METRO_NO_ACC); Case 'o': Mididev = argument; break; Case 'r': Record = 1; mode = MPU_START_OVERDUB; Case 'S': Sync = *argument; Case 's': Simultaneous = 1; Case 't': MpuSet(MPU_TEMPO), MpuSet(atoi(argument)); Case 'w': Wait = atoi(argument); Case 'x': MpuSet(MPU_EXCLUSIVE_TO_HOST_ON), MpuSet(MPU_SEND_MEASURE_END_OFF); Default : use(1); } if (DX7) dx7_clear(); MpuSet(MPU_MIDI_THRU_OFF); if (i == ac) { f[0] = fileno(F[0] = stdin); FromPipe = isapipe(f[0]); } else if (Simultaneous) { tracks = ac - i; for (; i < ac && n < sizeof f; i++) if (F[n] = Open(av[i])) { f[n] = fileno(F[n]); FromPipe += isapipe(f[n]); ++n; } else perror(av[i]); if (n == sizeof f) fprintf(stderr, "max 8 files\n"); } else if (F[0] = Open(av[i++])) FromPipe = isapipe(f[0] = fileno(F[0])); else exit(1); if (Wait || FromPipe) sleep(Wait? Wait : 2); /* let input pipes fill up a little */ if (!(midi = MidiPlayInit(init_file,f,tracks,mode))) Error(Mididev); if (Simultaneous) splay(midi,f,n); else do { if (F[0]) { play(midi,fileno(F[0])); Close(0); } } while (i < ac && (F[0] = Open(av[i++]))); if (!Record) done(midi); /* playing finished, continue recording until user hits a key */ for(;;) record(midi, fileno(stdout)); /*NOTREACHED*/ } done(fh) { close(fh); if (DX7) dx7_reset(-1); exit(0); } Error(s) { MidiError("%s: ", av0); perror(s); exit(1); } MidiPlayInit(file, fd, numtracks, mode) char *file; int fd[], numtracks, mode; { register int i, tracks=0; int f = open(Mididev,2); if (f == -1) { perror(Mididev); return(0); } if (numtracks == 0) numtracks = 1; for (i = 0; i < numtracks; i++) { char s[256]; int n = read(fd[i],s,sizeof s); tracks |= (1< 0) { if (otty) printf("0x%02x\n",c); else if (write(out,&c,n)!= n) return(perror("write")); } } /* true if a file desc. in 'f' is still open (ie, 'f[i] >= 0'). */ dataleft(f, nfiles) int f[]; { Int i; loop(i,nfiles) if (f[i] >= 0) return(1); return(0); } splay(midi,f,nfiles) /* simultaneously play all files in 'f' */ int f[]; { Int n, i; char s[512]; while (dataleft(f,nfiles)) { for (i = 0; i < nfiles; i++) { if (f[i] < 0) continue; if ((n=read(f[i],s,sizeof s)) > 0) { MpuSetTrack(midi,i); if (write(midi,s,n) != n) { perror(Mididev); Close(i); } } else Close(i); record(midi, fileno(stdout)); } } /* following necessary to guard against final pops */ MpuSetTrack(midi,0); putTCIP(midi); } play(midi,f) /* play 'f' into midi device */ { Int n; char s[512]; while ((n=read(f,s,sizeof s)) > 0) if (write(midi,s,n) != n) { perror(Mididev); MpuSetTrack(midi, 0); } else record(midi,fileno(stdout)); } FILE *Open(s) char *s; { FILE *f = sopen(s,"r"); return(f? f : OpenTune(s)); } #include #include void interrupt() { /*** signal(SIGINT,SIG_DFL); /* this line is important */ ioctl(midi, MPU_IOC_PURGE, 0); /**** MpuSend(midi, MPU_RESET, 0); /****/ done(midi); }