PocketSphinx  0.6
src/libpocketsphinx/hmm.h
Go to the documentation of this file.
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 1999-2004 Carnegie Mellon University.  All rights
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  */
00037 
00042 #ifndef __HMM_H__
00043 #define __HMM_H__
00044 
00045 /* System headers. */
00046 #include <stdio.h>
00047 
00048 /* SphinxBase headers. */
00049 #include <sphinxbase/fixpoint.h>
00050 #include <sphinxbase/listelem_alloc.h>
00051 
00052 /* PocketSphinx headers. */
00053 #include "bin_mdef.h"
00054 
00055 #ifdef __cplusplus
00056 extern "C" {
00057 #endif
00058 #if 0
00059 } /* Fool Emacs into not indenting things. */
00060 #endif
00061 
00063 #define SENSCR_SHIFT 10
00064 
00074 #define WORST_SCORE             ((int)0xE0000000)
00075 
00080 #define TMAT_WORST_SCORE        (-255)
00081 
00085 #define BETTER_THAN >
00086 
00090 #define WORSE_THAN <
00091 
00136 typedef struct hmm_context_s {
00137     int32 n_emit_state;     
00138     uint8 ** const *tp;     
00139     int16 const *senscore;  
00141     uint16 * const *sseq;   
00142     int32 *st_sen_scr;      
00143     listelem_alloc_t *mpx_ssid_alloc; 
00144     void *udata;            
00145 } hmm_context_t;
00146 
00150 #define HMM_MAX_NSTATE 5
00151 
00160 typedef struct hmm_s {
00161     hmm_context_t *ctx;            
00162     int32 score[HMM_MAX_NSTATE];   
00163     int32 history[HMM_MAX_NSTATE]; 
00164     int32 out_score;               
00165     int32 out_history;             
00166     uint16 ssid;                   
00167     uint16 senid[HMM_MAX_NSTATE];  
00168     int32 bestscore;    
00169     int16 tmatid;       
00170     int16 frame;        
00171     uint8 mpx;          
00172     uint8 n_emit_state; 
00173 } hmm_t;
00174 
00176 #define hmm_context(h) (h)->ctx
00177 #define hmm_is_mpx(h) (h)->mpx
00178 
00179 #define hmm_in_score(h) (h)->score[0]
00180 #define hmm_score(h,st) (h)->score[st]
00181 #define hmm_out_score(h) (h)->out_score
00182 
00183 #define hmm_in_history(h) (h)->history[0]
00184 #define hmm_history(h,st) (h)->history[st]
00185 #define hmm_out_history(h) (h)->out_history
00186 
00187 #define hmm_bestscore(h) (h)->bestscore
00188 #define hmm_frame(h) (h)->frame
00189 #define hmm_mpx_ssid(h,st) (h)->senid[st]
00190 #define hmm_nonmpx_ssid(h) (h)->ssid
00191 #define hmm_ssid(h,st) (hmm_is_mpx(h)                                   \
00192                         ? hmm_mpx_ssid(h,st) : hmm_nonmpx_ssid(h))
00193 #define hmm_mpx_senid(h,st) (hmm_mpx_ssid(h,st) == BAD_SENID \
00194                              ? BAD_SENID : (h)->ctx->sseq[hmm_mpx_ssid(h,st)][st])
00195 #define hmm_nonmpx_senid(h,st) ((h)->senid[st])
00196 #define hmm_senid(h,st) (hmm_is_mpx(h)                                  \
00197                          ? hmm_mpx_senid(h,st) : hmm_nonmpx_senid(h,st))
00198 #define hmm_senscr(h,st) (hmm_senid(h,st) == BAD_SENID                  \
00199                           ? WORST_SCORE                                 \
00200                           : -(h)->ctx->senscore[hmm_senid(h,st)])
00201 #define hmm_tmatid(h) (h)->tmatid
00202 #define hmm_tprob(h,i,j) (-(h)->ctx->tp[hmm_tmatid(h)][i][j])
00203 #define hmm_n_emit_state(h) ((h)->n_emit_state)
00204 #define hmm_n_state(h) ((h)->n_emit_state + 1)
00205 
00209 hmm_context_t *hmm_context_init(int32 n_emit_state,
00210                                 uint8 ** const *tp,
00211                                 int16 const *senscore,
00212                                 uint16 * const *sseq);
00213 
00217 #define hmm_context_set_senscore(ctx, senscr) ((ctx)->senscore = (senscr))
00218 
00226 void hmm_context_free(hmm_context_t *ctx);
00227 
00231 void hmm_init(hmm_context_t *ctx, hmm_t *hmm, int mpx, int ssid, int tmatid);
00232 
00236 void hmm_deinit(hmm_t *hmm);
00237 
00243 void hmm_clear(hmm_t *h);
00244 
00248 void hmm_clear_scores(hmm_t *h);
00249 
00253 void hmm_normalize(hmm_t *h, int32 bestscr);
00254 
00258 void hmm_enter(hmm_t *h, int32 score,
00259                int32 histid, int frame);
00260 
00273 int32 hmm_vit_eval(hmm_t *hmm);
00274   
00275 
00279 int32 hmm_dump_vit_eval(hmm_t *hmm,  
00280                         FILE *fp 
00281     );
00282 
00287 void hmm_dump(hmm_t *h,  
00288               FILE *fp 
00289     );
00290 
00291 
00292 #if 0
00293 { /* Stop indent from complaining */
00294 #endif
00295 #ifdef __cplusplus
00296 }
00297 #endif
00298 
00299 #endif /* __HMM_H__ */