home *** CD-ROM | disk | FTP | other *** search
- /* PlaySound.c */
- /* This routine sets up an ioRequest and plays back a */
- /* waveform through the Amiga audio hardware */
-
- /* Usage : PlaySound(buffer,repeat,period,volume) */
- /* buffer is a pointer to a waveform */
- /* repeat is the number of times to play the wave (0 == forever) */
- /* period determines the playback rate (minimum value == 124) */
- /* volume goes from 0 to 64 */
-
- #include "exec/types.h"
- #include "devices/audio.h"
- #include "exec/memory.h"
- #include "SoundErrors.h"
-
- #define LEFT0F 1
- #define RIGHT0F 2
- #define RIGHT1F 4
- #define LEFT1F 8
-
- extern struct MsgPort *CreatePort();
-
- /* Look for a left channel, then a right */
- UBYTE allocationMap[] = {LEFT0F,LEFT1F,RIGHT0F,RIGHT1F};
-
- /* Allocate and initialize an IO Request Block */
- SetIOA(per,vol,repeat,len,ioa)
- int per,vol,repeat;
- ULONG len;
- struct IOAudio **ioa;
- {
- struct MsgPort *port;
- char *PortName;
-
- PortName = "Sound Channel";
-
- /* Allocate IOAudio structure */
- (*ioa) = (struct IOAudio *)AllocMem(sizeof(struct IOAudio),
- MEMF_PUBLIC|MEMF_CLEAR);
-
- /* If Allocation Successful ... */
- if((*ioa)!=0)
- {
- /* Set Priority */
- (*ioa)->ioa_Request.io_Message.mn_Node.ln_Pri = 10;
- /* Create Message port for IORequest to talk to Amiga */
- if ((port = CreatePort(PortName,0)) == 0)
- {
- FreeMem((*ioa),sizeof(struct IOAudio));
- }
- /* If Creation Successful ... */
- else
- {
- /* Get a channel */
- (*ioa)->ioa_Request.io_Message.mn_ReplyPort = port;
- (*ioa)->ioa_Data = allocationMap;
- (*ioa)->ioa_Length = sizeof(allocationMap);
- /* Open Audio Device for output */
- if(OpenDevice(AUDIONAME,0,(*ioa),0) != 0)
- {
- DeletePort(port);
- FreeMem((*ioa),sizeof(struct IOAudio));
- }
- /* If open worked ... */
- else
- {
- /* Set Up Request */
- (*ioa)->ioa_Request.io_Flags = ADIOF_PERVOL;
- (*ioa)->ioa_Request.io_Command = CMD_WRITE;
- (*ioa)->ioa_Period = per;
- (*ioa)->ioa_Volume = vol;
-
- /* For some reason, the Audio chip can't play samples */
- /* longer than 131k, so we kludge. Oh, well. */
- if(len<131000)
- {
- (*ioa)->ioa_Cycles = repeat;
- }
- else
- {
- (*ioa)->ioa_Cycles = 1;
- }
- }
- }
- }
- }
-
- /* Play a sound */
- struct IOAudio *PlaySound(buffer,buflen,repeat,period,volume)
- BYTE *buffer;
- ULONG buflen;
- int repeat,period,volume;
- {
- struct IOAudio *ioa;
- BYTE *DataPtr;
- ULONG PlayLen=0;
- int sound_done=0;
- int count;
-
- count = repeat?(repeat-1):-1;
- DataPtr = buffer;
-
- /* Set Up IOAudio structure */
- SetIOA(period,volume,repeat,buflen,&ioa);
-
- /* Set up data and length pointers of ioa */
- SetLength(&PlayLen,buflen,&DataPtr,ioa);
-
- /* Send command to Audio chip */
- BeginIO(ioa);
-
- /* If no data remains to play, return ioa pointer */
- if(PlayLen == 0)
- {
- return(ioa);
- }
-
- /* If there is more (buflen >131000), continue until there isn't */
- while(!sound_done)
- {
- /* If current chunk is done ... */
- if(CheckIO(ioa))
- {
- /* If more remains, continue */
- if(PlayLen > 0)
- {
- /* update pointers and start next chunk */
- FixLength(&PlayLen,&DataPtr,ioa);
- BeginIO(ioa);
- if((PlayLen == 0) && (count == 0))
- {
- return(ioa);
- }
- }
- /* If not ... */
- else
- {
- /* Check repeat counter */
- if(count != 0)
- {
- /* Restart wave */
- DataPtr = buffer;
- SetLength(&PlayLen,buflen,&DataPtr,ioa);
- BeginIO(ioa);
- if(count>0)
- {
- count--;
- }
- }
- else
- {
- /* finished */
- sound_done = 1;
- }
- }
- }
- }
- /* Free IOAudio stuff */
- StopSound(ioa);
- }
-
- StopSound(ioa)
- struct IOAudio *ioa;
- {
- AbortIO(ioa);
- if(ioa->ioa_Request.io_Device)
- {
- CloseDevice(ioa);
- }
- if(ioa->ioa_Request.io_Message.mn_ReplyPort)
- {
- DeletePort(ioa->ioa_Request.io_Message.mn_ReplyPort);
- }
- if(ioa)
- {
- FreeMem(ioa,sizeof(struct IOAudio));
- }
- }
-
- SetLength(LenPtr,buflen,DataHndl,ioa)
- ULONG *LenPtr,buflen;
- BYTE **DataHndl;
- struct IOAudio *ioa;
- {
- if(buflen<= 131000)
- {
- (*LenPtr) = buflen;
- }
- else
- {
- (*LenPtr) = 131000;
- }
-
- ioa->ioa_Length = (*LenPtr);
- ioa->ioa_Data = (*DataHndl);
-
- if((*LenPtr) != buflen)
- {
- (*LenPtr) = buflen - 131000;
- (*DataHndl) += 131000;
- }
- else
- {
- (*LenPtr) = 0;
- }
- }
-
- FixLength(LenPtr,DataHndl,ioa)
- ULONG *LenPtr;
- BYTE **DataHndl;
- struct IOAudio *ioa;
- {
- if((*LenPtr) > 131000)
- {
- ioa->ioa_Length = 131000;
- ioa->ioa_Data = (*DataHndl);
- (*LenPtr) -= 131000;
- (*DataHndl) += 131000;
- }
- else
- {
- ioa->ioa_Length = (*LenPtr);
- ioa->ioa_Data = (*DataHndl);
- (*LenPtr) = 0;
- }
- }
-