PASDK-568: added logic and encoder wrapper to handle output buffer wrapping around
authorJianzhong Xu <a0869574@ti.com>
Thu, 19 Apr 2018 21:16:12 +0000 (17:16 -0400)
committerJianzhong Xu <a0869574@ti.com>
Thu, 19 Apr 2018 21:16:12 +0000 (17:16 -0400)
pasdk/test_dsp/framework/audioStreamOutDec.c
pasdk/test_dsp/framework/audioStreamOutIo.c
pasdk/test_dsp/framework/audioStreamOutIo.h
pasdk/test_dsp/framework/audioStreamOutProc.c

index eba3872e82601f371f590b5f479413edc530efdb..16b57b776c8d6a278fb35f36d208d50ee2afebc9 100644 (file)
@@ -51,6 +51,8 @@ All rights reserved.
 #include "audioStreamOutProc.h"
 #include "audioStreamOutIo.h"
 #include "audioStreamOutDec.h"
+#include "ioConfig.h"    //TODO: remove this header
+#include "ioPhy.h"
 
 #define ENC_Handle PCE_Handle /* works for all: PCE */
 
@@ -156,7 +158,7 @@ Int asopDecOutProcInfo1(
     // Reset ASP chain
     //
     TRACE_VERBOSE0("asopDecOutProcInfo1: calling streamChainFunction.");
-    errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);
+    errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);  // SRC reset is called inside;
     if (errno)
     {
         TRACE_TERSE1("asopDecOutProcInfo1: streamChainFunction returns errno 0x%x ", errno);
@@ -523,22 +525,27 @@ Int asopDecOutProcEncode(
 
         if (pOut[z].hIoPhy)
         {
-            // update length (e.g. ARC may have changed)
-            pAstCfg->xOut[z].outBufConfig.lengthofFrame =
+            uint32_t phyXferSizeOld;
+
+            // update length (e.g. ARC may have changed) - moved out of this function
+/*            pAstCfg->xOut[z].outBufConfig.lengthofFrame =
                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
-                
+*/
             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- idle", as+zS, frame);
 
 #if 0 // FL, New IO: add similar thing to be figured out
             // Update framework Phy transfer size
-            pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * OUTPUT_STRIDE * WORD_SIZE_PCM;
+            phyXferSizeOld = pOut[z].phyXferSize;
+            pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * pOut[z].stride * WORD_SIZE_PCM;
             // Update IO Phy transfer size            
             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
             ioPhyCtl.params.xferFrameSize = pOut[z].phyXferSize;
             ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
             // Update IO Buff delay to match Phy transfer size
-            ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
-
+            if(pOut[z].phyXferSize != phyXferSizeOld) {
+                ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
+            }
+/*
             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
             if (errno < 0)
             {
@@ -546,6 +553,7 @@ Int asopDecOutProcEncode(
                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
                 return -errno; // SIO negates error codes
             }
+*/
 #endif
 
 #if 0 // debug 
@@ -983,7 +991,7 @@ static Int streamChainFunction(
                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final)"
                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
                        as+z, logArg);
-            errno = (*func) (chain, frame);
+            errno = (*func) (chain, frame);   // ASP chain reset function: SRC is the 1st in the chain and reset
             TRACE_VERBOSE2("asopStreamChainFunction: AS%d: errno 0x%x.", as+z, errno);
 
             if (errno && abortOnError)
index 2a92966baf005aa697de0a1efa954a7c2b1e6a20..f8ea42b7d0750b89a87acbb82910b0a76101ead8 100644 (file)
@@ -609,6 +609,43 @@ Int asopInitOutBufConfig(
     return 0;
 }
 
+Int asopGetOutBufPtrs(
+    PAF_AST_IoOut *pOutIo,
+    size_t writeSize
+)
+{
+    void *buff1, *buff2;
+    size_t size1, size2;
+    Int status;
+
+    status = ioBuffGetWritePtrs(pOutIo->hIoBuff, writeSize,
+                                &buff1, &size1, &buff2, &size2);
+    if (status == IOBUFF_ERR_OVERFLOW)
+    {
+        pOutIo->errIoBuffOvrCnt++;
+        //System_printf ("asopGetOutBufPtrs: output buff overflow\n"); // debug
+
+        // skip processing since output buffer overflows
+        return -1;
+    }
+    else if (status == IOBUFF_ERR_UNDERFLOW)
+    {
+        pOutIo->errIoBuffUndCnt++;
+        //System_printf ("asopGetOutBufPtrs: output buff underflow\n"); // debug
+
+        // already underflows and remain in underflow
+    }
+
+    // save buffer pointers & sizes for later write complete
+    pOutIo->buff1 = buff1;
+    pOutIo->size1 = size1;
+    pOutIo->buff2 = buff2;
+    pOutIo->size2 = size2;
+
+    return 0;
+}
+
+#if 0
 // Update Output buffer configuration.
 // This is needed for proper operation of PCM encoder.
 Int asopUpdateOutBufConfig(
@@ -652,7 +689,7 @@ Int asopUpdateOutBufConfig(
         
         // already underflows and remain in underflow
     }
-
+#if 0
     // Update Output buffer pointer for Encoder
        pOutBufCfg->pntr.pLgInt = buff1;
     if ((buff2 != NULL) || (size2 != 0))
@@ -661,7 +698,7 @@ Int asopUpdateOutBufConfig(
         // Track this here.
         pOutIo->ioBuffBuf2AllocCnt++; // debug
     }
-    
+#endif
     // save buffer pointers & sizes for later write complete
     pOutIo->buff1 = buff1;
     pOutIo->size1 = size1;
@@ -670,6 +707,7 @@ Int asopUpdateOutBufConfig(
     
     return 0;
 }
+#endif
 
 // Mark Output buffers write complete
 Int asopMarkOutBuffsWriteComplete(
index cbebe02f8d80be5ca02848f599d5547ee959d412..605438489066252ceb8428cc1af87aa6d530c12d 100644 (file)
@@ -107,6 +107,12 @@ Int asopInitOutBufConfig(
     PAF_AST_IoOut *pOutIo
 );
 
+// Get output buffer write pointers for encoder to write
+Int asopGetOutBufPtrs(
+    PAF_AST_IoOut *pOutIo,
+    size_t writeSize
+);
+
 // Update Output buffer configuration
 Int asopUpdateOutBufConfig(
     PAF_AST_OutBuf *pOutBuf, 
index 3515ac05cf05839ee40e2d62e2dd65c17db0daac..ce7c121b7c4048a88c931ca332bd3fd375333eee 100644 (file)
@@ -46,6 +46,7 @@ All rights reserved.
 #include "audioStreamOutInit.h"
 #include "audioStreamOutDec.h"
 #include "audioStreamOutIo.h"
+#include "common.h"
 
 //#include "pfp/pfp.h"
 //#include "pfp_app.h"        /* contains all PFP ID's */
@@ -242,6 +243,14 @@ static Int PAF_ASOT_initSyncResync(
     Int frame
 );
 
+static Int asopDecOutProcEncodeWrap(
+    const PAF_ASOT_Params *pP,
+    const PAF_ASOT_Patchs *pQ,
+    PAF_ASOT_Config *pAsotCfg,
+    Int frame,
+    Int zO
+);
+
 // ASOT SM function
 //   Purpose:   Re-select devices used for Output.
 //              Performs Init-Sync using stored Dec Reset/Info1 AFs.
@@ -371,7 +380,7 @@ Void taskAsopFxn(
         }
 
         asopLoopCount++;
-        TRACE_GEN1("TaskAsop (begin Main loop %d)", asopLoopCount);
+        //TRACE_GEN1("TaskAsop (begin Main loop %d)", asopLoopCount);
 
         switch (pAsotCfg->state)
         {
@@ -1142,7 +1151,9 @@ static Int PAF_ASOT_initSyncDecInfo1(
             // THD sets this to 256 (hard-coded in Dec Info)
             // DDP sets this to 0 (audio frame pass through, 0 from ASDT AF frame length)
             // PCM sets this to 256 (decodeControl.frameLength)
-        pDecInfo1Af->sampleCount = gOutFrameLen;    // !!!! GJ: Revisit !!!!
+        //pDecInfo1Af->sampleCount = pAsotCfg->pAstCfg->xDecOpCb[zMS].strFrameLen; // gOutFrameLen;    // !!!! GJ: Revisit !!!!
+        pDecInfo1Af->sampleCount = 512; // debugging for 96kHz
+        //pDecInfo1Af->sampleCount = 1024; // debugging for 192kHz
         
         // Update Stream Audio Frame.
         // Copy Dec Reset AF to Stream AF.
@@ -1153,6 +1164,7 @@ static Int PAF_ASOT_initSyncDecInfo1(
         //      - Enc Info,
         //      - Start Output
         status = asopDecOutProcInfo1(pP, pQ, pAsotCfg, frame);
+
         if (status < 0)
         {
             return status;
@@ -1223,6 +1235,7 @@ static Int PAF_ASOT_initSyncDecDecode1(
 
         // I/O physical layer prime operation required by McASP LLD
         asopIoPhyPrime(&pAsotCfg->pIoOut[zO]);        
+        TRACE_VERBOSE0("PAF_ASOT_initSyncDecDecode1: ASOP McASP LLD primed.");
         
         return ASOP_SOK;
     }
@@ -1321,15 +1334,18 @@ static Int PAF_ASOT_procDecOut(
 
     if (status == ASOP_SOK)
     {
-        // Update Output buffer configuration
-        asopUpdateOutBufConfig(&pAstCfg->xOut[zO], &pAsotCfg->pIoOut[zO]);
-        
-        // Execute encode
-        errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
-        if (errno < 0)
-        {
-            status = errno;
-        }
+        size_t totalOutputSize;
+
+        // Calculate the total size that encoder will write to output buffer
+        totalOutputSize = pAstCfg->xEnc[zO].encodeInStruct.pAudioFrame->sampleCount
+                          * pAstCfg->xOut[zO].outBufConfig.stride
+                          * pAstCfg->xOut[zO].outBufConfig.sizeofElement;
+
+        // Get output buffer pointers for encoder to write. Pointers are stored in pAsotCfg->pIoOut[zO]
+        asopGetOutBufPtrs(&pAsotCfg->pIoOut[zO], totalOutputSize);
+
+        // Invoke the encoder
+        asopDecOutProcEncodeWrap(pP, pQ, pAsotCfg, frame, zO);
 
         // Mark Output buffers write complete
         asopMarkOutBuffsWriteComplete(&pAstCfg->xOut[zO], &pAsotCfg->pIoOut[zO]);
@@ -1367,6 +1383,95 @@ static Int PAF_ASOT_procDecOut(
     return status;
 }
 
+static Int asopDecOutProcEncodeWrap(
+    const PAF_ASOT_Params *pP,
+    const PAF_ASOT_Patchs *pQ,
+    PAF_ASOT_Config *pAsotCfg,
+    Int frame,
+    Int zO
+)
+{
+    PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
+    Int errno;                  // error number
+    Int status;                 // status code
+    PAF_OutBufConfig *pOutBufCfg;
+    PAF_AudioFrame * pAf;
+
+    status = ASOP_SOK;
+    pAstCfg = pAsotCfg->pAstCfg;
+    pOutBufCfg = &(pAstCfg->xOut[zO].outBufConfig);
+    pAf = pAstCfg->xEnc[zO].encodeInStruct.pAudioFrame;
+
+    if(pAsotCfg->pIoOut[zO].buff2 == NULL)
+    {
+        // Output buffer won't wrap around - to invoke the encoder once
+        pOutBufCfg->lengthofFrame = pAf->sampleCount;
+        pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff1;
+
+        // Execute encode
+        errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
+        if (errno < 0)
+        {
+            status = errno;
+        }
+    }
+    else
+    {
+        // Output buffer will wrap around - to invoke the encoder twice
+        XDAS_Int16 sampleCountSave;
+        PAF_AudioData *afDataAddrSave[16];
+        PAF_AudioData **afDataAddr;
+        int i, ch;
+
+        sampleCountSave = pAf->sampleCount;  // save sample count for restoring later
+
+        // Invoke the encoder to write data to the end of output buffer
+        pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size1 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
+        pAf->sampleCount = pOutBufCfg->lengthofFrame;
+        pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff1;
+
+        // Execute encode
+        errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
+        if (errno < 0)
+        {
+            status = errno;
+        }
+
+        // Adjust audio frame buffer addresses for second invoking of the encoder
+        afDataAddr = pAf->data.sample;
+        for(i=0; i<pOutBufCfg->stride; i++)
+        {
+            ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
+            afDataAddrSave[i] = afDataAddr[ch];   // save audio frame buffer addresses
+            afDataAddr[ch] = &afDataAddr[ch][pOutBufCfg->lengthofFrame];
+        }
+
+        // Invoke the encoder to write data to the beginning of output buffer (wrapping around)
+        pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size2 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
+        pAf->sampleCount = pOutBufCfg->lengthofFrame;
+        pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff2;
+
+        // Execute encode
+        errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
+        if (errno < 0)
+        {
+            status = errno;
+        }
+
+        // Restore sample count and audio frame buffer addresses
+        pAf->sampleCount = sampleCountSave;
+        for(i=0; i<pOutBufCfg->stride; i++)
+        {
+            ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
+            afDataAddr[ch] = afDataAddrSave[i];
+        }
+
+        pAsotCfg->pIoOut[zO].ioBuffBuf2AllocCnt++; // debug
+    }
+
+    return status;
+}
+
 // ASOT SM function
 //   Purpose:   Init-Sync Re-Sync state function.
 //              Performs Init-Sync using stored Dec Reset/Info1 AFs.