1 /*---------------------------------------------------------------------------* 2 * ca_front.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_Frontend Methods 22 ************************************************************************/ 23 24 25 #ifndef _RTT 26 #include <stdio.h> 27 #endif 28 #include <stdlib.h> 29 #include <string.h> 30 #include <limits.h> 31 32 #ifdef unix 33 #include <unistd.h> 34 #endif 35 #include <assert.h> 36 37 #include "frontapi.h" 38 39 #include "portable.h" 40 41 #ifdef USE_COMP_STATS 42 void stop_front_end_clock(void); 43 void start_front_end_clock(void); 44 #endif 45 46 /* These are front-end functions 47 */ 48 49 CA_Frontend *CA_AllocateFrontend(float srcscale, int offset, 50 float sinkscale) 51 { 52 CA_Frontend *hFrontend = NULL; 53 TRY_CA_EXCEPT 54 hFrontend = (CA_Frontend *) CALLOC_CLR(1, sizeof(CA_Frontend), "ca.hFrontend"); 55 hFrontend->src_scale = srcscale; 56 hFrontend->sink_scale = sinkscale; 57 hFrontend->offset = offset; 58 59 hFrontend->is_configured = False; 60 hFrontend->is_filter_loaded = False; 61 62 hFrontend->ca_rtti = CA_FRONTEND_SIGNATURE; 63 return (hFrontend); 64 BEG_CATCH_CA_EXCEPT; 65 END_CATCH_CA_EXCEPT(hFrontend) 66 } 67 68 void CA_FreeFrontend(CA_Frontend *hFrontend) 69 { 70 TRY_CA_EXCEPT 71 ASSERT(hFrontend); 72 if (hFrontend->is_configured == True) 73 SERVICE_ERROR(CONFIGURED_FRONTEND); 74 if (hFrontend->is_filter_loaded == True) 75 SERVICE_ERROR(SPEC_FILTER_CONFIGURED); 76 77 FREE((char *) hFrontend); 78 return; 79 BEG_CATCH_CA_EXCEPT; 80 END_CATCH_CA_EXCEPT(hFrontend); 81 } 82 83 84 void CA_ConfigureFrontend(CA_Frontend *hFrontend, 85 CA_FrontendInputParams *hFrontArgs) 86 { 87 TRY_CA_EXCEPT 88 ASSERT(hFrontend); 89 ASSERT(hFrontArgs); 90 91 if (hFrontArgs->is_loaded == False) 92 SERVICE_ERROR(FRONTEND_INPUT_NOT_LOADED); 93 if (hFrontend->is_configured == True) 94 SERVICE_ERROR(CONFIGURED_FRONTEND); 95 96 hFrontend->config = create_config_object() ; 97 setup_config_object(hFrontend->config, hFrontArgs); 98 hFrontend->is_configured = True; 99 100 return; 101 BEG_CATCH_CA_EXCEPT; 102 END_CATCH_CA_EXCEPT(hFrontend); 103 } 104 105 void CA_UnconfigureFrontend(CA_Frontend *hFrontend) 106 { 107 TRY_CA_EXCEPT 108 ASSERT(hFrontend); 109 if (hFrontend->is_configured == False) 110 SERVICE_ERROR(UNCONFIGURED_FRONTEND); 111 112 clear_config_object(hFrontend->config); 113 delete_config_object(hFrontend->config); 114 hFrontend->config = NULL; 115 116 hFrontend->is_configured = False; 117 118 return; 119 BEG_CATCH_CA_EXCEPT; 120 END_CATCH_CA_EXCEPT(hFrontend); 121 } 122 123 124 int CA_MakeFrame(CA_Frontend *hFrontend, CA_Utterance *hUtt, CA_Wave *hWave) 125 { 126 /* Note: samdata has already been loaded 127 */ 128 int valid; 129 TRY_CA_EXCEPT 130 featdata framdata[MAX_CHAN_DIM], voicedata = 0; 131 132 ASSERT(hFrontend); 133 ASSERT(hUtt); 134 ASSERT(hWave); 135 136 ASSERT(hUtt->data.gen_utt.frame->uttDim <= MAX_CHAN_DIM); 137 138 if (hFrontend->is_configured == False) 139 SERVICE_ERROR(UNCONFIGURED_FRONTEND); 140 if (hUtt->data.utt_type != LIVE_INPUT) 141 SERVICE_ERROR(UTTERANCE_INVALID); 142 143 #ifdef USE_COMP_STATS 144 start_front_end_clock(); 145 #endif 146 147 148 if (hUtt->data.gen_utt.frame->haveVoiced) 149 valid = make_frame(hWave->data.channel, hFrontend->config->waveobj, 150 hFrontend->config->freqobj, hFrontend->config->cepobj, 151 &hWave->voice, hWave->data.income, hWave->data.outgo, 152 hWave->data.num_samples, 153 framdata, &voicedata); 154 else 155 valid = make_frame(hWave->data.channel, hFrontend->config->waveobj, 156 hFrontend->config->freqobj, 157 hFrontend->config->cepobj, 158 NULL, hWave->data.income, hWave->data.outgo, 159 hWave->data.num_samples, 160 framdata, &voicedata); 161 162 /* Ignore first 3 frames. This prevents a spike due to dc offset. 163 ** This effect would normally be removed by loading the window 164 ** overhang but we are not doing that (tricky). 165 */ 166 if (valid > 0 && hWave->data.channel->frame_count > (DELTA + 3)) 167 { 168 if (pushSingleFEPframe(hUtt->data.gen_utt.frame, 169 framdata, voicedata) != False) 170 valid = False; 171 } 172 else valid = False; 173 174 #ifdef USE_COMP_STATS 175 stop_front_end_clock(); 176 #endif 177 178 return (valid); 179 BEG_CATCH_CA_EXCEPT; 180 END_CATCH_CA_EXCEPT(hFrontend); 181 } 182 183 int CA_GetFrontendUtteranceDimension(CA_Frontend *hFrontend) 184 { 185 int dim; 186 TRY_CA_EXCEPT 187 ASSERT(hFrontend); 188 ASSERT(hFrontend->config); 189 190 if (hFrontend->is_configured == False) 191 SERVICE_ERROR(UNCONFIGURED_FRONTEND); 192 193 /* TODO: Determine the dim exactly */ 194 dim = 2 * hFrontend->config->cepobj->mel_dim; 195 if (hFrontend->config->cepobj->do_dd_mel) 196 dim += hFrontend->config->cepobj->mel_dim; 197 return (dim); 198 BEG_CATCH_CA_EXCEPT; 199 END_CATCH_CA_EXCEPT(hFrontend); 200 } 201