45 #include <sphinxbase/ckd_alloc.h> 64 ckd_free(al->word.seq);
65 ckd_free(al->sseq.seq);
66 ckd_free(al->state.seq);
71 #define VECTOR_GROW 10 73 vector_grow_one(
void *ptr, uint16 *n_alloc, uint16 *n,
size_t item_size)
76 if (newsize < *n_alloc) {
80 newsize += VECTOR_GROW;
83 ptr = ckd_realloc(ptr, newsize * item_size);
93 ptr = vector_grow_one(vec->seq, &vec->n_alloc,
94 &vec->n_ent,
sizeof(*vec->seq));
98 return vec->seq + vec->n_ent - 1;
109 int32 wid,
int duration)
113 if ((ent = ps_alignment_vector_grow_one(&al->word)) == NULL)
116 if (al->word.n_ent > 1)
117 ent->start = ent[-1].start + ent[-1].duration;
120 ent->duration = duration;
121 ent->parent = PS_ALIGNMENT_NONE;
122 ent->child = PS_ALIGNMENT_NONE;
124 return al->word.n_ent;
136 ps_alignment_vector_empty(&al->sseq);
137 ps_alignment_vector_empty(&al->state);
143 lc = bin_mdef_silphone(mdef);
144 for (i = 0; i < al->word.n_ent; ++i) {
147 int wid = went->id.wid;
148 int len = dict_pronlen(dict, wid);
151 if (i < al->word.n_ent - 1)
152 rc = dict_first_phone(dict, al->word.seq[i+1].id.wid);
154 rc = bin_mdef_silphone(mdef);
157 if ((sent = ps_alignment_vector_grow_one(&al->sseq)) == NULL) {
158 E_ERROR(
"Failed to add phone entry!\n");
161 sent->id.pid.cipid = dict_first_phone(dict, wid);
162 sent->id.pid.tmatid = bin_mdef_pid2tmatid(mdef, sent->id.pid.cipid);
163 sent->start = went->start;
164 sent->duration = went->duration;
166 went->child = (uint16)(sent - al->sseq.seq);
169 = dict2pid_lrdiph_rc(d2p, sent->id.pid.cipid, lc, rc);
172 = dict2pid_ldiph_lc(d2p, sent->id.pid.cipid,
173 dict_second_phone(dict, wid), lc);
174 assert(sent->id.pid.ssid !=
BAD_SSID);
177 for (j = 1; j < len - 1; ++j) {
178 if ((sent = ps_alignment_vector_grow_one(&al->sseq)) == NULL) {
179 E_ERROR(
"Failed to add phone entry!\n");
182 sent->id.pid.cipid =
dict_pron(dict, wid, j);
183 sent->id.pid.tmatid = bin_mdef_pid2tmatid(mdef, sent->id.pid.cipid);
185 assert(sent->id.pid.ssid !=
BAD_SSID);
186 sent->start = went->start;
187 sent->duration = went->duration;
194 assert(j == len - 1);
195 if ((sent = ps_alignment_vector_grow_one(&al->sseq)) == NULL) {
196 E_ERROR(
"Failed to add phone entry!\n");
199 sent->id.pid.cipid = dict_last_phone(dict, wid);
200 sent->id.pid.tmatid = bin_mdef_pid2tmatid(mdef, sent->id.pid.cipid);
202 dict_second_last_phone(dict, wid));
203 sent->id.pid.ssid = rssid->
ssid[rssid->
cimap[rc]];
204 assert(sent->id.pid.ssid !=
BAD_SSID);
205 sent->start = went->start;
206 sent->duration = went->duration;
211 lc = dict_last_phone(dict, wid);
217 for (i = 0; i < al->sseq.n_ent; ++i) {
222 for (j = 0; j < bin_mdef_n_emit_state(mdef); ++j) {
223 if ((sent = ps_alignment_vector_grow_one(&al->state)) == NULL) {
224 E_ERROR(
"Failed to add state entry!\n");
227 sent->id.senid = bin_mdef_sseq2sen(mdef, pent->id.pid.ssid, j);
229 sent->start = pent->start;
230 sent->duration = pent->duration;
233 pent->child = (uint16)(sent - al->state.seq);
250 ps_alignment_vector_empty(&al->sseq);
251 ps_alignment_vector_empty(&al->state);
257 for (i = 0; i < al->word.n_ent; ++i) {
260 int wid = went->id.wid;
261 int len = dict_pronlen(dict, wid);
264 for (j = 0; j < len; ++j) {
265 if ((sent = ps_alignment_vector_grow_one(&al->sseq)) == NULL) {
266 E_ERROR(
"Failed to add phone entry!\n");
269 sent->id.pid.cipid =
dict_pron(dict, wid, j);
270 sent->id.pid.tmatid = bin_mdef_pid2tmatid(mdef, sent->id.pid.cipid);
271 sent->id.pid.ssid = bin_mdef_pid2ssid(mdef, sent->id.pid.cipid);
272 assert(sent->id.pid.ssid !=
BAD_SSID);
273 sent->start = went->start;
274 sent->duration = went->duration;
282 for (i = 0; i < al->sseq.n_ent; ++i) {
287 for (j = 0; j < bin_mdef_n_emit_state(mdef); ++j) {
288 if ((sent = ps_alignment_vector_grow_one(&al->state)) == NULL) {
289 E_ERROR(
"Failed to add state entry!\n");
292 sent->id.senid = bin_mdef_sseq2sen(mdef, pent->id.pid.ssid, j);
294 sent->start = pent->start;
295 sent->duration = pent->duration;
298 pent->child = (uint16)(sent - al->state.seq);
312 for (i = 0; i < al->state.n_ent; ++i) {
315 if (pent != last_ent) {
316 pent->start = sent->start;
319 pent->duration += sent->duration;
325 for (i = 0; i < al->sseq.n_ent; ++i) {
328 if (went != last_ent) {
329 went->start = pent->start;
332 went->duration += pent->duration;
342 return (
int)al->word.n_ent;
348 return (
int)al->sseq.n_ent;
354 return (
int)al->state.n_ent;
362 if (al->word.n_ent == 0)
364 itor = ckd_calloc(1,
sizeof(*itor));
366 itor->vec = &al->word;
376 if (al->sseq.n_ent == 0)
378 itor = ckd_calloc(1,
sizeof(*itor));
380 itor->vec = &al->sseq;
390 if (al->state.n_ent == 0)
392 itor = ckd_calloc(1,
sizeof(*itor));
394 itor->vec = &al->state;
402 return itor->vec->seq + itor->pos;
417 if (pos >= itor->vec->n_ent) {
430 if (++itor->pos >= itor->vec->n_ent) {
442 if (--itor->pos < 0) {
455 if (itor->vec == &itor->al->word)
457 if (itor->vec->seq[itor->pos].parent == PS_ALIGNMENT_NONE)
459 itor2 = ckd_calloc(1,
sizeof(*itor2));
460 itor2->al = itor->al;
461 itor2->pos = itor->vec->seq[itor->pos].parent;
462 if (itor->vec == &itor->al->sseq)
463 itor2->vec = &itor->al->word;
465 itor2->vec = &itor->al->sseq;
475 if (itor->vec == &itor->al->state)
477 if (itor->vec->seq[itor->pos].child == PS_ALIGNMENT_NONE)
479 itor2 = ckd_calloc(1,
sizeof(*itor2));
480 itor2->al = itor->al;
481 itor2->pos = itor->vec->seq[itor->pos].child;
482 if (itor->vec == &itor->al->word)
483 itor2->vec = &itor->al->sseq;
485 itor2->vec = &itor->al->state;
int ps_alignment_n_states(ps_alignment_t *al)
Number of states.
int ps_alignment_populate_ci(ps_alignment_t *al)
Populate lower layers using context-independent phones.
ps_alignment_t * ps_alignment_init(dict2pid_t *d2p)
Create a new, empty alignment.
ps_alignment_iter_t * ps_alignment_iter_goto(ps_alignment_iter_t *itor, int pos)
Move alignment iterator to given index.
#define BAD_SSID
Invalid senone sequence ID (limited to 16 bits for PocketSphinx).
ps_alignment_iter_t * ps_alignment_iter_next(ps_alignment_iter_t *itor)
Move an alignment iterator forward.
int dict2pid_free(dict2pid_t *d2p)
Free the memory dict2pid structure.
int ps_alignment_free(ps_alignment_t *al)
Release an alignment.
#define dict2pid_rssid(d, ci, lc)
Access macros; not designed for arbitrary use.
int ps_alignment_propagate(ps_alignment_t *al)
Propagate timing information up from state sequence.
#define BAD_SENID
Invalid senone ID (limited to 16 bits for PocketSphinx).
bin_mdef_t * mdef
Model definition, used to generate internal ssids on the fly.
ps_alignment_iter_t * ps_alignment_words(ps_alignment_t *al)
Iterate over the alignment starting at the first word.
dict_t * dict
Dictionary this table refers to.
a structure for a dictionary.
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.
ps_alignment_iter_t * ps_alignment_iter_prev(ps_alignment_iter_t *itor)
Move an alignment iterator back.
ps_alignment_iter_t * ps_alignment_states(ps_alignment_t *al)
Iterate over the alignment starting at the first state.
ps_alignment_iter_t * ps_alignment_iter_up(ps_alignment_iter_t *itor)
Get a new iterator starting at the parent of the current node.
ps_alignment_iter_t * ps_alignment_iter_down(ps_alignment_iter_t *itor)
Get a new iterator starting at the first child of the current node.
int ps_alignment_n_phones(ps_alignment_t *al)
Number of phones.
int ps_alignment_iter_free(ps_alignment_iter_t *itor)
Release an iterator before completing all iterations.
s3cipid_t * cimap
Index into ssid[] above for each ci phone.
Multi-level alignment structure.
int ps_alignment_populate(ps_alignment_t *al)
Populate lower layers using available word information.
#define dict_pron(d, w, p)
The CI phones of the word w at position p.
ps_alignment_iter_t * ps_alignment_phones(ps_alignment_t *al)
Iterate over the alignment starting at the first phone.
Building composite triphone (as well as word internal triphones) with the dictionary.
s3ssid_t * ssid
Senone Sequence ID list for all context ciphones.
int ps_alignment_add_word(ps_alignment_t *al, int32 wid, int duration)
Append a word.
ps_alignment_entry_t * ps_alignment_iter_get(ps_alignment_iter_t *itor)
Get the alignment entry pointed to by an iterator.
int ps_alignment_n_words(ps_alignment_t *al)
Number of words.