home *** CD-ROM | disk | FTP | other *** search
- /*
- ** $Id: termBeep.c,v 1.3 92/08/15 20:13:35 olsen Sta Locker: olsen $
- ** $Revision: 1.3 $
- ** $Date: 92/08/15 20:13:35 $
- **
- ** Sound support routines
- **
- ** Copyright ⌐ 1990-1992 by Olaf `Olsen' Barthel & MXM
- ** All Rights Reserved
- */
-
- #include "termGlobal.h"
-
- /* IFF Sound `8SVX' voice header. */
-
- struct Voice8Header
- {
- ULONG oneShotHiSamples, /* # samples in the high octave 1-shot part */
- repeatHiSamples, /* # samples in the high octave repeat part */
- samplesPerHiCycle; /* # samples/cycle in high octave, else 0 */
- UWORD samplesPerSec; /* data sampling rate */
- UBYTE ctOctave, /* # of octaves of waveforms */
- sCompression; /* data compression technique used */
- LONG volume; /* playback nominal volume from 0 to Unity
- * (full volume). Map this value into
- * the output hardware's dynamic range.
- */
- };
-
- /* Small sound information. */
-
- struct SoundInfo
- {
- APTR Data; /* Data pointer. */
-
- LONG Length; /* Real length. */
- ULONG Rate; /* Recording rate. */
- WORD Volume; /* Sound volume. */
- };
-
- /* Local sound info. */
-
- STATIC struct SoundInfo SoundInfo;
- STATIC BYTE HasSound = FALSE,
- SoundPlayed = FALSE;
-
- /* CreateBeep():
- *
- * Set up the audio.device for a decent beep sound.
- */
-
- BYTE
- CreateBeep()
- {
- /* Do we already have the resources we need? */
-
- if(!AudioBlock)
- {
- struct MsgPort *AudioPort;
-
- /* No sound so far. */
-
- SoundPlayed = FALSE;
-
- /* Create the IO reply port. */
-
- if(AudioPort = (struct MsgPort *)CreateMsgPort())
- {
- /* Create the audio IO info. */
-
- if(AudioBlock = (struct IOAudio *)CreateIORequest(AudioPort,sizeof(struct IOAudio)))
- {
- /* Open audio.device */
-
- if(!OpenDevice(AUDIONAME,0,AudioBlock,0))
- return(TRUE);
-
- DeleteIORequest(AudioBlock);
- }
-
- DeleteMsgPort(AudioPort);
- }
-
- AudioBlock = NULL;
-
- return(FALSE);
- }
- else
- return(TRUE);
- }
-
- /* DeleteBeep():
- *
- * Remove the data allocated for the beep sound.
- */
-
- VOID
- DeleteBeep()
- {
- if(AudioBlock)
- {
- if(AudioBlock -> ioa_Request . io_Device)
- CloseDevice(AudioBlock);
-
- if(AudioBlock -> ioa_Request . io_Message . mn_ReplyPort)
- DeleteMsgPort(AudioBlock -> ioa_Request . io_Message . mn_ReplyPort);
-
- DeleteIORequest(AudioBlock);
-
- AudioBlock = NULL;
- }
-
- if(HasSound)
- {
- FreeVec(SoundInfo . Data);
-
- HasSound = FALSE;
- }
- }
-
- /* ClearAudio():
- *
- * Clear the audio control block for reuse.
- */
-
- VOID
- ClearAudio()
- {
- /* Remove the request. */
-
- WaitIO(AudioBlock);
-
- /* Clear the signal bit. */
-
- SetSignal(0,SIG_AUDIO);
-
- /* Free the channels we had allocated. */
-
- AudioBlock -> ioa_Request . io_Command = ADCMD_FREE;
-
- DoIO(AudioBlock);
-
- /* No sound running. */
-
- SoundPlayed = FALSE;
- }
-
- /* Beep():
- *
- * Produce a decent beep sound.
- */
-
- VOID
- Beep()
- {
- if(AudioBlock)
- {
- BYTE PlayItAgainSam; /* Note: `Sam' is Sam Dicker, the author of
- * the original audio.device implementation.
- */
-
- /* AudioRequest has returned. */
-
- if(CheckSignal(SIG_AUDIO))
- ClearAudio();
-
- /* Check whether we are to play the sound or not. */
-
- if(!SoundPlayed)
- PlayItAgainSam = TRUE;
- else
- {
- if(CheckIO(AudioBlock))
- PlayItAgainSam = TRUE;
- else
- PlayItAgainSam = FALSE;
- }
-
- /* May we play the sound? */
-
- if(PlayItAgainSam)
- {
- /* Allocate a sound channel, we don't want to
- * wait for it, the `beep' sound is to played
- * right now.
- */
-
- AudioBlock -> ioa_Request . io_Command = ADCMD_ALLOCATE;
- AudioBlock -> ioa_Request . io_Flags = ADIOF_NOWAIT | IOF_QUICK;
- AudioBlock -> ioa_Request . io_Message . mn_Node . ln_Pri = 80;
- AudioBlock -> ioa_Data = AnyChannel;
- AudioBlock -> ioa_Length = 4;
-
- /* Try the allocation. */
-
- BeginIO(AudioBlock);
-
- /* If still in progress, no channel is available yet. */
-
- if(!CheckIO(AudioBlock))
- {
- /* Abort the allocation. */
-
- AbortIO(AudioBlock);
-
- /* Wait for request to be returned. */
-
- WaitIO(AudioBlock);
- }
- else
- {
- /* Wait for request to be returned. */
-
- if(!WaitIO(AudioBlock))
- {
- /* Set up the sound IO data. */
-
- if(HasSound)
- {
- AudioBlock -> ioa_Period = SoundInfo . Rate;
- AudioBlock -> ioa_Volume = SoundInfo . Volume;
- AudioBlock -> ioa_Cycles = 1;
- AudioBlock -> ioa_Data = SoundInfo . Data;
- AudioBlock -> ioa_Length = SoundInfo . Length;
- }
- else
- {
- AudioBlock -> ioa_Period = 223;
- AudioBlock -> ioa_Volume = 64 / 2;
- AudioBlock -> ioa_Cycles = 150;
- AudioBlock -> ioa_Data = &SineWave[0];
- AudioBlock -> ioa_Length = 8;
- }
-
- AudioBlock -> ioa_Request . io_Command = CMD_WRITE;
- AudioBlock -> ioa_Request . io_Flags = ADIOF_PERVOL;
-
- /* Start the sound. */
-
- BeginIO(AudioBlock);
-
- SoundPlayed = TRUE;
- }
- }
- }
- }
- }
-
- /* OpenSound(UBYTE *Name):
- *
- * Load an IFF-8SVX sound file instead of the standard
- * beep (yes, this is a zany feature nobody will ever need!).
- */
-
- BYTE
- OpenSound(UBYTE *Name)
- {
- STATIC ULONG SoundProps[] = { '8SVX', 'VHDR' };
-
- struct IFFHandle *Handle;
- struct StoredProperty *Prop;
- struct Voice8Header *VoiceHeader;
-
- BYTE Success = FALSE;
-
- /* Allocate an IFF handle. */
-
- if(Handle = AllocIFF())
- {
- /* Open the file. */
-
- if(Handle -> iff_Stream = Open(Name,MODE_OLDFILE))
- {
- /* Say it's a DOS file. */
-
- InitIFFasDOS(Handle);
-
- /* Open the file for reading. */
-
- if(!OpenIFF(Handle,IFFF_READ))
- {
- /* Remember VHDR-chunks encountered. */
-
- if(!PropChunks(Handle,&SoundProps[0],1))
- {
- /* Stop at the body chunk. */
-
- if(!StopChunk(Handle,'8SVX','BODY'))
- {
- /* Start scanning... */
-
- if(!ParseIFF(Handle,IFFPARSE_SCAN))
- {
- /* Obtain the stored VHDR-chunk. */
-
- if(Prop = FindProp(Handle,'8SVX','VHDR'))
- {
- VoiceHeader = (struct Voice8Header *)Prop -> sp_Data;
-
- /* Compressed data not supported so far. */
-
- if(!VoiceHeader -> sCompression)
- {
- struct ContextNode *ContextNode;
-
- /* Inquire current chunk. */
-
- if(ContextNode = CurrentChunk(Handle))
- {
- /* We don't support double-buffering, this
- * is only a *simple* example.
- */
-
- if(ContextNode -> cn_Size < 102400)
- {
- /* Allocate the data storage. */
-
- if(SoundInfo . Data = AllocVec(ContextNode -> cn_Size,MEMF_CHIP|MEMF_CLEAR))
- {
- /* Play either the one-shot or the continuous
- * part, not both.
- */
-
- SoundInfo . Length = VoiceHeader -> oneShotHiSamples ? VoiceHeader -> oneShotHiSamples : VoiceHeader -> repeatHiSamples;
-
- /* Calculate recording rate. */
-
- SoundInfo . Rate = (GfxBase -> DisplayFlags & PAL ? 3546895 : 3579545) / VoiceHeader -> samplesPerSec;
-
- /* Calculate volume. */
-
- SoundInfo . Volume = (VoiceHeader -> volume * 64) / 0x10000;
-
- /* Read the data. */
-
- if(ReadChunkBytes(Handle,SoundInfo . Data,ContextNode -> cn_Size))
- Success = TRUE;
- else
- FreeVec(SoundInfo . Data);
- }
- }
- }
- }
- }
- }
- }
- }
-
- /* Make iffparse clean up after us. */
-
- CloseIFF(Handle);
- }
-
- /* Close the DOS handle. */
-
- Close(Handle -> iff_Stream);
- }
-
- /* Free the IFF handle. */
-
- FreeIFF(Handle);
- }
-
- /* Remember success/failure. */
-
- HasSound = Success;
-
- return(Success);
- }
-