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 >
C/C++ Source or Header  |  1990-10-06  |  9KB  |  298 lines

  1. #include <exec/types.h>
  2. #include <exec/execbase.h>
  3. #include <exec/memory.h>
  4. #include <exec/devices.h>
  5. #include <devices/timer.h>
  6. #include <devices/audio.h>
  7. #include <libraries/dos.h>
  8. #include <libraries/dosextens.h>
  9. #include <stdio.h>
  10. #include "randcmd.h"
  11.  
  12. extern struct ExecBase      *SysBase;
  13. extern struct DosLibrary    *DOSBase;
  14. struct FileInfoBlock        *fib;
  15. struct Lock                 *flock;
  16.  
  17. struct MsgPort              *CreatePort();
  18. struct MsgPort              *AudioPort;
  19. struct IOAudio               Audio;
  20. struct MsgPort              *Timermessage;
  21. struct timerequest           TimerReq;
  22. struct MsgPort              *CommandPort;
  23. struct commandrequest       *cmdmessage;
  24. struct Message              *GetMsg();
  25.  
  26. char *FilePointer;
  27. UBYTE Channels[] = { 0x0F };
  28. short AudioDev = NULL,TimerDev = NULL;
  29. UBYTE *sounddata;
  30. ULONG  samlen;
  31.  
  32.  
  33. char RandSamVers[50] = {"Randsam v1.1 , by Steven Lagerweij 030490"};
  34.  
  35. #define ERR_NOTFOUND  -10
  36. #define ERR_ILLEGAL   -11
  37. #define ERR_NOSAMPLES -12
  38.  
  39. struct SampleData sample[50];
  40.  
  41. LONG current = 0;
  42. LONG avail   = 0;
  43.  
  44. struct Values var;
  45.  
  46. LONG rand(void);
  47. LONG skipiff;
  48. char ConfigName[50] = {"s:play.config"};
  49.  
  50. #define mindelay var.vl_mindelay
  51. #define maxdelay var.vl_maxdelay
  52. #define mincyc   var.vl_mincyc
  53. #define maxcyc   var.vl_maxcyc
  54. #define maxdiff  var.vl_maxdiff
  55. #define diff     var.vl_diff
  56. #define speed    var.vl_speed
  57. #define Cyc      var.vl_Cyc
  58. #define vol      var.vl_vol
  59. #define waittime var.vl_waittime
  60.  
  61. FILE *cfp;
  62.  
  63. long secs;
  64.  
  65. VOID main()
  66. {
  67. ULONG sig;
  68. LONG cmd,ret,quit = FALSE;
  69.     if(FindPort(CMDPORTNAME))
  70.       { printf("Randsam is already running!\n"); exit(0); }
  71.  
  72.     OpenAll();
  73.     if((ret = ReadConfig()) != NULL)
  74.       {
  75.       switch(ret)
  76.         {
  77.         case ERR_NOTFOUND  : printf("Config file not found!\n"); break;
  78.         case ERR_ILLEGAL   : printf("Minimum and maximum delay values are incorrect\n"); break;
  79.         case ERR_NOSAMPLES : printf("Must have at least one sample\n"); break;
  80.         }
  81.       Quit();
  82.       }
  83.     if(mindelay < 1) mindelay = 1;
  84.     while(!quit)
  85.       {
  86.         secs = (rand() % (maxdelay - mindelay)) + mindelay;
  87.         TimerReq.tr_time.tv_secs = secs;
  88.         TimerReq.tr_time.tv_micro= 0;
  89.         SendIO(&TimerReq.tr_node);
  90. waitstate:
  91.         var.vl_randseed = SysBase->DispCount;
  92.         srand(var.vl_randseed); /* Get a (I hope) random seed */
  93.         if(quit) Quit();
  94.         sig = Wait(1<<Timermessage->mp_SigBit | 1<<CommandPort->mp_SigBit);
  95.  
  96.         if(sig & (1<<CommandPort->mp_SigBit))
  97.           {
  98.             cmdmessage = (struct commandrequest *)GetMsg(CommandPort);
  99.             if(cmdmessage != NULL)
  100.               {
  101.                 cmd = cmdmessage->Command;
  102.                 switch(cmd)
  103.                   {
  104.                     case COM_QUIT : quit = TRUE; break;
  105.                     case COM_PLAY : for(current=0;current<avail;current++)
  106.                                       {
  107.                                          Cyc = 1; vol = 64;
  108.                                          speed = sample[current].Period;
  109.                                          PlaySample();
  110.                                       }
  111.                                     break;
  112.                     case COM_CONF :
  113.                                     waittime = TimerReq.tr_time.tv_secs;
  114.                                     cmdmessage->data1 = (char *)&sample[current];
  115.                                     cmdmessage->data2 = (char *)&var;
  116.                                     break;
  117.                   }
  118.                 ReplyMsg(cmdmessage);
  119.               }
  120.           }
  121.         if(sig & (1<<Timermessage->mp_SigBit))
  122.           {
  123.             GetMsg(Timermessage);
  124.             var.vl_cur = current = (rand() % avail);
  125.             diff = 0; vol = 64; Cyc = 1;
  126.             if(maxdiff)
  127.               {
  128.                 diff = ((WORD)rand() % (WORD)maxdiff);
  129.                 if(rand() % 2 == 0) diff *= -1;
  130.               }
  131.             if((Cyc = sample[current].Cycles) == 0)
  132.               {
  133.                 if(maxcyc > 0) Cyc = (WORD)(rand() % (maxcyc-(mincyc-1)))+mincyc;
  134.                 else Cyc = 1;
  135.               }
  136.             vol = (WORD)sample[current].Vol;
  137.             if((vol < 1) || (vol > 64)) vol = (WORD)(rand() % 64)+1;
  138.             if((speed = sample[current].Period + diff) < 1) speed = 124;
  139.             PlaySample();
  140.           }
  141.         else goto waitstate; /* prevent multiple timer requests */
  142.       }
  143. Quit();
  144. exit(0);
  145. }
  146.  
  147. ReadConfig()
  148. {
  149. ULONG temp;
  150.  
  151.     if(!(cfp = fopen(&ConfigName[0],"r"))) return(ERR_NOTFOUND);
  152.  
  153.     fscanf(cfp,"%ld",&temp); var.vl_mindelay = temp;
  154.     fscanf(cfp,"%ld",&temp); var.vl_maxdelay = temp;
  155.     fscanf(cfp,"%ld",&temp); var.vl_maxdiff  = temp;
  156.     fscanf(cfp,"%ld",&temp); var.vl_mincyc   = temp;
  157.     fscanf(cfp,"%ld",&temp); var.vl_maxcyc   = temp;
  158.     fscanf(cfp,"%ld",&temp); avail = var.vl_num = temp;
  159.     if(maxcyc > 0) if(mincyc < 1) { mincyc = 1; maxcyc++; }
  160.  
  161.     if(mindelay > maxdelay)
  162.       { temp = mindelay; mindelay = maxdelay; maxdelay = temp; }
  163.     else if((maxdelay == 0) || (maxdelay == mindelay)) return(ERR_ILLEGAL);
  164.     if(avail < 1) return(ERR_NOSAMPLES);
  165.     if(avail > 49) avail = 49;
  166.     for(current = 0;current < avail;current++)
  167.       {
  168.         fscanf(cfp,"%s",&(sample[current].Name[0]));
  169.         fscanf(cfp,"%ld",&temp); (sample[current].Period) = temp;
  170.         fscanf(cfp,"%ld",&temp); (sample[current].Vol) = temp;
  171.         fscanf(cfp,"%ld",&temp); (sample[current].Cycles) = temp;
  172.       }
  173.     fclose(cfp);
  174.     return(0);
  175. }
  176.  
  177. LoadFile()
  178. {
  179.   int ret = FALSE;
  180.   fib = NULL; FilePointer = NULL; flock = NULL; sounddata = NULL;
  181.  
  182.   if(!(fib = (struct FileInfoBlock *)
  183.       AllocMem((ULONG)sizeof(struct FileInfoBlock),(ULONG)MEMF_CLEAR)))
  184.        goto quit;
  185.   if(!(FilePointer = (char *)Open(sample[current].Name,1005))) goto quit;
  186.   if(!(flock = (struct Lock *)Lock(sample[current].Name,SHARED_LOCK))) goto quit;
  187.   if(!(Examine(flock,fib))) goto quit;
  188.   samlen = fib->fib_Size;
  189.   sounddata = (UBYTE *)AllocMem((LONG)samlen,MEMF_CHIP | MEMF_CLEAR);
  190.   if(sounddata == NULL) goto quit;
  191.  
  192.   Read(FilePointer,sounddata,samlen);
  193.   skipiff = CountIFF();
  194.   ret = TRUE;
  195. quit:
  196.   if(FilePointer) Close(FilePointer);
  197.   if(flock)       UnLock(flock);
  198.   if(fib)         FreeMem(fib, (ULONG) sizeof(struct FileInfoBlock));
  199.   return(ret);
  200. }
  201.  
  202.  
  203. PlaySample()
  204. {
  205. int ret = FALSE, t = 0;
  206.     AudioPort = 0;
  207.     AudioDev  = TRUE;
  208.     sounddata = NULL;
  209.  
  210.     if(!LoadFile()) goto qt2;
  211.     if(!(AudioPort = CreatePort("randsam Audioport"))) goto quit;
  212.     Audio.ioa_Request.io_Message.mn_Node.ln_Pri = 50;
  213.     Audio.ioa_Request.io_Message.mn_ReplyPort   = AudioPort;
  214.     Audio.ioa_Request.io_Command                = ADCMD_ALLOCATE;
  215.     Audio.ioa_Data                              = Channels;
  216.     Audio.ioa_Length                            = (long)sizeof(Channels);
  217.  
  218.     AudioDev = OpenDevice(AUDIONAME,0,&Audio,0);
  219.     if(AudioDev != NULL) goto quit;
  220.  
  221. again:
  222.     Audio.ioa_Request.io_Command = CMD_WRITE;
  223.     Audio.ioa_Request.io_Flags   = ADIOF_PERVOL | ADIOF_SYNCCYCLE;
  224.     Audio.ioa_Request.io_Unit    = (struct Unit *)(rand() % 4);
  225.     Audio.ioa_Data               = (UBYTE *)(sounddata+skipiff);
  226.     Audio.ioa_Length             = samlen;
  227.     Audio.ioa_Period             = speed;
  228.     Audio.ioa_Cycles             = Cyc;
  229.     Audio.ioa_Volume             = vol;
  230.  
  231.     BeginIO(&Audio);
  232.     if(CheckIO(&Audio))
  233.       {
  234.         t++; WaitIO(&Audio);
  235.         if(t<25) goto again;
  236.       }
  237.     WaitIO(&Audio);
  238.     ret = TRUE;
  239. quit:
  240.     if(!AudioDev)   CloseDevice(&Audio);
  241.     if(AudioPort)   DeletePort(AudioPort);
  242. qt2:
  243.     if(sounddata)   FreeMem(sounddata,samlen);
  244. return(ret);
  245. }
  246.  
  247. OpenAll()
  248. {
  249.  if(!(DOSBase = (struct DosLibrary *)OpenLibrary("dos.library",0)))
  250.     { printf("No dos.library!\n"); Quit(); };
  251.  
  252.  if((CommandPort=CreatePort(CMDPORTNAME, 0))==NULL)
  253.     { printf("Cannot setup command port\n"); Quit(); };
  254.  if((Timermessage=CreatePort("Randsam Timer Port", 0))==NULL)
  255.     { printf("Cannot setup a timer port\n"); Quit(); };
  256.  TimerReq.tr_node.io_Message.mn_ReplyPort=Timermessage;
  257.  TimerReq.tr_node.io_Command=TR_ADDREQUEST;
  258.  TimerReq.tr_node.io_Flags=0;
  259.  TimerReq.tr_node.io_Error=0;
  260.  if((TimerDev = OpenDevice(TIMERNAME,UNIT_VBLANK,&TimerReq,0)) != NULL)
  261.     { printf("Cannot open timer.device!\n"); Quit(); };
  262.  
  263. return(0);
  264. }
  265.  
  266.  
  267. Quit()
  268. {
  269.     if(DOSBase) CloseLibrary(DOSBase);
  270.     AbortIO(&TimerReq.tr_node);
  271.     if(!TimerDev)    CloseDevice(&TimerReq);
  272.     if(Timermessage) DeletePort(Timermessage);
  273.     if(CommandPort)  DeletePort(CommandPort);
  274. exit(0); return(0);
  275. }
  276.  
  277. CountIFF()
  278. {
  279.     long cnt = 4,ret = 0;
  280.  
  281.     if( (sounddata[0] == 'F') &&
  282.         (sounddata[1] == 'O') &&
  283.         (sounddata[2] == 'R') &&
  284.         (sounddata[3] == 'M'))
  285.       {
  286.         while(cnt < (samlen-4))
  287.           {
  288.             if( (sounddata[cnt+0] == 'B') &&
  289.                 (sounddata[cnt+1] == 'O') &&
  290.                 (sounddata[cnt+2] == 'D') &&
  291.                 (sounddata[cnt+3] == 'Y'))
  292.                     { ret = cnt+8; cnt = samlen; }
  293.             cnt++;
  294.           }
  295.       }
  296. return(ret);
  297. }
  298.