home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Club Amiga de Montreal - CAM
/
CAM_CD_1.iso
/
files
/
428.lha
/
RandSam
/
src
/
RandSam.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-06
|
9KB
|
298 lines
#include <exec/types.h>
#include <exec/execbase.h>
#include <exec/memory.h>
#include <exec/devices.h>
#include <devices/timer.h>
#include <devices/audio.h>
#include <libraries/dos.h>
#include <libraries/dosextens.h>
#include <stdio.h>
#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<<Timermessage->mp_SigBit | 1<<CommandPort->mp_SigBit);
if(sig & (1<<CommandPort->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;current<avail;current++)
{
Cyc = 1; vol = 64;
speed = sample[current].Period;
PlaySample();
}
break;
case COM_CONF :
waittime = TimerReq.tr_time.tv_secs;
cmdmessage->data1 = (char *)&sample[current];
cmdmessage->data2 = (char *)&var;
break;
}
ReplyMsg(cmdmessage);
}
}
if(sig & (1<<Timermessage->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);
}