/* 
             CREATOR: Colin Ligertwood
                DATE: ?????
         DESCRIPTION: operations for verifying and reading wav files. 
            FILENAME: wav_write.c
             STARTED: ?????
           PLATFORMS: Linux (DOS)
	 MOD_HISTORY: 
                  - ????? ????? initial creation
                  - Sep 5 2000 Dan Williams, general cleanup.

*/


//#include <sys/soundcard.h>
#include <sys/types.h>

#include <stdio.h>
#include <fcntl.h>
//#include <signal.h>
#include <string.h>
//#include <unistd.h>
#include "wav_lib.h"

// !!!???!!!
//#include <IO.h> // for DOS

/*
------------------------------ init_head -------------------------------
does: (re)initializes a wav header
  in: wav_sig structure with handle, chans, srate, and depth initialized
 out: void (be sure not to put voids in your pocket or your change will vanish)
*/
void init_head(wav_sig *info){
  strncpy(&info->head[0], "RIFF", 4);
  // 36 because the first 4 bytes arn't counted
  *(int32_t *)&info->head[4]  = (info->sofar + 36); 
  strncpy(&info->head[8], "WAVEfmt ", 8);
  *(int32_t *)&info->head[16] = 16;
  *(int16_t *)&info->head[20] = 1;                                       // PCM
  *(int16_t *)&info->head[22] = info->chans;                             // channels
  *(int32_t *)&info->head[24] = info->srate;                             // sample rate
  *(int32_t *)&info->head[28] = info->srate*(info->depth/8)*info->chans; // bps
  *(int16_t *)&info->head[32] = (info->depth/8)*info->chans;             // blkalign
  *(int16_t *)&info->head[34] = info->depth;                             // depth
  strncpy(&info->head[36], "data", 4);                                   // signature
  *(int32_t *)&info->head[40] = info->sofar;                             // data length
} 

/*
----------------------------- init_wav_write ----------------------------
does: initializes a new wav file for output
  in: filename, sampleRate, sampleDepth, channelCount, wav_sig structure
 out: 
  success: handle to file
     fail: -1
*/
int init_wav_write(const char *file_name, int32_t sps, int16_t bps, int16_t channels,  wav_sig *info){
  info->sofar    = 0;                           // no data yet
  info->name     = file_name;                   // You are responsible for this pointer 
  info->chans    = channels;                    // 1 = mono etc
  info->srate    = sps;                         // samples per second
  info->depth    = bps;                         // bits per sample
  info->blkalign = (info->depth/8)*info->chans; // bytes per 'frame'  
  if ((info->handle = open(info->name, O_CREAT | O_RDWR, 0644)) == (-1)) {
    return (-1);
  }
  init_head(info);
  write(info->handle, info->head, 44);
  return(info->handle);
}


/*
------------------------------ fin_wav_write ---------------------------
does: finalize a wav-writeing session
  in: wav_sig structure
 out: 0
*/
int fin_wav_write(wav_sig *info){
  lseek(info->handle, 0, SEEK_SET);
  init_head(info);
  write(info->handle, info->head, 44);
  close(info->handle);
  return 0;
}







