Initial import to Tizen
[profile/ivi/pocketsphinx.git] / src / libpocketsphinx / bin_mdef.h
1 /* -*- c-file-style: "linux" -*- */
2 /* ====================================================================
3  * Copyright (c) 2005 Carnegie Mellon University.  All rights 
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 /**
38  * @file bin_mdef.h
39  * 
40  * Binary format model definition files, with support for
41  * heterogeneous topologies and variable-size N-phones
42  *
43  * @author David Huggins-Daines <dhuggins@cs.cmu.edu>
44  */
45 #ifndef __BIN_MDEF_H__
46 #define __BIN_MDEF_H__
47
48 #ifdef __cplusplus
49 extern "C" {
50 #if 0
51 }; /* Fool Emacs */
52 #endif
53 #endif /* __cplusplus */
54
55 /* SphinxBase headers. */
56 #include <sphinxbase/mmio.h>
57 #include <sphinxbase/cmd_ln.h>
58
59 #include "mdef.h"
60
61 #define BIN_MDEF_FORMAT_VERSION 1
62 /* Little-endian machines will write "BMDF" to disk, big-endian ones "FDMB". */
63 #define BIN_MDEF_NATIVE_ENDIAN 0x46444d42 /* 'BMDF' in little-endian order */
64 #define BIN_MDEF_OTHER_ENDIAN 0x424d4446  /* 'BMDF' in big-endian order */
65 #ifdef __GNUC__
66 #define ATTRIBUTE_PACKED __attribute__((packed))
67 #else
68 #define ATTRIBUTE_PACKED
69 #endif
70
71 /**
72  * Phone entry (on-disk, 12 bytes)
73  */
74 typedef struct mdef_entry_s mdef_entry_t;
75 struct mdef_entry_s {
76         int32 ssid; /**< Senone sequence ID */
77         int32 tmat; /**< Transition matrix ID */
78         /* FIXME: is any of this actually necessary? */
79         union {
80                 /**< CI phone information - attributes (just "filler" for now) */
81                 struct {
82                         int8 filler;
83                         int8 reserved[3];
84                 } ci;
85                 /**< CD phone information - context info. */
86                 struct {
87                         int8 wpos;
88                         int8 ctx[3]; /**< quintphones will require hacking */
89                 } cd;
90         } info;
91 } ATTRIBUTE_PACKED;
92
93 /**
94  * Invalid senone sequence ID (limited to 16 bits for PocketSphinx).
95  */
96 #define BAD_SSID 0xffff
97 /**
98  * Invalid senone ID (limited to 16 bits for PocketSphinx).
99  */
100 #define BAD_SENID 0xffff
101
102 /**
103  * Node in CD phone tree (on-disk, 8 bytes).
104  */
105 typedef struct cd_tree_s cd_tree_t;
106 struct cd_tree_s {
107         int16 ctx; /**< Context (word position or CI phone) */
108         int16 n_down; /**< Number of children (0 for leafnode) */
109         union {
110                 int32 pid; /**< Phone ID (leafnode) */
111                 int32 down; /**< Next level of the tree (offset from start of cd_trees) */ 
112         } c;
113 };
114
115 /**
116  * Model definition structure (in-memory).
117  */
118 typedef struct bin_mdef_s bin_mdef_t;
119 struct bin_mdef_s {
120         int refcnt;
121         int32 n_ciphone;    /**< Number of base (CI) phones */
122         int32 n_phone;      /**< Number of base (CI) phones + (CD) triphones */
123         int32 n_emit_state; /**< Number of emitting states per phone (0 for heterogeneous) */
124         int32 n_ci_sen;     /**< Number of CI senones; these are the first */
125         int32 n_sen;        /**< Number of senones (CI+CD) */
126         int32 n_tmat;       /**< Number of transition matrices */
127         int32 n_sseq;       /**< Number of unique senone sequences */
128         int32 n_ctx;        /**< Number of phones of context */
129         int32 n_cd_tree;    /**< Number of nodes in cd_tree (below) */
130         int16 sil;          /**< CI phone ID for silence */
131
132         mmio_file_t *filemap;/**< File map for this file (if any) */
133         char **ciname;       /**< CI phone names */
134         cd_tree_t *cd_tree;  /**< Tree mapping CD phones to phone IDs */
135         mdef_entry_t *phone; /**< All phone structures */
136         uint16 **sseq;       /**< Unique senone sequences (2D array built at load time) */
137         uint8 *sseq_len;     /**< Number of states in each sseq (NULL for homogeneous) */
138
139         /* These two are not stored on disk, but are generated at load time. */
140         int16 *cd2cisen;        /**< Parent CI-senone id for each senone */
141         int16 *sen2cimap;       /**< Parent CI-phone for each senone (CI or CD) */
142
143         /** Allocation mode for this object. */
144         enum { BIN_MDEF_FROM_TEXT, BIN_MDEF_IN_MEMORY, BIN_MDEF_ON_DISK } alloc_mode;
145 };
146
147 #define bin_mdef_is_fillerphone(m,p)    (((p) < (m)->n_ciphone) \
148                                          ? (m)->phone[p].info.ci.filler \
149                                          : (m)->phone[(m)->phone[p].info.cd.ctx[0]].info.ci.filler)
150 #define bin_mdef_is_ciphone(m,p)        ((p) < (m)->n_ciphone)
151 #define bin_mdef_n_ciphone(m)           ((m)->n_ciphone)
152 #define bin_mdef_n_phone(m)             ((m)->n_phone)
153 #define bin_mdef_n_sseq(m)              ((m)->n_sseq)
154 #define bin_mdef_n_emit_state(m)        ((m)->n_emit_state)
155 #define bin_mdef_n_emit_state_phone(m,p) ((m)->n_emit_state ? (m)->n_emit_state \
156                                           : (m)->sseq_len[(m)->phone[p].ssid])
157 #define bin_mdef_n_sen(m)               ((m)->n_sen)
158 #define bin_mdef_n_tmat(m)              ((m)->n_tmat)
159 #define bin_mdef_pid2ssid(m,p)          ((m)->phone[p].ssid)
160 #define bin_mdef_pid2tmatid(m,p)        ((m)->phone[p].tmat)
161 #define bin_mdef_silphone(m)            ((m)->sil)
162 #define bin_mdef_sen2cimap(m,s)         ((m)->sen2cimap[s])
163 #define bin_mdef_sseq2sen(m,ss,pos)     ((m)->sseq[ss][pos])
164 #define bin_mdef_pid2ci(m,p)            (((p) < (m)->n_ciphone) ? (p) \
165                                          : (m)->phone[p].info.cd.ctx[0])
166
167 /**
168  * Read a binary mdef from a file.
169  */
170 bin_mdef_t *bin_mdef_read(cmd_ln_t *config, const char *filename);
171 /**
172  * Read a text mdef from a file (creating an in-memory binary mdef).
173  */
174 bin_mdef_t *bin_mdef_read_text(cmd_ln_t *config, const char *filename);
175 /**
176  * Write a binary mdef to a file.
177  */
178 int bin_mdef_write(bin_mdef_t *m, const char *filename);
179 /**
180  * Write a binary mdef to a text file.
181  */
182 int bin_mdef_write_text(bin_mdef_t *m, const char *filename);
183 /**
184  * Retain a pointer to a bin_mdef_t.
185  */
186 bin_mdef_t *bin_mdef_retain(bin_mdef_t *m);
187 /**
188  * Release a pointer to a binary mdef.
189  */
190 int bin_mdef_free(bin_mdef_t *m);
191
192 /**
193  * Context-independent phone lookup.
194  * @return phone id for ciphone.
195  */
196 int bin_mdef_ciphone_id(bin_mdef_t *m,         /**< In: Model structure being queried */
197                         const char *ciphone);  /**< In: ciphone for which id wanted */
198
199 /**
200  * Case-insensitive context-independent phone lookup.
201  * @return phone id for ciphone.
202  */
203 int bin_mdef_ciphone_id_nocase(bin_mdef_t *m,        /**< In: Model structure being queried */
204                                const char *ciphone); /**< In: ciphone for which id wanted */
205
206 /* Return value: READ-ONLY ciphone string name for the given ciphone id */
207 const char *bin_mdef_ciphone_str(bin_mdef_t *m, /**< In: Model structure being queried */
208                                  int32 ci);     /**< In: ciphone id for which name wanted */
209
210 /* Return value: phone id for the given constituents if found, else -1 */
211 int bin_mdef_phone_id(bin_mdef_t *m,    /**< In: Model structure being queried */
212                       int32 b,          /**< In: base ciphone id */
213                       int32 l,          /**< In: left context ciphone id */
214                       int32 r,          /**< In: right context ciphone id */
215                       int32 pos);       /**< In: Word position */
216
217 /* Look up a phone id, backing off to other word positions. */
218 int bin_mdef_phone_id_nearest(bin_mdef_t * m, int32 b,
219                               int32 l, int32 r, int32 pos);
220
221 /**
222  * Create a phone string for the given phone (base or triphone) id in the given buf.
223  *
224  * @return 0 if successful, -1 if error.
225  */
226 int bin_mdef_phone_str(bin_mdef_t *m,   /**< In: Model structure being queried */
227                        int pid,         /**< In: phone id being queried */
228                        char *buf);      /**< Out: On return, buf has the string */
229
230 #ifdef __cplusplus
231 }; /* extern "C" */
232 #endif /* __cplusplus */
233
234 #endif /* __BIN_MDEF_H__ */