Edinburgh Speech Tools  2.1-release
ssff.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1999 */
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 : Alan W Black */
34 /* Date : November 1999 */
35 /*-----------------------------------------------------------------------*/
36 /* Version of code for reading and writing MacQuarie's SSFF format as */
37 /* used in emulabel */
38 /* */
39 /*=======================================================================*/
40 #include <fstream>
41 #include <iostream>
42 #include <cstdlib>
43 #include <cmath>
44 #include <time.h>
45 #include "EST_unix.h"
46 #include "EST_types.h"
47 #include "EST_Track.h"
48 #include "EST_track_aux.h"
49 #include "EST_TrackMap.h"
50 #include "EST_cutils.h"
51 #include "EST_Token.h"
52 #include "EST_TList.h"
53 #include "EST_string_aux.h"
54 #include "EST_walloc.h"
55 #include "EST_TrackFile.h"
56 #include "EST_FileType.h"
57 #include "EST_File.h"
58 
59 using namespace std;
60 
62  EST_Track &tr, float ishift, float startt)
63 {
64  EST_TokenStream ts;
65 
66  if (((filename == "-") ? ts.open(cin) : ts.open(filename)) != 0)
67  {
68  cerr << "Can't open track file " << filename << endl;
69  return misc_read_error;
70  }
71  tr.set_name(filename);
72  return load_ssff_ts(ts, tr, ishift, startt);
73 }
74 
76 {
77  (void)ishift;
78  (void)startt;
79  ssize_t num_frames, num_channels;
80  int swap = FALSE;
81  ssize_t i,j;
82  EST_FilePos pos,end;
83  float Start_Time, Record_Freq;
84  EST_Features channels;
85  EST_String c, name, type, size, cname;
86  FILE *fp;
87  double dbuff[2];
88  short sbuff[2];
89 
90  num_frames = num_channels = 0;
91  Start_Time = Record_Freq = 0;
92 
93  if (ts.get() != "SSFF")
94  return wrong_format;
95 
96  if ((ts.get() != "--") ||
97  (ts.get() != "(c)") ||
98  (ts.get() != "SHLRC"))
99  {
100  cerr << "ssff load track \"" << ts.filename() << "\": bad header"
101  << endl;
102  return misc_read_error;
103  }
104 
105  while (ts.peek() != "-----------------")
106  {
107  c = (EST_String)ts.get();
108  if (c == "Comment")
109  ts.get_upto_eoln();
110  else if (c == "Start_Time")
111  {
112  Start_Time = atof(ts.get().string());
113  tr.f_set("Start_Time",Start_Time);
114  }
115  else if (c == "Record_Freq")
116  {
117  Record_Freq = atof(ts.get().string());
118  tr.f_set("Record_Freq",Record_Freq);
119  }
120  else if (c == "Machine")
121  {
122  if (ts.get() == "SPARC")
123  {
124  if (EST_NATIVE_BO != bo_big)
125  swap = TRUE;
126  }
127  else if (EST_NATIVE_BO == bo_big)
128  swap = TRUE;
129  }
130  else if (c == "Column")
131  {
132  name = (EST_String)ts.get();
133  type = (EST_String)ts.get();
134  size = (EST_String)ts.get();
135  cname = EST_String("Channel_")+itoString(num_channels);
136  channels.set(cname+".name",name);
137  channels.set(cname+".type",type);
138  channels.set(cname+".size",atoi(size));
139  num_channels++;
140  }
141  else if ((c == "window_type") ||
142  (c == "window_duration") ||
143  (c == "lpc_order") ||
144  (c == "lpc_type") ||
145  (c == "end_time") ||
146  (c == "preemphasis") ||
147  (c == "frame_duration"))
148  {
149  type = (EST_String)ts.get();
150  if (type == "SHORT")
151  tr.f_set(c,atoi(ts.get().string()));
152  else if (type == "DOUBLE")
153  tr.f_set(c,(float)atof(ts.get().string()));
154  else
155  tr.f_set(c,ts.get().string());
156  }
157  else if (ts.eof())
158  {
159  cerr << "ssff load track \"" << ts.filename() <<
160  "\": bad header unexpected eof" << endl;
161  return misc_read_error;
162  }
163  // else
164  // {
165  // cerr << "ssff load track \"" << ts.filename() <<
166  // "\": unknown header value \"" << c << "\"" << endl;
167  // }
168  }
169  ts.get(); // skip over end of header line
170 
171  // There's no num_records field in the header so have to use file's
172  // length to calculate it
173  fp = ts.filedescriptor();
174  pos = EST_ftell(fp);
175  EST_fseek(fp,0,SEEK_END);
176  end = EST_ftell(fp);
177  EST_fseek(fp,pos,SEEK_SET);
178  if (num_channels == 0) { /* Dummy unlikely case (wrong format?) */
179  num_frames = 0;
180  } else {
181  num_frames = (end - pos)/(num_channels*sizeof(double));
182  }
183 
184  // Finished reading header
185  tr.resize(num_frames,num_channels);
186  tr.fill_time(1.0/Record_Freq);
187  tr.set_equal_space(true);
188 
189  for (i=0; i<num_channels; i++)
190  tr.set_channel_name(channels.S(EST_String("Channel_")+
191  itoString(i)+".name"),i);
192 
193  for (i=0; i < num_frames; i++)
194  for (j=0; j<num_channels; j++)
195  {
196  type = channels.S(EST_String("Channel_")+ itoString(j)+".type");
197  if (type == "DOUBLE")
198  {
199  if (ts.fread(dbuff,sizeof(double),1) != 1)
200  {
201  cerr << "Failed to read frame " << i << ", channel " <<
202  j << endl;
203  return misc_read_error;
204  }
205  if (swap)
206  swap_bytes_double(dbuff,1);
207  tr(i,j) = *dbuff;
208  }
209  else if (type == "SHORT")
210  {
211  if (ts.fread(sbuff,sizeof(short),1) != 1)
212  {
213  cerr << "Failed to read short from frame" << i <<
214  ", channel " << j << endl;
215  return misc_read_error;
216  }
217  if (swap)
218  swap_bytes_short(sbuff,1);
219  tr(i,j) = (float)(*sbuff);
220  }
221  else
222  {
223  cerr << "ssff load track \"" << ts.filename() <<
224  "\": unknown channel type value \"" << type << "\"" << endl;
225  return misc_read_error;
226  }
227  }
228 
229  return format_ok;
230 }
231 
233 {
234  FILE *fd;
236 
237  if (filename == "-")
238  fd = stdout;
239  else if ((fd = fopen(filename,"wb")) == NULL)
240  return write_fail;
241 
242  r = save_ssff_ts(fd,tr);
243 
244  if (fd != stdout)
245  fclose(fd);
246  return r;
247 
248 }
249 
251 {
252  ssize_t i,j;
253  int need_prob_voice = 0;
254 
255  if (tr.equal_space() != 1)
256  {
257  cerr << "ssf save track: can't save variable spaced track as SSFF"
258  << endl;
259  return write_error;
260  }
261 
262  fprintf(fp,"SSFF -- (c) SHLRC\n");
263  if (EST_NATIVE_BO == bo_big)
264  fprintf(fp,"Machine SPARC\n");
265  else
266  fprintf(fp,"Machine IBM-PC\n");
267  if (tr.f_present("Start_Time"))
268  fprintf(fp,"Start_Time %g\n",(double)tr.f_F("Start_Time"));
269  else
270  fprintf(fp,"Start_Time 0.000000\n");
271  // If there are less than two sample points I can't get this value
272  if (tr.f_present("Record_Freq"))
273  fprintf(fp,"Record_Freq %g\n",(double)tr.f_F("Record_Freq"));
274  else if (tr.num_frames() < 2)
275  fprintf(fp,"Record_Freq %d\n", 100);
276  else
277  fprintf(fp,"Record_Freq %g\n", 1/(tr.t(1)-tr.t(0)));
278 
279  for (i = 0; i < tr.num_channels(); ++i)
280  fprintf(fp, "Column %s DOUBLE 1\n",(const char *)(tr.channel_name(i)));
281  // For EMULABEL to read this is needs prob_voice too
282  if ((tr.num_channels() == 1) &&
283  (tr.channel_name(0) == "F0"))
284  {
285  need_prob_voice = 1;
286  fprintf(fp, "Column prob_voice DOUBLE 1\n");
287  }
289 
290  for (p.begin(tr); p; ++p)
291  {
292  if ((p->k == "Start_Time") ||
293  (p->k == "Record_Freq"))
294  continue;
295  else
296  fprintf(fp, "%s DOUBLE %s\n", (const char *)p->k,
297  (const char *) p->v.String());
298  }
299  fprintf(fp,"-----------------\n");
300  for (i=0; i< tr.num_frames(); i++)
301  {
302  double prob_voice;
303  double dd;
304  for (j=0; j< tr.num_channels(); j++)
305  {
306  dd = tr(i,j);
307  fwrite(&dd,sizeof(double),1,fp);
308  }
309  if (need_prob_voice)
310  {
311  if (tr(i,0) == 0)
312  prob_voice = 0;
313  else
314  prob_voice = 1;
315  fwrite(&prob_voice,sizeof(double),1,fp);
316  }
317  }
318 
319  return write_ok;
320 }
EST_TokenStream & get(EST_Token &t)
get next token in stream
Definition: EST_Token.cc:499
float end(const EST_Item &item)
Definition: EST_item_aux.cc:96
FILE * filedescriptor()
For the people who need the actual description (if possible)
Definition: EST_Token.h:380
EST_FilePos EST_ftell(FILE *fp)
Definition: EST_File.h:71
EST_write_status
int fread(void *buff, int size, int nitems) EST_WARN_UNUSED_RESULT
Reading binary data, (don&#39;t use peek() immediately beforehand)
Definition: EST_Token.cc:368
void set_channel_name(const EST_String &name, int channel)
set the name of the channel.
Definition: EST_Track.cc:168
int num_channels() const
return number of channels in track
Definition: EST_Track.h:657
static EST_write_status save_ssff_ts(SaveTrac_TokenStreamArgs)
Definition: ssff.cc:250
const EST_String filename() const
The originating filename (if there is one)
Definition: EST_Token.h:378
EST_String itoString(int n)
Make a EST_String object from an integer.
Definition: util_io.cc:141
void swap_bytes_double(double *data, int length)
Definition: EST_swapping.cc:68
void set(const EST_String &name, int ival)
Definition: EST_Features.h:186
int ssize_t
void resize(ssize_t num_frames, int num_channels, bool preserve=1)
Definition: EST_Track.cc:214
int open(const EST_String &filename)
open a EST_TokenStream for a file.
Definition: EST_Token.cc:213
const EST_String S(const EST_String &path) const
Definition: EST_Features.h:158
static EST_read_status load_ssff_ts(LoadTrack_TokenStreamArgs)
Definition: ssff.cc:75
The file was not written successfully.
int eof()
end of file
Definition: EST_Token.h:362
#define SEEK_END
Definition: system.h:28
bool equal_space() const
return true if track has equal (i.e. fixed) frame spacing */
Definition: EST_Track.h:670
float & t(ssize_t i=0)
return time position of frame i
Definition: EST_Track.h:478
The file was written successfully.
void set_name(const EST_String &n)
set name of track - redundant use access to features
Definition: EST_Track.h:199
#define wrong_format
#define FALSE
Definition: EST_bool.h:119
void swap_bytes_short(short *data, int length)
Definition: EST_swapping.cc:97
#define misc_read_error
NULL
Definition: EST_WFST.cc:55
int EST_fseek(FILE *fp, EST_FilePos offset, int whence)
Definition: EST_File.h:75
ssize_t num_frames() const
return number of frames in track
Definition: EST_Track.h:651
EST_Token & peek(void)
peek at next token
Definition: EST_Token.h:332
The file was not written successfully.
const EST_String channel_name(int channel, const EST_ChannelNameMap &map, int strings_override=1) const
Definition: EST_Track.cc:138
EST_read_status
void begin(const Container &over)
Set the iterator ready to run over this container.
#define format_ok
#define EST_NATIVE_BO
Definition: EST_cutils.h:72
EST_Token get_upto_eoln(void)
get up to s in end of line as a single token.
Definition: EST_Token.cc:529
static EST_write_status save_ssff(SaveTrackFileArgs)
Definition: ssff.cc:232
LISP fp
Definition: kkcompile.cc:63
EST_String
#define TRUE
Definition: EST_bool.h:118
static EST_read_status load_ssff(LoadTrackFileArgs)
Definition: ssff.cc:61
off_t EST_FilePos
Definition: EST_File.h:69
void set_equal_space(bool t)
Definition: EST_Track.h:675
void fill_time(float t, int start=1)
Definition: EST_Track.cc:789
Utility EST_String Functions header file.
#define SEEK_SET
Definition: system.h:20