Loading...
Searching...
No Matches
esps_io.cc
/*************************************************************************/
/* */
/* Centre for Speech Technology Research */
/* University of Edinburgh, UK */
/* Copyright (c) 1994,1995,1996 */
/* All Rights Reserved. */
/* */
/* Permission is hereby granted, free of charge, to use and distribute */
/* this software and its documentation without restriction, including */
/* without limitation the rights to use, copy, modify, merge, publish, */
/* distribute, sublicense, and/or sell copies of this work, and to */
/* permit persons to whom this work is furnished to do so, subject to */
/* the following conditions: */
/* 1. The code must retain the above copyright notice, this list of */
/* conditions and the following disclaimer. */
/* 2. Any modifications must be clearly marked as such. */
/* 3. Original authors' names are not deleted. */
/* 4. The authors' names are not used to endorse or promote products */
/* derived from this software without specific prior written */
/* permission. */
/* */
/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
/* THIS SOFTWARE. */
/* */
/*************************************************************************/
/* Author : Paul Taylor and Alan W Black */
/* Date : June 1994 (June 1996) */
/*-----------------------------------------------------------------------*/
/* Access ESPS headered files */
/* This offers a licence free interface to reading and writing ESPS */
/* headered files. although not complete it works for most major ESPS */
/* files include signals, lpc and F0 files */
/* */
/*=======================================================================*/
#include <cstdio>
#include <cstdlib>
#include "EST_unix.h"
#include <cstring>
#include "EST_cutils.h"
#include "EST_wave_utils.h"
#include "esps_utils.h"
/* The following are attempts to read and write ESPS header files without */
/* Using the Entropic libraries. These routines do not read all ESPS */
/* headers but are adequate for all of the uses we wish (and those you */
/* wish too probably) */
enum EST_write_status put_esps(const char *filename,const char *style, float *t, float *a,
int *v, float fsize, float rate, int num_points)
{
(void)t;
esps_hdr hdr;
esps_rec rec;
FILE *fd;
int i;
if ((fd=fopen(filename,"wb")) == NULL)
{
fprintf(stderr,"ESPS file: cannot open file \"%s\" for writing\n",
filename);
return misc_write_error;
}
hdr = make_esps_hdr();
if (streq(style,"F0"))
{
add_field(hdr,"F0",ESPS_DOUBLE,1);
add_field(hdr,"prob_voice",ESPS_DOUBLE,1);
add_field(hdr,"rms",ESPS_DOUBLE,1);
add_field(hdr,"ac_peak",ESPS_DOUBLE,1);
add_field(hdr,"k1",ESPS_DOUBLE,1);
add_fea_d(hdr,"record_freq",0,(double)rate);
add_fea_d(hdr,"frame_duration",0,(double)fsize);
add_fea_d(hdr,"start_time",0,(double)0);
add_fea_special(hdr,ESPS_FEA_COMMAND,
"EDST F0 written as ESPS FEA_SD.\n");
write_esps_hdr(hdr,fd);
rec = new_esps_rec(hdr);
for (i = 0; i < num_points; i++)
{
set_field_d(rec,0,0,a[i]);
set_field_d(rec,1,0,(float)v[i]);
set_field_d(rec,2,0,0.5);
set_field_d(rec,3,0,0.5);
set_field_d(rec,4,0,0.5);
write_esps_rec(rec,hdr,fd);
}
delete_esps_rec(rec);
}
else
{
add_field(hdr,"Track",ESPS_DOUBLE,1);
add_fea_d(hdr,"window_duration",0,(double)0.049);
add_fea_d(hdr,"frame_duration",0,(double)fsize);
add_fea_d(hdr,"record_freq",0,(double)rate);
add_fea_d(hdr,"start_time",0,(double)0);
add_fea_special(hdr,ESPS_FEA_COMMAND,
"EDST Track written as ESPS FEA_SD.\n");
write_esps_hdr(hdr,fd);
rec = new_esps_rec(hdr);
for (i = 0; i < num_points; i++)
{
set_field_d(rec,0,0,a[i]);
write_esps_rec(rec,hdr,fd);
}
delete_esps_rec(rec);
}
delete_esps_hdr(hdr);
fclose(fd);
return write_ok;
}
enum EST_write_status put_track_esps(const char *filename, char **f_names,
float **a, float fsize, float rate,
int order, int num_points, short fixed)
{
esps_hdr hdr;
esps_rec rec;
FILE *fd;
int i, j;
hdr = make_esps_hdr();
if ((fd = fopen(filename, "wb")) == NULL)
{
fprintf(stderr,"ESPS file: cannot open file \"%s\" for writing\n",
filename);
return misc_write_error;
}
for (i = 0; i < order; ++i)
add_field(hdr,f_names[i],ESPS_DOUBLE,1);
if (!streq(f_names[0],"F0"))
{
add_fea_s(hdr,"lpccep_order",0,(short)order);
add_fea_i(hdr,"step",0,(int)fsize);
add_fea_d(hdr,"window_duration",0,(double)0.049);
add_fea_i(hdr,"start",0,(int)1);
add_fea_f(hdr,"warping_param",0,(float)0.0);
add_fea_s(hdr,"window_type",0,(short)2);
}
add_fea_d(hdr,"record_freq",0,(double)rate);
add_fea_d(hdr,"frame_duration",0,(double)fsize);
add_fea_d(hdr,"start_time",0,(double)0.0);
if (!fixed)
add_fea_s(hdr,"est_variable_frame", 0, (short)1);
write_esps_hdr(hdr,fd);
rec = new_esps_rec(hdr);
for (i = 0; i < num_points; ++i)
{
for (j = 0; j < order; ++j)
set_field_d(rec, j, 0,(double)a[i][j]);
write_esps_rec(rec,hdr,fd);
}
delete_esps_hdr(hdr);
fclose(fd);
return write_ok;
}
enum EST_read_status get_esps(const char *filename, char *style,
float **t, float **a, int **v, float *fsize, int *num_points)
{
(void)t;
FILE *fd;
enum EST_read_status rv;
int ff0, fprob_voice, i;
esps_hdr hdr;
float *ta;
double d;
int *tv;
esps_rec rec;
if ((fd = fopen(filename, "rb")) == NULL)
{
fprintf(stderr, "Can't open esps file %s for reading\n", filename);
return misc_read_error;
}
if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
{
fclose(fd);
return rv;
}
ta = walloc(float,hdr->num_records);
tv = walloc(int,hdr->num_records);
/* Find field number of FO and prob_voice */
for (ff0=fprob_voice=-1,i=0; i < hdr->num_fields; i++)
if (streq("F0",hdr->field_name[i]))
ff0=i;
else if (streq("prob_voice",hdr->field_name[i]))
fprob_voice = i;
rec = new_esps_rec(hdr);
for (i=0; i < hdr->num_records; i++)
{
if (read_esps_rec(rec,hdr,fd) == EOF)
{
fprintf(stderr,"ESPS file: unexpected end of file when reading record %d\n", i);
delete_esps_rec(rec);
delete_esps_hdr(hdr);
fclose(fd);
return misc_read_error;
}
if (ff0 == -1) /* F0 field isn't explicitly labelled */
{ /* so take first field */
switch(rec->field[0]->type)
{
case ESPS_DOUBLE:
ta[i] = get_field_d(rec,0,0); break;
case ESPS_FLOAT:
ta[i] = get_field_f(rec,0,0); break;
default:
fprintf(stderr,"ESPS file: doesn't seem to be F0 file\n");
delete_esps_rec(rec);
delete_esps_hdr(hdr);
fclose(fd);
return misc_read_error;
}
}
else /* use named field -- assume its a double */
ta[i] = get_field_d(rec,ff0,0);
if (fprob_voice == -1)
tv[i] = 1; /* no prob_voice field in this */
else
tv[i] = ((get_field_d(rec,fprob_voice,0) < 0.5) ? 0 : 1);
}
*num_points = hdr->num_records;
*a = ta;
*v = tv;
if (fea_value_d("record_freq",0,hdr,&d) != 0)
*fsize = 0;
else
*fsize = 1.0/d;
if (ff0 != -1)
strcpy(style, "F0");
else
strcpy(style, "track");
delete_esps_rec(rec);
delete_esps_hdr(hdr);
fclose(fd);
return format_ok;
}
enum EST_read_status get_track_esps(const char *filename, char ***fields,
float ***a, float *fsize,
int *num_points, int *num_fields,
short *fixed)
{
esps_hdr hdr;
esps_rec rec;
FILE *fd;
int i, j, order, num_recs;
enum EST_read_status rv;
double d;
char **tf;
float **ta;
if ((fd = fopen(filename, "rb")) == NULL)
return misc_read_error;
if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
{
fclose(fd);
return rv;
}
num_recs = hdr->num_records;
order = hdr->num_fields;
ta = walloc(float *,num_recs);
tf = walloc(char *,order);
for (j = 0; j < num_recs; ++j)
ta[j] = walloc(float,order);
/* Read data values */
rec = new_esps_rec(hdr);
{
short v;
*fixed = fea_value_s("est_variable_frame", 0, hdr, &v) != 0;
}
for (j = 0; j < hdr->num_records; j++)
{
if (read_esps_rec(rec,hdr,fd) == EOF)
{
fprintf(stderr,"ESPS file: unexpected end of file when reading record %d\n", j);
delete_esps_rec(rec);
delete_esps_hdr(hdr);
}
for (i = 0; i < order; ++i)
switch (rec->field[i]->type)
{
case ESPS_DOUBLE:
ta[j][i]=get_field_d(rec,i,0); break;
case ESPS_FLOAT:
ta[j][i]=get_field_f(rec,i,0); break;
case ESPS_INT:
ta[j][i]=(float)get_field_i(rec,i,0); break;
case ESPS_SHORT:
ta[j][i]=(float)get_field_s(rec,i,0); break;
case ESPS_CHAR:
ta[j][i]=(float)get_field_c(rec,i,0); break;
case ESPS_CODED:
ta[j][i]=(float)get_field_s(rec,i,0); break;
default:
fprintf(stderr,"ESPS file: unsupported type in record %d\n",
rec->field[i]->type);
delete_esps_rec(rec);
delete_esps_hdr(hdr);
fclose(fd);
return misc_read_error;
}
}
num_recs = j; /* just a safe guard */
/* read field names */
for (j = 0; j < order; ++j)
tf[j] = wstrdup(hdr->field_name[j]);
/* copy local variables into argument list */
*fields = tf;
*num_points = num_recs;
*num_fields = order;
*a = ta;
if (fea_value_d("record_freq",0,hdr,&d) != 0)
*fsize = 0;
else
*fsize = 1.0/d;
delete_esps_rec(rec);
delete_esps_hdr(hdr);
fclose(fd);
return format_ok;
}