home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fish 'n' More 2
/
fishmore-publicdomainlibraryvol.ii1991xetec.iso
/
fish
/
libraries
/
ilbm
/
c
/
play8svx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-02-15
|
11KB
|
401 lines
/* 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 );
}