• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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