Edinburgh Speech Tools  2.4-release
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends Pages
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 
55 enum 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 
123 enum 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 
174 enum 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 
260 enum 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