diff --git a/pasdk/test_arm/framework/aspDecOpCircBuf_slave.c b/pasdk/test_arm/framework/aspDecOpCircBuf_slave.c
index 50b2d861d04d4aecaf53d169985e421bea9728f3..79c645bf5bf92f409e311f979c3ef236091ad078 100644 (file)
//#include "pafsp.h"
#include "aspDecOpCircBuf_slave.h"
+#include "evmc66x_gpio_dbg.h" // Debug
+
+// Init last audio frame configuration info
+static Void cbInitLastAfInfo(
+ PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
+ PAF_AudioFrame *pAfInit // audio frame used for init
+);
+
+
+#if 0 // FL: moved to common
// Initialize circular buffer control
Int cbCtlInit(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
}
else
{
- pCbCtl->gateHandle = NULL;
+ pCbCtl->gateHandle = NULL;
return ASP_DECOP_CB_CTL_INIT_INV_GATE;
}
- pCbCtl->pXDecOpCb = pXDecOpCb;
+ pCbCtl->numCb = numCb; // init number of circular buffers
+ pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
return ASP_DECOP_CB_SOK;
+}
+#endif
+
+// debug
+//Int8 gCbInitDecWriteCnt=0;
+//Int8 gCbInitDecWriteThdCnt=0;
+
+/// Initialize circular buffer for Decoder writes
+Int cbInitDecWrite(
+ PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
+ Int8 cbIdx, // decoder output circular buffer index
+ Int8 sourceSelect, // source select (PCM, DDP, etc.)
+ Int16 decOpFrameLen, // decoder output frame length (PCM samples)
+ Int8 resetRwFlags, // whether to reset reader, writer, and drain flags
+ PAF_AudioFrame *pDecInitAf // pointer to Dec output audio frame used for CB initialization
+)
+{
+ IArg key;
+ GateMP_Handle gateHandle;
+ PAF_AST_DecOpCircBuf *pCb;
+ PAF_AudioFrame *pAfCb;
+ PAF_AudioData *pPcmBuf;
+ UInt8 *pMetaBuf;
+ Int8 n;
+ Int8 i;
+
+ //gCbInitDecWriteCnt++; // debug
+
+ // Get gate handle
+ gateHandle = pCbCtl->gateHandle;
+ // Enter gate
+ key = GateMP_enter(gateHandle);
+
+ // 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();
+
+ //Log_info1("cbInitDecWrite:afCb=0x%04x", (IArg)pCb->afCb); // debug
+
+ // Set source select
+ pCb->sourceSel = sourceSelect;
+
+ // Set input frame length
+ pCb->decOpFrameLen = decOpFrameLen;
+
+ //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 AFs
+ // - target nominal delay
+ // - AF write, read indices
+ // - maximum AF channel and sample counts
+ // - maximum number of PCM samples per channel
+ if (sourceSelect == PAF_SOURCE_PCM)
+ {
+ pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
+ 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->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
+ pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
+
+ pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
+ }
+ else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
+ {
+ pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
+
+ pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
+ pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
+
+ pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
+ pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
+
+ pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
+ }
+ else if (sourceSelect == PAF_SOURCE_THD)
+ {
+ //gCbInitSourceSelThdCnt++; //debug
+
+ pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
+
+ //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
+ // FL: (***) set nominal delay per sampling rate -- need to review these settings
+ switch (pDecInitAf->sampleRate)
+ {
+ case PAF_SAMPLERATE_44100HZ:
+ case PAF_SAMPLERATE_48000HZ:
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
+ break;
+ case PAF_SAMPLERATE_88200HZ:
+ case PAF_SAMPLERATE_96000HZ:
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
+ break;
+ case PAF_SAMPLERATE_176400HZ:
+ case PAF_SAMPLERATE_192000HZ:
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
+ break;
+ default:
+ pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
+ break;
+ }
+
+ pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
+ pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
+
+ pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
+ pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
+
+ pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
+ }
+ else
+ {
+ //
+ // Currently unsupported source select
+ //
+
+ SW_BREAKPOINT; // debug
+
+ // Leave the gate
+ GateMP_leave(gateHandle, key);
+
+ return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
+ }
+
+ // Initialize circular buffer:
+ // - PCM read index
+ // - Private metadata read index
+ // - number of PCM samples in CB
+ pCb->pcmRdIdx = 0;
+ pCb->prvMdRdIdx = 0;
+ pCb->numPcmSampsPerCh = 0;
+
+ // Initialize audio frames
+ for (n = 0; n < pCb->maxNumAfCb; n++)
+ {
+ pAfCb = &pCb->afCb[n]; // get pointer to CB AF
+
+ // Dec init AF sample count not correct for CB AFs.
+ // Dec Op frame length is computed in framework based on selected source.
+ pAfCb->sampleCount = decOpFrameLen;
+
+ // initialize CB AF using Dec init AF
+ pAfCb->sampleDecode = pDecInitAf->sampleDecode;
+ PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
+ pAfCb->sampleRate = pDecInitAf->sampleRate;
+ pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
+ pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
+
+ // initialize metadata information updated by decoder
+ pAfCb->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
+ pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
+ 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 circular buffer current number of frames
+ pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
+
+ // Initialize audio frame PCM buffers
+ pPcmBuf = pCb->pcmBuf;
+ pMetaBuf = pCb->metaBuf;
+ for (n=0; n<pCb->maxNumAfCb; n++)
+ {
+ pAfCb = &pCb->afCb[n]; // get pointer to CB AF
+
+ pAfCb->data.nChannels = pCb->maxAFChanNum;
+ pAfCb->data.nSamples = decOpFrameLen;
+ for (i=0; i<pCb->maxAFChanNum; i++)
+ {
+ pAfCb->data.sample[i] = pPcmBuf;
+ memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
+ pPcmBuf += pCb->maxAFSampCount;
+
+ pAfCb->data.samsiz[i] = 0;
+ }
+
+ // Initialize metadata buffers
+ for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
+ {
+ pAfCb->pafPrivateMetadata[i].offset = 0;
+ pAfCb->pafPrivateMetadata[i].size = 0;
+ pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
+ pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
+ }
+ }
+
+ // Initialize last audio frame configuration info
+ cbInitLastAfInfo(pCb, pDecInitAf);
+
+ // Reset read/write flags
+ if (resetRwFlags != 0)
+ {
+ pCb->writerActiveFlag = 0;
+ pCb->readerActiveFlag = 0;
+ pCb->drainFlag = 0;
+ }
+
+ // Reset stats
+ pCb->readAfWriterInactiveCnt = 0;
+ pCb->readAfNdCnt = 0;
+ pCb->wrtAfReaderInactiveCnt = 0;
+ pCb->wrtAfZeroSampsCnt = 0;
+ pCb->errAfUndCnt = 0;
+ pCb->errAfOvrCnt = 0;
+ pCb->errPcmUndCnt = 0;
+ pCb->errPcmOvrCnt = 0;
+
+ // Write back circular buffer configuration
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ // Write back AF circular buffer
+ Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
+ // Write back PCM data
+ for (n=0; n<pCb->maxNumAfCb; n++)
+ {
+ pAfCb = &pCb->afCb[n];
+ Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
+ Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
+ for (i=0; i<pCb->maxAFChanNum; i++)
+ {
+ Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
+ }
+ }
+ Cache_wait();
+
+ // Leave the gate
+ GateMP_leave(gateHandle, key);
+ return ASP_DECOP_CB_SOK;
}
+//Int8 gCbWriteStartCnt=0; // debug
+
// Start writes to circular buffer
Int cbWriteStart(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
Int8 n;
//Int8 i;
+ //gCbWriteStartCnt++; // debug
+
// Get gate handle
gateHandle = pCbCtl->gateHandle;
// Enter gate
// Get circular buffer base pointer
pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
- // (***) FL: revisit
// Invalidate circular buffer configuration.
// NOTE: Probably only a subset of this information needs to be updated.
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
// Invalidate AF circular buffer
Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
// update flags
pCb->writerActiveFlag = 1;
- pCb->emptyFlag = 0;
- pCb->afLagIdx = 0;
+ pCb->drainFlag = 0;
+ //pCb->afLagIdx = 0;
- // (***) 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("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
+ //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
// update flags
pCb->writerActiveFlag = 0;
- pCb->emptyFlag = 1;
+ pCb->drainFlag = 1;
- // (***) 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 gSampleCountBuf[10];
+//Int16 gCalcDeltaSampsBuf[10];
+//Int8 gPrimedFlagCnt=0;
+
+// (***) FL: revisit
// Write audio frame to circular buffer
Int cbWriteAf(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
PAF_ChannelMask_HD streamMask;
Int8 i;
Int16 j;
- PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
-
+ PAF_AudioData *pPcmBuf; UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
+ PAF_AudioFrame *pAfCbRd;
+ PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
+
// Get gate handle
gateHandle = pCbCtl->gateHandle;
// Enter gate
key = GateMP_enter(gateHandle);
- //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
+ //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
// Get circular buffer base pointer
pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
- //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // FL: debug
+ //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
- // (***) FL: revisit
// Invalidate circular buffer configuration.
- // NOTE: Probably only a subset of this information nexeds to be updated.
+ // NOTE: Probably only a subset of this information needs to be updated.
Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
- //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
- //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // FL: debug
-
- if ((pCb->readerActiveFlag == 1) && (pAfWrt->sampleCount)) //QIN ?
- {
- //
- // Normal case, reader active.
- // If reader not active, don't write to circular buffer or check OVRflow.
-
-#if 0
- if (pCb->cbWriteAfInit == 0)
- {
- // Invalidate AF circular buffer
- Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
- for (n=0; n<pCb->maxNumAfCb; n++)
- {
- pAfCb = &pCb->afCb[n];
- Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
- }
- Cache_wait();
-
- pCb->cbWriteAfInit = 1;
- }
-#endif
-
- //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // FL: debug
+ //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
+ //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
- // check overflow
- //while (pCb->numAfCb >= pCb->maxNumAfCb); // FL: debug
- if (pCb->numAfCb >= pCb->maxNumAfCb)
+ //if (pCb->readerActiveFlag == 1)
+ //{
+ // //
+ // // Normal case, reader active.
+ // //
+
+ if (pAfWrt->sampleCount != 0)
{
- pCb->errOvrCnt++;
+ //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
- //SW_BREAKPOINT;
- Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
+ // check AF overflow
+ if (pCb->numAfCb >= pCb->maxNumAfCb)
+ {
+ pCb->errAfOvrCnt++;
- // Write back circular buffer configuration
- Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ //SW_BREAKPOINT;
+ Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
- // Leave the gate
- GateMP_leave(gateHandle, key);
+ // Write back circular buffer configuration
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ Cache_wait();
- //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
+ // Leave the gate
+ GateMP_leave(gateHandle, key);
- return ASP_DECOP_CB_WRITE_OVERFLOW;
- }
+ //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
- pAfCb = &pCb->afCb[pCb->afWrtIdx];
- pPcmBuf = pAfCb->data.sample[0];
- pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
- if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
- {
- pPcmBuf = pCb->pcmBuf;
- }
+ return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
+ }
+
+ // FL: this won't reliably detect overflow because of PCM buffer write address wrap
+ // check PCM overflow
+ //if ((pCb->numPcmSampsPerCh + pAfWrt->sampleCount) > pCb->maxNumPcmSampsPerCh)
+ //{
+ // pCb->errPcmOvrCnt++;
+ //
+ // Log_info3("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d, maxNumPcmSampsPerCh=%d",
+ // pCb->numPcmSampsPerCh, pAfWrt->sampleCount, pCb->maxNumPcmSampsPerCh);
+ //
+ // // 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_PCM_WRITE_OVERFLOW;
+ //}
+
+ pAfCb = &pCb->afCb[pCb->afWrtIdx]; // get CB AF to be written
+
+ // Get reader current PCM buffer location for PCM buffer overflow check
+ pAfCbRd = &pCb->afCb[pCb->afRdIdx];
+ //pPcmBufRd = pAfCbRd->data.sample[0]; // FL: starting location of PCM samples for AF being read
+ pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx; // FL: current location of PCM samples for AF being read
+
+ pPcmBufWrt = pAfCb->data.sample[0]; // get current location in PCM buffer to be written
+ // (***) FL: currently no metadata buffer overflow detection
+ pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf; // get current location in MD buffer to be written
+
+ // check PCM buffer overflow
+ pPcmBuf = pPcmBufWrt;
+ for (i = 0; i < pCb->maxAFChanNum; i++)
+ {
+ // check PCM buffer wrap
+ if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
+ {
+ pPcmBuf = pCb->pcmBuf;
+ }
+
+ // check PCM buffer overflow
+ if ((pPcmBuf < pPcmBufRd) &&
+ ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
+ {
+ pCb->errPcmOvrCnt++;;
+
+ Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d",
+ pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
+
+ //SW_BREAKPOINT; // debug
+
+ // 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_PCM_WRITE_OVERFLOW;
+ }
+
+ pPcmBuf += pAfWrt->sampleCount;
+ }
+
+ // configure AF sample pointers
+ pPcmBuf = pPcmBufWrt;
+ for (i = 0; i < pCb->maxAFChanNum; i++)
+ {
+ // check PCM buffer wrap
+ if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
+ {
+ pPcmBuf = pCb->pcmBuf;
+ }
+
+ pAfCb->data.sample[i] = pPcmBuf;
+ pPcmBuf += pAfWrt->sampleCount;
+ pAfCb->data.samsiz[i] = 0;
+ }
+ Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
+ Cache_wait();
- for (i=0; i<pCb->maxAFChanNum; i++)
- {
+ // FL: brute force reset of all metadata in CB AF?
+ for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
+ {
+ pAfCb->pafPrivateMetadata[i].offset = 0;
+ pAfCb->pafPrivateMetadata[i].size = 0;
+ pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
+ pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
+ }
- pAfCb->data.sample[i] = pPcmBuf;
- pPcmBuf += pAfWrt->sampleCount;
- pAfCb->data.samsiz[i] = 0;
- }
- Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
- Cache_wait();
+ nextWrtIdx = 0;
+ if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
+ {
+ //Log_info0("cbWriteAf: AF Wrap around **** ");
+ // next audio frame will be audio frame 0
+ nextWrtIdx = 0;
+ }
+ else
+ {
+ // next audio frame will be current audio frame + 1
+ nextWrtIdx = pCb->afWrtIdx + 1;
+ }
- for (i=0; i<pCb->maxAFChanNum; i++){
- }
- for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
- {
- pAfCb->pafPrivateMetadata[i].offset = 0;
- pAfCb->pafPrivateMetadata[i].size = 0;
- pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
- pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
- }
+ pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
+ pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
+
+ // write audio frame information updated by decoder
+ pAfCb->sampleDecode = pAfWrt->sampleDecode;
+ PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
+ pAfCb->sampleRate = pAfWrt->sampleRate;
+ pAfCb->sampleCount = pAfWrt->sampleCount;
+ pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
+ pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
+ // write metadata information updated by decoder
+ pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
+ pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
+ pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
+ pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
+ // write PCM samples
+ streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
+ for (i = 0; i < pCb->maxAFChanNum; i++)
+ {
+ if ((streamMask >> i) & 0x1)
+ {
+ for (j = 0; j < pAfWrt->sampleCount; j++)
+ {
+ pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
+ }
- nextWrtIdx = 0;
- if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
- {
- //Log_info0("cbWriteAf: AF Wrap around **** ");
- nextWrtIdx = 0;
- }else{
- nextWrtIdx = pCb->afWrtIdx + 1;
- }
+ pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
+ }
+ }
+
+ // Update PCM samples per channel
+ pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
+
+ #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] = pAfWrt->sampleCount;
+ pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
+ // 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
- pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
- pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
-
- // write audio frame information updated by decoder
- pAfCb->sampleDecode = pAfWrt->sampleDecode;
- PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
- pAfCb->sampleRate = pAfWrt->sampleRate;
- pAfCb->sampleCount = pAfWrt->sampleCount;
- pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
- pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
- // write metadata information updated by decoder //QIN
- pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
- pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
- pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
- pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
- // write PCM samples
- streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
-
- for (i = 0; i < pCb->maxAFChanNum; i++)
- {
- if ((streamMask >> i) & 0x1)
+ // prepare metadata buffer pointers according to the metadata and buffer sizes
+ for (i=0; i < pAfWrt->numPrivateMetadata; i++)
{
- for (j = 0; j < pAfWrt->sampleCount; j++)
+ UInt8 *nextMdBuf;
+ if(i == 0)
+ nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
+ else
+ nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
+ if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
+ {
+ pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
+ }
+ else if(i != 0)
{
- pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
+ pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
}
+ Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
+ }
- pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
+ // Write metadata to circular buffer
+ for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
+ {
+ pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
+ pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
+ memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
}
- }
+ Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
+ Cache_wait();
+ for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
+ {
+ //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
+ Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
+ }
+ // update audio frame write index
+ pCb->afWrtIdx++;
+ if (pCb->afWrtIdx >= pCb->maxNumAfCb)
+ {
+ pCb->afWrtIdx = 0;
+ }
- // prepare metadata buffer pointers according to the metadata and buffer sizes
- for (i=0; i < pAfWrt->numPrivateMetadata; i++)
- {
- UInt8 *nextMdBuf;
- if(i == 0)
- nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
+ pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
+ if(pAfWrt->numPrivateMetadata > 0)
+ {
+ pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
+ }
else
- nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
- if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
{
- pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
+ pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
+ Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
+ Cache_wait();
}
- else if(i != 0)
+ Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
+ Cache_wait();
+ // update number of audio frames in circular buffer
+ pCb->numAfCb++;
+
+ // Update CB Lag index
+ //if (pCb->afLagIdx < pCb->afInitialLag)
+ //{
+ // pCb->afLagIdx += 1;
+ //}
+
+ // Update CB primed flag
+ // calculate number of delta samples before allowing CB read
+ if (pCb->primedFlag == 0)
{
- pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
+ pCb->primedFlag = 1;
+
+ // Calculate number of output frames to block reader.
+ // This is sample count reader waits before allowed to actually read samples from the CB.
+ //pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
+ // FL: CB read decrements by strFrameLen and tests for >0, so rounding to strFrameLen is unnecessary
+ pCb->deltaSamps = pCb->targetNDSamps - pAfWrt->sampleCount;
+
+ // debug
+ //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
+ //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
+ //if (gPrimedFlagCnt < 10)
+ // gPrimedFlagCnt++;
}
- Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
- }
- // Write metadata to circular buffer
- for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
- {
- pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
- pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
- memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
- }
+ // Write back circular buffer configuration
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
+ // write back audio frame
+ Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
+ Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
+ Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
+ Cache_wait();
+ // write back PCM data
+ for (i = 0; i < pCb->maxAFChanNum; i++)
+ {
+ if ((streamMask >> i) & 0x1)
+ {
+ Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
+ }
+ }
+ Cache_wait();
- Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
- Cache_wait();
- for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
- {
- //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
- Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
- }
- // update audio frame write index
- pCb->afWrtIdx++;
- if (pCb->afWrtIdx >= pCb->maxNumAfCb)
- {
- pCb->afWrtIdx = 0;
- }
+#if 0 // (***) FL: shows timing of CB write
+ // debug
+ {
+ static Uint8 toggleState = 0;
+ if (toggleState == 0)
+ GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
+ else
+ GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
+ toggleState = ~(toggleState);
+ }
+#endif
- pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
- if(pAfWrt->numPrivateMetadata > 0)
- {
- pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
+ Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
+ Log_info4("CBWMETA num=%d size=%d offset=%d chrequest=0x%04x", pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[0].size, pAfCb->pafPrivateMetadata[0].offset, pAfCb->channelConfigurationRequest.full);
}
else
{
- pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
- Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
+ //
+ // Skip write in case of 0 sample count
+ //
+
+ // writing audio frame w/ zero samples
+ // update stat
+ pCb->wrtAfZeroSampsCnt++;
+
+ // Write back circular buffer configuration
+ Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
Cache_wait();
}
- Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
- Cache_wait();
- // update number of audio frames in circular buffer
- pCb->numAfCb++;
- // Update CB Lag index
- if (pCb->afLagIdx < pCb->afInitialLag)
- {
- pCb->afLagIdx += 1;
- }
-
+ //}
+ //else if (pCb->readerActiveFlag == 0)
+ if (pCb->readerActiveFlag == 0)
+ {
+ //
+ // Reader inactive, don't write to circular buffer or check OVRflow.
+ //
+
+ // writing AF w/ inactive reader
+ // update stat
+ pCb->wrtAfReaderInactiveCnt++;
- // (***) FL: revisit
// Write back circular buffer configuration
Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
- // write back audio frame
- Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
- Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
- Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
- Cache_wait();
- // write back PCM data
- for (i = 0; i < pCb->maxAFChanNum; i++)
- {
- if ((streamMask >> i) & 0x1)
- {
- Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
- }
- }
Cache_wait();
- Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
- // write back private metadata // QIN
- Log_info4("CBWMETA num=%d size=%d offset=%d chrequest=0x%04x", pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[0].size, pAfCb->pafPrivateMetadata[0].offset, pAfCb->channelConfigurationRequest.full);
}
// Leave the gate
GateMP_leave(gateHandle, key);
- //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
+ //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
return ASP_DECOP_CB_SOK;
}
+#if 0
// Get next audio frame to write in circular buffer
Int cbGetNextWriteAf(
PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
return ASP_DECOP_CB_SOK;
}
+#endif
+
+// Init last audio frame configuration info
+static Void cbInitLastAfInfo(
+ PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
+ PAF_AudioFrame *pAfInit // audio frame used for init
+)
+{
+ memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
+
+ pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
+ pCb->lastAf.sampleRate = pAfInit->sampleRate;
+ pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
+ pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;
+}