]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blobdiff - pasdk/test_arm/framework/aspDecOpCircBuf_slave.c
PASDK-218:CB updates for THD 192 kHz
[processor-sdk/performance-audio-sr.git] / pasdk / test_arm / framework / aspDecOpCircBuf_slave.c
index 5427145162c5ed28f06a1bf04669714a1c34b41c..79c645bf5bf92f409e311f979c3ef236091ad078 100644 (file)
@@ -47,6 +47,13 @@ All rights reserved.
 
 #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(
@@ -78,18 +85,17 @@ Int cbCtlInit(
 #endif
 
 // debug
-//Int8 gCbInitSourceSelCnt=0;
-//Int8 gCbInitSourceSelThdCnt=0;
+//Int8 gCbInitDecWriteCnt=0;
+//Int8 gCbInitDecWriteThdCnt=0;
 
-// Initialize circular buffer based on selected source
-Int cbInitSourceSel(
+/// 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)
-    Int16 strFrameLen,                  // stream frame length (PCM samples)
     Int8 resetRwFlags,                  // whether to reset reader, writer, and drain flags
-    PAF_AudioFrame *pDecInfo1Af         // pointer to Dec Info1 audio frame
+    PAF_AudioFrame *pDecInitAf          // pointer to Dec output audio frame used for CB initialization
 )
 {
     IArg key;
@@ -101,7 +107,7 @@ Int cbInitSourceSel(
     Int8 n;
     Int8 i;
 
-    //gCbInitSourceSelCnt++; // debug
+    //gCbInitDecWriteCnt++; // debug
     
     // Get gate handle
     gateHandle = pCbCtl->gateHandle;
@@ -115,7 +121,7 @@ Int cbInitSourceSel(
     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
     Cache_wait();
 
-    //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
+    //Log_info1("cbInitDecWrite:afCb=0x%04x", (IArg)pCb->afCb); // debug
 
     // Set source select
     pCb->sourceSel = sourceSelect;
@@ -123,9 +129,6 @@ Int cbInitSourceSel(
     // Set input frame length
     pCb->decOpFrameLen = decOpFrameLen;
     
-    // Set output frame length
-    pCb->strFrameLen = strFrameLen;
-
     //pCb->afInitialLag = 0;  // default No lag
     //pCb->afLagIdx = 0;
     // Initialize CB primed flag
@@ -138,6 +141,7 @@ Int cbInitSourceSel(
     //  - 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;
@@ -147,10 +151,11 @@ Int cbInitSourceSel(
         
         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;        
+        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))
     {
@@ -161,10 +166,11 @@ Int cbInitSourceSel(
         
         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
-        pCb->pcmRdIdx = 0;
         
         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)
     {
@@ -174,7 +180,7 @@ Int cbInitSourceSel(
         
         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
         // FL: (***) set nominal delay per sampling rate -- need to review these settings
-        switch (pDecInfo1Af->sampleRate)
+        switch (pDecInitAf->sampleRate)
         {
             case PAF_SAMPLERATE_44100HZ:
             case PAF_SAMPLERATE_48000HZ:
@@ -195,10 +201,11 @@ Int cbInitSourceSel(
         
         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;        
+
+        pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
     }
     else
     {
@@ -213,21 +220,30 @@ Int cbInitSourceSel(
 
         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 Info1 AF sample count not correct for CB AFs
+        // 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 Info1 AF
-        pAfCb->sampleDecode = pDecInfo1Af->sampleDecode;
-        PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInfo1Af->sampleProcess);
-        pAfCb->sampleRate = pDecInfo1Af->sampleRate;
-        pAfCb->channelConfigurationRequest.full = pDecInfo1Af->channelConfigurationRequest.full;
-        pAfCb->channelConfigurationStream.full = pDecInfo1Af->channelConfigurationStream.full;
+        // 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. */
@@ -267,6 +283,9 @@ Int cbInitSourceSel(
         }
     }
     
+    // Initialize last audio frame configuration info
+    cbInitLastAfInfo(pCb, pDecInitAf);
+    
     // Reset read/write flags
     if (resetRwFlags != 0)
     {
@@ -277,10 +296,13 @@ Int cbInitSourceSel(
     
     // Reset stats
     pCb->readAfWriterInactiveCnt = 0;
+    pCb->readAfNdCnt = 0;
     pCb->wrtAfReaderInactiveCnt = 0;
     pCb->wrtAfZeroSampsCnt = 0;
-    pCb->errUndCnt = 0;
-    pCb->errOvrCnt = 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);
@@ -419,8 +441,10 @@ Int cbWriteAf(
     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
@@ -450,14 +474,13 @@ Int cbWriteAf(
         {
             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
 
-            // check overflow
-            //while (pCb->numAfCb >= pCb->maxNumAfCb); // debug
+            // check AF overflow
             if (pCb->numAfCb >= pCb->maxNumAfCb)
             {
-                pCb->errOvrCnt++;
+                pCb->errAfOvrCnt++;
 
                 //SW_BREAKPOINT;
-                Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
+                Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
 
                 // Write back circular buffer configuration
                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
@@ -468,28 +491,91 @@ Int cbWriteAf(
 
                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
 
-                return ASP_DECOP_CB_WRITE_OVERFLOW;
+                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];
-            pPcmBuf = pAfCb->data.sample[0];
-            pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
-            if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
+            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++)
             {
-                pPcmBuf = pCb->pcmBuf;
+                // 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;
             }
-
-            for (i=0; i<pCb->maxAFChanNum; i++)
+            
+            // configure AF sample pointers
+            pPcmBuf = pPcmBufWrt;
+            for (i = 0; i < pCb->maxAFChanNum; i++)
             {
-                pAfCb->data.sample[i] = pPcmBuf;
+                // 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;
@@ -499,7 +585,7 @@ Int cbWriteAf(
             }
 
             nextWrtIdx = 0;
-            if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
+            if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
             {
                 //Log_info0("cbWriteAf: AF Wrap around **** ");
                 // next audio frame will be audio frame 0
@@ -540,7 +626,10 @@ Int cbWriteAf(
                     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)
             {
@@ -629,7 +718,9 @@ Int cbWriteAf(
                 
                 // 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;
+                //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;
@@ -655,6 +746,8 @@ Int cbWriteAf(
             }
             Cache_wait();
 
+#if 0 // (***) FL: shows timing of CB write
+            // debug
             {
                 static Uint8 toggleState = 0;
                if (toggleState == 0)
@@ -663,6 +756,8 @@ Int cbWriteAf(
                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
                toggleState = ~(toggleState);
             }
+#endif
+
             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);
         }
@@ -741,3 +836,17 @@ Int cbGetNextWriteAf(
     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;
+}