Home | History | Annotate | Download | only in cfront
      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, &amp,
    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