1 /*---------------------------------------------------------------------------* 2 * ca_wave.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 40 /* CA_Wave functions. See simpars.c for frontend params */ 41 42 CA_Wave *CA_AllocateWave(char type) 43 { 44 CA_Wave *hWave = NULL; 45 TRY_CA_EXCEPT 46 hWave = (CA_Wave *) CALLOC_CLR(1, sizeof(CA_Wave), "cfront.hWave"); 47 #ifndef _RTT 48 hWave->data.device.file.typ = type; 49 #endif 50 hWave->data.channel = create_channel_object(); 51 hWave->is_configured = False; 52 hWave->is_configuredForVoicing = False; 53 hWave->ca_rtti = CA_WAVE_SIGNATURE; 54 return (hWave); 55 56 BEG_CATCH_CA_EXCEPT; 57 END_CATCH_CA_EXCEPT(hWave); 58 } 59 60 void CA_ConfigureWave(CA_Wave *hWave, CA_Frontend *hFrontend) 61 { 62 TRY_CA_EXCEPT 63 ASSERT(hWave); 64 ASSERT(hFrontend); 65 ASSERT(FRAMERATE > 0); 66 67 if (hFrontend->is_configured == False) 68 SERVICE_ERROR(UNCONFIGURED_FRONTEND); 69 if (hWave->is_configured == True) 70 SERVICE_ERROR(CONFIGURED_WAVE); 71 72 ASSERT(hFrontend->config->waveobj->samplerate); 73 74 hWave->data.scale = hFrontend->src_scale; 75 hWave->data.offset = hFrontend->offset; 76 setup_channel_object(hWave->data.channel, hFrontend->config->waveobj, 77 hFrontend->config->freqobj, 78 hFrontend->config->cepobj); 79 80 hWave->data.samplerate = hFrontend->config->waveobj->samplerate; 81 82 /* Buffer size is set to one frame's worth of data */ 83 create_sample_buffer(&hWave->data, 84 hFrontend->config->waveobj->samplerate / FRAMERATE, 85 hFrontend->config->freqobj->window_length); 86 87 hWave->data.stats.highclip_level = hFrontend->config->waveobj->high_clip; 88 hWave->data.stats.lowclip_level = hFrontend->config->waveobj->low_clip; 89 hWave->data.stats.max_per10000_clip = 90 hFrontend->config->waveobj->max_per10000_clip; 91 hWave->data.stats.max_dc_offset = 92 hFrontend->config->waveobj->max_dc_offset; 93 hWave->data.stats.high_noise_level_bit = 94 hFrontend->config->waveobj->high_noise_level_bit; 95 hWave->data.stats.low_speech_level_bit = 96 hFrontend->config->waveobj->low_speech_level_bit; 97 hWave->data.stats.min_samples = 98 hFrontend->config->waveobj->min_samples; 99 100 hWave->is_configured = True; 101 return; 102 103 BEG_CATCH_CA_EXCEPT; 104 END_CATCH_CA_EXCEPT(hWave); 105 } 106 107 void CA_ConfigureVoicingAnalysis(CA_Wave *hWave, CA_FrontendInputParams *hFrontPar) 108 { 109 TRY_CA_EXCEPT 110 111 hWave->voice.margin = hFrontPar->voice_margin; 112 hWave->voice.fast_margin = hFrontPar->fast_voice_margin; 113 hWave->voice.quiet_margin = hFrontPar->tracker_margin; 114 hWave->voice.voice_duration = hFrontPar->voice_duration; 115 hWave->voice.quiet_duration = hFrontPar->quiet_duration; 116 hWave->is_configuredForVoicing = True; 117 return; 118 119 BEG_CATCH_CA_EXCEPT 120 END_CATCH_CA_EXCEPT(hWave) 121 } 122 123 void CA_UnconfigureWave(CA_Wave *hWave) 124 { 125 TRY_CA_EXCEPT 126 ASSERT(hWave); 127 if (hWave->is_configured == False) 128 SERVICE_ERROR(UNCONFIGURED_WAVE); 129 130 clear_channel_object(hWave->data.channel); 131 free_sample_buffer(&hWave->data); 132 hWave->data.samplerate = 0; 133 134 hWave->is_configured = False; 135 136 /* The following is not correct in this place as it does not match where it is set to TRUE. 137 * This is needed for the sample rate change function. 138 * hWave->is_configuredForVoicing = False; 139 */ 140 BEG_CATCH_CA_EXCEPT; 141 END_CATCH_CA_EXCEPT(hWave); 142 } 143 144 void CA_FreeWave(CA_Wave *hWave) 145 { 146 TRY_CA_EXCEPT 147 ASSERT(hWave); 148 149 if (hWave->is_configured == True) 150 SERVICE_ERROR(CONFIGURED_WAVE); 151 152 delete_channel_object(hWave->data.channel); 153 FREE((char *) hWave); 154 return; 155 BEG_CATCH_CA_EXCEPT; 156 END_CATCH_CA_EXCEPT(hWave); 157 } 158 159 int CA_OpenWaveFromDevice(CA_Wave *hWave, 160 int wave_type, 161 int samplerate, 162 int device_id, 163 int device_type) 164 { 165 TRY_CA_EXCEPT 166 ASSERT(hWave); 167 ASSERT(device_id >= 0); 168 ASSERT(device_type == WAVE_DEVICE_RAW); 169 170 if (hWave->is_configured == False) 171 SERVICE_ERROR(UNCONFIGURED_WAVE); 172 if (hWave->is_configuredForVoicing == False) 173 SERVICE_ERROR(UNCONFIGURED_WAVE); 174 175 reset_channel_object(hWave->data.channel); 176 hWave->data.wave_type = wave_type; 177 hWave->data.device_type = device_type; 178 hWave->data.device.ext.op = WAVE_DEVICE_INPUT; 179 hWave->data.samplerate = samplerate; 180 init_voicing_analysis(&hWave->voice); 181 182 reset_sig_check(&hWave->data.stats); 183 hWave->data.do_stats = ESR_TRUE; 184 185 return (True); 186 BEG_CATCH_CA_EXCEPT; 187 END_CATCH_CA_EXCEPT(hWave); 188 } 189 190 191 ESR_BOOL CA_DoSignalCheck(CA_Wave *hWave, 192 ESR_BOOL *clipping, 193 ESR_BOOL *dcoffset, 194 ESR_BOOL *highnoise, 195 ESR_BOOL *quietspeech, 196 ESR_BOOL *too_few_samples, 197 ESR_BOOL *too_many_samples) 198 { 199 TRY_CA_EXCEPT 200 201 int nsam; 202 int pclowclip; 203 int pchighclip; 204 int dc_offset; 205 int amp; 206 int pc5; 207 int pc95; 208 int overflow; 209 ESR_BOOL error; 210 wave_stats *ws; 211 212 ASSERT(hWave); 213 214 ws = &hWave->data.stats; 215 get_sig_check(ws, &nsam, &pclowclip, &pchighclip, &dc_offset, &, 216 &pc5, &pc95, &overflow); 217 218 if ((pclowclip + pchighclip) > ws->max_per10000_clip) 219 *clipping = ESR_TRUE; 220 else *clipping = ESR_FALSE; 221 if (abs(dc_offset) > ws->max_dc_offset) *dcoffset = ESR_TRUE; 222 else *dcoffset = ESR_FALSE; 223 if (pc5 >= ws->high_noise_level_bit) *highnoise = ESR_TRUE; 224 else *highnoise = ESR_FALSE; 225 if (pc95 < ws->low_speech_level_bit) *quietspeech = ESR_TRUE; 226 else *quietspeech = ESR_FALSE; 227 if (nsam < ws->min_samples) *too_few_samples = ESR_TRUE; 228 else *too_few_samples = ESR_FALSE; 229 if (overflow) *too_many_samples = ESR_TRUE; 230 else *too_many_samples = ESR_FALSE; 231 232 /* This is better than casting the logical expression to ESR_BOOL */ 233 if (*clipping || *dcoffset || *highnoise || *quietspeech || *too_few_samples || *too_many_samples) 234 error = ESR_TRUE; 235 else 236 error = ESR_FALSE; 237 238 return(error); 239 240 BEG_CATCH_CA_EXCEPT 241 END_CATCH_CA_EXCEPT(hWave) 242 } 243 244 void CA_CloseDevice(CA_Wave *hWave) 245 { 246 TRY_CA_EXCEPT 247 if (hWave->is_configured == False) 248 SERVICE_ERROR(UNCONFIGURED_WAVE); 249 250 ASSERT(hWave->data.device.ext.op == WAVE_DEVICE_INPUT); /* because I don't have output yet! */ 251 252 return; 253 BEG_CATCH_CA_EXCEPT; 254 END_CATCH_CA_EXCEPT(hWave); 255 } 256 257 258 int CA_LoadSamples(CA_Wave *hWave, 259 samdata *pPCMData, 260 int sampleCount) 261 { 262 ASSERT(hWave); 263 ASSERT(pPCMData); 264 265 TRY_CA_EXCEPT 266 if (hWave->is_configured == False) 267 SERVICE_ERROR(UNCONFIGURED_WAVE); 268 if (hWave->data.device_type != WAVE_DEVICE_RAW) 269 SERVICE_ERROR(BAD_WAV_DEVICE); 270 if (hWave->data.window_size < sampleCount) 271 SERVICE_ERROR(INCORRECT_SAMPLERATE); 272 273 memcpy(hWave->data.income, 274 pPCMData, 275 sampleCount * sizeof(samdata)); 276 277 hWave->data.num_samples = sampleCount; 278 279 if (hWave->data.do_stats) 280 acc_wave_stats(&hWave->data); 281 282 return (True); 283 BEG_CATCH_CA_EXCEPT; 284 END_CATCH_CA_EXCEPT(hWave); 285 } 286 287 void CA_ConditionSamples(CA_Wave *hWave) 288 { 289 TRY_CA_EXCEPT 290 int ii; 291 292 if (hWave->is_configured == False) 293 SERVICE_ERROR(UNCONFIGURED_WAVE); 294 295 if (hWave->data.offset != 0) 296 for (ii = 0; ii < hWave->data.num_samples; ii++) 297 hWave->data.income[ii] = RANGE(hWave->data.income[ii] + 298 hWave->data.offset, SHRT_MIN, SHRT_MAX); 299 if (hWave->data.scale != 1.0) 300 for (ii = 0; ii < hWave->data.num_samples; ii++) 301 hWave->data.income[ii] = (short) RANGE(hWave->data.income[ii] * 302 hWave->data.scale, SHRT_MIN, SHRT_MAX); 303 return; 304 BEG_CATCH_CA_EXCEPT; 305 END_CATCH_CA_EXCEPT(hWave); 306 } 307