Update Dec Output circular buffer
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / common / paf_decOpCircBuf.c
index a4b4865a5654d5036ae872f59d2ba5b6ea90e5ce..12e80a665fb4990b78e60bd9dcde855e7c3d1197 100644 (file)
@@ -1,8 +1,44 @@
+
+/*
+Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
+All rights reserved.
+
+* Redistribution and use in source and binary forms, with or without 
+* modification, are permitted provided that the following conditions
+* are met:
+*
+* Redistributions of source code must retain the above copyright
+* notice, this list of conditions and the following disclaimer.
+*
+* Redistributions in binary form must reproduce the above copyright
+* notice, this list of conditions and the following disclaimer in the
+* documentation and/or other materials provided with the
+* distribution.
+*
+* Neither the name of Texas Instruments Incorporated nor the names of
+* its contributors may be used to endorse or promote products derived
+* from this software without specific prior written permission.
+*
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*
+*/
+
 #include <string.h> // for memset()
 #include <xdc/std.h>
 #include <ti/sysbios/hal/Cache.h>
 #include <xdc/runtime/Log.h>
 
+#include "common.h"
 #include "pafdec.h"
 #include "pafsp.h"
 #include "paf_decOpCircBuf.h"
@@ -17,7 +53,8 @@ Int cbInit(
     Int8 sourceSelect,          // source select (PCM, DDP, etc.)
     Int16 decOpFrameLen,        // decoder output frame length (PCM samples)
     Int16 strFrameLen,          // stream frame length (PCM samples)
-    PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
+    PAF_DecodeOpCircBuf *pCb,   // decoder output circular buffer
+    Int8 resetRwFlags           // whether to reset reader, writer, and empty flags
 )
 {
     PAF_AudioFrame *pAfCb;
@@ -60,8 +97,8 @@ Int cbInit(
     {
         pCb->maxNumAfCb = MAX_NUM_AF_DDP;
         pCb->afRdIdx = 0;
-        pCb->afWrtIdx = 0;//1;//QIN - Reduce delay to prevent cb overflow. Need further investigation.
-        pCb->pcmRdIdx = 0;//decOpFrameLen - CB_INIT_RD_LAG*strFrameLen; //QIN - Reduce delay to prevent cb overflow. Need further investigation.
+        pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG*strFrameLen;
+        pCb->afWrtIdx = 1;
         
         // initialize audio frames
         for (n=0; n<pCb->maxNumAfCb; n++)
@@ -112,11 +149,17 @@ Int cbInit(
             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
         }
     }
-    // update flags
-    pCb->writerActiveFlag = 0;
-    pCb->readerActiveFlag = 0;
-    pCb->emptyFlag = 0;
-    //pCb->cbWriteAfInit = 0;
+    
+    // reset read/write flags
+    if (resetRwFlags)
+    {
+        pCb->writerActiveFlag = 0;
+        pCb->readerActiveFlag = 0;
+        pCb->emptyFlag = 0;
+    }
+    // reset error counts
+    pCb->errUndCnt = 0;
+    pCb->errOvrCnt = 0;
     
     // (***) FL: revisit
     // Write back circular buffer configuration
@@ -178,6 +221,7 @@ Int cbWriteStart(
     // (***) FL: revisit
     // Write back circular buffer configuration
     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
 
     return PAF_DECOP_CB_SOK;
 };
@@ -187,6 +231,10 @@ Int cbWriteStop(
     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
 )
 {
+    // Invalidate circular buffer configuration
+    Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
+    
     // update flags
     pCb->writerActiveFlag = 0;
     pCb->emptyFlag = 1;
@@ -194,6 +242,7 @@ Int cbWriteStop(
     // (***) FL: revisit
     // Write back circular buffer configuration
     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
     
     return PAF_DECOP_CB_SOK;
 }
@@ -203,12 +252,17 @@ Int cbReadStart(
     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
 )
 {
+    // Invalidate circular buffer configuration
+    Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
+    
     // update flags
     pCb->readerActiveFlag = 1;
     
     // (***) FL: revisit
     // Write back circular buffer configuration
     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
 
     return PAF_DECOP_CB_SOK;
 }
@@ -218,31 +272,17 @@ Int cbReadStop(
     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
 )
 {
-    // update flags
-    pCb->readerActiveFlag = 0;
-    
-    // (***) FL: revisit
-    // Write back circular buffer configuration
-    Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
-
-    return PAF_DECOP_CB_SOK;
-}
-// restore read/write flags of the circular buffer. - QIN
-Int cbReadWriteRestore(
-    PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
-)
-{
-    // Invalidate circular buffer configuration.
+    // Invalidate circular buffer configuration
     Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
     Cache_wait();
-
+    
     // update flags
-    pCb->readerActiveFlag = 1;
-    pCb->writerActiveFlag = 1;
+    pCb->readerActiveFlag = 0;
     
     // (***) FL: revisit
     // Write back circular buffer configuration
     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
+    Cache_wait();
 
     return PAF_DECOP_CB_SOK;
 }
@@ -268,6 +308,7 @@ Int cbReadAf(
         // This shouldn't occur:
         //  writer is active AND draining circular buffer
         Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
+        SW_BREAKPOINT; // FL: debug
         return PAF_DECOP_CB_READ_INVSTATE;
     }
 
@@ -277,7 +318,6 @@ Int cbReadAf(
         // No active writer, not draining circular buffer.
         // Skip UNDerflow check, mute output.
         //
-        
         pAfRd->sampleDecode = PAF_SOURCE_PCM;
         PAF_PROCESS_ZERO(pAfRd->sampleProcess);
         pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
@@ -309,6 +349,9 @@ Int cbReadAf(
         // check underflow
         if (pCb->numAfCb <= 0)
         {
+            pCb->errUndCnt++;
+            //SW_BREAKPOINT; // FL: debug
+            Log_info1("cbReadAf: ERROR: underflow, numAfCb=%d", pCb->numAfCb);
             return PAF_DECOP_CB_READ_UNDERFLOW;
         }
     }
@@ -378,7 +421,7 @@ Int cbReadAf(
         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
         {
             //Invalidate metadata data
-              Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
+            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))
@@ -477,13 +520,15 @@ Int cbWriteAf(
         }
 #endif        
 
-
         // check overflow
-        //if (pCb->numAfCb >= pCb->maxNumAfCb)
-        //{
-        //    return PAF_DECOP_CB_WRITE_OVERFLOW;
-        //}
-        while (pCb->numAfCb >= pCb->maxNumAfCb); //Qin replace with while loop for debugging
+        if (pCb->numAfCb >= pCb->maxNumAfCb)
+        {
+            pCb->errOvrCnt++;
+            //SW_BREAKPOINT;
+            Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
+            return PAF_DECOP_CB_WRITE_OVERFLOW;
+        }
+        //while (pCb->numAfCb >= pCb->maxNumAfCb); //Qin replace with while loop for debugging
         // get pointer to current audio frame in circular buffer
         pAfCb = &pCb->afCb[pCb->afWrtIdx];
            
@@ -517,7 +562,7 @@ Int cbWriteAf(
         //Write metadata to circular buffer //QIN
         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
         {
-            if (pAfWrt->pafPrivateMetadata[i].size )
+            if (pAfWrt->pafPrivateMetadata[i].size)
             {
                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset; 
                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size; 
@@ -553,7 +598,7 @@ Int cbWriteAf(
                 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
             }
         }
-
+        // write back private metadata
         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
         {
             Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
@@ -587,16 +632,19 @@ Int cbGetNextWriteAf(
 // Output log of circular buffer control variables (debug)
 Int cbLog(
     PAF_DecodeOpCircBuf *pCb,
-    Int8 fullLog
+    Int8 fullLog, 
+    char *locInfo
 )
 {
-    Log_info4("afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, 
+    Log_info1("CB: %s", (IArg)locInfo);
+    Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, emptyFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->emptyFlag);
+    Log_info4("CB: afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, 
         pCb->afWrtIdx, 
         pCb->numAfCb);
     if (fullLog)
     {
-        Log_info1("maxNumAfCb=%d", pCb->maxNumAfCb);  
-        Log_info2("decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
+        Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb);  
+        Log_info2("CB: decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
         //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
     }