diff --git a/pasdk/test_dsp/framework/aspDecOpCircBuf_master.c b/pasdk/test_dsp/framework/aspDecOpCircBuf_master.c
index f79f85128dbdd25db0b9ec8491776a4374c830a0..e7349d0546d6fe6027b56aff8cdae955e109d3eb 100644 (file)
#include "pafdec.h"
#include "aspDecOpCircBuf_master.h"
-#include "dbgBenchmark.h" // PCM high-sampling rate + SRC + CAR benchmarking
-
#include "evmc66x_gpio_dbg.h" // Debug
#ifdef CB_RW_OP_CAP_PP // debug
Uint8 *gCB_numAfCb = NULL;
#endif
-#define DEF_SOURCE_SEL ( PAF_SOURCE_PCM ) // default source select
-#define DEF_DEC_OP_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // ( 256 ) // default decoder output frame length
-#define DEF_STR_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // default stream frame length
-
#if 0
// Generate mute AF on circular buffer read
static Void cbReadAfMute(
);
#endif
+#if 0
// Init last audio frame configuration info
static Void cbInitLastAfInfo(
PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
);
+#endif
+
+// Update last audio frame configuration info
+static Void cbUpdateLastAfInfo(
+ PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
+ PAF_AudioFrame *pAfUpd // audio frame used for update
+);
// Generate mute AF on circular buffer read using the last AF configuration info
-static Void cbReadMuteWithLastAfInfo (
+static Void cbReadMuteWithLastAfInfo(
PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
PAF_AudioFrame *pAfRd // audio frame into which to read
);
+#if 0 // FL: moved to common
// Initialize circular buffer control
Int cbCtlInit(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
+ Int8 numCb, // number of circular buffers
PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
)
{
return ASP_DECOP_CB_CTL_INIT_INV_GATE;
}
- pCbCtl->pXDecOpCb = pXDecOpCb;
-
- return ASP_DECOP_CB_SOK;
+ pCbCtl->numCb = numCb; // init number of circular buffers
+ pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
+ return ASP_DECOP_CB_SOK;
}
+#endif
// Initialize circular buffer
Int cbInit(
PAF_AST_DecOpCircBuf *pCb
)
{
+#if 0 // FL: unused
PAF_AudioFrame *pAfCb;
PAF_AudioData *pPcmBuf;
UInt8 *pMetaBuf;
pCb->strFrameLen = DEF_STR_FRAME_LEN;
// initialize circular buffer maximum number of audio frames
- pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;//ASP_DECOP_CB_MAX_NUM_AF_PCM;
+ pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD; //ASP_DECOP_CB_MAX_NUM_AF_PCM;
pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
pCb->afRdIdx = 0;
pCb->pcmRdIdx = 0;
// reset read/write flags
pCb->writerActiveFlag = 0;
pCb->readerActiveFlag = 0;
- pCb->emptyFlag = 0;
+ pCb->drainFlag = 0;
- // reset error counts
+ // reset stats
+ pCb->readAfWriterInactiveCnt = 0;
+ pCb->readAfNdCnt = 0;
+ pCb->wrtAfReaderInactiveCnt = 0;
+ pCb->wrtAfZeroSampsCnt = 0;
pCb->errUndCnt = 0;
pCb->errOvrCnt = 0;
}
}
Cache_wait();
+#endif
+
+ // set source select
+ pCb->sourceSel = PAF_SOURCE_UNKNOWN;
+
+ #ifdef CB_RW_OP_CAP_PP // debug
+ // Get address in global variables
+ gCB_samples_op = pCb->cb_samples_op;
+ gCB_op_owner = pCb->cb_op_owner;
+ gCB_opCnt = &pCb->cb_opCnt;
+ gCB_afRdIdx = pCb->cb_afRdIdx;
+ gCB_afWrtIdx = pCb->cb_afWrtIdx;
+ gCB_numAfCb = pCb->cb_numAfCb;
+ #endif
+
+ // Write back circular buffer configuration
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ Cache_wait();
return ASP_DECOP_CB_SOK;
}
+
+#if 0 // FL: moved to ARM
// debug
//Int8 gCbInitSourceSelCnt=0;
//Int8 gCbInitSourceSelThdCnt=0;
Int8 sourceSelect, // source select (PCM, DDP, etc.)
Int16 decOpFrameLen, // decoder output frame length (PCM samples)
Int16 strFrameLen, // stream frame length (PCM samples)
- Int8 resetRwFlags // whether to reset reader, writer, and empty flags
+ Int8 resetRwFlags // whether to reset reader, writer, and drain flags
)
{
IArg key;
{
pCb->writerActiveFlag = 0;
pCb->readerActiveFlag = 0;
- pCb->emptyFlag = 0;
+ pCb->drainFlag = 0;
}
- // reset error counts
+ // reset stats
+ pCb->readAfWriterInactiveCnt = 0;
+ pCb->readAfNdCnt = 0;
+ pCb->wrtAfReaderInactiveCnt = 0;
+ pCb->wrtAfZeroSampsCnt = 0;
pCb->errUndCnt = 0;
pCb->errOvrCnt = 0;
return ASP_DECOP_CB_SOK;
}
+#endif
// Start reads from circular buffer
Int cbReadStart(
Int8 i;
Int16 j;
Int8 numMetadata = 0;
-
+
// Get gate handle
gateHandle = pCbCtl->gateHandle;
// Enter gate
//Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
- if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
+ // Check (writerActiveFlag,drainFlag)=(1,1)
+ if ((pCb->writerActiveFlag == 1) && (pCb->drainFlag == 1))
{
+ //
// This shouldn't occur:
- // writer is active AND draining circular buffer
- //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
+ // writer is active AND draining circular buffer
+ //
+
+ //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, drainFlag=%d", pCb->writerActiveFlag, pCb->drainFlag); // FL: debug
SW_BREAKPOINT; // FL: debug
// Leave the gate
return ASP_DECOP_CB_READ_INVSTATE;
}
- //if (((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
- if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
+ // Check (writerActiveFlag,drainFlag)=(0,0)
+ //if (((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
+ if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0))
{
//
- // No active writer, not draining circular buffer.
+ // Writer inactive, not draining circular buffer.
// Skip UNDerflow check, mute output.
//
+
+ pCb->readAfWriterInactiveCnt++;
+
//cbReadAfMute(pAfRd, pCb->strFrameLen);
cbReadMuteWithLastAfInfo(pCb, pAfRd);
+ // Write back circular buffer configuration.
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ Cache_wait();
+
// Leave the gate
GateMP_leave(gateHandle, key);
//if ((pCb->primedFlag == 0) || ((pCb->primedFlag==1) && (pCb->deltaSamps > 0))
if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
{
+ pCb->readAfNdCnt++;
+
if (pCb->primedFlag == 1)
{
pCb->deltaSamps = pCb->deltaSamps - pCb->strFrameLen;
return ASP_DECOP_CB_SOK;
}
-
- // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
- // Here we are checking (1,0) state here
+ // (writerActiveFlag,drainFlag)= (0,0) and (1,1) checked above
+ // (writerActiveFlag,drainFlag)=(1,0) and (0,1) are left
+ // Checking (writerActiveFlag,drainFlag)=(1,0) state here
if (pCb->writerActiveFlag == 1)
{
// check underflow
cbReadMuteWithLastAfInfo(pCb, pAfRd);
//SW_BREAKPOINT; // FL: debug
+ // debug
{
static Uint8 toggleState = 0;
if (toggleState == 0)
}
}
- if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
+ // Checking (writerActiveFlag,drainFlag)=(1,0) state above and here
+ // Checking (writerActiveFlag,drainFlag)=(0,1) state here
+ if ((pCb->writerActiveFlag == 1) || (pCb->drainFlag == 1))
{
//
// Writer active or draining remaining frames in circular buffer.
}
#endif
- // update Last Cb info as per actual stream
- pCb->lastAf.sampleCount = pCb->strFrameLen;
- pCb->lastAf.sampleRate = pAfCb->sampleRate;
+ //// update Last Cb info as per actual stream
+ //pCb->lastAf.sampleCount = pCb->strFrameLen; // FL: last AF sample count isn't used (see cbReadMuteWithLastAfInfo())
+ //pCb->lastAf.sampleRate = pAfCb->sampleRate; // FL: moved inside cbUpdateLastAfInfo() along with other params from memcpy below
+ // Update last audio frame configuration info
+ cbUpdateLastAfInfo(pCb, pAfRd);
// read PCM samples
for (i = 0; i < pCb->maxAFChanNum; i++)
// update number of audio frames in circular buffer
pCb->numAfCb--;
}
- memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
+
+ // FL: this update of Last AF is handled above
+ //memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
{
static Uint8 toggleState = 0;
}
}
- if (pCb->emptyFlag == 1)
+ if (pCb->drainFlag == 1)
{
//
// Writer inactive, but remaining frames in circular buffer.
- // Update empty flag.
+ // Update drain flag.
//
if (pCb->numAfCb <= 0)
{
- pCb->emptyFlag = 0;
+ pCb->drainFlag = 0;
}
}
}
#endif
+#if 0 // FL: unused
// Init last audio frame configuration info
static Void cbInitLastAfInfo(
PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
}
+#endif
+
+// Update last audio frame configuration info
+static Void cbUpdateLastAfInfo(
+ PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
+ PAF_AudioFrame *pAfUpd // audio frame used for update
+)
+{
+ // FL: full copy shouldn't be necessary
+ // Note currently (data.nChannels, data.nSamples)=(32,256) is fixed in ASOT stream AF.
+ // There parameters aren't copied from CB on CB read.
+ //memcpy (&pCb->lastAf, pAfUpd, sizeof(PAF_AudioFrame));
+
+ // These are parameters used in cbReadMuteWithLastAfInfo()
+ pCb->lastAf.sampleDecode = pAfUpd->sampleDecode;
+ pCb->lastAf.sampleRate = pAfUpd->sampleRate;
+ pCb->lastAf.channelConfigurationRequest.full = pAfUpd->channelConfigurationRequest.full;
+ pCb->lastAf.channelConfigurationStream.full = pAfUpd->channelConfigurationStream.full;
+}
// Generate mute AF on circular buffer read using the last AF configuration info
-static Void cbReadMuteWithLastAfInfo (
+static Void cbReadMuteWithLastAfInfo(
PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
PAF_AudioFrame *pAfRd // audio frame into which to read
)
pAfRd->sampleRate = pCb->lastAf.sampleRate;
pAfRd->sampleCount = pCb->strFrameLen;
pAfRd->channelConfigurationRequest.full = pCb->lastAf.channelConfigurationRequest.full;
- pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat;
- pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
+ //pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat; // FL: not necessary since full in union already copied
+ //pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
pAfRd->channelConfigurationStream.full = pCb->lastAf.channelConfigurationStream.full;
- pAfRd->channelConfigurationStream.part.sat = pCb->lastAf.channelConfigurationStream.part.sat;
- pAfRd->channelConfigurationStream.part.sub = pCb->lastAf.channelConfigurationStream.part.sub;
+ //pAfRd->channelConfigurationStream.part.sat = pCb->lastAf.channelConfigurationStream.part.sat;
+ //pAfRd->channelConfigurationStream.part.sub = pCb->lastAf.channelConfigurationStream.part.sub;
// compute stream mask
streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
}
+// Check circular buffer drain state
+Int cbCheckDrainState(
+ PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
+ Int8 cbIdx, // decoder output circular buffer index, or indicator combined drain state desired
+ Int8 *pDrainedFlag // output drain state indicator (combined or for selected circular buffer)
+)
+{
+ IArg key;
+ GateMP_Handle gateHandle;
+ PAF_AST_DecOpCircBuf *pCb;
+ Int8 drainedFlag;
+ Int8 i;
+
+ // Get gate handle
+ gateHandle = pCbCtl->gateHandle;
+ // Enter gate
+ key = GateMP_enter(gateHandle);
+
+ if (cbIdx != ASP_DECOP_CHECK_DRAINSTATE_ALL)
+ {
+ //
+ // Check drain state for selected circular buffer
+ //
+
+ // Get circular buffer base pointer
+ pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
+
+ // Invalidate circular buffer configuration
+ Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ Cache_wait();
+
+ drainedFlag = !pCb->writerActiveFlag && !pCb->drainFlag;
+ }
+ else
+ {
+ //
+ // Check combined drain state for all circular buffers.
+ // Combined drain state is logical AND of drain state for all circular buffers.
+ //
+
+ drainedFlag = 1; // init combined drained flag to TRUE
+ for (i = 0; i < pCbCtl->numDecOpCb; i++)
+ {
+ // Get circular buffer base pointer
+ pCb = &((*pCbCtl->pXDecOpCb)[i]);
+
+ // Invalidate circular buffer configuration
+ Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ Cache_wait();
+
+ // Update combined drain state
+ drainedFlag = drainedFlag && (!pCb->writerActiveFlag && !pCb->drainFlag);
+ }
+ }
+
+ *pDrainedFlag = drainedFlag;
+
+ // Leave the gate
+ GateMP_leave(gateHandle, key);
+
+ return ASP_DECOP_CB_SOK;
+}