/*
   These routines provide limited IFF support for FutureSound.
   They will read and write single octave one-shot sounds.

   Additional octave and repeat support may be added later.

   Based on the "8SVX" IFF 8-Bit Sampled Voice document dated
   Febuary 7, 1985.

   Routines:

      ULONG SizeIFF(Filename)
      char *Filename;      File to open 

         returns size of sample or 0 if error.


      UWORD ReadIFF(Filename,Buffer)
      char *Filename;      File to read
      BYTE *Buffer;       Buffer to read sample into

         returns the record rate;

   Dan Lovy    May 1986

   Modified for use with FutureSound auxiliary routines - June 1986
      by Ralph Hebb

   Converted to use AmigaDOS I/O calls, John Foust, 6/22/86

*/

/* for comments see IFF spec,  I'm too tired to type them in now */

#include "stdio.h"
#include "exec/types.h"
#include "SoundErrors.h"

#include "libraries/dosextens.h"

extern struct FileHandle *Open();

typedef LONG Fixed;

#define Unity 0x10000L
#define sCmpNone      0
#define sCmpFibDelta   1

typedef struct {
   ULONG   oneShotHiSamples,   /* # samples in the high octave 1-shot part */
         repeatHiSamples,   /* # samples in the high octave repeat part */
         samplesPerHiCycle;   /* # samples/cycle in high octave, else 0   */
   UWORD   samplesPerSec;      /* data sampling rate */
   UBYTE   ctOctave,         /* number of octaves of waveforms */
         sCompression;      /* data compression technique used */
   Fixed   volume;            /* playback volume from 0 to Unity */

   } Voice8Header;

ULONG SizeIFF(Filename)
char *Filename;      /* File to open */
/* returns size of sample or 0 if error. */
{

/*   FILE *fp; */
struct FileHandle *fp;

   char *ckname = "    ";
   LONG dummy;
   Voice8Header Header;

   if (fp = Open(Filename,MODE_OLDFILE))
   {
      Read(fp,ckname,4);
      if (strcmp(ckname,"FORM")==0)
      {
         Read(fp,ckname,4);   /* two calls, eat 8 chars */
         Read(fp,ckname,4);
         if (strcmp(ckname,"8SVX")==0)
         {
            get_to("VHDR",fp);
            Read(fp,&dummy,sizeof(LONG));
            Read(fp,&Header,sizeof(Header));
            Close(fp);
            return(Header.oneShotHiSamples+
                  Header.repeatHiSamples);
         }
         else
         {
            Close(fp);
            return(0);      
         }
      }
      else
      {
         Close(fp);
         return(0);      
      }
   }
   else
   {
      return(0);
   }
}

UWORD ReadIFF(Filename,IFFBuf0)
char *Filename;      /* File to read */
BYTE *IFFBuf0;         /* Buffer to read sample into */
/* returns the record rate */
{
/* FILE *fp; */
   struct FileHandle *fp;
   char *ckname = "    ";
   LONG dummy;
   Voice8Header Header;

   if (fp = Open(Filename,MODE_OLDFILE))
   {
      Read(fp,ckname,4);
      if (strcmp(ckname,"FORM")==0)
      {
         Read(fp,ckname,4);      /* two calls, eat 8 chars */
         Read(fp,ckname,4);
         if (strcmp(ckname,"8SVX")==0)
         {
            get_to("VHDR",fp);
            Read(fp,&dummy,sizeof(LONG));
            Read(fp,&Header,sizeof(Header));
            get_to("BODY",fp);
            Read(fp,&dummy,sizeof(LONG));
            Read(fp,IFFBuf0,Header.oneShotHiSamples+
                 Header.repeatHiSamples);
            Close(fp);
            return(Header.samplesPerSec);
         }
         else
         {
            Close(fp);
            return(Error(IFF_ERROR,Filename));      
         }
      }
      else
      {
         Close(fp);
         return(Error(IFF_ERROR,Filename));      
      }
   }
   else
   {
      return(Error(OPEN_ERROR,Filename));
   }
} 

/* this routine walks through the iff file looking for chunks */
get_to(ckname,fp)
char *ckname;
/* FILE *fp; */
struct FileHandle *fp;
{
   char *ckcheck = "    ";
   int  skip,i,dummy;
   int numread = 1;

   while(numread!=0)       /* !feof(fp)) */
   {
      Read(fp,ckcheck,4);
      if (strcmp(ckname,ckcheck)==0)
      {
         return(1);
      }
      numread = Read(fp,&skip,sizeof(LONG));
      for (i=0; i<skip; i++)
      {
         numread = Read(fp,&dummy,1);
      }
   }
}

