/**
* @file wrwav.c
*
*
* @brief 音声波形データを WAV ファイルに保存する
*
*
* @brief Write waveform data to WAV file
*
*
* @author Akinobu LEE
* @date Tue Feb 15 01:02:18 2005
*
* $Revision: 1.4 $
*
*/
/*
* Copyright (c) 1991-2012 Kawahara Lab., Kyoto University
* Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
* Copyright (c) 2005-2012 Julius project team, Nagoya Institute of Technology
* All rights reserved
*/
#include
#include
/// Total number of samples written to the file.
static int totallen;
/**
* Write speech data in little endian.
*
* @param buf [in] speech data
* @param unitbyte [in] unit size in bytes
* @param unitnum [in] number of units to be written
* @param fp [in] file pointer
*
* @return TRUE on success (specified number of data has been written), FALSE on failure.
*/
static boolean
mywrite(void *buf, size_t unitbyte, int unitnum, FILE *fp)
{
int tmp;
#ifdef WORDS_BIGENDIAN
if (unitbyte > 1) swap_bytes(buf, unitbyte, unitnum);
#endif
if ((tmp = myfwrite(buf, unitbyte, unitnum, fp)) < unitnum) {
return(FALSE);
}
#ifdef WORDS_BIGENDIAN
if (unitbyte > 1) swap_bytes(buf, unitbyte, unitnum);
#endif
return(TRUE);
}
/// Function macro to mywrite() with error handling.
#define MYWRITE(A,B,C,D) if (!mywrite(A, B, C, D)) {jlog("Error: wrwav: failed to write wave data\n"); fclose_writefile(fp); return NULL;}
/* open/create a WAVE file for writing, and write header */
/* return file pointer, NULL on failure */
/**
* @brief Open/create a WAVE file and write header.
*
* Open or creat a new WAV file and prepare for later data writing.
* The frame length written here is dummy, and will be overwritten when
* closed by wrwav_close().
*
* @param filename [in] file name
* @param sfreq [in] sampling frequency of the data you are going to write
*
* @return the file pointer.
*/
FILE *
wrwav_open(char *filename, int sfreq)
{
FILE *fp;
unsigned int i;
unsigned short s;
/* open file for writing */
if ((fp = fopen_writefile(filename)) == NULL) return NULL;
/* write header */
/* first 4 byte: 'R' 'I' 'F' 'F' */
MYWRITE("RIFF", 1, 4, fp);
/* 4 byte: byte num of rest: dummy for now */
i = 0; MYWRITE(&i, 4, 1, fp);
/* first part: WAVE format specifications */
/* 8 byte: 'W' 'A' 'V' 'E' 'f' 'm' 't' ' ' */
MYWRITE("WAVEfmt ", 1, 8, fp);
/* 4byte: byte size of the next part (16 bytes here) */
i = 16; MYWRITE(&i, 4, 1, fp);
/* 2byte: data format */
s = 1; MYWRITE(&s, 2, 1, fp); /* PCM */
/* 2byte: channel num */
s = 1; MYWRITE(&s, 2, 1, fp); /* mono */
/* 4byte: sampling rate */
i = sfreq; MYWRITE(&i, 4, 1, fp);
/* 4byte: bytes per second */
i = sfreq * sizeof(SP16); MYWRITE(&i, 4, 1, fp);
/* 2bytes: bytes per frame ( = (bytes per sample) x channel ) */
s = sizeof(SP16); MYWRITE(&s, 2, 1, fp);
/* 2bytes: bits per sample */
s = sizeof(SP16) * 8; MYWRITE(&s, 2, 1, fp);
/* data part header */
MYWRITE("data", 1, 4, fp);
/* data length: dummy for now */
i = 0; MYWRITE(&i, 4, 1, fp);
totallen = 0; /* reset total length */
return(fp);
}
/**
* Write speech samples.
*
* @param fp [in] file descriptor
* @param buf [in] speech data to be written
* @param len [in] length of above
*
* @return actual number of written samples.
*/
boolean
wrwav_data(FILE *fp, SP16 *buf, int len)
{
boolean ret;
ret = mywrite(buf, sizeof(SP16), len, fp);
if (ret) totallen += len;
return(ret);
}
/* close file */
/**
* @brief Close the file.
*
* The frame length in the header part is overwritten by the actual value
* before file close.
*
* @param fp [in] file pointer to close, previously opened by wrwav_open().
*
* @return TRUE on success, FALSE on failure.
*/
boolean
wrwav_close(FILE *fp)
{
unsigned int i;
/* overwrite data length after recording */
/* at 5-8(len+36), 41-44 (len) */
if (fseek(fp, 40, SEEK_SET) != 0) { /* error */
jlog("Error: wrwav: failed to seek for header\n");
return(FALSE);
}
i = totallen * sizeof(SP16);
if (!mywrite(&i, 4, 1, fp)) {
jlog("Error: wrwav: failed to re-write header\n");
return(FALSE);
}
if (fseek(fp, 4, SEEK_SET) != 0) { /* error */
jlog("Error: wrwav: failed to seek for header\n");
return(FALSE);
}
i = totallen * sizeof(SP16) + 36;
if (!mywrite(&i, 4, 1, fp)) {
jlog("Error: wrwav: failed to re-write header\n");
return(FALSE);
}
/* close file */
fclose_writefile(fp);
return(TRUE);
}