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
42static 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
47ESR_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
59ESR_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
71void 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
85void CA_SaveCMSParameters(CA_Wave *hWave, const char *basename)
86{
87	SERVICE_ERROR(FEATURE_NOT_SUPPORTED);
88}
89
90
91void 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
131void 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
156void 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
187ESR_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
195ESR_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
203void 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
231void 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