home *** CD-ROM | disk | FTP | other *** search
/ Frozen Fish 1: Amiga / FrozenFish-Apr94.iso / bbs / alib / d1xx / d114 / wblander.lha / WBLander / Source / player.c < prev    next >
C/C++ Source or Header  |  1987-11-22  |  6KB  |  295 lines

  1. #include <exec/types.h>
  2. #include <exec/memory.h>
  3. #include <devices/audio.h>
  4. #include <stdio.h>
  5. #include "sample.h"
  6. #include "sounds.h"
  7.  
  8. #define YES 1
  9. #define NO 0
  10.  
  11. extern int debug;
  12.  
  13. /* #define WHERE fprintf(stderr,"%s %s %d\n",__FILE__,__FUNC__,__LINE__); */
  14. /* #define WHAT(x) fprintf(stderr,"%s %s %d %s\n",__FILE__,__FUNC__,__LINE__,x->name); */
  15. #define WHERE
  16. #define WHAT(x)
  17.  
  18. #define CLOCKFREQ 3579545
  19.  
  20. extern Sound *sounds[];
  21. extern int maxsounds;
  22.  
  23. int audio_up = NO;            /* set to yes after initilization is complete, */
  24.                             /* used by "endaudio" to figure out clean up */
  25.  
  26. struct Device *AudioDevice;
  27. struct MsgPort *AudioPort;
  28. struct IOAudio *openIOB;
  29.  
  30. static UBYTE LeftMap[] = {LEFT0, LEFT1};
  31. static UBYTE RightMap[] = {RIGHT0, RIGHT1};
  32. static UBYTE TryLeftMap[] = {LEFT1, LEFT0, RIGHT1, RIGHT0};
  33. static UBYTE TryRightMap[] = {RIGHT1, RIGHT0, LEFT1, LEFT0};
  34.  
  35. _abort()
  36. {
  37.     fputs("abort caused by ^C or audio panic\n",stderr);
  38.     cleanup(debug);
  39.     exit(10);
  40. }
  41.  
  42. panic(s)
  43. char *s;
  44. {
  45.     fprintf(stderr,"panic: %s\n",s);
  46.     _abort();
  47. }
  48.  
  49. struct IOAudio *IOBallocate()
  50. {
  51.     struct IOAudio *IOB;
  52.  
  53.     if ((IOB = (struct IOAudio *)AllocMem(sizeof(struct IOAudio), MEMF_PUBLIC | MEMF_CLEAR)) == (struct IOAudio *) NULL)
  54.         panic("IOBallocate failed"); 
  55.  
  56.     return(IOB);
  57. }
  58.  
  59. IOBfree(IOBp)
  60. struct IOAudio *IOBp;
  61. {
  62.     if (IOBp != NULL)
  63.         FreeMem(IOBp, sizeof(struct IOAudio));
  64. }
  65.  
  66.  
  67. InitPlayIOB(soundp)
  68. Sound *soundp;
  69. {
  70.     struct IOAudio *IOB = soundp->IOBs[PLAY_IOB];
  71.  
  72.     IOB->ioa_Request.io_Command = CMD_WRITE;
  73.     IOB->ioa_Request.io_Flags = ADIOF_PERVOL;
  74.     IOB->ioa_Volume = soundp->volume;
  75.     IOB->ioa_Cycles = soundp->cycles;
  76.     IOB->ioa_Data = (UBYTE *)&soundp->samplep->sampledata[0];
  77.     IOB->ioa_Length = (ULONG)soundp->samplep->nsamples;
  78.     IOB->ioa_Period = (CLOCKFREQ / soundp->samplep->sampsec) + soundp->detune;
  79. }
  80.  
  81. InitStopIOB(soundp)
  82. Sound *soundp;
  83. {
  84.     struct IOAudio *IOB = soundp->IOBs[STOP_IOB];
  85.  
  86.     IOB->ioa_Request.io_Command = ADCMD_FINISH;
  87.     IOB->ioa_Request.io_Flags = IOF_QUICK;
  88. }
  89.  
  90.  
  91. InitAllocIOB(soundp)
  92. Sound *soundp;
  93. {
  94.     struct IOAudio *allocIOB = soundp->IOBs[ALLOC_IOB];
  95.  
  96.     allocIOB->ioa_Request.io_Command = ADCMD_ALLOCATE;
  97.     allocIOB->ioa_Request.io_Message.mn_Node.ln_Pri = soundp->precedence;
  98.  
  99.     if (!soundp->flags & EITHER) {
  100.         allocIOB->ioa_Data = (soundp->flags & LEFT) ? LeftMap : RightMap;
  101.         allocIOB->ioa_Length = 2;
  102.     } else {
  103.         allocIOB->ioa_Data = (soundp->flags & LEFT) ? TryLeftMap : TryRightMap;
  104.         allocIOB->ioa_Length = 4;
  105.     }
  106.  
  107.     allocIOB->ioa_Request.io_Flags = (ADIOF_NOWAIT | IOF_QUICK);
  108. }
  109.  
  110. InitDeallocIOB(soundp)
  111. Sound *soundp;
  112. {
  113.     struct IOAudio *IOB = soundp->IOBs[FREE_IOB];
  114.  
  115.     IOB->ioa_Request.io_Command = ADCMD_FREE;
  116.     IOB->ioa_Request.io_Flags = IOF_QUICK;
  117. }
  118.  
  119.  
  120. initsound(soundindex)
  121. int soundindex;
  122. {
  123.     int i;
  124.     struct IOAudio *IOB;
  125.     Sound *soundp = sounds[soundindex];
  126.  
  127.     if ((soundp->port = CreatePort(soundp->name, 0)) == 0)
  128.     {
  129.         fprintf(stderr,"can't create audio port \"%s\"\n",soundp->name);
  130.         panic("can't create audio port");
  131.     }
  132.  
  133.     for (i = 0; i < MAX_SOUND_IOBS; i++)
  134.     {
  135.         IOB = soundp->IOBs[i] = IOBallocate();
  136.  
  137.         IOB->ioa_Request.io_Message.mn_ReplyPort = soundp->port;
  138.         IOB->ioa_Request.io_Device = AudioDevice;
  139.  
  140.         /* We assign our own AllocKeys so we'll have a handle to determine
  141.          * which sound structure we received at a reply port.  This also
  142.          * makes playtime overhead less by not having to throw around
  143.          * dynamically-allocated allocation keys.  If AllocKey
  144.          * is zero when channels are allocated, a key is dynamically assigned
  145.          * We use soundindex + 1 instead of soundindex to prevent a zero
  146.          * allockey.  Also, we reduce playtime overhead by not throwing
  147.          * dynamically-assigned keys around.
  148.          */
  149.  
  150.         IOB->ioa_AllocKey = soundindex + 1;
  151.     }
  152.  
  153.     InitPlayIOB(soundp);
  154.     InitStopIOB(soundp);
  155.     InitAllocIOB(soundp);
  156.     InitDeallocIOB(soundp);
  157. }
  158.  
  159. initaudio()
  160. {
  161.     int i;
  162.  
  163.     openIOB = IOBallocate();
  164.  
  165.     if (OpenDevice(AUDIONAME, 0, openIOB, 0) != 0)
  166.         panic("can't open audio device");
  167.  
  168.     AudioDevice = openIOB->ioa_Request.io_Device;
  169.  
  170.     for (i = 0; i < maxsounds; i++)
  171.         initsound(i);
  172.  
  173.     audio_up = YES;
  174. }
  175.  
  176. endaudio()
  177. {
  178.         int i, j;
  179.  
  180.  
  181.         if (audio_up)
  182.             {
  183.                 for (i = 0; i < maxsounds; i++)
  184.                 StopSound(sounds[i]);
  185.             }
  186.  
  187.         for (i = 0; i < maxsounds; i++)
  188.         {
  189.             for (j = 0; j < MAX_SOUND_IOBS; j++)
  190.                 IOBfree(sounds[i]->IOBs[j]);
  191.             if (sounds[i]->port)
  192.                 DeletePort(sounds[i]->port,sizeof(struct MsgPort));
  193.         }
  194.         CloseDevice(openIOB);
  195.         IOBfree(openIOB);
  196. }
  197.  
  198. PlaySound(soundp)
  199. Sound *soundp;
  200. {
  201.     int i;
  202.  
  203.     struct IOAudio *allocIOB = soundp->IOBs[ALLOC_IOB];
  204.     struct IOAudio *playIOB = soundp->IOBs[PLAY_IOB];
  205.  
  206.     if (soundp->flags & PLAYING)
  207.         return;
  208.  
  209.     BeginIO(allocIOB);
  210.  
  211.     /* the only possible error return is ADIOERR_NOALLOCATION */
  212.     if (allocIOB->ioa_Request.io_Error)
  213.         return;
  214.  
  215.     for (i = PLAY_IOB; i <= FREE_IOB; i++)
  216.         soundp->IOBs[i]->ioa_Request.io_Unit = allocIOB->ioa_Request.io_Unit;
  217.  
  218.     BeginIO(playIOB);
  219.  
  220.     /* possible errors are IOERR_ABORTED and ADIOERR_NOALLOCATION */
  221.     if (playIOB->ioa_Request.io_Error)
  222.         return;
  223.  
  224.     soundp->flags |= PLAYING;
  225. }
  226.  
  227. DeallocSound(soundp)
  228. Sound *soundp;
  229. {
  230.     struct IOAudio *freeIOB = soundp->IOBs[FREE_IOB];
  231.  
  232.     BeginIO(freeIOB);
  233.  
  234.     /* only possible error return is ADIOERR_NOALLOCATION */
  235. }
  236.  
  237. StopSound(soundp)
  238. Sound *soundp;
  239. {
  240.     struct IOAudio *stopIOB = soundp->IOBs[STOP_IOB];
  241.     struct IOAudio *freeIOB= soundp->IOBs[FREE_IOB];
  242.  
  243.     WHAT(soundp);
  244.     if (soundp->flags & PLAYING)
  245.     {
  246.         soundp->flags &= ~PLAYING;
  247.         BeginIO(stopIOB);
  248.         /* only error return is ADIOERR_NOALLOCATION */
  249.  
  250.         WaitIO(soundp->IOBs[PLAY_IOB]);
  251.         /* error returns can be IOERR_ABORTED and ADIOERR_NOALLOCATION */
  252.     }
  253.     DeallocSound(soundp);
  254. }
  255.  
  256. WaitSound(soundp)
  257. Sound *soundp;
  258. {
  259.     WHAT(soundp);
  260.  
  261.     if (soundp->flags & PLAYING)
  262.     {
  263.         WaitIO(soundp->IOBs[PLAY_IOB]);
  264.         soundp->flags &= ~PLAYING;
  265.     }
  266.     DeallocSound(soundp);
  267. }
  268.  
  269. dumpsound(soundp)
  270. Sound *soundp;
  271. {
  272.     printf("dump of sound %s\n",soundp->name);
  273.     printf("cycles %d, volume %d, flags %d, precedence %d, detune %d\n",
  274.         soundp->cycles, soundp->volume, soundp->flags, soundp->precedence,
  275.         soundp->detune);
  276.     dumpsample(soundp->samplep);
  277. }
  278.  
  279. dumpsample(samptr)
  280. Sample *samptr;
  281. {
  282.     int i, linect;
  283.     printf("nsamples %d, sampsec %d\n",samptr->nsamples, samptr->sampsec);
  284.     /* for (i = 0; i < samptr->nsamples; i++)
  285.     {
  286.         printf("%4d ",samptr->sampledata[i]);
  287.         if (++linect > 14)
  288.         {
  289.             putchar('\n');
  290.             linect = 0;
  291.         }
  292.     } */
  293. }
  294.  
  295.