Merge branch 'dev_pasdk_frank_pasdk516AsotRefactoring' into dev_pasdk_pasdk29Integration
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamInpDec.c
index c3a0388ddbd96daab8544c49b79cf7de821a0973..cc48d809c1e8f7b61042b22f8e5ee4d5da1a98e7 100644 (file)
@@ -52,36 +52,51 @@ All rights reserved.
 #include "ioPhy.h"
 #include "ioData.h"
 
+
+extern void asitPostInfoEvent();    // TODO: remove
+extern void asitPostDecEvent();     // TODO: remove
+
 enum {
-    INFO1,
-    INFO2,
-    DECODE,
-    QUIT
+    DEC_STATE_INFO_SND,
+    DEC_STATE_INFO_ACK_DECODE_SND,
+    DEC_STATE_DECODE_ACK,
+    DEC_STATE_QUIT
 };
 
-static Int decDecodeInit(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg,
-                         Int sourceSelect);
-static Int decDecodeInfo(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
-                         PAF_ASIT_Config *pAsitCfg);
-static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
-                         PAF_ASIT_Config *pAsitCfg, Int sourceSelect);
+static Int decodeInit(const PAF_ASIT_Params *pP, PAF_ASIT_Config *pAsitCfg,
+                      Int sourceSelect);
+
 static Int decDecodeComplete(const PAF_ASIT_Params *pP,
                              PAF_ASIT_Config *pAsitCfg);
 
-extern Int getFrameLengthSourceSel(const PAF_ASIT_Params *pP, Int8 sourceSelect);
+static Int decErrorCheck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                         PAF_ASIT_Config *pAsitCfg, Int sourceSelect);
+static Int decInfoSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                         PAF_ASIT_Config *pAsitCfg);
+static Int decInfoAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                         PAF_ASIT_Config *pAsitCfg);
+static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                           PAF_ASIT_Config *pAsitCfg);
+static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                           PAF_ASIT_Config *pAsitCfg);
+static Int decDecodeFinalTest(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                              PAF_ASIT_Config *pAsitCfg);
+Int decCheckMajorAu(PAF_AST_Config *pAstCfg);
 
-extern UInt32 gCbWrtAfErrCnt;
+Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf);
+Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf);
 
