1 /*---------------------------------------------------------------------------*
2 * pat_basi.c *
3 * *
4 * Copyright 2007, 2008 Nuance Communciations, Inc. *
5 * *
6 * Licensed under the Apache License, Version 2.0 (the 'License'); *
7 * you may not use this file except in compliance with the License. *
8 * *
9 * You may obtain a copy of the License at *
10 * http://www.apache.org/licenses/LICENSE-2.0 *
11 * *
12 * Unless required by applicable law or agreed to in writing, software *
13 * distributed under the License is distributed on an 'AS IS' BASIS, *
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
15 * See the License for the specific language governing permissions and *
16 * limitations under the License. *
17 * *
18 *---------------------------------------------------------------------------*/
19
20 #include <stdlib.h>
21 #include <string.h>
22 #ifndef _RTT
23 #include <stdio.h>
24 #endif
25
26 #ifdef unix
27 #include <unistd.h>
28 #endif
29 #include <assert.h>
30
31
32 #include "simapi.h"
33 #include "portable.h"
34 #include "swicms.h"
35
36 #ifdef SET_RCSID
37 static const char *rcsid = 0 ? (const char *) &rcsid :
38 "$Id: pat_basi.c,v 1.9.6.11 2008/03/07 18:49:28 dahan Exp $";
39 #endif
40
41 extern const float root_pi_over_2;
42
CA_AllocatePattern(void)43 CA_Pattern *CA_AllocatePattern(void)
44 {
45 TRY_CA_EXCEPT
46 CA_Pattern *hPattern = NULL;
47
48 hPattern = (CA_Pattern *) CALLOC_CLR(1,
49 sizeof(CA_Pattern), "ca.hPattern");
50 hPattern->is_loaded = False;
51 //hPattern->setup_whole = NULL;
52 //hPattern->setup_sub = NULL;
53 hPattern->ca_rtti = CA_PATTERN_SIGNATURE;
54 return (hPattern);
55
56 BEG_CATCH_CA_EXCEPT
57 END_CATCH_CA_EXCEPT(hPattern)
58 }
59
60
CA_FreePattern(CA_Pattern * hPattern)61 void CA_FreePattern(CA_Pattern *hPattern)
62 {
63 TRY_CA_EXCEPT
64
65 ASSERT(hPattern);
66 FREE((char *) hPattern);
67 return;
68
69 BEG_CATCH_CA_EXCEPT
70 END_CATCH_CA_EXCEPT(hPattern)
71 }
72
73
CA_LoadPattern(CA_Pattern * hPattern,CA_PatInputParams * hPatInput,int dimen,char * multable,char * imelda)74 int CA_LoadPattern(CA_Pattern *hPattern, CA_PatInputParams *hPatInput,
75 int dimen , char *multable , char *imelda)
76 {
77
78 TRY_CA_EXCEPT
79 #ifndef _RTT
80 int ii, ret_code;
81
82 ASSERT(hPattern);
83 ASSERT(hPatInput);
84 if (hPattern->is_loaded == True)
85 SERVICE_ERROR(PATTERN_ALREADY_LOADED);
86 if (hPatInput->is_loaded == False)
87 SERVICE_ERROR(PATTERN_INPUT_NOT_LOADED);
88
89 hPattern->data.prep = (preprocessed *) CALLOC_CLR(1,
90 sizeof(preprocessed), "ca.hPattern->data.prep");
91
92 /* Load the Imelda transform if specified */
93 if (imelda && strlen(imelda) > 0)
94 {
95 ret_code = init_newton_transform(hPattern->data.prep, 0, imelda, hPatInput->dimen);
96 if (ret_code > 0)
97 SERVICE_ERROR(PATTERN_NOT_LOADED);
98 }
99 else
100 {
101 hPattern->data.prep->use_dim = hPatInput->dimen;
102 hPattern->data.prep->use_from = hPatInput->feat_start;
103 }
104
105 if (hPatInput->whole_dimen == 0)
106 hPattern->data.prep->whole_dim = hPatInput->dimen;
107 else
108 hPattern->data.prep->whole_dim = hPatInput->whole_dimen;
109 if (hPattern->data.prep->whole_dim > hPattern->data.prep->use_dim)
110 SERVICE_ERROR(BAD_PARAMETER);
111
112 hPattern->data.prep->mix_score_scale = (prdata)(128 * hPatInput->mix_score_scale + 0.5)
113 - (prdata)0.5;
114 hPattern->data.prep->uni_score_scale = (prdata)(128 * hPatInput->uni_score_scale + 0.5)
115 - (prdata)0.5;
116 hPattern->data.prep->uni_score_offset = (prdata) hPatInput->uni_score_offset;
117 hPattern->data.prep->imelda_scale = (prdata)hPatInput->imelda_scale;
118 init_preprocessed(hPattern->data.prep, dimen, hPatInput->imelda_scale); /* TODO: move this to Setup */
119
120
121 /* Annotation parameters */
122 hPattern->data.prep->end.rel_low = hPatInput->rel_low;
123 hPattern->data.prep->end.rel_high = hPatInput->rel_high;
124 hPattern->data.prep->end.gap_period = hPatInput->gap_period;
125 hPattern->data.prep->end.click_period = hPatInput->click_period;
126 hPattern->data.prep->end.breath_period = hPatInput->breath_period;
127 hPattern->data.prep->end.extend_annotation = hPatInput->extend_annotation;
128 hPattern->data.prep->end.min_annotation_frames = hPatInput->min_annotation_frames;
129 hPattern->data.prep->end.max_annotation_frames = hPatInput->max_annotation_frames;
130 hPattern->data.prep->end.min_segment_rel_c0 = hPatInput->min_segment_rel_c0;
131 hPattern->data.prep->end.min_initial_quiet_frames = hPatInput->min_initial_quiet_frames;
132 hPattern->data.prep->end.delete_leading_segments = hPatInput->delete_leading_segments;
133 hPattern->data.prep->end.leading_segment_min_frames = hPatInput->leading_segment_min_frames;
134 hPattern->data.prep->end.leading_segment_max_frames = hPatInput->leading_segment_max_frames;
135 hPattern->data.prep->end.leading_segment_min_silence_gap_frames
136 = hPatInput->leading_segment_min_silence_gap_frames;
137 hPattern->data.prep->end.leading_segment_accept_if_not_found
138 = hPatInput->leading_segment_accept_if_not_found;
139 #if DO_SUBTRACTED_SEGMENTATION
140 hPattern->data.prep->end.snr_holdoff = hPatInput->snr_holdoff;
141 hPattern->data.prep->end.min_acceptable_snr = hPatInput->min_acceptable_snr;
142 #endif
143 hPattern->data.prep->end.param = hPatInput->param;
144 hPattern->data.prep->end.beep_size = hPatInput->beep_size;
145 hPattern->data.prep->end.beep_threshold = hPatInput->beep_threshold;
146
147
148 /* log-lookup table */
149 create_lookup_logadd(&hPattern->data.prep->add, (float)MUL_SCALE);
150
151 /* Build the weights conversion table */
152 for (ii = 0; ii < MAX_WTS; ii++)
153 hPattern->data.prep->exp_wt[ii] =
154 (prdata)(WEIGHT_SCALE * exp((double)(0x01 << WT_ADJUST) *
155 (double) - ii / (MUL_SCALE * hPattern->data.prep->add.scale)) +
156 0.5) - (prdata)0.5;
157
158 hPattern->data.prep->ref_count = 1;
159 hPattern->is_loaded = True;
160
161 return (True);
162 #else
163 log_report("RTT not in module\n");
164 SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
165 return (False);
166 #endif
167
168
169 BEG_CATCH_CA_EXCEPT
170 END_CATCH_CA_EXCEPT(hPattern)
171
172 }
173
CA_UnloadPattern(CA_Pattern * hPattern)174 void CA_UnloadPattern(CA_Pattern *hPattern)
175 {
176 TRY_CA_EXCEPT
177 ASSERT(hPattern);
178 if (hPattern->is_loaded == False)
179 SERVICE_ERROR(PATTERN_NOT_LOADED);
180
181 if (--hPattern->data.prep->ref_count == 0)
182 {
183 if (hPattern->data.prep->matrix)
184 free_linear_transform(hPattern->data.prep);
185
186 if (hPattern->data.prep->add.table)
187 destroy_lookup_logadd(&hPattern->data.prep->add);
188
189 clear_preprocessed(hPattern->data.prep);
190
191 FREE((char *) hPattern->data.prep);
192 hPattern->data.prep = NULL;
193 }
194
195 hPattern->is_loaded = False;
196 return;
197 BEG_CATCH_CA_EXCEPT
198 END_CATCH_CA_EXCEPT(hPattern)
199 }
200
201
CA_SetupPatternForAcoustic(CA_Pattern * hPattern,CA_Acoustic * hAcoust)202 void CA_SetupPatternForAcoustic(CA_Pattern *hPattern, CA_Acoustic *hAcoust)
203 {
204 TRY_CA_EXCEPT
205 #ifdef SREC_ENGINE_VERBOSE_LOGGING
206 PLogMessage("in SetupPatternForAcoustic\n");
207 #endif
208 /* Setup for mul-table if necessary
209 */
210 ASSERT(hPattern);
211 ASSERT(hAcoust);
212 if (hPattern->is_loaded == False)
213 SERVICE_ERROR(PATTERN_NOT_LOADED);
214 if (hAcoust->is_loaded == False)
215 SERVICE_ERROR(ACOUSTIC_NOT_LOADED);
216 /* Check that if the Acoustic object is already set up then
217 the pattern objects must have certain similarities. */
218 if (hAcoust->pattern_setup_count > 0)
219 {
220 if (hPattern->data.prep->imelda_scale != hAcoust->imelda_scale)
221 SERVICE_ERROR(ACOUSTIC_PATTERN_MISMATCH);
222 if (hPattern->data.prep->use_dim != hAcoust->use_dim)
223 SERVICE_ERROR(ACOUSTIC_PATTERN_MISMATCH);
224 }
225 #ifdef SREC_ENGINE_VERBOSE_LOGGING
226 //PLogMessage("mod_style %d\n", hAcoust->acc.mod_style);
227 #endif
228
229 hAcoust->pattern_setup_count++;
230 return;
231
232 BEG_CATCH_CA_EXCEPT
233 END_CATCH_CA_EXCEPT(hPattern)
234 }
235
CA_ClearPatternForAcoustic(CA_Pattern * hPattern,CA_Acoustic * hAcoust)236 void CA_ClearPatternForAcoustic(CA_Pattern *hPattern, CA_Acoustic *hAcoust)
237 {
238 TRY_CA_EXCEPT
239 ASSERT(hPattern);
240 ASSERT(hAcoust);
241 if (hPattern->is_loaded == False)
242 SERVICE_ERROR(PATTERN_NOT_LOADED);
243 if (hAcoust->pattern_setup_count == 0)
244 SERVICE_ERROR(ACOUSTIC_HAS_NO_PATTERN);
245 hAcoust->pattern_setup_count--;
246
247 return;
248 BEG_CATCH_CA_EXCEPT
249 END_CATCH_CA_EXCEPT(hPattern)
250 }
251
252
CA_MakePatternFrame(CA_Pattern * hPattern,CA_Utterance * hUtt)253 int CA_MakePatternFrame(CA_Pattern *hPattern, CA_Utterance *hUtt)
254 {
255
256 TRY_CA_EXCEPT
257 int status_code;
258 swicms_norm_info* swicms;
259
260 ASSERT(hPattern);
261 ASSERT(hUtt);
262
263 if (hPattern->is_loaded == False)
264 SERVICE_ERROR(PATTERN_NOT_LOADED);
265
266 status_code = get_data_frame(hPattern->data.prep, &hUtt->data);
267
268 /* swicms_cache_frame() must be here because get_data_frame() is called from
269 backtracing. Is the caching at the front-end even necessary any more?
270 */
271 swicms = hUtt->data.gen_utt.swicms;
272 if (!swicms->is_valid)
273 swicms_lda_process(swicms, hPattern->data.prep);
274
275 swicms_cache_frame(swicms, hPattern->data.prep->seq_unnorm,
276 hUtt->data.gen_utt.channorm->dim);
277 apply_channel_normalization_in_swicms(swicms, hPattern->data.prep->seq,
278 hPattern->data.prep->seq_unnorm,
279 hUtt->data.gen_utt.channorm->dim);
280
281 /* prepare is fairly useless and should be removed */
282 prepare_data_frame(hPattern->data.prep);
283 return (status_code);
284
285 BEG_CATCH_CA_EXCEPT
286 END_CATCH_CA_EXCEPT(hPattern)
287 }
288
289