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 59static int incThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr); 60static int decThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr); 61 62 63 64fepFramePkt* 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 138int 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 185int 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 200void 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 219int 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 245void 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 259void 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 271void 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 302int 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 452int 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 516featdata* 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 535featdata* 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 565int 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 612int 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 646static 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 674static 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 687featdata 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 700void 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 713void 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 721int 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 783void 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 893int rec_frame_voicing_status(fepFramePkt *frmPkt) 894{ 895 ASSERT(frmPkt); 896 return (getVoicingCode(frmPkt, (featdata *)frmPkt->pullp)); 897} 898