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 >
C/C++ Source or Header  |  1988-12-13  |  9KB  |  266 lines

  1.  
  2. /** Read8SVX.c **********************************************************
  3.  * 
  4.  * Read a sound sample from an IFF file.  21Jan85 
  5.  * 
  6.  * By Steve Hayes, Electronic Arts. 
  7.  * This software is in the public domain. 
  8.  * 
  9.  * Linkage:
  10.  * LStartup.obj,Read8SVX.o,dunpack.o,iffr.o LIBRARY  LC.lib,Amiga.lib
  11.  *
  12.  ************************************************************************/
  13.  
  14. #include "exec/types.h" 
  15. #include "exec/exec.h" 
  16. #include "libraries/dos.h" 
  17. #include "iff/8svx.h" 
  18.  
  19. /* Message strings for IFFP codes. */ 
  20. char MsgOkay[]        = { "(IFF_OKAY) No FORM 8SVX in the file." }; 
  21. char MsgEndMark[]     = { "(END_MARK) How did you get this message?" }; 
  22. char MsgDone[]        = { "(IFF_DONE) All done."}; 
  23. char MsgDos[]         = { "(DOS_ERROR) The DOS returned an error." }; 
  24. char MsgNot[]         = { "(NOT_IFF) Not an IFF file." }; 
  25. char MsgNoFile[]      = { "(NO_FILE) No such file found." }; 
  26. char MsgClientError[] = { "(CLIENT_ERROR) Read8SVX bug or insufficient RAM."}; 
  27. char MsgForm[]        = { "(BAD_FORM) A malformed FORM 8SVX." }; 
  28. char MsgShort[]       = { "(SHORT_CHUNK) A malformed FORM 8SVX." }; 
  29. char MsgBad[]         = { "(BAD_IFF) A mangled IFF file." }; 
  30.  
  31. /* THESE MUST APPEAR IN RIGHT ORDER!! */ 
  32. char *IFFPMessages[-LAST_ERROR+1] = { 
  33.     /*IFF_OKAY*/  MsgOkay, 
  34.     /*END_MARK*/  MsgEndMark, 
  35.     /*IFF_DONE*/  MsgDone, 
  36.     /*DOS_ERROR*/ MsgDos, 
  37.     /*NOT_IFF*/   MsgNot, 
  38.     /*NO_FILE*/   MsgNoFile, 
  39.     /*CLIENT_ERROR*/ MsgClientError, 
  40.     /*BAD_FORM*/  MsgForm, 
  41.     /*SHORT_CHUNK*/  MsgShort, 
  42.     /*BAD_IFF*/   MsgBad 
  43.     }; 
  44.  
  45. typedef struct { 
  46.    ClientFrame clientFrame; 
  47.    UBYTE foundVHDR; 
  48.    UBYTE pad1; 
  49.    Voice8Header sampHdr; 
  50.    } SVXFrame; 
  51.  
  52.  
  53. /* NOTE: For a simple version of this program, set Fancy to 0. 
  54.  * That'll compile a program that skips all LISTs and PROPs in the input 
  55.  * file. It will look in CATs for FORMs 8SVX. That's suitable for most uses. 
  56.  * 
  57.  * For a fancy version that handles LISTs and PROPs, set Fancy to 1.
  58.  */
  59.  
  60. #define Fancy  1 
  61.  
  62. BYTE *buf; 
  63. int szBuf; 
  64.  
  65. /** DoSomethingWithSample() **********************************************
  66.  * 
  67.  * Interface to Amiga sound driver. 
  68.  * 
  69.  *************************************************************************/
  70. DoSomethingWithSample(sampHdr)  Voice8Header *sampHdr;  { 
  71.     BYTE *t; 
  72.     printf("\noneShotHiSamples=%ld", sampHdr->oneShotHiSamples); 
  73.     printf("\nrepeatHiSamples=%ld", sampHdr->repeatHiSamples); 
  74.     printf("\nsamplesPerHiCycle=%ld", sampHdr->samplesPerHiCycle); 
  75.     printf("\nsamplesPerSec=%ld", sampHdr->samplesPerSec); 
  76.     printf("\nctOctave=%ld", sampHdr->ctOctave); 
  77.     printf("\nsCompression=%ld", sampHdr->sCompression); 
  78.     printf("\nvolume=0x%lx", sampHdr->volume); 
  79.     /* Decompress, if needed. */ 
  80.     if (sampHdr->sCompression) { 
  81.         t = (BYTE *)AllocMem(szBuf<<1, MEMF_CHIP); 
  82.         DUnpack(buf, szBuf, t); 
  83.         FreeMem(buf, szBuf); 
  84.         buf = t; 
  85.         szBuf <<= 1; 
  86.         }; 
  87.     printf("\nData = %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld",  
  88.            buf[0],buf[1],buf[2],buf[3],buf[4],buf[5],buf[6],buf[7]); 
  89.     printf("\n       %3ld %3ld %3ld %3ld %3ld %3ld %3ld %3ld ...\n",  
  90.            buf[8+0],buf[8+1],buf[8+2],buf[8+3],buf[8+4],buf[8+5],
  91.            buf[8+6],buf[8+ 7]); 
  92.     } 
  93.  
  94. /** ReadBODY() ***********************************************************
  95.  * 
  96.  * Read a BODY into RAM.  
  97.  * 
  98.  *************************************************************************/
  99. IFFP ReadBODY(context)  GroupContext *context;  { 
  100.     IFFP iffp; 
  101.  
  102.     szBuf  = ChunkMoreBytes(context); 
  103.     buf  = (BYTE *)AllocMem(szBuf, MEMF_CHIP); 
  104.     if (buf == NULL) 
  105.         iffp = CLIENT_ERROR; 
  106.     else 
  107.         iffp = IFFReadBytes(context, (BYTE *)buf, szBuf); 
  108.     CheckIFFP(); 
  109.     } 
  110.  
  111. /** GetFo8SVX() **********************************************************
  112.  * 
  113.  * Called via ReadSample to handle every FORM encountered in an IFF file. 
  114.  * Reads FORMs 8SVX and skips all others. 
  115.  * Inside a FORM 8SVX, it reads BODY. It complains if it 
  116.  * doesn't find an VHDR before the BODY. 
  117.  * 
  118.  * [TBD] We could read and print out any NAME and "(c) " chunks. 
  119.  * 
  120.  *************************************************************************/
  121. IFFP GetFo8SVX(parent)  GroupContext *parent;  { 
  122.    /*compilerBug register*/ IFFP iffp; 
  123.    GroupContext formContext; 
  124.    SVXFrame smusFrame;          /* only used for non-clientFrame fields.*/ 
  125.  
  126.    if (parent->subtype != ID_8SVX) 
  127.       return(IFF_OKAY); /* just continue scaning the file */ 
  128.  
  129.    smusFrame = *(SVXFrame *)parent->clientFrame; 
  130.    iffp = OpenRGroup(parent, &formContext); 
  131.    CheckIFFP(); 
  132.  
  133.    do switch (iffp = GetFChunkHdr(&formContext)) { 
  134.       case ID_VHDR: { 
  135.         smusFrame.foundVHDR = TRUE; 
  136.         iffp = GetVHDR(&formContext, &smusFrame.sampHdr); 
  137.         break; } 
  138.       case ID_BODY: { 
  139.         if (!smusFrame.foundVHDR) 
  140.             iffp = BAD_FORM;            /* Need an VHDR chunk first! */ 
  141.         else iffp = ReadBODY(&formContext); 
  142.         break; } 
  143.       case END_MARK: { 
  144.         if (!smusFrame.foundVHDR) 
  145.             iffp = BAD_FORM; 
  146.         else 
  147.             iffp = IFF_DONE; 
  148.         break; } 
  149.       } while (iffp >= IFF_OKAY);  /* loop if valid ID of ignored chunk or a 
  150.                                 * subroutine returned IFF_OKAY (no errors).*/ 
  151.  
  152.     if (iffp != IFF_DONE)  return(iffp); 
  153.  
  154.     /* If we get this far, there were no errors. */ 
  155.     CloseRGroup(&formContext); 
  156.     DoSomethingWithSample(&smusFrame.sampHdr); 
  157.     FreeMem(buf, szBuf); 
  158.     return(iffp); 
  159.     } 
  160.  
  161. /** Notes on extending GetFo8SVX ****************************************
  162.  * 
  163.  * To read more kinds of chunks, just add clauses to the switch statement. 
  164.  * To read more kinds of property chunks (like NAME) add clauses to 
  165.  * the switch statement in GetPr8SVX, too. 
  166.  * 
  167.  ************************************************************************/
  168.  
  169. /** GetPr8SVX() *********************************************************
  170.  * 
  171.  * Called via ReadSample to handle every PROP encountered in an IFF file. 
  172.  * Reads PROPs 8SVX and skips all others. 
  173.  * 
  174.  *************************************************************************/
  175. #if Fancy 
  176. IFFP GetPr8SVX(parent)  GroupContext *parent;  { 
  177.    /*compilerBug register*/ IFFP iffp; 
  178.    GroupContext propContext; 
  179.    SVXFrame *svxFrame = (SVXFrame *)parent->clientFrame; /* Subclass */ 
  180.  
  181.    if (parent->subtype != ID_8SVX) 
  182.       return(IFF_OKAY); /* just continue scaning the file */ 
  183.  
  184.    iffp = OpenRGroup(parent, &propContext); 
  185.    CheckIFFP(); 
  186.  
  187.    do switch (iffp = GetPChunkHdr(&propContext)) { 
  188.       case ID_VHDR: { 
  189.         svxFrame->foundVHDR = TRUE; 
  190.         iffp = GetVHDR(&propContext, &svxFrame->sampHdr); 
  191.         break; } 
  192.       } while (iffp >= IFF_OKAY);  /* loop if valid ID of ignored chunk or a 
  193.                               * subroutine returned IFF_OKAY (no errors).*/ 
  194.  
  195.    CloseRGroup(&propContext); 
  196.    return(iffp == END_MARK ? IFF_OKAY : iffp); 
  197.    } 
  198. #endif 
  199.  
  200. /** GetLi8SVX() **********************************************************
  201.  * 
  202.  * Called via ReadSample to handle every LIST encountered in an IFF file. 
  203.  * 
  204.  *************************************************************************/
  205. #if Fancy 
  206. IFFP GetLi8SVX(parent)  GroupContext *parent;  { 
  207.     SVXFrame newFrame;  /* allocate a new Frame */ 
  208.  
  209.     newFrame = *(SVXFrame *)parent->clientFrame;  /* copy parent frame */ 
  210.  
  211.     return( ReadIList(parent, (ClientFrame *)&newFrame) ); 
  212.     } 
  213. #endif 
  214.  
  215. /** ReadSample() **********************************************************
  216.  * 
  217.  * Read IFF 8SVX, given a file handle open for reading.
  218.  * 
  219.  *************************************************************************/
  220. IFFP ReadSample(file)  LONG file;  { 
  221.    SVXFrame sFrame;     /* Top level "client frame".*/ 
  222.    IFFP iffp = IFF_OKAY; 
  223.  
  224. #if Fancy 
  225.    sFrame.clientFrame.getList = GetLi8SVX; 
  226.    sFrame.clientFrame.getProp = GetPr8SVX; 
  227. #else 
  228.    sFrame.clientFrame.getList = SkipGroup; 
  229.    sFrame.clientFrame.getProp = SkipGroup; 
  230. #endif 
  231.    sFrame.clientFrame.getForm = GetFo8SVX; 
  232.    sFrame.clientFrame.getCat  = ReadICat ; 
  233.  
  234.    /* Initialize the top-level client frame's property settings to the 
  235.     * program-wide defaults. This example just records that we haven't read 
  236.     * any VHDR properties yet. 
  237.     * If you want to read another property, init it's fields in sFrame. */ 
  238.    sFrame.foundVHDR = FALSE; 
  239.    sFrame.pad1      = 0; 
  240.  
  241.    iffp = ReadIFF(file, (ClientFrame *)&sFrame); 
  242.  
  243.    return(iffp); 
  244.    } 
  245.  
  246. /** main0() **************************************************************/
  247. void main0(filename)  char *filename;  { 
  248.     LONG file; 
  249.     IFFP iffp = NO_FILE; 
  250.     file = Open(filename, MODE_OLDFILE); 
  251.     if (file) 
  252.         iffp = ReadSample(file); 
  253.     Close(file); 
  254.     printf(" %s\n", IFFPMessages[-iffp]); 
  255.     } 
  256.  
  257. /** main() ***************************************************************/
  258. void main(argc, argv)  int argc;  char **argv;  { 
  259.     printf("Reading file '%s' ...", argv[1]); 
  260.     if (argc < 2) 
  261.         printf("\nfilename required\n"); 
  262.     else 
  263.         main0(argv[1]); 
  264.     } 
  265.  
  266.