home *** CD-ROM | disk | FTP | other *** search
/ Audio 4.94 - Over 11,000 Files / audio-11000.iso / amiga / iff / source / newiff / read8svx.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-11-01  |  8.8 KB  |  262 lines

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