home *** CD-ROM | disk | FTP | other *** search
- /* Ilbm.library C application, Play8SVX.c:
-
- Set your editor's TAB width to 3
-
- cc +p Play8SVX.c
- as -cd IlbmInterface.asm
- ln Play8SVX.o IlbmInterface.o -lcl32
-
- This program can only be run from the CLI. It takes 1 arg, the name of a
- file. If an 8SVX file, this program will then play the sample.
-
- This is an example of using the library's mid-level routine LoadIFF() with
- our own FORM and PROP handlers instead of lib's default routines. This is the
- way to go if you need some non-ILBM reader/writer. Note that we need to
- define some PropFrame for 8SVX PROPs.
- */
-
- #include "math.h"
- #include "functions.h" /* Manx C declarations */
-
- #include "exec/tasks.h"
- #include "exec/types.h"
- #include "exec/memory.h"
- #include "libraries/dos.h"
- #include "libraries/dosextens.h"
- #include "devices/audio.h"
-
- /* The ilbm lib C INCLUDE file */
- #include "ILBM_Lib.h"
-
-
- /*-------------------------------defines---------------------------------*/
-
- IFFP myForm();
- IFFP myProp();
-
- typedef struct {
- ULONG oneShotHiSamples,
- repeatHiSamples,
- samplesPerHiCycle;
- UWORD samplesPerSec;
- UBYTE ctOctave,
- sCompression;
- LONG volume;
- } Voice8Header;
-
- /* Data for the Dissidents ILBM library */
- struct ILBMBase *ILBMBase=0L;
-
- /* OK. Let's make up an 8SVXFrame and 8SVXPropFrame */
-
- typedef struct {
- USHORT vFlags;
- Voice8Header vhdr;
- } v8SVXFrame;
-
- typedef struct {
- ULONG NextPropFrame;
- LONG ifID;
- UWORD PropFrameSize;
- v8SVXFrame PropFrame;
- } v8SVXPropFrame;
-
- /* definitions for iFlags field */
- #define VHDRFLAG 1 /* if a VHDR chunk found in the file */
-
- #define GetVHDR(context, vhdr) \
- IFFReadBytes(sizeof(Voice8Header), context, (BYTE *)vhdr)
-
- #define ID_VHDR MakeID('V','H','D','R')
- #define ID_8SVX MakeID('8','S','V','X')
-
- v8SVXFrame my8SVXFrame;
-
- /* Data for our program */
- struct FileHandle *fp = 0;
- BYTE *memptr = 0;
- ULONG memsize = 0;
-
- #define SetFlag(v,f) ((v)|=(f))
- #define ClearFlag(v,f) ((v)&=~(f))
- #define ToggleFlag(v,f) ((v)^=(f))
- #define FlagIsSet(v,f) ((BOOL)(((v)&(f))!=0))
-
- /*=================== For audio.device playback of wave ==================*/
- struct IOAudio ioaudio = {0}, ioaudio2 = {0};
- struct MsgPort *audPort = 0L;
- UBYTE audio_gub = 0;
- UBYTE anychan[4] = {1,2,4,8};
-
-
- /*-----------closes audio dev, audio port, ILBM lib---------*/
-
- VOID exit_all()
- {
- if( audio_gub ) CloseDevice( &ioaudio );
- if( audPort ) DeletePort( audPort );
- if( ILBMBase ) CloseLibrary( ILBMBase );
- exit( FALSE );
- }
-
-
- /*---------- Opens audio dev, audio port, ilbm lib ---------*/
-
- VOID open_all()
- {
-
- /* Open the ILBM lib */
- if( !(ILBMBase=(struct ILBMBase *)OpenLibrary("ilbm.library", 0L)) )
- {
- printf("Need the dissidents ilbm.library on boot disk\n");
- exit();
- }
-
- /* Open audio.device and allocate a channel */
-
- if( !(audPort = CreatePort( "SAMP_Port", 0 )) )
- {
- puts("no audio port");
- exit_all();
- }
-
- ioaudio.ioa_Request.io_Message.mn_ReplyPort = audPort;
-
- ioaudio.ioa_Request.io_Command = ADCMD_ALLOCATE;
- ioaudio.ioa_Data = (UBYTE *)anychan;
- ioaudio.ioa_Length = 4;
- ioaudio.ioa_Request.io_Flags = ADIOF_NOWAIT | IOF_QUICK;
- if( OpenDevice("audio.device", 0, &ioaudio, 0 ) )
- {
- puts("audio device open error\n");
- exit_all();
- }
-
- if( !(ioaudio.ioa_Request.io_Flags & IOF_QUICK ) )
- GetMsg( audPort );
-
- audio_gub = 1;
-
- ioaudio2 = ioaudio;
- /* initialize the AudioIO for the looping portion */
-
- }
-
-
- /*----------------------------start of main()----------------------------*/
-
- main( argc, argv )
- LONG argc;
- UBYTE *argv[];
- {
- IFFP Result;
- LONG err;
-
- /* LoadIFF() needs a Vectors structure */
- Vectors myVectors;
-
- /* We expect the filename for the first arg. */
- if( argc != 2 )
- {
- printf("USAGE: Play8SVX filename\n");
- exit();
- }
-
- /* Open ilbm.library, setup audio device */
- open_all();
-
- /* Open the IFF File */
- fp = Open( argv[1], MODE_OLDFILE );
-
- if (fp)
- {
-
- /* Note that we are using the lib's middle level functions so that we can
- install our own handlers for each encountered group and context. Also,
- we can parse any IFF FORM, not just ILBMs and ANIMs using this level.
- We are going to install our own function, myForm(), as the routine
- which the library calls whenever it encounters a FORM ID. Our function,
- myProp() will be called for 8SVX PROPS.
- We "install" these routines by setting up the appropriate fields in our
- Vectors structure. Let's do all this now. */
-
- myVectors.PROPhandler = myProp;
- myVectors.FORMhandler = myForm;
- myVectors.CHUNKhandler = 0;
- myVectors.NonILBMhandler = 0;
- /* Don't care about CHUNKhandler or NonILBMhandler as long as we have
- our own FORMhandler. */
-
- /* Start parsing the file using LoadIFF() */
- Result=LoadIFF( fp, &myVectors, &my8SVXFrame );
-
- /* O.K. we're back. Did we successfully parse as much as we wanted?
- Well, our FORM routine should have returned IFF_DONE if we found
- the 8SVX BODY. Otherwise, myForm, myProp, or an internal library
- routine knocked us out by returning some other IFFP error code. Let's
- get an informative error msg to display.
- */
-
- /* If some error, get the IFFP error message and print it */
- if( Result != IFF_DONE )
- {
- puts( GetIFFPMsg( Result ) );
- }
- else
- {
- /* Play one lousy, stinking note. Hey this is just for a test! */
-
- ioaudio.ioa_Volume = 64; /* Play everything with MAX volume */
- ioaudio2.ioa_Volume = 64;
- ioaudio.ioa_Request.io_Command = CMD_WRITE;
- ioaudio2.ioa_Request.io_Command = CMD_WRITE;
-
- /* Play the OneShot portion */
- ioaudio.ioa_Data = (UBYTE *)memptr;
- ioaudio.ioa_Length = (ULONG)my8SVXFrame.vhdr.oneShotHiSamples;
- ioaudio.ioa_Request.io_Flags = ADIOF_PERVOL;
- ioaudio.ioa_Cycles = 1;
- if (my8SVXFrame.vhdr.samplesPerSec==0)
- my8SVXFrame.vhdr.samplesPerSec = 7000;
- ioaudio.ioa_Period = 3579545L / my8SVXFrame.vhdr.samplesPerSec;
-
- ioaudio2.ioa_Data = (UBYTE *)(memptr + my8SVXFrame.vhdr.oneShotHiSamples);
- ioaudio2.ioa_Request.io_Flags = 0;
- ioaudio2.ioa_Cycles = 10; /* only play the loop 10 times. */
- ioaudio2.ioa_Period = ioaudio.ioa_Period;
- ioaudio2.ioa_Length = (ULONG)my8SVXFrame.vhdr.repeatHiSamples;
-
- BeginIO( &ioaudio );
-
- if( ioaudio2.ioa_Length )
- BeginIO( &ioaudio2 );
- err = WaitIO( &ioaudio );
- GetMsg( audPort );
- if(ioaudio2.ioa_Length)
- {
- err = WaitIO( &ioaudio2 );
- GetMsg( audPort );
- }
-
- }
-
- /* Close the IFF File */
- Close(fp);
-
- /* Free any allocated CHIP mem for the sample */
- if (memptr) FreeMem(memptr, memsize);
-
- }
- else printf( "Couldn't open %s. \n", argv[1]);
-
- printf("\n");
-
- exit_all();
- } /* end of main() */
-
-
-
- /*========= LoadIFF() calls me when it finds a FORM ==========*/
-
- IFFP myForm( chunkID, context, vectors, frame, proplist )
- PROPList *proplist;
- v8SVXFrame *frame; /* We expect an 8SVXFrame */
- Vectors *vectors;
- GroupContext *context;
- ID chunkID;
- {
- register IFFP code = IFF_OKAY; /* Assume that we skip the FORM */
- register ULONG propf;
-
- /* Is this an 8SVX? If not, skip any other FORM by returning IFF_OKAY */
-
- if (chunkID == ID_8SVX)
- {
-
- /* OK. It's 8SVX. Now check to see if we have any 8SVX PROPS.
- If so, copy over that PropFrame to our present 8SVXFrame. */
-
- propf = SearchPROP(chunkID, proplist);
- if (propf) CopyMem(propf, frame, sizeof(v8SVXFrame) );
-
- while ( code >= 0 )
- {
-
- /* Read in the next chunk */
- code = GetFChunkHdr(context);
-
- /* ================== VHDR ===================== */
- if( code == ID_VHDR )
- {
-
- /* Load the VHDR into 8SVXFrame and set VHDR flag */
-
- code = GetVHDR(context, &frame->vhdr);
- if( code == IFF_OKAY )
- {
- SetFlag(frame->vFlags, VHDRFLAG);
- }
- } /* end of VHDR parse */
-
- /* ================== BODY ===================== */
- if( code == ID_BODY )
- {
- /* If we got an VHDR, start loading the samples into chip mem */
- if ( FlagIsSet(frame->vFlags, VHDRFLAG) );
- {
- ClearFlag(frame->vFlags, VHDRFLAG);
- code = IFF_NOMEM; /* Assume error */
- if ( memptr ) FreeMem( memsize, memptr );
- memsize = ChunkMoreBytes(context);
- if ( (memptr = AllocMem(memsize, MEMF_CHIP)) );
- {
- code = IFFReadBytes(memsize, context, memptr);
- if( code == IFF_OKAY ) code = IFF_DONE; /* Stop the parsing and return this */
- }
- }
- } /* end of BODY parse */
-
- } /* end of while */
-
- } /* end of ID_8SVX */
-
- /* Reasons for falling out:
- 1). We found and successfully loaded the BODY, returning IFF_DONE.
- 2). GetFChunkHdr returned END_MARK, meaning that we got to the end
- of our 8SVX without finding a BODY.
- 3). One of the lib routines returned some IFFP error. We simply
- return that error.
- All 3 scenarios cause our parsing to stop. Note that if we never find
- an 8SVX FORM in the file, the lib will eventually return us to main
- with LoadIFF returning END_MARK. Note: To change this routine so that
- it continues parsing the rest of the file, eliminate the line:
- if (code == IFF_OKAY) code = IFF_DONE;
- Instead, when you get back to main, you can test memptr to see if any
- 8SVX file was loaded. You might want to do this if you were going to
- add parsing for ID_SMUS to this form handler, and didn't want to stop
- until you parsed the entire file.
- */
-
- return( code );
- }
-
-
- /*========= LoadIFF() calls me when it finds a PROP ==========*/
-
- IFFP myProp( chunkID, propID, context, vectors, frame, proplist )
- PROPList *proplist;
- v8SVXFrame *frame;
- Vectors *vectors;
- GroupContext *context;
- ID propID;
- ID chunkID;
- {
- register IFFP code = IFF_OKAY;
- register v8SVXFrame *pframe;
-
- /* We only care about 8SVX PROPS. If PropID not 8SVX, immediately return
- IFF_OKAY to skip. Otherwise, we allocate an 8SVXPropFrame and parse
- the PROP's chunks just like in the FORMhandler, storing info in
- this new PropFrame. Later, in our FORMHandler, we search the PROPList
- for the appropriate ID and retrieve the info. The library automatically
- updates the PROPList when it gets to the end of an IFF group so that you
- don't have to keep track of which level we're at and which PROPS affect
- which chunks. Also, the library frees all PropFrames that we allocate
- with GetPROPStruct() by the time we return to main. */
-
-
- if ( propID == ID_8SVX )
- {
- /* Allocate an 8SVXPropFrame and link into PROPList */
- code = IFF_NOMEM;
- pframe = GetPROPStruct( sizeof(v8SVXPropFrame), propID, proplist );
- if ( pframe )
- {
- code = IFF_OKAY;
- while ( code >= 0 )
- {
- /* Read in the next chunk */
- code = GetPChunkHdr(context);
-
- /* ================== VHDR ===================== */
- if( code == ID_VHDR )
- {
-
- /* Load the VHDR into 8SVXPropFrame and set VHDR flag */
- code = GetVHDR(context, &pframe->vhdr);
- if( code == IFF_OKAY )
- {
- SetFlag(frame->vFlags, VHDRFLAG);
- }
- } /* end of VHDR parse */
-
- } /* end of while */
-
- }
- }
-
- return( code );
- }
-
-