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
37static 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
41extern const float   root_pi_over_2;
42
43CA_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
61void 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
74int 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
174void 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
202void 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
236void 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
253int 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