diff --git a/pasdk/test_dsp/framework/aspDecOpCircBuf_master.c b/pasdk/test_dsp/framework/aspDecOpCircBuf_master.c
index d337750266192103dc2629e05a72625a84abab66..e7349d0546d6fe6027b56aff8cdae955e109d3eb 100644 (file)
/*
-Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
+Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
All rights reserved.
* Redistribution and use in source and binary forms, with or without
#include "pafdec.h"
#include "aspDecOpCircBuf_master.h"
-#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 ( 256 ) // default stream frame length
+#include "evmc66x_gpio_dbg.h" // Debug
+#ifdef CB_RW_OP_CAP_PP // debug
+// Global variables
+Uint32 *gCB_samples_op = NULL;
+Uint8 *gCB_op_owner = NULL;
+Uint32 *gCB_opCnt = 0;
+Uint8 *gCB_afRdIdx = NULL;
+Uint8 *gCB_afWrtIdx = NULL;
+Uint8 *gCB_numAfCb = NULL;
+#endif
+
+#if 0
// Generate mute AF on circular buffer read
static Void cbReadAfMute(
PAF_AudioFrame *pAfRd, // audio frame into which to read
Int16 strFrameLen // stream frame length (output transaction size)
);
+#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; // 2*256 in behind
+ pCb->pcmRdIdx = 0;
+
+ // Initialize CB primed flag
+ pCb->primedFlag = 0;
+ // Initialize delta samples
+ pCb->deltaSamps = 0;
// set default value to PCM configuration
pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
// initialize audio frame PCM buffers
pPcmBuf = pCb->pcmBuf;
- pMetaBuf = pCb->metaBuf; //QIN
+ pMetaBuf = pCb->metaBuf;
for (n=0; n<pCb->maxNumAfCb; n++)
{
pAfCb = &pCb->afCb[n];
pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
- // Initialize metadata buffers //QIN
+ // Initialize metadata buffers
for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
{
pAfCb->pafPrivateMetadata[i].offset = 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;
+ #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
+
cbInitLastAfInfo(&pCb->lastAf);
- // (***) FL: revisit
// Write back circular buffer configuration
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
// Write back AF circular buffer
{
Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
}
- // FL: unnecessary since part of AF
- //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
- //{
- // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 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;
+
// Initialize circular buffer based on selected source
Int cbInitSourceSel(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
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;
PAF_AST_DecOpCircBuf *pCb;
PAF_AudioFrame *pAfCb;
PAF_AudioData *pPcmBuf;
- UInt8 *pMetaBuf; //QIN
+ UInt8 *pMetaBuf;
Int8 n;
Int8 i;
+ //gCbInitSourceSelCnt++; // debug
+
// Get gate handle
gateHandle = pCbCtl->gateHandle;
// Enter gate
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
// set source select
pCb->sourceSel = sourceSelect;
// set output frame length
pCb->strFrameLen = strFrameLen;
+
+ //pCb->afInitialLag = 0; // default No lag
+ //pCb->afLagIdx = 0;
+ // Initialize CB primed flag
+ pCb->primedFlag = 0;
+ // Initialize delta samples
+ pCb->deltaSamps = 0;
// initialize circular buffer maximum number of audio frames
if (sourceSelect == PAF_SOURCE_PCM)
{
pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
- // 2*256 in behind
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
+ // Initialize target nominal delay
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
+
pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
pCb->pcmRdIdx = 0;
+
pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
{
pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
- // 4*256 in behind
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
+ // Initialize target nominal delay
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kDDP;
+
pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
- pCb->pcmRdIdx = decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
+ pCb->pcmRdIdx = 0;
+
pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
}
else if (sourceSelect == PAF_SOURCE_THD)
{
+ //gCbInitSourceSelThdCnt++; //debug
+
pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
- // 0 in behind
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
+ // Initialize target nominal delay
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
+
pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
pCb->pcmRdIdx = 0;
+
pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
// initialize audio frame PCM buffers
pPcmBuf = pCb->pcmBuf;
- pMetaBuf = pCb->metaBuf; //QIN
+ pMetaBuf = pCb->metaBuf;
for (n=0; n<pCb->maxNumAfCb; n++)
{
pAfCb = &pCb->afCb[n];
pAfCb->data.samsiz[i] = 0;
}
- // Initialize metadata buffers //QIN
+ // Initialize metadata buffers
for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
{
pAfCb->pafPrivateMetadata[i].offset = 0;
{
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;
- // (***) FL: revisit
// Write back circular buffer configuration
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
// Write back AF circular buffer
return ASP_DECOP_CB_SOK;
}
+#endif
// Start reads from circular buffer
Int cbReadStart(
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
// update flags
pCb->readerActiveFlag = 1;
- // (***) FL: revisit
// Write back circular buffer configuration
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
// update flags
pCb->readerActiveFlag = 0;
- // (***) FL: revisit
// Write back circular buffer configuration
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
return ASP_DECOP_CB_SOK;
}
+// debug
+//Int16 gDeltaSampsBuf[20];
+//Int8 gDeltaSampsBufIdx=0;
+
// Read audio frame from circular buffer
Int cbReadAf(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
Int8 i;
Int16 j;
Int8 numMetadata = 0;
-
+
// Get gate handle
gateHandle = pCbCtl->gateHandle;
// Enter gate
// Get circular buffer base pointer
pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
- // (***) FL: revisit
// Invalidate circular buffer configuration.
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //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))
+ // 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);
+
+ return ASP_DECOP_CB_SOK;
+ }
+
+ //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;
+
+ // debug
+ //gDeltaSampsBuf[gDeltaSampsBufIdx] = pCb->deltaSamps;
+ //if (gDeltaSampsBufIdx < 20)
+ // gDeltaSampsBufIdx++;
+ }
+
+ 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);
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)
+ GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
+ else
+ GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
+ toggleState = ~(toggleState);
+ }
+
+ #ifdef CB_RW_OP_CAP_PP // debug
+ if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
+ {
+ if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
+ {
+ // log sample count
+ pCb->cb_samples_op[pCb->cb_opCnt] = 0; // due to underflow
+ pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
+ // log idxs
+ pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
+ pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
+ pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
+ pCb->cb_opCnt++;
+ }
+ }
+ #endif
+
// Write back circular buffer configuration.
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
}
}
- 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.
// get pointer to current audio frame in circular buffer
pAfCb = &pCb->afCb[pCb->afRdIdx];
- // (***) FL: revisit
// Invalidate audio frame
Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
- for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
+ for (i=0; i<pAfCb->numPrivateMetadata; i++) // only invalidate numPrivateMetadata
{
- Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
+ Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
}
Cache_wait();
// compute stream mask
streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
+ // Invalidate channel pointers
+ Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
+ Cache_wait();
+
// Invalidate PCM data
for (i = 0; i < pCb->maxAFChanNum; i++)
{
pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
- // read metadata information updated by decoder //QIN
+ // read metadata information updated by decoder
pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
- // update Last Cb info as per actual stream
- pCb->lastAf.sampleCount = pCb->strFrameLen;
- pCb->lastAf.sampleRate = pAfCb->sampleRate;
+ #ifdef CB_RW_OP_CAP_PP // debug
+ if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
+ {
+ if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
+ {
+ // log sample count
+ pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
+ pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
+ // log idxs
+ pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
+ pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
+ pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
+ pCb->cb_opCnt++;
+ }
+ }
+ #endif
+
+ //// 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++)
pAfRd->pafPrivateMetadata[i].size = 0;
}
- // read metadata //QIN
- for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
+ // read metadata
+ for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only read numPrivateMetadata
{
- // FL: this is done above
- ////Invalidate metadata data
- //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
- //Cache_wait();
-
if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
&&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
&&(pAfCb->pafPrivateMetadata[i].size))
{
- // FL: this is done above
- ////Invalidate metadata data
- //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
- //Cache_wait();
-
// the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
pAfRd->pafPrivateMetadata[numMetadata].size = pAfCb->pafPrivateMetadata[i].size;
// 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 (toggleState == 0)
+ GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
+ else
+ GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
+ toggleState = ~(toggleState);
+ }
}
- 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;
}
}
- // (***) FL: revisit
// Write back circular buffer configuration.
// NOTE: Probably only a subset of this information needs to be updated.
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
return ASP_DECOP_CB_SOK;
}
+#if 0
// Generate mute AF on circular buffer read
static Void cbReadAfMute(
PAF_AudioFrame *pAfRd, // audio frame into which to read
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
+
+#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;
+}