Main Page | Modules | Data Structures | Directories | File List | Data Fields | Globals | Related Pages

realtime-1stpass.c

Go to the documentation of this file.
00001 
00116 /*
00117  * Copyright (c) 1991-2006 Kawahara Lab., Kyoto University
00118  * Copyright (c) 2000-2005 Shikano Lab., Nara Institute of Science and Technology
00119  * Copyright (c) 2005-2006 Julius project team, Nagoya Institute of Technology, Nagoya Institute of Technology
00120  * All rights reserved
00121  */
00122 
00123 #include <julius.h>
00124 
00125 #undef RDEBUG                   
00126 
00127 /* MFCC parameter */
00128 static HTK_Param *param = NULL; 
00129 static Value para;              
00130 static float *bf;               
00131 static DeltaBuf *db;            
00132 static DeltaBuf *ab;            
00133 static VECT *tmpmfcc;           
00134 static int maxframelen;         
00135 static int last_time;           
00136 
00137 static boolean last_is_segmented; 
00138 #ifdef SP_BREAK_CURRENT_FRAME
00139 static SP16 *rest_Speech = NULL; 
00140 static int rest_alloc_len = 0;  
00141 static int rest_len;            
00142 #endif
00143 
00144 static int f_raw;               
00145 static int f;                   
00146 static SP16 *window;            
00147 static int windowlen;           
00148 static int windownum;           
00149 
00150 
00151 /* init_para() moved to wav2mfcc.c */
00152 
00153 /* 計算結果の MFCC を保存する param 構造体を準備する
00154    これは1回の認識ごとに繰り返し呼ばれる */
00155 /* prepare new parameter vector holder for RealTime*
00156    This will be called each time a recognition begins */
00168 static void
00169 init_param()
00170 {
00171   /* param 構造体を新たにアロケート */
00172   /* allocate parameter data */
00173   param = new_param();
00174   /* これから計算されるパラメータの型をヘッダに設定 */
00175   /* set header types */
00176   param->header.samptype = F_MFCC;
00177   if (para.delta) param->header.samptype |= F_DELTA;
00178   if (para.acc) param->header.samptype |= F_ACCL;
00179   if (para.energy) param->header.samptype |= F_ENERGY;
00180   if (para.c0) param->header.samptype |= F_ZEROTH;
00181   if (para.absesup) param->header.samptype |= F_ENERGY_SUP;
00182   if (para.cmn) param->header.samptype |= F_CEPNORM;
00183 
00184   param->header.wshift = para.smp_period * para.frameshift;
00185   param->header.sampsize = para.veclen * sizeof(VECT); /* not compressed */
00186   param->veclen = para.veclen;
00187   /* フレームごとのパラメータベクトル保存のためのヘッダ領域を確保 */
00188   /* 最大時間分を固定でアロケート */
00189   /* assign max (safe with free_param)*/
00190   param->parvec = (VECT **)mymalloc(sizeof(VECT *) * maxframelen);
00191   /* 認識処理中/終了後にセットされる変数:
00192      param->parvec (パラメータベクトル系列)
00193      param->header.samplenum, param->samplenum (全フレーム数)
00194   */
00195   /* variables that will be set while/after computation has been done:
00196      param->parvec (parameter vector sequence)
00197      param->header.samplenum, param->samplenum (total number of frames)
00198   */
00199 }
00200 
00210 void
00211 RealTimeInit()
00212 {
00213   /* MFCC計算用パラメータをセット */
00214   /* initialize MFCC computation */
00215   init_para(&para);
00216   /* -ssload 指定時, SS用のノイズスペクトルをファイルから読み込む */
00217   /* if "-ssload", load noise spectrum for spectral subtraction from file */
00218   if (ssload_filename && ssbuf == NULL) {
00219     if ((ssbuf = new_SS_load_from_file(ssload_filename, &sslen)) == NULL) {
00220       j_error("Error: failed to read \"%s\"\n", ssload_filename);
00221     }
00222   }
00223   /* MFCC計算関数を初期化 */
00224   /* initialize MFCC computation functions */
00225   WMP_init(para, &bf, ssbuf, sslen);
00226   /* デルタ計算のためのサイクルバッファを用意 */
00227   /* initialize cycle buffers for delta and accel coef. computation */
00228   if (para.delta) db = WMP_deltabuf_new(para.baselen, para.delWin);
00229   if (para.acc) ab = WMP_deltabuf_new(para.baselen * 2, para.accWin);
00230   /* デルタ計算のためのワークエリアを確保 */
00231   /* allocate work area for the delta computation */
00232   tmpmfcc = (VECT *)mymalloc(sizeof(VECT) * para.vecbuflen);
00233   /* 最大フレーム長を最大入力時間数から計算 */
00234   /* set maximum allowed frame length */
00235   maxframelen = MAXSPEECHLEN / para.frameshift;
00236   /* 窓長をセット */
00237   /* set window length */
00238   windowlen = para.framesize + 1;
00239   /* 窓かけ用バッファを確保 */
00240   /* set window buffer */
00241   window = mymalloc(sizeof(SP16) * windowlen);
00242   /* MAP-CMN 用の初期ケプストラム平均を読み込んで初期化する */
00243   /* Initialize the initial cepstral mean data from file for MAP-CMN */
00244   if (para.cmn) CMN_realtime_init(para.mfcc_dim, cmn_map_weight);
00245   /* -cmnload 指定時, CMN用のケプストラム平均の初期値をファイルから読み込む */
00246   /* if "-cmnload", load initial cepstral mean data from file for CMN */
00247   if (cmnload_filename) {
00248     if (para.cmn) {
00249       if ((cmn_loaded = CMN_load_from_file(cmnload_filename, para.mfcc_dim))== FALSE) {
00250         j_printf("Warning: failed to read cepstral mean from \"%s\"\n", cmnload_filename);
00251       }
00252     } else {
00253       j_printf("Warning: CMN not required, file \"%s\" ignored\n", cmnload_filename);
00254     }
00255   }
00256 }
00257 
00258 /* ON-THE-FLY デコーディング関数: 準備 (認識開始時ごとに呼ばれる) */
00259 /* ON-THE-FLY DECODING FUNCTION: prepare (on start of every input segment) */
00269 void
00270 RealTimePipeLinePrepare()
00271 {
00272   /* 計算結果の MFCC を保存する param 構造体を準備する */
00273   /* prepare param to hold the resulting MFCC parameters */
00274   init_param();
00275   /* デルタ計算用バッファを準備 */
00276   /* set the delta cycle buffer */
00277   if (para.delta) WMP_deltabuf_prepare(db);
00278   if (para.acc) WMP_deltabuf_prepare(ab);
00279   /* 音響尤度計算用キャッシュを準備
00280      最大長をここであらかじめ確保してしまう */
00281   /* prepare cache area for acoustic computation of HMM states and mixtures
00282      pre-fetch for maximum length here */
00283   outprob_prepare(maxframelen);
00284   /* 準備した param 構造体のデータのパラメータ型を音響モデルとチェックする */
00285   /* check type coherence between param and hmminfo here */
00286   if (!check_param_coherence(hmminfo, param)) {
00287     j_error("parameter type not match?\n");
00288   }
00289   /* 計算用の変数を初期化 */
00290   /* initialize variables for computation */
00291   f_raw = 0;
00292   f = 0;
00293   windownum = 0;
00294 
00295   /* MAP-CMN の初期化 */
00296   /* Prepare for MAP-CMN */
00297   if (para.cmn) CMN_realtime_prepare();
00298 
00299   /* -record 指定時, 音声データを保存するファイルをここで開く */
00300   /* if "-record", open the file to write the incoming speech data here */
00301   if (record_dirname != NULL) {
00302     record_sample_open();
00303   }
00304   
00305 #ifdef VISUALIZE
00306   /* 音声波形の画面出力用に, 音声データを別に保存する.
00307      ここではポインタを初期化するのみ   */
00308   /* record data for waveform printing */
00309   speechlen = 0;
00310 #endif
00311 }
00312 
00351 int
00352 RealTimePipeLine(SP16 *Speech, int nowlen) /* Speech[0...nowlen] = input */
00353 {
00354   int i, now;
00355   boolean ret;
00356 
00357   /* window[0..windownum-1] は前回の呼び出しで残った音声データが格納されている */
00358   /* window[0..windownum-1] are speech data left from previous call */
00359 
00360   /* 処理用ポインタを初期化 */
00361   /* initialize pointer for local processing */
00362   now = 0;
00363   
00364   /* 認識処理がセグメント要求で終わったのかどうかのフラグをリセット */
00365   /* reset flag which indicates whether the input has ended with segmentation request */
00366   last_is_segmented = FALSE;
00367 
00368   /* 初めて呼び出されたときに, 認識開始のメッセージを出力 */
00369   /* If this is the first call, output start recording/processing message */
00370   if (f_raw == 0) status_recstart();
00371 
00372 #ifdef RDEBUG
00373   printf("got %d samples\n", nowlen);
00374 #endif
00375 
00376   /* -record 時, 音声データをファイルに追加する */
00377   /* if "-record", append the incoming samples to a file */
00378   if (record_dirname != NULL) {
00379     record_sample_write(Speech, nowlen);
00380   }
00381 
00382 #ifdef VISUALIZE
00383   /* record data for waveform printing */
00384   adin_cut_callback_store_buffer(Speech, nowlen);
00385 #endif
00386 
00387   while (now < nowlen) {        /* till whole input is processed */
00388     /* 入力長が maxframelen に達したらここで強制終了 */
00389     /* if input length reaches maximum buffer size, terminate 1st pass here */
00390     if (f_raw >= maxframelen) return(1);
00391     /* 窓バッファを埋められるだけ埋める */
00392     /* fill window buffer as many as possible */
00393     for(i = min(windowlen - windownum, nowlen - now); i > 0 ; i--)
00394       window[windownum++] = (float) Speech[now++];
00395     /* もし窓バッファが埋まらなければ, このセグメントの処理はここで終わる.
00396        処理されなかったサンプル (window[0..windownum-1]) は次回に持ち越し.*/
00397     /* if window buffer was not filled, end processing here, keeping the
00398        rest samples (window[0..windownum-1]) in the window buffer. */
00399     if (windownum < windowlen) break;
00400 #ifdef RDEBUG
00401     /*    printf("%d used, %d rest\n", now, nowlen - now);
00402 
00403           printf("[f_raw = %d, f = %d]\n", f_raw, f);*/
00404 #endif
00405 
00406     /* 音声波形から base MFCC を計算 */
00407     /* calculate base MFCC from waveform */
00408     for (i=0; i < windowlen; i++) {
00409       bf[i+1] = (float) window[i];
00410     }
00411     WMP_calc(tmpmfcc, bf, para, ssbuf);
00412 
00413     if (para.delta) {
00414       /* デルタを計算する */
00415       /* calc delta coefficients */
00416       ret = WMP_deltabuf_proceed(db, tmpmfcc);
00417 #ifdef RDEBUG
00418       printf("DeltaBuf: ret=%d, status=", ret);
00419       for(i=0;i<db->len;i++) {
00420         printf("%d", db->is_on[i]);
00421       }
00422       printf(", nextstore=%d\n", db->store);
00423 #endif
00424       /* ret == FALSE のときはまだディレイ中なので認識処理せず次入力へ */
00425       /* if ret == FALSE, there is no available frame.  So just wait for
00426          next input */
00427       if (! ret) {
00428         goto next_input;
00429       }
00430       /* db->vec に現在の元データとデルタ係数が入っているので tmpmfcc にコピー */
00431       /* now db->vec holds the current base and full delta, so copy them to tmpmfcc */
00432       memcpy(tmpmfcc, db->vec, sizeof(VECT) * para.baselen * 2);
00433     }
00434 
00435     if (para.acc) {
00436       /* Accelerationを計算する */
00437       /* calc acceleration coefficients */
00438       /* base+delta をそのまま入れる */
00439       /* send the whole base+delta to the cycle buffer */
00440       ret = WMP_deltabuf_proceed(ab, tmpmfcc);
00441 #ifdef RDEBUG
00442       printf("AccelBuf: ret=%d, status=", ret);
00443       for(i=0;i<ab->len;i++) {
00444         printf("%d", ab->is_on[i]);
00445       }
00446       printf(", nextstore=%d\n", ab->store);
00447 #endif
00448       /* ret == FALSE のときはまだディレイ中なので認識処理せず次入力へ */
00449       /* if ret == FALSE, there is no available frame.  So just wait for
00450          next input */
00451       if (! ret) {
00452         goto next_input;
00453       }
00454       /* ab->vec には,(base+delta) とその差分係数が入っている.
00455          [base] [delta] [delta] [acc] の順で入っているので,
00456          [base] [delta] [acc] を tmpmfcc にコピーする.*/
00457       /* now ab->vec holds the current (base+delta) and their delta coef. 
00458          it holds a vector in the order of [base] [delta] [delta] [acc], 
00459          so copy the [base], [delta] and [acc] to tmpmfcc.  */
00460       memcpy(tmpmfcc, ab->vec, sizeof(VECT) * para.baselen * 2);
00461       memcpy(&(tmpmfcc[para.baselen*2]), &(ab->vec[para.baselen*3]), sizeof(VECT) * para.baselen);
00462     }
00463 
00464     if (para.delta && para.energy && para.absesup) {
00465       /* 絶対値パワーを除去 */
00466       /* suppress absolute power */
00467       memmove(&(tmpmfcc[para.baselen-1]), &(tmpmfcc[para.baselen]), sizeof(VECT) * (para.vecbuflen - para.baselen));
00468     }
00469 
00470     /* この時点で tmpmfcc に現時点での最新の特徴ベクトルが格納されている */
00471     /* tmpmfcc[] now holds the latest parameter vector */
00472 
00473 #ifdef RDEBUG
00474       printf("DeltaBuf: got frame %d\n", f_raw);
00475 #endif
00476       /* CMN を計算 */
00477       /* perform CMN */
00478       if (para.cmn) CMN_realtime(tmpmfcc, para.mfcc_dim);
00479 
00480       /* MFCC完成,登録 */
00481       /* now get the MFCC vector of current frame, now store it to param */
00482       param->parvec[f_raw] = (VECT *)mymalloc(sizeof(VECT) * param->veclen);
00483       memcpy(param->parvec[f_raw], tmpmfcc, sizeof(VECT) * param->veclen);
00484       f = f_raw;
00485 
00486       /* ここでフレーム "f" に最新のMFCCが保存されたことになる */
00487       /* now we got the most recent MFCC parameter for frame 'f' */
00488       /* この "f" のフレームについて認識処理(フレーム同期ビーム探索)を進める */
00489       /* proceed beam search for this frame [f] */
00490       if (f == 0) {
00491         /* 最初のフレーム: 探索処理を初期化 */
00492         /* initial frame: initialize search process */
00493         get_back_trellis_init(param, wchmm, &backtrellis);
00494       }
00495 #ifndef MULTIPATH_VERSION
00496       if (f != 0) {
00497 #endif
00498         /* 1フレーム探索を進める */
00499         /* proceed search for 1 frame */
00500         if (get_back_trellis_proceed(f, param, wchmm, &backtrellis
00501 #ifdef MULTIPATH_VERSION
00502                                      ,FALSE
00503 #endif
00504                                      ) == FALSE) {
00505           /* 探索処理の終了が発生したのでここで認識を終える.
00506              最初のフレームから [f-1] 番目までが認識されたことになる
00507           */
00508           /* the recognition process tells us to stop recognition, so
00509              recognition should be terminated here.
00510              the recognized data are [0..f-1] */
00511           /* 認識処理は f-1 で終わったが, MFCCの計算は f まで,初期のMFCC計算
00512              は f_raw まで進んでいることに注意: 後で再開処理が必要*/
00513           /* notice: recognition process has done for "f-1" frame, but MFCC
00514              computation has already done for "f", and first 12-dim. MFCC
00515              has been alsp computed till "f_raw".  Some restarting operation
00516              is needed later */
00517 
00518           /* 認識処理のセグメント要求で終わったことをフラグにセット */
00519           /* set flag which indicates that the input has ended with segmentation request */
00520           last_is_segmented = TRUE;
00521           /* 最終フレームを last_time にセット */
00522           /* set the last frame to last_time */
00523           last_time = f-1;
00524 #ifdef SP_BREAK_CURRENT_FRAME
00525           /* ショートポーズセグメンテーション: バッファに残っているデータを
00526              別に保持して,次回の最初に処理する */
00527           /* short pause segmentation: there is some data left in buffer, so
00528            we should keep them for next processing */
00529           param->header.samplenum = f_raw+1;/* len = lastid + 1 */
00530           param->samplenum = f_raw+1;
00531           rest_len = nowlen - now;
00532           if (rest_len > 0) {
00533             /* copy rest samples to rest_Speech */
00534             if (rest_Speech == NULL) {
00535               rest_alloc_len = rest_len;
00536               rest_Speech = (SP16 *)mymalloc(sizeof(SP16)*rest_alloc_len);
00537             } else if (rest_alloc_len < rest_len) {
00538               rest_alloc_len = rest_len;
00539               rest_Speech = (SP16 *)myrealloc(rest_Speech, sizeof(SP16)*rest_alloc_len);
00540             }
00541             memcpy(rest_Speech, &(Speech[now]), sizeof(SP16) * rest_len);
00542           }
00543 #else
00544           /* param に格納されたフレーム長をセット */
00545           /* set number of frames to param */
00546           param->header.samplenum = f;
00547           param->samplenum = f;
00548 #endif
00549           /* tell the caller to be segmented by this function */
00550           /* 呼び出し元に,ここで入力を切るよう伝える */
00551           return(1);
00552         }
00553 #ifndef MULTIPATH_VERSION
00554       }
00555 #endif
00556       /* 1フレーム処理が進んだのでポインタを進める */
00557       /* proceed frame pointer */
00558       f_raw++;
00559 
00560   next_input:
00561 
00562     /* 窓バッファを処理が終わった分シフト */
00563     /* shift window */
00564     memmove(window, &(window[para.frameshift]), sizeof(SP16) * (windowlen - para.frameshift));
00565     windownum -= para.frameshift;
00566   }
00567 
00568   /* 与えられた音声セグメントに対する認識処理が全て終了
00569      呼び出し元に, 入力を続けるよう伝える */
00570   /* input segment is fully processed
00571      tell the caller to continue input */
00572   return(0);                    
00573 }
00574 
00575 #ifdef SP_BREAK_CURRENT_FRAME
00576 
00610 int
00611 RealTimeResume()
00612 {
00613   int t;
00614 
00615   /* rest_param に最後のsp区間のパラメータが入っている */
00616   /* rest_param holds the last MFCC parameters */
00617   param = rest_param;
00618 
00619   /* paramを準備 */
00620   /* prepare param by expanding the last input param */
00621   outprob_prepare(maxframelen);
00622   param->parvec = (VECT **)myrealloc(param->parvec, sizeof(VECT *) * maxframelen);
00623   /* param にある全パラメータを処理する: f_raw をあらかじめセット */
00624   /* process all data in param: pre-set the resulting f_raw */
00625   f_raw = param->samplenum - 1;
00626 
00627   /* param 内の全フレームについて認識処理を進める */
00628   /* proceed recognition for all frames in param */
00629   if (f_raw >= 0) {
00630     f = f_raw;
00631 #ifdef RDEBUG
00632     printf("Resume: f=%d,f_raw=%d\n", f, f_raw);
00633 #endif
00634     get_back_trellis_init(param, wchmm, &backtrellis);
00635     for (t=
00636 #ifdef MULTIPATH_VERSION
00637            0
00638 #else
00639            1
00640 #endif
00641            ;t<=f;t++) {
00642       if (get_back_trellis_proceed(t, param, wchmm, &backtrellis
00643 #ifdef MULTIPATH_VERSION
00644                                    ,FALSE
00645 #endif
00646                                    ) == FALSE) {
00647         /* segmented, end procs ([0..f])*/
00648         last_is_segmented = TRUE;
00649         last_time = t-1;
00650         return(1);              /* segmented by this function */
00651       }
00652     }
00653   }
00654 
00655   f_raw++;
00656   f = f_raw;
00657 
00658   /* シフトしておく */
00659   /* do last shift */
00660   memmove(window, &(window[para.frameshift]), sizeof(SP16) * (windowlen - para.frameshift));
00661   windownum -= para.frameshift;
00662 
00663   /* これで再開の準備が整ったので,まずは前回の処理で残っていた音声データから
00664      処理する */
00665   /* now that the search status has been prepared for the next input, we
00666      first process the rest unprocessed samples at the last session */
00667   if (rest_len > 0) {
00668 #ifdef RDEBUG
00669     printf("Resume: rest %d samples\n", rest_len);
00670 #endif
00671     return(RealTimePipeLine(rest_Speech, rest_len));
00672   }
00673 
00674   /* 新規の入力に対して認識処理は続く… */
00675   /* the recognition process will continue for the newly incoming samples... */
00676   return 0;
00677 }
00678 #endif /* SP_BREAK_CURRENT_FRAME */
00679 
00680 
00681 /* ON-THE-FLY デコーディング関数: 終了処理 */
00682 /* ON-THE-FLY DECODING FUNCTION: end processing */
00699 HTK_Param *
00700 RealTimeParam(LOGPROB *backmax)
00701 {
00702   boolean ret1, ret2;
00703 
00704   if (last_is_segmented) {
00705     /* RealTimePipeLine で認識処理側の理由により認識が中断した場合,
00706        現状態のMFCC計算データをそのまま次回へ保持する必要があるので,
00707        MFCC計算終了処理を行わずに第1パスの結果のみ出力して終わる.*/
00708     /* When input segmented by recognition process in RealTimePipeLine(),
00709        we have to keep the whole current status of MFCC computation to the
00710        next call.  So here we only output the 1st pass result. */
00711     *backmax = finalize_1st_pass(&backtrellis, winfo, last_time);
00712 #ifdef SP_BREAK_CURRENT_FRAME
00713     finalize_segment(&backtrellis, param, last_time);
00714 #endif
00715     /* この区間の param データを第2パスのために返す */
00716     /* return obtained parameter for 2nd pass */
00717     return(param);
00718   }
00719 
00720   /* MFCC計算の終了処理を行う: 最後の遅延フレーム分を処理 */
00721   /* finish MFCC computation for the last delayed frames */
00722 
00723   if (para.delta || para.acc) {
00724 
00725     /* look until all data has been flushed */
00726     while(1) {
00727 
00728       /* check if there is data in cycle buffer of delta */
00729       ret1 = WMP_deltabuf_flush(db);
00730 #ifdef RDEBUG
00731       {
00732         int i;
00733         printf("DeltaBufLast: ret=%d, status=", ret1);
00734         for(i=0;i<db->len;i++) {
00735           printf("%d", db->is_on[i]);
00736         }
00737         printf(", nextstore=%d\n", db->store);
00738       }
00739 #endif
00740       if (ret1) {
00741         /* uncomputed delta has flushed, compute it with tmpmfcc */
00742         if (para.energy && para.absesup) {
00743           memcpy(tmpmfcc, db->vec, sizeof(VECT) * (para.baselen - 1));
00744           memcpy(&(tmpmfcc[para.baselen-1]), &(db->vec[para.baselen]), sizeof(VECT) * para.baselen);
00745         } else {
00746           memcpy(tmpmfcc, db->vec, sizeof(VECT) * para.baselen * 2);
00747         }
00748         if (para.acc) {
00749           /* this new delta should be given to the accel cycle buffer */
00750           ret2 = WMP_deltabuf_proceed(ab, tmpmfcc);
00751 #ifdef RDEBUG
00752           printf("AccelBuf: ret=%d, status=", ret2);
00753           for(i=0;i<ab->len;i++) {
00754             printf("%d", ab->is_on[i]);
00755           }
00756           printf(", nextstore=%d\n", ab->store);
00757 #endif
00758           if (ret2) {
00759             /* uncomputed accel was given, compute it with tmpmfcc */
00760             memcpy(tmpmfcc, ab->vec, sizeof(VECT) * (para.veclen - para.baselen));
00761             memcpy(&(tmpmfcc[para.veclen - para.baselen]), &(ab->vec[para.veclen - para.baselen]), sizeof(VECT) * para.baselen);
00762           } else {
00763             /* no input is still available: */
00764             /* in case of very short input: go on to the next input */
00765             continue;
00766           }
00767         }
00768       } else {
00769         /* no data left in the delta buffer */
00770         if (para.acc) {
00771           /* no new data, just flush the accel buffer */
00772           ret2 = WMP_deltabuf_flush(ab);
00773 #ifdef RDEBUG
00774           printf("AccelBuf: ret=%d, status=", ret2);
00775           for(i=0;i<ab->len;i++) {
00776             printf("%d", ab->is_on[i]);
00777           }
00778           printf(", nextstore=%d\n", ab->store);
00779 #endif
00780           if (ret2) {
00781             /* uncomputed data has flushed, compute it with tmpmfcc */
00782             memcpy(tmpmfcc, ab->vec, sizeof(VECT) * (para.veclen - para.baselen));
00783             memcpy(&(tmpmfcc[para.veclen - para.baselen]), &(ab->vec[para.veclen - para.baselen]), sizeof(VECT) * para.baselen);
00784           } else {
00785             /* actually no data exists in both delta and accel */
00786             break;              /* end this loop */
00787           }
00788         } else {
00789           /* only delta: input fully flushed, end this loop */
00790           break;
00791         }
00792       }
00793       if(para.cmn) CMN_realtime(tmpmfcc, para.mfcc_dim);
00794       param->parvec[f_raw] = (VECT *)mymalloc(sizeof(VECT) * param->veclen);
00795       memcpy(param->parvec[f_raw], tmpmfcc, sizeof(VECT) * param->veclen);
00796       f = f_raw;
00797       if (f == 0) {
00798         get_back_trellis_init(param, wchmm, &backtrellis);
00799       }
00800 #ifdef MULTIPATH_VERSION
00801       get_back_trellis_proceed(f, param, wchmm, &backtrellis, FALSE);
00802 #else
00803       if (f != 0) {
00804         get_back_trellis_proceed(f, param, wchmm, &backtrellis);
00805       }
00806 #endif
00807       f_raw++;
00808     }
00809   }
00810 
00811   /* フレーム長をセット */
00812   /* set frame length */
00813   param->header.samplenum = f_raw;
00814   param->samplenum = f_raw;
00815 
00816   /* 入力長がデルタの計算に十分でない場合,
00817      MFCC が CMN まで正しく計算できないため,エラー終了とする.*/
00818   /* if input is short for compute all the delta coeff., terminate here */
00819   if (f_raw == 0) {
00820     j_printf("Error: too short input to compute delta coef! (%d frames)\n", f_raw);
00821     *backmax = finalize_1st_pass(&backtrellis, winfo, param->samplenum);
00822   } else {
00823     /* 第1パスの終了処理を行う */
00824     /* finalize 1st pass */
00825     get_back_trellis_end(param, wchmm, &backtrellis);
00826     *backmax = finalize_1st_pass(&backtrellis, winfo, param->samplenum);
00827 #ifdef SP_BREAK_CURRENT_FRAME
00828     finalize_segment(&backtrellis, param, param->samplenum);
00829 #endif
00830   }
00831 
00832   /* この区間の param データを第2パスのために返す */
00833   /* return obtained parameter for 2nd pass */
00834   return(param);
00835 }
00836 
00849 void
00850 RealTimeCMNUpdate(HTK_Param *param)
00851 {
00852   float mseclen;
00853   boolean cmn_update_p;
00854   
00855   /* update CMN vector for next speech */
00856   if(para.cmn) {
00857     if (cmn_update) {
00858       cmn_update_p = TRUE;
00859       if (rejectshortlen > 0) {
00860         /* not update if rejected by short input */
00861         mseclen = (float)param->samplenum * (float)smpPeriod * (float)fshift / 10000.0;
00862         if (mseclen < rejectshortlen) {
00863           cmn_update_p = FALSE;
00864         }
00865       }
00866       if (gmm_reject_cmn_string != NULL) {
00867         /* if using gmm, try avoiding update of CMN for noise input */
00868         if(! gmm_valid_input()) {
00869           cmn_update_p = FALSE;
00870         }
00871       }
00872       if (cmn_update_p) {
00873         /* update last CMN parameter for next spech */
00874         CMN_realtime_update();
00875       } else {
00876         /* do not update, because the last input is bogus */
00877         j_printf("CMN not updated\n");
00878       }
00879     }
00880     /* if needed, save the updated CMN parameter to a file */
00881     if (cmnsave_filename) {
00882       if (CMN_save_to_file(cmnsave_filename) == FALSE) {
00883         j_printf("Warning: failed to save cmn data to \"%s\"\n", cmnsave_filename);
00884       }
00885     }
00886   }
00887 }
00888 
00897 void
00898 RealTimeTerminate()
00899 {
00900   param->header.samplenum = f_raw;
00901   param->samplenum = f_raw;
00902 
00903   /* 入力長がデルタの計算に十分でない場合,
00904      MFCC が CMN まで正しく計算できないため,エラー終了とする.*/
00905   /* if input is short for compute all the delta coeff., terminate here */
00906   if (f_raw == 0) {
00907     finalize_1st_pass(&backtrellis, winfo, param->samplenum);
00908   } else {
00909     /* 第1パスの終了処理を行う */
00910     /* finalize 1st pass */
00911     status_recend();
00912     get_back_trellis_end(param, wchmm, &backtrellis);
00913     finalize_1st_pass(&backtrellis, winfo, param->samplenum);
00914 #ifdef SP_BREAK_CURRENT_FRAME
00915     finalize_segment(&backtrellis, param, param->samplenum);
00916 #endif
00917   }
00918   /* パラメータを解放 */
00919   /* free parameter */
00920   free_param(param);
00921 }

Generated on Tue Mar 28 16:01:38 2006 for Julius by  doxygen 1.4.2