PASDK-218:Update CB read to allow read spanning multiple CB AFs
authorFrank Livingston <frank-livingston@ti.com>
Thu, 20 Jul 2017 22:28:37 +0000 (17:28 -0500)
committerFrank Livingston <frank-livingston@ti.com>
Thu, 20 Jul 2017 22:28:37 +0000 (17:28 -0500)
- cbReadAf() can read frame lengths not a multiple of Dec output frame
  length(s)
- cbReadAf() doesn't re-scan entire CB AF metadata array for each read
  frame
- drain complete check moved to beginning of cbReadAf() to allow for
  delayed detection of drain state and CB empty

pasdk/common/aspDecOpCircBuf_common.c
pasdk/common/aspDecOpCircBuf_common.h
pasdk/test_arm/framework/aspDecOpCircBuf_slave.c
pasdk/test_arm/framework/audioStreamDecodeProc.c
pasdk/test_dsp/framework/aspDecOpCircBuf_master.c
pasdk/test_dsp/framework/itopo/params.c

index 39b8ba3b9e1487a62043479970c96c0939e6f2fd..50ab1b1f91163931ff7d7c6023ad489b0b82539d 100644 (file)
@@ -138,18 +138,21 @@ Int cbReset(
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
     }
     else if (pCb->sourceSel == PAF_SOURCE_DDP)
     {
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
     }
     else if (pCb->sourceSel == PAF_SOURCE_THD)
     {
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
     }
 
     // initialize circular buffer current number of frames
@@ -272,9 +275,7 @@ Int cbLog(
 
     Log_info1("CB: %s", (IArg)locInfo);
     Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, drainFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->drainFlag);
