00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119 #include <assert.h>
00120 #include <string.h>
00121 #ifdef HAVE_CONFIG_H
00122 #include <config.h>
00123 #endif
00124
00125 #ifdef _MSC_VER
00126 #pragma warning (disable: 4244 4996)
00127 #endif
00128
00129 #include "fe.h"
00130 #include "feat.h"
00131 #include "bio.h"
00132 #include "pio.h"
00133 #include "cmn.h"
00134 #include "agc.h"
00135 #include "err.h"
00136 #include "ckd_alloc.h"
00137 #include "prim_type.h"
00138 #include "glist.h"
00139
00140 #define FEAT_VERSION "1.0"
00141 #define FEAT_DCEP_WIN 2
00142
00143 #ifdef DUMP_FEATURES
00144 static void
00145 cep_dump_dbg(feat_t *fcb, mfcc_t **mfc, int32 nfr, const char *text)
00146 {
00147 int32 i, j;
00148
00149 E_INFO("%s\n", text);
00150 for (i = 0; i < nfr; i++) {
00151 for (j = 0; j < fcb->cepsize; j++) {
00152 fprintf(stderr, "%f ", MFCC2FLOAT(mfc[i][j]));
00153 }
00154 fprintf(stderr, "\n");
00155 }
00156 }
00157 static void
00158 feat_print_dbg(feat_t *fcb, mfcc_t ***feat, int32 nfr, const char *text)
00159 {
00160 E_INFO("%s\n", text);
00161 feat_print(fcb, feat, nfr, stderr);
00162 }
00163 #else
00164 #define cep_dump_dbg(fcb,mfc,nfr,text)
00165 #define feat_print_dbg(fcb,mfc,nfr,text)
00166 #endif
00167
00168 int32 **
00169 parse_subvecs(char const *str)
00170 {
00171 char const *strp;
00172 int32 n, n2, l;
00173 glist_t dimlist;
00174 glist_t veclist;
00175 int32 **subvec;
00176 gnode_t *gn, *gn2;
00177
00178 veclist = NULL;
00179
00180 strp = str;
00181 for (;;) {
00182 dimlist = NULL;
00183
00184 for (;;) {
00185 if (sscanf(strp, "%d%n", &n, &l) != 1)
00186 E_FATAL("'%s': Couldn't read int32 @pos %d\n", str,
00187 strp - str);
00188 strp += l;
00189
00190 if (*strp == '-') {
00191 strp++;
00192
00193 if (sscanf(strp, "%d%n", &n2, &l) != 1)
00194 E_FATAL("'%s': Couldn't read int32 @pos %d\n", str,
00195 strp - str);
00196 strp += l;
00197 }
00198 else
00199 n2 = n;
00200
00201 if ((n < 0) || (n > n2))
00202 E_FATAL("'%s': Bad subrange spec ending @pos %d\n", str,
00203 strp - str);
00204
00205 for (; n <= n2; n++) {
00206 gnode_t *gn;
00207 for (gn = dimlist; gn; gn = gnode_next(gn))
00208 if (gnode_int32(gn) == n)
00209 break;
00210 if (gn != NULL)
00211 E_FATAL("'%s': Duplicate dimension ending @pos %d\n",
00212 str, strp - str);
00213
00214 dimlist = glist_add_int32(dimlist, n);
00215 }
00216
00217 if ((*strp == '\0') || (*strp == '/'))
00218 break;
00219
00220 if (*strp != ',')
00221 E_FATAL("'%s': Bad delimiter @pos %d\n", str, strp - str);
00222
00223 strp++;
00224 }
00225
00226 veclist = glist_add_ptr(veclist, (void *) dimlist);
00227
00228 if (*strp == '\0')
00229 break;
00230
00231 assert(*strp == '/');
00232 strp++;
00233 }
00234
00235
00236 n = glist_count(veclist);
00237 subvec = (int32 **) ckd_calloc(n + 1, sizeof(int32 *));
00238 subvec[n] = NULL;
00239
00240 for (--n, gn = veclist; (n >= 0) && gn; gn = gnode_next(gn), --n) {
00241 gn2 = (glist_t) gnode_ptr(gn);
00242
00243 n2 = glist_count(gn2);
00244 if (n2 <= 0)
00245 E_FATAL("'%s': 0-length subvector\n", str);
00246
00247 subvec[n] = (int32 *) ckd_calloc(n2 + 1, sizeof(int32));
00248 subvec[n][n2] = -1;
00249
00250 for (--n2; (n2 >= 0) && gn2; gn2 = gnode_next(gn2), --n2)
00251 subvec[n][n2] = gnode_int32(gn2);
00252 assert((n2 < 0) && (!gn2));
00253 }
00254 assert((n < 0) && (!gn));
00255
00256
00257 for (gn = veclist; gn; gn = gnode_next(gn)) {
00258 gn2 = (glist_t) gnode_ptr(gn);
00259 glist_free(gn2);
00260 }
00261 glist_free(veclist);
00262
00263 return subvec;
00264 }
00265
00266 void
00267 subvecs_free(int32 **subvecs)
00268 {
00269 int32 **sv;
00270
00271 for (sv = subvecs; sv && *sv; ++sv)
00272 ckd_free(*sv);
00273 ckd_free(subvecs);
00274 }
00275
00276 int
00277 feat_set_subvecs(feat_t *fcb, int32 **subvecs)
00278 {
00279 int32 **sv;
00280 int32 n_sv, n_dim, i;
00281
00282 if (subvecs == NULL) {
00283 subvecs_free(fcb->subvecs);
00284 ckd_free(fcb->sv_buf);
00285 ckd_free(fcb->sv_len);
00286 fcb->n_sv = 0;
00287 fcb->subvecs = NULL;
00288 fcb->sv_len = NULL;
00289 fcb->sv_buf = NULL;
00290 fcb->sv_dim = 0;
00291 return 0;
00292 }
00293
00294 if (fcb->n_stream != 1) {
00295 E_ERROR("Subvector specifications require single-stream features!");
00296 return -1;
00297 }
00298
00299 n_sv = 0;
00300 n_dim = 0;
00301 for (sv = subvecs; sv && *sv; ++sv) {
00302 int32 *d;
00303
00304 for (d = *sv; d && *d != -1; ++d) {
00305 ++n_dim;
00306 }
00307 ++n_sv;
00308 }
00309 if (n_dim > feat_dimension(fcb)) {
00310 E_ERROR("Total dimensionality of subvector specification %d "
00311 "> feature dimensionality %d\n", n_dim, feat_dimension(fcb));
00312 return -1;
00313 }
00314
00315 fcb->n_sv = n_sv;
00316 fcb->subvecs = subvecs;
00317 fcb->sv_len = ckd_calloc(n_sv, sizeof(*fcb->sv_len));
00318 fcb->sv_buf = ckd_calloc(n_dim, sizeof(*fcb->sv_buf));
00319 fcb->sv_dim = n_dim;
00320 for (i = 0; i < n_sv; ++i) {
00321 int32 *d;
00322 for (d = subvecs[i]; d && *d != -1; ++d) {
00323 ++fcb->sv_len[i];
00324 }
00325 }
00326
00327 return 0;
00328 }
00329
00333 static void
00334 feat_subvec_project(feat_t *fcb, mfcc_t ***inout_feat, uint32 nfr)
00335 {
00336 uint32 i;
00337
00338 if (fcb->subvecs == NULL)
00339 return;
00340 for (i = 0; i < nfr; ++i) {
00341 mfcc_t *out;
00342 int32 j;
00343
00344 out = fcb->sv_buf;
00345 for (j = 0; j < fcb->n_sv; ++j) {
00346 int32 *d;
00347 for (d = fcb->subvecs[j]; d && *d != -1; ++d) {
00348 *out++ = inout_feat[i][0][*d];
00349 }
00350 }
00351 memcpy(inout_feat[i][0], fcb->sv_buf, fcb->sv_dim * sizeof(*fcb->sv_buf));
00352 }
00353 }
00354
00355
00356
00357
00358
00359 int32
00360 feat_s2mfc_read(char *file, int32 win,
00361 int32 sf, int32 ef,
00362 mfcc_t ***out_mfc,
00363 int32 maxfr,
00364 int32 cepsize)
00365 {
00366 FILE *fp;
00367 int32 n_float32;
00368 float32 *float_feat;
00369 struct stat statbuf;
00370 int32 i, n, byterev;
00371 int32 start_pad, end_pad;
00372 mfcc_t **mfc;
00373
00374
00375
00376 if (out_mfc)
00377 *out_mfc = NULL;
00378 E_INFO("Reading mfc file: '%s'[%d..%d]\n", file, sf, ef);
00379 if (ef >= 0 && ef <= sf) {
00380 E_ERROR("%s: End frame (%d) <= Start frame (%d)\n", file, ef, sf);
00381 return -1;
00382 }
00383
00384
00385 if ((stat_retry(file, &statbuf) < 0)
00386 || ((fp = fopen(file, "rb")) == NULL)) {
00387 E_ERROR("stat_retry/fopen(%s) failed\n", file);
00388 return -1;
00389 }
00390
00391
00392 if (fread_retry(&n_float32, sizeof(int32), 1, fp) != 1) {
00393 E_ERROR("%s: fread(#floats) failed\n", file);
00394 fclose(fp);
00395 return -1;
00396 }
00397
00398
00399 byterev = 0;
00400 if ((int32) (n_float32 * sizeof(float32) + 4) != (int32) statbuf.st_size) {
00401 n = n_float32;
00402 SWAP_INT32(&n);
00403
00404 if ((int32) (n * sizeof(float32) + 4) != (int32) (statbuf.st_size)) {
00405 E_ERROR
00406 ("%s: Header size field: %d(%08x); filesize: %d(%08x)\n",
00407 file, n_float32, n_float32, statbuf.st_size,
00408 statbuf.st_size);
00409 fclose(fp);
00410 return -1;
00411 }
00412
00413 n_float32 = n;
00414 byterev = 1;
00415 }
00416 if (n_float32 <= 0) {
00417 E_ERROR("%s: Header size field (#floats) = %d\n", file, n_float32);
00418 fclose(fp);
00419 return -1;
00420 }
00421
00422
00423 n = n_float32 / cepsize;
00424 if (n * cepsize != n_float32) {
00425 E_ERROR("Header size field: %d; not multiple of %d\n", n_float32,
00426 cepsize);
00427 fclose(fp);
00428 return -1;
00429 }
00430
00431
00432 if (sf > 0) {
00433 if (sf >= n) {
00434 E_ERROR("%s: Start frame (%d) beyond file size (%d)\n", file,
00435 sf, n);
00436 fclose(fp);
00437 return -1;
00438 }
00439 }
00440 if (ef < 0)
00441 ef = n-1;
00442 else if (ef >= n) {
00443 E_WARN("%s: End frame (%d) beyond file size (%d), will truncate\n",
00444 file, ef, n);
00445 ef = n-1;
00446 }
00447
00448
00449 sf -= win;
00450 ef += win;
00451 if (sf < 0) {
00452 start_pad = -sf;
00453 sf = 0;
00454 }
00455 else
00456 start_pad = 0;
00457 if (ef >= n) {
00458 end_pad = ef - n + 1;
00459 ef = n - 1;
00460 }
00461 else
00462 end_pad = 0;
00463
00464
00465 if ((ef - sf + 1) < n)
00466 n = (ef - sf + 1);
00467 if (maxfr > 0 && n + start_pad + end_pad > maxfr) {
00468 E_ERROR("%s: Maximum output size(%d frames) < actual #frames(%d)\n",
00469 file, maxfr, n + start_pad + end_pad);
00470 fclose(fp);
00471 return -1;
00472 }
00473
00474
00475 if (out_mfc != NULL) {
00476
00477 mfc = (mfcc_t **)ckd_calloc_2d(n + start_pad + end_pad, cepsize, sizeof(mfcc_t));
00478 if (sf > 0)
00479 fseek(fp, sf * cepsize * sizeof(float32), SEEK_CUR);
00480 n_float32 = n * cepsize;
00481 #ifdef FIXED_POINT
00482 float_feat = ckd_calloc(n_float32, sizeof(float32));
00483 #else
00484 float_feat = mfc[start_pad];
00485 #endif
00486 if (fread_retry(float_feat, sizeof(float32), n_float32, fp) != n_float32) {
00487 E_ERROR("%s: fread(%dx%d) (MFC data) failed\n", file, n, cepsize);
00488 ckd_free_2d(mfc);
00489 fclose(fp);
00490 return -1;
00491 }
00492 if (byterev) {
00493 for (i = 0; i < n_float32; i++) {
00494 SWAP_FLOAT32(&float_feat[i]);
00495 }
00496 }
00497 #ifdef FIXED_POINT
00498 for (i = 0; i < n_float32; ++i) {
00499 mfc[start_pad][i] = FLOAT2MFCC(float_feat[i]);
00500 }
00501 ckd_free(float_feat);
00502 #endif
00503
00504
00505 for (i = 0; i < start_pad; ++i)
00506 memcpy(mfc[i], mfc[start_pad], cepsize * sizeof(mfcc_t));
00507 for (i = 0; i < end_pad; ++i)
00508 memcpy(mfc[start_pad + n + i], mfc[start_pad + n - 1],
00509 cepsize * sizeof(mfcc_t));
00510
00511 *out_mfc = mfc;
00512 }
00513
00514 fclose(fp);
00515 return n + start_pad + end_pad;
00516 }
00517
00518 mfcc_t ***
00519 feat_array_alloc(feat_t * fcb, int32 nfr)
00520 {
00521 int32 i, j, k;
00522 mfcc_t *data, *d, ***feat;
00523
00524 assert(fcb);
00525 assert(nfr > 0);
00526 assert(feat_dimension(fcb) > 0);
00527
00528
00529
00530 k = 0;
00531 for (i = 0; i < fcb->n_stream; ++i)
00532 k += fcb->stream_len[i];
00533 assert(k >= feat_dimension(fcb));
00534 assert(k >= fcb->sv_dim);
00535
00536 feat =
00537 (mfcc_t ***) ckd_calloc_2d(nfr, feat_dimension1(fcb), sizeof(mfcc_t *));
00538 data = (mfcc_t *) ckd_calloc(nfr * k, sizeof(mfcc_t));
00539
00540 for (i = 0; i < nfr; i++) {
00541 d = data + i * k;
00542 for (j = 0; j < feat_dimension1(fcb); j++) {
00543 feat[i][j] = d;
00544 d += feat_dimension2(fcb, j);
00545 }
00546 }
00547
00548 return feat;
00549 }
00550
00551 void
00552 feat_array_free(mfcc_t ***feat)
00553 {
00554 ckd_free(feat[0][0]);
00555 ckd_free_2d((void **)feat);
00556 }
00557
00558 static void
00559 feat_s2_4x_cep2feat(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00560 {
00561 mfcc_t *f;
00562 mfcc_t *w, *_w;
00563 mfcc_t *w1, *w_1, *_w1, *_w_1;
00564 mfcc_t d1, d2;
00565 int32 i, j;
00566
00567 assert(fcb);
00568 assert(feat_cepsize(fcb) == 13);
00569 assert(feat_n_stream(fcb) == 4);
00570 assert(feat_stream_len(fcb, 0) == 12);
00571 assert(feat_stream_len(fcb, 1) == 24);
00572 assert(feat_stream_len(fcb, 2) == 3);
00573 assert(feat_stream_len(fcb, 3) == 12);
00574 assert(feat_window_size(fcb) == 4);
00575
00576
00577 memcpy(feat[0], mfc[0] + 1, (feat_cepsize(fcb) - 1) * sizeof(mfcc_t));
00578
00579
00580
00581
00582
00583 w = mfc[2] + 1;
00584 _w = mfc[-2] + 1;
00585
00586 f = feat[1];
00587 for (i = 0; i < feat_cepsize(fcb) - 1; i++)
00588 f[i] = w[i] - _w[i];
00589
00590 w = mfc[4] + 1;
00591 _w = mfc[-4] + 1;
00592
00593 for (j = 0; j < feat_cepsize(fcb) - 1; i++, j++)
00594 f[i] = w[j] - _w[j];
00595
00596
00597 w1 = mfc[3] + 1;
00598 _w1 = mfc[-1] + 1;
00599 w_1 = mfc[1] + 1;
00600 _w_1 = mfc[-3] + 1;
00601
00602 f = feat[3];
00603 for (i = 0; i < feat_cepsize(fcb) - 1; i++) {
00604 d1 = w1[i] - _w1[i];
00605 d2 = w_1[i] - _w_1[i];
00606
00607 f[i] = d1 - d2;
00608 }
00609
00610
00611 f = feat[2];
00612 f[0] = mfc[0][0];
00613 f[1] = mfc[2][0] - mfc[-2][0];
00614
00615 d1 = mfc[3][0] - mfc[-1][0];
00616 d2 = mfc[1][0] - mfc[-3][0];
00617 f[2] = d1 - d2;
00618 }
00619
00620
00621 static void
00622 feat_s3_1x39_cep2feat(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00623 {
00624 mfcc_t *f;
00625 mfcc_t *w, *_w;
00626 mfcc_t *w1, *w_1, *_w1, *_w_1;
00627 mfcc_t d1, d2;
00628 int32 i;
00629
00630 assert(fcb);
00631 assert(feat_cepsize(fcb) == 13);
00632 assert(feat_n_stream(fcb) == 1);
00633 assert(feat_stream_len(fcb, 0) == 39);
00634 assert(feat_window_size(fcb) == 3);
00635
00636
00637 memcpy(feat[0], mfc[0] + 1, (feat_cepsize(fcb) - 1) * sizeof(mfcc_t));
00638
00639
00640
00641 f = feat[0] + feat_cepsize(fcb) - 1;
00642 w = mfc[2] + 1;
00643 _w = mfc[-2] + 1;
00644
00645 for (i = 0; i < feat_cepsize(fcb) - 1; i++)
00646 f[i] = w[i] - _w[i];
00647
00648
00649 f += feat_cepsize(fcb) - 1;
00650
00651 f[0] = mfc[0][0];
00652 f[1] = mfc[2][0] - mfc[-2][0];
00653
00654 d1 = mfc[3][0] - mfc[-1][0];
00655 d2 = mfc[1][0] - mfc[-3][0];
00656 f[2] = d1 - d2;
00657
00658
00659 f += 3;
00660
00661 w1 = mfc[3] + 1;
00662 _w1 = mfc[-1] + 1;
00663 w_1 = mfc[1] + 1;
00664 _w_1 = mfc[-3] + 1;
00665
00666 for (i = 0; i < feat_cepsize(fcb) - 1; i++) {
00667 d1 = w1[i] - _w1[i];
00668 d2 = w_1[i] - _w_1[i];
00669
00670 f[i] = d1 - d2;
00671 }
00672 }
00673
00674
00675 static void
00676 feat_s3_cep(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00677 {
00678 assert(fcb);
00679 assert(feat_n_stream(fcb) == 1);
00680 assert(feat_window_size(fcb) == 0);
00681
00682
00683 memcpy(feat[0], mfc[0], feat_cepsize(fcb) * sizeof(mfcc_t));
00684 }
00685
00686
00687 static void
00688 feat_s3_cep_dcep(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00689 {
00690 mfcc_t *f;
00691 mfcc_t *w, *_w;
00692 int32 i;
00693
00694 assert(fcb);
00695 assert(feat_n_stream(fcb) == 1);
00696 assert(feat_stream_len(fcb, 0) == feat_cepsize(fcb) * 2);
00697 assert(feat_window_size(fcb) == 2);
00698
00699
00700 memcpy(feat[0], mfc[0], feat_cepsize(fcb) * sizeof(mfcc_t));
00701
00702
00703
00704
00705 f = feat[0] + feat_cepsize(fcb);
00706 w = mfc[2];
00707 _w = mfc[-2];
00708
00709 for (i = 0; i < feat_cepsize(fcb); i++)
00710 f[i] = w[i] - _w[i];
00711 }
00712
00713 static void
00714 feat_1s_c_d_dd_cep2feat(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00715 {
00716 mfcc_t *f;
00717 mfcc_t *w, *_w;
00718 mfcc_t *w1, *w_1, *_w1, *_w_1;
00719 mfcc_t d1, d2;
00720 int32 i;
00721
00722 assert(fcb);
00723 assert(feat_n_stream(fcb) == 1);
00724 assert(feat_stream_len(fcb, 0) == feat_cepsize(fcb) * 3);
00725 assert(feat_window_size(fcb) == FEAT_DCEP_WIN + 1);
00726
00727
00728 memcpy(feat[0], mfc[0], feat_cepsize(fcb) * sizeof(mfcc_t));
00729
00730
00731
00732
00733 f = feat[0] + feat_cepsize(fcb);
00734 w = mfc[FEAT_DCEP_WIN];
00735 _w = mfc[-FEAT_DCEP_WIN];
00736
00737 for (i = 0; i < feat_cepsize(fcb); i++)
00738 f[i] = w[i] - _w[i];
00739
00740
00741
00742
00743
00744 f += feat_cepsize(fcb);
00745
00746 w1 = mfc[FEAT_DCEP_WIN + 1];
00747 _w1 = mfc[-FEAT_DCEP_WIN + 1];
00748 w_1 = mfc[FEAT_DCEP_WIN - 1];
00749 _w_1 = mfc[-FEAT_DCEP_WIN - 1];
00750
00751 for (i = 0; i < feat_cepsize(fcb); i++) {
00752 d1 = w1[i] - _w1[i];
00753 d2 = w_1[i] - _w_1[i];
00754
00755 f[i] = d1 - d2;
00756 }
00757 }
00758
00759 static void
00760 feat_1s_c_d_ld_dd_cep2feat(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00761 {
00762 mfcc_t *f;
00763 mfcc_t *w, *_w;
00764 mfcc_t *w1, *w_1, *_w1, *_w_1;
00765 mfcc_t d1, d2;
00766 int32 i;
00767
00768 assert(fcb);
00769 assert(feat_n_stream(fcb) == 1);
00770 assert(feat_stream_len(fcb, 0) == feat_cepsize(fcb) * 4);
00771 assert(feat_window_size(fcb) == FEAT_DCEP_WIN * 2);
00772
00773
00774 memcpy(feat[0], mfc[0], feat_cepsize(fcb) * sizeof(mfcc_t));
00775
00776
00777
00778
00779 f = feat[0] + feat_cepsize(fcb);
00780 w = mfc[FEAT_DCEP_WIN];
00781 _w = mfc[-FEAT_DCEP_WIN];
00782
00783 for (i = 0; i < feat_cepsize(fcb); i++)
00784 f[i] = w[i] - _w[i];
00785
00786
00787
00788
00789 f += feat_cepsize(fcb);
00790 w = mfc[FEAT_DCEP_WIN * 2];
00791 _w = mfc[-FEAT_DCEP_WIN * 2];
00792
00793 for (i = 0; i < feat_cepsize(fcb); i++)
00794 f[i] = w[i] - _w[i];
00795
00796
00797
00798
00799
00800 f += feat_cepsize(fcb);
00801
00802 w1 = mfc[FEAT_DCEP_WIN + 1];
00803 _w1 = mfc[-FEAT_DCEP_WIN + 1];
00804 w_1 = mfc[FEAT_DCEP_WIN - 1];
00805 _w_1 = mfc[-FEAT_DCEP_WIN - 1];
00806
00807 for (i = 0; i < feat_cepsize(fcb); i++) {
00808 d1 = w1[i] - _w1[i];
00809 d2 = w_1[i] - _w_1[i];
00810
00811 f[i] = d1 - d2;
00812 }
00813 }
00814
00815 static void
00816 feat_copy(feat_t * fcb, mfcc_t ** mfc, mfcc_t ** feat)
00817 {
00818 int32 win, i, j;
00819
00820 win = feat_window_size(fcb);
00821
00822
00823 for (i = -win; i <= win; ++i) {
00824 uint32 spos = 0;
00825
00826 for (j = 0; j < feat_n_stream(fcb); ++j) {
00827 uint32 stream_len;
00828
00829
00830 stream_len = feat_stream_len(fcb, j) / (2 * win + 1);
00831 memcpy(feat[j] + ((i + win) * stream_len),
00832 mfc[i] + spos,
00833 stream_len * sizeof(mfcc_t));
00834 spos += stream_len;
00835 }
00836 }
00837 }
00838
00839 feat_t *
00840 feat_init(char const *type, cmn_type_t cmn, int32 varnorm,
00841 agc_type_t agc, int32 breport, int32 cepsize)
00842 {
00843 feat_t *fcb;
00844
00845 if (cepsize == 0)
00846 cepsize = 13;
00847 if (breport)
00848 E_INFO
00849 ("Initializing feature stream to type: '%s', ceplen=%d, CMN='%s', VARNORM='%s', AGC='%s'\n",
00850 type, cepsize, cmn_type_str[cmn], varnorm ? "yes" : "no", agc_type_str[agc]);
00851
00852 fcb = (feat_t *) ckd_calloc(1, sizeof(feat_t));
00853 fcb->refcount = 1;
00854 fcb->name = (char *) ckd_salloc(type);
00855 if (strcmp(type, "s2_4x") == 0) {
00856
00857 if (cepsize != 13) {
00858 E_ERROR("s2_4x features require cepsize == 13\n");
00859 ckd_free(fcb);
00860 return NULL;
00861 }
00862 fcb->cepsize = 13;
00863 fcb->n_stream = 4;
00864 fcb->stream_len = (int32 *) ckd_calloc(4, sizeof(int32));
00865 fcb->stream_len[0] = 12;
00866 fcb->stream_len[1] = 24;
00867 fcb->stream_len[2] = 3;
00868 fcb->stream_len[3] = 12;
00869 fcb->out_dim = 51;
00870 fcb->window_size = 4;
00871 fcb->compute_feat = feat_s2_4x_cep2feat;
00872 }
00873 else if (strcmp(type, "s3_1x39") == 0) {
00874
00875 if (cepsize != 13) {
00876 E_ERROR("s2_4x features require cepsize == 13\n");
00877 ckd_free(fcb);
00878 return NULL;
00879 }
00880 fcb->cepsize = 13;
00881 fcb->n_stream = 1;
00882 fcb->stream_len = (int32 *) ckd_calloc(1, sizeof(int32));
00883 fcb->stream_len[0] = 39;
00884 fcb->out_dim = 39;
00885 fcb->window_size = 3;
00886 fcb->compute_feat = feat_s3_1x39_cep2feat;
00887 }
00888 else if (strncmp(type, "1s_c_d_dd", 9) == 0) {
00889 fcb->cepsize = cepsize;
00890 fcb->n_stream = 1;
00891 fcb->stream_len = (int32 *) ckd_calloc(1, sizeof(int32));
00892 fcb->stream_len[0] = cepsize * 3;
00893 fcb->out_dim = cepsize * 3;
00894 fcb->window_size = FEAT_DCEP_WIN + 1;
00895 fcb->compute_feat = feat_1s_c_d_dd_cep2feat;
00896 }
00897 else if (strncmp(type, "1s_c_d_ld_dd", 12) == 0) {
00898 fcb->cepsize = cepsize;
00899 fcb->n_stream = 1;
00900 fcb->stream_len = (int32 *) ckd_calloc(1, sizeof(int32));
00901 fcb->stream_len[0] = cepsize * 4;
00902 fcb->out_dim = cepsize * 4;
00903 fcb->window_size = FEAT_DCEP_WIN * 2;
00904 fcb->compute_feat = feat_1s_c_d_ld_dd_cep2feat;
00905 }
00906 else if (strncmp(type, "cep_dcep", 8) == 0 || strncmp(type, "1s_c_d", 6) == 0) {
00907
00908 fcb->cepsize = cepsize;
00909 fcb->n_stream = 1;
00910 fcb->stream_len = (int32 *) ckd_calloc(1, sizeof(int32));
00911 fcb->stream_len[0] = feat_cepsize(fcb) * 2;
00912 fcb->out_dim = fcb->stream_len[0];
00913 fcb->window_size = 2;
00914 fcb->compute_feat = feat_s3_cep_dcep;
00915 }
00916 else if (strncmp(type, "cep", 3) == 0 || strncmp(type, "1s_c", 4) == 0) {
00917
00918 fcb->cepsize = cepsize;
00919 fcb->n_stream = 1;
00920 fcb->stream_len = (int32 *) ckd_calloc(1, sizeof(int32));
00921 fcb->stream_len[0] = feat_cepsize(fcb);
00922 fcb->out_dim = fcb->stream_len[0];
00923 fcb->window_size = 0;
00924 fcb->compute_feat = feat_s3_cep;
00925 }
00926 else {
00927 int32 i, l, k;
00928 char *strp;
00929 char *mtype = ckd_salloc(type);
00930 char *wd = ckd_salloc(type);
00931
00932
00933
00934
00935
00936
00937
00938 l = strlen(mtype);
00939 k = 0;
00940 for (i = 1; i < l - 1; i++) {
00941 if (mtype[i] == ',') {
00942 mtype[i] = ' ';
00943 k++;
00944 }
00945 else if (mtype[i] == ':') {
00946 mtype[i] = '\0';
00947 fcb->window_size = atoi(mtype + i + 1);
00948 break;
00949 }
00950 }
00951 k++;
00952 fcb->n_stream = k;
00953 fcb->stream_len = (int32 *) ckd_calloc(k, sizeof(int32));
00954
00955
00956 strp = mtype;
00957 i = 0;
00958 fcb->out_dim = 0;
00959 fcb->cepsize = 0;
00960 while (sscanf(strp, "%s%n", wd, &l) == 1) {
00961 strp += l;
00962 if ((i >= fcb->n_stream)
00963 || (sscanf(wd, "%d", &(fcb->stream_len[i])) != 1)
00964 || (fcb->stream_len[i] <= 0))
00965 E_FATAL("Bad feature type argument\n");
00966
00967 fcb->cepsize += fcb->stream_len[i];
00968 if (fcb->window_size > 0)
00969 fcb->stream_len[i] *= (fcb->window_size * 2 + 1);
00970
00971 fcb->out_dim += fcb->stream_len[i];
00972 i++;
00973 }
00974 if (i != fcb->n_stream)
00975 E_FATAL("Bad feature type argument\n");
00976
00977
00978 fcb->compute_feat = feat_copy;
00979 ckd_free(mtype);
00980 ckd_free(wd);
00981 }
00982
00983 if (cmn != CMN_NONE)
00984 fcb->cmn_struct = cmn_init(feat_cepsize(fcb));
00985 fcb->cmn = cmn;
00986 fcb->varnorm = varnorm;
00987 if (agc != AGC_NONE) {
00988 fcb->agc_struct = agc_init();
00989
00990
00991
00992
00993
00994
00995 agc_emax_set(fcb->agc_struct, (cmn != CMN_NONE) ? 5.0 : 10.0);
00996 }
00997 fcb->agc = agc;
00998
00999
01000
01001 fcb->cepbuf = (mfcc_t **) ckd_calloc_2d((LIVEBUFBLOCKSIZE < feat_window_size(fcb) * 2) ? feat_window_size(fcb) * 2 : LIVEBUFBLOCKSIZE,
01002 feat_cepsize(fcb),
01003 sizeof(mfcc_t));
01004
01005
01006 fcb->tmpcepbuf = ckd_calloc(2 * feat_window_size(fcb) + 1,
01007 sizeof(*fcb->tmpcepbuf));
01008
01009 return fcb;
01010 }
01011
01012
01013 void
01014 feat_print(feat_t * fcb, mfcc_t *** feat, int32 nfr, FILE * fp)
01015 {
01016 int32 i, j, k;
01017
01018 for (i = 0; i < nfr; i++) {
01019 fprintf(fp, "%8d:\n", i);
01020
01021 for (j = 0; j < feat_dimension1(fcb); j++) {
01022 fprintf(fp, "\t%2d:", j);
01023
01024 for (k = 0; k < feat_dimension2(fcb, j); k++)
01025 fprintf(fp, " %8.4f", MFCC2FLOAT(feat[i][j][k]));
01026 fprintf(fp, "\n");
01027 }
01028 }
01029
01030 fflush(fp);
01031 }
01032
01033 static void
01034 feat_cmn(feat_t *fcb, mfcc_t **mfc, int32 nfr, int32 beginutt, int32 endutt)
01035 {
01036 cmn_type_t cmn_type = fcb->cmn;
01037
01038 if (!(beginutt && endutt)
01039 && cmn_type != CMN_NONE)
01040 cmn_type = CMN_PRIOR;
01041
01042 switch (cmn_type) {
01043 case CMN_CURRENT:
01044 cmn(fcb->cmn_struct, mfc, fcb->varnorm, nfr);
01045 break;
01046 case CMN_PRIOR:
01047 cmn_prior(fcb->cmn_struct, mfc, fcb->varnorm, nfr);
01048 if (endutt)
01049 cmn_prior_update(fcb->cmn_struct);
01050 break;
01051 default:
01052 ;
01053 }
01054 cep_dump_dbg(fcb, mfc, nfr, "After CMN");
01055 }
01056
01057 static void
01058 feat_agc(feat_t *fcb, mfcc_t **mfc, int32 nfr, int32 beginutt, int32 endutt)
01059 {
01060 agc_type_t agc_type = fcb->agc;
01061
01062 if (!(beginutt && endutt)
01063 && agc_type != AGC_NONE)
01064 agc_type = AGC_EMAX;
01065
01066 switch (agc_type) {
01067 case AGC_MAX:
01068 agc_max(fcb->agc_struct, mfc, nfr);
01069 break;
01070 case AGC_EMAX:
01071 agc_emax(fcb->agc_struct, mfc, nfr);
01072 if (endutt)
01073 agc_emax_update(fcb->agc_struct);
01074 break;
01075 case AGC_NOISE:
01076 agc_noise(fcb->agc_struct, mfc, nfr);
01077 break;
01078 default:
01079 ;
01080 }
01081 cep_dump_dbg(fcb, mfc, nfr, "After AGC");
01082 }
01083
01084 static void
01085 feat_compute_utt(feat_t *fcb, mfcc_t **mfc, int32 nfr, int32 win, mfcc_t ***feat)
01086 {
01087 int32 i;
01088
01089 cep_dump_dbg(fcb, mfc, nfr, "Incoming features (after padding)");
01090 feat_cmn(fcb, mfc, nfr, 1, 1);
01091 feat_agc(fcb, mfc, nfr, 1, 1);
01092
01093
01094 for (i = win; i < nfr - win; i++) {
01095 fcb->compute_feat(fcb, mfc + i, feat[i - win]);
01096 }
01097
01098 feat_print_dbg(fcb, feat, nfr - win * 2, "After dynamic feature computation");
01099
01100 if (fcb->lda) {
01101 feat_lda_transform(fcb, feat, nfr - win * 2);
01102 feat_print_dbg(fcb, feat, nfr - win * 2, "After LDA");
01103 }
01104
01105 if (fcb->subvecs) {
01106 feat_subvec_project(fcb, feat, nfr - win * 2);
01107 feat_print_dbg(fcb, feat, nfr - win * 2, "After subvector projection");
01108 }
01109 }
01110
01111 int32
01112 feat_s2mfc2feat(feat_t * fcb, const char *file, const char *dir, const char *cepext,
01113 int32 sf, int32 ef, mfcc_t *** feat, int32 maxfr)
01114 {
01115 char *path;
01116 char *ps = "/";
01117 int32 win, nfr;
01118 int32 file_length, cepext_length, path_length = 0;
01119 mfcc_t **mfc;
01120
01121 if (fcb->cepsize <= 0) {
01122 E_ERROR("Bad cepsize: %d\n", fcb->cepsize);
01123 return -1;
01124 }
01125
01126 if (cepext == NULL)
01127 cepext = "";
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138 if (dir == NULL) {
01139 dir = "";
01140 ps = "";
01141
01142
01143
01144
01145 E_INFO("At directory . (current directory)\n");
01146 }
01147 else {
01148 E_INFO("At directory %s\n", dir);
01149
01150
01151
01152 path_length += strlen(dir) + 1;
01153 }
01154
01155
01156
01157
01158 file_length = strlen(file);
01159 cepext_length = strlen(cepext);
01160 if ((file_length > cepext_length)
01161 && (strcmp(file + file_length - cepext_length, cepext) == 0)) {
01162 cepext = "";
01163 cepext_length = 0;
01164 }
01165
01166
01167
01168
01169 path_length += file_length + cepext_length + 1;
01170 path = (char*) ckd_calloc(path_length, sizeof(char));
01171
01172 #ifdef HAVE_SNPRINTF
01173
01174
01175
01176 while ((file_length = snprintf(path, path_length, "%s%s%s%s", dir, ps, file, cepext)) > path_length) {
01177 path_length = file_length;
01178 path = (char*) ckd_realloc(path, path_length * sizeof(char));
01179 }
01180 #else
01181 sprintf(path, "%s%s%s%s", dir, ps, file, cepext);
01182 #endif
01183
01184 win = feat_window_size(fcb);
01185
01186
01187 if (maxfr >= 0)
01188 maxfr += win * 2;
01189
01190 if (feat != NULL) {
01191
01192 nfr = feat_s2mfc_read(path, win, sf, ef, &mfc, maxfr, fcb->cepsize);
01193 ckd_free(path);
01194 if (nfr < 0) {
01195 ckd_free_2d((void **) mfc);
01196 return -1;
01197 }
01198
01199 feat_compute_utt(fcb, mfc, nfr, win, feat);
01200 ckd_free_2d((void **) mfc);
01201 }
01202 else {
01203
01204 nfr = feat_s2mfc_read(path, win, sf, ef, NULL, maxfr, fcb->cepsize);
01205 ckd_free(path);
01206 if (nfr < 0)
01207 return nfr;
01208 }
01209
01210
01211 return (nfr - win * 2);
01212 }
01213
01214 static int32
01215 feat_s2mfc2feat_block_utt(feat_t * fcb, mfcc_t ** uttcep,
01216 int32 nfr, mfcc_t *** ofeat)
01217 {
01218 mfcc_t **cepbuf;
01219 int32 i, win, cepsize;
01220
01221 win = feat_window_size(fcb);
01222 cepsize = feat_cepsize(fcb);
01223
01224
01225
01226
01227 cepbuf = ckd_calloc(nfr + win * 2, sizeof(mfcc_t *));
01228 memcpy(cepbuf + win, uttcep, nfr * sizeof(mfcc_t *));
01229 for (i = 0; i < win; ++i) {
01230 cepbuf[i] = fcb->cepbuf[i];
01231 memcpy(cepbuf[i], uttcep[0], cepsize * sizeof(mfcc_t));
01232 cepbuf[nfr + win + i] = fcb->cepbuf[win + i];
01233 memcpy(cepbuf[nfr + win + i], uttcep[nfr - 1], cepsize * sizeof(mfcc_t));
01234 }
01235
01236 feat_compute_utt(fcb, cepbuf, nfr + win * 2, win, ofeat);
01237 ckd_free(cepbuf);
01238 return nfr;
01239 }
01240
01241 int32
01242 feat_s2mfc2feat_live(feat_t * fcb, mfcc_t ** uttcep, int32 *inout_ncep,
01243 int32 beginutt, int32 endutt, mfcc_t *** ofeat)
01244 {
01245 int32 win, cepsize, nbufcep;
01246 int32 i, j, nfeatvec;
01247 int32 zero = 0;
01248
01249
01250 if (inout_ncep == NULL) inout_ncep = &zero;
01251
01252
01253 if (beginutt && endutt && *inout_ncep > 0)
01254 return feat_s2mfc2feat_block_utt(fcb, uttcep, *inout_ncep, ofeat);
01255
01256 win = feat_window_size(fcb);
01257 cepsize = feat_cepsize(fcb);
01258
01259
01260 if (beginutt)
01261 fcb->bufpos = fcb->curpos;
01262
01263
01264 nbufcep = fcb->bufpos - fcb->curpos;
01265 if (nbufcep < 0)
01266 nbufcep = fcb->bufpos + LIVEBUFBLOCKSIZE - fcb->curpos;
01267
01268 if (beginutt && *inout_ncep > 0)
01269 nbufcep += win;
01270 if (endutt)
01271 nbufcep += win;
01272
01273
01274 if (nbufcep + *inout_ncep > LIVEBUFBLOCKSIZE) {
01275
01276
01277 *inout_ncep = LIVEBUFBLOCKSIZE - nbufcep - win;
01278
01279 endutt = FALSE;
01280 }
01281
01282
01283 feat_cmn(fcb, uttcep, *inout_ncep, beginutt, endutt);
01284 feat_agc(fcb, uttcep, *inout_ncep, beginutt, endutt);
01285
01286
01287
01288
01289 if (beginutt && *inout_ncep > 0) {
01290 for (i = 0; i < win; i++) {
01291 memcpy(fcb->cepbuf[fcb->bufpos++], uttcep[0],
01292 cepsize * sizeof(mfcc_t));
01293 fcb->bufpos %= LIVEBUFBLOCKSIZE;
01294 }
01295
01296 fcb->curpos = fcb->bufpos;
01297 nbufcep -= win;
01298 }
01299
01300
01301 for (i = 0; i < *inout_ncep; ++i) {
01302 memcpy(fcb->cepbuf[fcb->bufpos++], uttcep[i],
01303 cepsize * sizeof(mfcc_t));
01304 fcb->bufpos %= LIVEBUFBLOCKSIZE;
01305 ++nbufcep;
01306 }
01307
01308
01309
01310
01311 if (endutt) {
01312 int32 tpos;
01313 if (fcb->bufpos == 0)
01314 tpos = LIVEBUFBLOCKSIZE - 1;
01315 else
01316 tpos = fcb->bufpos - 1;
01317 for (i = 0; i < win; ++i) {
01318 memcpy(fcb->cepbuf[fcb->bufpos++], fcb->cepbuf[tpos],
01319 cepsize * sizeof(mfcc_t));
01320 fcb->bufpos %= LIVEBUFBLOCKSIZE;
01321 }
01322 }
01323
01324
01325 nfeatvec = nbufcep - win;
01326 if (nfeatvec <= 0)
01327 return 0;
01328
01329 for (i = 0; i < nfeatvec; ++i) {
01330
01331 if (fcb->curpos - win < 0 || fcb->curpos + win >= LIVEBUFBLOCKSIZE) {
01332
01333 for (j = -win; j <= win; ++j) {
01334 int32 tmppos =
01335 (fcb->curpos + j + LIVEBUFBLOCKSIZE) % LIVEBUFBLOCKSIZE;
01336 fcb->tmpcepbuf[win + j] = fcb->cepbuf[tmppos];
01337 }
01338 fcb->compute_feat(fcb, fcb->tmpcepbuf + win, ofeat[i]);
01339 }
01340 else {
01341 fcb->compute_feat(fcb, fcb->cepbuf + fcb->curpos, ofeat[i]);
01342 }
01343
01344 ++fcb->curpos;
01345 fcb->curpos %= LIVEBUFBLOCKSIZE;
01346 }
01347
01348 if (fcb->lda)
01349 feat_lda_transform(fcb, ofeat, nfeatvec);
01350
01351 if (fcb->subvecs)
01352 feat_subvec_project(fcb, ofeat, nfeatvec);
01353
01354 return nfeatvec;
01355 }
01356
01357 feat_t *
01358 feat_retain(feat_t *f)
01359 {
01360 ++f->refcount;
01361 return f;
01362 }
01363
01364 int
01365 feat_free(feat_t * f)
01366 {
01367 if (f == NULL)
01368 return 0;
01369 if (--f->refcount > 0)
01370 return f->refcount;
01371
01372 if (f->cepbuf)
01373 ckd_free_2d((void **) f->cepbuf);
01374 ckd_free(f->tmpcepbuf);
01375
01376 if (f->name) {
01377 ckd_free((void *) f->name);
01378 }
01379 if (f->lda)
01380 ckd_free_3d((void ***) f->lda);
01381
01382 ckd_free(f->stream_len);
01383 ckd_free(f->sv_len);
01384 ckd_free(f->sv_buf);
01385 subvecs_free(f->subvecs);
01386
01387 cmn_free(f->cmn_struct);
01388 agc_free(f->agc_struct);
01389
01390 ckd_free(f);
01391 return 0;
01392 }
01393
01394
01395 void
01396 feat_report(feat_t * f)
01397 {
01398 int i;
01399 E_INFO_NOFN("Initialization of feat_t, report:\n");
01400 E_INFO_NOFN("Feature type = %s\n", f->name);
01401 E_INFO_NOFN("Cepstral size = %d\n", f->cepsize);
01402 E_INFO_NOFN("Number of streams = %d\n", f->n_stream);
01403 for (i = 0; i < f->n_stream; i++) {
01404 E_INFO_NOFN("Vector size of stream[%d]: %d\n", i,
01405 f->stream_len[i]);
01406 }
01407 E_INFO_NOFN("Number of subvectors = %d\n", f->n_sv);
01408 for (i = 0; i < f->n_sv; i++) {
01409 int32 *sv;
01410
01411 E_INFO_NOFN("Components of subvector[%d]:", i);
01412 for (sv = f->subvecs[i]; sv && *sv != -1; ++sv)
01413 E_INFOCONT(" %d", *sv);
01414 E_INFOCONT("\n");
01415 }
01416 E_INFO_NOFN("Whether CMN is used = %d\n", f->cmn);
01417 E_INFO_NOFN("Whether AGC is used = %d\n", f->agc);
01418 E_INFO_NOFN("Whether variance is normalized = %d\n", f->varnorm);
01419 E_INFO_NOFN("\n");
01420 }