Edinburgh Speech Tools 2.4-release
esps_io.cc
1/*************************************************************************/
2/* */
3/* Centre for Speech Technology Research */
4/* University of Edinburgh, UK */
5/* Copyright (c) 1994,1995,1996 */
6/* All Rights Reserved. */
7/* */
8/* Permission is hereby granted, free of charge, to use and distribute */
9/* this software and its documentation without restriction, including */
10/* without limitation the rights to use, copy, modify, merge, publish, */
11/* distribute, sublicense, and/or sell copies of this work, and to */
12/* permit persons to whom this work is furnished to do so, subject to */
13/* the following conditions: */
14/* 1. The code must retain the above copyright notice, this list of */
15/* conditions and the following disclaimer. */
16/* 2. Any modifications must be clearly marked as such. */
17/* 3. Original authors' names are not deleted. */
18/* 4. The authors' names are not used to endorse or promote products */
19/* derived from this software without specific prior written */
20/* permission. */
21/* */
22/* THE UNIVERSITY OF EDINBURGH AND THE CONTRIBUTORS TO THIS WORK */
23/* DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING */
24/* ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT */
25/* SHALL THE UNIVERSITY OF EDINBURGH NOR THE CONTRIBUTORS BE LIABLE */
26/* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES */
27/* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN */
28/* AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, */
29/* ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF */
30/* THIS SOFTWARE. */
31/* */
32/*************************************************************************/
33/* Author : Paul Taylor and Alan W Black */
34/* Date : June 1994 (June 1996) */
35/*-----------------------------------------------------------------------*/
36/* Access ESPS headered files */
37/* This offers a licence free interface to reading and writing ESPS */
38/* headered files. although not complete it works for most major ESPS */
39/* files include signals, lpc and F0 files */
40/* */
41/*=======================================================================*/
42#include <cstdio>
43#include <cstdlib>
44#include "EST_unix.h"
45#include <cstring>
46#include "EST_cutils.h"
47#include "EST_wave_utils.h"
48#include "esps_utils.h"
49
50/* The following are attempts to read and write ESPS header files without */
51/* Using the Entropic libraries. These routines do not read all ESPS */
52/* headers but are adequate for all of the uses we wish (and those you */
53/* wish too probably) */
54
55enum EST_write_status put_esps(const char *filename,const char *style, float *t, float *a,
56 int *v, float fsize, float rate, int num_points)
57{
58 (void)t;
59 esps_hdr hdr;
60 esps_rec rec;
61 FILE *fd;
62 int i;
63
64 if ((fd=fopen(filename,"wb")) == NULL)
65 {
66 fprintf(stderr,"ESPS file: cannot open file \"%s\" for writing\n",
67 filename);
68 return misc_write_error;
69 }
70
71 hdr = make_esps_hdr();
72
73 if (streq(style,"F0"))
74 {
75 add_field(hdr,"F0",ESPS_DOUBLE,1);
76 add_field(hdr,"prob_voice",ESPS_DOUBLE,1);
77 add_field(hdr,"rms",ESPS_DOUBLE,1);
78 add_field(hdr,"ac_peak",ESPS_DOUBLE,1);
79 add_field(hdr,"k1",ESPS_DOUBLE,1);
80 add_fea_d(hdr,"record_freq",0,(double)rate);
81 add_fea_d(hdr,"frame_duration",0,(double)fsize);
82 add_fea_d(hdr,"start_time",0,(double)0);
83 add_fea_special(hdr,ESPS_FEA_COMMAND,
84 "EDST F0 written as ESPS FEA_SD.\n");
85 write_esps_hdr(hdr,fd);
86 rec = new_esps_rec(hdr);
87 for (i = 0; i < num_points; i++)
88 {
89 set_field_d(rec,0,0,a[i]);
90 set_field_d(rec,1,0,(float)v[i]);
91 set_field_d(rec,2,0,0.5);
92 set_field_d(rec,3,0,0.5);
93 set_field_d(rec,4,0,0.5);
94 write_esps_rec(rec,hdr,fd);
95 }
96 delete_esps_rec(rec);
97 }
98 else
99 {
100 add_field(hdr,"Track",ESPS_DOUBLE,1);
101 add_fea_d(hdr,"window_duration",0,(double)0.049);
102 add_fea_d(hdr,"frame_duration",0,(double)fsize);
103 add_fea_d(hdr,"record_freq",0,(double)rate);
104 add_fea_d(hdr,"start_time",0,(double)0);
105 add_fea_special(hdr,ESPS_FEA_COMMAND,
106 "EDST Track written as ESPS FEA_SD.\n");
107 write_esps_hdr(hdr,fd);
108 rec = new_esps_rec(hdr);
109 for (i = 0; i < num_points; i++)
110 {
111 set_field_d(rec,0,0,a[i]);
112 write_esps_rec(rec,hdr,fd);
113 }
114 delete_esps_rec(rec);
115 }
116
117 delete_esps_hdr(hdr);
118 fclose(fd);
119
120 return write_ok;
121}
122
123enum EST_write_status put_track_esps(const char *filename, char **f_names,
124 float **a, float fsize, float rate,
125 int order, int num_points, short fixed)
126{
127 esps_hdr hdr;
128 esps_rec rec;
129 FILE *fd;
130 int i, j;
131
132 hdr = make_esps_hdr();
133
134 if ((fd = fopen(filename, "wb")) == NULL)
135 {
136 fprintf(stderr,"ESPS file: cannot open file \"%s\" for writing\n",
137 filename);
138 return misc_write_error;
139 }
140
141 for (i = 0; i < order; ++i)
142 add_field(hdr,f_names[i],ESPS_DOUBLE,1);
143
144 if (!streq(f_names[0],"F0"))
145 {
146 add_fea_s(hdr,"lpccep_order",0,(short)order);
147 add_fea_i(hdr,"step",0,(int)fsize);
148 add_fea_d(hdr,"window_duration",0,(double)0.049);
149 add_fea_i(hdr,"start",0,(int)1);
150 add_fea_f(hdr,"warping_param",0,(float)0.0);
151 add_fea_s(hdr,"window_type",0,(short)2);
152 }
153 add_fea_d(hdr,"record_freq",0,(double)rate);
154 add_fea_d(hdr,"frame_duration",0,(double)fsize);
155 add_fea_d(hdr,"start_time",0,(double)0.0);
156 if (!fixed)
157 add_fea_s(hdr,"est_variable_frame", 0, (short)1);
158
159 write_esps_hdr(hdr,fd);
160
161 rec = new_esps_rec(hdr);
162 for (i = 0; i < num_points; ++i)
163 {
164 for (j = 0; j < order; ++j)
165 set_field_d(rec, j, 0,(double)a[i][j]);
166 write_esps_rec(rec,hdr,fd);
167 }
168
169 delete_esps_hdr(hdr);
170 fclose(fd);
171 return write_ok;
172}
173
174enum EST_read_status get_esps(const char *filename, char *style,
175 float **t, float **a, int **v, float *fsize, int *num_points)
176{
177 (void)t;
178 FILE *fd;
179 enum EST_read_status rv;
180 int ff0, fprob_voice, i;
181 esps_hdr hdr;
182 float *ta;
183 double d;
184 int *tv;
185 esps_rec rec;
186
187 if ((fd = fopen(filename, "rb")) == NULL)
188 {
189 fprintf(stderr, "Can't open esps file %s for reading\n", filename);
190 return misc_read_error;
191 }
192
193 if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
194 {
195 fclose(fd);
196 return rv;
197 }
198 ta = walloc(float,hdr->num_records);
199 tv = walloc(int,hdr->num_records);
200 /* Find field number of FO and prob_voice */
201 for (ff0=fprob_voice=-1,i=0; i < hdr->num_fields; i++)
202 if (streq("F0",hdr->field_name[i]))
203 ff0=i;
204 else if (streq("prob_voice",hdr->field_name[i]))
205 fprob_voice = i;
206
207 rec = new_esps_rec(hdr);
208 for (i=0; i < hdr->num_records; i++)
209 {
210 if (read_esps_rec(rec,hdr,fd) == EOF)
211 {
212 fprintf(stderr,"ESPS file: unexpected end of file when reading record %d\n", i);
213 delete_esps_rec(rec);
214 delete_esps_hdr(hdr);
215 fclose(fd);
216 return misc_read_error;
217 }
218 if (ff0 == -1) /* F0 field isn't explicitly labelled */
219 { /* so take first field */
220 switch(rec->field[0]->type)
221 {
222 case ESPS_DOUBLE:
223 ta[i] = get_field_d(rec,0,0); break;
224 case ESPS_FLOAT:
225 ta[i] = get_field_f(rec,0,0); break;
226 default:
227 fprintf(stderr,"ESPS file: doesn't seem to be F0 file\n");
228 delete_esps_rec(rec);
229 delete_esps_hdr(hdr);
230 fclose(fd);
231 return misc_read_error;
232 }
233 }
234 else /* use named field -- assume its a double */
235 ta[i] = get_field_d(rec,ff0,0);
236 if (fprob_voice == -1)
237 tv[i] = 1; /* no prob_voice field in this */
238 else
239 tv[i] = ((get_field_d(rec,fprob_voice,0) < 0.5) ? 0 : 1);
240 }
241
242 *num_points = hdr->num_records;
243 *a = ta;
244 *v = tv;
245 if (fea_value_d("record_freq",0,hdr,&d) != 0)
246 *fsize = 0;
247 else
248 *fsize = 1.0/d;
249 if (ff0 != -1)
250 strcpy(style, "F0");
251 else
252 strcpy(style, "track");
253 delete_esps_rec(rec);
254 delete_esps_hdr(hdr);
255 fclose(fd);
256
257 return format_ok;
258}
259
260enum EST_read_status get_track_esps(const char *filename, char ***fields,
261 float ***a, float *fsize,
262 int *num_points, int *num_fields,
263 short *fixed)
264{
265 esps_hdr hdr;
266 esps_rec rec;
267 FILE *fd;
268 int i, j, order, num_recs;
269 enum EST_read_status rv;
270 double d;
271 char **tf;
272 float **ta;
273
274 if ((fd = fopen(filename, "rb")) == NULL)
275 return misc_read_error;
276
277 if ((rv=read_esps_hdr(&hdr,fd)) != format_ok)
278 {
279 fclose(fd);
280 return rv;
281 }
282 num_recs = hdr->num_records;
283 order = hdr->num_fields;
284
285 ta = walloc(float *,num_recs);
286 tf = walloc(char *,order);
287 for (j = 0; j < num_recs; ++j)
288 ta[j] = walloc(float,order);
289
290 /* Read data values */
291 rec = new_esps_rec(hdr);
292
293 {
294 short v;
295 *fixed = fea_value_s("est_variable_frame", 0, hdr, &v) != 0;
296 }
297
298 for (j = 0; j < hdr->num_records; j++)
299 {
300 if (read_esps_rec(rec,hdr,fd) == EOF)
301 {
302 fprintf(stderr,"ESPS file: unexpected end of file when reading record %d\n", j);
303 delete_esps_rec(rec);
304 delete_esps_hdr(hdr);
305 }
306 for (i = 0; i < order; ++i)
307 switch (rec->field[i]->type)
308 {
309 case ESPS_DOUBLE:
310 ta[j][i]=get_field_d(rec,i,0); break;
311 case ESPS_FLOAT:
312 ta[j][i]=get_field_f(rec,i,0); break;
313 case ESPS_INT:
314 ta[j][i]=(float)get_field_i(rec,i,0); break;
315 case ESPS_SHORT:
316 ta[j][i]=(float)get_field_s(rec,i,0); break;
317 case ESPS_CHAR:
318 ta[j][i]=(float)get_field_c(rec,i,0); break;
319 case ESPS_CODED:
320 ta[j][i]=(float)get_field_s(rec,i,0); break;
321 default:
322 fprintf(stderr,"ESPS file: unsupported type in record %d\n",
323 rec->field[i]->type);
324 delete_esps_rec(rec);
325 delete_esps_hdr(hdr);
326 fclose(fd);
327 return misc_read_error;
328 }
329 }
330 num_recs = j; /* just a safe guard */
331
332 /* read field names */
333 for (j = 0; j < order; ++j)
334 tf[j] = wstrdup(hdr->field_name[j]);
335
336 /* copy local variables into argument list */
337 *fields = tf;
338 *num_points = num_recs;
339 *num_fields = order;
340 *a = ta;
341
342 if (fea_value_d("record_freq",0,hdr,&d) != 0)
343 *fsize = 0;
344 else
345 *fsize = 1.0/d;
346
347 delete_esps_rec(rec);
348 delete_esps_hdr(hdr);
349
350 fclose(fd);
351 return format_ok;
352}
353