PocketSphinx  5prealpha
dict2pid.c
Go to the documentation of this file.
1 /* -*- c-basic-offset:4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2004 Carnegie Mellon University. All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced
19  * Research Projects Agency and the National Science Foundation of the
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 
38 #include <string.h>
39 
40 #include "dict2pid.h"
41 #include "hmm.h"
42 
43 
48 void
49 compress_table(s3ssid_t * uncomp_tab, s3ssid_t * com_tab,
50  s3cipid_t * ci_map, int32 n_ci)
51 {
52  int32 found;
53  int32 r;
54  int32 tmp_r;
55 
56  for (r = 0; r < n_ci; r++) {
57  com_tab[r] = BAD_S3SSID;
58  ci_map[r] = BAD_S3CIPID;
59  }
61  for (r = 0; r < n_ci; r++) {
62 
63  found = 0;
64  for (tmp_r = 0; tmp_r < r && com_tab[tmp_r] != BAD_S3SSID; tmp_r++) { /* If it appears before, just filled in cimap; */
65  if (uncomp_tab[r] == com_tab[tmp_r]) {
66  found = 1;
67  ci_map[r] = tmp_r;
68  break;
69  }
70  }
71 
72  if (found == 0) {
73  com_tab[tmp_r] = uncomp_tab[r];
74  ci_map[r] = tmp_r;
75  }
76  }
77 }
78 
79 
80 static void
81 compress_right_context_tree(dict2pid_t * d2p,
82  s3ssid_t ***rdiph_rc)
83 {
84  int32 n_ci;
85  int32 b, l, r;
86  s3ssid_t *rmap;
87  s3ssid_t *tmpssid;
88  s3cipid_t *tmpcimap;
89  bin_mdef_t *mdef = d2p->mdef;
90  size_t alloc;
91 
92  n_ci = mdef->n_ciphone;
93 
94  tmpssid = ckd_calloc(n_ci, sizeof(s3ssid_t));
95  tmpcimap = ckd_calloc(n_ci, sizeof(s3cipid_t));
96 
97  d2p->rssid =
98  (xwdssid_t **) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t *));
99  alloc = mdef->n_ciphone * sizeof(xwdssid_t *);
100 
101  for (b = 0; b < n_ci; b++) {
102  d2p->rssid[b] =
103  (xwdssid_t *) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t));
104  alloc += mdef->n_ciphone * sizeof(xwdssid_t);
105 
106  for (l = 0; l < n_ci; l++) {
107  rmap = rdiph_rc[b][l];
108  compress_table(rmap, tmpssid, tmpcimap, mdef->n_ciphone);
109 
110  for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID;
111  r++);
112 
113  if (tmpssid[0] != BAD_S3SSID) {
114  d2p->rssid[b][l].ssid = ckd_calloc(r, sizeof(s3ssid_t));
115  memcpy(d2p->rssid[b][l].ssid, tmpssid,
116  r * sizeof(s3ssid_t));
117  d2p->rssid[b][l].cimap =
118  ckd_calloc(mdef->n_ciphone, sizeof(s3cipid_t));
119  memcpy(d2p->rssid[b][l].cimap, tmpcimap,
120  (mdef->n_ciphone) * sizeof(s3cipid_t));
121  d2p->rssid[b][l].n_ssid = r;
122  }
123  else {
124  d2p->rssid[b][l].ssid = NULL;
125  d2p->rssid[b][l].cimap = NULL;
126  d2p->rssid[b][l].n_ssid = 0;
127  }
128  }
129  }
130 
131  E_INFO("Allocated %d bytes (%d KiB) for word-final triphones\n",
132  (int)alloc, (int)alloc / 1024);
133  ckd_free(tmpssid);
134  ckd_free(tmpcimap);
135 }
136 
137 static void
138 compress_left_right_context_tree(dict2pid_t * d2p)
139 {
140  int32 n_ci;
141  int32 b, l, r;
142  s3ssid_t *rmap;
143  s3ssid_t *tmpssid;
144  s3cipid_t *tmpcimap;
145  bin_mdef_t *mdef = d2p->mdef;
146  size_t alloc;
147 
148  n_ci = mdef->n_ciphone;
149 
150  tmpssid = ckd_calloc(n_ci, sizeof(s3ssid_t));
151  tmpcimap = ckd_calloc(n_ci, sizeof(s3cipid_t));
152 
153  assert(d2p->lrdiph_rc);
154 
155  d2p->lrssid =
156  (xwdssid_t **) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t *));
157  alloc = mdef->n_ciphone * sizeof(xwdssid_t *);
158 
159  for (b = 0; b < n_ci; b++) {
160 
161  d2p->lrssid[b] =
162  (xwdssid_t *) ckd_calloc(mdef->n_ciphone, sizeof(xwdssid_t));
163  alloc += mdef->n_ciphone * sizeof(xwdssid_t);
164 
165  for (l = 0; l < n_ci; l++) {
166  rmap = d2p->lrdiph_rc[b][l];
167 
168  compress_table(rmap, tmpssid, tmpcimap, mdef->n_ciphone);
169 
170  for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID;
171  r++);
172 
173  if (tmpssid[0] != BAD_S3SSID) {
174  d2p->lrssid[b][l].ssid = ckd_calloc(r, sizeof(s3ssid_t));
175  memcpy(d2p->lrssid[b][l].ssid, tmpssid,
176  r * sizeof(s3ssid_t));
177  d2p->lrssid[b][l].cimap =
178  ckd_calloc(mdef->n_ciphone, sizeof(s3cipid_t));
179  memcpy(d2p->lrssid[b][l].cimap, tmpcimap,
180  (mdef->n_ciphone) * sizeof(s3cipid_t));
181  d2p->lrssid[b][l].n_ssid = r;
182  }
183  else {
184  d2p->lrssid[b][l].ssid = NULL;
185  d2p->lrssid[b][l].cimap = NULL;
186  d2p->lrssid[b][l].n_ssid = 0;
187  }
188  }
189  }
190 
191  /* Try to compress lrdiph_rc into lrdiph_rc_compressed */
192  ckd_free(tmpssid);
193  ckd_free(tmpcimap);
194 
195  E_INFO("Allocated %d bytes (%d KiB) for single-phone word triphones\n",
196  (int)alloc, (int)alloc / 1024);
197 }
198 
203 int32
204 get_rc_nssid(dict2pid_t * d2p, s3wid_t w)
205 {
206  int32 pronlen;
207  s3cipid_t b, lc;
208  dict_t *dict = d2p->dict;
209 
210  pronlen = dict->word[w].pronlen;
211  b = dict->word[w].ciphone[pronlen - 1];
212 
213  if (pronlen == 1) {
214  /* Is this true ?
215  No known left context. But all cimaps (for any l) are identical; pick one
216  */
217  /*E_INFO("Single phone word\n"); */
218  return (d2p->lrssid[b][0].n_ssid);
219  }
220  else {
221  /* E_INFO("Multiple phone word\n"); */
222  lc = dict->word[w].ciphone[pronlen - 2];
223  return (d2p->rssid[b][lc].n_ssid);
224  }
225 
226 }
227 
228 s3cipid_t *
230 {
231  int32 pronlen;
232  s3cipid_t b, lc;
233  dict_t *dict = d2p->dict;
234 
235  pronlen = dict->word[w].pronlen;
236  b = dict->word[w].ciphone[pronlen - 1];
237 
238  if (pronlen == 1) {
239  /* Is this true ?
240  No known left context. But all cimaps (for any l) are identical; pick one
241  */
242  /*E_INFO("Single phone word\n"); */
243  return (d2p->lrssid[b][0].cimap);
244  }
245  else {
246  /* E_INFO("Multiple phone word\n"); */
247  lc = dict->word[w].ciphone[pronlen - 2];
248  return (d2p->rssid[b][lc].cimap);
249  }
250 }
251 
252 static void
253 free_compress_map(xwdssid_t ** tree, int32 n_ci)
254 {
255  int32 b, l;
256  for (b = 0; b < n_ci; b++) {
257  for (l = 0; l < n_ci; l++) {
258  ckd_free(tree[b][l].ssid);
259  ckd_free(tree[b][l].cimap);
260  }
261  ckd_free(tree[b]);
262  }
263  ckd_free(tree);
264 }
265 
266 static void
267 populate_lrdiph(dict2pid_t *d2p, s3ssid_t ***rdiph_rc, s3cipid_t b)
268 {
269  bin_mdef_t *mdef = d2p->mdef;
270  s3cipid_t l, r;
271 
272  for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
273  for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
274  s3pid_t p;
275  p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
276  (s3cipid_t) l,
277  (s3cipid_t) r,
279  d2p->lrdiph_rc[b][l][r]
280  = bin_mdef_pid2ssid(mdef, p);
281  if (r == bin_mdef_silphone(mdef))
282  d2p->ldiph_lc[b][r][l]
283  = bin_mdef_pid2ssid(mdef, p);
284  if (rdiph_rc && l == bin_mdef_silphone(mdef))
285  rdiph_rc[b][l][r]
286  = bin_mdef_pid2ssid(mdef, p);
287  assert(IS_S3SSID(bin_mdef_pid2ssid(mdef, p)));
288  E_DEBUG(2,("%s(%s,%s) => %d / %d\n",
289  bin_mdef_ciphone_str(mdef, b),
290  bin_mdef_ciphone_str(mdef, l),
291  bin_mdef_ciphone_str(mdef, r),
292  p, bin_mdef_pid2ssid(mdef, p)));
293  }
294  }
295 }
296 
297 int
299  int32 wid)
300 {
301  bin_mdef_t *mdef = d2p->mdef;
302  dict_t *d = d2p->dict;
303 
304  if (dict_pronlen(d, wid) > 1) {
305  s3cipid_t l;
306  /* Make sure we have left and right context diphones for this
307  * word. */
308  if (d2p->ldiph_lc[dict_first_phone(d, wid)][dict_second_phone(d, wid)][0]
309  == BAD_S3SSID) {
310  E_DEBUG(2, ("Filling in left-context diphones for %s(?,%s)\n",
311  bin_mdef_ciphone_str(mdef, dict_first_phone(d, wid)),
312  bin_mdef_ciphone_str(mdef, dict_second_phone(d, wid))));
313  for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
314  int p
315  = bin_mdef_phone_id_nearest(mdef,
316  dict_first_phone(d, wid), l,
317  dict_second_phone(d, wid),
319  d2p->ldiph_lc[dict_first_phone(d, wid)][dict_second_phone(d, wid)][l]
320  = bin_mdef_pid2ssid(mdef, p);
321  }
322  }
323  if (d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].n_ssid
324  == 0) {
325  s3ssid_t *rmap;
326  s3ssid_t *tmpssid;
327  s3cipid_t *tmpcimap;
328  s3cipid_t r;
329 
330  E_DEBUG(2, ("Filling in right-context diphones for %s(%s,?)\n",
331  bin_mdef_ciphone_str(mdef, dict_last_phone(d, wid)),
332  bin_mdef_ciphone_str(mdef, dict_second_last_phone(d, wid))));
333  rmap = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*rmap));
334  for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
335  int p
336  = bin_mdef_phone_id_nearest(mdef,
337  dict_last_phone(d, wid),
338  dict_second_last_phone(d, wid), r,
339  WORD_POSN_END);
340  rmap[r] = bin_mdef_pid2ssid(mdef, p);
341  }
342  tmpssid = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*tmpssid));
343  tmpcimap = ckd_calloc(bin_mdef_n_ciphone(mdef), sizeof(*tmpcimap));
344  compress_table(rmap, tmpssid, tmpcimap, bin_mdef_n_ciphone(mdef));
345  for (r = 0; r < mdef->n_ciphone && tmpssid[r] != BAD_S3SSID; r++)
346  ;
347  d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].ssid = tmpssid;
348  d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].cimap = tmpcimap;
349  d2p->rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].n_ssid = r;
350  ckd_free(rmap);
351  }
352  }
353  else {
354  /* Make sure we have a left-right context triphone entry for
355  * this word. */
356  E_INFO("Filling in context triphones for %s(?,?)\n",
357  bin_mdef_ciphone_str(mdef, dict_first_phone(d, wid)));
358  if (d2p->lrdiph_rc[dict_first_phone(d, wid)][0][0] == BAD_S3SSID) {
359  populate_lrdiph(d2p, NULL, dict_first_phone(d, wid));
360  }
361  }
362 
363  return 0;
364 }
365 
366 s3ssid_t
368  int32 wid,
369  int pos)
370 {
371  int b, l, r, p;
372  dict_t *dict = d2p->dict;
373  bin_mdef_t *mdef = d2p->mdef;
374 
375  if (pos == 0 || pos == dict_pronlen(dict, wid))
376  return BAD_S3SSID;
377 
378  b = dict_pron(dict, wid, pos);
379  l = dict_pron(dict, wid, pos - 1);
380  r = dict_pron(dict, wid, pos + 1);
381  p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
382  (s3cipid_t) l, (s3cipid_t) r,
384  return bin_mdef_pid2ssid(mdef, p);
385 }
386 
387 dict2pid_t *
389 {
390  dict2pid_t *dict2pid;
391  s3ssid_t ***rdiph_rc;
392  bitvec_t *ldiph, *rdiph, *single;
393  int32 pronlen;
394  int32 b, l, r, w, p;
395 
396  E_INFO("Building PID tables for dictionary\n");
397  assert(mdef);
398  assert(dict);
399 
400  dict2pid = (dict2pid_t *) ckd_calloc(1, sizeof(dict2pid_t));
401  dict2pid->refcount = 1;
402  dict2pid->mdef = bin_mdef_retain(mdef);
403  dict2pid->dict = dict_retain(dict);
404  E_INFO("Allocating %d^3 * %d bytes (%d KiB) for word-initial triphones\n",
405  mdef->n_ciphone, sizeof(s3ssid_t),
406  mdef->n_ciphone * mdef->n_ciphone * mdef->n_ciphone * sizeof(s3ssid_t) / 1024);
407  dict2pid->ldiph_lc =
408  (s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone, mdef->n_ciphone,
409  mdef->n_ciphone, sizeof(s3ssid_t));
410  /* Only used internally to generate rssid */
411  rdiph_rc =
412  (s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone, mdef->n_ciphone,
413  mdef->n_ciphone, sizeof(s3ssid_t));
414 
415  dict2pid->lrdiph_rc = (s3ssid_t ***) ckd_calloc_3d(mdef->n_ciphone,
416  mdef->n_ciphone,
417  mdef->n_ciphone,
418  sizeof
419  (s3ssid_t));
420  /* Actually could use memset for this, if BAD_S3SSID is guaranteed
421  * to be 65535... */
422  for (b = 0; b < mdef->n_ciphone; ++b) {
423  for (r = 0; r < mdef->n_ciphone; ++r) {
424  for (l = 0; l < mdef->n_ciphone; ++l) {
425  dict2pid->ldiph_lc[b][r][l] = BAD_S3SSID;
426  dict2pid->lrdiph_rc[b][l][r] = BAD_S3SSID;
427  rdiph_rc[b][l][r] = BAD_S3SSID;
428  }
429  }
430  }
431 
432  /* Track which diphones / ciphones have been seen. */
433  ldiph = bitvec_alloc(mdef->n_ciphone * mdef->n_ciphone);
434  rdiph = bitvec_alloc(mdef->n_ciphone * mdef->n_ciphone);
435  single = bitvec_alloc(mdef->n_ciphone);
436 
437  for (w = 0; w < dict_size(dict2pid->dict); w++) {
438  pronlen = dict_pronlen(dict, w);
439 
440  if (pronlen >= 2) {
441  b = dict_first_phone(dict, w);
442  r = dict_second_phone(dict, w);
443  /* Populate ldiph_lc */
444  if (bitvec_is_clear(ldiph, b * mdef->n_ciphone + r)) {
445  /* Mark this diphone as done */
446  bitvec_set(ldiph, b * mdef->n_ciphone + r);
447 
448  /* Record all possible ssids for b(?,r) */
449  for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
450  p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
451  (s3cipid_t) l, (s3cipid_t) r,
453  dict2pid->ldiph_lc[b][r][l] = bin_mdef_pid2ssid(mdef, p);
454  }
455  }
456 
457 
458  /* Populate rdiph_rc */
459  l = dict_second_last_phone(dict, w);
460  b = dict_last_phone(dict, w);
461  if (bitvec_is_clear(rdiph, b * mdef->n_ciphone + l)) {
462  /* Mark this diphone as done */
463  bitvec_set(rdiph, b * mdef->n_ciphone + l);
464 
465  for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
466  p = bin_mdef_phone_id_nearest(mdef, (s3cipid_t) b,
467  (s3cipid_t) l, (s3cipid_t) r,
468  WORD_POSN_END);
469  rdiph_rc[b][l][r] = bin_mdef_pid2ssid(mdef, p);
470  }
471  }
472  }
473  else if (pronlen == 1) {
474  b = dict_pron(dict, w, 0);
475  E_DEBUG(1,("Building tables for single phone word %s phone %d = %s\n",
476  dict_wordstr(dict, w), b, bin_mdef_ciphone_str(mdef, b)));
477  /* Populate lrdiph_rc (and also ldiph_lc, rdiph_rc if needed) */
478  if (bitvec_is_clear(single, b)) {
479  populate_lrdiph(dict2pid, rdiph_rc, b);
480  bitvec_set(single, b);
481  }
482  }
483  }
484 
485  bitvec_free(ldiph);
486  bitvec_free(rdiph);
487  bitvec_free(single);
488 
489  /* Try to compress rdiph_rc into rdiph_rc_compressed */
490  compress_right_context_tree(dict2pid, rdiph_rc);
491  compress_left_right_context_tree(dict2pid);
492 
493  ckd_free_3d(rdiph_rc);
494 
495  dict2pid_report(dict2pid);
496  return dict2pid;
497 }
498 
499 dict2pid_t *
501 {
502  ++d2p->refcount;
503  return d2p;
504 }
505 
506 int
508 {
509  if (d2p == NULL)
510  return 0;
511  if (--d2p->refcount > 0)
512  return d2p->refcount;
513 
514  if (d2p->ldiph_lc)
515  ckd_free_3d((void ***) d2p->ldiph_lc);
516 
517  if (d2p->lrdiph_rc)
518  ckd_free_3d((void ***) d2p->lrdiph_rc);
519 
520  if (d2p->rssid)
521  free_compress_map(d2p->rssid, bin_mdef_n_ciphone(d2p->mdef));
522 
523  if (d2p->lrssid)
524  free_compress_map(d2p->lrssid, bin_mdef_n_ciphone(d2p->mdef));
525 
526  bin_mdef_free(d2p->mdef);
527  dict_free(d2p->dict);
528  ckd_free(d2p);
529  return 0;
530 }
531 
532 void
534 {
535 }
536 
537 void
538 dict2pid_dump(FILE * fp, dict2pid_t * d2p)
539 {
540  int32 w, p, pronlen;
541  int32 i, j, b, l, r;
542  bin_mdef_t *mdef = d2p->mdef;
543  dict_t *dict = d2p->dict;
544 
545  fprintf(fp, "# INTERNAL (wd comssid ssid ssid ... ssid comssid)\n");
546  for (w = 0; w < dict_size(dict); w++) {
547  fprintf(fp, "%30s ", dict_wordstr(dict, w));
548 
549  pronlen = dict_pronlen(dict, w);
550  for (p = 0; p < pronlen; p++)
551  fprintf(fp, " %5d", dict2pid_internal(d2p, w, p));
552  fprintf(fp, "\n");
553  }
554  fprintf(fp, "#\n");
555 
556  fprintf(fp, "# LDIPH_LC (b r l ssid)\n");
557  for (b = 0; b < bin_mdef_n_ciphone(mdef); b++) {
558  for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
559  for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
560  if (IS_S3SSID(d2p->ldiph_lc[b][r][l]))
561  fprintf(fp, "%6s %6s %6s %5d\n", bin_mdef_ciphone_str(mdef, (s3cipid_t) b), bin_mdef_ciphone_str(mdef, (s3cipid_t) r), bin_mdef_ciphone_str(mdef, (s3cipid_t) l), d2p->ldiph_lc[b][r][l]); /* RAH, ldiph_lc is returning an int32, %d expects an int16 */
562  }
563  }
564  }
565  fprintf(fp, "#\n");
566 
567  fprintf(fp, "# SSEQ %d (senid senid ...)\n", mdef->n_sseq);
568  for (i = 0; i < mdef->n_sseq; i++) {
569  fprintf(fp, "%5d ", i);
570  for (j = 0; j < bin_mdef_n_emit_state(mdef); j++)
571  fprintf(fp, " %5d", mdef->sseq[i][j]);
572  fprintf(fp, "\n");
573  }
574  fprintf(fp, "#\n");
575  fprintf(fp, "# END\n");
576 
577  fflush(fp);
578 }
Building triphones for a dictionary.
void compress_table(s3ssid_t *uncomp_tab, s3ssid_t *com_tab, s3cipid_t *ci_map, int32 n_ci)
Definition: dict2pid.c:49
const char * bin_mdef_ciphone_str(bin_mdef_t *m, int32 ci)
In: ciphone id for which name wanted.
Definition: bin_mdef.c:737
int dict_free(dict_t *d)
Release a pointer to a dictionary.
Definition: dict.c:468
Single phone word (i.e.
Definition: mdef.h:76
uint16 ** sseq
Unique senone sequences (2D array built at load time)
Definition: bin_mdef.h:134
s3ssid_t *** ldiph_lc
For multi-phone words, [base][rc][lc] -&gt; ssid; filled out for word-initial base x rc combinations in ...
Definition: dict2pid.h:95
int32 n_ssid
#Unique ssid in above, compressed ssid list
Definition: dict2pid.h:76
xwdssid_t ** rssid
Right context state sequence id table First dimension: base phone, Second dimension: left context...
Definition: dict2pid.h:99
Ending phone of word.
Definition: mdef.h:75
void dict2pid_report(dict2pid_t *d2p)
Report a dict2pid data structure.
Definition: dict2pid.c:533
int dict2pid_free(dict2pid_t *d2p)
Free the memory dict2pid structure.
Definition: dict2pid.c:507
#define BAD_S3CIPID
Ci phone id.
Definition: s3types.h:64
Implementation of HMM base structure.
dict_t * dict_retain(dict_t *d)
Retain a pointer to an dict_t.
Definition: dict.c:461
#define BAD_S3SSID
Senone sequence id (triphone or ciphone)
Definition: s3types.h:78
int32 n_sseq
Number of unique senone sequences.
Definition: bin_mdef.h:125
int16 s3cipid_t
Size definitions for more semantially meaningful units.
Definition: s3types.h:63
bin_mdef_t * mdef
Model definition, used to generate internal ssids on the fly.
Definition: dict2pid.h:87
int dict2pid_add_word(dict2pid_t *d2p, int32 wid)
Add a word to the dict2pid structure (after adding it to dict).
Definition: dict2pid.c:298
s3ssid_t *** lrdiph_rc
For single-phone words, [base][lc][rc] -&gt; ssid; filled out for single-phone base x lc combinations in...
Definition: dict2pid.h:105
dict_t * dict
Dictionary this table refers to.
Definition: dict2pid.h:89
a structure for a dictionary.
Definition: dict.h:76
void dict2pid_dump(FILE *fp, dict2pid_t *d2p)
For debugging.
Definition: dict2pid.c:538
s3ssid_t dict2pid_internal(dict2pid_t *d2p, int32 wid, int pos)
Return the senone sequence ID for the given word position.
Definition: dict2pid.c:367
cross word triphone model structure
Definition: dict2pid.h:73
dict2pid_t * dict2pid_retain(dict2pid_t *d2p)
Retain a pointer to dict2pid.
Definition: dict2pid.c:500
xwdssid_t ** lrssid
Left-Right context state sequence id table First dimension: base phone, Second dimension: left contex...
Definition: dict2pid.h:108
int bin_mdef_free(bin_mdef_t *m)
Release a pointer to a binary mdef.
Definition: bin_mdef.c:272
s3cipid_t * dict2pid_get_rcmap(dict2pid_t *d2p, s3wid_t w)
Get RC map.
Definition: dict2pid.c:229
s3cipid_t * ciphone
Pronunciation.
Definition: dict.h:65
bin_mdef_t * bin_mdef_retain(bin_mdef_t *m)
Retain a pointer to a bin_mdef_t.
Definition: bin_mdef.c:265
dictword_t * word
Array of entries in dictionary.
Definition: dict.h:79
int32 get_rc_nssid(dict2pid_t *d2p, s3wid_t w)
ARCHAN, A duplicate of get_rc_npid in ctxt_table.h.
Definition: dict2pid.c:204
Beginning phone of word.
Definition: mdef.h:74
dict2pid_t * dict2pid_build(bin_mdef_t *mdef, dict_t *dict)
Build the dict2pid structure for the given model/dictionary.
Definition: dict2pid.c:388
int32 pronlen
Pronunciation length.
Definition: dict.h:66
int32 n_ciphone
Number of base (CI) phones.
Definition: bin_mdef.h:119
#define dict_size(d)
Packaged macro access to dictionary members.
Definition: dict.h:151
s3cipid_t * cimap
Index into ssid[] above for each ci phone.
Definition: dict2pid.h:75
Internal phone of word.
Definition: mdef.h:73
#define dict_pron(d, w, p)
The CI phones of the word w at position p.
Definition: dict.h:165
Building composite triphone (as well as word internal triphones) with the dictionary.
Definition: dict2pid.h:84
s3ssid_t * ssid
Senone Sequence ID list for all context ciphones.
Definition: dict2pid.h:74