-    Log_info4("CB: afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, 
-        pCb->afWrtIdx, 
-        pCb->numAfCb);
+    Log_info5("CB: afRdIdx=%d, pcmRdIdx=%d, prvMdRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, pCb->prvMdRdIdx, pCb->afWrtIdx, pCb->numAfCb);
     if (fullLog)
     {
         Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb);  
index f67bd67f6fb833d513c4e8145dce1640d2d61371..19b8a6c4d50a429d326e7342d2062e507d03550b 100644 (file)
@@ -101,8 +101,8 @@ All rights reserved.
 #define ASP_DECOP_CB_INIT_RDIDX_THD             ( 0 )
 //#define ASP_DECOP_CB_INIT_LAG_THD               ( 5 ) // 5*20ms = 100 ms, For the worst case of 100 ms
 #define ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD     ( 3600 ) //( 3504 ) //( 2224 ) // THD target Nominal Delay in number of samples, fs=48 kHz
-#define ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD     ( 7200 ) // THD target Nominal Delay in number of samples, fs=96 kHz
-#define ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD    ( ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD ) // THD target Nominal Delay in number of samples, fs=192 kHz
+#define ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD     ( 2*ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD ) // THD target Nominal Delay in number of samples, fs=96 kHz
+#define ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD    ( 4*ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD ) // THD target Nominal Delay in number of samples, fs=192 kHz
 
 //#define DEF_SOURCE_SEL                          ( PAF_SOURCE_PCM )          // default source select
 //#define DEF_DEC_OP_FRAME_LEN                    ( PAF_SYS_FRAMELENGTH )     // default decoder output frame length
@@ -124,6 +124,7 @@ typedef struct PAF_AST_DecOpCircBuf
     //Int8 afLagIdx;                  // audio frame CB Lag idx,
     //Int8 afInitialLag;              // Initial delay/lag between CB write and read
     Int16 pcmRdIdx;                 // pcm buffer read index
+    Int8 prvMdRdIdx;                // private metadata read index
     Int8 numAfCb;                   // current number frames in CB
     Int8 maxNumAfCb;                // maximum number of audio frames in CB
     Int16 decOpFrameLen;            // selected decoder output frame length (input transaction size)
index 7965102f01f3edd9bfc49ea0e97afd9c7818a058..7a80156fa85a29a7dac4066619ee2ccfbe28d8c5 100644 (file)
@@ -151,6 +151,7 @@ Int cbInitDecWrite(
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
         
         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;        
@@ -165,6 +166,7 @@ Int cbInitDecWrite(
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
         
         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
@@ -199,6 +201,7 @@ Int cbInitDecWrite(
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
         pCb->pcmRdIdx = 0;
+        pCb->prvMdRdIdx = 0;
         
         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;        
@@ -482,7 +485,7 @@ Int cbWriteAf(
             pAfCb = &pCb->afCb[pCb->afWrtIdx];
             pPcmBuf = pAfCb->data.sample[0];
             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
-            if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
+            if ((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum)) >= (pCb->pcmBufEnd))
             {
                 pPcmBuf = pCb->pcmBuf;
             }
index fbb796030825ebf16da5eb781670a6cc3df5567b..66c3af631a8d30d78d7a561c682d8956e37bc6fa 100644 (file)
@@ -138,17 +138,6 @@ Uint32 tempCap_frameCnt = 0;
 int tempCap_decSampleOut[CAP_FRAME_MAX] = {0};
 #endif
 
-// debug
-PAF_AudioFrame gDecInfoAfCap1[20];
-UInt8 gDecInfoAfCap1Idx=0;
-PAF_AudioFrame gDecInfoAfCap2[20];
-UInt8 gDecInfoAfCap2Idx=0;
-
-PAF_AudioFrame gDecDecodeAfCap1[20];
-UInt8 gDecDecodeAfCap1Idx=0;
-PAF_AudioFrame gDecDecodeAfCap2[20];
-UInt8 gDecDecodeAfCap2Idx=0;
-
 
 /*
  *  ======== taskAsdpFxn ========
@@ -670,13 +659,6 @@ Void taskAsdpFxn(
                     errno = 0;
                     if (dec->fxns->info)
                     {
-                        // debug
-                        if (gDecInfoAfCap1Idx < 20)
-                        {
-                            gDecInfoAfCap1[gDecInfoAfCap1Idx] = *pAstCfg->xDec[z].decodeControl.pAudioFrame;
-                            gDecInfoAfCap1Idx++;
-                        }
-                        
                         //
                         // Execute decode info
                         //
@@ -686,18 +668,6 @@ Void taskAsdpFxn(
                             &pAstCfg->xDec[z].decodeStatus);
                         pfpEnd(PFP_ID_ASDT_1, PFP_FINISH_MEAS);
 
-                        // debug
-                        if (gDecInfoAfCap2Idx < 20)
-                        {
-                            gDecInfoAfCap2[gDecInfoAfCap2Idx] = *pAstCfg->xDec[z].decodeControl.pAudioFrame;
-                            gDecInfoAfCap2Idx++;
-                        }
-                        
-                        // debug
-                        //if (outIsDecInfo1Flag < 10) 
-                        //    outIsDecInfo1Flag++;
-                        //if (outIsDecInfo1Flag == 10)
-                        
                         //
                         // Execute Dec Info1 Init-Sync if required
                         //
@@ -790,13 +760,6 @@ Void taskAsdpFxn(
                         // Capture input buffer (debug)
                         //capIb(pAstCfg->xInp[z].pInpBuf);
                         
-                        // debug
-                        if (gDecDecodeAfCap1Idx < 20)
-                        {
-                            gDecDecodeAfCap1[gDecDecodeAfCap1Idx] = *pAstCfg->xDec[z].decodeInStruct.pAudioFrame;
-                            gDecDecodeAfCap1Idx++;
-                        }                       
-                    
                         //
                         // Execute decode
                         //
@@ -809,22 +772,15 @@ Void taskAsdpFxn(
                         }
                         TRACE_TERSE0("Dec:decode done");
 
-                        // debug
-                        if (gDecDecodeAfCap2Idx < 20)
-                        {
-                            gDecDecodeAfCap2[gDecDecodeAfCap2Idx] = *pAstCfg->xDec[z].decodeOutStruct.pAudioFrame;
-                            gDecDecodeAfCap2Idx++;
-                        }                       
-                        
                         // Get pointer to Dec Decode output audio frame
                         pAfWrt = pAstCfg->xDec[z].decodeOutStruct.pAudioFrame;                           
                         TRACE_TERSE2("Dec:pAfWrt=0x%04x, nSamples=%d", (IArg)pAfWrt, pAfWrt->data.nSamples);
                         
                         // Capture audio frame (debug)
-                        //if (capAfWrite(pAfWrt, PAF_CNTR) != CAP_AF_SOK)
+                        //if (capAfWrite(pAfWrt, PAF_LEFT) != CAP_AF_SOK)
                         //{
                         //    Log_info0("capAfWrite() error");
-                        //}                        
+                        //}
 
                         #ifdef CAPTURE_DECODER_OUTSAMPLES_PP
                         if (tempCap_frameCnt < CAP_FRAME_MAX)
index e19652d08f52e03ae5a471177fc5d443bf6d6e0c..af544e00fc5adb81689da5f2f03bf0f02ccec128 100644 (file)
@@ -641,13 +641,16 @@ Int cbReadAf(
 )
 {
     IArg key;
-    GateMP_Handle gateHandle;
-    PAF_AST_DecOpCircBuf *pCb;
-    PAF_AudioFrame *pAfCb;
-    PAF_ChannelMask_HD streamMask;
+    GateMP_Handle gateHandle;           // CB gate handle to arbitrate CB r/w access
+    PAF_AST_DecOpCircBuf *pCb;          // pointer to CB
+    PAF_AudioFrame *pAfCb;              // pointer to current CB AF
+    PAF_ChannelMask_HD streamMask;      // CB AF stream mask
+    Int16 numSampsRd;                   // number of samples to read from current CB AF
+    Int16 totNumSampsRd;                // total number of samples read from CB
+    Int16 pcmWrtIdx;                    // read audio frame PCM write index
+    Int8 prvMdWrtIdx;                   // read audio frame metadata write index
     Int8 i;
     Int16 j;
-    Int8 numMetadata = 0;
     
     // Get gate handle
     gateHandle = pCbCtl->gateHandle;
@@ -663,7 +666,9 @@ Int cbReadAf(
 
     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
 
+    //
     // Check (writerActiveFlag,drainFlag)=(1,1)
+    //
     if ((pCb->writerActiveFlag == 1) && (pCb->drainFlag == 1))
     {
         //
@@ -671,8 +676,8 @@ Int cbReadAf(
         // 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
+        //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, drainFlag=%d", pCb->writerActiveFlag, pCb->drainFlag); // debug
+        SW_BREAKPOINT; // debug
         
         // Leave the gate
         GateMP_leave(gateHandle, key);
@@ -680,7 +685,9 @@ Int cbReadAf(
         return ASP_DECOP_CB_READ_INVSTATE;
     }
 
+    //
     // Check (writerActiveFlag,drainFlag)=(0,0)
+    //
     //if (((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0))
     {
@@ -691,19 +698,48 @@ Int cbReadAf(
         
         pCb->readAfWriterInactiveCnt++;
         
+        // Mute output if write inactive and not draining CB
         //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();    
+        Cache_wait();
 
         // Leave the gate
         GateMP_leave(gateHandle, key);
 
         return ASP_DECOP_CB_SOK;
     }
+
+    if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 1))
+    {
+        //
+        // Writer inactive, but remaining frames in circular buffer.
+        // Update drain flag.
+        //
+        
+        if (pCb->numAfCb <= 0)
+        {
+            pCb->drainFlag = 0;
+
+            // Mute output if CB drained
+            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;
+        }
+    }
     
+    //
+    // Hold off read of PCM samples from CB until Nominal Delay satisfied
+    //
     //if ((pCb->primedFlag == 0) || ((pCb->primedFlag==1) && (pCb->deltaSamps > 0))
     if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
     {
@@ -731,22 +767,25 @@ Int cbReadAf(
         return ASP_DECOP_CB_SOK;
     }
     
-    // (writerActiveFlag,drainFlag)= (0,0) and (1,1) checked above
-    // (writerActiveFlag,drainFlag)=(1,0) and (0,1) are left
+    //
+    // (writerActiveFlag,drainFlag)= (0,0) and (1,1) states checked above
+    // (writerActiveFlag,drainFlag)=(1,0) and (0,1) states are left
     // Checking (writerActiveFlag,drainFlag)=(1,0) state here
+    //
     if (pCb->writerActiveFlag == 1)
     {
         // check underflow
         if (pCb->numAfCb <= 0)
         {
             // 
-            // Increment underflow count.
-            // Mute output on underflow.
+            // Increment underflow count
             //
             pCb->errUndCnt++;
+
+            // Mute output on underflow
             //cbReadAfMute(pAfRd, pCb->strFrameLen);
             cbReadMuteWithLastAfInfo(pCb, pAfRd);
-            //SW_BREAKPOINT; // FL: debug
+            //SW_BREAKPOINT; // debug
             
 #if 0 // (***) FL: shows timing of CB underflow
             // debug
@@ -788,142 +827,279 @@ Int cbReadAf(
         }
     }
     
+    //
     // 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 next output audio frame.
+        // Read next audio frame.
+        //
+
+        //
+        // Read Audio Frame from CB Audio Frames.
+        // Read PCM & associated metadata from CB AFs until Read AF is filled.
+        //
+        // If multiple CB AFs are read in creating Read AF, CB AF parameters 
+        // can *change* between read CB AFs. Since only one Read AF is produced 
+        // per CB read, this is a "data collision", i.e. can't have more than 
+        // one set of CB AF parameters in Read AF.
         //
+        // Currently applying parameters from earliest read CB AF to Read Af.
+        // This can result in delay (or skip) w.r.t. application of additional 
+        // CB AF parameters not used for creating Read AF. This is reasonable 
+        // given there's no way to "interpolate" AF parameters, e.g. how to 
+        // interpolation change in in bit-stream metadata type, or CC stream?
+        //
+        
+        // debug
+        //gCbReadAfCnt++;
+        //if (gCbReadAfCnt == 1404)
+        //{
+        //   Log_info1("cbReadAf: gCbReadAfCnt=%d", gCbReadAfCnt); // debug
+        //}
         
-        // get pointer to current audio frame in circular buffer
+        // Get pointer to current CB Audio Frame
         pAfCb = &pCb->afCb[pCb->afRdIdx];
 
-        // Invalidate audio frame
+        // Cache invalidate CB AF
         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++) // only invalidate numPrivateMetadata
-        {
-            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++)
-        {
-            if ((streamMask >> i) & 0x1)
-            {
-                Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
-            }
-        }
-        Cache_wait();        
         
-        // read audio frame information updated by decoder
+        // Read CB AF information updated by decoder
         pAfRd->sampleDecode = pAfCb->sampleDecode;
         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
         pAfRd->sampleRate = pAfCb->sampleRate;
-        pAfRd->sampleCount = pCb->strFrameLen;
         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
-        
-        // read metadata information updated by decoder
-        pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
+        // Read CB AF bit-stream metadata information updated by decoder
+        pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if private 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 */
         
-        #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);
+        // Compute stream mask for current CB AF.
+        // Mask indicates which channels are present in AF.
+        // Mask needed for cache invalidate and read of PCM samples in AF.
+        streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
 
-        // read PCM samples
+        // Cache invalidate CB AF samsiz (volume scaling exponent) array
+        Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
+        Cache_wait();
+        
+        // Read CB AF samsiz array
         for (i = 0; i < pCb->maxAFChanNum; i++)
         {
             if ((streamMask >> i) & 0x1)
             {
-                for (j = 0; j < pCb->strFrameLen; j++)
-                {
-                    pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
-                }
-
                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
             }
         }
+
+        // FL: brute force clear of Read AF PCM data
+        // Reset Read AF PCM data
+        //for (i = 0; i < pCb->maxAFChanNum; i++)
+        //{
+        //    if ((streamMask >> i) & 0x1)
+        //    {
+        //        memset(pAfRd->data.sample[i], 0, pCb->strFrameLen);
+        //    }
+        //}
         
+        // FL: This brute force approach shouldn't be necessary if
+        //     decoders properly set, and downstream components
+        //     properly use, number of private metadata in frame
+        // Reset Read AF metadata
         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
         {
             pAfRd->pafPrivateMetadata[i].offset = 0;
             pAfRd->pafPrivateMetadata[i].size   = 0;
         }
         
-        // read metadata
-        for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only read numPrivateMetadata
+        totNumSampsRd = 0;  // init total number of samples read from CB
+        pcmWrtIdx = 0;      // init Read AF PCM write index
+        prvMdWrtIdx = 0;    // init Read AF metadata write index
+        while ((totNumSampsRd < pCb->strFrameLen) && (pCb->numAfCb > 0))
         {
-            if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
-                 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
-                 &&(pAfCb->pafPrivateMetadata[i].size))
+            // Compute how many PCM samples can be read from CB AF
+            //  Number of samples left in current CB AF: pAfCb->sampleCount - pCb->pcmRdIdx
+            //  Number of samples left to write to Read AF: pCb->strFrameLen - totNumSampsRd
+            numSampsRd = (pAfCb->sampleCount - pCb->pcmRdIdx) < (pCb->strFrameLen - totNumSampsRd) ? 
+                (pAfCb->sampleCount - pCb->pcmRdIdx) : (pCb->strFrameLen - totNumSampsRd);
+
+            // Cache invalidate CB AF PCM sample channel pointers
+            Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
+            Cache_wait();
+
+            // Cache invalidate CB AF PCM samples
+            for (i = 0; i < pCb->maxAFChanNum; i++)
             {
-                // 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;
-                memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
-                numMetadata++; //number of metadata associated with current 256 segment of audio samples
+                if ((streamMask >> i) & 0x1)
+                {
+                    Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], numSampsRd*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
+                }
             }
-            else //reset un-used buf
+            Cache_wait();
+
+            // Read PCM samples from CB AF
+            for (i = 0; i < pCb->maxAFChanNum; i++)
             {
-                pAfRd->pafPrivateMetadata[i].offset = 0;
-                pAfRd->pafPrivateMetadata[i].size   = 0;
+                if ((streamMask >> i) & 0x1)
+                {
+                    for (j = 0; j < numSampsRd; j++)
+                    {
+                        pAfRd->data.sample[i][pcmWrtIdx+j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
+                    }
+                }
             }
 
+            // Cache invalidate CB AF unused metadata
+            for (i = pCb->prvMdRdIdx; i < pAfCb->numPrivateMetadata; i++)
+            {
+                Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
+            }
+            Cache_wait();
+
+            // Read CB AF metadata
+            while (((pCb->prvMdRdIdx < pAfCb->numPrivateMetadata) && 
+                (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset >= pCb->pcmRdIdx) &&
+                (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset < (pCb->pcmRdIdx + numSampsRd)) &&
+                (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size)) &&
+                (prvMdWrtIdx < PAF_MAX_NUM_PRIVATE_MD))
+            {
+                // Write Read AF metadata offset.
+                //  Compute relative offset of PCM samples being read from CB AF.
+                //  Compute absolute offset of PCM samples written to Read AF by 
+                //  adding relative offset to Read AF PCM write index.
+                pAfRd->pafPrivateMetadata[prvMdWrtIdx].offset = 
+                    (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset - pCb->pcmRdIdx) +   // offset relative to samples being read from CB AF
+                    pcmWrtIdx;                                                              // absolute offset into samples being written to read AF
+                // Write Read AF metadata size    
+                pAfRd->pafPrivateMetadata[prvMdWrtIdx].size = pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size;
+                // Write Read AF metadata payload
+                memcpy(pAfRd->pafPrivateMetadata[prvMdWrtIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size);
+                
+                pCb->prvMdRdIdx++;  // update CB metadata read index
+                prvMdWrtIdx++;      // update CB metadata write index
+            }
+            
+            // Update CB control
+            pCb->pcmRdIdx += numSampsRd; // update PCM read index
+            if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
+            {
+                // Finished reading PCM samples from current CB AF.
+                // Move to next AF in CB.
+                
+                // Update audio frame read index.
+                // Wrap index if required.
+                pCb->afRdIdx++;
+                if (pCb->afRdIdx >= pCb->maxNumAfCb)
+                {
+                    pCb->afRdIdx = 0;
+                }
+                
+                // Reset PCM read index
+                pCb->pcmRdIdx = 0;
+                // Reset metadata read index
+                pCb->prvMdRdIdx = 0;
+                
+                // Update number of audio frames in circular buffer
+                pCb->numAfCb--;
+            }
+            
+            // Update PCM write index
+            pcmWrtIdx += numSampsRd;
+
+            // Update total number of samples read
+            totNumSampsRd += numSampsRd;
+            
+            if (totNumSampsRd < pCb->strFrameLen)
+            {
+                //
+                // Need to read another AF from CB to obtain all PCM/metadata for Read AF
+                //
+                
+                // Get pointer to current CB Audio Frame
+                pAfCb = &pCb->afCb[pCb->afRdIdx];
+                
+                // Cache invalidate CB AF
+                Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
+                Cache_wait();
+            }
         }
-        pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
-        
-        pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
-        if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
+       
+        pAfRd->sampleCount = totNumSampsRd;         // write Read AF sample count
+        pAfRd->numPrivateMetadata = prvMdWrtIdx;    // write Read AF number of metadata
+       
+        if (totNumSampsRd < pCb->strFrameLen)
         {
-            // update audio frame read index
-            pCb->afRdIdx++;
-            if (pCb->afRdIdx >= pCb->maxNumAfCb)
+            // Clear remaining Read AF PCM samples
+            for (i = 0; i < pCb->maxAFChanNum; i++)
             {
-                pCb->afRdIdx = 0;
+                if ((streamMask >> i) & 0x1)
+                {
+                    memset(&pAfRd->data.sample[i][pcmWrtIdx], 0, (pCb->strFrameLen-totNumSampsRd));
+                }
             }
             
-            // update PCM read index
-            pCb->pcmRdIdx = 0;
+            if (pCb->writerActiveFlag == 1)
+            {
+                //
+                // UNDerflow, 
+                // read stopped due to insufficient PCM samples in CB to fill Read AF
+                //
             
-            // update number of audio frames in circular buffer
-            pCb->numAfCb--;
+                // 
+                // Increment underflow count
+                //
+                pCb->errUndCnt++;
+
+                // Mute output on underflow
+                cbReadMuteWithLastAfInfo(pCb, pAfRd);
+                
+#if 0 // (***) FL: shows timing of CB underflow
+                // 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);
+                }
+#endif
+
+                #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();    
+                
+                // Leave the gate
+                GateMP_leave(gateHandle, key);
+                
+                return ASP_DECOP_CB_READ_UNDERFLOW;
+            }
         }
         
-        // FL: this update of Last AF is handled above
-        //memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
+        // Read AF complete, update Last CB AF Info
+        cbUpdateLastAfInfo(pCb, pAfRd);
 
 #if 0 // (***) FL: shows timing of successful CB read
         {
@@ -934,9 +1110,27 @@ Int cbReadAf(
                 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
             toggleState = ~(toggleState);
         }
-#endif        
+#endif
+
+#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
     }
     
+#if 0
     if (pCb->drainFlag == 1)
     {
         //
@@ -948,6 +1142,7 @@ Int cbReadAf(
             pCb->drainFlag = 0;
         }
     }
+#endif
     
     // Write back circular buffer configuration.
     // NOTE: Probably only a subset of this information needs to be updated.
index 37d40a2956ad92ed6972a5c2ee8e3daa3cbf699d..ddd95e343e9ae242099e9939bf1a77a3c77c4baf 100644 (file)
@@ -941,7 +941,7 @@ const PAF_ASOT_Params asop_params_PAi =
     NULL,                                                   // z_rx_bufsiz
     NULL,                                                   // z_tx_bufsiz
     PAF_AST_params_numchan,                                 // z_numchan
-    PAF_SYS_FRAMELENGTH,                                    // framelength
+    1024, //PAF_SYS_FRAMELENGTH,                                    // framelength
     &PAF_AST_params_audioFrameFunctions,                    // pAudioFrameFunctions
     &PAF_ASP_chainFxns,                                     // pChainFxns
     &PAF_AST_params_inpBufStatus,                           // pInpBufStatus
@@ -954,7 +954,7 @@ const PAF_ASOT_Params asop_params_PAi =
     &PAF_ASP_params_decSioMap,                              // pDecSioMap
     PAF_AST_streamsFromDecodes_std,                         // streamsFromDecodes
     PAF_AST_streamsFromEncodes_std,                         // streamsFromEncodes
-    PAF_MAX_SYS_FRAMELENGTH,                                // maxFramelength
+    1024, //PAF_MAX_SYS_FRAMELENGTH,                                // maxFramelength
     PAF_AST_streamOrder,                                    // streamOrder
     inpLinkInit,                                            // i_inpLinkInit
     outLinkInit,                                            // i_outLinkInit