• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*---------------------------------------------------------------------------*
2  *  fpi_tgt.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 
22 
23 
24 #ifndef _RTT
25 #include <stdio.h>
26 #endif
27 #include <assert.h>
28 
29 #include "all_defs.h"
30 #include "fpi_tgt.h"
31 #include "voicing.h"
32 #include "portable.h"
33 
34 #include "fpi_tgt.inl"
35 
36 #define DEBUG_REWIND 0
37 
38 /************************************************************************
39  * Create a Frame Buffer                                                *
40  ************************************************************************
41  *
42  * On the Real Time Target (_RTT) the caller of this function is
43  * responsible for publically declaring the location of the Frame Buffer
44  * so that the REC unit can locate it.  This is achived by use of the
45  * 'setPublicLocation()' and 'publicLocation()' functions.
46  *
47  ************************************************************************
48  *
49  * Arguments: "fCnt"       Size of Frame Stack
50  *            "dimen"      Size of Frame
51  *            "blockLen"   Blocking length (if Using)
52  *            "doVoice"    Reserve voicing parameter
53  *
54  * Returns:   fepFramePkt* Pointer to frame buffer
55  *                          NULL on error
56  *
57  ************************************************************************/
58 
59 static int  incThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr);
60 static int  decThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr);
61 
62 
63 
createFrameBuffer(int fCnt,int dimen,int blockLen,int doVoice)64 fepFramePkt* createFrameBuffer(int fCnt, int dimen, int blockLen, int doVoice)
65 {
66   fepFramePkt* frmPkt;
67 #if QUICK
68   unsigned long frame_mask = 1, tmpsiz;
69 #endif
70 
71   ASSERT(fCnt > 0);
72   ASSERT(dimen > 0);
73 
74   /* Allocate space for the Frame Packet  *
75    * and then accommodate the Frame Stack */
76 
77   frmPkt = (fepFramePkt*) CALLOC_CLR(1, sizeof(fepFramePkt), "clib.Frame_Buffer");
78   if (frmPkt == NULL)
79     return NULL;
80 
81 #if QUICK
82   tmpsiz = blockLen;
83   frame_mask = 1;
84   tmpsiz >>= 1;
85   while (tmpsiz)
86   {
87     frame_mask = (frame_mask << 1) | 0x01;
88     tmpsiz >>= 1;
89   }
90   blockLen = frame_mask + 1;
91   frmPkt->stackMask = frame_mask;
92 #endif
93 
94   frmPkt->uttDim = dimen;
95   if (doVoice) dimen++;
96 
97   frmPkt->frameStackSize  = fCnt;
98   frmPkt->frameSize       = dimen;
99   frmPkt->featuresInStack = fCnt * dimen;
100   frmPkt->blockLen = blockLen;
101   if (doVoice) frmPkt->haveVoiced = True;
102   else frmPkt->haveVoiced = False;
103 
104   frmPkt->frameStack = (featdata *) CALLOC(fCnt,
105                        sizeof(featdata) * dimen, "clib.Frame_Stack");
106   if (frmPkt == NULL)
107     return NULL;
108   frmPkt->lastFrameInStack = frmPkt->frameStack + (fCnt - 1) * dimen;
109 
110   /* Use standard function to clear the buffer,    *
111    * we don't care about the return code because   *
112    * we built it, others should care...            */
113 
114   (void) clearFrameBuffer(frmPkt);
115 
116   frmPkt->uttTimeout = 20;             /* default setting */
117 
118   return frmPkt;
119 }
120 
121 
122 /************************************************************************
123  * Clear an existing Frame Buffer                                       *
124  ************************************************************************
125  *
126  * Given a pointer to a previously created frame buffer structure
127  * this funtion will reset its member components to their initial
128  * values.
129  *
130  ************************************************************************
131  *
132  * Arguments: "frmPkt"     Frame Buffer Structure Pointer
133  *
134  * Returns:   int          non-ZERO on Error
135  *
136  ************************************************************************/
137 
clearFrameBuffer(fepFramePkt * frmPkt)138 int clearFrameBuffer(fepFramePkt* frmPkt)
139 {
140   ASSERT(frmPkt != NULL);
141 
142   /* Clear the frame stack to ZERO as  *
143    * this is done by model_allocate()  */
144 
145   memset(frmPkt->frameStack, 0,  /*  TODO: do we need this? */
146          sizeof(featdata) * frmPkt->frameSize * frmPkt->frameStackSize);
147 
148   /* Reset Structure Members           */
149 
150   frmPkt->isCollecting = FB_IDLE;
151   frmPkt->pullp       = frmPkt->frameStack;
152 
153   frmPkt->pushp       = frmPkt->frameStack;
154   frmPkt->pushBlkp    = frmPkt->frameStack;
155   frmPkt->pushBlocked = False;
156   frmPkt->blockTime   = 0;
157   frmPkt->pushTime    = 1;    /* 0 == invalid frame ID, 1 == first    */
158   frmPkt->pullTime    = 1;
159   frmPkt->startTime   = 0;    /* 0 == start hasn't been called        */
160   frmPkt->stopTime    = 0;    /* 0 == stop  hasn't been called        */
161 
162   clearEndOfUtterance(frmPkt);
163   clearC0Entries(frmPkt);
164 
165   return False;
166 }
167 
168 /************************************************************************
169  * Destroy a Previously Created Frame Buffer                            *
170  ************************************************************************
171  *
172  * On the Real Time Target (_RTT) the caller of this function is
173  * responsible for publically declaring the location of the Frame Buffer
174  * so that the REC unit can locate it.  This is achived by use of the
175  * 'setPublicLocation()' and 'publicLocation()' functions.
176  *
177  ************************************************************************
178  *
179  * Arguments: fepFramePkt* Pointer to frame buffer to destroy
180  *
181  * Returns:   int          non-ZERO on error
182  *
183  ************************************************************************/
184 
destroyFrameBuffer(fepFramePkt * frmPkt)185 int destroyFrameBuffer(fepFramePkt* frmPkt)
186 {
187   ASSERT(frmPkt);
188   /* De-allocate space for the Frame Stack *
189    * and then the Frame Packet             */
190 
191   FREE(frmPkt->frameStack);
192   FREE(frmPkt);
193   return False;
194 }
195 
196 /************************************************************************
197  * To Start Collecting Frames                                           *
198  ***********************************************************************/
199 
startFrameCollection(fepFramePkt * frmPkt)200 void startFrameCollection(fepFramePkt* frmPkt)
201 {
202   ASSERT(frmPkt);
203   if (frmPkt->isCollecting == FB_IDLE)
204   {
205     clearEndOfUtterance(frmPkt);
206     clearC0Entries(frmPkt);
207 
208     frmPkt->startTime = frmPkt->pushTime;
209     frmPkt->stopTime = 0;
210     frmPkt->isCollecting = FB_ACTIVE;
211   }
212   return;
213 }
214 
215 /************************************************************************
216  * To Stop Collecting Frames                                            *
217  ***********************************************************************/
218 
stopFrameCollection(fepFramePkt * frmPkt)219 int stopFrameCollection(fepFramePkt* frmPkt)
220 {
221   ASSERT(frmPkt);
222   ASSERT(frmPkt->startTime != 0);
223 
224   if (frmPkt->isCollecting == FB_ACTIVE)
225   {
226 
227     /* Remember, pushTime is the ID of the next frame to arrive
228      * The buffer starts empty, with pushTime == 1.
229      * So if Stop occurs at this point, then the start and end frames
230      * will be
231      */
232 
233     frmPkt->stopTime = frmPkt->pushTime;
234     frmPkt->isCollecting = FB_IDLE;
235 
236     return (True);
237   }
238 
239   return (False);
240 }
241 
242 /************************************************************************
243  ***********************************************************************/
244 
setupEndOfUtterance(fepFramePkt * frmPkt,long timeout,long holdOff)245 void setupEndOfUtterance(fepFramePkt* frmPkt, long timeout, long holdOff)
246 {
247   ASSERT(frmPkt);
248   ASSERT(timeout >= 0);
249   ASSERT(holdOff >= 0);
250   frmPkt->uttTimeout = timeout;
251   frmPkt->holdOffPeriod = holdOff;
252   frmPkt->holdOff = 0;
253   return;
254 }
255 
256 /************************************************************************
257  ***********************************************************************/
258 
clearEndOfUtterance(fepFramePkt * frmPkt)259 void clearEndOfUtterance(fepFramePkt* frmPkt)
260 {
261   ASSERT(frmPkt);
262   ASSERT(frmPkt->holdOffPeriod >= 0);
263   frmPkt->voicingDetected = 0;
264   frmPkt->quietFrames = 0;
265   frmPkt->utt_ended = False;
266   frmPkt->holdOff = frmPkt->holdOffPeriod;
267 
268   return;
269 }
270 
releaseBlockedFramesInBuffer(fepFramePkt * frmPkt)271 void releaseBlockedFramesInBuffer(fepFramePkt* frmPkt)
272 {
273   frmPkt->pullp = frmPkt->pushp;     /*  Move the Blocker to pullp */
274   frmPkt->pushBlkp = frmPkt->pushp;     /*  Move the Blocker to pullp */
275   frmPkt->pullTime = frmPkt->pushTime;
276   frmPkt->blockTime = frmPkt->pushTime;
277 
278   return;
279 }
280 
281 /************************************************************************
282  * Push a Single Frame into Frame Buffer                                *
283  ************************************************************************
284  *
285  * Inserts a new frame into the frame buffer.
286  *
287  * If there is no room in the buffer (the frame maker has exhausted the
288  * space which is being slowly 'eaten' by the associated recognizer) then
289  * the data is not inserted and an error value is returned.  For this to
290  * happen, blockLen member must be set.  Otherwise pushBlkp will always
291  * point to the oldest valid frame in the buffer.
292  *
293  ************************************************************************
294  *
295  * Arguments: "frmPkt"  Frame Buffer Pointer
296  *            "parPtr"  Pointer to contiguous block of Frame Parameters
297  *
298  * Returns:   int       non-ZERO on ERROR
299  *
300  ************************************************************************/
301 
pushSingleFEPframe(fepFramePkt * frmPkt,featdata * parPtr,int voiceData)302 int pushSingleFEPframe(fepFramePkt* frmPkt, featdata* parPtr, int voiceData)
303 {
304   featdata*   destFrmPtr;
305   featdata*   nextFrmPtr;
306 
307   ASSERT(frmPkt);
308   ASSERT(parPtr);
309 
310   /* 'pushp' must be either within the frame buffer or NULL. *
311    * If it is NULL then the frame is just discarded.         */
312 
313   if (frmPkt->isCollecting != FB_ACTIVE) return True;
314   if ((destFrmPtr = nextFrmPtr = (featdata*) frmPkt->pushp) == NULL)
315     return (0);
316 
317 #if DEBUG_REWIND
318   log_report("U: voicing at %d was %x\n", frmPkt->pushTime, voiceData);
319 #endif
320 
321   /* Copy the frame into the buffer.  Once this is done     *
322    * advance 'pushp' (unless it is up against the 'blocker' *
323    * The frame consists of Parameters and Signal Data       */
324 
325   memcpy(destFrmPtr, parPtr, frmPkt->uttDim * sizeof(featdata));
326   if (frmPkt->haveVoiced)
327     destFrmPtr[frmPkt->uttDim] = voiceData;
328 
329   /* The following (vocing detection which triggers EOU),
330    * is only active when the 'holdOff' member is 0.
331    * The intension is to delay 'voicing' signal for at least
332   * 'holdOffPeriod' frames.
333    */
334   if (frmPkt->holdOff <= 0)
335   {
336     if (frmPkt->haveVoiced && frmPkt->utt_ended == False)
337     {
338       if (voiceData & VOICE_BIT)
339       {
340         frmPkt->voicingDetected = 1;
341       }
342       if (voiceData & QUIET_BIT)
343       {
344         frmPkt->quietFrames++;
345         if (frmPkt->voicingDetected
346             && frmPkt->quietFrames > frmPkt->uttTimeout)
347         {
348           log_report("Level based utterance ended at %d\n",
349                      frmPkt->pushTime);
350           frmPkt->utt_ended = True;
351         }
352       }
353       else
354         frmPkt->quietFrames = 0;
355     }
356   }
357   else
358   {
359     ASSERT(frmPkt->holdOff > 0);
360     frmPkt->holdOff--;
361   }
362 
363   /*  Track C0 values
364   */
365   if (frmPkt->maxC0 < parPtr[0])      /* only works if the 0th entry - */
366     frmPkt->maxC0 = parPtr[0];       /* is C0 */
367 
368   if (frmPkt->minC0 > parPtr[0])      /* only works if the 0th entry - */
369     frmPkt->minC0 = parPtr[0];       /* is C0 */
370 
371   frmPkt->pushTime++;
372   if (frmPkt->pushTime == 0L)          /* Check for wrap - and ensure */
373     frmPkt->pushTime++;              /* ZERO is NEVER used          */
374 
375   /* Try to move the push pointer on, if it meets the *
376    * push blocker it should not increment.            */
377 
378   nextFrmPtr = (featdata *) NEXT_FRAME_POINTER(frmPkt, frmPkt->pushp);
379 
380   if (nextFrmPtr == frmPkt->pullp)
381   {
382     /* Latest Frame was blocked, so record the fact and then *
383     * record the frame time that this occured (useful?)     */
384 
385     frmPkt->pushBlocked++;
386     frmPkt->blockTime = frmPkt->pushTime;
387 
388     return True;
389   }
390 
391   else if (nextFrmPtr == frmPkt->pushBlkp)
392   {
393     if (frmPkt->blockLen == 0)
394     {
395       /* Simply move pushBlkp along */
396 
397       frmPkt->pushBlkp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pushBlkp);
398     }
399     else
400     {
401       /* Latest Frame was blocked, so record the fact and then *
402        * record the frame time that this occured (useful?)     */
403 
404       frmPkt->pushBlocked++;
405       frmPkt->blockTime = frmPkt->pushTime;
406 
407       return True;
408     }
409   }
410 
411   /* Free to move ahead, so increment the push pointer     *
412    * and increase the frame-count between pull & push      */
413 
414   frmPkt->pushp = nextFrmPtr;
415   /*      Increment semaphore count for each frame pushed.
416    Decrement is in waitforsinglefepframe */
417   return False;
418 }
419 
420 /************************************************************************
421  * Sets oldest frame pointer (Use with caution)                         *
422  ************************************************************************
423  *
424  * NOTES
425  *
426  * If 'masterREC', 'pullp' is manipulated, otherwise one of the
427  * multiple recognition pointers, 'auxPullp[]' is used.
428  *
429  ************************************************************************
430  *
431  * CAUTION
432  *
433  * With multiple recognizers, the gap-test doesn't work !!!
434  *
435  ************************************************************************
436  *
437  * Arguments: "frmPkt"     Pointer to Frame Packet
438  *            "fCnt"       Frame offset from Newest Frame
439  *                              +ve == Increase Distance between oldest & newest
440  *                              -ve == Decrease Distance
441  *            "mode"           ZERO means movement wrt Newest Frame
442  *                         non-ZERO means movement wrt Current Oldest Frame
443  *
444  * Retunrs:   int          Status of operation
445  *                          No Problems: False
446  *                          No FEP     : DUKRC_NOFEP
447  *
448  * Critical section code!
449  *
450  ************************************************************************/
451 
setRECframePtr(fepFramePkt * frmPkt,int fCnt,int mode)452 int setRECframePtr(fepFramePkt* frmPkt, int fCnt, int mode)
453 {
454   int   gap;
455 
456   ASSERT(frmPkt);
457 
458   if (mode != 0) /* wrt Current Oldest Frame */
459   {
460     /************
461     * Relative *
462     ************/
463 
464     /* Can it go backwards? */
465 
466     gap = POINTER_GAP(frmPkt, frmPkt->pullp, frmPkt->pushBlkp);
467     if (fCnt > gap)                         /* Limit movement      */
468       fCnt = gap;
469 
470     /* Can it go forwards? */
471 
472     gap = POINTER_GAP(frmPkt, frmPkt->pushp, frmPkt->pullp);
473     if (fCnt < -gap)                         /* Limit movement      */
474       fCnt = -gap;
475 
476     frmPkt->pullp = FIX_FRAME_POINTER(frmPkt,
477                                       frmPkt->pullp - fCnt * frmPkt->frameSize);
478     frmPkt->pullTime -= fCnt;
479 
480   }
481   else  /* wrt Newest Frame */
482   {
483     /************
484     * Absolute *
485     ************/
486 
487     /* ASSERT(fCnt); moved from the above block, do we need this? */
488     ASSERT(frmPkt->isCollecting != FB_DEAD);
489 
490     gap = POINTER_GAP(frmPkt, frmPkt->pushp, frmPkt->pushBlkp);
491 
492     if (fCnt > gap)                         /* Limit movement      */
493       fCnt = gap;
494 
495     frmPkt->pullp = FIX_FRAME_POINTER(frmPkt,
496                                       frmPkt->pushp - fCnt * frmPkt->frameSize);
497     frmPkt->pullTime = frmPkt->pushTime - fCnt;
498 
499   }
500 
501   return (fCnt);
502   ;
503 }
504 
505 /************************************************************************
506  * Returns Pointer to Oldest unread REC frame                           *
507  ************************************************************************
508  *
509  * Arguments: "frmPkt"  Frame Buffer Pointer
510  *
511  * Retunrs:   featdata*   Pointer to newest frame
512  *                          NULL on Error
513  *
514  ************************************************************************/
515 
currentRECframePtr(fepFramePkt * frmPkt)516 featdata* currentRECframePtr(fepFramePkt* frmPkt)
517 {
518   ASSERT(frmPkt);
519   if (frmPkt->pushp == frmPkt->pushBlkp)            /* uninitialized? */
520     return NULL;
521   return ((featdata *)frmPkt->pullp);
522 }
523 
524 /************************************************************************
525  * Returns Pointer to Newest Complete frame of given channel            *
526  ************************************************************************
527  *
528  * Arguments: "frmPkt"  Frame Buffer Pointer
529  *
530  * Retunrs:   featdata*   Pointer to newest frame
531  *                          NULL on Error.
532  *
533  ************************************************************************/
534 
currentFEPframePtr(fepFramePkt * frmPkt)535 featdata* currentFEPframePtr(fepFramePkt* frmPkt)
536 {
537   featdata* frmPtr;
538 
539   ASSERT(frmPkt);
540   frmPtr = frmPkt->pushp;  /* Where is FEP?    */
541   if (frmPtr == NULL)
542     return NULL;
543   (void) decThisFramePtr(frmPkt, &frmPtr);/* Move backwards   */
544   return frmPtr;
545 }
546 
547 /************************************************************************
548  * Moves REC's Frame Pointer backwards one Frame (if it can)            *
549  ************************************************************************
550  *
551  * NOTES
552  *
553  * If 'masterREC', 'pullp' is manipulated, otherwise one of the
554  * multiple recognition pointers, 'auxPullp[]' is used. (not sure about this)
555  * The pushBlkp is also moved accordingly.
556  *
557  ************************************************************************
558  *
559  * Arguments: "n"      Channel Number of Selected Frame
560  *
561  * Retunrs:   int      Non-zero on error
562  *
563  ************************************************************************/
564 
incRECframePtr(fepFramePkt * frmPkt)565 int incRECframePtr(fepFramePkt* frmPkt)
566 {
567   ASSERT(frmPkt);
568 
569   /* Ensure that the frame buffer for *
570    * the channel specified exists     */
571 
572   if (frmPkt->pullp == frmPkt->pushp)
573     return True;
574 
575 
576   frmPkt->pullp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pullp);
577 
578   frmPkt->pullTime++;
579   if (frmPkt->pullTime == 0)  /* Check for wrap and ensure */
580     frmPkt->pullTime++;     /* that it is never ZERO     */
581 
582   /* New 'pushBlkp' */
583   if (frmPkt->blockLen > 0 && frmPkt->isCollecting == FB_ACTIVE)
584   {
585     if (POINTER_GAP(frmPkt, frmPkt->pullp, frmPkt->pushBlkp) >= frmPkt->blockLen)
586     {
587       frmPkt->pushBlkp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pushBlkp);
588     }
589   }
590 
591   return False;
592 }
593 
594 /************************************************************************
595  * Moves REC's Frame Pointer backwards one Frame (if it can)            *
596  ************************************************************************
597  *
598  * NOTES
599  *
600  * If 'masterREC', 'pullp' is manipulated, otherwise one of the
601  * multiple recognition pointers, 'auxPullp[]' is used. (not sure about this)
602  * The pushBlkp is also moved accordingly.
603  *
604  ************************************************************************
605  *
606  * Arguments: "n"      Channel Number of Selected Frame
607  *
608  * Retunrs:   int      Non-zero on error
609  *
610  ************************************************************************/
611 
decRECframePtr(fepFramePkt * frmPkt)612 int decRECframePtr(fepFramePkt* frmPkt)
613 {
614   ASSERT(frmPkt);
615 
616   /* Ensure that the frame buffer for *
617    * the channel specified exists     */
618 
619   /* New 'pullp' */
620 
621   if (frmPkt->pullp == frmPkt->pushBlkp) return True;
622   frmPkt->pullp = PREV_FRAME_POINTER(frmPkt, frmPkt->pullp);
623   frmPkt->pullTime--;
624   return False;
625 }
626 
627 /************************************************************************
628  * Moves a Frame Pointer forwards one Frame (if it can)                 *
629  ************************************************************************
630  *
631  * Arguments: "n"      Channel Number of Selected Frame
632  *            "parPtr" Current Frame Pointer
633  *
634  * Retunrs:   int      Non-zero on error
635  *                     "parPtr" and "sigPtr" may have changed
636  *
637  * Caution:            Does not test to see whether 'parPtr' lies
638  *                     legally within the appropriate buffer or on an
639  *                     appropriate valid frame boundary
640  *
641  *                     The caller should NEVER modify frame buffer
642  *                     pointers by hand, always call an RTT-supplied function
643  *
644  ************************************************************************/
645 
incThisFramePtr(fepFramePkt * frmPkt,featdata ** parPtr)646 static int incThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr)
647 {
648   ASSERT(frmPkt);
649   ASSERT(parPtr);
650   if (*parPtr == frmPkt->pushp)
651     return True;
652   *parPtr = NEXT_FRAME_POINTER(frmPkt, *parPtr);
653   return False;
654 }
655 
656 /************************************************************************
657  * Moves a Frame Pointer backwards one Frame (if it can)                *
658  ************************************************************************
659  *
660  * Arguments: "frmPkt" Frame Buffer Pointer
661  *            "parPtr" Current Frame Pointer
662  *            "sigPtr" Signal Pointer
663  *                          Set to NULL if not required
664  *
665  * Retunrs:   int      Non-zero on error
666  *                     "parPtr" may have changed
667  *
668  * Caution:            Checks for bound within pushBlkp.
669  *                     The caller should NEVER modify frame buffer
670  *                     pointers by hand, always call an RTT-supplied function
671  *
672  ************************************************************************/
673 
decThisFramePtr(fepFramePkt * frmPkt,featdata ** parPtr)674 static int decThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr)
675 {
676   ASSERT(frmPkt);
677   ASSERT(parPtr);
678   if (*parPtr == frmPkt->pushBlkp)
679     return True;
680   *parPtr = PREV_FRAME_POINTER(frmPkt, *parPtr);
681   return False;
682 }
683 
684 /************************************************************************
685  ************************************************************************/
686 
getVoicingCode(fepFramePkt * frmPkt,featdata * frmptr)687 featdata getVoicingCode(fepFramePkt* frmPkt, featdata *frmptr)
688 {
689   ASSERT(frmPkt);
690   frmptr = CHECK_BOUND(frmPkt, frmptr);
691   if (frmptr && frmPkt->haveVoiced)
692     return (frmptr[frmPkt->uttDim]);
693   else
694     return (0);
695 }
696 
697 /************************************************************************
698  ************************************************************************/
699 
setVoicingCode(fepFramePkt * frmPkt,featdata * frmptr,featdata vcode)700 void setVoicingCode(fepFramePkt* frmPkt, featdata *frmptr, featdata vcode)
701 {
702   ASSERT(frmPkt);
703   frmptr = CHECK_BOUND(frmPkt, frmptr);
704   if (frmptr && frmPkt->haveVoiced)
705     frmptr[frmPkt->uttDim] =
706       SET_VOICING_CODES(frmptr[frmPkt->uttDim], vcode);
707   return;
708 }
709 
710 /************************************************************************
711  ************************************************************************/
712 
clearC0Entries(fepFramePkt * frmPkt)713 void clearC0Entries(fepFramePkt* frmPkt)
714 {
715   ASSERT(frmPkt);
716   frmPkt->maxC0 = 0;           /*  Assuming a normal range of 0 - 255 */
717   frmPkt->minC0 = 255;
718   return;
719 }
720 
get_background_statistics(fepFramePkt * frmPkt,int start,int end,spect_dist_info ** spec,int num,int relative_to_pullp)721 int get_background_statistics(fepFramePkt *frmPkt, int start, int end,
722                               spect_dist_info **spec, int num,
723                               int relative_to_pullp)
724 {
725   int len, /* count= 0, */ num_frames = 0;
726   int ii, jj, got;
727   featdata  *frame_ptr;
728 #ifndef NDEBUG
729   featdata  *base_ptr = NULL;
730 #endif
731 
732   ASSERT(frmPkt);
733   ASSERT(spec);
734   if (!frmPkt->haveVoiced) return(0);
735   if (start == end || (start == 0 && !relative_to_pullp))
736     return (0);
737 
738   /*  Cannot access the frames
739   */
740   if (relative_to_pullp && getBlockGap(frmPkt) < start)
741     return (0);
742 
743   ASSERT(base_ptr = frmPkt->pullp);
744   got = setRECframePtr(frmPkt, end, relative_to_pullp);
745   if (got != end)
746   {
747     (void) setRECframePtr(frmPkt, -got, relative_to_pullp);
748     ASSERT(base_ptr == currentRECframePtr(frmPkt));
749     return (0);
750   }
751   len = start - end;
752 
753   for (ii = 0; ii < len; ii++)
754   {
755     decRECframePtr(frmPkt);
756     frame_ptr   = currentRECframePtr(frmPkt);
757 #if DEBUG
758     log_report("%d %d %x\n", frame_ptr[0],
759                frame_ptr[frmPkt->uttDim], frame_ptr);
760 #endif
761     if ((frame_ptr[frmPkt->uttDim] & BELOW_THRESHOLD_BIT))
762     {
763       num_frames++;
764       for (jj = 0; jj < num; jj++)
765       {
766         ASSERT(spec[jj]);
767         add_distribution_data(spec[jj], (int) frame_ptr[jj]);
768       }
769     }
770   }
771 #if DEBUG
772   log_report("End of chunk\n");
773 #endif
774 
775   /* Put it back in the same place !
776   */
777   if (start != 0)
778     (void) setRECframePtr(frmPkt, -start, relative_to_pullp);
779   ASSERT(base_ptr == currentRECframePtr(frmPkt));
780   return (num_frames);
781 }
782 
utterance_detection_fixup(fepFramePkt * frmPkt,featdata ** last_pushp,int voice_duration,int quite_duration,int unsure_duration)783 void utterance_detection_fixup(fepFramePkt *frmPkt, featdata **last_pushp,
784                                int voice_duration, int quite_duration, int unsure_duration)
785 {
786   featdata  *fram;
787   long   gotstat, count, voistat;
788   featdata  *fepFrmPtr, *recFrmPtr, *last_push, voice_result;
789 
790   /* Adjust for delay in decision making by voicing_analysis
791   */
792   ASSERT(frmPkt);
793   ASSERT(last_pushp);
794   fepFrmPtr = currentFEPframePtr(frmPkt);
795   last_push = *last_pushp;
796   if (last_push == fepFrmPtr)
797     return;
798 
799   recFrmPtr = currentRECframePtr(frmPkt);
800   if (last_push == NULL)
801   {
802     last_push = recFrmPtr;
803     voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
804   }
805   else if (decThisFramePtr(frmPkt, &last_push) == False)
806   {
807     voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
808     (void) incThisFramePtr(frmPkt, &last_push);
809   }
810   else
811     voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
812 
813   while (last_push != fepFrmPtr)
814   {
815 
816     gotstat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
817     if (gotstat != voistat)
818     {
819       /*  Voicing status has changed
820       */
821       fram = last_push;
822       voice_result = getVoicingCode(frmPkt, fram);
823       if (FAST_BIT_SET(voice_result))
824       {
825         for (count = voice_duration; count > 0 && fram != recFrmPtr;
826              count--)
827         {
828           if (decThisFramePtr(frmPkt, &fram) != False)
829             break;
830 #if DEBUG_REWIND
831           log_report("U: voice rewind at %d was %x\n", frmPkt->pullTime
832                      + POINTER_GAP(frmPkt, fram, recFrmPtr),
833                      getVoicingCode(frmPkt, fram));
834 #endif
835           setVoicingCode(frmPkt, fram, REC_VOICE_BIT);
836         }
837 
838         /* set to unsure for start period of voicing
839         */
840         for (count = 0; count < unsure_duration && fram != recFrmPtr;
841              count++)
842         {
843           if (decThisFramePtr(frmPkt, &fram) != False)
844             break;
845 #if DEBUG_REWIND
846           log_report("U: unsure rewind at %d was %x\n", frmPkt->pullTime
847                      + POINTER_GAP(frmPkt, fram, recFrmPtr),
848                      getVoicingCode(frmPkt, fram));
849 #endif
850           setVoicingCode(frmPkt, fram, REC_UNSURE_BIT);
851         }
852       }
853 
854       else if (QUIET_BIT_SET(voice_result))
855       {
856         for (count = quite_duration; count > 0 && fram != recFrmPtr;
857              count--)
858         {
859           if (decThisFramePtr(frmPkt, &fram) != False)
860             break;
861 #if DEBUG_REWIND
862           log_report("U: quiet rewind at %d was %x\n", frmPkt->pullTime
863                      + POINTER_GAP(frmPkt, fram, recFrmPtr),
864                      getVoicingCode(frmPkt, fram));
865 #endif
866           setVoicingCode(frmPkt, fram, REC_QUIET_BIT);
867         }
868       }
869 
870       voistat = gotstat;
871     }
872 
873     /* copy to recognizer bits if status not changed */
874 #if DEBUG_REWIND
875     log_report("U: copying at %d was %x\n", frmPkt->pullTime
876                + POINTER_GAP(frmPkt, last_push, recFrmPtr),
877                getVoicingCode(frmPkt, last_push));
878 #endif
879     if (QUIET_BIT_SET(getVoicingCode(frmPkt, last_push)))
880       setVoicingCode(frmPkt, last_push, REC_QUIET_BIT);
881     else if (FAST_BIT_SET(getVoicingCode(frmPkt, last_push)))
882       setVoicingCode(frmPkt, last_push, REC_VOICE_BIT);
883     else
884       setVoicingCode(frmPkt, last_push, REC_UNSURE_BIT);
885 
886     if (incThisFramePtr(frmPkt, &last_push) != False) break;
887   }
888 
889   *last_pushp = last_push;
890   return;
891 }
892 
rec_frame_voicing_status(fepFramePkt * frmPkt)893 int rec_frame_voicing_status(fepFramePkt *frmPkt)
894 {
895   ASSERT(frmPkt);
896   return (getVoicingCode(frmPkt, (featdata *)frmPkt->pullp));
897 }
898