home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Frozen Fish 1: Amiga
/
FrozenFish-Apr94.iso
/
bbs
/
alib
/
d1xx
/
d185
/
iff.lha
/
SOURCE
/
Read8SVX.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-12-13
|
9KB
|
266 lines
/** Read8SVX.c **********************************************************
*
* Read a sound sample from an IFF file. 21Jan85
*
* By Steve Hayes, Electronic Arts.
* This software is in the public domain.
*
* Linkage:
* LStartup.obj,Read8SVX.o,dunpack.o,iffr.o LIBRARY LC.lib,Amiga.lib
*
************************************************************************/
#include "exec/types.h"
#include "exec/exec.h"
#include "libraries/dos.h"
#include "iff/8svx.h"
/* Message strings for IFFP codes. */
char MsgOkay[] = { "(IFF_OKAY) No FORM 8SVX in the file." };
char MsgEndMark[] = { "(END_MARK) How did you get this message?" };
char MsgDone[] = { "(IFF_DONE) All done."};
char MsgDos[] = { "(DOS_ERROR) The DOS returned an error." };
char MsgNot[] = { "(NOT_IFF) Not an IFF file." };
char MsgNoFile[] = { "(NO_FILE) No such file found." };
char MsgClientError[] = { "(CLIENT_ERROR) Read8SVX bug or insufficient RAM."};
char MsgForm[] = { "(BAD_FORM) A malformed FORM 8SVX." };
char MsgShort[] = { "(SHORT_CHUNK) A malformed FORM 8SVX." };
char MsgBad[] = { "(BAD_IFF) A mangled IFF file." };
/* THESE MUST APPEAR IN RIGHT ORDER!! */
char *IFFPMessages[-LAST_ERROR+1] = {
/*IFF_OKAY*/ MsgOkay,
/*END_MARK*/ MsgEndMark,
/*IFF_DONE*/ MsgDone,
/*DOS_ERROR*/ MsgDos,
/*NOT_IFF*/ MsgNot,
/*NO_FILE*/ MsgNoFile,
/*CLIENT_ERROR*/ MsgClientError,
/*BAD_FORM*/ MsgForm,
/*SHORT_CHUNK*/ MsgShort,
/*BAD_IFF*/ MsgBad
};
typedef struct {
ClientFrame clientFrame;
UBYTE foundVHDR;
UBYTE pad1;
Voice8Header sampHdr;
} SVXFrame;
/* NOTE: For a simple version of this program, set Fancy to 0.
* That'll compile a program that skips all LISTs and PROPs in the input
* file. It will look in CATs for FORMs 8SVX. That's suitable for most uses.
*
* For a fancy version that handles LISTs and PROPs, set Fancy to 1.
*/
#define Fancy 1
BYTE *buf;
int szBuf;
/** DoSomethingWithSample() **********************************************
*
* Interface to Amiga sound driver.
*
*************************************************************************/
DoSomethingWithSample(sampHdr) Voice8Header *sampHdr; {
BYTE *t;
printf("\noneShotHiSamples=%ld", sampHdr->oneShotHiSamples);
printf("\nrepeatHiSamples=%ld", sampHdr->repeatHiSamples);
printf("\nsamplesPerHiCycle=%ld", sampHdr->samplesPerHiCycle);
printf("\nsamplesPerSec=%ld", sampHdr->samplesPerSec);
printf("\nctOctave=%ld", sampHdr->ctOctave);
printf("\nsCompression=%ld", sampHdr->sCompression);
printf("\nvolume=0x%lx", sampHdr->volume);
/* Decompress, if needed. */
if (sampHdr->sCompression) {
t = (BYTE *)AllocMem(szBuf<<1, MEMF_CHIP);
DUnpack(buf, szBuf, t);
FreeMem(buf, szBuf);
buf = t;
szBuf <<= 1;
};
printf("\nData = %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld",
buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]);
printf("\n %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld ...\n",
buf[8+0],buf[8+1],buf[8+2],buf[8+3],buf[8+4],buf[8+5],
buf[8+6],buf[8+ 7]);
}
/** ReadBODY() ***********************************************************
*
* Read a BODY into RAM.
*
*************************************************************************/
IFFP ReadBODY(context) GroupContext *context; {
IFFP iffp;
szBuf = ChunkMoreBytes(context);
buf = (BYTE *)AllocMem(szBuf, MEMF_CHIP);
if (buf == NULL)
iffp = CLIENT_ERROR;
else
iffp = IFFReadBytes(context, (BYTE *)buf, szBuf);
CheckIFFP();
}
/** GetFo8SVX() **********************************************************
*
* Called via ReadSample to handle every FORM encountered in an IFF file.
* Reads FORMs 8SVX and skips all others.
* Inside a FORM 8SVX, it reads BODY. It complains if it
* doesn't find an VHDR before the BODY.
*
* [TBD] We could read and print out any NAME and "(c) " chunks.
*
*************************************************************************/
IFFP GetFo8SVX(parent) GroupContext *parent; {
/*compilerBug register*/ IFFP iffp;
GroupContext formContext;
SVXFrame smusFrame; /* only used for non-clientFrame fields.*/
if (parent->subtype != ID_8SVX)
return(IFF_OKAY); /* just continue scaning the file */
smusFrame = *(SVXFrame *)parent->clientFrame;
iffp = OpenRGroup(parent, &formContext);
CheckIFFP();
do switch (iffp = GetFChunkHdr(&formContext)) {
case ID_VHDR: {
smusFrame.foundVHDR = TRUE;
iffp = GetVHDR(&formContext, &smusFrame.sampHdr);
break; }
case ID_BODY: {
if (!smusFrame.foundVHDR)
iffp = BAD_FORM; /* Need an VHDR chunk first! */
else iffp = ReadBODY(&formContext);
break; }
case END_MARK: {
if (!smusFrame.foundVHDR)
iffp = BAD_FORM;
else
iffp = IFF_DONE;
break; }
} while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
* subroutine returned IFF_OKAY (no errors).*/
if (iffp != IFF_DONE) return(iffp);
/* If we get this far, there were no errors. */
CloseRGroup(&formContext);
DoSomethingWithSample(&smusFrame.sampHdr);
FreeMem(buf, szBuf);
return(iffp);
}
/** Notes on extending GetFo8SVX ****************************************
*
* To read more kinds of chunks, just add clauses to the switch statement.
* To read more kinds of property chunks (like NAME) add clauses to
* the switch statement in GetPr8SVX, too.
*
************************************************************************/
/** GetPr8SVX() *********************************************************
*
* Called via ReadSample to handle every PROP encountered in an IFF file.
* Reads PROPs 8SVX and skips all others.
*
*************************************************************************/
#if Fancy
IFFP GetPr8SVX(parent) GroupContext *parent; {
/*compilerBug register*/ IFFP iffp;
GroupContext propContext;
SVXFrame *svxFrame = (SVXFrame *)parent->clientFrame; /* Subclass */
if (parent->subtype != ID_8SVX)
return(IFF_OKAY); /* just continue scaning the file */
iffp = OpenRGroup(parent, &propContext);
CheckIFFP();
do switch (iffp = GetPChunkHdr(&propContext)) {
case ID_VHDR: {
svxFrame->foundVHDR = TRUE;
iffp = GetVHDR(&propContext, &svxFrame->sampHdr);
break; }
} while (iffp >= IFF_OKAY); /* loop if valid ID of ignored chunk or a
* subroutine returned IFF_OKAY (no errors).*/
CloseRGroup(&propContext);
return(iffp == END_MARK ? IFF_OKAY : iffp);
}
#endif
/** GetLi8SVX() **********************************************************
*
* Called via ReadSample to handle every LIST encountered in an IFF file.
*
*************************************************************************/
#if Fancy
IFFP GetLi8SVX(parent) GroupContext *parent; {
SVXFrame newFrame; /* allocate a new Frame */
newFrame = *(SVXFrame *)parent->clientFrame; /* copy parent frame */
return( ReadIList(parent, (ClientFrame *)&newFrame) );
}
#endif
/** ReadSample() **********************************************************
*
* Read IFF 8SVX, given a file handle open for reading.
*
*************************************************************************/
IFFP ReadSample(file) LONG file; {
SVXFrame sFrame; /* Top level "client frame".*/
IFFP iffp = IFF_OKAY;
#if Fancy
sFrame.clientFrame.getList = GetLi8SVX;
sFrame.clientFrame.getProp = GetPr8SVX;
#else
sFrame.clientFrame.getList = SkipGroup;
sFrame.clientFrame.getProp = SkipGroup;
#endif
sFrame.clientFrame.getForm = GetFo8SVX;
sFrame.clientFrame.getCat = ReadICat ;
/* Initialize the top-level client frame's property settings to the
* program-wide defaults. This example just records that we haven't read
* any VHDR properties yet.
* If you want to read another property, init it's fields in sFrame. */
sFrame.foundVHDR = FALSE;
sFrame.pad1 = 0;
iffp = ReadIFF(file, (ClientFrame *)&sFrame);
return(iffp);
}
/** main0() **************************************************************/
void main0(filename) char *filename; {
LONG file;
IFFP iffp = NO_FILE;
file = Open(filename, MODE_OLDFILE);
if (file)
iffp = ReadSample(file);
Close(file);
printf(" %s\n", IFFPMessages[-iffp]);
}
/** main() ***************************************************************/
void main(argc, argv) int argc; char **argv; {
printf("Reading file '%s' ...", argv[1]);
if (argc < 2)
printf("\nfilename required\n");
else
main0(argv[1]);
}