Edinburgh Speech Tools  2.1-release
siod_est.cc
Go to the documentation of this file.
1 /*************************************************************************/
2 /* */
3 /* Centre for Speech Technology Research */
4 /* University of Edinburgh, UK */
5 /* Copyright (c) 1996-1998 */
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 : February 1998 */
35 /*-----------------------------------------------------------------------*/
36 /* */
37 /* Functions to add Speech Tools basic objects to the SIOD LISP obj */
38 /* */
39 /* This offers non-intrusive support for arbitrary objects in LISP, */
40 /* however because the deletion method are called this needs to access */
41 /* Thus if you include siod_est_init(), you'll get Utterances, Nodes */
42 /* Stream_Items, Waves and Tracks in your binary */
43 /* */
44 /*=======================================================================*/
45 #include <iostream>
46 #include "siod.h"
48 #include "ling_class/EST_Item.h"
49 #include "EST_THash.h"
50 #include "EST_Wave.h"
51 #include "EST_wave_aux.h"
52 #include "EST_Track.h"
53 #include "EST_track_aux.h"
54 
55 Declare_TStringHash_Base(LISP,(LISP)0,NIL)
56 
57 #if defined(INSTANTIATE_TEMPLATES)
58 #include "../base_class/EST_THash.cc"
59 
61 
62 #endif
63 
64 using namespace std;
65 
66 // To make garbage collection easy the following functions offer an index
67 // of arbitrary objects to LISP cells. You can use this to return the
68 // same LISP cell for the same object. This is used for utterance
69 // objects otherwise I'd need to add reference counts to the utterance
70 // itself
71 //
72 // This is implemented as a hash table of printed address
73 // This if fine for hundreds of things, but probably not
74 // for thousands of things
75 static EST_TStringHash<LISP> estobjs(100);
76 
77 static void void_to_addrname(const void *v,EST_String &saddr)
78 {
79  char addr[128];
80 
81  sprintf(addr,"%p",v);
82  saddr = addr;
83 }
84 
85 // The following are the types for EST objects in LISP, they are set when
86 // the objects are registered. I don't think they should be required
87 // out side this file so they are static functions like siod_utterance_p
88 // should be used elsewhere
89 static int tc_utt = -1;
90 static int tc_val = -1;
91 
92 class EST_Utterance *utterance(LISP x)
93 {
94  if (TYPEP(x,tc_utt))
95  return (class EST_Utterance *)USERVAL(x);
96  else
97  err("wrong type of argument to get_c_utt",x);
98 
99  return NULL; // err doesn't return but compilers don't know that
100 }
101 
102 int utterance_p(LISP x)
103 {
104  if (TYPEP(x,tc_utt))
105  return TRUE;
106  else
107  return FALSE;
108 }
109 
110 LISP siod(const class EST_Utterance *u)
111 {
112  LISP utt;
113  EST_String saddr;
114  LISP cell;
115 
116  void_to_addrname(u,saddr);
117 
118  if ((cell = estobjs.val(saddr)) != NIL)
119  return cell;
120 
121  // A new one
122  utt = siod_make_typed_cell(tc_utt,(void *)u);
123 
124  // Add to list
125  estobjs.add_item(saddr,utt);
126 
127  return utt;
128 }
129 
130 static void utt_free(LISP lutt)
131 {
132  class EST_Utterance *u = utterance(lutt);
133  EST_String saddr;
134 
135  void_to_addrname(u,saddr);
136 
137  // Mark it unused, this doesn't gc the extra data in the hash
138  // table to hold the index, this might be a problem over very
139  // long runs of the system (i.e. this should be fixed).
140  estobjs.remove_item(saddr);
141  delete u;
142 
143 
144  USERVAL(lutt) = NULL;
145 }
146 
147 LISP utt_mark(LISP utt)
148 {
149  // Should mark all the LISP cells in it
150  // but at present we use the gc_(un)protect mechanism
151  return utt;
152 }
153 
154 // EST_Vals (and everything else)
155 class EST_Val &val(LISP x)
156 {
157  if (TYPEP(x,tc_val))
158  return *((class EST_Val *)x->storage_as.val.v);
159 
160  else
161  err("wrong type of argument to get_c_val",x);
162  // sigh
163  static EST_Val def;
164 
165  return def;
166 }
167 
168 LISP val_equal(LISP a,LISP b)
169 {
170  if (val(a) == val(b))
171  return truth;
172  else
173  return NIL;
174 }
175 
176 int val_p(LISP x)
177 {
178  if (TYPEP(x,tc_val))
179  return TRUE;
180  else
181  return FALSE;
182 }
183 
184 LISP siod(const class EST_Val v)
185 {
186  return siod_make_typed_cell(tc_val,new EST_Val(v));
187 }
188 
189 static void val_free(LISP val)
190 {
191  class EST_Val *v = (EST_Val *)USERVAL(val);
192  delete v;
193  USERVAL(val) = NULL;
194 }
195 
196 static void val_prin1(LISP v, FILE *fd)
197 {
198  char b[1024];
199  fput_st(fd,"#<");
200  fput_st(fd,val(v).type());
201  sprintf(b," %p",val(v).internal_ptr());
202  fput_st(fd,b);
203  fput_st(fd,">");
204 }
205 
206 static void val_print_string(LISP v, char *tkbuffer)
207 {
208  sprintf(tkbuffer,"#<%s %p>",val(v).type(),val(v).internal_ptr());
209 }
210 
215 
216 // This is an example of something that's a little scary and it
217 // would be better if we didn't have to do this. Here we define
218 // support for LISP's as VAL, even though we've got VAL's a LISPs
219 // This allows arbitrary LISP objects to be held as VALs most
220 // likely as values in features or being returned by feature functions
221 // We have to do some special memory management to do this and
222 // you can probably mess things up completely if you start using this
223 // arbitrarily
225 struct obj_val {LISP l;};
226 LISP scheme(const EST_Val &v)
227 {
228  if (v.type() == val_type_scheme)
229  return ((obj_val *)v.internal_ptr())->l;
230  else
231  EST_error("val not of type val_type_scheme");
232  return NULL;
233 }
234 static void val_delete_scheme(void *v)
235 {
236  struct obj_val *ov = (struct obj_val *)v;
237  gc_unprotect(&ov->l);
238  wfree(ov);
239 }
240 
241 EST_Val est_val(const obj *v)
242 {
243  struct obj_val *ov = walloc(struct obj_val,1);
244  ov->l = (LISP)(void *)v;
245  gc_protect(&ov->l);
246  return EST_Val(val_type_scheme,
247  (void *)ov,
248  val_delete_scheme);
249 }
250 
251 LISP lisp_val(const EST_Val &pv)
252 {
253  if (pv.type() == val_unset)
254  {
255  cerr << "EST_Val unset, can't build lisp value" << endl;
256  siod_error();
257  return NIL;
258  }
259  else if (pv.type() == val_int)
260  return flocons(pv.Int());
261  else if (pv.type() == val_float)
262  return flocons(pv.Float());
263  else if (pv.type() == val_string)
264  return strintern(pv.string_only());
265  else if (pv.type() == val_type_scheme)
266  return scheme(pv);
267  else if (pv.type() == val_type_feats)
268  return features_to_lisp(*feats(pv));
269  else
270  return siod(pv);
271 }
272 
273 static int feature_like(LISP v)
274 {
275  // True if non nil and assoc like
276  if ((v == NIL) || (!consp(v)))
277  return FALSE;
278  else
279  {
280  LISP p;
281  for (p=v; p != NIL; p=cdr(p))
282  {
283  if (!consp(p) || (!consp(car(p))) || (consp(car(car(p)))))
284  return FALSE;
285  }
286  return TRUE;
287  }
288 }
289 
291 {
292  if (feature_like(v))
293  {
294  EST_Features *f = new EST_Features;
295  lisp_to_features(v,*f);
296  return est_val(f);
297  }
298  else if (FLONUMP(v))
299  return EST_Val(get_c_float(v));
300  else if (TYPEP(v,tc_val))
301  return val(v);
302  else if (TYPEP(v,tc_symbol) || (TYPEP(v,tc_string)))
303  return EST_Val(EST_String(get_c_string(v)));
304  else
305  return est_val(v);
306 }
307 
309 {
310  LISP l = NIL;
311 
313 
314  for(p.begin(kvl); p; ++p)
315  {
316  l=cons(cons(rintern(p->k),
317  cons(lisp_val(p->v),NIL)),
318  l);
319  }
320  // reverse it to make it the same order as f, though that shouldn't matter
321  return reverse(l);
322 }
323 
325 {
326  LISP p;
327 
328  for (p=l; p; p = cdr(p))
329  kvl.add_item(get_c_string(car(car(p))),
330  get_c_string(car(cdr(car(p)))));
331 }
332 
334 {
335  LISP lf = NIL;
336 
338 
339  for(p.begin(f); p; ++p)
340  {
341  lf=cons(cons(rintern(p->k),
342  cons(lisp_val(p->v),NIL)),
343  lf);
344  }
345  // reverse it to make it the same order as f, though that shouldn't matter
346  return reverse(lf);
347 }
348 
350 {
351  LISP p;
352 
353  for (p=lf; p; p = cdr(p))
354  f.set_val(get_c_string(car(car(p))),
355  val_lisp(car(cdr(car(p)))));
356 }
357 
358 static LISP feats_set(LISP lfeats, LISP fname, LISP val)
359 {
360  // Probably should restrict what can be in fname, not : would be good
361  LISP lf = lfeats;
362  if (lfeats == NIL)
363  {
364  EST_Features *f = new EST_Features;
365  lf = siod(f);
366  }
367  feats(lf)->set_path(get_c_string(fname),val_lisp(val));
368  return lf;
369 }
370 
371 static LISP feats_get(LISP f, LISP fname)
372 {
373  return lisp_val(feats(f)->val_path(get_c_string(fname)));
374 }
375 
376 static LISP feats_make()
377 {
378  EST_Features *f = new EST_Features;
379  return siod(f);
380 }
381 
382 static LISP feats_tolisp(LISP lf)
383 {
384  return features_to_lisp(*feats(lf));
385 }
386 
387 static LISP feats_remove(LISP lf, LISP fname)
388 {
389  EST_Features *f = feats(lf);
390  f->remove(get_c_string(fname));
391  return lf;
392 }
393 
394 static LISP feats_present(LISP lf, LISP fname)
395 {
396  EST_Features *f = feats(lf);
397  if (f->present(get_c_string(fname)))
398  return truth;
399  else
400  return NIL;
401 }
402 
404 {
405  EST_Features *f = feats(siod_get_lval("Param","No Param features set"));
406  return *f;
407 }
408 
410 {
411  // add EST specific objects as user types to LISP obj
412  long kind;
413 
414  // In general to add a type
415  // tc_TYPENAME = siod_register_user_type("TYPENAME");
416  // define above
417  // EST_TYPENAME *get_c_TYPENAME(LISP x) and
418  // int siod_TYPENAME_p(LISP x)
419  // LISP siod_make_utt(EST_TYPENAME *x)
420  // you will often also need to define
421  // TYPENAME_free(LISP x) too if you want the contents gc'd
422  // other options to the set_*_hooks functions allow you to customize
423  // the object's behaviour more
424 
425  tc_utt = siod_register_user_type("Utterance");
426  set_gc_hooks(tc_utt, 0, NULL,utt_mark,NULL,utt_free,NULL,&kind);
427 
428  tc_val = siod_register_user_type("Val");
429  set_gc_hooks(tc_val, 0, NULL,NULL,NULL,val_free,NULL,&kind);
430  set_print_hooks(tc_val,val_prin1,val_print_string);
431  set_type_hooks(tc_val,NULL,val_equal);
432 
433  init_subr_2("feats.get",feats_get,
434  "(feats.get FEATS FEATNAME)\n\
435  Return value of FEATNAME (which may be a simple feature name or a\n\
436  pathname) in FEATS. If FEATS is nil a new feature set is created");
437  init_subr_3("feats.set",feats_set,
438  "(feats.set FEATS FEATNAME VALUE)\n\
439  Set FEATNAME to VALUE in FEATS.");
440  init_subr_2("feats.remove",feats_remove,
441  "(feats.remove FEATS FEATNAME)\n\
442  Remove feature names FEATNAME from FEATS.");
443  init_subr_2("feats.present",feats_present,
444  "(feats.present FEATS FEATNAME)\n\
445  Return t is FEATNAME is present in FEATS, nil otherwise.");
446  init_subr_0("feats.make",feats_make,
447  "(feats.make)\n\
448  Return an new empty features object.");
449  init_subr_1("feats.tolisp",feats_tolisp,
450  "(feats.tolisp FEATS)\n\
451  Gives a lisp representation of the features, this is a debug function\n\
452  and may or may not exist tomorrow.");
453 
454 }
455 
A class for storing digital waveforms. The waveform is stored as an array of 16 bit shorts...
Definition: EST_Wave.h:64
Definition: siod_defs.h:32
void lisp_to_features(LISP lf, EST_Features &f)
Definition: siod_est.cc:349
int Int(void) const
Definition: EST_Val.h:141
int val_p(LISP x)
Definition: siod_est.cc:176
LISP siod_make_typed_cell(long type, void *s)
Definition: slib.cc:1953
#define walloc(TYPE, SIZE)
Definition: EST_walloc.h:52
#define Instantiate_TStringHash(VAL)
#define SIOD_REGISTER_CLASS(NAME, CLASS)
Definition: siod_defs.h:207
float get_c_float(LISP x)
Definition: slib.cc:1858
#define tc_symbol
Definition: siod_defs.h:106
#define siod_error()
Definition: siod.h:211
LISP val_equal(LISP a, LISP b)
Definition: siod_est.cc:168
EST_Features & Param()
Definition: siod_est.cc:403
void set_val(const EST_String &name, const EST_Val &sval)
Definition: EST_Features.h:217
LISP siod_get_lval(const char *name, const char *message)
Definition: siod.cc:94
val_type val_string
Definition: EST_Val.cc:46
#define NIL
Definition: siod_defs.h:92
LISP strintern(const char *data)
Definition: slib_str.cc:22
void siod_est_init()
Definition: siod_est.cc:409
int utterance_p(LISP x)
Definition: siod_est.cc:102
const char * val_type
Definition: EST_Val.h:57
void init_subr_2(const char *name, LISP(*fcn)(LISP, LISP), const char *doc)
Definition: slib.cc:900
void gc_unprotect(LISP *location)
Definition: slib.cc:759
A specialised hash table for when the key is an EST_String.
Definition: EST_THash.h:304
class EST_Utterance * utterance(LISP x)
Definition: siod_est.cc:92
void set_print_hooks(long type, void(*prin1)(LISP, FILE *), void(*print_string)(LISP, char *))
Definition: slib.cc:1486
val_type val_float
Definition: EST_Val.cc:45
LISP utt_mark(LISP utt)
Definition: siod_est.cc:147
LISP lisp_val(const EST_Val &pv)
Definition: siod_est.cc:251
void err(const char *message, LISP x) EST_NORETURN
Definition: slib.cc:608
int siod_register_user_type(const char *name)
Definition: slib.cc:925
const char * get_c_string(LISP x)
Definition: slib.cc:638
val_type val_type_scheme
Definition: siod_est.cc:224
LISP scheme(const EST_Val &v)
Definition: siod_est.cc:226
Declare_TStringHash_Base(LISP,(LISP) 0, NIL) using namespace std
LISP cons(LISP x, LISP y)
Definition: slib_list.cc:97
void fput_st(FILE *f, const char *st)
Definition: slib.cc:450
EST_Val val_lisp(LISP v)
Definition: siod_est.cc:290
val_type type(void) const
Definition: EST_Val.h:137
#define FLONUMP(x)
Definition: siod_defs.h:154
#define FALSE
Definition: EST_bool.h:119
void remove(const EST_String &name)
Definition: EST_Features.h:247
NULL
Definition: EST_WFST.cc:55
const void * internal_ptr(void) const
Definition: EST_Val.h:174
LISP consp(LISP x)
Definition: slib_list.cc:112
int present(const EST_String &name) const
#define EST_error
Definition: EST_error.h:104
f
Definition: EST_item_aux.cc:48
void init_subr_1(const char *name, LISP(*fcn)(LISP), const char *doc)
Definition: slib.cc:898
#define TYPEP(x, y)
Definition: siod_defs.h:100
int add_item(const K &rkey, const V &rval, int no_search=0)
add key-val pair to list
Definition: EST_TKVL.cc:248
#define tc_string
Definition: siod_defs.h:116
const EST_String & string_only(void) const
Definition: EST_Val.h:169
class EST_Val & val(LISP x)
Definition: siod_est.cc:155
void init_subr_3(const char *name, LISP(*fcn)(LISP, LISP, LISP), const char *doc)
Definition: slib.cc:902
val_type val_int
Definition: EST_Val.cc:44
EST_Val()
Definition: EST_Val.h:93
LISP siod(const class EST_Utterance *u)
Definition: siod_est.cc:110
LISP rintern(const char *name)
Definition: slib.cc:734
void begin(const Container &over)
Set the iterator ready to run over this container.
char * tkbuffer
Definition: slib.cc:122
void init_subr_0(const char *name, LISP(*fcn)(void), const char *doc)
Definition: slib.cc:896
LISP flocons(double x)
Definition: slib.cc:673
EST_Val est_val(const obj *v)
Definition: siod_est.cc:241
void gc_protect(LISP *location)
Definition: slib.cc:791
LISP features_to_lisp(EST_Features &f)
Definition: siod_est.cc:333
LISP car(LISP x)
Definition: slib_list.cc:115
#define USERVAL(x)
Definition: siod_defs.h:89
LISP kvlss_to_lisp(const EST_TKVL< EST_String, EST_String > &kvl)
Definition: siod_est.cc:308
LISP truth
Definition: slib.cc:135
EST_String
void wfree(void *p)
Definition: walloc.c:131
val_type val_unset
Definition: EST_Val.cc:43
#define TRUE
Definition: EST_bool.h:118
void set_gc_hooks(long type, int gc_free_once, LISP(*rel)(LISP), LISP(*mark)(LISP), void(*scan)(LISP), void(*free)(LISP), void(*clear)(LISP), long *kind)
Definition: slib.cc:946
void reverse(EST_Wave &sig)
LISP cdr(LISP x)
Definition: slib_list.cc:124
void lisp_to_kvlss(LISP l, EST_TKVL< EST_String, EST_String > &kvl)
Definition: siod_est.cc:324
float Float(void) const
Definition: EST_Val.h:149
void set_type_hooks(long type, long(*c_sxhash)(LISP, long), LISP(*equal)(LISP, LISP))
Definition: slib.cc:1506