44 #include <sphinxbase/bio.h> 49 #define MIXW_PARAM_VERSION "1.0" 50 #define SPDEF_PARAM_VERSION "1.2" 53 senone_mgau_map_read(
senone_t * s,
char const *file_name)
56 int32 byteswap, chksum_present, n_gauden_present;
60 char **argname, **argval;
64 E_INFO(
"Reading senone gauden-codebook map file: %s\n", file_name);
66 if ((fp = fopen(file_name,
"rb")) == NULL)
67 E_FATAL_SYSTEM(
"Failed to open map file '%s' for reading", file_name);
70 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
71 E_FATAL(
"Failed to read header from file '%s'\n", file_name);
76 for (i = 0; argname[i]; i++) {
77 if (strcmp(argname[i],
"version") == 0) {
78 if (strcmp(argval[i], SPDEF_PARAM_VERSION) != 0) {
79 E_WARN(
"Version mismatch(%s): %s, expecting %s\n",
80 file_name, argval[i], SPDEF_PARAM_VERSION);
84 if (sscanf(argval[i],
"%f", &v) != 1)
85 E_FATAL(
"%s: Bad version no. string: %s\n", file_name,
88 n_gauden_present = (v > 1.1) ? 1 : 0;
90 else if (strcmp(argname[i],
"chksum0") == 0) {
94 bio_hdrarg_free(argname, argval);
95 argname = argval = NULL;
100 if (n_gauden_present) {
101 E_INFO(
"Reading number of codebooks from %s\n", file_name);
103 (&(s->
n_gauden),
sizeof(int32), 1, fp, byteswap, &chksum) != 1)
104 E_FATAL(
"fread(%s) (#gauden) failed\n", file_name);
108 if (bio_fread_1d(&ptr,
sizeof(uint32), &(s->
n_sen), fp,
109 byteswap, &chksum) < 0) {
110 E_FATAL(
"bio_fread_1d(%s) failed\n", file_name);
113 E_INFO(
"Mapping %d senones to %d codebooks\n", s->
n_sen, s->
n_gauden);
116 if (!n_gauden_present) {
118 for (i = 0; i < s->
n_sen; i++)
124 bio_verify_chksum(fp, byteswap, chksum);
126 if (fread(&eofchk, 1, 1, fp) == 1)
127 E_FATAL(
"More data than expected in %s: %d\n", file_name, eofchk);
131 E_INFO(
"Read %d->%d senone-codebook mappings\n", s->
n_sen,
139 senone_mixw_read(
senone_t * s,
char const *file_name, logmath_t *lmath)
143 int32 byteswap, chksum_present;
146 int32 i, f, c, p, n_err;
147 char **argname, **argval;
149 E_INFO(
"Reading senone mixture weights: %s\n", file_name);
151 if ((fp = fopen(file_name,
"rb")) == NULL)
152 E_FATAL_SYSTEM(
"Failed to open mixture weights file '%s' for reading", file_name);
155 if (bio_readhdr(fp, &argname, &argval, &byteswap) < 0)
156 E_FATAL(
"Failed to read header from file '%s'\n", file_name);
160 for (i = 0; argname[i]; i++) {
161 if (strcmp(argname[i],
"version") == 0) {
162 if (strcmp(argval[i], MIXW_PARAM_VERSION) != 0)
163 E_WARN(
"Version mismatch(%s): %s, expecting %s\n",
164 file_name, argval[i], MIXW_PARAM_VERSION);
166 else if (strcmp(argname[i],
"chksum0") == 0) {
170 bio_hdrarg_free(argname, argval);
171 argname = argval = NULL;
176 if ((bio_fread(&(s->
n_sen),
sizeof(int32), 1, fp, byteswap, &chksum) !=
179 (bio_fread(&(s->
n_feat),
sizeof(int32), 1, fp, byteswap, &chksum)
181 || (bio_fread(&(s->
n_cw),
sizeof(int32), 1, fp, byteswap, &chksum)
183 || (bio_fread(&i,
sizeof(int32), 1, fp, byteswap, &chksum) != 1)) {
184 E_FATAL(
"bio_fread(%s) (arraysize) failed\n", file_name);
188 (
"%s: #float32s(%d) doesn't match dimensions: %d x %d x %d\n",
197 E_FATAL(
"mixwfloor (%e) not in range (0, 1)\n", s->
mixwfloor);
200 E_INFO(
"Truncating senone logs3(pdf) values by %d bits\n",
SENSCR_SHIFT);
207 E_INFO(
"Not transposing mixture weights in memory\n");
213 E_INFO(
"Transposing mixture weights in memory\n");
220 pdf = (float32 *) ckd_calloc(s->
n_cw,
sizeof(float32));
224 for (i = 0; i < s->
n_sen; i++) {
225 for (f = 0; f < s->
n_feat; f++) {
227 ((
void *) pdf,
sizeof(float32), s->
n_cw, fp, byteswap,
230 E_FATAL(
"bio_fread(%s) (arraydata) failed\n", file_name);
234 if (vector_sum_norm(pdf, s->
n_cw) <= 0.0)
237 vector_sum_norm(pdf, s->
n_cw);
240 for (c = 0; c < s->
n_cw; c++) {
241 p = -(logmath_log(lmath, pdf[c]));
246 (p < (255 << SENSCR_SHIFT)) ? (p >>
SENSCR_SHIFT) : 255;
249 (p < (255 << SENSCR_SHIFT)) ? (p >>
SENSCR_SHIFT) : 255;
254 E_WARN(
"Weight normalization failed for %d mixture weights components\n", n_err);
259 bio_verify_chksum(fp, byteswap, chksum);
261 if (fread(&eofchk, 1, 1, fp) == 1)
262 E_FATAL(
"More data than expected in %s\n", file_name);
267 (
"Read mixture weights for %d senones: %d features x %d codewords\n",
276 float32 mixwfloor, logmath_t *lmath,
bin_mdef_t *mdef)
286 if (sen2mgau_map_file) {
287 if (!(strcmp(sen2mgau_map_file,
".semi.") == 0
288 || strcmp(sen2mgau_map_file,
".ptm.") == 0
289 || strcmp(sen2mgau_map_file,
".cont.") == 0)) {
290 senone_mgau_map_read(s, sen2mgau_map_file);
296 sen2mgau_map_file =
".semi.";
297 else if (s->
n_gauden == bin_mdef_n_ciphone(mdef))
298 sen2mgau_map_file =
".ptm.";
300 sen2mgau_map_file =
".cont.";
303 senone_mixw_read(s, mixwfile, lmath);
305 if (strcmp(sen2mgau_map_file,
".semi.") == 0) {
307 E_INFO(
"Mapping all senones to one codebook\n");
310 else if (strcmp(sen2mgau_map_file,
".ptm.") == 0) {
312 E_INFO(
"Mapping senones to context-independent phone codebooks\n");
314 for (i = 0; i < s->
n_sen; i++)
315 s->
mgau[i] = bin_mdef_sen2cimap(mdef, i);
317 else if (strcmp(sen2mgau_map_file,
".cont.") == 0
318 || strcmp(sen2mgau_map_file,
".s3cont.") == 0) {
320 E_INFO(
"Mapping senones to individual codebooks\n");
322 E_FATAL(
"#senone=%d; must be >1\n", s->
n_sen);
325 for (i = 0; i < s->
n_sen; i++)
332 E_FATAL(
"#senones inconsistent: %d in %s; %d in %s\n",
333 n, sen2mgau_map_file, s->
n_sen, mixwfile);
346 ckd_free_3d((
void *) s->
pdf);
351 logmath_free(s->
lmath);
371 assert((
id >= 0) && (id < s->n_sen));
372 assert((n_top > 0) && (n_top <= s->n_cw));
376 for (f = 0; f < s->
n_feat; f++) {
388 ? (fden + -s->
pdf[
id][f][fdist[0].id])
389 : (fden + -s->
pdf[f][fdist[0].id][id]);
390 E_DEBUG(1, (
"fden[%d][%d] l+= %d + %d = %d\n",
391 id, f, -(fscr - fden), -(fden-top), -(fscr-top)));
393 for (t = 1; t < n_top; t++) {
396 (fden + -s->
pdf[
id][f][fdist[t].id]) :
397 (fden + -s->
pdf[f][fdist[t].id][id]);
398 fscr = logmath_add(s->
lmath, fscr, fwscr);
399 E_DEBUG(1, (
"fden[%d][%d] l+= %d + %d = %d\n",
400 id, f, -(fwscr - fden), -(fden-top), -(fscr-top)));
senprob_t *** pdf
gaussian density mixture weights, organized two possible ways depending on n_gauden: if (n_gauden > 1...
(Sphinx 3.0 specific) multiple streams senones.
int32 aw
Inverse acoustic weight.
Structure to store distance (density) values for a given input observation wrt density values in some...
float32 mixwfloor
floor applied to each PDF entry
uint32 n_sen
Number senones in this set.
uint32 * mgau
senone-id -> mgau-id mapping for senones in this set
8-bit senone PDF structure.
uint32 n_feat
Number feature streams.
int32 * featscr
The feature score for every senone, will be initialized inside senone_eval_all.
int32 senone_eval(senone_t *s, int id, gauden_dist_t **dist, int n_top)
Evaluate the score for the given senone wrt to the given top N gaussian codewords.
int32 n_mgau
Number codebooks.
#define SENSCR_SHIFT
Shift count for senone scores.
void senone_free(senone_t *s)
Release memory allocated by senone_init.
logmath_t * lmath
log math computation
uint32 n_cw
Number codewords per codebook,stream.
uint32 n_gauden
Number gaussian density codebooks referred to by senones.
Multivariate gaussian mixture density parameters.
senone_t * senone_init(gauden_t *g, char const *mixwfile, char const *mgau_mapfile, float32 mixwfloor, logmath_t *lmath, bin_mdef_t *mdef)
Load a set of senones (mixing weights and mixture gaussian codebook mappings) from the given files...
uint8 senprob_t
Senone logs3-probs, truncated to 8 bits.