/*
 * libkarma/wav.c 
 *
 * Copyright (c) Paul van der Mark <pmark@liacs.nl> ???? *
 *               (playwav.c - ask the search engine of your choice)
 *           (c) Frank Zschockelt <libkarma@freakysoft.de> 2004
 *
 * You may distribute and modify this program under the terms of 
 * the GNU GPL, version 2 or later.
 * 
 */
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>

#include "wav.h"

/* 
   open file for reading and parse RIFF header:
   A riff header is constructed of a header word+opt. size of chunk+chunk(data)
   where a chunk can contain multiple headers

   So a wave file looks like
   "RIFF" size 
    "WAVE"
        "fmt " size
           chunk with format parameters
        optional chunks like fact
        "data", size 
        chunk with samples
   RIFFssssWAVEfmt ssssbbbbbbbbbdatabbbbbbb
   If you think this is complicated:look at compressed audio/video(AVI) riffs :)
*/

typedef u_char uc;
#define TOFOUR(a) (((uc) a[0]<<24)|((uc) a[1]<<16)|((uc) a[2]<<8)|((uc) a[3]))
#define RIFF TOFOUR("RIFF")
#define WAVE TOFOUR("WAVE")
#define FMT  TOFOUR("fmt ")

int openwav(wave_header **wh, char *filename)
{
    int filefd;
    
    if(0==(*wh=malloc(sizeof(wave_header))))
        return -1;
    
    (void) memset(*wh, 0, sizeof(wave_header)); 
    
    if(-1==(filefd=open(filename, O_RDONLY)))
        return -1;
    
    if(read(filefd, *wh, sizeof(wave_header)) != (ssize_t) sizeof(wave_header)){
        (void) close(filefd); /* close input file */
        return -1;
    }
    (void) close(filefd);
    
    if((TOFOUR((*wh)->RiffID) != RIFF) ||
       (TOFOUR((*wh)->WaveID) != WAVE) ||
       (TOFOUR((*wh)->FmtID) != FMT)) return -1;
    
    return 0;
}

void cleanup(wave_header **wh)
{
    if(*wh!=0)
        free(*wh);
    *wh=0;
}
