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