#include #include #include #include #include #include #include #include #include #include "randcmd.h" extern struct ExecBase *SysBase; extern struct DosLibrary *DOSBase; struct FileInfoBlock *fib; struct Lock *flock; struct MsgPort *CreatePort(); struct MsgPort *AudioPort; struct IOAudio Audio; struct MsgPort *Timermessage; struct timerequest TimerReq; struct MsgPort *CommandPort; struct commandrequest *cmdmessage; struct Message *GetMsg(); char *FilePointer; UBYTE Channels[] = { 0x0F }; short AudioDev = NULL,TimerDev = NULL; UBYTE *sounddata; ULONG samlen; char RandSamVers[50] = {"Randsam v1.1 , by Steven Lagerweij 030490"}; #define ERR_NOTFOUND -10 #define ERR_ILLEGAL -11 #define ERR_NOSAMPLES -12 struct SampleData sample[50]; LONG current = 0; LONG avail = 0; struct Values var; LONG rand(void); LONG skipiff; char ConfigName[50] = {"s:play.config"}; #define mindelay var.vl_mindelay #define maxdelay var.vl_maxdelay #define mincyc var.vl_mincyc #define maxcyc var.vl_maxcyc #define maxdiff var.vl_maxdiff #define diff var.vl_diff #define speed var.vl_speed #define Cyc var.vl_Cyc #define vol var.vl_vol #define waittime var.vl_waittime FILE *cfp; long secs; VOID main() { ULONG sig; LONG cmd,ret,quit = FALSE; if(FindPort(CMDPORTNAME)) { printf("Randsam is already running!\n"); exit(0); } OpenAll(); if((ret = ReadConfig()) != NULL) { switch(ret) { case ERR_NOTFOUND : printf("Config file not found!\n"); break; case ERR_ILLEGAL : printf("Minimum and maximum delay values are incorrect\n"); break; case ERR_NOSAMPLES : printf("Must have at least one sample\n"); break; } Quit(); } if(mindelay < 1) mindelay = 1; while(!quit) { secs = (rand() % (maxdelay - mindelay)) + mindelay; TimerReq.tr_time.tv_secs = secs; TimerReq.tr_time.tv_micro= 0; SendIO(&TimerReq.tr_node); waitstate: var.vl_randseed = SysBase->DispCount; srand(var.vl_randseed); /* Get a (I hope) random seed */ if(quit) Quit(); sig = Wait(1<mp_SigBit | 1<mp_SigBit); if(sig & (1<mp_SigBit)) { cmdmessage = (struct commandrequest *)GetMsg(CommandPort); if(cmdmessage != NULL) { cmd = cmdmessage->Command; switch(cmd) { case COM_QUIT : quit = TRUE; break; case COM_PLAY : for(current=0;currentdata1 = (char *)&sample[current]; cmdmessage->data2 = (char *)&var; break; } ReplyMsg(cmdmessage); } } if(sig & (1<mp_SigBit)) { GetMsg(Timermessage); var.vl_cur = current = (rand() % avail); diff = 0; vol = 64; Cyc = 1; if(maxdiff) { diff = ((WORD)rand() % (WORD)maxdiff); if(rand() % 2 == 0) diff *= -1; } if((Cyc = sample[current].Cycles) == 0) { if(maxcyc > 0) Cyc = (WORD)(rand() % (maxcyc-(mincyc-1)))+mincyc; else Cyc = 1; } vol = (WORD)sample[current].Vol; if((vol < 1) || (vol > 64)) vol = (WORD)(rand() % 64)+1; if((speed = sample[current].Period + diff) < 1) speed = 124; PlaySample(); } else goto waitstate; /* prevent multiple timer requests */ } Quit(); exit(0); } ReadConfig() { ULONG temp; if(!(cfp = fopen(&ConfigName[0],"r"))) return(ERR_NOTFOUND); fscanf(cfp,"%ld",&temp); var.vl_mindelay = temp; fscanf(cfp,"%ld",&temp); var.vl_maxdelay = temp; fscanf(cfp,"%ld",&temp); var.vl_maxdiff = temp; fscanf(cfp,"%ld",&temp); var.vl_mincyc = temp; fscanf(cfp,"%ld",&temp); var.vl_maxcyc = temp; fscanf(cfp,"%ld",&temp); avail = var.vl_num = temp; if(maxcyc > 0) if(mincyc < 1) { mincyc = 1; maxcyc++; } if(mindelay > maxdelay) { temp = mindelay; mindelay = maxdelay; maxdelay = temp; } else if((maxdelay == 0) || (maxdelay == mindelay)) return(ERR_ILLEGAL); if(avail < 1) return(ERR_NOSAMPLES); if(avail > 49) avail = 49; for(current = 0;current < avail;current++) { fscanf(cfp,"%s",&(sample[current].Name[0])); fscanf(cfp,"%ld",&temp); (sample[current].Period) = temp; fscanf(cfp,"%ld",&temp); (sample[current].Vol) = temp; fscanf(cfp,"%ld",&temp); (sample[current].Cycles) = temp; } fclose(cfp); return(0); } LoadFile() { int ret = FALSE; fib = NULL; FilePointer = NULL; flock = NULL; sounddata = NULL; if(!(fib = (struct FileInfoBlock *) AllocMem((ULONG)sizeof(struct FileInfoBlock),(ULONG)MEMF_CLEAR))) goto quit; if(!(FilePointer = (char *)Open(sample[current].Name,1005))) goto quit; if(!(flock = (struct Lock *)Lock(sample[current].Name,SHARED_LOCK))) goto quit; if(!(Examine(flock,fib))) goto quit; samlen = fib->fib_Size; sounddata = (UBYTE *)AllocMem((LONG)samlen,MEMF_CHIP | MEMF_CLEAR); if(sounddata == NULL) goto quit; Read(FilePointer,sounddata,samlen); skipiff = CountIFF(); ret = TRUE; quit: if(FilePointer) Close(FilePointer); if(flock) UnLock(flock); if(fib) FreeMem(fib, (ULONG) sizeof(struct FileInfoBlock)); return(ret); } PlaySample() { int ret = FALSE, t = 0; AudioPort = 0; AudioDev = TRUE; sounddata = NULL; if(!LoadFile()) goto qt2; if(!(AudioPort = CreatePort("randsam Audioport"))) goto quit; Audio.ioa_Request.io_Message.mn_Node.ln_Pri = 50; Audio.ioa_Request.io_Message.mn_ReplyPort = AudioPort; Audio.ioa_Request.io_Command = ADCMD_ALLOCATE; Audio.ioa_Data = Channels; Audio.ioa_Length = (long)sizeof(Channels); AudioDev = OpenDevice(AUDIONAME,0,&Audio,0); if(AudioDev != NULL) goto quit; again: Audio.ioa_Request.io_Command = CMD_WRITE; Audio.ioa_Request.io_Flags = ADIOF_PERVOL | ADIOF_SYNCCYCLE; Audio.ioa_Request.io_Unit = (struct Unit *)(rand() % 4); Audio.ioa_Data = (UBYTE *)(sounddata+skipiff); Audio.ioa_Length = samlen; Audio.ioa_Period = speed; Audio.ioa_Cycles = Cyc; Audio.ioa_Volume = vol; BeginIO(&Audio); if(CheckIO(&Audio)) { t++; WaitIO(&Audio); if(t<25) goto again; } WaitIO(&Audio); ret = TRUE; quit: if(!AudioDev) CloseDevice(&Audio); if(AudioPort) DeletePort(AudioPort); qt2: if(sounddata) FreeMem(sounddata,samlen); return(ret); } OpenAll() { if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0))) { printf("No dos.library!\n"); Quit(); }; if((CommandPort=CreatePort(CMDPORTNAME, 0))==NULL) { printf("Cannot setup command port\n"); Quit(); }; if((Timermessage=CreatePort("Randsam Timer Port", 0))==NULL) { printf("Cannot setup a timer port\n"); Quit(); }; TimerReq.tr_node.io_Message.mn_ReplyPort=Timermessage; TimerReq.tr_node.io_Command=TR_ADDREQUEST; TimerReq.tr_node.io_Flags=0; TimerReq.tr_node.io_Error=0; if((TimerDev = OpenDevice(TIMERNAME,UNIT_VBLANK,&TimerReq,0)) != NULL) { printf("Cannot open timer.device!\n"); Quit(); }; return(0); } Quit() { if(DOSBase) CloseLibrary(DOSBase); AbortIO(&TimerReq.tr_node); if(!TimerDev) CloseDevice(&TimerReq); if(Timermessage) DeletePort(Timermessage); if(CommandPort) DeletePort(CommandPort); exit(0); return(0); } CountIFF() { long cnt = 4,ret = 0; if( (sounddata[0] == 'F') && (sounddata[1] == 'O') && (sounddata[2] == 'R') && (sounddata[3] == 'M')) { while(cnt < (samlen-4)) { if( (sounddata[cnt+0] == 'B') && (sounddata[cnt+1] == 'O') && (sounddata[cnt+2] == 'D') && (sounddata[cnt+3] == 'Y')) { ret = cnt+8; cnt = samlen; } cnt++; } } return(ret); }