/*

 Name:  MWAV.C

 Description:
 WAV sample loader

 Portability:
 All compilers -- All systems (hopefully)

*/

#include <string.h>
#include "mikmod.h"


typedef struct WAV
{   CHAR  rID[4];
    ULONG rLen;
    CHAR  wID[4];
    CHAR  fID[4];
    ULONG fLen;
    UWORD wFormatTag;
    UWORD nChannels;
    ULONG nSamplesPerSec;
    ULONG nAvgBytesPerSec;
    UWORD nBlockAlign;
    UWORD nFormatSpecific;
} WAV;


static CHAR  *LOCAL_UNKNOWN_FILE_TYPE = "Not a WAV file";
static CHAR  *LOCAL_UNSUPPORTED_TYPE = "Only mono WAV's are supported";

SAMPLE *MW_LoadWavFP(FILE *fp)
{
    SAMPLE     *si;
    static WAV  wh;
    static CHAR dID[4];

    _mm_rewind(fp);

    // read wav header

    _mm_read_string(wh.rID,4,fp);
    wh.rLen            = _mm_read_I_ULONG(fp);
    _mm_read_string(wh.wID,4,fp);
    _mm_read_string(wh.fID,4,fp);
    wh.fLen            = _mm_read_I_ULONG(fp);
    wh.wFormatTag      = _mm_read_I_UWORD(fp);
    wh.nChannels       = _mm_read_I_UWORD(fp);
    wh.nSamplesPerSec  = _mm_read_I_ULONG(fp);
    wh.nAvgBytesPerSec = _mm_read_I_ULONG(fp);
    wh.nBlockAlign     = _mm_read_I_UWORD(fp);
    wh.nFormatSpecific = _mm_read_I_UWORD(fp);

    // check it

    if( feof(fp) ||
        memcmp(wh.rID,"RIFF",4) ||
        memcmp(wh.wID,"WAVE",4) ||
        memcmp(wh.fID,"fmt ",4) )
    {
        _mm_error = LOCAL_UNKNOWN_FILE_TYPE;
        return NULL;
    }

    // skip other crap

    _mm_fseek(fp,wh.fLen-16,SEEK_CUR);
    _mm_read_string(dID,4,fp);

    if( memcmp(dID,"data",4) )
    {   _mm_error = LOCAL_UNKNOWN_FILE_TYPE;
        return NULL;
    }

    if(wh.nChannels > 1)
    {   _mm_error = LOCAL_UNSUPPORTED_TYPE;
        return NULL;
    }

//  printf("wFormatTag: %x\n",wh.wFormatTag);
//  printf("blockalign: %x\n",wh.nBlockAlign);
//  prinff("nFormatSpc: %x\n",wh.nFormatSpecific);

    if((si=(SAMPLE *)_mm_calloc(1,sizeof(SAMPLE)))==NULL) return NULL;

    si->c2spd  = 8192;
    si->volume = 64;

    si->length = _mm_read_I_ULONG(fp);

    if(wh.nBlockAlign==2)
    {   si->flags = SF_16BITS|SF_SIGNED;
        si->length>>=1;
    }

    // this needs to be converted to the SAMPLELOADER crap :)
    si->handle = MD_SampleLoad((SAMPLOAD *)si,fp);

    if(si->handle < 0)
    {   free(si);
        return NULL;
    }

    return si;
}


SAMPLE *MW_LoadWavFN(CHAR *filename)
{
    FILE   *fp;
    SAMPLE *si;

    if((fp=_mm_fopen(filename,"rb"))==NULL) return NULL;

    si = MW_LoadWavFP(fp);

    fclose(fp);
    return si;
}


void MW_FreeWav(SAMPLE *si)
{
    if(si!=NULL)
    {   MD_SampleUnLoad(si->handle);
        free(si);
    }
}

