blob: 1f0b5fa3fddab66a3a2e576b57000a9637c6ffc1 [file] [log] [blame]
/*---------------------------------------------------------------------------*
* fpi_tgt.c *
* *
* Copyright 2007, 2008 Nuance Communciations, Inc. *
* *
* Licensed under the Apache License, Version 2.0 (the 'License'); *
* you may not use this file except in compliance with the License. *
* *
* You may obtain a copy of the License at *
* http://www.apache.org/licenses/LICENSE-2.0 *
* *
* Unless required by applicable law or agreed to in writing, software *
* distributed under the License is distributed on an 'AS IS' BASIS, *
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. *
* See the License for the specific language governing permissions and *
* limitations under the License. *
* *
*---------------------------------------------------------------------------*/
#ifndef _RTT
#include <stdio.h>
#endif
#include <assert.h>
#include "all_defs.h"
#include "fpi_tgt.h"
#include "voicing.h"
#include "portable.h"
#include "fpi_tgt.inl"
#define DEBUG_REWIND 0
/************************************************************************
* Create a Frame Buffer *
************************************************************************
*
* On the Real Time Target (_RTT) the caller of this function is
* responsible for publically declaring the location of the Frame Buffer
* so that the REC unit can locate it. This is achived by use of the
* 'setPublicLocation()' and 'publicLocation()' functions.
*
************************************************************************
*
* Arguments: "fCnt" Size of Frame Stack
* "dimen" Size of Frame
* "blockLen" Blocking length (if Using)
* "doVoice" Reserve voicing parameter
*
* Returns: fepFramePkt* Pointer to frame buffer
* NULL on error
*
************************************************************************/
static int incThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr);
static int decThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr);
fepFramePkt* createFrameBuffer(int fCnt, int dimen, int blockLen, int doVoice)
{
fepFramePkt* frmPkt;
#if QUICK
unsigned long frame_mask = 1, tmpsiz;
#endif
ASSERT(fCnt > 0);
ASSERT(dimen > 0);
/* Allocate space for the Frame Packet *
* and then accommodate the Frame Stack */
frmPkt = (fepFramePkt*) CALLOC_CLR(1, sizeof(fepFramePkt), "clib.Frame_Buffer");
if (frmPkt == NULL)
return NULL;
#if QUICK
tmpsiz = blockLen;
frame_mask = 1;
tmpsiz >>= 1;
while (tmpsiz)
{
frame_mask = (frame_mask << 1) | 0x01;
tmpsiz >>= 1;
}
blockLen = frame_mask + 1;
frmPkt->stackMask = frame_mask;
#endif
frmPkt->uttDim = dimen;
if (doVoice) dimen++;
frmPkt->frameStackSize = fCnt;
frmPkt->frameSize = dimen;
frmPkt->featuresInStack = fCnt * dimen;
frmPkt->blockLen = blockLen;
if (doVoice) frmPkt->haveVoiced = True;
else frmPkt->haveVoiced = False;
frmPkt->frameStack = (featdata *) CALLOC(fCnt,
sizeof(featdata) * dimen, "clib.Frame_Stack");
if (frmPkt == NULL)
return NULL;
frmPkt->lastFrameInStack = frmPkt->frameStack + (fCnt - 1) * dimen;
/* Use standard function to clear the buffer, *
* we don't care about the return code because *
* we built it, others should care... */
(void) clearFrameBuffer(frmPkt);
frmPkt->uttTimeout = 20; /* default setting */
return frmPkt;
}
/************************************************************************
* Clear an existing Frame Buffer *
************************************************************************
*
* Given a pointer to a previously created frame buffer structure
* this funtion will reset its member components to their initial
* values.
*
************************************************************************
*
* Arguments: "frmPkt" Frame Buffer Structure Pointer
*
* Returns: int non-ZERO on Error
*
************************************************************************/
int clearFrameBuffer(fepFramePkt* frmPkt)
{
ASSERT(frmPkt != NULL);
/* Clear the frame stack to ZERO as *
* this is done by model_allocate() */
memset(frmPkt->frameStack, 0, /* TODO: do we need this? */
sizeof(featdata) * frmPkt->frameSize * frmPkt->frameStackSize);
/* Reset Structure Members */
frmPkt->isCollecting = FB_IDLE;
frmPkt->pullp = frmPkt->frameStack;
frmPkt->pushp = frmPkt->frameStack;
frmPkt->pushBlkp = frmPkt->frameStack;
frmPkt->pushBlocked = False;
frmPkt->blockTime = 0;
frmPkt->pushTime = 1; /* 0 == invalid frame ID, 1 == first */
frmPkt->pullTime = 1;
frmPkt->startTime = 0; /* 0 == start hasn't been called */
frmPkt->stopTime = 0; /* 0 == stop hasn't been called */
clearEndOfUtterance(frmPkt);
clearC0Entries(frmPkt);
return False;
}
/************************************************************************
* Destroy a Previously Created Frame Buffer *
************************************************************************
*
* On the Real Time Target (_RTT) the caller of this function is
* responsible for publically declaring the location of the Frame Buffer
* so that the REC unit can locate it. This is achived by use of the
* 'setPublicLocation()' and 'publicLocation()' functions.
*
************************************************************************
*
* Arguments: fepFramePkt* Pointer to frame buffer to destroy
*
* Returns: int non-ZERO on error
*
************************************************************************/
int destroyFrameBuffer(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
/* De-allocate space for the Frame Stack *
* and then the Frame Packet */
FREE(frmPkt->frameStack);
FREE(frmPkt);
return False;
}
/************************************************************************
* To Start Collecting Frames *
***********************************************************************/
void startFrameCollection(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
if (frmPkt->isCollecting == FB_IDLE)
{
clearEndOfUtterance(frmPkt);
clearC0Entries(frmPkt);
frmPkt->startTime = frmPkt->pushTime;
frmPkt->stopTime = 0;
frmPkt->isCollecting = FB_ACTIVE;
}
return;
}
/************************************************************************
* To Stop Collecting Frames *
***********************************************************************/
int stopFrameCollection(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
ASSERT(frmPkt->startTime != 0);
if (frmPkt->isCollecting == FB_ACTIVE)
{
/* Remember, pushTime is the ID of the next frame to arrive
* The buffer starts empty, with pushTime == 1.
* So if Stop occurs at this point, then the start and end frames
* will be
*/
frmPkt->stopTime = frmPkt->pushTime;
frmPkt->isCollecting = FB_IDLE;
return (True);
}
return (False);
}
/************************************************************************
***********************************************************************/
void setupEndOfUtterance(fepFramePkt* frmPkt, long timeout, long holdOff)
{
ASSERT(frmPkt);
ASSERT(timeout >= 0);
ASSERT(holdOff >= 0);
frmPkt->uttTimeout = timeout;
frmPkt->holdOffPeriod = holdOff;
frmPkt->holdOff = 0;
return;
}
/************************************************************************
***********************************************************************/
void clearEndOfUtterance(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
ASSERT(frmPkt->holdOffPeriod >= 0);
frmPkt->voicingDetected = 0;
frmPkt->quietFrames = 0;
frmPkt->utt_ended = False;
frmPkt->holdOff = frmPkt->holdOffPeriod;
return;
}
void releaseBlockedFramesInBuffer(fepFramePkt* frmPkt)
{
frmPkt->pullp = frmPkt->pushp; /* Move the Blocker to pullp */
frmPkt->pushBlkp = frmPkt->pushp; /* Move the Blocker to pullp */
frmPkt->pullTime = frmPkt->pushTime;
frmPkt->blockTime = frmPkt->pushTime;
return;
}
/************************************************************************
* Push a Single Frame into Frame Buffer *
************************************************************************
*
* Inserts a new frame into the frame buffer.
*
* If there is no room in the buffer (the frame maker has exhausted the
* space which is being slowly 'eaten' by the associated recognizer) then
* the data is not inserted and an error value is returned. For this to
* happen, blockLen member must be set. Otherwise pushBlkp will always
* point to the oldest valid frame in the buffer.
*
************************************************************************
*
* Arguments: "frmPkt" Frame Buffer Pointer
* "parPtr" Pointer to contiguous block of Frame Parameters
*
* Returns: int non-ZERO on ERROR
*
************************************************************************/
int pushSingleFEPframe(fepFramePkt* frmPkt, featdata* parPtr, int voiceData)
{
featdata* destFrmPtr;
featdata* nextFrmPtr;
ASSERT(frmPkt);
ASSERT(parPtr);
/* 'pushp' must be either within the frame buffer or NULL. *
* If it is NULL then the frame is just discarded. */
if (frmPkt->isCollecting != FB_ACTIVE) return True;
if ((destFrmPtr = nextFrmPtr = (featdata*) frmPkt->pushp) == NULL)
return (0);
#if DEBUG_REWIND
log_report("U: voicing at %d was %x\n", frmPkt->pushTime, voiceData);
#endif
/* Copy the frame into the buffer. Once this is done *
* advance 'pushp' (unless it is up against the 'blocker' *
* The frame consists of Parameters and Signal Data */
memcpy(destFrmPtr, parPtr, frmPkt->uttDim * sizeof(featdata));
if (frmPkt->haveVoiced)
destFrmPtr[frmPkt->uttDim] = voiceData;
/* The following (vocing detection which triggers EOU),
* is only active when the 'holdOff' member is 0.
* The intension is to delay 'voicing' signal for at least
* 'holdOffPeriod' frames.
*/
if (frmPkt->holdOff <= 0)
{
if (frmPkt->haveVoiced && frmPkt->utt_ended == False)
{
if (voiceData & VOICE_BIT)
{
frmPkt->voicingDetected = 1;
}
if (voiceData & QUIET_BIT)
{
frmPkt->quietFrames++;
if (frmPkt->voicingDetected
&& frmPkt->quietFrames > frmPkt->uttTimeout)
{
log_report("Level based utterance ended at %d\n",
frmPkt->pushTime);
frmPkt->utt_ended = True;
}
}
else
frmPkt->quietFrames = 0;
}
}
else
{
ASSERT(frmPkt->holdOff > 0);
frmPkt->holdOff--;
}
/* Track C0 values
*/
if (frmPkt->maxC0 < parPtr[0]) /* only works if the 0th entry - */
frmPkt->maxC0 = parPtr[0]; /* is C0 */
if (frmPkt->minC0 > parPtr[0]) /* only works if the 0th entry - */
frmPkt->minC0 = parPtr[0]; /* is C0 */
frmPkt->pushTime++;
if (frmPkt->pushTime == 0L) /* Check for wrap - and ensure */
frmPkt->pushTime++; /* ZERO is NEVER used */
/* Try to move the push pointer on, if it meets the *
* push blocker it should not increment. */
nextFrmPtr = (featdata *) NEXT_FRAME_POINTER(frmPkt, frmPkt->pushp);
if (nextFrmPtr == frmPkt->pullp)
{
/* Latest Frame was blocked, so record the fact and then *
* record the frame time that this occured (useful?) */
frmPkt->pushBlocked++;
frmPkt->blockTime = frmPkt->pushTime;
return True;
}
else if (nextFrmPtr == frmPkt->pushBlkp)
{
if (frmPkt->blockLen == 0)
{
/* Simply move pushBlkp along */
frmPkt->pushBlkp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pushBlkp);
}
else
{
/* Latest Frame was blocked, so record the fact and then *
* record the frame time that this occured (useful?) */
frmPkt->pushBlocked++;
frmPkt->blockTime = frmPkt->pushTime;
return True;
}
}
/* Free to move ahead, so increment the push pointer *
* and increase the frame-count between pull & push */
frmPkt->pushp = nextFrmPtr;
/* Increment semaphore count for each frame pushed.
Decrement is in waitforsinglefepframe */
return False;
}
/************************************************************************
* Sets oldest frame pointer (Use with caution) *
************************************************************************
*
* NOTES
*
* If 'masterREC', 'pullp' is manipulated, otherwise one of the
* multiple recognition pointers, 'auxPullp[]' is used.
*
************************************************************************
*
* CAUTION
*
* With multiple recognizers, the gap-test doesn't work !!!
*
************************************************************************
*
* Arguments: "frmPkt" Pointer to Frame Packet
* "fCnt" Frame offset from Newest Frame
* +ve == Increase Distance between oldest & newest
* -ve == Decrease Distance
* "mode" ZERO means movement wrt Newest Frame
* non-ZERO means movement wrt Current Oldest Frame
*
* Retunrs: int Status of operation
* No Problems: False
* No FEP : DUKRC_NOFEP
*
* Critical section code!
*
************************************************************************/
int setRECframePtr(fepFramePkt* frmPkt, int fCnt, int mode)
{
int gap;
ASSERT(frmPkt);
if (mode != 0) /* wrt Current Oldest Frame */
{
/************
* Relative *
************/
/* Can it go backwards? */
gap = POINTER_GAP(frmPkt, frmPkt->pullp, frmPkt->pushBlkp);
if (fCnt > gap) /* Limit movement */
fCnt = gap;
/* Can it go forwards? */
gap = POINTER_GAP(frmPkt, frmPkt->pushp, frmPkt->pullp);
if (fCnt < -gap) /* Limit movement */
fCnt = -gap;
frmPkt->pullp = FIX_FRAME_POINTER(frmPkt,
frmPkt->pullp - fCnt * frmPkt->frameSize);
frmPkt->pullTime -= fCnt;
}
else /* wrt Newest Frame */
{
/************
* Absolute *
************/
/* ASSERT(fCnt); moved from the above block, do we need this? */
ASSERT(frmPkt->isCollecting != FB_DEAD);
gap = POINTER_GAP(frmPkt, frmPkt->pushp, frmPkt->pushBlkp);
if (fCnt > gap) /* Limit movement */
fCnt = gap;
frmPkt->pullp = FIX_FRAME_POINTER(frmPkt,
frmPkt->pushp - fCnt * frmPkt->frameSize);
frmPkt->pullTime = frmPkt->pushTime - fCnt;
}
return (fCnt);
;
}
/************************************************************************
* Returns Pointer to Oldest unread REC frame *
************************************************************************
*
* Arguments: "frmPkt" Frame Buffer Pointer
*
* Retunrs: featdata* Pointer to newest frame
* NULL on Error
*
************************************************************************/
featdata* currentRECframePtr(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
if (frmPkt->pushp == frmPkt->pushBlkp) /* uninitialized? */
return NULL;
return ((featdata *)frmPkt->pullp);
}
/************************************************************************
* Returns Pointer to Newest Complete frame of given channel *
************************************************************************
*
* Arguments: "frmPkt" Frame Buffer Pointer
*
* Retunrs: featdata* Pointer to newest frame
* NULL on Error.
*
************************************************************************/
featdata* currentFEPframePtr(fepFramePkt* frmPkt)
{
featdata* frmPtr;
ASSERT(frmPkt);
frmPtr = frmPkt->pushp; /* Where is FEP? */
if (frmPtr == NULL)
return NULL;
(void) decThisFramePtr(frmPkt, &frmPtr);/* Move backwards */
return frmPtr;
}
/************************************************************************
* Moves REC's Frame Pointer backwards one Frame (if it can) *
************************************************************************
*
* NOTES
*
* If 'masterREC', 'pullp' is manipulated, otherwise one of the
* multiple recognition pointers, 'auxPullp[]' is used. (not sure about this)
* The pushBlkp is also moved accordingly.
*
************************************************************************
*
* Arguments: "n" Channel Number of Selected Frame
*
* Retunrs: int Non-zero on error
*
************************************************************************/
int incRECframePtr(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
/* Ensure that the frame buffer for *
* the channel specified exists */
if (frmPkt->pullp == frmPkt->pushp)
return True;
frmPkt->pullp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pullp);
frmPkt->pullTime++;
if (frmPkt->pullTime == 0) /* Check for wrap and ensure */
frmPkt->pullTime++; /* that it is never ZERO */
/* New 'pushBlkp' */
if (frmPkt->blockLen > 0 && frmPkt->isCollecting == FB_ACTIVE)
{
if (POINTER_GAP(frmPkt, frmPkt->pullp, frmPkt->pushBlkp) >= frmPkt->blockLen)
{
frmPkt->pushBlkp = NEXT_FRAME_POINTER(frmPkt, frmPkt->pushBlkp);
}
}
return False;
}
/************************************************************************
* Moves REC's Frame Pointer backwards one Frame (if it can) *
************************************************************************
*
* NOTES
*
* If 'masterREC', 'pullp' is manipulated, otherwise one of the
* multiple recognition pointers, 'auxPullp[]' is used. (not sure about this)
* The pushBlkp is also moved accordingly.
*
************************************************************************
*
* Arguments: "n" Channel Number of Selected Frame
*
* Retunrs: int Non-zero on error
*
************************************************************************/
int decRECframePtr(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
/* Ensure that the frame buffer for *
* the channel specified exists */
/* New 'pullp' */
if (frmPkt->pullp == frmPkt->pushBlkp) return True;
frmPkt->pullp = PREV_FRAME_POINTER(frmPkt, frmPkt->pullp);
frmPkt->pullTime--;
return False;
}
/************************************************************************
* Moves a Frame Pointer forwards one Frame (if it can) *
************************************************************************
*
* Arguments: "n" Channel Number of Selected Frame
* "parPtr" Current Frame Pointer
*
* Retunrs: int Non-zero on error
* "parPtr" and "sigPtr" may have changed
*
* Caution: Does not test to see whether 'parPtr' lies
* legally within the appropriate buffer or on an
* appropriate valid frame boundary
*
* The caller should NEVER modify frame buffer
* pointers by hand, always call an RTT-supplied function
*
************************************************************************/
static int incThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr)
{
ASSERT(frmPkt);
ASSERT(parPtr);
if (*parPtr == frmPkt->pushp)
return True;
*parPtr = NEXT_FRAME_POINTER(frmPkt, *parPtr);
return False;
}
/************************************************************************
* Moves a Frame Pointer backwards one Frame (if it can) *
************************************************************************
*
* Arguments: "frmPkt" Frame Buffer Pointer
* "parPtr" Current Frame Pointer
* "sigPtr" Signal Pointer
* Set to NULL if not required
*
* Retunrs: int Non-zero on error
* "parPtr" may have changed
*
* Caution: Checks for bound within pushBlkp.
* The caller should NEVER modify frame buffer
* pointers by hand, always call an RTT-supplied function
*
************************************************************************/
static int decThisFramePtr(fepFramePkt* frmPkt, featdata** parPtr)
{
ASSERT(frmPkt);
ASSERT(parPtr);
if (*parPtr == frmPkt->pushBlkp)
return True;
*parPtr = PREV_FRAME_POINTER(frmPkt, *parPtr);
return False;
}
/************************************************************************
************************************************************************/
featdata getVoicingCode(fepFramePkt* frmPkt, featdata *frmptr)
{
ASSERT(frmPkt);
frmptr = CHECK_BOUND(frmPkt, frmptr);
if (frmptr && frmPkt->haveVoiced)
return (frmptr[frmPkt->uttDim]);
else
return (0);
}
/************************************************************************
************************************************************************/
void setVoicingCode(fepFramePkt* frmPkt, featdata *frmptr, featdata vcode)
{
ASSERT(frmPkt);
frmptr = CHECK_BOUND(frmPkt, frmptr);
if (frmptr && frmPkt->haveVoiced)
frmptr[frmPkt->uttDim] =
SET_VOICING_CODES(frmptr[frmPkt->uttDim], vcode);
return;
}
/************************************************************************
************************************************************************/
void clearC0Entries(fepFramePkt* frmPkt)
{
ASSERT(frmPkt);
frmPkt->maxC0 = 0; /* Assuming a normal range of 0 - 255 */
frmPkt->minC0 = 255;
return;
}
int get_background_statistics(fepFramePkt *frmPkt, int start, int end,
spect_dist_info **spec, int num,
int relative_to_pullp)
{
int len, /* count= 0, */ num_frames = 0;
int ii, jj, got;
featdata *frame_ptr;
#ifndef NDEBUG
featdata *base_ptr = NULL;
#endif
ASSERT(frmPkt);
ASSERT(spec);
if (!frmPkt->haveVoiced) return(0);
if (start == end || (start == 0 && !relative_to_pullp))
return (0);
/* Cannot access the frames
*/
if (relative_to_pullp && getBlockGap(frmPkt) < start)
return (0);
ASSERT(base_ptr = frmPkt->pullp);
got = setRECframePtr(frmPkt, end, relative_to_pullp);
if (got != end)
{
(void) setRECframePtr(frmPkt, -got, relative_to_pullp);
ASSERT(base_ptr == currentRECframePtr(frmPkt));
return (0);
}
len = start - end;
for (ii = 0; ii < len; ii++)
{
decRECframePtr(frmPkt);
frame_ptr = currentRECframePtr(frmPkt);
#if DEBUG
log_report("%d %d %x\n", frame_ptr[0],
frame_ptr[frmPkt->uttDim], frame_ptr);
#endif
if ((frame_ptr[frmPkt->uttDim] & BELOW_THRESHOLD_BIT))
{
num_frames++;
for (jj = 0; jj < num; jj++)
{
ASSERT(spec[jj]);
add_distribution_data(spec[jj], (int) frame_ptr[jj]);
}
}
}
#if DEBUG
log_report("End of chunk\n");
#endif
/* Put it back in the same place !
*/
if (start != 0)
(void) setRECframePtr(frmPkt, -start, relative_to_pullp);
ASSERT(base_ptr == currentRECframePtr(frmPkt));
return (num_frames);
}
void utterance_detection_fixup(fepFramePkt *frmPkt, featdata **last_pushp,
int voice_duration, int quite_duration, int unsure_duration)
{
featdata *fram;
long gotstat, count, voistat;
featdata *fepFrmPtr, *recFrmPtr, *last_push, voice_result;
/* Adjust for delay in decision making by voicing_analysis
*/
ASSERT(frmPkt);
ASSERT(last_pushp);
fepFrmPtr = currentFEPframePtr(frmPkt);
last_push = *last_pushp;
if (last_push == fepFrmPtr)
return;
recFrmPtr = currentRECframePtr(frmPkt);
if (last_push == NULL)
{
last_push = recFrmPtr;
voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
}
else if (decThisFramePtr(frmPkt, &last_push) == False)
{
voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
(void) incThisFramePtr(frmPkt, &last_push);
}
else
voistat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
while (last_push != fepFrmPtr)
{
gotstat = FAST_MATCH_DATA(getVoicingCode(frmPkt, last_push));
if (gotstat != voistat)
{
/* Voicing status has changed
*/
fram = last_push;
voice_result = getVoicingCode(frmPkt, fram);
if (FAST_BIT_SET(voice_result))
{
for (count = voice_duration; count > 0 && fram != recFrmPtr;
count--)
{
if (decThisFramePtr(frmPkt, &fram) != False)
break;
#if DEBUG_REWIND
log_report("U: voice rewind at %d was %x\n", frmPkt->pullTime
+ POINTER_GAP(frmPkt, fram, recFrmPtr),
getVoicingCode(frmPkt, fram));
#endif
setVoicingCode(frmPkt, fram, REC_VOICE_BIT);
}
/* set to unsure for start period of voicing
*/
for (count = 0; count < unsure_duration && fram != recFrmPtr;
count++)
{
if (decThisFramePtr(frmPkt, &fram) != False)
break;
#if DEBUG_REWIND
log_report("U: unsure rewind at %d was %x\n", frmPkt->pullTime
+ POINTER_GAP(frmPkt, fram, recFrmPtr),
getVoicingCode(frmPkt, fram));
#endif
setVoicingCode(frmPkt, fram, REC_UNSURE_BIT);
}
}
else if (QUIET_BIT_SET(voice_result))
{
for (count = quite_duration; count > 0 && fram != recFrmPtr;
count--)
{
if (decThisFramePtr(frmPkt, &fram) != False)
break;
#if DEBUG_REWIND
log_report("U: quiet rewind at %d was %x\n", frmPkt->pullTime
+ POINTER_GAP(frmPkt, fram, recFrmPtr),
getVoicingCode(frmPkt, fram));
#endif
setVoicingCode(frmPkt, fram, REC_QUIET_BIT);
}
}
voistat = gotstat;
}
/* copy to recognizer bits if status not changed */
#if DEBUG_REWIND
log_report("U: copying at %d was %x\n", frmPkt->pullTime
+ POINTER_GAP(frmPkt, last_push, recFrmPtr),
getVoicingCode(frmPkt, last_push));
#endif
if (QUIET_BIT_SET(getVoicingCode(frmPkt, last_push)))
setVoicingCode(frmPkt, last_push, REC_QUIET_BIT);
else if (FAST_BIT_SET(getVoicingCode(frmPkt, last_push)))
setVoicingCode(frmPkt, last_push, REC_VOICE_BIT);
else
setVoicingCode(frmPkt, last_push, REC_UNSURE_BIT);
if (incThisFramePtr(frmPkt, &last_push) != False) break;
}
*last_pushp = last_push;
return;
}
int rec_frame_voicing_status(fepFramePkt *frmPkt)
{
ASSERT(frmPkt);
return (getVoicingCode(frmPkt, (featdata *)frmPkt->pullp));
}