1
/* -*- c-basic-offset: 4 -*- */
2
/* ====================================================================
3
* Copyright (c) 1995-2000 Carnegie Mellon University. All rights
6
* Redistribution and use in source and binary forms, with or without
7
* modification, are permitted provided that the following conditions
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
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
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.
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.
34
* ====================================================================
37
/*********************************************************************
42
* This routine uses a source model definition file, source
43
* mixing weight file and destination model definition file
44
* to initialize a destination mixing weight file.
47
* Eric H. Thayer (eht@cs.cmu.edu)
49
*********************************************************************/
50
#include "parse_cmd_ln.h"
52
/* The SPHINX-III common library */
53
#include <s3/common.h>
54
#include <s3/was_added.h>
56
#include <s3/model_inventory.h>
57
#include <s3/model_def_io.h>
58
#include <s3/s3ts2cb_io.h>
60
#include <s3/s3mixw_io.h>
61
#include <s3/s3tmat_io.h>
62
#include <s3/s3gau_io.h>
64
/* Some SPHINX-II compatibility definitions */
68
#if (!defined(WIN32) || defined(__CYGWIN__))
69
#include <sys/param.h>
74
static int init_mixw(void);
82
/* define, parse and (partially) validate the command line */
83
parse_cmd_ln(argc, argv);
89
init_uniform(float32 ***dest_mixw,
90
model_def_entry_t *dest,
94
float32 uniform = 1.0f / (float32)n_gau;
98
for (s = 0; s < dest->n_state; s++) {
100
for (i = 0; i < n_feat; i++) {
101
for (j = 0; j < n_gau; j++) {
102
if (d_m != TYING_NON_EMITTING)
103
dest_mixw[d_m][i][j] = uniform;
111
static pair_t **mixw_dest_list = NULL;
112
static pair_t **cb_dest_list = NULL;
113
static pair_t **tmat_dest_list = NULL;
116
init_model(float32 ***dest_mixw,
117
vector_t ***dest_mean,
118
vector_t ***dest_var,
119
vector_t ****dest_fullvar,
120
float32 ***dest_tmat,
121
model_def_entry_t *dest,
123
acmod_set_t *dest_acmod_set,
126
vector_t ***src_mean,
128
vector_t ****src_fullvar,
130
model_def_entry_t *src,
132
acmod_set_t *src_acmod_set,
137
const uint32 *veclen)
139
unsigned int s, i, j, k, l, ll;
140
unsigned int s_m, s_mg;
141
unsigned int d_m, d_mg;
142
uint32 s_tmat, d_tmat;
144
printf("%10s <- %-10s: ",
145
acmod_set_id2name(dest_acmod_set, dest->p),
146
acmod_set_id2name(src_acmod_set, src->p));
153
if (!was_added(&tmat_dest_list[d_tmat], s_tmat)) {
154
printf("[tm %5u += %5u]\n", d_tmat, s_tmat);
155
for (i = 0; i < n_state_pm-1; i++) {
156
for (j = 0; j < n_state_pm; j++) {
157
dest_tmat[d_tmat][i][j] += src_tmat[s_tmat][i][j];
162
for (s = 0; s < src->n_state; s++) {
164
d_m = dest->state[s];
166
if ((s_m == TYING_NON_EMITTING) &&
167
(d_m == TYING_NON_EMITTING))
170
if ((s_m != TYING_NON_EMITTING) &&
171
(d_m != TYING_NON_EMITTING)) {
173
if (!was_added(&mixw_dest_list[d_m], s_m)) {
174
printf("[mx %5u(%1u) += %5u] ", d_m, s, s_m);
176
for (j = 0; j < n_feat; j++) {
177
for (k = 0; k < n_gau; k++) {
178
dest_mixw[d_m][j][k] += src_mixw[s_m][j][k];
183
s_mg = src_cb_map[s_m];
184
d_mg = dest_cb_map[d_m];
185
if (!was_added(&cb_dest_list[d_mg], s_mg)) {
186
printf("[mg %5u(%1u) <- %5u] ", d_mg, s, s_mg);
188
for (j = 0; j < n_feat; j++) {
189
for (k = 0; k < n_gau; k++) {
190
for (l = 0; l < veclen[j]; l++) {
191
dest_mean[d_mg][j][k][l] = src_mean[s_mg][j][k][l];
193
dest_var[d_mg][j][k][l] = src_var[s_mg][j][k][l];
194
else if (dest_fullvar) {
195
for (ll = 0; ll < veclen[j]; ++ll) {
196
dest_fullvar[d_mg][j][k][l][ll]
197
= src_fullvar[s_mg][j][k][l][ll];
206
E_ERROR("Source is %semitting and destination is %semitting\n",
207
(s_m != TYING_NON_EMITTING ? "" : "non-"),
208
(d_m != TYING_NON_EMITTING ? "" : "non-"));
220
model_def_t *src_mdef;
222
vector_t ***src_mean;
223
vector_t ***src_var = NULL;
224
vector_t ****src_fullvar = NULL;
227
model_def_t *dest_mdef;
228
float32 ***dest_mixw;
229
vector_t ***dest_mean;
230
vector_t ***dest_var = NULL;
231
vector_t ****dest_fullvar = NULL;
232
float32 ***dest_tmat;
252
acmod_id_t src_m_base;
253
const char *dest_m_name;
254
const char *dest_m_base_name;
262
E_INFO("Reading src %s\n", cmd_ln_str("-src_moddeffn"));
264
/* read in the source model definition file */
265
if (model_def_read(&src_mdef,
266
cmd_ln_str("-src_moddeffn")) != S3_SUCCESS) {
271
ts2cbfn = cmd_ln_str("-src_ts2cbfn");
272
if (strcmp(SEMI_LABEL, ts2cbfn) == 0) {
273
E_INFO("Generating semi-continous ts2cb mapping\n");
274
src_mdef->cb = semi_ts2cb(src_mdef->n_tied_state);
275
n_ts = src_mdef->n_tied_state;
278
else if (strcmp(CONT_LABEL, ts2cbfn) == 0) {
279
E_INFO("Generating continous ts2cb mapping\n");
280
src_mdef->cb = cont_ts2cb(src_mdef->n_tied_state);
281
n_ts = src_mdef->n_tied_state;
282
n_cb = src_mdef->n_tied_state;
284
else if (strcmp(PTM_LABEL, ts2cbfn) == 0) {
285
E_INFO("Generating phonetically tied ts2cb mapping\n");
286
src_mdef->cb = ptm_ts2cb(src_mdef);
287
n_ts = src_mdef->n_tied_state;
288
n_cb = src_mdef->acmod_set->n_ci;
291
E_INFO("Reading src %s\n", cmd_ln_str("-src_ts2cbfn"));
292
if (s3ts2cb_read(ts2cbfn,
295
&n_cb) != S3_SUCCESS) {
300
E_INFO("Reading src %s\n", cmd_ln_str("-src_mixwfn"));
302
/* read in the source mixing weight parameter file */
303
if (s3mixw_read(cmd_ln_str("-src_mixwfn"),
304
&src_mixw, &n_mixw_src, &n_feat, &n_gau) != S3_SUCCESS) {
309
E_INFO("Reading src %s\n",
310
cmd_ln_str("-src_tmatfn"));
312
if (s3tmat_read(cmd_ln_str("-src_tmatfn"),
315
&n_state_pm) != S3_SUCCESS) {
319
E_INFO("Reading src %s\n", cmd_ln_str("-src_meanfn"));
321
if (s3gau_read(cmd_ln_str("-src_meanfn"),
326
&veclen) != S3_SUCCESS) {
330
if (tmp_n_feat != n_feat) {
331
E_FATAL("src mean n_feat (== %u) != prior value (== %u)\n",
334
if (tmp_n_gau != n_gau) {
335
E_FATAL("src mean n_gau (== %u) != prior value (== %u)\n",
338
if (n_cb_src != n_cb) {
339
E_FATAL("src mean n_cb (== %u) is inconsistent with ts2cb mapping %u. Most probably phoneset has duplicated phones\n",
343
E_INFO("Reading src %s\n", cmd_ln_str("-src_varfn"));
344
if (cmd_ln_int32("-fullvar")) {
345
if (s3gau_read_full(cmd_ln_str("-src_varfn"),
350
&tmp_veclen) != S3_SUCCESS) {
355
if (s3gau_read(cmd_ln_str("-src_varfn"),
360
&tmp_veclen) != S3_SUCCESS) {
365
if (tmp_n_feat != n_feat) {
366
E_FATAL("src var n_feat (== %u) != prior value (== %u)\n",
369
if (tmp_n_gau != n_gau) {
370
E_FATAL("src var n_gau (== %u) != prior value (== %u)\n",
373
if (n_cb_src != n_cb) {
374
E_FATAL("src var n_cb (== %u) inconsistent w/ ts2cb mapping %u\n",
378
if (n_mixw_src < src_mdef->n_tied_state) {
379
E_FATAL("Too few source mixing weights, %u, for the # of tied states, %u\n",
380
n_mixw_src, src_mdef->n_tied_state);
383
for (i = 0; i < n_feat; i++) {
384
if (veclen[i] != tmp_veclen[i]) {
385
E_FATAL("src var veclen[%u] (== %u) != prior value (== %u)\n",
386
i, tmp_veclen[i], veclen[i]);
389
ckd_free(tmp_veclen);
391
E_INFO("Reading dest %s\n",
392
cmd_ln_str("-dest_moddeffn"));
394
/* read in the destination model definition file */
395
if (model_def_read(&dest_mdef,
396
cmd_ln_str("-dest_moddeffn")) < S3_SUCCESS) {
400
ts2cbfn = cmd_ln_str("-dest_ts2cbfn");
401
if (strcmp(SEMI_LABEL, ts2cbfn) == 0) {
402
E_INFO("Generating semi-continous ts2cb mapping\n");
403
dest_mdef->cb = semi_ts2cb(dest_mdef->n_tied_state);
404
n_ts = dest_mdef->n_tied_state;
407
else if (strcmp(CONT_LABEL, ts2cbfn) == 0) {
408
E_INFO("Generating continous ts2cb mapping\n");
409
dest_mdef->cb = cont_ts2cb(dest_mdef->n_tied_state);
410
n_ts = dest_mdef->n_tied_state;
411
n_cb = dest_mdef->n_tied_state;
413
else if (strcmp(PTM_LABEL, ts2cbfn) == 0) {
414
E_INFO("Generating phonetically tied ts2cb mapping\n");
415
dest_mdef->cb = ptm_ts2cb(dest_mdef);
416
n_ts = dest_mdef->n_tied_state;
417
n_cb = dest_mdef->acmod_set->n_ci;
420
E_INFO("Reading dest %s\n",
421
cmd_ln_str("-dest_ts2cbfn"));
424
if (s3ts2cb_read(ts2cbfn,
427
&n_cb) != S3_SUCCESS) {
432
E_INFO("Calculating initial model parameters\n");
434
n_tmat_dest = dest_mdef->n_tied_tmat;
435
tmat_dest_list = init_was_added(n_tmat_dest);
437
E_INFO("Alloc %ux%ux%u dest tmat\n",
442
dest_tmat = (float32 ***)ckd_calloc_3d(n_tmat_dest,
447
n_mixw_dest = dest_mdef->n_tied_state;
448
mixw_dest_list = init_was_added(n_mixw_dest);
450
E_INFO("Alloc %ux%ux%u dest mixw\n",
451
n_mixw_dest, n_feat, n_gau);
452
dest_mixw = (float32 ***)ckd_calloc_3d(n_mixw_dest, n_feat, n_gau, sizeof(float32));
454
for (i = 0, n_cb_dest = 0; i < n_mixw_dest; i++) {
455
if (dest_mdef->cb[i] > n_cb_dest) {
456
n_cb_dest = dest_mdef->cb[i];
461
cb_dest_list = init_was_added(n_cb_dest);
463
E_INFO("Alloc %ux%ux%u dest mean and var\n",
464
n_cb_dest, n_feat, n_gau);
465
dest_mean = gauden_alloc_param(n_cb_dest, n_feat, n_gau, veclen);
467
dest_var = gauden_alloc_param(n_cb_dest, n_feat, n_gau, veclen);
468
else if (src_fullvar)
469
dest_fullvar = gauden_alloc_param_full(n_cb_dest, n_feat, n_gau, veclen);
471
for (dest_m = 0; dest_m < dest_mdef->n_defn; dest_m++) {
472
dest_m_name = acmod_set_id2name(dest_mdef->acmod_set, dest_m);
473
src_m = acmod_set_name2id(src_mdef->acmod_set, dest_m_name);
474
if (src_m == NO_ACMOD) {
475
/* No corresponding phone model in the source set */
477
/* See if there is a source base phone corresponding to this destination model
479
dest_m_base = acmod_set_base_phone(dest_mdef->acmod_set, dest_m);
480
dest_m_base_name = acmod_set_id2name(dest_mdef->acmod_set, dest_m_base);
482
src_m_base = acmod_set_name2id(src_mdef->acmod_set, dest_m_base_name);
483
if (src_m_base == NO_ACMOD) {
484
/* No corresponding model or base model found. Use uniform distribution */
486
E_INFO("No source base phone %s found. Initializing %s using uniform distribution\n",
487
dest_m_base_name, dest_m_name);
490
E_INFO("Uniform initialization of tmat not supported\n");
492
init_uniform(dest_mixw, &dest_mdef->defn[dest_m], n_feat, n_gau);
495
/* No corresponding model, but a base model was found. Use base distribution. */
496
init_model(dest_mixw, dest_mean, dest_var, dest_fullvar, dest_tmat,
497
&dest_mdef->defn[dest_m], dest_mdef->cb, dest_mdef->acmod_set,
498
src_mixw, src_mean, src_var, src_fullvar, src_tmat,
499
&src_mdef->defn[src_m_base], src_mdef->cb, src_mdef->acmod_set,
500
n_feat, n_gau, n_state_pm, veclen);
504
/* Found a corresponding model in the source set, so use source distributions to init
506
init_model(dest_mixw, dest_mean, dest_var, dest_fullvar, dest_tmat,
507
&dest_mdef->defn[dest_m], dest_mdef->cb, dest_mdef->acmod_set,
508
src_mixw, src_mean, src_var, src_fullvar, src_tmat,
509
&src_mdef->defn[src_m], src_mdef->cb, src_mdef->acmod_set,
510
n_feat, n_gau, n_state_pm, veclen);
514
for (m = 0; m < n_mixw_dest; m++) {
515
if (mixw_dest_list[m] == NULL) {
516
E_WARN("Destination state %u has not been initialized!\n", m);
520
for (m = 0; m < n_cb_dest; m++) {
521
if (cb_dest_list[m] == NULL) {
522
E_WARN("Destination cb %u has not been initialized!\n", m);
524
else if (cb_dest_list[m]->next != NULL) {
525
E_WARN("dest cb %u has > 1 corresponding source cb\n", m);
529
E_INFO("Writing dest %s\n",
530
cmd_ln_str("-dest_tmatfn"));
532
if (s3tmat_write(cmd_ln_str("-dest_tmatfn"),
535
n_state_pm) != S3_SUCCESS) {
540
E_INFO("Writing dest %s\n",
541
cmd_ln_str("-dest_mixwfn"));
543
if (s3mixw_write(cmd_ln_str("-dest_mixwfn"),
545
dest_mdef->n_tied_state, n_feat, n_gau) < S3_SUCCESS) {
549
E_INFO("Writing dest %s\n",
550
cmd_ln_str("-dest_meanfn"));
552
if (s3gau_write(cmd_ln_str("-dest_meanfn"),
553
(const vector_t ***)dest_mean,
557
veclen) != S3_SUCCESS) {
561
E_INFO("Writing dest %s\n",
562
cmd_ln_str("-dest_varfn"));
563
if (cmd_ln_int32("-fullvar")) {
564
if (s3gau_write_full(cmd_ln_str("-dest_varfn"),
565
(const vector_t ****)dest_fullvar,
569
veclen) != S3_SUCCESS) {
574
if (s3gau_write(cmd_ln_str("-dest_varfn"),
575
(const vector_t ***)dest_var,
579
veclen) != S3_SUCCESS) {
588
main(int argc, char *argv[])
590
if (initialize(argc, argv) != S3_SUCCESS) {
591
E_ERROR("errors initializing.\n");
595
if (init_mixw() != S3_SUCCESS) {
603
* Log record. Maintained by RCS.
606
* Revision 1.5 2004/07/21 22:32:26 egouvea
607
* Fixed some compatibility issues between platforms: make sure we open
608
* files with "wb" or "rb", move some #include not defined for all
609
* platforms to the proper #if defined() etc.
611
* Revision 1.4 2004/07/21 22:00:43 egouvea
612
* Changed the license terms to make it the same as sphinx2 and sphinx3.
614
* Revision 1.3 2001/04/05 20:02:31 awb
615
* *** empty log message ***
617
* Revision 1.2 2000/09/29 22:35:14 awb
618
* *** empty log message ***
620
* Revision 1.1 2000/09/24 21:38:31 awb
621
* *** empty log message ***
623
* Revision 1.8 97/07/16 11:36:22 eht
624
* *** empty log message ***
626
* Revision 1.7 1995/12/15 18:37:07 eht
627
* Added some type cases for memory alloc/free
629
* Revision 1.6 1995/12/14 20:05:00 eht
630
* Fixed seg fault for non-emitting states
632
* Revision 1.5 1995/11/10 19:18:43 eht
633
* Generate a WARN error if the state is not initialized rather that quitting
635
* Revision 1.4 1995/10/12 15:08:09 eht
636
* Expanded the output a little.
637
* Allow init_mixw to be used instead of clone_ci.
638
* init_mixw is more general so that it can be configured
639
* to do the work of clone_ci.
641
* Revision 1.3 1995/10/10 13:09:40 eht
642
* Changed to use <sphinxbase/prim_type.h>
644
* Revision 1.2 1995/10/09 15:16:02 eht
645
* Added some status printf's
646
* Changed interface to ckd_alloc to remove __FILE__, __LINE__ arguments
648
* Revision 1.1 1995/10/05 12:54:02 eht