PASDK-402:Add writeDECCommandRestart updates
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutProc.c
2 /*
3 Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 /*
37  *  ======== audioStreamOutProc.c ========
38  */
40 #include <string.h> // for memset
41 #include <xdc/runtime/Log.h>
42 #include <xdc/runtime/Error.h>
43 #include <xdc/runtime/Memory.h>
44 #include <ti/sysbios/knl/Clock.h>
45 #include <ti/sysbios/knl/Task.h>
47 #include "paferr.h"
48 #include <acp_mds.h>
49 #include <pcm.h>
50 #include <pce.h>
51 #include <pafsio_ialg.h>
52 #include <stdasp.h>
53 #include <doberr.h>
54 #include "asperr.h"
56 #include "common.h"
57 #include "aspMsg_common.h"
58 #include "aspMsg_master.h"
59 #include "aspDecOpCircBuf_master.h"
60 #include "aspOutInitSync_master.h"
61 #include "audioStreamProc_common.h"
62 #include "audioStreamOutProc.h"
64 #include "pfp/pfp.h"
65 #include "pfp_app.h"        /* contains all PFP ID's */
66 Int32 gNumPfpAsot1=0; // debug
68 // FL: debug
69 #include "evmc66x_gpio_dbg.h"
70 #include "dbgCapAf.h"
73 // -----------------------------------------------------------------------------
74 // Debugging Trace Control, local to this file.
75 // 
76 #include "logp.h"
78 #define TRACE_TIME(a)
80 // Allow a developer to selectively enable tracing.
81 #define CURRENT_TRACE_MASK      0x07
83 #define TRACE_MASK_TERSE        0x01   // only flag errors and show init
84 #define TRACE_MASK_GENERAL      0x02   // half dozen lines per frame
85 #define TRACE_MASK_VERBOSE      0x04   // trace full operation
87 #if !(CURRENT_TRACE_MASK & TRACE_MASK_TERSE)
88     #undef  TRACE_TERSE0
89     #undef  TRACE_TERSE1
90     #undef  TRACE_TERSE2
91     #undef  TRACE_TERSE3
92     #undef  TRACE_TERSE4
93     #define TRACE_TERSE0(a)
94     #define TRACE_TERSE1(a,b)
95     #define TRACE_TERSE2(a,b,c)
96     #define TRACE_TERSE3(a,b,c,d)
97     #define TRACE_TERSE4(a,b,c,d,e)
98 #endif
99     
100 #if !(CURRENT_TRACE_MASK & TRACE_MASK_GENERAL)
101     #undef  TRACE_GEN0
102     #undef  TRACE_GEN1
103     #undef  TRACE_GEN2
104     #undef  TRACE_GEN3
105     #undef  TRACE_GEN4
106     #define TRACE_GEN0(a)
107     #define TRACE_GEN1(a,b)
108     #define TRACE_GEN2(a,b,c)
109     #define TRACE_GEN3(a,b,c,d)
110     #define TRACE_GEN4(a,b,c,d,e)
111 #endif
113 #if !(CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE)
114     #undef  TRACE_VERBOSE0
115     #undef  TRACE_VERBOSE1
116     #undef  TRACE_VERBOSE2
117     #undef  TRACE_VERBOSE3
118     #undef  TRACE_VERBOSE4
119     #define TRACE_VERBOSE0(a)
120     #define TRACE_VERBOSE1(a,b)
121     #define TRACE_VERBOSE2(a,b,c)
122     #define TRACE_VERBOSE3(a,b,c,d)
123     #define TRACE_VERBOSE4(a,b,c,d,e)
124 #endif
126 // .............................................................................
128 //
129 // Audio Stream Definitions
130 //
132 //
133 // Audio Stream Processing Definitions
134 //
135 #define aspLinkInit pQ->i_aspLinkInit
137 //
138 // Encoder Definitions
139 //
140 #define encLinkInit pQ->i_encLinkInit
142 //
143 // Output Definitions
144 //
145 #define outLinkInit pP->i_outLinkInit
147 /* ---------------------------------------------------------------- */
148 /*              Parameter macro definitions end here.               */
149 /* ---------------------------------------------------------------- */
151 //
152 // Standardized Definitions
153 //
155 #define ENC_Handle PCE_Handle /* works for all: PCE */
157 #define __TASK_NAME__  "TaskAsop"
160 //
161 // Audio Stream Output Task definitions
162 //
164 // status codes
165 // Output FSM
166 #define ASOP_INITSYNC_NOTREADY      (  1 )  // ok, init-sync not ready
167 #define ASOP_SOK                    (  0 )  // ok
168 #define ASOP_FORWARD_ERR            ( -1 )  // forward (ASIT) error
169 #define ASOP_ENCRESET_ERR           ( -2 )  // enc reset error
170 #define ASOP_DECINFO1_ERR           ( -3 )  // dec info1 error
171 // Decode Processing
172 #define ASOP_DP_OUT_SIO_UPDATE      (  3 )  // new output selected
173 #define ASOP_DP_CB_DRAINED          (  2 )  // circular buffer drained
174 #define ASOP_DP_SOK                 (  0 )  // ok
175 #define ASOP_DP_FORWARD_ERR         ( -1 )  // forward (ASIT) error
176 #define ASOP_DP_DECINIT_ERR         ( -2 )  // decode init error
177 #define ASOP_DP_DECSTREAM_ERR       ( -3 )  // decode stream error
178 #define ASOP_DP_DECENC_ERR          ( -4 )  // decode encode error
179 #define ASOP_DP_DECINFO2_ERR        ( -5 )  // decode encode error
180 #define ASOP_DP_DECFINALTEST_ERR    ( -6 )  // decode final error
184 /* Check if at least one output selected */
185 static Int checkOutSel(
186     const PAF_ASOT_Params *pP, 
187     PAF_ASOT_Config *pAsotCfg,
188     Int *pOutSel
189 );
191 /* Check if at least one output sio changed */
192 static Int checkOutSio(
193     const PAF_ASOT_Params *pP, 
194     PAF_ASOT_Config *pAsotCfg,
195     Int *pOutSioUpdate
196 );
198 // Initialize Output Processing state function
199 static Int PAF_ASOT_initOutProc(
200     const PAF_ASOT_Params *pP, 
201     PAF_AST_Stream *xStr
202 );
204 // Initialize Output Processing state function
205 static Int PAF_ASOT_initSyncDecReset(
206     const PAF_ASOT_Params *pP, 
207     const PAF_ASOT_Patchs *pQ, 
208     PAF_ASOT_Config *pAsotCfg,
209     PAF_AudioFrame *pDecResetAf
210 );
212 //   Purpose:   ASOT Function for Output reset
213 static Int PAF_ASOT_outputReset(
214     const PAF_ASOT_Params *pP, 
215     const PAF_ASOT_Patchs *pQ, 
216     PAF_ASOT_Config *pAsotCfg
217 );
219 //   Purpose:   Init-Sync Dec Info1 state function.
220 //              Performes Dec Info1 Init-Sync.
221 static Int PAF_ASOT_initSyncDecInfo1(
222     const PAF_ASOT_Params *pP, 
223     const PAF_ASOT_Patchs *pQ, 
224     PAF_ASOT_Config *pAsotCfg,
225     PAF_AudioFrame *pDecInfo1Af
226 );
228 //   Purpose:   ASOT function for ASP chain reset and ENC info
229 static Int PAF_ASOT_outputInfo1(
230     const PAF_ASOT_Params *pP, 
231     const PAF_ASOT_Patchs *pQ, 
232     PAF_ASOT_Config *pAsotCfg
233 );
235 //   Purpose:   Init-Sync Dec Decode1 state function.
236 //              Performes Dec Decode1 Init-Sync.
237 static Int PAF_ASOT_initSyncDecDecode1(
238     const PAF_ASOT_Params *pP, 
239     const PAF_ASOT_Patchs *pQ, 
240     PAF_ASOT_Config *pAsotCfg
241 );
243 //   Purpose:   Init-Sync Re-Sync state function.
244 //              Peformed Init-Sync using stored Dec Reset/Info1 AFs.
245 static Int PAF_ASOT_initSyncResync(
246     const PAF_ASOT_Params *pP, 
247     const PAF_ASOT_Patchs *pQ, 
248     PAF_ASOT_Config *pAsotCfg,
249     PAF_AudioFrame *pDecResetAf,
250     PAF_AudioFrame *pDecInfo1Af  
251 );
253 #if 0
254 // Init-Sync update audio frame
255 static Int initSyncUpdateAf(
256     PAF_AudioFrame *dstAf, 
257     PAF_AudioFrame *srcAf
258 );
259 #endif
261 // Reset audio frames
262 static Void resetAfs(
263     const PAF_ASOT_Params *pP, 
264     PAF_AST_Stream *xStr
265 );
267 // Reset audio frame pointers to original values
268 static Void resetAfPointers(
269     const PAF_ASOT_Params *pP, 
270     PAF_AST_Stream *xStr
271 );
273 // Reset audio frame meta data elements
274 static Void resetAfMetadata(
275     const PAF_ASOT_Params *pP, 
276     PAF_AST_Stream *xStr
277 );
280 LINNO_DEFN(TaskAsop); /* Line number macros */
281 ERRNO_DEFN(TaskAsop); /* Error number macros */
283 // ASOT configuration
284 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
285 PAF_ASOT_Config gPAF_ASOT_config = {
286     NULL,               // taskHandle
287     NULL,               // acp
288     0,0,0,              // CB drained flags (size DECODE_MAXN)
289     &gPAF_ASPM_config,  // pAspmCfg
290     &gPAF_AST_config    // pAstCfg
291 };
293 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
294 #define DEC_OP_CB_RDAF_UND_THR  ( 80 ) // FL: arbitrary setting
295 UInt32 gCbReadAfErr         =0; // read circular buffer error count, not including underflows
296 UInt32 gDecOpCbRdAfUnd      =0; // decoder output circular buffer underflow count
297 UInt32 gMaxDecOpCbRdAfUnd   =0; // max (consecutive) decoder output circular buffer underflow count
298 UInt32 gMasterCbResetCnt    =0; // master circular buffer reset count
300 // For writeDECCommandRestart
301 extern volatile UInt32 gCommandOutputTask_SYNC;
302 extern volatile UInt32 gCommandOutputTask_ACK;
304 // Global debug counters */
305 UInt32 gAsopTxSioReclaimCnt         =0;
306 UInt32 gAsopInitOutProcCnt          =0;
307 UInt32 gAsopInitSyncDecResetCnt     =0;
308 UInt32 gAsopInitSyncDecInfo1Cnt     =0;
309 UInt32 gAsopInitSyncDecDecode1Cnt   =0;
310 UInt32 gAsopInitSyncResyncCnt       =0;
311 UInt32 gAsopOutProcCnt              =0;
312 UInt32 gAsopInitCnt                 =0;
313 UInt32 gAsopStreamCnt               =0;
314 UInt32 gAsopEncodeCnt               =0;
315 UInt32 gAsopFinalCnt                =0;
316 UInt32 gAsopOutSioUpdateCnt         =0;
317 UInt32 gAsopQuitCnt                 =0;
319 /*
320  *  ======== taskAsopFxn ========
321  *  Audio Stream Output Processing task function
322  */
323 Void taskAsopFxn(
324 //    Int betaPrimeValue, // FL: revisit
325     const PAF_ASOT_Params *pP,
326     const PAF_ASOT_Patchs *pQ
329     PAF_ASOT_Config *pAsotCfg;      /* ASOT configuration pointer */
330     PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
331     Int as;                         /* Audio Stream Number (1, 2, etc.) */
332     Int z;                          /* input/encode/stream/decode/output counter */
333     Int i;                          /* phase */
334     Int zMS;
335     Int errno;                      // error number
336     Int8 procSleep;                 // whether to sleep: 0: No, 1: Yes
337     Int8 procOutDevSel;             // whether to perform output device selection: 0: No, 1:Yes
338     Int outSel;                     // whether output device selected
339     enum { INIT_OUT_PROC_STATE, 
340            INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE, 
341            INITSYNC_RESYNC_STATE, 
342            OUT_PROC_STATE } state;
343     PAF_AudioFrame decResetAf;
344     PAF_AudioFrame decInfo1Af;
345     Int loopCount = 0;              // used to stop trace to see startup behavior.
346     
348     Log_info0("Enter taskAsopFxn()");    
350     //
351     // Audio Stream Output Task Parameters & Patch (*pP, *pQ)
352     //
353     if (!pP) 
354     {
355         TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
356         LINNO_RPRT(TaskAsop, -1);
357         return;
358     }
360     if (!pQ)
361     {
362         TRACE_TERSE0("TaskAsop: No Patchs defined. Exiting.");
363         LINNO_RPRT(TaskAsop, -1);
364         return;
365     }    
367     //
368     // Audio Stream Output Task Configuration (*pAsotCfg):
369     //
370     pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
371     pAsotCfg->taskHandle = Task_self(); // set task handle
372     pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
374     /* Obtain Audio Stream Number (1, 2, etc.) */    
375     as = pAstCfg->as;
376     TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
378     //
379     // Initialize message log trace and line number reporting
380     //
381     for (z=STREAM1; z < STREAMN; z++)
382     {
383         TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
384     }
385     LINNO_RPRT(TaskAsop, -1);
386     
387     //
388     // Determine stream index
389     //
390     zMS = pAstCfg->masterStr;
392     // Initialize as per parametrized phases:
393     //
394     //   In standard form these are:
395     //      - Malloc: Memory Allocation
396     //      - Config: Configuration Initialization
397     //      - AcpAlg: ACP Algorithm Initialization and Local Attachment
398     //      - Common: Common Memory Initialization
399     //      - AlgKey: Dec/Enc chain to Array Initialization
400     //      - Device: I/O Device Initialization
401     //      - Unused: (available)
402     //      - Unused: (available)
403     //
404     LINNO_RPRT(TaskAsop, -2);
405     for (i=0; i < lengthof(pP->fxns->initPhase); i++)
406     {
407         Int linno;
408         if (pP->fxns->initPhase[i])
409         {
410             linno = pP->fxns->initPhase[i](pP, pQ, pAsotCfg);
411             if (linno) 
412             {
413                 LINNO_RPRT(TaskAsop, linno);
414                 return;
415             }
416         }
417         else 
418         {
419             TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
420         }
421         TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
422         LINNO_RPRT(TaskAsop, -i-3);
423     }
424   
425     //
426     // End of Initialization -- display memory usage report.
427     //
428     if (pP->fxns->memStatusPrint)
429     {
430         pP->fxns->memStatusPrint("ASOT MEMSTAT REPORT",
431             HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, 
432             HEAP_INTERNAL1_SHM, HEAP_EXTERNAL_SHM, HEAP_EXTERNAL_NONCACHED_SHM);
433     }
435     //
436     // Main processing loop
437     //   
438     for (z=STREAM1; z < STREAMN; z++)
439     {
440         TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z);
441     }
442     
443     errno = 0;                      // init error indicator -- no error
444     procSleep = 1;                  // init sleep flag -- sleep
445     procOutDevSel = 1;              // init device output selection flag -- perform output device selection
446     state = INIT_OUT_PROC_STATE;    // init state
447     for (;;)
448     {
449         loopCount++;
450         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
452         //
453         // Check forward (ASIT) error here, TBD
454         //
455         
456         // Even if we are not in error state, we check if writeDECCommandRestar issued or not
457         if (gCommandOutputTask_SYNC) {
458             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Wait for the command deasserted");
459             gCommandOutputTask_ACK = 1;
460             while (gCommandOutputTask_SYNC) {
461                 Task_sleep(1);
462             }
463             TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Startover the process");
464             procSleep = 1;                  // init sleep flag -- sleep
465             procOutDevSel = 1;              // init device output selection flag -- perform output device selection
466             state = INIT_OUT_PROC_STATE;    // init state -- starover
467             errno = ASOP_DP_FORWARD_ERR;    // Override the error -- for flushing SIO output device
468         }
469         
470         // any error forces idling of output
471         if (errno) 
472         {
473             for (z=OUTPUT1; z < OUTPUTN; z++)
474             {
475                 if (pAstCfg->xOut[z].hTxSio)
476                 {
477                     SIO_idle(pAstCfg->xOut[z].hTxSio);
478                 }
479             }
480         
481             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
482             ERRNO_RPRT(TaskAsop, errno);
483         }
484         
485         if (procSleep == 1)
486         {
487             TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
488             Task_sleep(1);
489         }
491         if (procOutDevSel == 1)
492         {
493             // select output devices
494             TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
495             errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
496             if (errno)
497             {
498                 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
500                 procSleep = 1;
501                 procOutDevSel = 1;
503                 continue;
504             }
506             // if no output selected skip remaining processing
507             errno = checkOutSel(pP, pAsotCfg, &outSel);
508             if (errno < 0)
509             {
510                 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
512                 procSleep = 1;
513                 procOutDevSel = 1;
515                 continue;
516             }
517             else if (!outSel)
518             {
519                 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
521                 procSleep = 1;
522                 procOutDevSel = 1;
523                 
524                 continue;
525             }
526         }
527         
528         switch (state)
529         {
530             case INIT_OUT_PROC_STATE:
531                 gAsopInitOutProcCnt++;
532                 Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
533                 
534                 //
535                 // Output Processing initialization.
536                 //
537                 errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
538                 if (errno < 0)
539                 {
540                     state = INIT_OUT_PROC_STATE;
541                     procSleep = 1;
542                     procOutDevSel = 1;
543                 }
544                 else
545                 {
546                     state = INITSYNC_DEC_RESET_STATE;
547                     procSleep = 0;
548                     procOutDevSel = 0;
549                 }
550             
551                 break;
552                 
553             case INITSYNC_DEC_RESET_STATE:
554                 gAsopInitSyncDecResetCnt++;
555                 Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
557                 //
558                 // Dec Reset Init-Sync.
559                 //  
560                 
561                 // Perform Dec Reset init-sync.
562                 // Latch Dec Reset AF.
563                 errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
564                 if (errno < 0)
565                 {
566                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
568                     // sync error -- start over
569                     state = INIT_OUT_PROC_STATE;
570                     procSleep = 1;
571                     procOutDevSel = 1;
572                 }
573                 else if (errno == ASOP_INITSYNC_NOTREADY)
574                 {
575                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
577                     // sync not ready -- try again
578                     state = INITSYNC_DEC_RESET_STATE;
579                     errno=0; // FL: temp hack
580                     procSleep = 1;
581                     procOutDevSel = 1;
582                 }
583                 else // errno==0
584                 {
585                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
587                     // sync'd -- move on
588                     state = INITSYNC_DEC_INFO1_STATE;
589                     procSleep = 0;
590                     procOutDevSel = 0;
591                 }
592                 
593                 break;
594             
595             case INITSYNC_DEC_INFO1_STATE:
596                 gAsopInitSyncDecInfo1Cnt++;
597                 Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
598                 
599                 //
600                 // Dec Info1 Init-Sync.
601                 //
603                 // Perform Dec Info1 init-sync.
604                 // Latch Dec Info1 AF.
605                 errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
606                 if (errno < 0)
607                 {
608                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
609                     
610                     // sync error -- start over
611                     state = INIT_OUT_PROC_STATE;
612                     procSleep = 1;
613                     procOutDevSel = 1;
614                 }
615                 else if (errno == ASOP_INITSYNC_NOTREADY)
616                 {
617                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
619                     // sync not ready -- try again
620                     state = INITSYNC_DEC_INFO1_STATE;
621                     errno=0; // FL: temp hack
622                     procSleep = 1;
623                     procOutDevSel = 0;
624                 }
625                 else // errno = 0
626                 {
627                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
629                     // sync'd -- move on
630                     state = INITSYNC_DEC_DECODE1_STATE;
631                     procSleep = 0;
632                     procOutDevSel = 0;
633                 }
634                 
635                 break;
636             
637             case INITSYNC_DEC_DECODE1_STATE:
638                 gAsopInitSyncDecDecode1Cnt++;
639                 Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
640                 
641                 //
642                 // Dec Info1 Init-Sync.
643                 //
645                 // Perform Dec Info1 init-sync.
646                 // Latch Dec Info1 AF.
647                 errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
648                 if (errno < 0)
649                 {
650                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
652                     // sync error -- start over
653                     state = INIT_OUT_PROC_STATE;
654                     procSleep = 1;
655                     procOutDevSel = 1;
656                 }
657                 else if (errno == ASOP_INITSYNC_NOTREADY)
658                 {
659                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
661                     // sync not ready -- try again
662                     state = INITSYNC_DEC_DECODE1_STATE;
663                     errno=0; // FL: temp hack
664                     procSleep = 1;
665                     procOutDevSel = 0;
666                 }
667                 else // errno = 0
668                 {
669                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
671                     // sync'd -- move on
672                     state = OUT_PROC_STATE;
673                     procSleep = 0;
674                     procOutDevSel = 0;
675                 }
676                 
677                 break;
678             
679             case INITSYNC_RESYNC_STATE:
680                 gAsopInitSyncResyncCnt++;
681                 Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
683                 //
684                 // Re-Sync.
685                 // Use stored AF info from init-sync.
686                 // This is done in case of local error.
687                 //
688                 
689                 // Perform Dec Info1 init-sync.
690                 errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf, 
691                     &decInfo1Af);
692                 if (errno < 0)
693                 {
694                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
696                     // sync error -- start over
697                     state = INIT_OUT_PROC_STATE;
698                     procSleep = 1;
699                     procOutDevSel = 1;
700                 }
701                 else
702                 {
703                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
705                     // re-sync'd -- move on
706                     state = OUT_PROC_STATE;
707                     procSleep = 0;
708                     procOutDevSel = 0;
709                 }
710                     
711                 break;
712             
713             case OUT_PROC_STATE:        
714                 gAsopOutProcCnt++;
715                 Log_info0("TaskAsop: state=OUT_PROC_STATE");
716                 
717                 //
718                 // Output Processing.
719                 //
721                 TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
722                 errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
723                 if (errno < 0)
724                 {
725                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
726                     
727                     //
728                     // Output Processing exit, due to error
729                     //
730                     
731                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
732                     if (errno == ASOP_DP_FORWARD_ERR)
733                     {
734                         // forward (ASIT) error -- start over
735                         state = INIT_OUT_PROC_STATE;
736                         procSleep = 1;
737                         procOutDevSel = 1;
738                     }
739                     else
740                     {
741                         // local (ASOT) error
742                         state = INITSYNC_RESYNC_STATE;    
743                         procSleep = 1;
744                         procOutDevSel = 0; // disallow device re-select if local error during output processing
745                     }        
746                 }
747                 else if (errno > 0)
748                 {
749                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
751                     //
752                     // Output Processing exit, not due to error
753                     //
755                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);                    
756                     if (errno == ASOP_DP_OUT_SIO_UPDATE)
757                     {
758                         // skip re-sync
759                         // resume output processing after new output selected
760                         state = OUT_PROC_STATE;
761                         procSleep = 1;
762                         procOutDevSel = 1;
763                     }
764                 }
765                 else
766                 {
767                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
769                     //
770                     // Output Processing exit, normal
771                     //
772                     
773                     TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
774                     
775                     // no error returned if CB drained 
776                     // (i.e. CB drained is normal behavior)
777                     state = INIT_OUT_PROC_STATE;
778                     procSleep = 1;
779                     procOutDevSel = 1;
780                 }
781                 
782                 break;
783             
784             default: // unknown state
785                 TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state);
786                 break;
787         }
788     } // End of main processing loop for (;;)
789     
790     //Log_info0("Exit taskAsopFxn()");
793 // -----------------------------------------------------------------------------
794 // AST Initialization Function - Memory Allocation
795 //
796 //   Name:      PAF_ASOT_initPhaseMalloc
797 //   Purpose:   Audio Stream Output Task Function for initialization of data pointers
798 //              by allocation of memory.
799 //   From:      audioStream1Task or equivalent
800 //   Uses:      See code.
801 //   States:    x
802 //   Return:    0 on success.
803 //              Source code line number on MEM_calloc failure.
804 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
805 //              * State information as per parent.
806 //              * Memory allocation errors.
807 //
809 Int
810 PAF_ASOT_initPhaseMalloc (
811     const PAF_ASOT_Params *pP, 
812     const PAF_ASOT_Patchs *pQ, 
813     PAF_ASOT_Config *pAsotCfg
816     PAF_AST_Config *pAstCfg;
817     Int as;                     /* Audio Stream Number (1, 2, etc.) */
818     Int zMS;
819     Error_Block    eb;
820     //Int i;
822     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
823     as = pAstCfg->as;
824     zMS = pAstCfg->masterStr;
826     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
828     // Initialize error block
829     Error_init(&eb); 
831     /* Stream memory */
832     if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
833     {
834         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
835         SW_BREAKPOINT;
836         return __LINE__;
837     }
838     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
839             STREAMN * sizeof (*pAstCfg->xStr),
840             HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
842     {
843         Int z;                          /* stream counter */
845         PAF_AudioFrame *fBuf;
847         if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
848         {
849             TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
850             SW_BREAKPOINT;
851             return __LINE__;
852         }
853         TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
854                 STREAMS * sizeof (*fBuf),
855                 HEAP_ID_INTERNAL, (IArg)fBuf);
857         for (z=STREAM1; z < STREAMN; z++)
858         {
859             pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
860             TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
861         }
862     }
864     /* Encode memory */
865     if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
866     {
867         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
868         SW_BREAKPOINT;
869         return __LINE__;
870     }
871     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
872             ENCODEN * sizeof (*pAstCfg->xEnc),
873             HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
875     /* Output memory */
876     if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb)))
877     {
878         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
879         SW_BREAKPOINT;
880         return __LINE__;
881     }
882     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.",
883             OUTPUTN * sizeof (*pAstCfg->xOut),
884             HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
886     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
887     return 0;
888 } //PAF_ASOT_initPhaseMalloc
890 // -----------------------------------------------------------------------------
891 // ASOT Initialization Function - Memory Initialization from Configuration
892 //
893 //   Name:      PAF_ASOT_initPhaseConfig
894 //   Purpose:   Audio Stream Output Task Function for initialization of data values
895 //              from parameters.
896 //   From:      audioStream1Task or equivalent
897 //   Uses:      See code.
898 //   States:    x
899 //   Return:    0 on success.
900 //              Other as per initFrame0 and initFrame1.
901 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
902 //              * State information as per parent.
903 //
904 Int
905 PAF_ASOT_initPhaseConfig(
906     const PAF_ASOT_Params *pP, 
907     const PAF_ASOT_Patchs *pQ, 
908     PAF_ASOT_Config *pAsotCfg
911     PAF_AST_Config *pAstCfg;
912     Int as;                     /* Audio Stream Number (1, 2, etc.) */
913     Int z;                      /* input/encode/stream/decode/output counter */
914     Int zMS;
916     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
917     as = pAstCfg->as;
918     zMS = pAstCfg->masterStr;
920     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
922     //
923     // Unspecified elements have been initialized to zero during alloc
924     //
926     for (z=STREAM1; z < STREAMN; z++) 
927     {
928         Int linno;
929         if (linno = pP->fxns->initFrame0(pP, pQ, pAsotCfg, z))
930         {
931             return linno;           
932         }
933         if (linno = pP->fxns->initFrame1(pP, pQ, pAsotCfg, z, -1))
934         {
935             return linno;
936         }
937     }
939     for (z=ENCODE1; z < ENCODEN; z++) 
940     {
941         Int zO = pP->outputsFromEncodes[z];
942         Int zS = pP->streamsFromEncodes[z];
943         pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
944         pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
945         pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
946         pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
947         pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
948         pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
949         pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
950         pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
951     }
953     for (z=OUTPUT1; z < OUTPUTN; z++)
954     {
955         pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
956     }
958     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
959     return 0;
960 } //PAF_ASOT_initPhaseConfig
962 // -----------------------------------------------------------------------------
963 // ASOT Initialization Function - ACP Algorithm Instantiation
964 //
965 //   Name:      PAF_ASOT_initPhaseAcpAlg
966 //   Purpose:   Audio Stream Input Task Function for initialization of ACP by
967 //              instantiation of the algorithm.
968 //   From:      audioStream1Task or equivalent
969 //   Uses:      See code.
970 //   States:    x
971 //   Return:    0 on success.
972 //              Source code line number on ACP Algorithm creation failure.
973 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
974 //              * State information as per parent.
975 //              * Memory allocation errors.
976 //
977 Int
978 PAF_ASOT_initPhaseAcpAlg(
979     const PAF_ASOT_Params *pP, 
980     const PAF_ASOT_Patchs *pQ, 
981     PAF_ASOT_Config *pAsotCfg
984     PAF_AST_Config *pAstCfg;
985     Int as;                     /* Audio Stream Number (1, 2, etc.) */
986     Int z;                      /* input/encode/stream/decode/output counter */
987     Int betaPrimeOffset;
988     ACP_Handle acp;
989     Int zMS;
990     Int zS, zX;
992     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
993     as = pAstCfg->as;
994     zMS = pAstCfg->masterStr;
996     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
998     ACP_MDS_init();
1000     if (!(acp = (ACP_Handle )ACP_MDS_create(NULL))) 
1001     {
1002         TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation  failed", as+zMS);
1003         return __LINE__;
1004     }
1005     pAsotCfg->acp = acp;
1007     ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
1008         ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
1010     for (z=ENCODE1; z < ENCODEN; z++) 
1011     {
1012         zS = pP->streamsFromEncodes[z];
1013         acp->fxns->attach(acp, ACP_SERIES_STD,
1014             STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
1015             (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
1016         acp->fxns->attach(acp, ACP_SERIES_STD,
1017             STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
1018             (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
1019         /* Ignore errors, not reported. */
1020     }
1022     for (z=OUTPUT1; z < OUTPUTN; z++) 
1023     {
1024         zS = z;
1025         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1026         {
1027             if (pP->outputsFromEncodes[zX] == z) 
1028             {
1029                 zS = pP->streamsFromEncodes[zX];
1030                 break;
1031             }
1032         }
1033         acp->fxns->attach(acp, ACP_SERIES_STD,
1034             STD_BETA_OB + betaPrimeOffset * (as-1+zS),
1035             (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
1036         /* Ignore errors, not reported. */
1037     }
1039     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
1041     return 0;
1042 } //PAF_ASOT_initPhaseAcpAlg
1044 // -----------------------------------------------------------------------------
1045 // ASOT Initialization Function - Common Memory
1046 //
1047 //   Name:      PAF_ASOT_initPhaseCommon
1048 //   Purpose:   Audio Stream Output Task Function for allocation of common memory.
1049 //   From:      audioStream1Task or equivalent
1050 //   Uses:      See code.
1051 //   States:    x
1052 //   Return:    0 on success.
1053 //              Source code line number on PAF_ALG_alloc failure.
1054 //              Source code line number on PAF_ALG_mallocMemory failure.
1055 //              Source code line number on Decode Chain initialization failure.
1056 //              Source code line number on ASP Chain initialization failure.
1057 //              Source code line number on Encode Chain initialization failure.
1058 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1059 //              * State information as per parent.
1060 //              * Memory allocation errors.
1061 //
1062 Int
1063 PAF_ASOT_initPhaseCommon(
1064     const PAF_ASOT_Params *pP, 
1065     const PAF_ASOT_Patchs *pQ, 
1066     PAF_ASOT_Config *pAsotCfg
1069     PAF_AST_Config *pAstCfg;
1070     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1071     Int z;                      /* stream counter */
1072     Int g;                      /* gear */
1073     ACP_Handle acp;
1074     PAF_IALG_Config pafAlgConfig;
1075     IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
1076    
1077     acp = pAsotCfg->acp;
1078     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1079     as = pAstCfg->as;
1081     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
1083     //
1084     // Determine memory needs and instantiate algorithms across audio streams
1085     //
1086     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
1087     PAF_ALG_setup(&pafAlgConfig, 
1088         HEAP_ID_INTERNAL,                 HEAP_INTERNAL, 
1089         HEAP_ID_INTERNAL1,                HEAP_INTERNAL1, 
1090         HEAP_ID_EXTERNAL,                 HEAP_EXTERNAL, 
1091         HEAP_ID_INTERNAL1_SHM,            HEAP_INTERNAL1_SHM, 
1092         HEAP_ID_EXTERNAL_SHM,             HEAP_EXTERNAL_SHM, 
1093         HEAP_ID_EXTERNAL_NONCACHED_SHM,   HEAP_EXTERNAL_NONCACHED_SHM,
1094         HEAP_CLEAR);
1096     if (pP->fxns->headerPrint)
1097     {
1098         pP->fxns->headerPrint();        
1099     }
1101     for (z = STREAM1; z < STREAMN; z++) 
1102     {
1103         //Int zD, zE, zX;
1104         Int zE, zX;
1106         TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
1108         //
1109         // Determine common memory needs for:
1110         //  (1) ASP Algorithms
1111         //  (2) Encode Algorithms
1112         //  (3) Logical Output drivers
1113         //
1114         PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
1116         zE = -1;
1117         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1118         {
1119             if (pP->streamsFromEncodes[zX] == z) 
1120             {
1121                 zE = zX;
1122                 break;
1123             }
1124         }
1126         TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
1127         if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z])) 
1128         {
1129             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
1130             TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
1131             SW_BREAKPOINT;
1132             return __LINE__;
1133         }
1134         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1135         if (pP->fxns->allocPrint)
1136         {
1137             pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
1138         }
1140         if (zE >= 0) 
1141         {
1142             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
1143             if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z])) 
1144             {
1145                 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
1146                 SW_BREAKPOINT;
1147                 return __LINE__;
1148             }
1149             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1150             if (pP->fxns->allocPrint)
1151             {
1152                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
1153             }
1154         }
1156         //
1157         // Determine common memory needs of Logical IO drivers
1158         //
1160         if (OUTPUT1 <= z && z < OUTPUTN)
1161         {
1162             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
1163             if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
1164             {
1165                 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
1166                 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
1167                 SW_BREAKPOINT;
1168                 return __LINE__;
1169             }
1170             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1171             if (pP->fxns->allocPrint)
1172             {
1173                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
1174             }
1175         }
1176     }
1177     {
1178         // Changes made to share scratch between zones
1179         // Assume maximum 3 zones and scratch common memory is at offset 0;
1180         int max=0;
1181         for (z=STREAM1; z<STREAMN; z++)
1182         {
1183             if (max < common[z][0].size)
1184             {
1185                 max = common[z][0].size;
1186             }
1187         }
1188         common[STREAM1][0].size=max;
1189         for (z=STREAM1+1; z<STREAMN; z++)
1190         {
1191             common[z][0].size = 0;            
1192         }
1193     }
1194         
1195     //
1196     // Allocate common memory for:
1197     //  (1) ASP Algorithms
1198     //  (2) Encode Algorithms
1199     //  (3) Logical Output drivers
1200     //
1201     for (z = STREAM1; z < STREAMN; z++) 
1202     {
1203         //Int zD, zE, zX;
1204         Int zE, zX;
1206         TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
1207         if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig)) 
1208         {
1209             TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
1210             TRACE_TERSE3("AS%d: z: %d.  Size 0x%x", as+z, z, common[z][0].size);
1211             SW_BREAKPOINT;
1212             return __LINE__;
1213         }
1214         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1215         // share zone0 scratch with all zones 
1216         common[z][0].base = common[0][0].base;
1217         if (pP->fxns->commonPrint)
1218         {
1219             pP->fxns->commonPrint(common[z], &pafAlgConfig);
1220         }
1222         zE = -1;
1223         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1224         {
1225             if (pP->streamsFromEncodes[zX] == z) 
1226             {
1227                 zE = zX;
1228                 break;
1229             }
1230         }
1232         pAstCfg->xStr[z].aspChain[0] = NULL;
1233         for (g=0; g < GEARS; g++) 
1234         {
1235             PAF_ASP_Chain *chain;
1236             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
1237             chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
1238                 HEAP_INTERNAL, as+z, acp, &trace,
1239                 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
1240             if (!chain) 
1241             {
1242                 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
1243                 return __LINE__;
1244             }
1245             else
1246             {
1247                 pAstCfg->xStr[z].aspChain[g] = chain;
1248             }
1249         }
1251         if (zE >= 0) 
1252         {
1253             PAF_ASP_Chain *chain;
1254             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
1255             chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
1256                 HEAP_INTERNAL, as+z, acp, &trace,
1257                 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
1258             if (!chain) 
1259             {
1260                 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
1261                 return __LINE__;
1262             }
1263         }
1265         //
1266         // Allocate non-common memories for Logical IO drivers
1267         //    Since these structures are used at run-time we allocate from external memory
1268         if (OUTPUT1 <= z && z < OUTPUTN) 
1269         {
1270             PAF_ASP_Chain *chain;
1271             TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
1272                            as+z, z);
1273             chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
1274                         HEAP_EXTERNAL, as+z, acp, &trace,
1275                         outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
1276             if (!chain) 
1277             {
1278                 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
1279                 return __LINE__;
1280             }
1281         }
1282     }
1283     TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
1285     return 0;
1286 } //PAF_ASOT_initPhaseCommon
1288 // -----------------------------------------------------------------------------
1289 // ASOT Initialization Function - Algorithm Keys
1290 //
1291 //   Name:      PAF_ASOT_initPhaseAlgKey
1292 //   Purpose:   Audio Stream Output Task Function for initialization of data values
1293 //              from parameters for Algorithm Keys.
1294 //   From:      audioStream1Task or equivalent
1295 //   Uses:      See code.
1296 //   States:    x
1297 //   Return:    0.
1298 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1299 //              * State information as per parent.
1300 //
1301 // .............................................................................
1302 Int
1303 PAF_ASOT_initPhaseAlgKey(
1304     const PAF_ASOT_Params *pP, 
1305     const PAF_ASOT_Patchs *pQ, 
1306     PAF_ASOT_Config *pAsotCfg
1309     PAF_AST_Config *pAstCfg;
1310     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1311     Int z;                      /* decode/encode counter */
1312     Int s;                      /* key number */
1313     PAF_ASP_Link *that;
1315     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1316     as = pAstCfg->as;
1317     (void)as; // clear compiler warning in case not used with tracing disabled
1319     TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
1321     for (z=ENCODE1; z < ENCODEN; z++) 
1322     {
1323         for (s=0; s < pP->pEncAlgKey->length; s++) 
1324         {
1325             if ((pP->pEncAlgKey->code[s].full != 0) && 
1326                 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
1327             {
1328                 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
1329             }
1330             /* Cast in interface, for now --Kurt */
1331             else
1332             {
1333                 pAstCfg->xEnc[z].encAlg[s] = NULL;                
1334             }
1335         }
1336     }
1338     return 0;
1339 } //PAF_ASOT_initPhaseAlgKey
1341 // -----------------------------------------------------------------------------
1342 // ASOT Initialization Function - I/O Devices
1343 //
1344 //   Name:      PAF_ASOT_initPhaseDevice
1345 //   Purpose:   Audio Stream Output Task Function for initialization of I/O Devices.
1346 //   From:      audioStream1Task or equivalent
1347 //   Uses:      See code.
1348 //   States:    x
1349 //   Return:    0 on success.
1350 //              Source code line number on device allocation failure.
1351 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1352 //              * State information as per parent.
1353 //              * Memory allocation errors.
1354 //
1355 Int
1356 PAF_ASOT_initPhaseDevice(
1357     const PAF_ASOT_Params *pP, 
1358     const PAF_ASOT_Patchs *pQ, 
1359     PAF_ASOT_Config *pAsotCfg
1362     PAF_AST_Config *pAstCfg;
1363     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1364     Int z;                      /* input/output counter */
1365     PAF_SIO_IALG_Obj    *pObj;
1366     PAF_SIO_IALG_Config *pAlgConfig;
1367     PAF_IALG_Config pafAlgConfig;
1369     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1370     as = pAstCfg->as;
1371     (void)as; // clear compiler warning in case not used with tracing disabled
1373     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
1375     if(pP->fxns->bufMemPrint)
1376     {
1377         PAF_ALG_setup (&pafAlgConfig, 
1378             HEAP_ID_INTERNAL,               HEAP_INTERNAL, 
1379             HEAP_ID_INTERNAL1,              HEAP_INTERNAL1,
1380             HEAP_ID_EXTERNAL,               HEAP_EXTERNAL,
1381             HEAP_ID_INTERNAL1_SHM,          HEAP_INTERNAL1_SHM,
1382             HEAP_ID_EXTERNAL_SHM,           HEAP_EXTERNAL_SHM,
1383             HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
1384             HEAP_CLEAR);
1385         TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
1386     }
1387     
1388     for (z=OUTPUT1; z < OUTPUTN; z++) 
1389     {
1390         PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
1392         pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
1393         pAlgConfig = &pObj->config;
1395         pAstCfg->xOut[z].hTxSio = NULL;
1396         pConfig->base.pVoid     = pAlgConfig->pMemRec[0].base;
1397         pConfig->pntr.pVoid     = pAlgConfig->pMemRec[0].base;
1398         pConfig->head.pVoid     = pAlgConfig->pMemRec[0].base;
1399         pConfig->allocation     = pAlgConfig->pMemRec[0].size;
1400         pConfig->sizeofElement  = 3;
1401         pConfig->precision      = 24;
1402         if(pP->fxns->bufMemPrint)
1403         {
1404             pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
1405         }
1406     }
1407     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
1409     return 0;
1410 } //PAF_ASOT_initPhaseDevice
1412 // -----------------------------------------------------------------------------
1413 // ASOT Initialization Function Helper - Initialization of Audio Frame
1414 //
1415 //   Name:      PAF_ASOT_initFrame0
1416 //   Purpose:   Audio Stream Output Task Function for initialization of the Audio
1417 //              Frame(s) by memory allocation and loading of data pointers
1418 //              and values.
1419 //   From:      AST Parameter Function -> decodeInfo
1420 //   Uses:      See code.
1421 //   States:    x
1422 //   Return:    0 on success.
1423 //              Source code line number on MEM_calloc failure.
1424 //              Source code line number on unsupported option.
1425 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1426 //              * Memory allocation errors.
1427 //              * Unsupported option errors.
1428 //
1430 // MID 314
1431 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
1432 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
1434 Int
1435 PAF_ASOT_initFrame0(
1436     const PAF_ASOT_Params *pP, 
1437     const PAF_ASOT_Patchs *pQ, 
1438     PAF_ASOT_Config *pAsotCfg, 
1439     Int z
1442     PAF_AST_Config *pAstCfg;
1443     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1444     Int ch;
1445     //Int aLen;
1446     Int aLen_int=0,aLen_ext=0;
1447     Int aSize = sizeof(PAF_AudioData);
1448     Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
1449     Int maxFrameLength = pP->maxFramelength;
1450     Int zX;
1451     PAF_AudioData *aBuf_int=NULL;
1452     PAF_AudioData *aBuf_ext=NULL;
1453     XDAS_UInt8 *metadataBuf;
1454     char i;
1455     Error_Block    eb;
1457     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1458     as = pAstCfg->as;
1460     // Initialize error block
1461     Error_init(&eb); 
1463     // Compute maximum framelength (needed for ARC support)
1464     maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
1465     //aLen = numchan[z] * maxFrameLength;
1466     for (i=0; i < numchan[z]; i++)
1467     {
1468         if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1469         {
1470             aLen_int += maxFrameLength;
1471         }
1472         else
1473         {
1474             aLen_ext += maxFrameLength;
1475         }
1476     }
1478     //
1479     // Initialize audio frame elements directly
1480     //
1481     pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
1482     pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
1483 ///    pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
1484     pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
1485     pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
1486     pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
1487     pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1489     //
1490     // Allocate memory for and initialize pointers to audio data buffers
1491     //
1492     //   The NUMCHANMASK is used to identify the channels for which data
1493     //   buffers can be allocated. Using this mask and switch statement
1494     //   rather than some other construct allows efficient code generation,
1495     //   providing just the code necessary (with significant savings).
1496     //
1497     if (pP->fxns->bufMemPrint)
1498     {
1499         pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1500         pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1501     }
1503     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1504     
1505     if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1506     {
1507         if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1508         {
1509             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1510             TRACE_TERSE2("  maxFrameLength: %d.  aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1511             SW_BREAKPOINT;
1512             return __LINE__;
1513         }
1514     }
1515         
1516     if (aLen_ext*aSize!=0)
1517     {
1518         if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset
1519         {
1520             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1521             TRACE_TERSE2("  maxFrameLength: %d.  aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1522             SW_BREAKPOINT;
1523             return __LINE__;
1524         }
1525     }
1526     
1527     TRACE_TERSE3("  maxFrameLength: %d.  aLen_int*aSize: %d.  aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1528     TRACE_TERSE3("  maxFrameLength: %d.  aLen_ext*aSize: %d.  aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1530     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1531     if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1532     {
1533         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1534         TRACE_TERSE1("  bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1535         SW_BREAKPOINT;
1536         return __LINE__;
1537     }
1539     {
1540         Int i;
1542 #pragma UNROLL(1)
1543         for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1544         {
1545             pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1546         }
1547     }
1549     // MID 314
1550     if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1)) 
1551     {
1552         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1553         return __LINE__;
1554     }
1555     else 
1556     {
1557         Int j = 0;
1558         Int k = 0;
1559         TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1560         for(i=0;i<numchan[z];i++)
1561         {
1562             char chan = AFChanPtrMap[numchan[z]][i];
1563             if(chan != -1)
1564             {
1565                 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1566                 {
1567                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1568                     j++;
1569                 }
1570                 else
1571                 {        
1572                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1573                     k++;
1574                 }    
1575                 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1576                 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1577             }
1578         }
1579     }
1581     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1582     {
1583         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1584         {
1585             pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1586         }
1587     }
1589     //
1590     // Initialize meta data elements
1591     //
1592     pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1593     pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1594     pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1595     pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1596     pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1597     for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1598     {
1599         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1600         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1601         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1602     }
1604     //
1605     // Initialize decoder elements directly
1606     //
1608     for (zX = DECODE1; zX < DECODEN; zX++) 
1609     {
1610         if (pP->streamsFromDecodes[zX] == z) 
1611         {
1612 #ifdef NOAUDIOSHARE
1613             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1614             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1615 #else /* NOAUDIOSHARE */
1616             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1617             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1618 #endif /* NOAUDIOSHARE */
1619         }
1620     }
1622     return 0;
1623 } //PAF_ASOT_initFrame0
1625 // -----------------------------------------------------------------------------
1626 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1627 // AST Decoding Function              - Reinitialization of Audio Frame
1628 //
1629 //   Name:      PAF_ASOT_initFrame1
1630 //   Purpose:   Audio Stream Task Function for initialization or reinitiali-
1631 //              zation of the Audio Frame(s) by loading of data values of a
1632 //              time-varying nature.
1633 //   From:      audioStream1Task or equivalent
1634 //              AST Parameter Function -> decodeInfo
1635 //              AST Parameter Function -> decodeDecode
1636 //   Uses:      See code.
1637 //   States:    x
1638 //   Return:    0.
1639 //   Trace:     None.
1640 //
1641 Int
1642 PAF_ASOT_initFrame1(
1643     const PAF_ASOT_Params *pP, 
1644     const PAF_ASOT_Patchs *pQ, 
1645     PAF_ASOT_Config *pAsotCfg, 
1646     Int z, 
1647     Int apply
1650     PAF_AST_Config *pAstCfg;
1652     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1654     //
1655     // Reinitialize audio frame elements:
1656     //
1657     //   Channel Configurations during sys init                 = Unknown
1658     //      "          "        during info or decode           = None
1659     //
1660     //   Sample Rate / Count    during sys init, info or decode = Unknown / 0
1661     //
1663     if (apply < 0) 
1664     {
1665         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1666         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1667     }
1668     else 
1669     {
1670         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1671         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1672     }
1674     if (apply < 1) 
1675     {
1676         pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1677         pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1678     }
1680     return 0;
1681 } //PAF_ASOT_initFrame1
1683 // -----------------------------------------------------------------------------
1684 // ASOT Selection Function - Output Device Selection
1685 //
1686 //   Name:      PAF_ASOT_selectDevices
1687 //   Purpose:   Audio Stream Output Task Function for selecting the devices used
1688 //              for output.
1689 //   From:      audioStream1Task or equivalent
1690 //   Uses:      See code.
1691 //   States:    x
1692 //   Return:    Error number in standard form (0 on success).
1693 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1694 //              * State information as per parent.
1695 //
1696 Int
1697 PAF_ASOT_selectDevices(
1698     const PAF_ASOT_Params *pP, 
1699     const PAF_ASOT_Patchs *pQ, 
1700     PAF_ASOT_Config *pAsotCfg
1703     PAF_AST_Config *pAstCfg;
1704     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1705     Int z;                      /* input/output counter */
1706     Int errno = 0;              /* error number */
1707     Int errme;                  /* error number, local */
1708     Int device;
1710     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1711     as = pAstCfg->as;
1712     (void)as;  // clear compiler warning in case not used with tracing disabled
1714     // Select output devices
1715     for (z=OUTPUT1; z < OUTPUTN; z++) 
1716     {
1717         if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0) 
1718         {
1719             TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1721             /* check for valid index into device array */
1722             if (device >= pQ->devout->n)
1723             {
1724                 device = 0; /* treat as device None */
1725             }
1727             errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT, 
1728                 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1729             if (errme)
1730             {
1731                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1732                 if (!errno)
1733                 {
1734                     errno = ASPERR_DEVOUT + errme;
1735                 }
1736                 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1737             }
1738             else 
1739             {
1740                 Int zE;
1742                 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1743                 // register outBufStatus and encodeStatus pointers with output devices
1744                 // This enables proper IEC encapsulation.
1745                 if (pAstCfg->xOut[z].hTxSio) 
1746                 {
1747                     // set max # of output buffers (use override if necessary)
1748                     if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1749                     {
1750                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1751                             (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1752                     }
1753                     else
1754                     {
1755                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1756                             (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1757                     }
1759                     // register PAF_SIO_IALG object address
1760                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1761                         (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1762                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR, 
1763                         (Arg)&pAstCfg->xOut[z].outBufStatus);
1764                     for (zE=ENCODE1; zE < ENCODEN; zE++) 
1765                     {
1766                         if (pP->outputsFromEncodes[zE] == z) 
1767                         {
1768                             SIO_ctrl(pAstCfg->xOut[z].hTxSio, 
1769                                 PAF_SIO_CONTROL_SET_ENCSTATUSADDR, 
1770                                 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1771                             break;
1772                         }
1773                     }
1774                 }
1775             }
1776         }
1778 /* No need to start-clocks here, since only selecting the device. */
1779 #if 0
1780         // if device selected and valid then enable stat tracking if
1781         // required and start clocking
1782         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) 
1783         {
1784             TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1785             errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1786             if (errme)
1787             {
1788                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1789                 SIO_idle(pAstCfg->xOut[z].hTxSio);
1790                 if (!errno)
1791                 {
1792                     errno = ASPERR_DEVOUT + errme;
1793                 }
1794             }
1795         }
1796 #endif
1797     }
1799     return errno;
1800 } //PAF_ASOT_selectDevices
1803 // -----------------------------------------------------------------------------
1804 // ASOT Processing Function - Decode Processing
1805 //
1806 //   Name:      PAF_ASOT_decodeProcessing
1807 //   Purpose:   Audio Stream Output Task Function for processing audio data.
1808 //
1809 Int
1810 PAF_ASOT_decodeProcessing(
1811     const PAF_ASOT_Params *pP, 
1812     const PAF_ASOT_Patchs *pQ, 
1813     PAF_ASOT_Config *pAsotCfg 
1816     PAF_AST_Config *pAstCfg;
1817     Int errno;                          /* error number */
1818     Int getVal;
1819     enum { INIT, STREAM, ENCODE, FINAL, QUIT, OUT_SIO_UPDATE } state;
1820     state = INIT;
1821     errno = 0; /* error number */
1822     Int frame; // (***) FL: formerly -- decoder input frame count
1823     Int block; // decoder output block count / input frame
1824     Int outSioUpdate;
1825     
1826     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1828     for (;;) 
1829     {
1830         //
1831         // Check forward (ASIT) error here, TBD
1832         //
1833         
1834         // If writeDECCommandRestart issued, force exit the statemachine
1835         if (gCommandOutputTask_SYNC) {
1836             TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: writeDECCommandRestart issued in state=0x%x ... exiting core loop", state);
1837             errno = ASOP_DP_FORWARD_ERR;
1838             break;
1839         }
1841         // Check if any change in output SIO, e.g. from Output shortcut.
1842         // Changes will break FSM and allow Output reconfiguration.
1843         errno = checkOutSio(pP, pAsotCfg, &outSioUpdate);
1844         if (errno < 0)
1845         {
1846             TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1847             break;
1848         }
1849         else if (outSioUpdate)
1850         {
1851             TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1852             state = OUT_SIO_UPDATE;
1853         }
1854         
1855         // Process commands (encode)
1856         getVal = pP->fxns->encodeCommand(pP, pQ, pAsotCfg);
1857         if (getVal) 
1858         {
1859             /* ignore */;
1860         }
1862         // Process state (decode)
1863         switch (state) 
1864         {
1865             case INIT: // initial state
1866                 gAsopInitCnt++;
1867                 Log_info0("TaskAsop: state=INIT");
1868             
1869                 frame = 0;
1870                 block = 0;
1872 #if 0 // FL: moved to PAF_ASOT_initOutProc()
1873                 // Reset audio frame pointers to original values
1874                 // (may be needed if error occurred).
1875                 resetAfPointers(pP, pAstCfg->xStr);
1876                 // Reset audio frame meta data elements
1877                 resetAfMetadata(pP, pAstCfg->xStr);
1878 #endif
1880                 errno = pP->fxns->decodeInit(pP, pQ, pAsotCfg);
1881                 if (errno)
1882                 {
1883                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInit", errno);
1884                     errno = ASOP_DP_DECINIT_ERR;
1885                     break;
1886                 }
1887                 
1888                 //
1889                 // Setup output: setCheckRateX, start output
1890                 //
1891                 // Establish secondary timing
1892                 errno = pP->fxns->decodeInfo1(pP, pQ, pAsotCfg, frame, block);
1893                 if (errno)
1894                 {
1895                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInfo1", errno);
1896                     break;
1897                 }
1898                 
1899                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");                
1900                 state = STREAM;
1901                 continue;
1902                 
1903             case STREAM: // stream state
1904                 gAsopStreamCnt++;
1905                 Log_info0("TaskAsop: state=STREAM");
1907                 errno = pP->fxns->decodeStream(pP, pQ, pAsotCfg, frame, block);
1908                 if (errno)
1909                 {
1910                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM.  decodeStream err 0x%x", errno);
1911                     errno = ASOP_DP_DECSTREAM_ERR;
1912                     break;
1913                 }
1915                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1916                 state = ENCODE;
1917                 continue;
1918                 
1919             case ENCODE: // encode state
1920                 gAsopEncodeCnt++;
1921                 Log_info0("TaskAsop: state=ENCODE");
1923                 errno = pP->fxns->decodeEncode(pP, pQ, pAsotCfg, frame, block);
1924                 if (errno)
1925                 {
1926                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE.  decodeEncode err 0x%x", errno);
1927                     errno = ASOP_DP_DECENC_ERR;
1928                     break;
1929                 }
1930                 
1931                 // Measure cycles in output processing loop.
1932                 // Only measures cycles spent in loop.
1933                 pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS);
1934                 gNumPfpAsot1--;
1935                 pfpBegin(PFP_ID_ASOT_1, pAsotCfg->taskHandle);
1936                 gNumPfpAsot1++;
1937                 
1938                 // (***) FL: do we need this? 
1939                 //       AF pointers come from CB read, any resets occur in Decoder AF.
1940                 //
1941                 // Reset audio frame pointers to original values
1942                 // (may have been adjusted by ARC or the like).
1943                 resetAfPointers(pP, pAstCfg->xStr);
1945                 // (***) FL: update output (setCheckRateX)
1946                 //           Contained in INFO2 in combined FSM.
1947                 errno = pP->fxns->decodeInfo2(pP, pQ, pAsotCfg, frame, block);
1948                 if (errno)
1949                 {
1950                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1951                     errno = ASOP_DP_DECINFO2_ERR;
1952                     break;
1953                 }
1955                 block++;
1956                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1957                 state = FINAL;
1958                 continue;
1959                 
1960             case FINAL:
1961                 gAsopFinalCnt++;
1962                 Log_info0("TaskAsop: state=FINAL");
1963                 
1964                 //
1965                 // (***) FL: this needs to be fixed.
1966                 //       (1) Only require selected Output to be in this FSM
1967                 //           => Dec Status checks aren't valid, 
1968                 //              will probably always exit FSM if only Output running
1969                 //       (2) Checking Dec Status info asych to input events (maybe ok)
1970                 //
1971                 // Check for final frame, and if indicated:
1972                 // - Update audio flag to cause output buffer flush rather than
1973                 //   the default truncate in "complete" processing.
1974                 // - Exit state machine to "complete" processing.
1975 #if 0
1976                 if (pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block)) 
1977                 {
1978                     for (z=OUTPUT1; z < OUTPUTN; z++)
1979                     {
1980                         if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1981                         {
1982                             TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1983                             pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1984                         }
1985                     }
1986                     break;
1987                 }
1988 #endif
1989                 errno = pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block);
1990                 if (errno < 0)
1991                 {
1992                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL break. errno 0x%x", errno);
1993                     errno = ASOP_DP_DECFINALTEST_ERR;
1994                     break;
1995                 }
1996                 else if (errno == ASOP_DP_CB_DRAINED)
1997                 {
1998                     // EOS, exit normally
1999                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL normal exit. errno 0x%x", errno);
2000                     errno = ASOP_DP_SOK;
2001                     break;
2002                 }
2004                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
2005                 state = STREAM;
2006                 continue;
2007                 
2008             case OUT_SIO_UPDATE:
2009                 gAsopOutSioUpdateCnt++;
2010                 Log_info0("TaskAsop: state=OUT_SIO_UPDATE");
2012                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: OUT_SIO_UPDATE");
2013                 errno = ASOP_DP_OUT_SIO_UPDATE;
2014                 break;
2015                 
2016             case QUIT:
2017                 gAsopQuitCnt++;
2018                 Log_info0("TaskAsop: state=QUIT");
2020                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
2021                 errno = ASPERR_QUIT;
2022                 break;
2024             default: // unknown state
2025                 // Unknown:
2026                 // - Set error number registers.
2027                 // - Exit state machine to "complete" processing.
2029                 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
2030                 errno = ASPERR_UNKNOWNSTATE;
2031                 break;
2033         }  // End of switch (state).
2034         
2035         TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
2036         if (pP->fxns->decodeComplete(pP, pQ, pAsotCfg, NULL, frame, block))
2037         {
2038             /* ignored? */;
2039         }
2040         
2041         //pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
2042         //gNumPfpAsot1--;
2043         
2044         //return errno;
2045         break;        
2046     } // End of for (;;)
2047         
2048     pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
2049     gNumPfpAsot1--;
2050         
2051     return errno;
2054 // -----------------------------------------------------------------------------
2055 // ASOT Decoding Function - Encode Command Processing
2056 //
2057 //   Name:      PAF_ASOT_encodeCommand
2058 //   Purpose:   Decoding Function for processing Encode Commands.
2059 //   From:      AST Parameter Function -> decodeProcessing
2060 //   Uses:      See code.
2061 //   States:    x
2062 //   Return:    0.
2063 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2064 //              * Command execution.
2065 //              * SIO control errors.
2066 //              * Error number macros.
2067 //
2068 Int
2069 PAF_ASOT_encodeCommand(
2070     const PAF_ASOT_Params *pP, 
2071     const PAF_ASOT_Patchs *pQ, 
2072     PAF_ASOT_Config *pAsotCfg
2075     PAF_AST_Config *pAstCfg;
2076     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2077     Int z;                      /* encode counter */
2078     Int errno = 0;              /* error number */
2079     Int zO, zS;
2082     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2083     as = pAstCfg->as;
2085     for (z=ENCODE1; z < ENCODEN; z++) 
2086     {
2087         zO = pP->outputsFromEncodes[z];
2088         zS = pP->streamsFromEncodes[z];
2089         if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
2090         {
2091             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
2092             {
2093                 case 0: // command none - process
2094                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2095                     break;
2096                 case 1: // mute command
2097                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
2098                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
2099                         && pAstCfg->xOut[zO].hTxSio
2100                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
2101                     {
2102                         errno = (errno & 0xff) | ASPERR_MUTE;
2103                         /* convert to sensical errno */
2104                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
2105                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
2106                     }
2107                     else 
2108                     {
2109                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
2110                     }
2111                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2112                     break;
2113                 case 2: // unmute command
2114                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
2115                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
2116                         && pAstCfg->xOut[zO].hTxSio
2117                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
2118                     {
2119                         errno = (errno & 0xff) | ASPERR_MUTE;
2120                         /* convert to sensical errno */
2121                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
2122                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
2123                     }
2124                     else 
2125                     {
2126                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
2127                     }
2128                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2129                     break;
2130                 default: // command unknown - ignore
2131                     break;
2132             }
2133         }
2134     }
2136     ERRNO_RPRT (TaskAsop, errno);
2138     return 0;
2139 } //PAF_ASOT_encodeCommand
2141 //debug -- allow dynamic config
2142 //Int16 gStrFrameLen=DEF_STR_FRAME_LEN; // stream frame length (PCM samples)
2144 //   Purpose:   Decoding Function for reinitializing the decoding process.
2145 Int
2146 PAF_ASOT_decodeInit(
2147     const PAF_ASOT_Params *pP, 
2148     const PAF_ASOT_Patchs *pQ, 
2149     PAF_ASOT_Config *pAsotCfg
2152     //PAF_AST_Config *pAstCfg;
2153     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2154     //Int as;                             /* Audio Stream Number (1, 2, etc.) */
2155     Int z;                              /* decode/encode counter */
2156     Int errno;                          /* error number */
2157     //Int zO, zS;
2159     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2160     //as = pAstCfg->as;
2162     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2164     for (z=DECODE1; z < DECODEN; z++)
2165     {
2166         // Initialize decoder output circular buffer for stream reads
2167         //errno = cbInitStreamRead(pCbCtl, z, gStrFrameLen);
2168         errno = cbInitStreamRead(pCbCtl, z);
2169         if (errno)
2170         {
2171             TRACE_TERSE1("PAF_ASOT_decodeInit:cbInitStreamRead() error=%d", errno);
2172             SW_BREAKPOINT; // debug
2173             return errno;
2174         }
2175         
2176         // Start decoder output circular buffer reads
2177         errno = cbReadStart(pCbCtl, z);
2178         if (errno)
2179         {
2180             TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
2181             SW_BREAKPOINT; // debug
2182             return errno;
2183         }
2184         
2185         gCbReadAfErr=0;         // reset read circular buffer error count
2186         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
2187         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
2188         gMasterCbResetCnt=0;    // reset master circular buffer reset count
2190         // FL: debug, log circular buffer control variables
2191         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
2192     }
2193     
2194 #if 0 // moved to PAF_ASOT_outputReset()
2195     // TODO: move this to start of this function so that it doesn't affect IO timing
2196     for (z=ENCODE1; z < ENCODEN; z++) 
2197     {
2198         zO = pP->outputsFromEncodes[z];
2199         zS = pP->streamsFromEncodes[z];
2200         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2201         {
2202             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2203             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2204             ENC_Handle enc = (ENC_Handle )encAlg;
2205             TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
2206             if (encAlg->fxns->algActivate)
2207             {
2208                 encAlg->fxns->algActivate (encAlg);
2209             }
2210             if (enc->fxns->reset)
2211             {
2212                 errno = enc->fxns->reset(enc, NULL, 
2213                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus);
2214                 if (errno)
2215                 {
2216                     return errno;
2217                 }
2218             }
2219         }
2220     }
2221 #endif
2222     
2223     return 0;
2226 // -----------------------------------------------------------------------------
2227 // ASOT Decoding Function - Info Processing, Initial
2228 //
2229 //   Name:      PAF_ASOT_decodeInfo1
2230 //   Purpose:   Decoding Function for processing information in a manner that
2231 //              is unique to initial frames of input data.
2232 //   From:      AST Parameter Function -> decodeProcessing
2233 //   Uses:      See code.
2234 //   States:    x
2235 //   Return:    Error number in standard or SIO form (0 on success).
2236 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2237 //              * State information as per parent.
2238 //
2239 Int
2240 PAF_ASOT_decodeInfo1(
2241     const PAF_ASOT_Params *pP, 
2242     const PAF_ASOT_Patchs *pQ, 
2243     PAF_ASOT_Config *pAsotCfg, 
2244     Int frame, 
2245     Int block
2248     //PAF_AST_Config *pAstCfg;
2249     //Int z;                              /* decode/encode counter */
2250     Int errno;                          /* error number */
2252 #if 0 // moved to PAF_ASOT_outputInfo1()
2253     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2255     // run the chain of ASP's on the stream.
2256     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
2257     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2258         PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);
2259     if (errno)
2260     {
2261         TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
2262         return errno;
2263     }
2265     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
2266     for (z=ENCODE1; z < ENCODEN; z++) 
2267     {
2268         Int zO = pP->outputsFromEncodes[z];
2269         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2270         {
2271             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2272             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2273             ENC_Handle enc = (ENC_Handle )encAlg;
2274             
2275             if (enc->fxns->info)
2276             {
2277                 errno = enc->fxns->info(enc, NULL,
2278                     &pAstCfg->xEnc[z].encodeControl, 
2279                     &pAstCfg->xEnc[z].encodeStatus);
2280                 if (errno)
2281                 {
2282                     TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
2283                     return errno;
2284                 }
2285             }
2286         }
2287     }
2288 #endif    
2290     errno = pP->fxns->setCheckRateX(pP, pQ, pAsotCfg, 0);
2291     if (errno)
2292     {
2293         // ignore if rateX has changed since we haven't, but are about to,
2294         // start the output. If we didn't ignore this case then the state machine
2295         // would restart unnecessarily, e.g. in the case of SRC, resulting in
2296         // added latency.
2297         if (errno != ASPERR_INFO_RATECHANGE)
2298         {
2299             TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
2300             return errno;
2301         }
2302         else
2303         {
2304             TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
2305         }
2306     }
2308     errno = pP->fxns->startOutput(pP, pQ, pAsotCfg);
2309     if (errno) 
2310     {
2311         if (errno == 0x105) 
2312         {
2313             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
2314         }
2315         else
2316         {
2317             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
2318         }
2319         return errno;
2320     }
2321     
2322     return 0;
2325 // -----------------------------------------------------------------------------
2326 // ASOT Decoding Function - Info Processing, Subsequent
2327 //
2328 //   Name:      PAF_ASOT_decodeInfo2
2329 //   Purpose:   Decoding Function for processing information in a manner that
2330 //              is unique to frames of input data other than the initial one.
2331 //   From:      AST Parameter Function -> decodeProcessing
2332 //   Uses:      See code.
2333 //   States:    x
2334 //   Return:    Error number in standard form (0 on success).
2335 //   Trace:     None.
2336 //
2337 Int
2338 PAF_ASOT_decodeInfo2(
2339     const PAF_ASOT_Params *pP, 
2340     const PAF_ASOT_Patchs *pQ, 
2341     PAF_ASOT_Config *pAsotCfg, 
2342     Int frame, 
2343     Int block
2346     //PAF_AST_Config *pAstCfg;
2347     Int errno;
2349     
2350     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2352     errno = pP->fxns->setCheckRateX (pP, pQ, pAsotCfg, 1);
2353     TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
2354     return errno;
2355 } //PAF_ASOT_decodeInfo2
2358 PAF_AST_DecOpCircBufStats gCbStats; // FL: debug
2359 // -----------------------------------------------------------------------------
2360 // ASOT Decoding Function - Stream Processing
2361 //
2362 //   Name:      PAF_ASOT_decodeStream
2363 //   Purpose:   Decoding Function for processing of audio frame data by the
2364 //              ASP Algorithms.
2365 //   From:      AST Parameter Function -> decodeProcessing
2366 //   Uses:      See code.
2367 //   States:    x
2368 //   Return:    Error number in standard form (0 on success).
2369 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2370 //              * State information as per parent/child.
2371 //
2372 Int
2373 PAF_ASOT_decodeStream(
2374     const PAF_ASOT_Params *pP, 
2375     const PAF_ASOT_Patchs *pQ, 
2376     PAF_ASOT_Config *pAsotCfg, 
2377     Int frame, 
2378     Int block
2381     PAF_AST_Config *pAstCfg;
2382     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2383     Int z;                              /* decode/stream counter */
2384     PAF_AudioFrame *pAfRd;
2385     Int cbErrno;
2386     //PAF_AST_DecOpCircBufStats cbStats;  /* circular buffer statistics */
2387     Int errno;
2390     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2391     
2392     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2393     
2394     for (z=DECODE1; z < DECODEN; z++) 
2395     {
2396         Int zS = pP->streamsFromDecodes[z];
2397         
2398         //
2399         // Read decoder output circular buffer
2400         //
2401         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
2402         //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
2403         cbErrno = cbReadAf(pCbCtl, z, pAfRd);
2404         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
2405         if ((cbErrno < 0) && 
2406             (cbErrno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && 
2407             (cbErrno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
2408         {
2409             gCbReadAfErr++;
2410             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
2411             //SW_BREAKPOINT; // debug
2412             return cbErrno;
2413         }
2415         // Handle underflows
2416         if ((cbErrno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
2417             (cbErrno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
2418         {
2419             // (***) FL: Need to check behavior of cbReset().
2420             // Need to check behavior on exit/re-entry into Output processing.
2421             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
2422             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
2423             {
2424                 // Underflow count above threshold.
2425                 // (1) set max underflow count to threshold
2426                 // (2) reset underflow count
2427                 // (3) reset circular buffer
2428                 
2429                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
2430                 gDecOpCbRdAfUnd = 0; // reset underflow count
2432                 // Reset circular buffer
2433                 cbReset(pCbCtl, z);
2434                 gMasterCbResetCnt++; // increment master circular buffer reset count
2435                 Log_info0("ASOT:cbReset");
2436             
2437                 return cbErrno;
2438             }
2439         }
2440         else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
2441         {
2442             // No underflow detected.
2443             // update max underflow count,
2444             // reset underflow count
2445             
2446             // update max underflow count
2447             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
2448             {
2449                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
2450             }
2451             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
2452         }
2453         //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2454         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
2455         Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2456         
2457 #if 0 // (***) FL: shows timing of CB read
2458             // (***) debug // B8
2459             {
2460                 static Uint8 toggleState = 0;
2461                 if (toggleState == 0)
2462                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2463                 else
2464                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2465                 toggleState = ~(toggleState);
2466             }
2467 #endif
2469         // debug, get circular buffer statistics
2470         //cbGetStats(pCbCtl, z, &cbStats);
2471         cbGetStats(pCbCtl, z, &gCbStats);
2473         // debug
2474         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
2475         
2476 #if 0 // debug, capture audio frame
2477         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
2478         {
2479             Log_info0("capAfWrite() error");
2480         }
2481 #endif
2482     }
2483             
2484     TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
2485     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2486         PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
2487     if (errno)
2488     {
2489         TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
2490         return errno;
2491     }
2493     return 0;
2495 } //PAF_ASOT_decodeStream
2497 // -----------------------------------------------------------------------------
2498 // ASOT Decoding Function - Encode Processing
2499 //
2500 //   Name:      PAF_ASOT_decodeEncode
2501 //   Purpose:   Decoding Function for processing of audio frame data by the
2502 //              Encode Algorithm.
2503 //   From:      AST Parameter Function -> decodeProcessing
2504 //   Uses:      See code.
2505 //   States:    x
2506 //   Return:    Error number in standard or SIO form (0 on success).
2507 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2508 //              * State information as per parent.
2509 //
2510 Int
2511 PAF_ASOT_decodeEncode(
2512     const PAF_ASOT_Params *pP, 
2513     const PAF_ASOT_Patchs *pQ, 
2514     PAF_ASOT_Config *pAsotCfg, 
2515     Int frame, 
2516     Int block
2519     PAF_AST_Config *pAstCfg;
2520     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2521     Int z;                      /* encode/output counter */
2522     Int errno;                  /* error number */
2523     Int zX, zE, zS;
2524     // debug
2525     //UInt32 curTime;
2527     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2528     as = pAstCfg->as;
2530     // Await output buffers (but not first time)
2531     for (z=OUTPUT1; z < OUTPUTN; z++) 
2532     {
2533         // determine encoder associated with this output
2534         zE = z;
2535         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2536         {
2537             if (pP->outputsFromEncodes[zX] == z) 
2538             {
2539                 zE = zX;
2540                 break;
2541             }
2542         }
2543         zS = pP->streamsFromEncodes[zE];
2545         if (pAstCfg->xOut[z].hTxSio) 
2546         {
2547             // update length (e.g. ARC may have changed)
2548             pAstCfg->xOut[z].outBufConfig.lengthofFrame = 
2549                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2550             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
2551             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
2552             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
2553             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
2554             if (errno < 0)
2555             {
2556                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2557                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
2558                 return -errno; // SIO negates error codes
2559             }
2560             // TODO: use pC->xOut[z].pOutBuf in following ->encode call
2562 #if 0 // (***) FL: shows timing of Output Rx SIO reclaim
2563             // (***) debug // B8
2564             {
2565                 static Uint8 toggleState = 0;
2566                 if (toggleState == 0)
2567                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2568                 else
2569                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2570                 toggleState = ~(toggleState);
2571             }
2572 #endif            
2574             //
2575             // Simulate Tx SIO_reclaim() pend
2576             //
2577             //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
2578             //curTime = Clock_getTicks();
2579             //System_printf("System time in TaskAsopFxn Tx audio = %lu\n", (ULong)curTime);
2580             //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
2581             
2582             gAsopTxSioReclaimCnt++;
2583         }
2584         else 
2585         {
2586             TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
2587         }
2588     }
2590     // Encode data
2591     for (z=ENCODE1; z < ENCODEN; z++) 
2592     {
2593         Int zO = pP->outputsFromEncodes[z];
2594         Int zS = pP->streamsFromEncodes[z];
2595         (void)zS; // clear compiler warning in case not used with tracing disabled
2596         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2597         {
2598             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2599             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2600             ENC_Handle enc = (ENC_Handle )encAlg;
2601             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
2602             {
2603                 pAstCfg->xEnc[z].encodeControl.encActive = select;
2604                 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
2605                 return (-1);
2606             }
2607             TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
2609             // (MID 1933) temp. workaround for PCE2
2610             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
2612           /*
2613           #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2614             {
2615                 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2616                 int *wp;
2617                 wp = (int*)pAudioFrame->data.sample[0];
2618                 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2619                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2620                 wp = (int*)pAudioFrame->data.sample[1];
2621                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2622                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2623                 wp = (int*)pAudioFrame->data.sample[2];
2624                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2625                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2626             }
2627           #endif
2628           */
2630             if (enc->fxns->encode)
2631             {
2632                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2633                         pP->z_pEncodeStatus[z]->encBypass;
2634                 errno = enc->fxns->encode(enc, NULL, 
2635                     &pAstCfg->xEnc[z].encodeInStruct, 
2636                     &pAstCfg->xEnc[z].encodeOutStruct);
2637                 if (errno)
2638                 {
2639                     if (errno != PCEERR_OUTPUT_POINTERNULL)
2640                     {
2641                         TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2642                         return errno;
2643                     }
2644                 }
2645             /*  #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2646                 else
2647                 {
2648                     int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2649                     TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2650                     TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2651                 }
2652               #endif
2653               */
2654             }
2655         }
2656         else 
2657         {
2658             TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2659                 as+pP->streamsFromEncodes[z], block);
2660         }
2661     }
2663     // Transmit data
2664     for (z=OUTPUT1; z < OUTPUTN; z++) 
2665     {
2666         // determine encoder associated with this output
2667         zE = z;
2668         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2669         {
2670             if (pP->outputsFromEncodes[zX] == z) 
2671             {
2672                 zE = zX;
2673                 break;
2674             }
2675         }
2676         zS = pP->streamsFromEncodes[zE];
2678         if (pAstCfg->xOut[z].hTxSio) 
2679         {
2680             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2681             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
2682             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
2683                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2684             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
2685             if (errno)
2686             {
2687                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2688                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
2689                 {
2690 //                    statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2691                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2692                 }
2693                 if (errno > 0)
2694                 {
2695                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2696                     return (ASPERR_ISSUE + (z << 4));
2697                 }
2698                 else if (errno < 0)
2699                 {
2700                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2701                     return -errno; // SIO negates error codes
2702                 }
2703             }
2704             if (errno > 0)
2705             {
2706                 return (ASPERR_ISSUE + (z << 4));
2707             }
2708             else if (errno < 0)
2709             {
2710                 return -errno; // SIO negates error codes
2711             }
2712         }
2713         else 
2714         {
2715             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2716         }
2717     }
2719     return 0;
2720 } //PAF_ASOT_decodeEncode
2722 // -----------------------------------------------------------------------------
2723 // ASOT Decoding Function - Stream-Final Processing
2724 //
2725 //   Name:      PAF_ASOT_decodeComplete
2726 //   Purpose:   Decoding Function for terminating the decoding process.
2727 //   From:      AST Parameter Function -> decodeProcessing
2728 //   Uses:      See code.
2729 //   States:    x
2730 //   Return:    0.
2731 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2732 //              * State information as per parent.
2733 //
2734 Int
2735 PAF_ASOT_decodeComplete(
2736     const PAF_ASOT_Params *pP, 
2737     const PAF_ASOT_Patchs *pQ, 
2738     PAF_ASOT_Config *pAsotCfg, 
2739     ALG_Handle decAlg[], 
2740     Int frame, 
2741     Int block
2744     PAF_AST_Config *pAstCfg;
2745     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2746     Int as;                             /* Audio Stream Number (1, 2, etc.) */
2747     Int z;                              /* decode/encode counter */
2748     Int errno;                          /* error number */
2750     
2751     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2752     as = pAstCfg->as;
2753     (void)as;  // clear compiler warning in case not used with tracing disabled
2755     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2756     
2757     for (z=DECODE1; z < DECODEN; z++)
2758     {
2759         // Stop decoder output circular buffer reads
2760         errno = cbReadStop(pCbCtl, z);
2761         if (errno)
2762         {
2763             TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2764             SW_BREAKPOINT; // FL: debug
2765             return errno;
2766         }
2767         // FL: debug
2768         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2769     }
2770     
2771     pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2773     for (z=ENCODE1; z < ENCODEN; z++) 
2774     {
2775         Int zO = pP->outputsFromEncodes[z];
2776         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2777         {
2778             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2779             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2780 #ifdef PAF_ASP_FINAL
2781             ENC_Handle enc = (ENC_Handle)encAlg;
2782 #endif /* PAF_ASP_FINAL */
2783             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2784 #ifdef PAF_ASP_FINAL
2785             if (enc->fxns->final)
2786                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2787                                  &pAstCfg->xEnc[z].encodeStatus);
2788 #endif /* PAF_ASP_FINAL */
2789             if (encAlg->fxns->algDeactivate)
2790             {
2791                 encAlg->fxns->algDeactivate(encAlg);
2792             }
2793         }
2794         else 
2795         {
2796             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2797         }
2798     }
2800     // wait for remaining data to be output
2801     pP->fxns->stopOutput(pP, pQ, pAsotCfg);
2803     return 0;
2804 } //PAF_ASOT_decodeComplete
2806 // -----------------------------------------------------------------------------
2807 // ASOT Decoding Function Helper - SIO Driver Start
2808 //
2809 //   Name:      PAF_ASOT_startOutput
2810 //   Purpose:   Decoding Function for initiating output.
2811 //   From:      AST Parameter Function -> decodeInfo1
2812 //   Uses:      See code.
2813 //   States:    x
2814 //   Return:    Error number in standard or SIO form (0 on success).
2815 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2816 //              * State information as per parent.
2817 //              * SIO control errors.
2818 //
2819 #define DEC_OUTNUMBUF_MAP(X) \
2820       pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2822 Int
2823 PAF_ASOT_startOutput(
2824     const PAF_ASOT_Params *pP, 
2825     const PAF_ASOT_Patchs *pQ, 
2826     PAF_ASOT_Config *pAsotCfg
2827
2829     PAF_AST_Config *pAstCfg;
2830     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2831     Int z;                      /* output counter */
2832     Int errno,nbufs, errme;            /* error number */
2833     Int zE, zS, zX;
2834     Int zMD;
2835     PAF_SIO_IALG_Obj    *pObj;
2836     PAF_SIO_IALG_Config *pAlgConfig;
2838     
2839     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2840     as = pAstCfg->as;
2841     zMD = pAstCfg->masterDec;
2843     for (z=OUTPUT1; z < OUTPUTN; z++) 
2844     {
2845         if (pAstCfg->xOut[z].hTxSio) 
2846         {
2847             // determine associated encoder and stream
2848             zE = z;
2849             zS = z;
2850             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2851             {
2852                 if (pP->outputsFromEncodes[zX] == z) 
2853                 {
2854                     zE = zX;
2855                     zS = pP->streamsFromEncodes[zE];
2856                     break;
2857                 }
2858             }
2860 // Need to Revisit: Starting Clocks here seems logical & also manages the McASP without spurious underruns .
2862 #if 1
2863             // if device selected and valid then enable stat tracking if
2864                         // required and start clocking
2865                         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
2866                         {
2867                                 TRACE_VERBOSE0("PAF_ASOT_startOutput: start SIO clocks");
2868                                 errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
2869                                 if (errno)
2870                                 {
2871                                         TRACE_VERBOSE2("PAF_ASOT_startOutput: errme 0x%x, errno 0x%x", errme, errno);
2872                                         SIO_idle(pAstCfg->xOut[z].hTxSio);
2873                                         if (!errno)
2874                                         {
2875                                                 errno = ASPERR_DEVOUT + errme;
2876                                         }
2877                                 }
2878                         }
2879 #endif
2880             // Set sample count so that DOB knows how much data to send
2881             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2882                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2884             if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED) 
2885             {
2886                 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2887                 pAlgConfig = &pObj->config;
2888                 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA, 
2889                     pAlgConfig->pMemRec[0].size);
2890             }
2892             // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2893             // decoder. How should we handle the sourceProgram for multiple decoders?
2894             // Override as needed
2895             nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2896             if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2897             {
2898                 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2899             }
2900             SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2902             if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2903                 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0)) 
2904             {
2905                 SIO_idle(pAstCfg->xOut[z].hTxSio);