/* Copyright (c) 2017, 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. * */ /* * ======== audioStreamOutProc.c ======== */ #include // for memset #include #include #include #include #include #include "paferr.h" #include #include #include #include #include #include #include "asperr.h" #include "common.h" #include "aspMsg_common.h" #include "aspMsg_master.h" #include "aspDecOpCircBuf_master.h" #include "aspOutInitSync_master.h" #include "audioStreamProc_common.h" #include "audioStreamOutProc.h" #include "pfp/pfp.h" #include "pfp_app.h" /* contains all PFP ID's */ Int32 gNumPfpAsot1=0; // debug // FL: debug #include "evmc66x_gpio_dbg.h" #include "dbgCapAf.h" #include "ioConfig.h" // ----------------------------------------------------------------------------- // Debugging Trace Control, local to this file. // #include "logp.h" #define TRACE_TIME(a) // Allow a developer to selectively enable tracing. #define CURRENT_TRACE_MASK 0x07 #define TRACE_MASK_TERSE 0x01 // only flag errors and show init #define TRACE_MASK_GENERAL 0x02 // half dozen lines per frame #define TRACE_MASK_VERBOSE 0x04 // trace full operation #if !(CURRENT_TRACE_MASK & TRACE_MASK_TERSE) #undef TRACE_TERSE0 #undef TRACE_TERSE1 #undef TRACE_TERSE2 #undef TRACE_TERSE3 #undef TRACE_TERSE4 #define TRACE_TERSE0(a) #define TRACE_TERSE1(a,b) #define TRACE_TERSE2(a,b,c) #define TRACE_TERSE3(a,b,c,d) #define TRACE_TERSE4(a,b,c,d,e) #endif #if !(CURRENT_TRACE_MASK & TRACE_MASK_GENERAL) #undef TRACE_GEN0 #undef TRACE_GEN1 #undef TRACE_GEN2 #undef TRACE_GEN3 #undef TRACE_GEN4 #define TRACE_GEN0(a) #define TRACE_GEN1(a,b) #define TRACE_GEN2(a,b,c) #define TRACE_GEN3(a,b,c,d) #define TRACE_GEN4(a,b,c,d,e) #endif #if !(CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE) #undef TRACE_VERBOSE0 #undef TRACE_VERBOSE1 #undef TRACE_VERBOSE2 #undef TRACE_VERBOSE3 #undef TRACE_VERBOSE4 #define TRACE_VERBOSE0(a) #define TRACE_VERBOSE1(a,b) #define TRACE_VERBOSE2(a,b,c) #define TRACE_VERBOSE3(a,b,c,d) #define TRACE_VERBOSE4(a,b,c,d,e) #endif // ............................................................................. // // Audio Stream Definitions // // // Audio Stream Processing Definitions // #define aspLinkInit pQ->i_aspLinkInit // // Encoder Definitions // #define encLinkInit pQ->i_encLinkInit // // Output Definitions // #define outLinkInit pP->i_outLinkInit /* ---------------------------------------------------------------- */ /* Parameter macro definitions end here. */ /* ---------------------------------------------------------------- */ // // Standardized Definitions // #define ENC_Handle PCE_Handle /* works for all: PCE */ #define __TASK_NAME__ "TaskAsop" // // Audio Stream Output Task definitions // // status codes // Output FSM #define ASOP_INITSYNC_NOTREADY ( 1 ) // ok, init-sync not ready #define ASOP_SOK ( 0 ) // ok #define ASOP_FORWARD_ERR ( -1 ) // forward (ASIT) error #define ASOP_ENCRESET_ERR ( -2 ) // enc reset error #define ASOP_DECINFO1_ERR ( -3 ) // dec info1 error // Decode Processing #define ASOP_DP_OUT_SIO_UPDATE ( 3 ) // new output selected #define ASOP_DP_CB_DRAINED ( 2 ) // circular buffer drained #define ASOP_DP_SOK ( 0 ) // ok #define ASOP_DP_FORWARD_ERR ( -1 ) // forward (ASIT) error #define ASOP_DP_DECINIT_ERR ( -2 ) // decode init error #define ASOP_DP_DECSTREAM_ERR ( -3 ) // decode stream error #define ASOP_DP_DECENC_ERR ( -4 ) // decode encode error #define ASOP_DP_DECINFO2_ERR ( -5 ) // decode encode error #define ASOP_DP_DECFINALTEST_ERR ( -6 ) // decode final error /* Check if at least one output selected */ static Int checkOutSel( const PAF_ASOT_Params *pP, PAF_ASOT_Config *pAsotCfg, Int *pOutSel ); /* Check if at least one output sio changed */ static Int checkOutSio( const PAF_ASOT_Params *pP, PAF_ASOT_Config *pAsotCfg, Int *pOutSioUpdate ); // Initialize Output Processing state function //static Int PAF_ASOT_initOutProc( // used by new OutProc.c, will be changed back to static once refactoring is done Int PAF_ASOT_initOutProc( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ); // Initialize Output Processing state function // used by new OutProc.c, will be changed back to static once refactoring is done Int PAF_ASOT_initSyncDecReset( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecResetAf ); // Purpose: ASOT Function for Output reset static Int PAF_ASOT_outputReset( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ); // Purpose: Init-Sync Dec Info1 state function. // Performes Dec Info1 Init-Sync. Int PAF_ASOT_initSyncDecInfo1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecInfo1Af ); // Purpose: ASOT function for ASP chain reset and ENC info static Int PAF_ASOT_outputInfo1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ); // Purpose: Init-Sync Dec Decode1 state function. // Performes Dec Decode1 Init-Sync. Int PAF_ASOT_initSyncDecDecode1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ); // Purpose: Init-Sync Re-Sync state function. // Peformed Init-Sync using stored Dec Reset/Info1 AFs. Int PAF_ASOT_initSyncResync( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecResetAf, PAF_AudioFrame *pDecInfo1Af ); #if 0 // Init-Sync update audio frame static Int initSyncUpdateAf( PAF_AudioFrame *dstAf, PAF_AudioFrame *srcAf ); #endif // Reset audio frames static Void resetAfs( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ); // Reset audio frame pointers to original values static Void resetAfPointers( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ); // Reset audio frame meta data elements static Void resetAfMetadata( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ); LINNO_DEFN(TaskAsop); /* Line number macros */ ERRNO_DEFN(TaskAsop); /* Error number macros */ // ASOT configuration #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig") PAF_ASOT_Config gPAF_ASOT_config = { NULL, // taskHandle NULL, // acp 0,0,0, // CB drained flags (size DECODE_MAXN) &gPAF_ASPM_config, // pAspmCfg &gPAF_AST_config // pAstCfg }; // Underflow threshold before circular buffer reset and return error to Top-Level FSM #define DEC_OP_CB_RDAF_UND_THR ( 80 ) // FL: arbitrary setting UInt32 gCbReadAfErr =0; // read circular buffer error count, not including underflows UInt32 gDecOpCbRdAfUnd =0; // decoder output circular buffer underflow count UInt32 gMaxDecOpCbRdAfUnd =0; // max (consecutive) decoder output circular buffer underflow count UInt32 gMasterCbResetCnt =0; // master circular buffer reset count // For writeDECCommandRestart extern volatile UInt32 gCommandOutputTask_SYNC; extern volatile UInt32 gCommandOutputTask_ACK; // Global debug counters */ UInt32 gAsopTxSioReclaimCnt =0; UInt32 gAsopInitOutProcCnt =0; UInt32 gAsopInitSyncDecResetCnt =0; UInt32 gAsopInitSyncDecInfo1Cnt =0; UInt32 gAsopInitSyncDecDecode1Cnt =0; UInt32 gAsopInitSyncResyncCnt =0; UInt32 gAsopOutProcCnt =0; UInt32 gAsopInitCnt =0; UInt32 gAsopStreamCnt =0; UInt32 gAsopEncodeCnt =0; UInt32 gAsopFinalCnt =0; UInt32 gAsopOutSioUpdateCnt =0; UInt32 gAsopQuitCnt =0; /* * ======== taskAsopFxnInit ======== * Audio Stream Output Processing initialization function */ Void taskAsopFxnInit( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ ) { PAF_ASOT_Config *pAsotCfg; /* ASOT configuration pointer */ PAF_AST_Config *pAstCfg; /* Common (shared) configuration pointer */ Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/encode/stream/decode/output counter */ Int i; /* phase */ Int zMS; Log_info0("Enter taskAsopFxnInit()"); // // Audio Stream Output Task Parameters & Patch (*pP, *pQ) // if (!pP) { TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting."); LINNO_RPRT(TaskAsop, -1); return; } if (!pQ) { TRACE_TERSE0("TaskAsop: No Patchs defined. Exiting."); LINNO_RPRT(TaskAsop, -1); return; } // // Audio Stream Output Task Configuration (*pAsotCfg): // pAsotCfg = &gPAF_ASOT_config; // initialize pointer to task configuration pAsotCfg->taskHandle = Task_self(); // set task handle pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration /* Obtain Audio Stream Number (1, 2, etc.) */ as = pAstCfg->as; TRACE_TERSE1("TaskAsop: Started with AS%d.", as); // // Initialize message log trace and line number reporting // for (z=STREAM1; z < STREAMN; z++) { TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z); } LINNO_RPRT(TaskAsop, -1); // // Determine stream index // zMS = pAstCfg->masterStr; // Initialize as per parametrized phases: // // In standard form these are: // - Malloc: Memory Allocation // - Config: Configuration Initialization // - AcpAlg: ACP Algorithm Initialization and Local Attachment // - Common: Common Memory Initialization // - AlgKey: Dec/Enc chain to Array Initialization // - Device: I/O Device Initialization // - Unused: (available) // - Unused: (available) // LINNO_RPRT(TaskAsop, -2); for (i=0; i < lengthof(pP->fxns->initPhase); i++) { Int linno; if (pP->fxns->initPhase[i]) { linno = pP->fxns->initPhase[i](pP, pQ, pAsotCfg); if (linno) { LINNO_RPRT(TaskAsop, linno); return; } } else { TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS); } TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i); LINNO_RPRT(TaskAsop, -i-3); } // // End of Initialization -- display memory usage report. // if (pP->fxns->memStatusPrint) { pP->fxns->memStatusPrint("ASOT MEMSTAT REPORT", HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, HEAP_INTERNAL1_SHM, HEAP_EXTERNAL_SHM, HEAP_EXTERNAL_NONCACHED_SHM); } } /* taskAsopFxnInit */ /* * ======== taskAsopFxn ======== * Audio Stream Output Processing task function */ #ifdef PASDK_SIO_DEV Void taskAsopFxn( #else #ifndef IO_LOOPBACK_TEST Void taskAsopFxn_NOt_Used( #else Void taskAsopFxn_Not_Used( #endif #endif const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ ) { PAF_ASOT_Config *pAsotCfg; /* ASOT configuration pointer */ PAF_AST_Config *pAstCfg; /* Common (shared) configuration pointer */ Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/encode/stream/decode/output counter */ Int zMS; Int errno; // error number Int8 procSleep; // whether to sleep: 0: No, 1: Yes Int8 procOutDevSel; // whether to perform output device selection: 0: No, 1:Yes Int outSel; // whether output device selected enum { INIT_OUT_PROC_STATE, INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE, INITSYNC_RESYNC_STATE, OUT_PROC_STATE } state; PAF_AudioFrame decResetAf; PAF_AudioFrame decInfo1Af; Int loopCount = 0; // used to stop trace to see startup behavior. Log_info0("Enter taskAsopFxn()"); taskAsopFxnInit(pP, pQ); // initialization of output task // // Audio Stream Output Task Configuration (*pAsotCfg): // pAsotCfg = &gPAF_ASOT_config; // initialize pointer to task configuration pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration /* Obtain Audio Stream Number (1, 2, etc.) */ as = pAstCfg->as; zMS = pAstCfg->masterStr; // // Main processing loop // for (z=STREAM1; z < STREAMN; z++) { TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z); } errno = 0; // init error indicator -- no error procSleep = 1; // init sleep flag -- sleep procOutDevSel = 1; // init device output selection flag -- perform output device selection state = INIT_OUT_PROC_STATE; // init state for (;;) { loopCount++; TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno); // // Check forward (ASIT) error here, TBD // // Even if we are not in error state, we check if writeDECCommandRestar issued or not if (gCommandOutputTask_SYNC) { TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Wait for the command deasserted"); gCommandOutputTask_ACK = 1; while (gCommandOutputTask_SYNC) { Task_sleep(1); } TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Startover the process"); procSleep = 1; // init sleep flag -- sleep procOutDevSel = 1; // init device output selection flag -- perform output device selection state = INIT_OUT_PROC_STATE; // init state -- starover errno = ASOP_DP_FORWARD_ERR; // Override the error -- for flushing SIO output device } // any error forces idling of output if (errno) { for (z=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].hTxSio) { SIO_idle(pAstCfg->xOut[z].hTxSio); } } TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount); ERRNO_RPRT(TaskAsop, errno); } if (procSleep == 1) { TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS); Task_sleep(1); } if (procOutDevSel == 1) { // select output devices TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS); errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg); if (errno) { TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno); procSleep = 1; procOutDevSel = 1; continue; } // if no output selected skip remaining processing errno = checkOutSel(pP, pAsotCfg, &outSel); if (errno < 0) { TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno); procSleep = 1; procOutDevSel = 1; continue; } else if (!outSel) { TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS); procSleep = 1; procOutDevSel = 1; continue; } } switch (state) { case INIT_OUT_PROC_STATE: gAsopInitOutProcCnt++; Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE"); // // Output Processing initialization. // errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr); if (errno < 0) { state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else { state = INITSYNC_DEC_RESET_STATE; procSleep = 0; procOutDevSel = 0; } break; case INITSYNC_DEC_RESET_STATE: gAsopInitSyncDecResetCnt++; Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE"); // // Dec Reset Init-Sync. // // Perform Dec Reset init-sync. // Latch Dec Reset AF. errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf); if (errno < 0) { Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno); // sync error -- start over state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else if (errno == ASOP_INITSYNC_NOTREADY) { Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno); // sync not ready -- try again state = INITSYNC_DEC_RESET_STATE; errno=0; // FL: temp hack procSleep = 1; procOutDevSel = 1; } else // errno==0 { Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno); // sync'd -- move on state = INITSYNC_DEC_INFO1_STATE; procSleep = 0; procOutDevSel = 0; } break; case INITSYNC_DEC_INFO1_STATE: gAsopInitSyncDecInfo1Cnt++; Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE"); // // Dec Info1 Init-Sync. // // Perform Dec Info1 init-sync. // Latch Dec Info1 AF. errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af); if (errno < 0) { Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno); // sync error -- start over state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else if (errno == ASOP_INITSYNC_NOTREADY) { Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno); // sync not ready -- try again state = INITSYNC_DEC_INFO1_STATE; errno=0; // FL: temp hack procSleep = 1; procOutDevSel = 0; } else // errno = 0 { Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno); // sync'd -- move on state = INITSYNC_DEC_DECODE1_STATE; procSleep = 0; procOutDevSel = 0; } break; case INITSYNC_DEC_DECODE1_STATE: gAsopInitSyncDecDecode1Cnt++; Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE"); // // Dec Info1 Init-Sync. // // Perform Dec Info1 init-sync. // Latch Dec Info1 AF. errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg); if (errno < 0) { Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno); // sync error -- start over state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else if (errno == ASOP_INITSYNC_NOTREADY) { Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno); // sync not ready -- try again state = INITSYNC_DEC_DECODE1_STATE; errno=0; // FL: temp hack procSleep = 1; procOutDevSel = 0; } else // errno = 0 { Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno); // sync'd -- move on state = OUT_PROC_STATE; procSleep = 0; procOutDevSel = 0; } break; case INITSYNC_RESYNC_STATE: gAsopInitSyncResyncCnt++; Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE"); // // Re-Sync. // Use stored AF info from init-sync. // This is done in case of local error. // // Perform Dec Info1 init-sync. errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf, &decInfo1Af); if (errno < 0) { Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno); // sync error -- start over state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else { Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno); // re-sync'd -- move on state = OUT_PROC_STATE; procSleep = 0; procOutDevSel = 0; } break; case OUT_PROC_STATE: gAsopOutProcCnt++; Log_info0("TaskAsop: state=OUT_PROC_STATE"); // // Output Processing. // TRACE_VERBOSE0("TaskAsop: calling decodeProcessing."); errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg); if (errno < 0) { Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno); // // Output Processing exit, due to error // TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno); if (errno == ASOP_DP_FORWARD_ERR) { // forward (ASIT) error -- start over state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } else { // local (ASOT) error state = INITSYNC_RESYNC_STATE; procSleep = 1; procOutDevSel = 0; // disallow device re-select if local error during output processing } } else if (errno > 0) { Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno); // // Output Processing exit, not due to error // TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno); if (errno == ASOP_DP_OUT_SIO_UPDATE) { // skip re-sync // resume output processing after new output selected state = OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } } else { Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno); // // Output Processing exit, normal // TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error."); // no error returned if CB drained // (i.e. CB drained is normal behavior) state = INIT_OUT_PROC_STATE; procSleep = 1; procOutDevSel = 1; } break; default: // unknown state TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state); break; } } // End of main processing loop for (;;) //Log_info0("Exit taskAsopFxn()"); } Int PAF_ASOT_ioCompCreate(PAF_AST_IoOut *pIoOut, int numOut, IHeap_Handle iHeapHandle) { int i, j, num_alloc; lib_mem_rec_t *mem_rec; ioBuffHandle_t ioBufHandle; ioPhyHandle_t ioPhyHandle; Error_Block eb; for(i=0; ipAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; zMS = pAstCfg->masterStr; TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS); // Initialize error block Error_init(&eb); /* Stream memory */ if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb))) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.", STREAMN * sizeof (*pAstCfg->xStr), HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr); { Int z; /* stream counter */ PAF_AudioFrame *fBuf; if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb))) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.", STREAMS * sizeof (*fBuf), HEAP_ID_INTERNAL, (IArg)fBuf); for (z=STREAM1; z < STREAMN; z++) { pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1]; TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame); } } /* Encode memory */ if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb))) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.", ENCODEN * sizeof (*pAstCfg->xEnc), HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc); /* Output memory */ if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb))) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.", OUTPUTN * sizeof (*pAstCfg->xOut), HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut); /* Output I/O data structure memory */ if (!(pAsotCfg->pIoOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAsotCfg->pIoOut), 4, &eb))) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAsotCfg->pIoOut) %d bytes from space %d at 0x%x.", OUTPUTN * sizeof (*pAsotCfg->pIoOut), HEAP_ID_INTERNAL, (IArg)pAsotCfg->pIoOut); /* I/O components memory for output */ errLineNum = PAF_ASOT_ioCompCreate(pAsotCfg->pIoOut, OUTPUTN, (IHeap_Handle)HEAP_INTERNAL); if(errLineNum) { SW_BREAKPOINT; return errLineNum; } TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS); return 0; } //PAF_ASOT_initPhaseMalloc // ----------------------------------------------------------------------------- // ASOT Initialization Function - Memory Initialization from Configuration // // Name: PAF_ASOT_initPhaseConfig // Purpose: Audio Stream Output Task Function for initialization of data values // from parameters. // From: audioStream1Task or equivalent // Uses: See code. // States: x // Return: 0 on success. // Other as per initFrame0 and initFrame1. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // Int PAF_ASOT_initPhaseConfig( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/encode/stream/decode/output counter */ Int zMS; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; zMS = pAstCfg->masterStr; TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS); // // Unspecified elements have been initialized to zero during alloc // for (z=STREAM1; z < STREAMN; z++) { Int linno; if (linno = pP->fxns->initFrame0(pP, pQ, pAsotCfg, z)) { return linno; } if (linno = pP->fxns->initFrame1(pP, pQ, pAsotCfg, z, -1)) { return linno; } } for (z=ENCODE1; z < ENCODEN; z++) { Int zO = pP->outputsFromEncodes[z]; Int zS = pP->streamsFromEncodes[z]; pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl); pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame; pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus; pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig; pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z]; pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select; pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus; pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame; } for (z=OUTPUT1; z < OUTPUTN; z++) { pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus; } TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS); return 0; } //PAF_ASOT_initPhaseConfig // ----------------------------------------------------------------------------- // ASOT Initialization Function - ACP Algorithm Instantiation // // Name: PAF_ASOT_initPhaseAcpAlg // Purpose: Audio Stream Input Task Function for initialization of ACP by // instantiation of the algorithm. // From: audioStream1Task or equivalent // Uses: See code. // States: x // Return: 0 on success. // Source code line number on ACP Algorithm creation failure. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // * Memory allocation errors. // Int PAF_ASOT_initPhaseAcpAlg( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/encode/stream/decode/output counter */ Int betaPrimeOffset; ACP_Handle acp; Int zMS; Int zS, zX; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; zMS = pAstCfg->masterStr; TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS); ACP_MDS_init(); if (!(acp = (ACP_Handle )ACP_MDS_create(NULL))) { TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation failed", as+zMS); return __LINE__; } pAsotCfg->acp = acp; ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp, ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset); for (z=ENCODE1; z < ENCODEN; z++) { zS = pP->streamsFromEncodes[z]; acp->fxns->attach(acp, ACP_SERIES_STD, STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS), (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus); acp->fxns->attach(acp, ACP_SERIES_STD, STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS), (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus); /* Ignore errors, not reported. */ } for (z=OUTPUT1; z < OUTPUTN; z++) { zS = z; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zS = pP->streamsFromEncodes[zX]; break; } } acp->fxns->attach(acp, ACP_SERIES_STD, STD_BETA_OB + betaPrimeOffset * (as-1+zS), (IALG_Status *)&pAstCfg->xOut[z].outBufStatus); /* Ignore errors, not reported. */ } TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS); return 0; } //PAF_ASOT_initPhaseAcpAlg // ----------------------------------------------------------------------------- // ASOT Initialization Function - Common Memory // // Name: PAF_ASOT_initPhaseCommon // Purpose: Audio Stream Output Task Function for allocation of common memory. // From: audioStream1Task or equivalent // Uses: See code. // States: x // Return: 0 on success. // Source code line number on PAF_ALG_alloc failure. // Source code line number on PAF_ALG_mallocMemory failure. // Source code line number on Decode Chain initialization failure. // Source code line number on ASP Chain initialization failure. // Source code line number on Encode Chain initialization failure. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // * Memory allocation errors. // Int PAF_ASOT_initPhaseCommon( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* stream counter */ Int g; /* gear */ ACP_Handle acp; PAF_IALG_Config pafAlgConfig; IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1]; acp = pAsotCfg->acp; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory"); // // Determine memory needs and instantiate algorithms across audio streams // TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup."); PAF_ALG_setup(&pafAlgConfig, HEAP_ID_INTERNAL, HEAP_INTERNAL, HEAP_ID_INTERNAL1, HEAP_INTERNAL1, HEAP_ID_EXTERNAL, HEAP_EXTERNAL, HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM, HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM, HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM, HEAP_CLEAR); if (pP->fxns->headerPrint) { pP->fxns->headerPrint(); } for (z = STREAM1; z < STREAMN; z++) { //Int zD, zE, zX; Int zE, zX; TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z); // // Determine common memory needs for: // (1) ASP Algorithms // (2) Encode Algorithms // (3) Logical Output drivers // PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE); zE = -1; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->streamsFromEncodes[zX] == z) { zE = zX; break; } } TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z); if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z])) { TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z); TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base); if (pP->fxns->allocPrint) { pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig); } if (zE >= 0) { TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z); if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z])) { TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base); if (pP->fxns->allocPrint) { pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig); } } // // Determine common memory needs of Logical IO drivers // if (OUTPUT1 <= z && z < OUTPUTN) { TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z); if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z])) { TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z); TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space); SW_BREAKPOINT; return __LINE__; } TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base); if (pP->fxns->allocPrint) { pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig); } } } { // Changes made to share scratch between zones // Assume maximum 3 zones and scratch common memory is at offset 0; int max=0; for (z=STREAM1; zsize, common[z]->space, (IArg)common[z]->base); // share zone0 scratch with all zones common[z][0].base = common[0][0].base; if (pP->fxns->commonPrint) { pP->fxns->commonPrint(common[z], &pafAlgConfig); } zE = -1; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->streamsFromEncodes[zX] == z) { zE = zX; break; } } pAstCfg->xStr[z].aspChain[0] = NULL; for (g=0; g < GEARS; g++) { PAF_ASP_Chain *chain; TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs."); chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns, HEAP_INTERNAL, as+z, acp, &trace, aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig); if (!chain) { TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g); return __LINE__; } else { pAstCfg->xStr[z].aspChain[g] = chain; } } if (zE >= 0) { PAF_ASP_Chain *chain; TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode."); chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns, HEAP_INTERNAL, as+z, acp, &trace, encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig); if (!chain) { TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z); return __LINE__; } } // // Allocate non-common memories for Logical IO drivers // Since these structures are used at run-time we allocate from external memory if (OUTPUT1 <= z && z < OUTPUTN) { PAF_ASP_Chain *chain; TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d", as+z, z); chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns, HEAP_EXTERNAL, as+z, acp, &trace, outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig); if (!chain) { TRACE_TERSE1("AS%d: Output chain initialization failed", as+z); return __LINE__; } } } TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z); return 0; } //PAF_ASOT_initPhaseCommon // ----------------------------------------------------------------------------- // ASOT Initialization Function - Algorithm Keys // // Name: PAF_ASOT_initPhaseAlgKey // Purpose: Audio Stream Output Task Function for initialization of data values // from parameters for Algorithm Keys. // From: audioStream1Task or equivalent // Uses: See code. // States: x // Return: 0. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // // ............................................................................. Int PAF_ASOT_initPhaseAlgKey( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/encode counter */ Int s; /* key number */ PAF_ASP_Link *that; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as); for (z=ENCODE1; z < ENCODEN; z++) { for (s=0; s < pP->pEncAlgKey->length; s++) { if ((pP->pEncAlgKey->code[s].full != 0) && (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s]))) { pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg; } /* Cast in interface, for now --Kurt */ else { pAstCfg->xEnc[z].encAlg[s] = NULL; } } } return 0; } //PAF_ASOT_initPhaseAlgKey // ----------------------------------------------------------------------------- // ASOT Initialization Function - I/O Devices // // Name: PAF_ASOT_initPhaseDevice // Purpose: Audio Stream Output Task Function for initialization of I/O Devices. // From: audioStream1Task or equivalent // Uses: See code. // States: x // Return: 0 on success. // Source code line number on device allocation failure. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // * Memory allocation errors. // Int PAF_ASOT_initPhaseDevice( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/output counter */ PAF_SIO_IALG_Obj *pObj; PAF_SIO_IALG_Config *pAlgConfig; PAF_IALG_Config pafAlgConfig; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as); if(pP->fxns->bufMemPrint) { PAF_ALG_setup (&pafAlgConfig, HEAP_ID_INTERNAL, HEAP_INTERNAL, HEAP_ID_INTERNAL1, HEAP_INTERNAL1, HEAP_ID_EXTERNAL, HEAP_EXTERNAL, HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM, HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM, HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM, HEAP_CLEAR); TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR); } for (z=OUTPUT1; z < OUTPUTN; z++) { PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig; pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg; pAlgConfig = &pObj->config; pAstCfg->xOut[z].hTxSio = NULL; pConfig->base.pVoid = pAlgConfig->pMemRec[0].base; pConfig->pntr.pVoid = pAlgConfig->pMemRec[0].base; pConfig->head.pVoid = pAlgConfig->pMemRec[0].base; pConfig->allocation = pAlgConfig->pMemRec[0].size; pConfig->sizeofElement = 3; pConfig->precision = 24; if(pP->fxns->bufMemPrint) { pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1); } } TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as); return 0; } //PAF_ASOT_initPhaseDevice // ----------------------------------------------------------------------------- // ASOT Initialization Function Helper - Initialization of Audio Frame // // Name: PAF_ASOT_initFrame0 // Purpose: Audio Stream Output Task Function for initialization of the Audio // Frame(s) by memory allocation and loading of data pointers // and values. // From: AST Parameter Function -> decodeInfo // Uses: See code. // States: x // Return: 0 on success. // Source code line number on MEM_calloc failure. // Source code line number on unsupported option. // Trace: Message Log "trace" in Debug Project Configuration reports: // * Memory allocation errors. // * Unsupported option errors. // // MID 314 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN]; extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch; Int PAF_ASOT_initFrame0( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int z ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int ch; //Int aLen; Int aLen_int=0,aLen_ext=0; Int aSize = sizeof(PAF_AudioData); Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize; Int maxFrameLength = pP->maxFramelength; Int zX; PAF_AudioData *aBuf_int=NULL; PAF_AudioData *aBuf_ext=NULL; XDAS_UInt8 *metadataBuf; char i; Error_Block eb; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; // Initialize error block Error_init(&eb); // Compute maximum framelength (needed for ARC support) maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO; //aLen = numchan[z] * maxFrameLength; for (i=0; i < numchan[z]; i++) { if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM) { aLen_int += maxFrameLength; } else { aLen_ext += maxFrameLength; } } // // Initialize audio frame elements directly // pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions; pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; /// /// pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF; pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH; pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers; pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes; pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT; // // Allocate memory for and initialize pointers to audio data buffers // // The NUMCHANMASK is used to identify the channels for which data // buffers can be allocated. Using this mask and switch statement // rather than some other construct allows efficient code generation, // providing just the code necessary (with significant savings). // if (pP->fxns->bufMemPrint) { pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2); pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2); } TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z); if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error { if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset { TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z); TRACE_TERSE2(" maxFrameLength: %d. aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize); SW_BREAKPOINT; return __LINE__; } } if (aLen_ext*aSize!=0) { if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset { TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z); TRACE_TERSE2(" maxFrameLength: %d. aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize); SW_BREAKPOINT; return __LINE__; } } TRACE_TERSE3(" maxFrameLength: %d. aLen_int*aSize: %d. aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int); TRACE_TERSE3(" maxFrameLength: %d. aLen_ext*aSize: %d. aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext); TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z); if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb))) { TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z); TRACE_TERSE1(" bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf); SW_BREAKPOINT; return __LINE__; } { Int i; #pragma UNROLL(1) for (i=0; i < PAF_MAXNUMCHAN_AF; i++) { pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL; } } // MID 314 if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1)) { TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z); return __LINE__; } else { Int j = 0; Int k = 0; TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]); for(i=0;ipAudioFrameBufStatus->space[i] == IALG_SARAM) { pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH; j++; } else { pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH; k++; } TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i); TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]); } } } for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) { if (pAstCfg->xStr[z].audioFrameChannelPointers[ch]) { pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch]; } } // // Initialize meta data elements // pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE; pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0; pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0; pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData; pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize; for(i=0;ipMetadataBufStatus->NumBuf;i++) { pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0; pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0; pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i; } // // Initialize decoder elements directly // for (zX = DECODE1; zX < DECODEN; zX++) { if (pP->streamsFromDecodes[zX] == z) { #ifdef NOAUDIOSHARE pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0; pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL; #else /* NOAUDIOSHARE */ pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int; pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int; #endif /* NOAUDIOSHARE */ } } return 0; } //PAF_ASOT_initFrame0 // ----------------------------------------------------------------------------- // ASOT Initialization Function Helper - Reinitialization of Audio Frame // AST Decoding Function - Reinitialization of Audio Frame // // Name: PAF_ASOT_initFrame1 // Purpose: Audio Stream Task Function for initialization or reinitiali- // zation of the Audio Frame(s) by loading of data values of a // time-varying nature. // From: audioStream1Task or equivalent // AST Parameter Function -> decodeInfo // AST Parameter Function -> decodeDecode // Uses: See code. // States: x // Return: 0. // Trace: None. // Int PAF_ASOT_initFrame1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int z, Int apply ) { PAF_AST_Config *pAstCfg; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration // // Reinitialize audio frame elements: // // Channel Configurations during sys init = Unknown // " " during info or decode = None // // Sample Rate / Count during sys init, info or decode = Unknown / 0 // if (apply < 0) { pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN; pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN; } else { pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE; pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE; } if (apply < 1) { pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN; pAstCfg->xStr[z].pAudioFrame->sampleCount = 0; } return 0; } //PAF_ASOT_initFrame1 // ----------------------------------------------------------------------------- // ASOT Selection Function - Output Device Selection // // Name: PAF_ASOT_selectDevices // Purpose: Audio Stream Output Task Function for selecting the devices used // for output. // From: audioStream1Task or equivalent // 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. // Int PAF_ASOT_selectDevices( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* input/output counter */ Int errno = 0; /* error number */ Int errme; /* error number, local */ Int device; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled // Select output devices for (z=OUTPUT1; z < OUTPUTN; z++) { if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0) { TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device); /* check for valid index into device array */ if (device >= pQ->devout->n) { device = 0; /* treat as device None */ } errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT, HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]); if (errme) { TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno); if (!errno) { errno = ASPERR_DEVOUT + errme; } pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80; } else { Int zE; pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80; // register outBufStatus and encodeStatus pointers with output devices // This enables proper IEC encapsulation. if (pAstCfg->xOut[z].hTxSio) { // set max # of output buffers (use override if necessary) if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0) { SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF, (Arg)pP->poutNumBufMap[z]->maxNumBuf); } else { SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF, (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride); } // register PAF_SIO_IALG object address SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR, (Arg)pAstCfg->xOut[z].outChainData.head->alg); SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR, (Arg)&pAstCfg->xOut[z].outBufStatus); for (zE=ENCODE1; zE < ENCODEN; zE++) { if (pP->outputsFromEncodes[zE] == z) { SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_ENCSTATUSADDR, (Arg)&pAstCfg->xEnc[zE].encodeStatus); break; } } } } } /* No need to start-clocks here, since only selecting the device. */ #if 0 // if device selected and valid then enable stat tracking if // required and start clocking if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) { TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks"); errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0); if (errme) { TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno); SIO_idle(pAstCfg->xOut[z].hTxSio); if (!errno) { errno = ASPERR_DEVOUT + errme; } } } #endif } return errno; } //PAF_ASOT_selectDevices // ----------------------------------------------------------------------------- // ASOT Processing Function - Decode Processing // // Name: PAF_ASOT_decodeProcessing // Purpose: Audio Stream Output Task Function for processing audio data. // Int PAF_ASOT_decodeProcessing( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int errno; /* error number */ Int getVal; enum { INIT, STREAM, ENCODE, FINAL, QUIT, OUT_SIO_UPDATE } state; state = INIT; errno = 0; /* error number */ Int frame; // (***) FL: formerly -- decoder input frame count Int block; // decoder output block count / input frame Int outSioUpdate; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration for (;;) { // // Check forward (ASIT) error here, TBD // // If writeDECCommandRestart issued, force exit the statemachine if (gCommandOutputTask_SYNC) { TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: writeDECCommandRestart issued in state=0x%x ... exiting core loop", state); errno = ASOP_DP_FORWARD_ERR; break; } // Check if any change in output SIO, e.g. from Output shortcut. // Changes will break FSM and allow Output reconfiguration. errno = checkOutSio(pP, pAsotCfg, &outSioUpdate); if (errno < 0) { TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno); break; } else if (outSioUpdate) { TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection"); state = OUT_SIO_UPDATE; } // Process commands (encode) getVal = pP->fxns->encodeCommand(pP, pQ, pAsotCfg); if (getVal) { /* ignore */; } // Process state (decode) switch (state) { case INIT: // initial state gAsopInitCnt++; Log_info0("TaskAsop: state=INIT"); frame = 0; block = 0; #if 0 // FL: moved to PAF_ASOT_initOutProc() // Reset audio frame pointers to original values // (may be needed if error occurred). resetAfPointers(pP, pAstCfg->xStr); // Reset audio frame meta data elements resetAfMetadata(pP, pAstCfg->xStr); #endif errno = pP->fxns->decodeInit(pP, pQ, pAsotCfg); if (errno) { TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInit", errno); errno = ASOP_DP_DECINIT_ERR; break; } // // Setup output: setCheckRateX, start output // // Establish secondary timing errno = pP->fxns->decodeInfo1(pP, pQ, pAsotCfg, frame, block); if (errno) { TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInfo1", errno); break; } TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM"); state = STREAM; continue; case STREAM: // stream state gAsopStreamCnt++; Log_info0("TaskAsop: state=STREAM"); errno = pP->fxns->decodeStream(pP, pQ, pAsotCfg, frame, block); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM. decodeStream err 0x%x", errno); errno = ASOP_DP_DECSTREAM_ERR; break; } TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE"); state = ENCODE; continue; case ENCODE: // encode state gAsopEncodeCnt++; Log_info0("TaskAsop: state=ENCODE"); errno = pP->fxns->decodeEncode(pP, pQ, pAsotCfg, frame, block); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE. decodeEncode err 0x%x", errno); errno = ASOP_DP_DECENC_ERR; break; } // Measure cycles in output processing loop. // Only measures cycles spent in loop. pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); gNumPfpAsot1--; pfpBegin(PFP_ID_ASOT_1, pAsotCfg->taskHandle); gNumPfpAsot1++; // (***) FL: do we need this? // AF pointers come from CB read, any resets occur in Decoder AF. // // Reset audio frame pointers to original values // (may have been adjusted by ARC or the like). resetAfPointers(pP, pAstCfg->xStr); // (***) FL: update output (setCheckRateX) // Contained in INFO2 in combined FSM. errno = pP->fxns->decodeInfo2(pP, pQ, pAsotCfg, frame, block); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno); errno = ASOP_DP_DECINFO2_ERR; break; } block++; TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL"); state = FINAL; continue; case FINAL: gAsopFinalCnt++; Log_info0("TaskAsop: state=FINAL"); // // (***) FL: this needs to be fixed. // (1) Only require selected Output to be in this FSM // => Dec Status checks aren't valid, // will probably always exit FSM if only Output running // (2) Checking Dec Status info asych to input events (maybe ok) // // Check for final frame, and if indicated: // - Update audio flag to cause output buffer flush rather than // the default truncate in "complete" processing. // - Exit state machine to "complete" processing. #if 0 if (pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block)) { for (z=OUTPUT1; z < OUTPUTN; z++) { if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) { TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET"); pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET } } break; } #endif errno = pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block); if (errno < 0) { TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL break. errno 0x%x", errno); errno = ASOP_DP_DECFINALTEST_ERR; break; } else if (errno == ASOP_DP_CB_DRAINED) { // EOS, exit normally TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL normal exit. errno 0x%x", errno); errno = ASOP_DP_SOK; break; } TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM"); state = STREAM; continue; case OUT_SIO_UPDATE: gAsopOutSioUpdateCnt++; Log_info0("TaskAsop: state=OUT_SIO_UPDATE"); TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: OUT_SIO_UPDATE"); errno = ASOP_DP_OUT_SIO_UPDATE; break; case QUIT: gAsopQuitCnt++; Log_info0("TaskAsop: state=QUIT"); TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT"); errno = ASPERR_QUIT; break; default: // unknown state // Unknown: // - Set error number registers. // - Exit state machine to "complete" processing. TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state); errno = ASPERR_UNKNOWNSTATE; break; } // End of switch (state). TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete"); if (pP->fxns->decodeComplete(pP, pQ, pAsotCfg, NULL, frame, block)) { /* ignored? */; } //pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change //gNumPfpAsot1--; //return errno; break; } // End of for (;;) pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change gNumPfpAsot1--; return errno; } // ----------------------------------------------------------------------------- // ASOT Decoding Function - Encode Command Processing // // Name: PAF_ASOT_encodeCommand // Purpose: Decoding Function for processing Encode Commands. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: 0. // Trace: Message Log "trace" in Debug Project Configuration reports: // * Command execution. // * SIO control errors. // * Error number macros. // Int PAF_ASOT_encodeCommand( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* encode counter */ Int errno = 0; /* error number */ Int zO, zS; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; for (z=ENCODE1; z < ENCODEN; z++) { zO = pP->outputsFromEncodes[z]; zS = pP->streamsFromEncodes[z]; if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) { switch (pAstCfg->xEnc[z].encodeStatus.command2) { case 0: // command none - process pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80; break; case 1: // mute command TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1); if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET && pAstCfg->xOut[zO].hTxSio && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) { errno = (errno & 0xff) | ASPERR_MUTE; /* convert to sensical errno */ TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS); TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x ", as+zS, errno); } else { pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED; } pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80; break; case 2: // unmute command TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2); if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET && pAstCfg->xOut[zO].hTxSio && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) { errno = (errno & 0xff) | ASPERR_MUTE; /* convert to sensical errno */ TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS); TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x ", as+zS, errno); } else { pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED; } pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80; break; default: // command unknown - ignore break; } } } ERRNO_RPRT (TaskAsop, errno); return 0; } //PAF_ASOT_encodeCommand //debug -- allow dynamic config //Int16 gStrFrameLen=DEF_STR_FRAME_LEN; // stream frame length (PCM samples) // Purpose: Decoding Function for reinitializing the decoding process. Int PAF_ASOT_decodeInit( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { //PAF_AST_Config *pAstCfg; PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */ //Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/encode counter */ Int errno; /* error number */ //Int zO, zS; //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration //as = pAstCfg->as; pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control for (z=DECODE1; z < DECODEN; z++) { // Initialize decoder output circular buffer for stream reads //errno = cbInitStreamRead(pCbCtl, z, gStrFrameLen); errno = cbInitStreamRead(pCbCtl, z); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeInit:cbInitStreamRead() error=%d", errno); SW_BREAKPOINT; // debug return errno; } // Start decoder output circular buffer reads errno = cbReadStart(pCbCtl, z); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno); SW_BREAKPOINT; // debug return errno; } gCbReadAfErr=0; // reset read circular buffer error count gDecOpCbRdAfUnd=0; // reset decoder output circular buffer underflow count gMaxDecOpCbRdAfUnd=0; // reset max decoder output circular buffer underflow count gMasterCbResetCnt=0; // reset master circular buffer reset count // FL: debug, log circular buffer control variables cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart"); } #if 0 // moved to PAF_ASOT_outputReset() // TODO: move this to start of this function so that it doesn't affect IO timing for (z=ENCODE1; z < ENCODEN; z++) { zO = pP->outputsFromEncodes[z]; zS = pP->streamsFromEncodes[z]; if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; ENC_Handle enc = (ENC_Handle )encAlg; TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS); if (encAlg->fxns->algActivate) { encAlg->fxns->algActivate (encAlg); } if (enc->fxns->reset) { errno = enc->fxns->reset(enc, NULL, &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus); if (errno) { return errno; } } } } #endif return 0; } // ----------------------------------------------------------------------------- // ASOT Decoding Function - Info Processing, Initial // // Name: PAF_ASOT_decodeInfo1 // Purpose: Decoding Function for processing information in a manner that // is unique to initial frames of input data. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: Error number in standard or SIO form (0 on success). // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // Int PAF_ASOT_decodeInfo1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int frame, Int block ) { //PAF_AST_Config *pAstCfg; //Int z; /* decode/encode counter */ Int errno; /* error number */ #if 0 // moved to PAF_ASOT_outputInfo1() pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration // run the chain of ASP's on the stream. TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction."); errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno); return errno; } TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info."); for (z=ENCODE1; z < ENCODEN; z++) { Int zO = pP->outputsFromEncodes[z]; if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; ENC_Handle enc = (ENC_Handle )encAlg; if (enc->fxns->info) { errno = enc->fxns->info(enc, NULL, &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno); return errno; } } } } #endif errno = pP->fxns->setCheckRateX(pP, pQ, pAsotCfg, 0); if (errno) { // ignore if rateX has changed since we haven't, but are about to, // start the output. If we didn't ignore this case then the state machine // would restart unnecessarily, e.g. in the case of SRC, resulting in // added latency. if (errno != ASPERR_INFO_RATECHANGE) { TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno); return errno; } else { TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring"); } } errno = pP->fxns->startOutput(pP, pQ, pAsotCfg); if (errno) { if (errno == 0x105) { TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno); } else { TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno); } return errno; } return 0; } // ----------------------------------------------------------------------------- // ASOT Decoding Function - Info Processing, Subsequent // // Name: PAF_ASOT_decodeInfo2 // Purpose: Decoding Function for processing information in a manner that // is unique to frames of input data other than the initial one. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: Error number in standard form (0 on success). // Trace: None. // Int PAF_ASOT_decodeInfo2( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int frame, Int block ) { //PAF_AST_Config *pAstCfg; Int errno; //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration errno = pP->fxns->setCheckRateX (pP, pQ, pAsotCfg, 1); TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno); return errno; } //PAF_ASOT_decodeInfo2 PAF_AST_DecOpCircBufStats gCbStats; // FL: debug // ----------------------------------------------------------------------------- // ASOT Decoding Function - Stream Processing // // Name: PAF_ASOT_decodeStream // Purpose: Decoding Function for processing of audio frame data by the // ASP Algorithms. // 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/child. // Int PAF_ASOT_decodeStream( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int frame, Int block ) { PAF_AST_Config *pAstCfg; PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */ Int z; /* decode/stream counter */ PAF_AudioFrame *pAfRd; Int cbErrno; //PAF_AST_DecOpCircBufStats cbStats; /* circular buffer statistics */ Int errno; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control for (z=DECODE1; z < DECODEN; z++) { Int zS = pP->streamsFromDecodes[z]; // // Read decoder output circular buffer // pAfRd = pAstCfg->xStr[zS].pAudioFrame; //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug cbErrno = cbReadAf(pCbCtl, z, pAfRd); //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug if ((cbErrno < 0) && (cbErrno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && (cbErrno != ASP_DECOP_CB_PCM_READ_UNDERFLOW)) { gCbReadAfErr++; TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno); //SW_BREAKPOINT; // debug return cbErrno; } // Handle underflows if ((cbErrno == ASP_DECOP_CB_AF_READ_UNDERFLOW) || (cbErrno == ASP_DECOP_CB_PCM_READ_UNDERFLOW)) { // (***) FL: Need to check behavior of cbReset(). // Need to check behavior on exit/re-entry into Output processing. gDecOpCbRdAfUnd++; // increment circular buffer underflow count if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) { // Underflow count above threshold. // (1) set max underflow count to threshold // (2) reset underflow count // (3) reset circular buffer gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count gDecOpCbRdAfUnd = 0; // reset underflow count // Reset circular buffer cbReset(pCbCtl, z); gMasterCbResetCnt++; // increment master circular buffer reset count Log_info0("ASOT:cbReset"); return cbErrno; } } else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0)) { // No underflow detected. // update max underflow count, // reset underflow count // update max underflow count if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd) { gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd; } gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count } //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete."); //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete."); #if 0 // (***) FL: shows timing of CB read // (***) debug // B8 { static Uint8 toggleState = 0; if (toggleState == 0) GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); else GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); toggleState = ~(toggleState); } #endif // debug, get circular buffer statistics //cbGetStats(pCbCtl, z, &cbStats); cbGetStats(pCbCtl, z, &gCbStats); // debug cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf"); #if 0 // debug, capture audio frame if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK) { Log_info0("capAfWrite() error"); } #endif } TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction."); errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block); if (errno) { TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno); return errno; } return 0; } //PAF_ASOT_decodeStream // ----------------------------------------------------------------------------- // ASOT Decoding Function - Encode Processing // // Name: PAF_ASOT_decodeEncode // Purpose: Decoding Function for processing of audio frame data by the // Encode Algorithm. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: Error number in standard or SIO form (0 on success). // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // Int PAF_ASOT_decodeEncode( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int frame, Int block ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* encode/output counter */ Int errno; /* error number */ Int zX, zE, zS; // debug //UInt32 curTime; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; // Await output buffers (but not first time) for (z=OUTPUT1; z < OUTPUTN; z++) { // determine encoder associated with this output zE = z; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zE = zX; break; } } zS = pP->streamsFromEncodes[zE]; if (pAstCfg->xOut[z].hTxSio) { // update length (e.g. ARC may have changed) pAstCfg->xOut[z].outBufConfig.lengthofFrame = pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount; TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block); //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL); //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug if (errno < 0) { SIO_idle(pAstCfg->xOut[z].hTxSio); TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno); return -errno; // SIO negates error codes } // TODO: use pC->xOut[z].pOutBuf in following ->encode call #if 0 // (***) FL: shows timing of Output Tx SIO reclaim // (***) debug // B8 { static Uint8 toggleState = 0; if (toggleState == 0) GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); else GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); toggleState = ~(toggleState); } #endif // // Simulate Tx SIO_reclaim() pend // //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER); //curTime = Clock_getTicks(); //System_printf("System time in TaskAsopFxn Tx audio = %lu\n", (ULong)curTime); //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime); gAsopTxSioReclaimCnt++; } else { TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle ", as+zS, block); } } // Encode data for (z=ENCODE1; z < ENCODEN; z++) { Int zO = pP->outputsFromEncodes[z]; Int zS = pP->streamsFromEncodes[z]; (void)zS; // clear compiler warning in case not used with tracing disabled if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; ENC_Handle enc = (ENC_Handle )encAlg; if (select != pAstCfg->xEnc[z].encodeControl.encActive) { pAstCfg->xEnc[z].encodeControl.encActive = select; TRACE_TERSE0("PAF_ASOT_decodeEncode: return error"); return (-1); } TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block); // (MID 1933) temp. workaround for PCE2 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; /* #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA) { PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame; int *wp; wp = (int*)pAudioFrame->data.sample[0]; TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__)); TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99])); wp = (int*)pAudioFrame->data.sample[1]; TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__)); TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99])); wp = (int*)pAudioFrame->data.sample[2]; TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__)); TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99])); } #endif */ if (enc->fxns->encode) { pAstCfg->xEnc[z].encodeOutStruct.bypassFlag = pP->z_pEncodeStatus[z]->encBypass; errno = enc->fxns->encode(enc, NULL, &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct); if (errno) { if (errno != PCEERR_OUTPUT_POINTERNULL) { TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno); return errno; } } /* #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA) else { int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid; TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__)); TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99])); } #endif */ } } else { TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode ", as+pP->streamsFromEncodes[z], block); } } // Transmit data for (z=OUTPUT1; z < OUTPUTN; z++) { // determine encoder associated with this output zE = z; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zE = zX; break; } } zS = pP->streamsFromEncodes[zE]; if (pAstCfg->xOut[z].hTxSio) { TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block); //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug errno = SIO_issue(pAstCfg->xOut[z].hTxSio, &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0); //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug if (errno) { SIO_idle(pAstCfg->xOut[z].hTxSio); if (errno == 0x105) // 0x105 == RINGIO_EBUFFULL { // statStruct_LogFullRing(STATSTRUCT_AS1_F2); TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno); } if (errno > 0) { TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno); return (ASPERR_ISSUE + (z << 4)); } else if (errno < 0) { TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno); return -errno; // SIO negates error codes } } if (errno > 0) { return (ASPERR_ISSUE + (z << 4)); } else if (errno < 0) { return -errno; // SIO negates error codes } } else { TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output ", as+zS, block); } } return 0; } //PAF_ASOT_decodeEncode // ----------------------------------------------------------------------------- // ASOT Decoding Function - Stream-Final Processing // // Name: PAF_ASOT_decodeComplete // Purpose: Decoding Function for terminating the decoding process. // From: AST Parameter Function -> decodeProcessing // Uses: See code. // States: x // Return: 0. // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // Int PAF_ASOT_decodeComplete( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, ALG_Handle decAlg[], Int frame, Int block ) { PAF_AST_Config *pAstCfg; PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */ Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* decode/encode counter */ Int errno; /* error number */ pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control for (z=DECODE1; z < DECODEN; z++) { // Stop decoder output circular buffer reads errno = cbReadStop(pCbCtl, z); if (errno) { TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno); SW_BREAKPOINT; // FL: debug return errno; } // FL: debug cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop"); } pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame); for (z=ENCODE1; z < ENCODEN; z++) { Int zO = pP->outputsFromEncodes[z]; if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; #ifdef PAF_ASP_FINAL ENC_Handle enc = (ENC_Handle)encAlg; #endif /* PAF_ASP_FINAL */ TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z); #ifdef PAF_ASP_FINAL if (enc->fxns->final) enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus); #endif /* PAF_ASP_FINAL */ if (encAlg->fxns->algDeactivate) { encAlg->fxns->algDeactivate(encAlg); } } else { TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode ", as+z); } } // wait for remaining data to be output pP->fxns->stopOutput(pP, pQ, pAsotCfg); return 0; } //PAF_ASOT_decodeComplete // ----------------------------------------------------------------------------- // ASOT Decoding Function Helper - SIO Driver Start // // Name: PAF_ASOT_startOutput // Purpose: Decoding Function for initiating output. // From: AST Parameter Function -> decodeInfo1 // Uses: See code. // States: x // Return: Error number in standard or SIO form (0 on success). // Trace: Message Log "trace" in Debug Project Configuration reports: // * State information as per parent. // * SIO control errors. // #define DEC_OUTNUMBUF_MAP(X) \ pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)] Int PAF_ASOT_startOutput( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* output counter */ Int errno,nbufs, errme; /* error number */ Int zE, zS, zX; Int zMD; PAF_SIO_IALG_Obj *pObj; PAF_SIO_IALG_Config *pAlgConfig; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; zMD = pAstCfg->masterDec; for (z=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].hTxSio) { // determine associated encoder and stream zE = z; zS = z; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zE = zX; zS = pP->streamsFromEncodes[zE]; break; } } // Need to Revisit: Starting Clocks here seems logical & also manages the McASP without spurious underruns . #if 1 // if device selected and valid then enable stat tracking if // required and start clocking if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) { TRACE_VERBOSE0("PAF_ASOT_startOutput: start SIO clocks"); errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0); if (errno) { TRACE_VERBOSE2("PAF_ASOT_startOutput: errme 0x%x, errno 0x%x", errme, errno); SIO_idle(pAstCfg->xOut[z].hTxSio); if (!errno) { errno = ASPERR_DEVOUT + errme; } } } #endif // Set sample count so that DOB knows how much data to send pAstCfg->xOut[z].outBufConfig.lengthofFrame = pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount; if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED) { pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg; pAlgConfig = &pObj->config; memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA, pAlgConfig->pMemRec[0].size); } // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master // decoder. How should we handle the sourceProgram for multiple decoders? // Override as needed nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram); if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0) { nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram]; } SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs); if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio, &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0)) { SIO_idle(pAstCfg->xOut[z].hTxSio); TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno); return errno; } if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && (errno = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) { errno = (errno & 0xff) | ASPERR_MUTE; /* convert to sensical errno */ TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno); return (errno); } else { pAstCfg->xOut[z].outBufStatus.audio = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND; } TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS); } } return 0; } //PAF_ASOT_startOutput // ----------------------------------------------------------------------------- // ASOT Decoding Function Helper - SIO Driver Stop // // Name: PAF_ASOT_stopOutput // Purpose: Decoding Function for terminating output. // From: AST Parameter Function -> decodeProcessing // AST Parameter Function -> decodeComplete // Uses: See code. // States: x // Return: Error number in standard or SIO form (0 on success). // Trace: Message Log "trace" in Debug Project Configuration reports: // * SIO control errors. // Int PAF_ASOT_stopOutput( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* output counter */ Int errno = 0, getVal; Int zS, zX; PAF_SIO_IALG_Obj *pObj; PAF_SIO_IALG_Config *pAlgConfig; pAstCfg = pAsotCfg->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=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].hTxSio) { // determine associated encoder and stream zS = z; (void)zS; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zS = pP->streamsFromEncodes[zX]; break; } } // Mute output before audio data termination in the usual case, // where such termination is due to decode error or user command. // Identification of this as the usual case is provided by the // "decode processing" state machine. if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) && (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) { if (!errno) { errno = (getVal & 0xff) | ASPERR_MUTE; /* convert to sensical errno */ } TRACE_VERBOSE1("PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS); } TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time())); // Terminate audio data output, truncating (ignore) or flushing // (play out) final samples as per (1) control register set by // the user and (2) the type of audio data termination: #if 0 // This form is not used because driver support for truncating // data is not supported for internal clocks, although it is // for external clocks. getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE, pC->xOut[z].outBufStatus.flush & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH ? 1 : 0); /* UNTESTED */ #else // This form should be used when driver support for truncating // data is supported for both internal and external clocks. getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE, pAstCfg->xOut[z].outBufStatus.flush ? 1 : (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH ? 1 : 0); /* TESTED */ #endif TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time())); if (!errno) { errno = getVal; } // Mute output after audio data termination in a special case, // where such termination is due to processing of a final frame // or user command. Identification of this as a special case is // provided by the "decode processing" state machine. if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) && (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) { if (!errno) { errno = (getVal & 0xff) | ASPERR_MUTE; /* convert to sensical errno */ } TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS); } pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f; // zero output buffers pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg; pAlgConfig = &pObj->config; memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size); } //pAstCfg->xOut[z].hTxSio }//OUTPUT return errno; } //PAF_ASOT_stopOutput // ----------------------------------------------------------------------------- // ASOT Decoding Function Helper - SIO Driver Change // // Name: PAF_ASOT_setCheckRateX // Purpose: Decoding Function for reinitiating output. // From: AST Parameter Function -> decodeInfo1 // AST Parameter Function -> decodeInfo2 // Uses: See code. // States: x // Return: Error number in standard form (0 on success). // Trace: None. // /* 0: set, 1: check, unused for now. --Kurt */ Int PAF_ASOT_setCheckRateX( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int check ) { PAF_AST_Config *pAstCfg; float rateX; PAF_SampleRateHz rateO /* std */, rateI /* inv */; Int z; /* output counter */ Int zx; /* output re-counter */ Int getVal; int inputRate, inputCount, outputRate, outputCount; Int zMD; Int zMI; Int zMS; Int zE, zX; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration zMD = pAstCfg->masterDec; zMS = pAstCfg->masterStr; zMI = pP->zone.master; inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus; inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength; rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV); for (z=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) { // determine associated encoder zE = z; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->outputsFromEncodes[zX] == z) { zE = zX; break; } } outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate; outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength; rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD); if ((rateI > 0) && (rateO > 0)) { rateX = rateO /* std */ * rateI /* inv */; } else if (inputCount != 0) { rateX = (float )outputCount / inputCount; } else { return ASPERR_INFO_RATERATIO; } getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg)&rateX); if (getVal == DOBERR_RATECHANGE) { for (zx=OUTPUT1; zx < OUTPUTN; zx++) { if (pAstCfg->xOut[zx].hTxSio) { SIO_idle (pAstCfg->xOut[zx].hTxSio); } } // this forces an exit from the calling state machine which will // eventually call startOutput which calls setCheckRateX for all outputs // and so it is ok, in the presence of a rate change on any output, to // exit this loop /function early. return ASPERR_INFO_RATECHANGE; } else if (getVal != SYS_OK) { return ((getVal & 0xff) | ASPERR_RATE_CHECK); } } } return 0; } //PAF_ASOT_setCheckRateX // ----------------------------------------------------------------------------- // ASOT Decoding Function Helper - Chain Processing // // Name: PAF_ASOT_streamChainFunction // Purpose: Common Function for processing algorithm chains. // From: AST Parameter Function -> decodeInfo1 // AST Parameter Function -> decodeStream // AST Parameter Function -> decodeComplete // 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. // Int PAF_ASOT_streamChainFunction( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, Int iChainFrameFxns, Int abortOnError, Int logArg ) { PAF_AST_Config *pAstCfg; Int as; /* Audio Stream Number (1, 2, etc.) */ Int z; /* stream counter */ Int errno; /* error number */ Int dFlag, eFlag, gear; Int zX; Int zS; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; (void)as; // clear compiler warning in case not used with tracing disabled for (zS = STREAM1; zS < STREAMN; zS++) { z = pP->streamOrder[zS]; // Select stream order from streamOrder parameter - MID 788 // apply stream // unless the stream is associated with a decoder and it is not running // or // unless the stream is associated with an encoder and it is not running // Also gear control only works for streams with an associated decoder // if no such association exists then gear 0 (All) is used dFlag = 1; gear = 0; for (zX = DECODE1; zX < DECODEN; zX++) { if (pP->streamsFromDecodes[zX] == z) { dFlag = pAstCfg->xDec[zX].decodeStatus.mode; gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus; break; } } eFlag = 1; for (zX = ENCODE1; zX < ENCODEN; zX++) { if (pP->streamsFromEncodes[zX] == z) { eFlag = pAstCfg->xEnc[zX].encodeStatus.mode; break; } } if (dFlag && eFlag) { PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear]; PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame; Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) = chain->fxns->chainFrameFunction[iChainFrameFxns]; TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)" : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)" : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)" : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)", as+z, logArg); errno = (*func) (chain, frame); TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.", as+z, errno); if (errno && abortOnError) return errno; } else { TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) " : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) " : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) " : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) ", as+z, logArg); } /* { void dp_tracePAF_Data(float *lBuf, float *rBuf, int count); PAF_AudioFrameData *afd; float ** afPtr; afd = &(pC->xStr->pAudioFrame->data); afPtr = (float**)afd->sample; dp_tracePAF_Data(afPtr[4], afPtr[5], 256); } */ } return 0; } //PAF_ASOT_streamChainFunction /* Check if at least one output selected */ static Int checkOutSel( const PAF_ASOT_Params *pP, PAF_ASOT_Config *pAsotCfg, Int *pOutSel ) { PAF_AST_Config *pAstCfg; Int outSel; Int z; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration outSel = 0; for (z=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].hTxSio) { outSel = 1; break; } } *pOutSel = outSel; return ASOP_SOK; } /* Check if at least one output sio changed */ static Int checkOutSio( const PAF_ASOT_Params *pP, PAF_ASOT_Config *pAsotCfg, Int *pOutSioUpdate ) { PAF_AST_Config *pAstCfg; Int outSioUpdate; Int z; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration outSioUpdate = 0; for (z=OUTPUT1; z < OUTPUTN; z++) { if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0) { outSioUpdate = 1; break; } } *pOutSioUpdate = outSioUpdate; return ASOP_SOK; } // Reset audio frames static Void resetAfs( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ) { // Reset audio frame pointers to original values // (may be needed if error occurred). resetAfPointers(pP, xStr); // Reset audio frame meta data elements resetAfMetadata(pP, xStr); } // Reset audio frame pointers to original values static Void resetAfPointers( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ) { Int z; Int ch; // Reset audio frame pointers to original values for (z = STREAM1; z < STREAMN; z++) { for (ch = PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) { if (xStr[z].audioFrameChannelPointers[ch]) { xStr[z].audioFrameChannelPointers[ch] = xStr[z].origAudioFrameChannelPointers[ch]; } } } } // Reset audio frame meta data elements static Void resetAfMetadata( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ) { Int z; Int i; for (z = STREAM1; z < STREAMN; z++) { xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE; xStr[z].pAudioFrame->numPrivateMetadata = 0; xStr[z].pAudioFrame->bsMetadata_offset = 0; xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData; for (i = 0; i < pP->pMetadataBufStatus->NumBuf; i++) { xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0; xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0; } } } // Initialize Output Processing state function //static Int PAF_ASOT_initOutProc( Int PAF_ASOT_initOutProc( const PAF_ASOT_Params *pP, PAF_AST_Stream *xStr ) { // Reset audio frames resetAfs(pP, xStr); return ASOP_SOK; } #if 0 // Init-Sync update audio frame static Int initSyncUpdateAf( PAF_AudioFrame *dstAf, PAF_AudioFrame *srcAf ) { memcpy(dstAf, srcAf, sizeof(PAF_AudioFrame)); return ASOP_SOK; } #endif // Purpose: Init-Sync Dec Reset state function. // Performes Dec Reset Init-Sync. //static Int PAF_ASOT_initSyncDecReset( // used by new OutProc.c, will be changed back to static once refactoring is done Int PAF_ASOT_initSyncDecReset( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecResetAf ) { PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration Int zMD, zMS; // Dec and Stream Master indices PAF_AudioFrame *pStrAf; // stream audio frame PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control Int8 decFlag; // dec stage flag Int errno; // error number pAstCfg = pAsotCfg->pAstCfg; zMD = pAstCfg->masterDec; pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl; // check for Dec Reset // store dec reset AF errno = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD, ASP_OUTIS_DEC_STAGE_RESET_IDX, &decFlag, pDecResetAf); if (errno < 0) { return errno; } if (decFlag == 0) { return ASOP_INITSYNC_NOTREADY; } else { zMS = pAstCfg->masterStr; pStrAf = pAstCfg->xStr[zMS].pAudioFrame; // Update Stream Audio Frame. // Copy Dec Reset AF to Stream AF. //errno = initSyncUpdateAf(pStrAf, pDecResetAf); //if (errno < 0) //{ // return errno; //} outIsCpyAf(pDecResetAf, pStrAf); // Enc activate // Enc reset errno = PAF_ASOT_outputReset(pP, pQ, pAsotCfg); if (errno < 0) { return errno; } return ASOP_SOK; } } // Purpose: ASOT Function for Output reset static Int PAF_ASOT_outputReset( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration Int as; // Audio Stream Number (1, 2, etc.) */ Int z; // encode counter Int errno; // error number Int zO, zS; pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration as = pAstCfg->as; for (z=ENCODE1; z < ENCODEN; z++) { zO = pP->outputsFromEncodes[z]; zS = pP->streamsFromEncodes[z]; if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; ENC_Handle enc = (ENC_Handle )encAlg; TRACE_VERBOSE1("AS%d: PAF_ASOT_outputReset: initializing encode", as+zS); if (encAlg->fxns->algActivate) { encAlg->fxns->algActivate(encAlg); } if (enc->fxns->reset) { errno = enc->fxns->reset(enc, NULL, &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus); if (errno) { return ASOP_ENCRESET_ERR; } } } } return ASOP_SOK; } // FL: debug, allow modification of output frame length via JTAG Int16 gOutFrameLen=PAF_ASOT_FRAMELENGTH; // output frame length (PCM samples) // Purpose: Init-Sync Dec Info1 state function. // Performes Dec Info1 Init-Sync. Int PAF_ASOT_initSyncDecInfo1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecInfo1Af ) { PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration Int zMD, zMS; // Dec and Stream Master indices PAF_AudioFrame *pStrAf; // stream audio frame PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control Int8 decFlag; // dec stage flag Int errno; // error number pAstCfg = pAsotCfg->pAstCfg; zMD = pAstCfg->masterDec; pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl; // Check for Dec Reset, // Store dec reset AF errno = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD, ASP_OUTIS_DEC_STAGE_INFO1_IDX, &decFlag, pDecInfo1Af); if (errno < 0) { return errno; } if (decFlag == 0) { return ASOP_INITSYNC_NOTREADY; } else { zMS = pAstCfg->masterStr; pStrAf = pAstCfg->xStr[zMS].pAudioFrame; // Update Stream Audio Frame. // Copy Dec Reset AF to Stream AF. //errno = initSyncUpdateAf(pStrAf, pDecInfo1Af); //if (errno < 0) //{ // return errno; //} // Hack to set ASOT output frame length. // THD sets this to 256 (hard-coded in Dec Info) // DDP sets this to 0 (audio frame passthrough, 0 from ASDT AF frame length) // PCM sets this to 256 (decodeControl.frameLength) //pDecInfo1Af->sampleCount = 256; // !!!! GJ: Revisit !!!! pDecInfo1Af->sampleCount = gOutFrameLen; outIsCpyAf(pDecInfo1Af, pStrAf); // Hack to set ASOT output frame length // THD sets this to 256 (hard-coded in Dec Info) // DDP sets this to 0 (audio frame passthrough, 0 from ASDT AF frame length) // PCM sets this to 256 (decodeControl.frameLength) //pStrAf->sampleCount = 256; // !!!! GJ: Revisit !!!! // outputInfo1(): // - ASP chain reset, // - Enc Info PAF_ASOT_outputInfo1(pP, pQ, pAsotCfg); if (errno) { return ASOP_DECINFO1_ERR; } return ASOP_SOK; } } // Purpose: ASOT function for ASP chain reset and ENC info static Int PAF_ASOT_outputInfo1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; Int z; /* decode/encode counter */ Int errno; /* error number */ pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration // FL: frame parameter hard-coded to 0 // run the chain of ASP's on the stream. TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction."); errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, 0); if (errno) { TRACE_TERSE1("PAF_ASOT_outputInfo1: streamChainFunction returns errno 0x%x ", errno); return errno; } TRACE_VERBOSE0("PAF_ASOT_outputInfo1: calling enc->info."); for (z=ENCODE1; z < ENCODEN; z++) { Int zO = pP->outputsFromEncodes[z]; if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) { Int select = pAstCfg->xEnc[z].encodeStatus.select; ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select]; ENC_Handle enc = (ENC_Handle )encAlg; if (enc->fxns->info) { errno = enc->fxns->info(enc, NULL, &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus); if (errno) { TRACE_TERSE1("PAF_ASOT_outputInfo1: info returns errno 0x%x ", errno); return errno; } } } } return 0; } // Purpose: Init-Sync Dec Decode1 state function. // Performes Dec Decode1 Init-Sync. //static Int PAF_ASOT_initSyncDecDecode1( Int PAF_ASOT_initSyncDecDecode1( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg ) { PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration Int zMD; // Dec Master index PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control Int8 decFlag; // dec stage flag Int errno; // error number pAstCfg = pAsotCfg->pAstCfg; zMD = pAstCfg->masterDec; pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl; // Check for Dec Reset, // Store dec reset AF errno = outIsReadDecStageFlag(pOutIsCtl, zMD, ASP_OUTIS_DEC_STAGE_DECODE1_IDX, &decFlag); if (errno < 0) { return errno; } if (decFlag == 0) { return ASOP_INITSYNC_NOTREADY; } else { return ASOP_SOK; } } // Purpose: Init-Sync Re-Sync state function. // Peformed Init-Sync using stored Dec Reset/Info1 AFs. Int PAF_ASOT_initSyncResync( const PAF_ASOT_Params *pP, const PAF_ASOT_Patchs *pQ, PAF_ASOT_Config *pAsotCfg, PAF_AudioFrame *pDecResetAf, PAF_AudioFrame *pDecInfo1Af ) { PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration Int zMS; // Stream Master index PAF_AudioFrame *pStrAf; // stream audio frame Int errno; // error number pAstCfg = pAsotCfg->pAstCfg; zMS = pAstCfg->masterStr; pStrAf = pAstCfg->xStr[zMS].pAudioFrame; // Reset audio frames resetAfs(pP, pAstCfg->xStr); // // Dec Reset re-sync using stored Dec Reset AF // // Update Stream Audio Frame. // Copy Dec Reset AF to Stream AF. //errno = initSyncUpdateAf(pStrAf, pDecResetAf); //if (errno < 0) //{ // return errno; //} outIsCpyAf(pDecResetAf, pStrAf); // Enc activate, // Enc reset errno = PAF_ASOT_outputReset(pP, pQ, pAsotCfg); if (errno) { return errno; } // // Dec Info1 re-sync using stored Dec Info1 AF // // Update Stream Audio Frame. // Copy Dec Info1 AF to Stream AF. //errno = initSyncUpdateAf(pStrAf, pDecInfo1Af); //if (errno < 0) //{ // return errno; //} outIsCpyAf(pDecInfo1Af, pStrAf); // decodeInfo1(): // - ASP chain reset, // - Enc Info errno = PAF_ASOT_outputInfo1(pP, pQ, pAsotCfg); if (errno) { return errno; } return ASOP_SOK; } // Purpose: Decoding Function for determining whether processing of the // current stream is complete. Int PAF_ASOT_decodeFinalTest( const struct PAF_ASOT_Params *pP, const struct PAF_ASOT_Patchs *pQ, struct PAF_ASOT_Config *pAsotCfg, Int frame, Int block ) { PAF_AST_DecOpCircBufCtl *pCbCtl; // decoder output circular buffer control Int8 drainedFlag; // CB drained indicator flag Int zMD; // master Dec index Int errno; // error number pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control zMD = pAsotCfg->pAstCfg->masterDec; // get master Dec index // Check circular buffer drain state //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107); // debug errno = cbCheckDrainState(pCbCtl, zMD, &drainedFlag); //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107); // debug if (errno < 0) { return errno; } if (drainedFlag == 1) { return ASOP_DP_CB_DRAINED; } return ASOP_DP_SOK; }