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