+extern UInt32 gCbWrtAfErrCnt;
 
 
-Int asipDecodeInit(
+Int decDecodeInit(
         const PAF_ASIT_Params *pP,
         PAF_ASIT_Config *pAsitCfg,
         Int sourceSelect)
 {
     Int errno;
 
-    errno = decDecodeInit(pP, pAsitCfg, sourceSelect);
+    errno = decodeInit(pP, pAsitCfg, sourceSelect);
 
     if(errno) {
         decDecodeComplete(pP, pAsitCfg);
@@ -89,153 +104,251 @@ Int asipDecodeInit(
         return ASIP_ERR_DECODE_INIT;
     }
 
+    pAsitCfg->inpDec.majorAuFound = FALSE;
+    
     return ASIP_NO_ERR;
 }
 
 
 // -----------------------------------------------------------------------------
-// ASIT Processing Function - Decode Processing
-//
-//   Name:      asipDecodeProcessing
-//   Purpose:
-//   Return:    Error number in standard form (0 on success).
 // -----------------------------------------------------------------------------
-Int asipDecodeProcessing(
+Int decDecodeFsm(
         const PAF_ASIT_Params *pP,
         const PAF_ASIT_Patchs *pQ,
         PAF_ASIT_Config *pAsitCfg,
-        Int sourceSelect)
+        Int sourceSelect,
+        UInt decMsg)
 {
-    PAF_AST_Config *pAstCfg;
-    Int decError, retVal, getVal;                          /* error number */
-    Int zMD;
-    Int8 tempVar8;
+    asipDecProc_t  *pDec;
+    Int decErr, decDone;
 
-    pAstCfg = pAsitCfg->pAstCfg;     // get pointer to common (shared) configuration
-    zMD = pAstCfg->masterDec;
+    pDec = &pAsitCfg->inpDec;
 
-    retVal = ASIP_NO_ERR;
+    TRACE_VERBOSE1("Entering decDecodeFsm with decMsg %d.", decMsg);
 
-    tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
-                                 GATEMP_INDEX_DEC);
-    if (tempVar8 == PAF_SOURCE_NONE) {
-        TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: sourceSelect == PAF_SOURCE_NONE");
-        pAsitCfg->inpDec.state = QUIT;   // skip processing, quit decoding
+    decErr = decErrorCheck(pP, pQ, pAsitCfg, sourceSelect);
+    if(decErr == DEC_ERR_ASPERR_ABORT) {
+        return decErr;
     }
-
-    // Process commands (decode)
-    getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg);
-    if (getVal) {
-        if (getVal == ASPERR_QUIT) {
-            pAsitCfg->inpDec.state = QUIT;  // skip processing, quit decoding
-            TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: state = QUIT");
-        }
-        else if (getVal == ASPERR_ABORT) {
-            TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: return getVal");
-
-            // PFP end -- outside of PFP for errors, EOS, or Input SIO change
-            //pfpEnd(PFP_ID_ASIT_2, PFP_FINISH_MEAS);
-            //gNumPfpAsit2--;
-
-            return ASIP_ERR_DECODE_COMMAND;
-        }
-        else {
-            /* ignore */;
-        }
+    else if(decErr != DEC_NO_ERR) {
+        pDec->state = DEC_STATE_QUIT;
+    }
+    else {
+        ; // No error
     }
 
-    retVal = ASIP_NO_ERR;
-
-    switch(pAsitCfg->inpDec.state)
-    {
-        case INFO1:
-            decError = decDecodeInfo(pP, pQ, pAsitCfg);
-            if (decError) {
-                //gAsipInfo1_PrimaryErrCnt++;
-                TRACE_TERSE1("INFO1: decError 0x%x after decodeInfo, primary timing", decError);
-                retVal = ASIP_ERR_DECODE_INFO1;
+    // It is possible to go through the FSM multiple times:
+    //    - Multiple messages may be received, INPDATA and DECACK. In this case,
+    //      the FSM will process DECACK in state DEC_STATE_DECODE_ACK and then 
+    //      INPDATA in state DEC_STATE_INFO_SND.
+    //    - DECACK is received after INPDATA. In this case, after DECACK is 
+    //      processed, we will spoof decMsg with INPDATA so that FSM will run 
+    //      again and process INPDATA in DEC_STATE_INFO_SND.
+    do {
+        switch(pDec->state)
+        {
+        case DEC_STATE_INFO_SND:
+            if(decMsg != DEC_MSGMSK_INPDATA) {
+                // Only DEC_MSGMSK_INPDATA is expected in this state
+                decErr = DEC_ERR_WRONG_MSG;
             }
             else {
-                // Don't start decode until major access unit is found.
-                Int8 sourceDecode, sampleRate;
-
-                sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode),
-                                                 GATEMP_INDEX_DEC);
-                sampleRate   = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate),
-                                                 GATEMP_INDEX_DEC);
-                if ( ( (sourceDecode == PAF_SOURCE_THD)     ||
-                       (sourceDecode == PAF_SOURCE_DXP)     ||
-                       (sourceDecode == PAF_SOURCE_DTSHD) ) &&
-                     ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) {
-                    //gMajorAuMissed++; // debug
-                    pAsitCfg->inpDec.frame++;
-                    //pAsitCfg->inpDec.state = INFO1;    // stay in this state
+                decMsg &= ~DEC_MSGMSK_INPDATA;   // clear bit mask
+
+                // Prepare and send INFO to decoder
+                decErr = decInfoSnd(pP, pQ, pAsitCfg);
+                if(decErr == DEC_NO_ERR) {
+                    pDec->state = DEC_STATE_INFO_ACK_DECODE_SND;
+                    TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_SND done.");
                 }
-                else {
-                    decError = pP->fxns->decodeInfo1(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block);
-                    if(decError) {
-                        retVal = ASIP_ERR_DECODE_INFO1;
+            }
+        break;
+
+        case DEC_STATE_INFO_ACK_DECODE_SND:
+            //if(decMsg != DEC_MSGMSK_INFOACK) {
+                // only DEC_MSGMSK_INFOACK is expected in this state
+            if((decMsg&DEC_MSGMSK_INFOACK) != DEC_MSGMSK_INFOACK) {
+                // During debugging, it is possible that INPDATA and INFOACK
+                // come at the same time (e.g. due to breaking point).
+                decErr = DEC_ERR_WRONG_MSG;
+            }
+            else {
+                decMsg &= ~DEC_MSGMSK_INFOACK;  // clear the bit mask
+
+                // Process the INFO acknowledgment from decoder
+                decErr = decInfoAck(pP, pQ, pAsitCfg);
+                if(decErr == DEC_NO_ERR) {
+                    // Don't start decode until major access unit is found.
+                    if(!pDec->majorAuFound) {
+                        // Do we want to still check major AU after it is found?
+                        // In old code, it was not checked again after it was found. 
+                        pDec->majorAuFound = decCheckMajorAu(pAsitCfg->pAstCfg);    
+                    }
+                    
+                    if(pDec->majorAuFound) {
+                        // Major access unit is found. Send message to decoder to decode now.
+                        decErr = decDecodeSnd(pP, pQ, pAsitCfg);
+                        if(decErr == DEC_NO_ERR) {
+                            pDec->state = DEC_STATE_DECODE_ACK;
+
+                            // Initialize decodeAckDelayed to FALSE - normally
+                            // DECODE ACK comes after INPDATA. 
+                            pDec->decodeAckDelayed = FALSE;
+
+                            TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_DECODE_ACK.");
+                        }
                     }
                     else {
-                        pAsitCfg->inpDec.state = DECODE;
+                        // No major access unit - go back to INFO.
+                        pDec->frame++;
+                        pDec->state = DEC_STATE_INFO_SND;
+                        TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_INFO_ACK_DECODE_SND done and going to DEC_STATE_INFO_SND.");
                     }
                 }
             }
-            break;
-
-        case INFO2:
-            decError = decDecodeInfo(pP, pQ, pAsitCfg);
-            if (decError) {
-                //gAsipInfo1_PrimaryErrCnt++;
-                TRACE_TERSE1("INFO2: decError 0x%x after decodeInfo, primary timing", decError);
-                retVal = ASIP_ERR_DECODE_INFO2;
-            }
-            else {
-                pAsitCfg->inpDec.state= DECODE;
+        break;
+
+        case DEC_STATE_DECODE_ACK:
+            // Two different messages may be received: DECACK (decode acknowledgment)
+            // or INPDATA (input data ready).
+            if(decMsg & DEC_MSGMSK_DECACK) {
+                decMsg &= ~DEC_MSGMSK_DECACK;
+
+                // Process DECODE ACK from decoder
+                decErr = decDecodeAck(pP, pQ, pAsitCfg);
+                if(decErr == DEC_NO_ERR) {
+                    // Decode finishes. Conduct final test.
+                    decErr = decDecodeFinalTest(pP, pQ, pAsitCfg);
+                    if(decErr == DEC_NO_ERR) {
+                        pDec->frame++;
+                        pDec->state = DEC_STATE_INFO_SND;
+                        TRACE_VERBOSE0("decDecodeFsm: DEC_STATE_DECODE_ACK done and going to DEC_STATE_INFO_SND.");
+
+                        // Check if DECACK comes late (after INPDATA)
+                        if(pDec->decodeAckDelayed) {
+                            pDec->decodeAckDelayed = FALSE;
+
+                            // Need to prepare and send INFO to decoder immediately.
+                            // Becuase INPUT_DATA message is already received, 
+                            // we're just spoofing the message with INPDATA to 
+                            // run the FSM one more time. 
+                            decMsg |= DEC_MSGMSK_INPDATA;
+
+                            TRACE_VERBOSE0("decDecodeFsm: Info was delayed.");
+                        }
+                    }
+                }
             }
-            break;
+            else if(decMsg & DEC_MSGMSK_INPDATA) {
+                // If we're here, it means decode acknowledgment from decoder
+                // is delayed, i.e., a new frame of input data is ready before
+                // current frame decoding is finished.
+                decMsg &= ~DEC_MSGMSK_INPDATA;
 
-        case DECODE:
-            decError = decDecodeData(pP, pQ, pAsitCfg, sourceSelect);
-            if (decError) {
-                //gAsipDecodeErrCnt++;
-                TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE.  decodeDecode err 0x%04x", decError);
-                retVal = ASIP_ERR_DECODE_DATA;
+                // Do nothing but set a flag to postpone action.
+                pDec->decodeAckDelayed = TRUE;
+
+                TRACE_VERBOSE0("decDecodeFsm: receiving INPDATA in DEC_STATE_DECODE_ACK");
             }
             else {
-                decError = pP->fxns->decodeFinalTest(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block);
-                if (decError) {
-                    retVal = ASIP_ERR_DECODE_FINAL;
-                }
-                else {
-                    pAsitCfg->inpDec.frame++;
-                    pAsitCfg->inpDec.state = INFO2;
-                }
+                decErr = DEC_ERR_WRONG_MSG;
             }
-            break;
+        break;
 
-        case QUIT:
+        case DEC_STATE_QUIT:
             //gAsipQuitCnt++;
-            Log_info0("TaskAsip: state=QUIT");
-
-            // Quit:
-            // - Set error number registers.
-            // - Exit state machine to "decode complete" processing.
-            TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: state: QUIT");
-            retVal = ASIP_ERR_DECODE_QUIT;
-            break;
+            TRACE_VERBOSE0("decDecodeFsm: state: DEC_STATE_QUIT");
+        break;
 
         default:
-            break;
+        break;
+        } /* switch */
+
+        // Loop through the FSM one more time if:
+        //    - there are more real or spoofed messages to process, 
+        //    - and there is no error.
+        if((decMsg==0) || (decErr!=DEC_NO_ERR)) {
+            decDone = TRUE;
+        }
+        else {
+            decDone = FALSE;
+        }
+    } while(!decDone);
 
+    // Error handling - complete decoding
+    if(decErr != DEC_NO_ERR) {
+        TRACE_VERBOSE1("decDecodeFsm: decErr %d, calling decDecodeComplete.", decErr);
+        decDecodeComplete(pP, pAsitCfg);
+        TRACE_VERBOSE0("decDecodeFsm: decDecodeComplete done.");
     }
 
-    if(retVal != ASIP_NO_ERR) {
-        decDecodeComplete(pP, pAsitCfg);
+    return decErr;
+} /* decDecodeFsm */
+
+
+Int decErrorCheck(const PAF_ASIT_Params *pP,
+                  const PAF_ASIT_Patchs *pQ,
+                  PAF_ASIT_Config *pAsitCfg,
+                  Int sourceSelect
+)
+{
+    Int retVal, getVal, zMD;
+    Int8 sourceConfig;
+
+    retVal = DEC_NO_ERR;
+
+    // Check if source has configured to NONE
+    zMD = pAsitCfg->pAstCfg->masterDec;
+    sourceConfig = sharedMemReadInt8(&(pAsitCfg->pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                     GATEMP_INDEX_DEC);
+    if (sourceConfig == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) {
+        TRACE_VERBOSE0("decDecodeFsm: sourceSelect == PAF_SOURCE_NONE");
+        retVal = DEC_ERR_SOURCE_NONE;
+    }
+
+    // Process commands (decode)
+    getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg);
+    if (getVal == ASPERR_QUIT) {
+        TRACE_VERBOSE0("decDecodeFsm. %d: state = QUIT");
+        retVal = DEC_ERR_ASPERR_QUIT;
+    }
+    else if (getVal == ASPERR_ABORT) {
+        TRACE_VERBOSE0("decDecodeFsm. %d: return getVal");
+
+        // Return here if ASPERR_ABORT
+        retVal = DEC_ERR_ASPERR_ABORT;
+    }
+    else {
+        ;  // No error
     }
 
     return retVal;
-}  /* asipDecodeProcessing */
+}  /* decErrorCheck */
+
+
+Int decCheckMajorAu(PAF_AST_Config *pAstCfg)
+{
+    Int8 sourceDecode, sampleRate;
+    Int zMD;
+
+    zMD = pAstCfg->masterDec;
+
+    sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode),
+                                     GATEMP_INDEX_DEC);
+    sampleRate   = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate),
+                                     GATEMP_INDEX_DEC);
+    if ( ( (sourceDecode == PAF_SOURCE_THD)     ||
+           (sourceDecode == PAF_SOURCE_DXP)     ||
+           (sourceDecode == PAF_SOURCE_DTSHD)
+         )
+       &&( sampleRate == PAF_SAMPLERATE_UNKNOWN)
+       ) {
+        return FALSE;
+    }
+    else {
+        return TRUE;
+    }
+} /* decCheckMajorAu*/
 
 
 // -----------------------------------------------------------------------------
@@ -251,7 +364,7 @@ Int asipDecodeProcessing(
 //              * State information as per parent.
 //
 // -----------------------------------------------------------------------------
-static Int decDecodeInit(
+static Int decodeInit(
         const PAF_ASIT_Params *pP,
         PAF_ASIT_Config *pAsitCfg,
         Int sourceSelect)
@@ -266,8 +379,6 @@ static Int decDecodeInit(
     Int argIdx;
     Int8 tempVar8;
     char decMsgBuf[ASP_MSG_BUF_LEN];
-    ioPhyCtl_t ioPhyCtl;
-    ioDataCtl_t ioDataCtl;
 
     pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration
     pInp    = pAsitCfg->pIoInp;
@@ -300,14 +411,13 @@ static Int decDecodeInit(
         if (pInp[zI].hIoPhy && tempVar8)
         {
             Uns gear;
-            Int frameLength;
             TRACE_VERBOSE1("AS%d: PAF_ASIT_decodeInit: initializing decode", as+zS);
 
             // write back Dec configuration
             Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
 
-            // FL: send dec activate message to slave
+            // send dec activate message to slave
             argIdx = 0; // set decIdx (zone index)
             *(Int32 *)&decMsgBuf[argIdx] = z;
             if(AspMsgSend(ASP_SLAVE_DEC_ACTIVATE, ASP_MASTER_DEC_ACTIVATE_DONE,
@@ -318,7 +428,7 @@ static Int decDecodeInit(
                 return ASIP_ERR_DECODE_MSG; // temporary
             }
 
-            // FL: send dec reset message to slave
+            // send dec reset message to slave
             argIdx = 0; // set decIdx
             *(Int32 *)&decMsgBuf[argIdx] = z;
             if(AspMsgSend(ASP_SLAVE_DEC_RESET, ASP_MASTER_DEC_RESET_DONE,
@@ -334,7 +444,6 @@ static Int decDecodeInit(
                 errno = *(Int32 *)&decMsgBuf[argIdx];
             }
 
-            // (***) FL: revisit
             // invalidate Dec configuration
             Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
@@ -350,12 +459,12 @@ static Int decDecodeInit(
                                tempVar8, GATEMP_INDEX_DEC);
 
             // Compute decoder frame length based on source selection
-            frameLength = getFrameLengthSourceSel(pP, sourceSelect);
+            // JXU: what does this function do? why does it only return PCM frame length?
+            /*frameLength = getFrameLengthSourceSel(pP, sourceSelect);
 
             pAstCfg->xDec[z].decodeControl.frameLength = frameLength;
             pAstCfg->xDec[z].decodeInStruct.sampleCount = frameLength;
-            pAstCfg->xDec[z].decodeControl.sampleRate = PAF_SAMPLERATE_UNKNOWN;
-
+            pAstCfg->xDec[z].decodeControl.sampleRate = PAF_SAMPLERATE_UNKNOWN;*/
 
 /*
             if (z != zMD) {    // JXTODO: implement similar thing with new I/O
@@ -364,21 +473,13 @@ static Int decDecodeInit(
                 }
             }
 */
-            pInp[z].sourceSelect = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.sourceSelect),
-                                                     GATEMP_INDEX_DEC);
-
+/*//JXTODO: find out if frameLength needs to be passed to I/O DATA or I/O PHY.
             ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH;
             ioDataCtl.param.frameLengthPcm = frameLength;
-            errno = ioDataControl(pInp[zI].hIoData, &ioDataCtl);
-
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = frameLength * (WORD_SIZE_PCM);
-            ioPhyControl(pInp[zI].hIoPhy, &ioPhyCtl);
-
-            pInp[zI].phyXferSize = ioPhyCtl.params.xferFrameSize;
-
+            ioDataControl(pInp[zI].hIoData, &ioDataCtl);
+*/
             //JXTODO: do we need to update input status here again?
-            if (errno = asipUpdateInputStatus(pInp[zI].pRxParams,
+            if (errno = asitUpdateInputStatus(pInp[zI].pRxParams,
                                               &pAstCfg->xInp[zI].inpBufStatus,
                                               &pAstCfg->xInp[zI].inpBufConfig)) {
                 return ASIP_ERR_INPUT_CFG;
@@ -388,31 +489,139 @@ static Int decDecodeInit(
 
     pAsitCfg->inpDec.frame = 0;
     pAsitCfg->inpDec.block = 0;
-    pAsitCfg->inpDec.state = INFO1;
+    pAsitCfg->inpDec.state = DEC_STATE_INFO_SND;
 
     return ASIP_NO_ERR;
 }  /* decDecodeInit */
 
 
+
+Int decDecodeComplete( const PAF_ASIT_Params *pP,
+                       PAF_ASIT_Config *pAsitCfg)
+{
+    PAF_AST_Config *pAstCfg;
+    Int as;                     /* Audio Stream Number (1, 2, etc.) */
+    Int z;                      /* decode/encode counter */
+    Int argIdx;
+    Int8 tempVar8;
+    char decMsgBuf[ASP_MSG_BUF_LEN];
+
+    pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration
+    as = pAstCfg->as;
+    (void)as;  // clear compiler warning in case not used with tracing disabled
+
+    for (z=DECODE1; z < DECODEN; z++)
+    {
+        tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode),
+                                     GATEMP_INDEX_DEC);
+        if (pAsitCfg->pIoInp[z].hIoPhy && tempVar8)
+        {
+            TRACE_VERBOSE1("decDecodeComplete: AS%d: finalizing decode", as+z);
+
+            // FL: send dec deactivate message to slave
+            argIdx = 0; // set decIdx
+            *(Int32 *)&decMsgBuf[argIdx] = z;
+            if(AspMsgSend(ASP_SLAVE_DEC_DEACTIVATE, ASP_MASTER_DEC_DEACTIVATE_DONE,
+                          decMsgBuf, NULL) != ASP_MSG_NO_ERR)
+            {
+                TRACE_TERSE0("decodeComplete: error in sending DEC_DEACTIVATE message.");
+                SW_BREAKPOINT;
+                return DEC_ERR_COMPLETE_MSG;
+            }
+        }
+        else
+        {
+            TRACE_VERBOSE1("decDecodeComplete: AS%d: processing decode <ignored>", as+z);
+        }
+    }
+
+    return DEC_NO_ERR;
+}  /* decDecodeComplete */
+
+
 // -----------------------------------------------------------------------------
-// ASIT Decoding Function - Info Processing, Common
+// Decoding Function - Frame-Final Processing
 //
-//   Name:      PAF_ASIT_decodeInfo
-//   Purpose:   Decoding Function for processing information in a manner that
-//              is common for both initial and subsequent frames of input data.
+//   Name:      decDecodeFinalTest
+//   Purpose:   Decoding Function for determining whether processing of the
+//              current frame is complete.
 //   From:      AST Parameter Function -> decodeProcessing
 //   Uses:      See code.
 //   States:    x
-//   Return:    Error number in standard form (0 on success).
-//   Trace:     Message Log "trace" in Debug Project Configuration reports:
-//              * State information as per parent.
-// -----------------------------------------------------------------------------
+//   Return:    0 if incomplete, and 1 if complete.
+//   Trace:     None.
+//
+
 Int
-decDecodeInfo(
+decDecodeFinalTest(
     const PAF_ASIT_Params *pP,
     const PAF_ASIT_Patchs *pQ,
     PAF_ASIT_Config *pAsitCfg
 )
+{
+    PAF_AST_Config *pAstCfg;
+    Int zMD;
+    Int sourceSelect;
+    Int sourceProgram;
+    Int8 tempVar8, temp2Var8;
+
+    pAstCfg = pAsitCfg->pAstCfg; // get pointer to AST common (shared) configuration
+    zMD = pAstCfg->masterDec;
+
+    sourceSelect  = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                           GATEMP_INDEX_DEC);
+    sourceProgram = (Int)sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceProgram),
+                                           GATEMP_INDEX_DEC);
+
+    if ((sourceSelect == PAF_SOURCE_NONE) || (sourceSelect == PAF_SOURCE_PASS))
+    {
+        return DEC_ERR_DECODE_FINAL;
+    }
+
+    // The following allows for Force modes to switch without command deferral. This might
+    // be better suited for inclusion in DIB_requestFrame, but for now will reside here.
+    if ((sourceSelect == PAF_SOURCE_SNG) || (sourceSelect > PAF_SOURCE_BITSTREAM))
+    {
+        if (sourceSelect == PAF_SOURCE_DTSALL)
+        {
+            if (sourceProgram != PAF_SOURCE_DTS11 &&
+                sourceProgram != PAF_SOURCE_DTS12 &&
+                sourceProgram != PAF_SOURCE_DTS13 &&
+                sourceProgram != PAF_SOURCE_DTS14 &&
+                sourceProgram != PAF_SOURCE_DTS16 &&
+                sourceProgram != PAF_SOURCE_DTSHD)
+            {
+                return DEC_ERR_DECODE_FINAL;
+            }
+        }
+        else if (sourceSelect == PAF_SOURCE_PCMAUTO)
+        {
+            if (sourceProgram != PAF_SOURCE_PCM)
+            {
+                return DEC_ERR_DECODE_FINAL;
+            }
+        }
+        else
+        {
+            tempVar8  = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode),
+                                          GATEMP_INDEX_DEC);
+            temp2Var8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                          GATEMP_INDEX_DEC);
+            if (temp2Var8 != tempVar8)
+            {
+                return DEC_ERR_DECODE_FINAL;
+            }
+        }
+    }
+
+    return DEC_NO_ERR;
+} //decDecodeFinalTest
+
+Int decInfoSnd(
+        const PAF_ASIT_Params *pP,
+        const PAF_ASIT_Patchs *pQ,
+        PAF_ASIT_Config *pAsitCfg
+)
 {
     PAF_AST_Config *pAstCfg;
     PAF_AST_IoInp  *pInp;
@@ -420,19 +629,13 @@ decDecodeInfo(
     Int z;                     /* input/decode/stream counter */
     Int errno;                 /* error number */
     Int zD, zI, zS, zX;
-    Int zMD;
-    Int zMS;
     Int argIdx;
     Int8 tempVar8;
-    Int tempVar;
     char decMsgBuf[ASP_MSG_BUF_LEN];
 
     pAstCfg = pAsitCfg->pAstCfg;   // get pointer to common (shared) configuration
     pInp    = pAsitCfg->pIoInp;
     as = pAstCfg->as;
-    zMD = pAstCfg->masterDec;
-    zMS = pAstCfg->masterStr;
-    (void)zMS;  (void)as;  // clear compiler warning in case not used with tracing disabled
 
     // Set decode control: sample rate, emphasis
     for (z=INPUT1; z < INPUTN; z++)
@@ -455,7 +658,7 @@ decDecodeInfo(
                         pAstCfg->xInp[z].inpBufStatus.sampleRateStatus;
                 }
                 else {
-                    TRACE_TERSE1("AS%d: return error ASPERR_INFO_RATECHANGE", as+pAstCfg->masterStr);
+                    //TRACE_TERSE1("decDecodeInfo: AS%d: return error ASPERR_INFO_RATECHANGE", as+pAstCfg->masterStr);
                     TRACE_TERSE2("inpBufStatus.sampleRateStatus: 0x%x, decodeControl.sampleRate: 0x%x",
                         pAstCfg->xInp[z].inpBufStatus.sampleRateStatus,
                         pAstCfg->xDec[zD].decodeControl.sampleRate);
@@ -476,14 +679,6 @@ decDecodeInfo(
         }
     } /* end of for (z=INPUT1; z < INPUTN; z++) */
 
-    // Wait for info input: (JX) all SIO_reclaim does is pend on data, and do sync scan or sync check,
-    //                           which is done in autoDetection routine now.
-    //if (pAstCfg->xInp[zMI].hRxSio)
-    //    sioErr = SIO_reclaim(pAstCfg->xInp[zMI].hRxSio, (Ptr)&pAstCfg->xInp[zMI].pInpBuf, NULL);
-    // FL: debug, capture input buffer
-    //capIb(pAstCfg->xInp[zMI].pInpBuf);
-    //gCapIb_cnt++;
-
     // Decode info
     for (z=DECODE1; z < DECODEN; z++)
     {
@@ -497,52 +692,116 @@ decDecodeInfo(
         {
             TRACE_GEN2("PAF_ASIT_decodeInfo: AS%d: processing frame %d -- info", as+zS, pAsitCfg->inpDec.frame);
 
-            if (errno = asipUpdateInputStatus(pInp[zI].pRxParams,
+            if (errno = asitUpdateInputStatus(pInp[zI].pRxParams,
                                               &pAstCfg->xInp[zI].inpBufStatus,
                                               &pAstCfg->xInp[zI].inpBufConfig)) {
-                TRACE_TERSE1("return error errno 0x%x.", errno);
-                return errno;
+                TRACE_TERSE1("asitUpdateInputStatus return error errno 0x%x.", errno);
+                return DEC_ERR_INFO_SNDMSG;
             }
 
-            // debug, capture input buffer
-            //capIb(pAstCfg->xInp[zI].pInpBuf);
-            //gCapIb_cnt++;
+#if 0 // debug
+            // capture input buffer
+            capIb(pAstCfg->xInp[zI].pInpBuf);
+            gCapIb_cnt++;
+#endif
 
-#if 1
-            // (***) FL: revisit
             // write back Inp configuration
             Cache_wb(&pAstCfg->xInp[zI], sizeof(PAF_AST_InpBuf), Cache_Type_ALLD, 0);
             // write back Dec configuration
             Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
-#endif
 
-            // FL: send info message to slave
+            // send info message to slave
             argIdx = 0; // set decIdx
             *(Int32 *)&decMsgBuf[argIdx] = z;
-            if(AspMsgSend(ASP_SLAVE_DEC_INFO, ASP_MASTER_DEC_INFO_DONE,
-                          decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR)
+            if(AspMsgSnd(ASP_SLAVE_DEC_INFO, decMsgBuf) != ASP_MSG_NO_ERR)
             {
                 TRACE_TERSE0("decodeInfo: error in sending DEC_INFO message ");
                 SW_BREAKPOINT; // temporary
                 return -1;     // temporary
             }
+/*            else
+            {
+                argIdx = 0; // get decErrno
+                errno = *(Int32 *)&decMsgBuf[argIdx];
+            }
+
+            if (errno) {
+                TRACE_TERSE1("decInfoSndMSg return error errno 0x%x.", errno);
+                return DEC_ERR_INFO_SNDMSG;
+            }
+*/
+        }
+    } // z=DECODE1 to DECODEN
+
+//////////////////////////////////////////////////////////////////////////////
+    asitPostInfoEvent();
+//////////////////////////////////////////////////////////////////////////////
+
+    return ASIP_NO_ERR;
+}  /* decInfoSnd() */
+
+
+Int decInfoAck(
+        const PAF_ASIT_Params *pP,
+        const PAF_ASIT_Patchs *pQ,
+        PAF_ASIT_Config *pAsitCfg
+)
+{
+    PAF_AST_Config *pAstCfg;
+    PAF_AST_IoInp  *pInp;
+    Int as;                    /* Audio Stream Number (1, 2, etc.) */
+    Int z;                     /* input/decode/stream counter */
+    Int errno;                 /* error number */
+    Int zI, zS;
+    Int zMD;
+    Int zMS;
+    Int argIdx;
+    Int8 tempVar8;
+    Int tempVar;
+    char decMsgBuf[ASP_MSG_BUF_LEN];
+
+    pAstCfg = pAsitCfg->pAstCfg;   // get pointer to common (shared) configuration
+    pInp    = pAsitCfg->pIoInp;
+    as = pAstCfg->as;
+    zMD = pAstCfg->masterDec;
+    zMS = pAstCfg->masterStr;
+    (void)zMS;  (void)as;  // clear compiler warning in case not used with tracing disabled
+
+    // Decode info
+    for (z=DECODE1; z < DECODEN; z++)
+    {
+        zI = pP->inputsFromDecodes[z];
+        zS = pP->streamsFromDecodes[z];
+        (void)zS; // clear compiler warning in case not used with tracing disabled
+
+        tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[z].decodeStatus.mode),
+                                     GATEMP_INDEX_DEC);
+        if (pInp[zI].hIoPhy  && tempVar8)
+        {
+            // FL: acknowledge info message from slave
+            argIdx = 0; // set decIdx
+            *(Int32 *)&decMsgBuf[argIdx] = z;
+            if(AspMsgAck(ASP_MASTER_DEC_INFO_DONE,
+                         decMsgBuf) != ASP_MSG_NO_ERR)
+            {
+                TRACE_TERSE0("decodeInfo: error in receiving DEC_INFO message ");
+                SW_BREAKPOINT; // temporary
+                return -1;     // temporary
+            }
             else
             {
                 argIdx = 0; // get decErrno
                 errno = *(Int32 *)&decMsgBuf[argIdx];
             }
 
-#if 1
-            // (***) FL: revisit
             // invalidate Dec configuration
             Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
-#endif
 
             if (errno) {
-                TRACE_TERSE1("return error errno 0x%x.", errno);
-                return errno;
+                TRACE_TERSE1("decInfoAck return error errno 0x%x.", errno);
+                return DEC_ERR_INFO_ACKMSG;
             }
 
             // increment decoded frame count
@@ -587,36 +846,19 @@ decDecodeInfo(
     }
 
     return ASIP_NO_ERR;
-} /* decDecodeInfo */
+}
 
 
-// -----------------------------------------------------------------------------
-// ASIT Decoding Function - Decode Processing
-//
-//   Name:      PAF_ASIT_decodeDecode
-//   Purpose:   Decoding Function for processing of input data by the
-//              Decode Algorithm.
-//   From:      AST Parameter Function -> decodeProcessing
-//   Uses:      See code.
-//   States:    x
-//   Return:    Error number in standard form (0 on success).
-//   Trace:     Message Log "trace" in Debug Project Configuration reports:
-//              * State information as per parent.
-// -----------------------------------------------------------------------------
-static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
-                         PAF_ASIT_Config *pAsitCfg, Int sourceSelect)
+static Int decDecodeSnd(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                           PAF_ASIT_Config *pAsitCfg)
 {
     PAF_AST_Config *pAstCfg;
     PAF_AST_IoInp  *pInp;
     Int as;                     /* Audio Stream Number (1, 2, etc.) */
     Int z;                      /* decode/stream counter */
-    Int errno;                  /* error number */
     Int argIdx;
-    Int cbErrno;
-    Int frameLength;
+    Int cbErrno, errno;
     char decMsgBuf[ASP_MSG_BUF_LEN];
-    ioPhyCtl_t  ioPhyCtl;
-    ioDataCtl_t ioDataCtl;
 
     pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration
     pInp    = pAsitCfg->pIoInp;
@@ -638,20 +880,89 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
                     (IArg)pAstCfg->xInp[z].pInpBuf->base.pVoid,
                     (IArg)pAstCfg->xInp[z].pInpBuf->head.pVoid);
 
-            // FL: debug, capture input buffer
-            //capIbPcm(pAstCfg->xInp[z].pInpBuf);
-
-            // (***) FL: revisit
+#if 0 // debug
+            // capture input buffer
+            capIbPcm(pAstCfg->xInp[z].pInpBuf);
+#endif
+            
             // write back Dec configuration
             Cache_wb(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
 
+            // send decode message to slave
+            errno  = 0;
+            argIdx = 0; // set decIdx
+            *(Int32 *)&decMsgBuf[argIdx] = z;
+            if(AspMsgSnd(ASP_SLAVE_DEC_DECODE, decMsgBuf) != ASP_MSG_NO_ERR)
+            {
+                TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message ");
+                SW_BREAKPOINT; // temporary
+                return -1;     // temporary
+            }
+/*            else
+            {
+                argIdx = 0; // get decErrno
+                errno = *(Int32 *)&decMsgBuf[argIdx];
+                argIdx += sizeof(Int32); // get cbErrno
+                cbErrno = *(Int32 *)&decMsgBuf[argIdx];
+                if (cbErrno != 0)
+                {
+                    gCbWrtAfErrCnt++;
+                    TRACE_TERSE1("CB write error=%d", cbErrno);
+                    //SW_BREAKPOINT; // temporary
+                }
+
+                if(errno) {
+                    TRACE_TERSE1("decDecodeSnd return error errno 0x%x.", errno);
+                    return DEC_ERR_DECODE_SNDMSG;
+                }
+            }*/
+
+        } // hIoPhy && decodeStatus.mode
+        else {
+            TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode <ignored>", as+zS, pAsitCfg->inpDec.block);
+        }
+    } // z=DECODE1 to DECODEN
+
+//////////////////////////////////////////////////////////////////////////////
+    asitPostDecEvent();
+//////////////////////////////////////////////////////////////////////////////
+
+    return ASIP_NO_ERR;
+} /* decDecodeSnd() */
+
+
+static Int decDecodeAck(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
+                           PAF_ASIT_Config *pAsitCfg)
+{
+    PAF_AST_Config *pAstCfg;
+    PAF_AST_IoInp  *pInp;
+    Int as;                     /* Audio Stream Number (1, 2, etc.) */
+    Int z;                      /* decode/stream counter */
+    Int errno;                  /* error number */
+    Int argIdx;
+    Int cbErrno;
+    char decMsgBuf[ASP_MSG_BUF_LEN];
+
+    pAstCfg = pAsitCfg->pAstCfg; // get pointer to common (shared) configuration
+    pInp    = pAsitCfg->pIoInp;
+    as = pAstCfg->as;
+    (void)as; // clear compiler warning in case not used with tracing disabled
+
+    // Decode data
+    for (z=DECODE1; z < DECODEN; z++)
+    {
+        Int zI = pP->inputsFromDecodes[z];
+        Int zS = pP->streamsFromDecodes[z];
+        (void)zS; // clear compiler warning in case not used with tracing disabled
+        if ( pInp[zI].hIoPhy && pAstCfg->xDec[z].decodeStatus.mode )
+        {
             // FL: send decode message to slave
             errno  = 0;
             argIdx = 0; // set decIdx
             *(Int32 *)&decMsgBuf[argIdx] = z;
-            if(AspMsgSend(ASP_SLAVE_DEC_DECODE, ASP_MASTER_DEC_DECODE_DONE,
-                          decMsgBuf, decMsgBuf) != ASP_MSG_NO_ERR)
+            errno = AspMsgAck(ASP_MASTER_DEC_DECODE_DONE, decMsgBuf);
+            if(errno != ASP_MSG_NO_ERR)
             {
                 TRACE_TERSE0("decodeDecode: error in sending DEC_DECODE message ");
                 SW_BREAKPOINT; // temporary
@@ -671,38 +982,18 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
                 }
             }
 
-            // (***) FL: revisit
             // invalidate Dec configuration
             Cache_inv(&pAstCfg->xDec[z], sizeof(PAF_AST_Decode), Cache_Type_ALLD, 0);
             Cache_wait();
 
-            if (errno)
-            {
-                TRACE_VERBOSE1("PAF_ASIT_decodeDecode: fxns->decode returns 0x%x", errno);
-                return errno;
+            if(errno) {
+                TRACE_TERSE1("decDecodeAck return error errno 0x%x.", errno);
+                return DEC_ERR_DECODE_ACKMSG;
             }
 
 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
             as_traceChannels(pAsitCfg, z);
 #endif
-
-            // Compute decoder frame length based on source selection
-            frameLength = getFrameLengthSourceSel(pP, sourceSelect);
-
-            pAstCfg->xDec[z].decodeControl.frameLength  = frameLength;
-            pAstCfg->xDec[z].decodeInStruct.sampleCount = frameLength;
-
-            ioDataCtl.code = IODATA_CTL_SET_PCM_FRAME_LENGTH;
-            ioDataCtl.param.frameLengthPcm = frameLength;
-            errno = ioDataControl(pInp[zI].hIoData, &ioDataCtl);
-
-            ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
-            ioPhyCtl.params.xferFrameSize = frameLength * (WORD_SIZE_PCM);
-            ioPhyControl(pInp[zI].hIoPhy, &ioPhyCtl);
-
-            pInp[zI].phyXferSize = ioPhyCtl.params.xferFrameSize;
-
-            //JXTODO: find out if frameLength needs to be passed to I/O DATA or I/O PHY.
         } // hIoPhy && decodeStatus.mode
         else {
             TRACE_VERBOSE2("AS%d: PAF_ASIT_decodeDecode: processing block %d -- decode <ignored>", as+zS, pAsitCfg->inpDec.block);
@@ -710,34 +1001,108 @@ static Int decDecodeData(const PAF_ASIT_Params *pP, const PAF_ASIT_Patchs *pQ,
     } // z=DECODE1 to DECODEN
 
     return ASIP_NO_ERR;
+} /* decDecodeAck */
 
-} /* decDecodeData */
 
 
-Int decDecodeComplete( const PAF_ASIT_Params *pP,
-                       PAF_ASIT_Config *pAsitCfg)
+/************************************************************************************
+ * ASP message sending function. Refer to aspMsg_master.h for detailed description.
+************************************************************************************/
+Int AspMsgSnd(UInt32 sndCmd, char *sndMsgBuf)
 {
-    int z, zMD, decError;
-    ALG_Handle alg[DECODEN_MAX];
+    ASP_Msg* pAspMsg;                   /* Messaging */
+    Int status;
+
+    // allocate message
+    pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize);
+    if (pAspMsg == NULL) {
+        TRACE_TERSE0("MessageQ_alloc() failure.");
+        return (ASP_MSG_ERR_QUEUE_ALLOC);
+    }
 
-    zMD = pAsitCfg->pAstCfg->masterDec;
+    // set the return address in the message header and fill in message payload
+    MessageQ_setReplyQueue(hAspMsgMaster->masterQue, (MessageQ_Msg)pAspMsg);
+    pAspMsg->cmd = sndCmd;
+    pAspMsg->procId = hAspMsgMaster->masterProcId;
+    pAspMsg->messageId = hAspMsgMaster->messageId & ~(1<<31);
+    pAspMsg->expectResp = TRUE;
 
-    for (z=DECODE1; z < DECODEN; z++)
-    {
-        alg[z] = pAsitCfg->pAstCfg->xDec[z].decAlg[PAF_SOURCE_PCM];
+    // copy the message provided by caller
+    if(sndMsgBuf != NULL) {
+        memcpy(pAspMsg->buf, sndMsgBuf, ASP_MSG_BUF_LEN*sizeof(char));
+    }
+
+    // send the message
+    TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId);
+    status = MessageQ_put(hAspMsgMaster->slaveQue, (MessageQ_Msg)pAspMsg);
+    if (status != MessageQ_S_SUCCESS) {
+        TRACE_TERSE0("MessageQ_put() failure.");
+        MessageQ_free((MessageQ_Msg)pAspMsg);
+        return (ASP_MSG_ERR_QUEUE_PUT);
+    }
+
+    status = MessageQ_free((MessageQ_Msg)pAspMsg);
+    if (status != MessageQ_S_SUCCESS) {
+        TRACE_TERSE0("MessageQ_free() failure.");
+        return (ASP_MSG_ERR_QUEUE_FREE);
     }
-    alg[zMD] = NULL; // decAlgMaster; // FL: alg[] init is on slave
 
-    // Call decodeComplete: 2nd argument is NOT used inside the function
-    decError = pP->fxns->decodeComplete(pP, NULL, pAsitCfg, alg,
-                                        pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block);
+    // No error in messaging operation, even though there
+    // may be error in returned (acknowledgement) message.
+    return (ASP_MSG_NO_ERR);
+} /* AspMsgSnd */
 
-    if(decError) {
-        return ASIP_ERR_DECODE_COMPLETE;
+/************************************************************************************
+ * ASP message sending function. Refer to aspMsg_master.h for detailed description.
+************************************************************************************/
+Int AspMsgAck(UInt32 ackCmd, char *ackMsgBuf)
+{
+    ASP_Msg* pAspMsg;                   /* Messaging */
+    Int status;
+
+    // allocate message
+    pAspMsg = (ASP_Msg *)MessageQ_alloc(hAspMsgMaster->heapId, hAspMsgMaster->msgSize);
+    if (pAspMsg == NULL) {
+        TRACE_TERSE0("MessageQ_alloc() failure.");
+        return (ASP_MSG_ERR_QUEUE_ALLOC);
     }
 
-    return ASIP_NO_ERR;
-}  /* decDecodeComplete */
+    // wait for complete message from slave
+    status = MessageQ_get(hAspMsgMaster->masterQue, (MessageQ_Msg *)&pAspMsg, MessageQ_FOREVER);
+    if (status != MessageQ_S_SUCCESS) {
+        TRACE_TERSE0("MessageQ_get() failure.");
+        MessageQ_free((MessageQ_Msg)pAspMsg);
+        return (ASP_MSG_ERR_QUEUE_GET);
+    }
+
+    // check if returned message is valid
+    if ((pAspMsg->procId != hAspMsgMaster->slaveProcId) ||
+        (pAspMsg->cmd != ackCmd) ||
+        (pAspMsg->messageId != (hAspMsgMaster->messageId | ((UInt32)1<<31)))) {
+        TRACE_TERSE3("ERROR: ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId);
+        MessageQ_free((MessageQ_Msg)pAspMsg);
+        return(ASP_MSG_ERR_ACKNOWLEDGE);
+    }
+
+    hAspMsgMaster->messageId = (hAspMsgMaster->messageId + 1) & ~(1<<31);
+    TRACE_TERSE3("ASP message: procId=%d, cmd=%d, messageId=0x%04x", pAspMsg->procId, pAspMsg->cmd, pAspMsg->messageId);
+
+    // get the returned message
+    if(ackMsgBuf != NULL) {
+        memcpy(ackMsgBuf, pAspMsg->buf, ASP_MSG_BUF_LEN*sizeof(char));
+    }
+
+    // free the message
+    status = MessageQ_free((MessageQ_Msg)pAspMsg);
+    if (status != MessageQ_S_SUCCESS) {
+        TRACE_TERSE0("MessageQ_free() failure.");
+        return (ASP_MSG_ERR_QUEUE_FREE);
+    }
+
+    // No error in messaging operation, even though there
+    // may be error in returned (acknowledgement) message.
+    return (ASP_MSG_NO_ERR);
+} /* AspMsgAck */
 
 
 #if 0
@@ -800,4 +1165,174 @@ Int asipDecodeProcessing(
 }  /* asipDecodeProcessing */
 #endif
 
+
+#if 0
+// -----------------------------------------------------------------------------
+// ASIT Processing Function - Decode Processing
+//
+//   Name:      asipDecodeProcessing
+//   Purpose:
+//   Return:    Error number in standard form (0 on success).
+// -----------------------------------------------------------------------------
+Int asipDecodeProcessing(
+        const PAF_ASIT_Params *pP,
+        const PAF_ASIT_Patchs *pQ,
+        PAF_ASIT_Config *pAsitCfg,
+        Int sourceSelect)
+{
+    PAF_AST_Config *pAstCfg;
+    asipDecProc_t  *pDec;
+    Int decError, retVal, getVal;                          /* error number */
+    Int zMD, decDone;
+    Int8 tempVar8;
+
+    pAstCfg = pAsitCfg->pAstCfg;     // get pointer to common (shared) configuration
+    zMD = pAstCfg->masterDec;
+    pDec = &pAsitCfg->inpDec;
+
+    retVal = ASIP_NO_ERR;
+
+    // Initialization for decode processing
+    if(!pDec->initDone) {
+        // Initialize decoder and send message to decoder
+        retVal = decDecodeInit(pP, pAsitCfg, pAsitCfg->pIoInp[zMD].sourceSelect);
+        if(retVal != ASIP_NO_ERR) {
+            decDecodeComplete(pP, pAsitCfg);
+
+            return retVal;
+        }
+
+        pDec->initDone = TRUE;
+    }
+
+    // Check if source has configured to NONE
+    tempVar8 = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceSelect),
+                                 GATEMP_INDEX_DEC);
+    if (tempVar8 == PAF_SOURCE_NONE || sourceSelect == PAF_SOURCE_NONE) {
+        TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: sourceSelect == PAF_SOURCE_NONE");
+        pAsitCfg->inpDec.state = QUIT;   // skip processing, quit decoding
+        retVal = ASIP_ERR_DECODE_QUIT;
+    }
+
+    // Process commands (decode)
+    getVal = pP->fxns->decodeCommand(pP, pQ, pAsitCfg);
+    if (getVal) {
+        retVal = ASIP_ERR_DECODE_COMMAND;
+        if (getVal == ASPERR_QUIT) {
+            TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: state = QUIT");
+
+            // Don't return if ASPERR_QUIT, but skip decode processing and quit
+            pAsitCfg->inpDec.state = QUIT;
+        }
+        else if (getVal == ASPERR_ABORT) {
+            TRACE_VERBOSE0("PAF_ASIT_decodeProcessing. %d: return getVal");
+
+            // Return here if ASPERR_ABORT
+            return retVal;
+        }
+        else {
+            /* ignore */;
+        }
+    }
+
+    do {
+        decDone = TRUE;
+
+        switch(pAsitCfg->inpDec.state)
+        {
+            case INFO1:
+                decError = decDecodeInfo(pP, pQ, pAsitCfg);
+                if (decError) {
+                    //gAsipInfo1_PrimaryErrCnt++;
+                    TRACE_TERSE1("INFO1: decError 0x%x after decodeInfo, primary timing", decError);
+                    retVal = ASIP_ERR_DECODE_INFO1;
+                }
+                else {
+                    // Don't start decode until major access unit is found.
+                    Int8 sourceDecode, sampleRate;
+
+                    sourceDecode = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sourceDecode),
+                                                     GATEMP_INDEX_DEC);
+                    sampleRate   = sharedMemReadInt8(&(pAstCfg->xDec[zMD].decodeStatus.sampleRate),
+                                                     GATEMP_INDEX_DEC);
+                    if ( ( (sourceDecode == PAF_SOURCE_THD)     ||
+                           (sourceDecode == PAF_SOURCE_DXP)     ||
+                           (sourceDecode == PAF_SOURCE_DTSHD) ) &&
+                         ( sampleRate == PAF_SAMPLERATE_UNKNOWN) ) {
+                        //gMajorAuMissed++; // debug
+                        pAsitCfg->inpDec.frame++;
+                        //pAsitCfg->inpDec.state = INFO1;    // stay in this state
+                    }
+                    else {
+                        decError = pP->fxns->decodeInfo1(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block);
+                        if(decError) {
+                            retVal = ASIP_ERR_DECODE_INFO1;
+                        }
+                        else {
+                            pAsitCfg->inpDec.state = DECODE;
+                            decDone = FALSE;    // go to DECODE state before return
+                        }
+                    }
+                }
+                break;
+
+            case INFO2:
+                decError = decDecodeInfo(pP, pQ, pAsitCfg);
+                if (decError) {
+                    //gAsipInfo1_PrimaryErrCnt++;
+                    TRACE_TERSE1("INFO2: decError 0x%x after decodeInfo, primary timing", decError);
+                    retVal = ASIP_ERR_DECODE_INFO2;
+                }
+                else {
+                    pAsitCfg->inpDec.state = DECODE;
+                    decDone = FALSE;     // go to DECODE state before return
+                }
+                break;
+
+            case DECODE:
+                decError = decDecodeData(pP, pQ, pAsitCfg, sourceSelect);
+                if (decError) {
+                    //gAsipDecodeErrCnt++;
+                    TRACE_TERSE1("PAF_ASIT_decodeProcessing: state: DECODE.  decodeDecode err 0x%04x", decError);
+                    retVal = ASIP_ERR_DECODE_DATA;
+                }
+                else {
+                    decError = pP->fxns->decodeFinalTest(pP, pQ, pAsitCfg, pAsitCfg->inpDec.frame, pAsitCfg->inpDec.block);
+                    if (decError) {
+                        retVal = ASIP_ERR_DECODE_FINAL;
+                    }
+                    else {
+                        pAsitCfg->inpDec.frame++;
+                        pAsitCfg->inpDec.state = INFO2;
+                    }
+                }
+                break;
+
+            case QUIT:
+                //gAsipQuitCnt++;
+                Log_info0("TaskAsip: state=QUIT");
+
+                // Quit:
+                // - Set error number registers.
+                // - Exit state machine to "decode complete" processing.
+                TRACE_VERBOSE0("PAF_ASIT_decodeProcessing: state: QUIT");
+                break;
+
+            default:
+                break;
+
+        }  /* switch */
+
+    } while (!decDone);
+
+    if(retVal != ASIP_NO_ERR) {
+        decDecodeComplete(pP, pAsitCfg);
+    }
+
+    return retVal;
+}  /* asipDecodeProcessing */
+
+#endif
+
+
 /* Nothing past this line */