56 for (r = 0; r < n_ci; r++) {
61 for (r = 0; r < n_ci; r++) {
64 for (tmp_r = 0; tmp_r < r && com_tab[tmp_r] !=
BAD_S3SSID; tmp_r++) {
65 if (uncomp_tab[r] == com_tab[tmp_r]) {
73 com_tab[tmp_r] = uncomp_tab[r];
94 tmpssid = ckd_calloc(n_ci,
sizeof(s3ssid_t));
95 tmpcimap = ckd_calloc(n_ci,
sizeof(
s3cipid_t));
101 for (b = 0; b < n_ci; b++) {
106 for (l = 0; l < n_ci; l++) {
107 rmap = rdiph_rc[b][l];
114 d2p->
rssid[b][l].
ssid = ckd_calloc(r,
sizeof(s3ssid_t));
116 r *
sizeof(s3ssid_t));
131 E_INFO(
"Allocated %d bytes (%d KiB) for word-final triphones\n",
132 (
int)alloc, (
int)alloc / 1024);
138 compress_left_right_context_tree(
dict2pid_t * d2p)
150 tmpssid = ckd_calloc(n_ci,
sizeof(s3ssid_t));
151 tmpcimap = ckd_calloc(n_ci,
sizeof(
s3cipid_t));
159 for (b = 0; b < n_ci; b++) {
165 for (l = 0; l < n_ci; l++) {
174 d2p->
lrssid[b][l].
ssid = ckd_calloc(r,
sizeof(s3ssid_t));
176 r *
sizeof(s3ssid_t));
195 E_INFO(
"Allocated %d bytes (%d KiB) for single-phone word triphones\n",
196 (
int)alloc, (
int)alloc / 1024);
253 free_compress_map(
xwdssid_t ** tree, int32 n_ci)
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);
272 for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
273 for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
275 p = bin_mdef_phone_id_nearest(mdef, (
s3cipid_t) b,
280 = bin_mdef_pid2ssid(mdef, p);
281 if (r == bin_mdef_silphone(mdef))
283 = bin_mdef_pid2ssid(mdef, p);
284 if (rdiph_rc && l == bin_mdef_silphone(mdef))
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",
292 p, bin_mdef_pid2ssid(mdef, p)));
304 if (dict_pronlen(d, wid) > 1) {
308 if (d2p->
ldiph_lc[dict_first_phone(d, wid)][dict_second_phone(d, wid)][0]
310 E_DEBUG(2, (
"Filling in left-context diphones for %s(?,%s)\n",
313 for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
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);
323 if (d2p->
rssid[dict_last_phone(d, wid)][dict_second_last_phone(d, wid)].n_ssid
330 E_DEBUG(2, (
"Filling in right-context diphones for %s(%s,?)\n",
333 rmap = ckd_calloc(bin_mdef_n_ciphone(mdef),
sizeof(*rmap));
334 for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
336 = bin_mdef_phone_id_nearest(mdef,
337 dict_last_phone(d, wid),
338 dict_second_last_phone(d, wid), r,
340 rmap[r] = bin_mdef_pid2ssid(mdef, p);
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));
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;
356 E_INFO(
"Filling in context triphones for %s(?,?)\n",
359 populate_lrdiph(d2p, NULL, dict_first_phone(d, wid));
375 if (pos == 0 || pos == dict_pronlen(dict, wid))
381 p = bin_mdef_phone_id_nearest(mdef, (
s3cipid_t) b,
384 return bin_mdef_pid2ssid(mdef, p);
391 s3ssid_t ***rdiph_rc;
392 bitvec_t *ldiph, *rdiph, *single;
396 E_INFO(
"Building PID tables for dictionary\n");
401 dict2pid->refcount = 1;
404 E_INFO(
"Allocating %d^3 * %d bytes (%d KiB) for word-initial triphones\n",
438 pronlen = dict_pronlen(dict, w);
441 b = dict_first_phone(dict, w);
442 r = dict_second_phone(dict, w);
444 if (bitvec_is_clear(ldiph, b * mdef->
n_ciphone + r)) {
446 bitvec_set(ldiph, b * mdef->
n_ciphone + r);
449 for (l = 0; l < bin_mdef_n_ciphone(mdef); l++) {
450 p = bin_mdef_phone_id_nearest(mdef, (
s3cipid_t) b,
453 dict2pid->
ldiph_lc[b][r][l] = bin_mdef_pid2ssid(mdef, p);
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)) {
463 bitvec_set(rdiph, b * mdef->
n_ciphone + l);
465 for (r = 0; r < bin_mdef_n_ciphone(mdef); r++) {
466 p = bin_mdef_phone_id_nearest(mdef, (
s3cipid_t) b,
469 rdiph_rc[b][l][r] = bin_mdef_pid2ssid(mdef, p);
473 else if (pronlen == 1) {
475 E_DEBUG(1,(
"Building tables for single phone word %s phone %d = %s\n",
478 if (bitvec_is_clear(single, b)) {
479 populate_lrdiph(dict2pid, rdiph_rc, b);
480 bitvec_set(single, b);
490 compress_right_context_tree(dict2pid, rdiph_rc);
491 compress_left_right_context_tree(dict2pid);
493 ckd_free_3d(rdiph_rc);
511 if (--d2p->refcount > 0)
512 return d2p->refcount;
515 ckd_free_3d((
void ***) d2p->
ldiph_lc);
521 free_compress_map(d2p->
rssid, bin_mdef_n_ciphone(d2p->
mdef));
524 free_compress_map(d2p->
lrssid, bin_mdef_n_ciphone(d2p->
mdef));
545 fprintf(fp,
"# INTERNAL (wd comssid ssid ssid ... ssid comssid)\n");
547 fprintf(fp,
"%30s ", dict_wordstr(dict, w));
549 pronlen = dict_pronlen(dict, w);
550 for (p = 0; p < pronlen; p++)
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]))
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]);
575 fprintf(fp,
"# END\n");
Building triphones for a dictionary.
void compress_table(s3ssid_t *uncomp_tab, s3ssid_t *com_tab, s3cipid_t *ci_map, int32 n_ci)
const char * bin_mdef_ciphone_str(bin_mdef_t *m, int32 ci)
In: ciphone id for which name wanted.
int dict_free(dict_t *d)
Release a pointer to a dictionary.
uint16 ** sseq
Unique senone sequences (2D array built at load time)
s3ssid_t *** ldiph_lc
For multi-phone words, [base][rc][lc] -> ssid; filled out for word-initial base x rc combinations in ...
int32 n_ssid
#Unique ssid in above, compressed ssid list
xwdssid_t ** rssid
Right context state sequence id table First dimension: base phone, Second dimension: left context...
void dict2pid_report(dict2pid_t *d2p)
Report a dict2pid data structure.
int dict2pid_free(dict2pid_t *d2p)
Free the memory dict2pid structure.
#define BAD_S3CIPID
Ci phone id.
Implementation of HMM base structure.
dict_t * dict_retain(dict_t *d)
Retain a pointer to an dict_t.
#define BAD_S3SSID
Senone sequence id (triphone or ciphone)
int32 n_sseq
Number of unique senone sequences.
int16 s3cipid_t
Size definitions for more semantially meaningful units.
bin_mdef_t * mdef
Model definition, used to generate internal ssids on the fly.
int dict2pid_add_word(dict2pid_t *d2p, int32 wid)
Add a word to the dict2pid structure (after adding it to dict).
s3ssid_t *** lrdiph_rc
For single-phone words, [base][lc][rc] -> ssid; filled out for single-phone base x lc combinations in...
dict_t * dict
Dictionary this table refers to.
a structure for a dictionary.
void dict2pid_dump(FILE *fp, dict2pid_t *d2p)
For debugging.
s3ssid_t dict2pid_internal(dict2pid_t *d2p, int32 wid, int pos)
Return the senone sequence ID for the given word position.
cross word triphone model structure
dict2pid_t * dict2pid_retain(dict2pid_t *d2p)
Retain a pointer to dict2pid.
xwdssid_t ** lrssid
Left-Right context state sequence id table First dimension: base phone, Second dimension: left contex...
int bin_mdef_free(bin_mdef_t *m)
Release a pointer to a binary mdef.
s3cipid_t * dict2pid_get_rcmap(dict2pid_t *d2p, s3wid_t w)
Get RC map.
s3cipid_t * ciphone
Pronunciation.
bin_mdef_t * bin_mdef_retain(bin_mdef_t *m)
Retain a pointer to a bin_mdef_t.
dictword_t * word
Array of entries in dictionary.
int32 get_rc_nssid(dict2pid_t *d2p, s3wid_t w)
ARCHAN, A duplicate of get_rc_npid in ctxt_table.h.
dict2pid_t * dict2pid_build(bin_mdef_t *mdef, dict_t *dict)
Build the dict2pid structure for the given model/dictionary.
int32 pronlen
Pronunciation length.
int32 n_ciphone
Number of base (CI) phones.
#define dict_size(d)
Packaged macro access to dictionary members.
s3cipid_t * cimap
Index into ssid[] above for each ci phone.
#define dict_pron(d, w, p)
The CI phones of the word w at position p.
Building composite triphone (as well as word internal triphones) with the dictionary.
s3ssid_t * ssid
Senone Sequence ID list for all context ciphones.