home *** CD-ROM | disk | FTP | other *** search
- /* audio.c Martin Round November '89
-
- This code is taken straight from Steven A. Bennett's 'scales.c'
- Thanks Steven!
- I've mostly left the code in it's original state, only putting in
- a few function prototypes and 'voids' to stop my compiler issuing
- me with warnings.
- I've also stripped comments and altered bracket indenting into my own
- weird style - sorry Steven! Actually it's not my own style, I'm driven
- to use it by a stupid Lint-like program I use called 'ccheck'.
- */
-
- #define PRIORITY 10L
- #define NBR_IOA_STRUCTS 10L
- #define PV_IOA_STRUCT 0L
- #define FIN_IOA_STRUCT 9L
- #define BIG_WAVE 256L
- #define NBR_WAVES 7L
- #define WAVES_TOTAL 1024L
- #define YES 1L
- #define NO 0L
-
- extern struct MsgPort *CreatePort();
- extern void *AllocMem();
-
- void clear_audio (int);
-
- UBYTE aMap[] = { 0x0f };
- long voiceMap[] = { 1, 2, 4, 8 };
- struct IOAudio *ioa, *finishioa, *ioapv;
- struct IOAudio *ioainuse[4];
- struct IOAudio *freeioa[4];
- long unitno = 1;
- int error;
- int waiting[4] = { NO, NO, NO, NO };
- int woffsets[] =
- { 0, 256, 384, 448, 480, 496, 504, 508, 510 };
- int wlen[] =
- { 256, 128, 64, 32, 16, 8, 4, 2, 1 };
- int perval[] =
- { 428, 404, 381, 360, 339, 320, 302, 285, 269, 254, 240, 226, 214 };
- BYTE *wptr;
- BYTE *owptr[4] = { NULL, NULL, NULL, NULL };
-
- char *portstring[] =
- {
- "Audio one",
- "Audio two",
- "Audio three",
- "Audio four",
- "Audio five",
- "Audio six",
- "Audio seven",
- "Audio eight"
- };
-
- int get_audio()
- {
- int i;
-
- ioa = (struct IOAudio *)
- AllocMem((NBR_IOA_STRUCTS * (long)sizeof(*ioa)),MEMF_PUBLIC | MEMF_CLEAR);
- if (ioa == NULL)
- {
- clear_audio(1);
- return(0);
- }
-
- for (i = 0; i < 4; ++i)
- {
- ioainuse[i] = &ioa[i + 1];
- freeioa[i] = &ioa[i + 5];
- }
- ioapv = &ioa[PV_IOA_STRUCT];
- finishioa = &ioa[FIN_IOA_STRUCT];
-
- ioa->ioa_Request.io_Message.mn_Node.ln_Pri = PRIORITY;
- ioa->ioa_Request.io_Message.mn_ReplyPort =
- CreatePort("Audio zero", 0L);
- if (ioa->ioa_Request.io_Message.mn_ReplyPort == NULL)
- {
- clear_audio(2);
- return(0);
- }
- ioa->ioa_Data = aMap;
- ioa->ioa_Length = (long)sizeof(aMap);
- error = OpenDevice(AUDIONAME, 0L, (struct ioRequest *) ioa, 0L);
- if (error)
- {
- clear_audio(3);
- return(0);
- }
-
- *finishioa = *ioa;
- finishioa->ioa_Request.io_Flags = IOF_QUICK;
- ioapv->ioa_Request.io_Flags = IOF_QUICK;
-
- finishioa->ioa_Request.io_Command = ADCMD_FINISH;
- ioapv->ioa_Request.io_Command = ADCMD_PERVOL;
-
- for (i = 0; i < 4; ++i)
- {
- *freeioa[i] = *ioa;
- *ioainuse[i] = *ioa;
- freeioa[i]->ioa_Request.io_Message.mn_ReplyPort =
- CreatePort(portstring[i], 0L);
- ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort =
- CreatePort(portstring[i + 4], 0L);
- }
- for (i = 0; i < 4; ++i)
- if
- (
- freeioa[i]->ioa_Request.io_Message.mn_ReplyPort == NULL ||
- ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort == NULL
- )
- {
- clear_audio(4);
- return (0);
- }
- return (makewaves());
- }
-
- void clear_audio(finishcode)
- int finishcode;
- {
- int i;
-
- switch(finishcode)
- {
- case 0:
-
- FreeMem(wptr, WAVES_TOTAL);
-
- case 4:
- case 5:
-
- for (i = 0; i < 4; ++i)
- {
- if (freeioa[i]->ioa_Request.io_Message.mn_ReplyPort)
- DeletePort(freeioa[i]->ioa_Request.io_Message.mn_ReplyPort);
- if (ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort)
- DeletePort(ioainuse[i]->ioa_Request.io_Message.mn_ReplyPort);
- }
-
-
- CloseDevice((struct ioRequest *) ioa);
-
- case 3:
-
- DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
-
- case 2:
-
- FreeMem(ioa, (NBR_IOA_STRUCTS * (long)sizeof(*ioa)));
-
- }
-
- }
-
- void setwpv(wf, len, per, vol, voice)
- char *wf;
- int len, per, vol, voice;
- {
- struct IOAudio *tmpioa;
-
- freeioa[voice]->ioa_Request.io_Command = CMD_WRITE;
- freeioa[voice]->ioa_Request.io_Flags = ADIOF_PERVOL | IOF_QUICK;
- freeioa[voice]->ioa_Cycles = 0;
-
- freeioa[voice]->ioa_Request.io_Unit = (struct Unit *)unitno;
- finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
-
-
- freeioa[voice]->ioa_Data = (UBYTE *)wf;
- freeioa[voice]->ioa_Length = len;
- freeioa[voice]->ioa_Period = per;
- freeioa[voice]->ioa_Volume = vol;
-
- if (waiting[voice])
- {
- BeginIO((struct ioRequest *) finishioa);
- WaitIO((struct ioRequest *) ioainuse[voice]);
- waiting[voice] = NO;
- }
-
-
- BeginIO((struct ioRequest *) freeioa[voice]);
- error = CheckIO((struct ioRequest *) freeioa[voice]);
- if (error)
- WaitIO((struct ioRequest *) freeioa[voice]);
-
- waiting[voice] = YES;
-
- tmpioa = ioainuse[voice];
- ioainuse[voice] = freeioa[voice];
- freeioa[voice] = tmpioa;
- }
-
- void setpv(per, vol)
- int per, vol;
- {
- ioapv->ioa_Period = per;
- ioapv->ioa_Volume = vol;
- ioapv->ioa_Request.io_Unit = (struct Unit *)unitno;
- BeginIO((struct ioRequest *) ioapv);
- }
-
- void StopVoices()
- {
- int voice;
-
- for (voice = 0; voice < 4; ++voice)
- {
- if (waiting[voice])
- {
- unitno = voiceMap[voice];
- setpv(128, 0);
- finishioa->ioa_Request.io_Unit = (struct Unit *)unitno;
- BeginIO((struct ioRequest *) finishioa);
- WaitIO((struct ioRequest *) ioainuse[voice]);
- waiting[voice] = NO;
- }
- }
- }
-
- void setwave(wfp)
- UBYTE *wfp;
- {
- int i;
-
- for (i = 0; i < BIG_WAVE; ++i)
- wfp[i] = i;
- }
-
- void xpandwave(wfp)
- BYTE *wfp;
- {
- int i, j, rate;
- BYTE *tptr;
-
- rate = 1;
- tptr = wfp + BIG_WAVE;
- for (i = 0; i < NBR_WAVES - 1; ++i)
- {
- rate *= 2;
- for (j = 0; j < BIG_WAVE; j += rate)
- *tptr++ = wfp[j];
- }
- }
-
- int makewaves()
- {
- wptr = (BYTE *)AllocMem(WAVES_TOTAL, MEMF_CHIP);
- if (wptr == NULL)
- {
- clear_audio(5);
- return (0);
- }
-
- setwave(wptr);
- xpandwave(wptr);
- return (1);
- }
-
- void play_note(note, voice)
- int note, voice;
- {
- int per, oct;
- BYTE *wfp;
-
- unitno = voiceMap[voice];
- if (note >= 100)
- {
- if (waiting[voice])
- setpv(200, 0);
- return;
- }
- oct = note / 12;
- per = perval[note % 12];
- wfp = wptr + woffsets[oct];
-
- if (wfp == owptr[voice])
- setpv(per, 32);
- else
- {
- setwpv(wfp, wlen[oct], per, 32, voice);
- owptr[voice] = wfp;
- }
- }