1 /*---------------------------------------------------------------------------*
2 * ca_cms.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 /************************************************************************
21 * CA_Wave Methods
22 ************************************************************************/
23
24 #ifndef _RTT
25 #include <stdio.h>
26 #endif
27 #include <stdlib.h>
28 #include <string.h>
29 #include <limits.h>
30
31 #ifdef unix
32 #include <unistd.h>
33 #endif
34 #include <assert.h>
35
36
37 #include "frontapi.h"
38 #include "portable.h"
39 #include "swicms.h"
40
41 #ifdef SET_RCSID
42 static const char *rcsid = 0 ? (const char *) &rcsid :
43 "$Id: ca_cms.c,v 1.7.6.11 2008/05/27 16:08:28 dahan Exp $";
44 #endif
45
46
CA_SetCMSParameters(CA_Wave * hWave,const LCHAR * param_string)47 ESR_ReturnCode CA_SetCMSParameters ( CA_Wave *hWave, const LCHAR *param_string )
48 {
49 ESR_ReturnCode set_status;
50
51 if ( hWave != NULL )
52 set_status = swicms_set_cmn ( hWave->data.channel->swicms, param_string );
53 else
54 set_status = ESR_INVALID_STATE;
55 return ( set_status );
56 }
57
58
CA_GetCMSParameters(CA_Wave * hWave,LCHAR * param_string,size_t * len)59 ESR_ReturnCode CA_GetCMSParameters ( CA_Wave *hWave, LCHAR *param_string, size_t* len )
60 {
61 ESR_ReturnCode get_status;
62
63 if ( hWave != NULL )
64 get_status = swicms_get_cmn ( hWave->data.channel->swicms, param_string, len );
65 else
66 get_status = ESR_INVALID_STATE;
67 return ( get_status );
68 }
69
70
CA_ReLoadCMSParameters(CA_Wave * hWave,const char * basename)71 void CA_ReLoadCMSParameters(CA_Wave *hWave, const char *basename)
72 {
73 ASSERT(hWave);
74 if (hWave->is_configuredForAgc == False)
75 SERVICE_ERROR(UNCONFIGURED_CMS_AND_AGC);
76 if (!basename) {
77 if( swicms_init(hWave->data.channel->swicms) )
78 SERVICE_ERROR(UNEXPECTED_DATA_ERROR);
79 }
80 else
81 SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
82 }
83
84
CA_SaveCMSParameters(CA_Wave * hWave,const char * basename)85 void CA_SaveCMSParameters(CA_Wave *hWave, const char *basename)
86 {
87 SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
88 }
89
90
CA_LoadCMSParameters(CA_Wave * hWave,const char * basename,CA_FrontendInputParams * hFrontArgs)91 void CA_LoadCMSParameters(CA_Wave *hWave, const char *basename,
92 CA_FrontendInputParams *hFrontArgs)
93 {
94 TRY_CA_EXCEPT
95 #if !defined(_RTT)
96 ASSERT(hWave);
97 /* ASSERT (basename); */
98 ASSERT(hFrontArgs);
99
100 if (hWave->is_configuredForAgc == True)
101 SERVICE_ERROR(CONFIGURED_CMS_AND_AGC);
102 if (hWave->is_attached == True)
103 SERVICE_ERROR(ATTACHED_CMS_AND_AGC);
104
105 hWave->data.channel->channorm = create_channel_normalization();
106 /* load_channel_parameters (basename, hWave->data.channel->channorm);
107 not used anymore, rather we spec this is the parfile directly */
108 hWave->data.channel->channorm->dim = MAX_CHAN_DIM;
109 setup_channel_normalization(hWave->data.channel->channorm,
110 hWave->data.channel->spchchan,
111 #if NORM_IN_IMELDA
112 hFrontArgs->mel_dim * 3, /* TODO: find appropriate number */
113 #else
114 hFrontArgs->mel_dim,
115 #endif
116 hFrontArgs->forget_factor);
117 hWave->data.channel->mel_dim = hFrontArgs->mel_dim; /* TODO: more checks */
118
119 hWave->data.channel->swicms = (swicms_norm_info*)CALLOC(1, sizeof(swicms_norm_info), "cfront.swicms");
120 if( swicms_init(hWave->data.channel->swicms) )
121 SERVICE_ERROR(UNEXPECTED_DATA_ERROR);
122 hWave->is_configuredForAgc = True;
123 #else
124 log_report("Channel normalization or RTT not in module\n");
125 SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
126 #endif
127 BEG_CATCH_CA_EXCEPT;
128 END_CATCH_CA_EXCEPT(hFrontend);
129 }
130
CA_ClearCMSParameters(CA_Wave * hWave)131 void CA_ClearCMSParameters(CA_Wave *hWave)
132 {
133 TRY_CA_EXCEPT
134 #if NORM_IN_IMELDA
135 int dim = hWave->data.channel->mel_dim * 3;
136 #else
137 int dim = hWave->data.channel->mel_dim;
138 #endif
139
140 ASSERT(hWave);
141 if (hWave->is_configuredForAgc == False)
142 SERVICE_ERROR(UNCONFIGURED_CMS_AND_AGC);
143 if (hWave->is_attached == True)
144 SERVICE_ERROR(ATTACHED_CMS_AND_AGC);
145
146 clear_channel_normalization(hWave->data.channel->spchchan, dim);
147 destroy_channel_normalization(hWave->data.channel->channorm);
148 hWave->data.channel->channorm = NULL;
149 hWave->is_configuredForAgc = False;
150
151 FREE(hWave->data.channel->swicms);
152 BEG_CATCH_CA_EXCEPT;
153 END_CATCH_CA_EXCEPT(hWave);
154 }
155
CA_AttachCMStoUtterance(CA_Wave * hWave,CA_Utterance * hUtt)156 void CA_AttachCMStoUtterance(CA_Wave *hWave, CA_Utterance *hUtt)
157 {
158 /* Link the utt's spchchan to the wave object's. This is checked in AGC fn
159 to ensure that the correct Utt & Wave objects have been supplied.
160 */
161
162 TRY_CA_EXCEPT
163 ASSERT(hUtt);
164 ASSERT(hWave);
165 if (hWave->is_configuredForAgc == False)
166 SERVICE_ERROR(UNCONFIGURED_CMS_AND_AGC);
167 if (hWave->is_attached == True)
168 SERVICE_ERROR(ATTACHED_CMS_AND_AGC);
169
170 ASSERT(hWave->data.channel->channorm);
171 hUtt->data.gen_utt.spchchan = hWave->data.channel->spchchan;
172 hUtt->data.gen_utt.channorm = hWave->data.channel->channorm;
173 hUtt->data.gen_utt.swicms = hWave->data.channel->swicms;
174 hUtt->data.gen_utt.do_channorm = True;
175 #if NORM_IN_IMELDA /* TODO: find appropriate number */
176 hUtt->data.gen_utt.num_chan = 3 * hWave->data.channel->mel_dim;
177 #else
178 hUtt->data.gen_utt.num_chan = hWave->data.channel->mel_dim;
179 #endif
180 hWave->is_configuredForAgc = True;
181 hWave->is_attached = True;
182 return;
183 BEG_CATCH_CA_EXCEPT;
184 END_CATCH_CA_EXCEPT(hFrontend);
185 }
186
CA_IsCMSAttachedtoUtterance(CA_Wave * hWave,ESR_BOOL * isAttached)187 ESR_ReturnCode CA_IsCMSAttachedtoUtterance(CA_Wave* hWave, ESR_BOOL* isAttached)
188 {
189 if (hWave == NULL || isAttached == NULL)
190 return ESR_INVALID_ARGUMENT;
191 *isAttached = hWave->is_attached;
192 return ESR_SUCCESS;
193 }
194
CA_IsConfiguredForAgc(CA_Wave * hWave,ESR_BOOL * isConfigured)195 ESR_ReturnCode CA_IsConfiguredForAgc(CA_Wave* hWave, ESR_BOOL* isConfigured)
196 {
197 if (hWave == NULL || isConfigured == NULL)
198 return ESR_INVALID_ARGUMENT;
199 *isConfigured = hWave->is_configuredForAgc;
200 return ESR_SUCCESS;
201 }
202
CA_DetachCMSfromUtterance(CA_Wave * hWave,CA_Utterance * hUtt)203 void CA_DetachCMSfromUtterance(CA_Wave *hWave, CA_Utterance *hUtt)
204 {
205 TRY_CA_EXCEPT
206 ASSERT(hWave);
207
208 if (hWave->is_configuredForAgc == False)
209 SERVICE_ERROR(UNCONFIGURED_CMS_AND_AGC);
210 if (hUtt && hUtt->data.gen_utt.do_channorm == False)
211 SERVICE_ERROR(UTTERANCE_INVALID);
212 if (hWave->is_attached == False)
213 SERVICE_ERROR(UNATTACHED_CMS_AND_AGC);
214 if (hWave->data.channel->spchchan && hUtt->data.gen_utt.spchchan
215 && hWave->data.channel->spchchan != hUtt->data.gen_utt.spchchan)
216 {
217 log_report("Mismatched channel and utterance\n");
218 SERVICE_ERROR(BAD_CHANNEL);
219 } /* TODO: find a better code */
220
221 hUtt->data.gen_utt.channorm = NULL;
222 hUtt->data.gen_utt.spchchan = NULL;
223 hUtt->data.gen_utt.do_channorm = False;
224 hWave->is_attached = False;
225
226 return;
227 BEG_CATCH_CA_EXCEPT;
228 END_CATCH_CA_EXCEPT(hWave)
229 }
230
CA_CalculateCMSParameters(CA_Wave * hWave)231 void CA_CalculateCMSParameters(CA_Wave *hWave)
232 {
233 TRY_CA_EXCEPT
234
235 if (hWave->is_configuredForAgc == False)
236 SERVICE_ERROR(UNCONFIGURED_CMS_AND_AGC);
237 if (hWave->is_attached == False)
238 SERVICE_ERROR(UNATTACHED_CMS_AND_AGC);
239
240 estimate_normalization_parameters(hWave->data.channel->channorm,
241 hWave->data.channel->spchchan,
242 #if NORM_IN_IMELDA /* TODO: find appropriate number */
243 hWave->data.channel->mel_dim * 3);
244 #else
245 hWave->data.channel->mel_dim);
246 #endif
247 return;
248 BEG_CATCH_CA_EXCEPT;
249 END_CATCH_CA_EXCEPT(hWave);
250 }
251