ce849f74e45a980ee93e3cd12a09836146575e97
[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 #define TRACE_TIME(a)
75 //
76 // Audio Stream Definitions
77 //
79 //
80 // Audio Stream Processing Definitions
81 //
82 #define aspLinkInit pQ->i_aspLinkInit
84 //
85 // Encoder Definitions
86 //
87 #define encLinkInit pQ->i_encLinkInit
89 //
90 // Output Definitions
91 //
92 #define outLinkInit pP->i_outLinkInit
94 /* ---------------------------------------------------------------- */
95 /*              Parameter macro definitions end here.               */
96 /* ---------------------------------------------------------------- */
98 //
99 // Standardized Definitions
100 //
102 #define ENC_Handle PCE_Handle /* works for all: PCE */
104 #define __TASK_NAME__  "TaskAsop"
107 //
108 // Audio Stream Output Task definitions
109 //
111 // status codes
112 // Output FSM
113 #define ASOP_INITSYNC_NOTREADY      (  1 )  // ok, init-sync not ready
114 #define ASOP_SOK                    (  0 )  // ok
115 #define ASOP_FORWARD_ERR            ( -1 )  // forward (ASIT) error
116 #define ASOP_ENCRESET_ERR           ( -2 )  // enc reset error
117 #define ASOP_DECINFO1_ERR           ( -3 )  // dec info1 error
118 // Decode Processing
119 #define ASOP_DP_OUT_SIO_UPDATE      (  3 )  // new output selected
120 #define ASOP_DP_CB_DRAINED          (  2 )  // circular buffer drained
121 #define ASOP_DP_SOK                 (  0 )  // ok
122 #define ASOP_DP_FORWARD_ERR         ( -1 )  // forward (ASIT) error
123 #define ASOP_DP_DECINIT_ERR         ( -2 )  // decode init error
124 #define ASOP_DP_DECSTREAM_ERR       ( -3 )  // decode stream error
125 #define ASOP_DP_DECENC_ERR          ( -4 )  // decode encode error
126 #define ASOP_DP_DECINFO2_ERR        ( -5 )  // decode encode error
127 #define ASOP_DP_DECFINALTEST_ERR    ( -6 )  // decode final error
131 /* Check if at least one output selected */
132 static Int checkOutSel(
133     const PAF_ASOT_Params *pP, 
134     PAF_ASOT_Config *pAsotCfg,
135     Int *pOutSel
136 );
138 /* Check if at least one output sio changed */
139 static Int checkOutSio(
140     const PAF_ASOT_Params *pP, 
141     PAF_ASOT_Config *pAsotCfg,
142     Int *pOutSioUpdate
143 );
145 // Initialize Output Processing state function
146 static Int PAF_ASOT_initOutProc(
147     const PAF_ASOT_Params *pP, 
148     PAF_AST_Stream *xStr
149 );
151 // Initialize Output Processing state function
152 static Int PAF_ASOT_initSyncDecReset(
153     const PAF_ASOT_Params *pP, 
154     const PAF_ASOT_Patchs *pQ, 
155     PAF_ASOT_Config *pAsotCfg,
156     PAF_AudioFrame *pDecResetAf
157 );
159 //   Purpose:   ASOT Function for Output reset
160 static Int PAF_ASOT_outputReset(
161     const PAF_ASOT_Params *pP, 
162     const PAF_ASOT_Patchs *pQ, 
163     PAF_ASOT_Config *pAsotCfg
164 );
166 //   Purpose:   Init-Sync Dec Info1 state function.
167 //              Performes Dec Info1 Init-Sync.
168 static Int PAF_ASOT_initSyncDecInfo1(
169     const PAF_ASOT_Params *pP, 
170     const PAF_ASOT_Patchs *pQ, 
171     PAF_ASOT_Config *pAsotCfg,
172     PAF_AudioFrame *pDecInfo1Af
173 );
175 //   Purpose:   ASOT function for ASP chain reset and ENC info
176 static Int PAF_ASOT_outputInfo1(
177     const PAF_ASOT_Params *pP, 
178     const PAF_ASOT_Patchs *pQ, 
179     PAF_ASOT_Config *pAsotCfg
180 );
182 //   Purpose:   Init-Sync Dec Decode1 state function.
183 //              Performes Dec Decode1 Init-Sync.
184 static Int PAF_ASOT_initSyncDecDecode1(
185     const PAF_ASOT_Params *pP, 
186     const PAF_ASOT_Patchs *pQ, 
187     PAF_ASOT_Config *pAsotCfg
188 );
190 //   Purpose:   Init-Sync Re-Sync state function.
191 //              Peformed Init-Sync using stored Dec Reset/Info1 AFs.
192 static Int PAF_ASOT_initSyncResync(
193     const PAF_ASOT_Params *pP, 
194     const PAF_ASOT_Patchs *pQ, 
195     PAF_ASOT_Config *pAsotCfg,
196     PAF_AudioFrame *pDecResetAf,
197     PAF_AudioFrame *pDecInfo1Af  
198 );
200 #if 0
201 // Init-Sync update audio frame
202 static Int initSyncUpdateAf(
203     PAF_AudioFrame *dstAf, 
204     PAF_AudioFrame *srcAf
205 );
206 #endif
208 // Reset audio frames
209 static Void resetAfs(
210     const PAF_ASOT_Params *pP, 
211     PAF_AST_Stream *xStr
212 );
214 // Reset audio frame pointers to original values
215 static Void resetAfPointers(
216     const PAF_ASOT_Params *pP, 
217     PAF_AST_Stream *xStr
218 );
220 // Reset audio frame meta data elements
221 static Void resetAfMetadata(
222     const PAF_ASOT_Params *pP, 
223     PAF_AST_Stream *xStr
224 );
227 LINNO_DEFN(TaskAsop); /* Line number macros */
228 ERRNO_DEFN(TaskAsop); /* Error number macros */
230 // ASOT configuration
231 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
232 PAF_ASOT_Config gPAF_ASOT_config = {
233     NULL,               // taskHandle
234     NULL,               // acp
235     0,0,0,              // CB drained flags (size DECODE_MAXN)
236     &gPAF_ASPM_config,  // pAspmCfg
237     &gPAF_AST_config    // pAstCfg
238 };
240 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
241 #define DEC_OP_CB_RDAF_UND_THR  ( 80 ) // FL: arbitrary setting
242 UInt32 gCbReadAfErr         =0; // read circular buffer error count, not including underflows
243 UInt32 gDecOpCbRdAfUnd      =0; // decoder output circular buffer underflow count
244 UInt32 gMaxDecOpCbRdAfUnd   =0; // max (consecutive) decoder output circular buffer underflow count
245 UInt32 gMasterCbResetCnt    =0; // master circular buffer reset count
247 // Global debug counters */
248 UInt32 gAsopInitOutProcCnt          =0;
249 UInt32 gAsopInitSyncDecResetCnt     =0;
250 UInt32 gAsopInitSyncDecInfo1Cnt     =0;
251 UInt32 gAsopInitSyncDecDecode1Cnt   =0;
252 UInt32 gAsopInitSyncResyncCnt       =0;
253 UInt32 gAsopOutProcCnt              =0;
254 UInt32 gAsopInitCnt                 =0;
255 UInt32 gAsopStreamCnt               =0;
256 UInt32 gAsopEncodeCnt               =0;
257 UInt32 gAsopFinalCnt                =0;
258 UInt32 gAsopOutSioUpdateCnt         =0;
259 UInt32 gAsopQuitCnt                 =0;
260 UInt32 gAsopTxSioReclaimCnt         =0;
262 /*
263  *  ======== taskAsopFxn ========
264  *  Audio Stream Output Processing task function
265  */
266 Void taskAsopFxn(
267 //    Int betaPrimeValue, // FL: revisit
268     const PAF_ASOT_Params *pP,
269     const PAF_ASOT_Patchs *pQ
272     PAF_ASOT_Config *pAsotCfg;      /* ASOT configuration pointer */
273     PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
274     Int as;                         /* Audio Stream Number (1, 2, etc.) */
275     Int z;                          /* input/encode/stream/decode/output counter */
276     Int i;                          /* phase */
277     Int zMS;
278     Int errno;                      // error number
279     Int8 procSleep;                 // whether to sleep: 0: No, 1: Yes
280     Int8 procOutDevSel;             // whether to perform output device selection: 0: No, 1:Yes
281     Int outSel;                     // whether output device selected
282     enum { INIT_OUT_PROC_STATE, 
283            INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE, 
284            INITSYNC_RESYNC_STATE, 
285            OUT_PROC_STATE } state;
286     PAF_AudioFrame decResetAf;
287     PAF_AudioFrame decInfo1Af;
288     Int loopCount = 0;              // used to stop trace to see startup behavior.
289     
291     Log_info0("Enter taskAsopFxn()");    
293     //
294     // Audio Stream Output Task Parameters & Patch (*pP, *pQ)
295     //
296     if (!pP) 
297     {
298         TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
299         LINNO_RPRT(TaskAsop, -1);
300         return;
301     }
303     if (!pQ)
304     {
305         TRACE_TERSE0("TaskAsip: No Patchs defined. Exiting.");
306         LINNO_RPRT(TaskAsop, -1);
307         return;
308     }    
310     //
311     // Audio Stream Output Task Configuration (*pAsotCfg):
312     //
313     pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
314     pAsotCfg->taskHandle = Task_self(); // set task handle
315     pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
317     /* Obtain Audio Stream Number (1, 2, etc.) */    
318     as = pAstCfg->as;
319     TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
321     //
322     // Initialize message log trace and line number reporting
323     //
324     for (z=STREAM1; z < STREAMN; z++)
325     {
326         TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
327     }
328     LINNO_RPRT(TaskAsop, -1);
329     
330     //
331     // Determine stream index
332     //
333     zMS = pAstCfg->masterStr;
335     // Initialize as per parametrized phases:
336     //
337     //   In standard form these are:
338     //      - Malloc: Memory Allocation
339     //      - Config: Configuration Initialization
340     //      - AcpAlg: ACP Algorithm Initialization and Local Attachment
341     //      - Common: Common Memory Initialization
342     //      - AlgKey: Dec/Enc chain to Array Initialization
343     //      - Device: I/O Device Initialization
344     //      - Unused: (available)
345     //      - Unused: (available)
346     //
347     LINNO_RPRT(TaskAsop, -2);
348     for (i=0; i < lengthof(pP->fxns->initPhase); i++)
349     {
350         Int linno;
351         if (pP->fxns->initPhase[i])
352         {
353             linno = pP->fxns->initPhase[i](pP, pQ, pAsotCfg);
354             if (linno) 
355             {
356                 LINNO_RPRT(TaskAsop, linno);
357                 return;
358             }
359         }
360         else 
361         {
362             TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
363         }
364         TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
365         LINNO_RPRT(TaskAsop, -i-3);
366     }
367   
368     //
369     // End of Initialization -- display memory usage report.
370     //
371     if (pP->fxns->memStatusPrint)
372     {
373         pP->fxns->memStatusPrint("ASOT MEMSTAT REPORT",
374             HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, 
375             HEAP_INTERNAL1_SHM, HEAP_EXTERNAL_SHM, HEAP_EXTERNAL_NONCACHED_SHM);
376     }
378     //
379     // Main processing loop
380     //   
381     for (z=STREAM1; z < STREAMN; z++)
382     {
383         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
384     }
385     
386     errno = 0;                      // init error indicator -- no error
387     procSleep = 1;                  // init sleep flag -- sleep
388     procOutDevSel = 1;              // init device output selection flag -- perform output device selection
389     state = INIT_OUT_PROC_STATE;    // init state
390     for (;;)
391     {
392         loopCount++;
393         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
395         //
396         // Check forward (ASIT) error here, TBD
397         //
398         
399         // any error forces idling of output
400         if (errno) 
401         {
402             for (z=OUTPUT1; z < OUTPUTN; z++)
403             {
404                 if (pAstCfg->xOut[z].hTxSio)
405                 {
406                     SIO_idle(pAstCfg->xOut[z].hTxSio);
407                 }
408             }
409         
410             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
411             ERRNO_RPRT(TaskAsop, errno);
412         }        
413     
414         if (procSleep == 1)
415         {
416             TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
417             Task_sleep(1);
418         }
420         if (procOutDevSel == 1)
421         {
422             // select output devices
423             TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
424             errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
425             if (errno)
426             {
427                 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
429                 procSleep = 1;
430                 procOutDevSel = 1;
432                 continue;
433             }
435             // if no output selected skip remaining processing
436             errno = checkOutSel(pP, pAsotCfg, &outSel);
437             if (errno < 0)
438             {
439                 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
441                 procSleep = 1;
442                 procOutDevSel = 1;
444                 continue;
445             }
446             else if (!outSel)
447             {
448                 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
450                 procSleep = 1;
451                 procOutDevSel = 1;
452                 
453                 continue;
454             }
455         }
456         
457         switch (state)
458         {
459             case INIT_OUT_PROC_STATE:
460                 gAsopInitOutProcCnt++;
461                 Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
462                 
463                 //
464                 // Output Processing initialization.
465                 //
466                 errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
467                 if (errno < 0)
468                 {
469                     state = INIT_OUT_PROC_STATE;
470                     procSleep = 1;
471                     procOutDevSel = 1;
472                 }
473                 else
474                 {
475                     state = INITSYNC_DEC_RESET_STATE;
476                     procSleep = 0;
477                     procOutDevSel = 0;
478                 }
479             
480                 break;
481                 
482             case INITSYNC_DEC_RESET_STATE:
483                 gAsopInitSyncDecResetCnt++;
484                 Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
486                 //
487                 // Dec Reset Init-Sync.
488                 //  
489                 
490                 // Perform Dec Reset init-sync.
491                 // Latch Dec Reset AF.
492                 errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
493                 if (errno < 0)
494                 {
495                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
497                     // sync error -- start over
498                     state = INIT_OUT_PROC_STATE;
499                     procSleep = 1;
500                     procOutDevSel = 1;
501                 }
502                 else if (errno == ASOP_INITSYNC_NOTREADY)
503                 {
504                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
506                     // sync not ready -- try again
507                     state = INITSYNC_DEC_RESET_STATE;
508                     errno=0; // FL: temp hack
509                     procSleep = 1;
510                     procOutDevSel = 1;
511                 }
512                 else // errno==0
513                 {
514                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
516                     // sync'd -- move on
517                     state = INITSYNC_DEC_INFO1_STATE;
518                     procSleep = 0;
519                     procOutDevSel = 0;
520                 }
521                 
522                 break;
523             
524             case INITSYNC_DEC_INFO1_STATE:
525                 gAsopInitSyncDecInfo1Cnt++;
526                 Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
527                 
528                 //
529                 // Dec Info1 Init-Sync.
530                 //
532                 // Perform Dec Info1 init-sync.
533                 // Latch Dec Info1 AF.
534                 errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
535                 if (errno < 0)
536                 {
537                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
538                     
539                     // sync error -- start over
540                     state = INIT_OUT_PROC_STATE;
541                     procSleep = 1;
542                     procOutDevSel = 1;
543                 }
544                 else if (errno == ASOP_INITSYNC_NOTREADY)
545                 {
546                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
548                     // sync not ready -- try again
549                     state = INITSYNC_DEC_INFO1_STATE;
550                     errno=0; // FL: temp hack
551                     procSleep = 1;
552                     procOutDevSel = 0;
553                 }
554                 else // errno = 0
555                 {
556                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
558                     // sync'd -- move on
559                     state = INITSYNC_DEC_DECODE1_STATE;
560                     procSleep = 0;
561                     procOutDevSel = 0;
562                 }
563                 
564                 break;
565             
566             case INITSYNC_DEC_DECODE1_STATE:
567                 gAsopInitSyncDecDecode1Cnt++;
568                 Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
569                 
570                 //
571                 // Dec Info1 Init-Sync.
572                 //
574                 // Perform Dec Info1 init-sync.
575                 // Latch Dec Info1 AF.
576                 errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
577                 if (errno < 0)
578                 {
579                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
581                     // sync error -- start over
582                     state = INIT_OUT_PROC_STATE;
583                     procSleep = 1;
584                     procOutDevSel = 1;
585                 }
586                 else if (errno == ASOP_INITSYNC_NOTREADY)
587                 {
588                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
590                     // sync not ready -- try again
591                     state = INITSYNC_DEC_DECODE1_STATE;
592                     errno=0; // FL: temp hack
593                     procSleep = 1;
594                     procOutDevSel = 0;
595                 }
596                 else // errno = 0
597                 {
598                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
600                     // sync'd -- move on
601                     state = OUT_PROC_STATE;
602                     procSleep = 0;
603                     procOutDevSel = 0;
604                 }
605                 
606                 break;
607             
608             case INITSYNC_RESYNC_STATE:
609                 gAsopInitSyncResyncCnt++;
610                 Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
612                 //
613                 // Re-Sync.
614                 // Use stored AF info from init-sync.
615                 // This is done in case of local error.
616                 //
617                 
618                 // Perform Dec Info1 init-sync.
619                 errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf, 
620                     &decInfo1Af);
621                 if (errno < 0)
622                 {
623                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
625                     // sync error -- start over
626                     state = INIT_OUT_PROC_STATE;
627                     procSleep = 1;
628                     procOutDevSel = 1;
629                 }
630                 else
631                 {
632                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
634                     // re-sync'd -- move on
635                     state = OUT_PROC_STATE;
636                     procSleep = 0;
637                     procOutDevSel = 0;
638                 }
639                     
640                 break;
641             
642             case OUT_PROC_STATE:        
643                 gAsopOutProcCnt++;
644                 Log_info0("TaskAsop: state=OUT_PROC_STATE");
645                 
646                 //
647                 // Output Processing.
648                 //
650                 TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
651                 errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
652                 if (errno < 0)
653                 {
654                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
655                     
656                     //
657                     // Output Processing exit, due to error
658                     //
659                     
660                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
661                     if (errno == ASOP_DP_FORWARD_ERR)
662                     {
663                         // forward (ASIT) error -- start over
664                         state = INIT_OUT_PROC_STATE;
665                         procSleep = 1;
666                         procOutDevSel = 1;
667                     }
668                     else
669                     {
670                         // local (ASOT) error
671                         state = INITSYNC_RESYNC_STATE;    
672                         procSleep = 1;
673                         procOutDevSel = 0; // disallow device re-select if local error during output processing
674                     }        
675                 }
676                 else if (errno > 0)
677                 {
678                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
680                     //
681                     // Output Processing exit, not due to error
682                     //
684                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);                    
685                     if (errno == ASOP_DP_OUT_SIO_UPDATE)
686                     {
687                         // skip re-sync
688                         // resume output processing after new output selected
689                         state = OUT_PROC_STATE;
690                         procSleep = 1;
691                         procOutDevSel = 1;
692                     }
693                 }
694                 else
695                 {
696                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
698                     //
699                     // Output Processing exit, normal
700                     //
701                     
702                     TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
703                     
704                     // no error returned if CB drained 
705                     // (i.e. CB drained is normal behavior)
706                     state = INIT_OUT_PROC_STATE;
707                     procSleep = 1;
708                     procOutDevSel = 1;
709                 }
710                 
711                 break;
712             
713             default: // unknown state
714                 TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state);
715                 break;
716         }
717     } // End of main processing loop for (;;)
718     
719     //Log_info0("Exit taskAsopFxn()");
722 // -----------------------------------------------------------------------------
723 // AST Initialization Function - Memory Allocation
724 //
725 //   Name:      PAF_ASOT_initPhaseMalloc
726 //   Purpose:   Audio Stream Output Task Function for initialization of data pointers
727 //              by allocation of memory.
728 //   From:      audioStream1Task or equivalent
729 //   Uses:      See code.
730 //   States:    x
731 //   Return:    0 on success.
732 //              Source code line number on MEM_calloc failure.
733 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
734 //              * State information as per parent.
735 //              * Memory allocation errors.
736 //
738 Int
739 PAF_ASOT_initPhaseMalloc (
740     const PAF_ASOT_Params *pP, 
741     const PAF_ASOT_Patchs *pQ, 
742     PAF_ASOT_Config *pAsotCfg
745     PAF_AST_Config *pAstCfg;
746     Int as;                     /* Audio Stream Number (1, 2, etc.) */
747     Int zMS;
748     Error_Block    eb;
749     //Int i;
751     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
752     as = pAstCfg->as;
753     zMS = pAstCfg->masterStr;
755     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
757     // Initialize error block
758     Error_init(&eb); 
760     /* Stream memory */
761     if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
762     {
763         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
764         SW_BREAKPOINT;
765         return __LINE__;
766     }
767     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
768             STREAMN * sizeof (*pAstCfg->xStr),
769             HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
771     {
772         Int z;                          /* stream counter */
774         PAF_AudioFrame *fBuf;
776         if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
777         {
778             TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
779             SW_BREAKPOINT;
780             return __LINE__;
781         }
782         TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
783                 STREAMS * sizeof (*fBuf),
784                 HEAP_ID_INTERNAL, (IArg)fBuf);
786         for (z=STREAM1; z < STREAMN; z++)
787         {
788             pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
789             TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
790         }
791     }
793     /* Encode memory */
794     if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
795     {
796         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
797         SW_BREAKPOINT;
798         return __LINE__;
799     }
800     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
801             ENCODEN * sizeof (*pAstCfg->xEnc),
802             HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
804     /* Output memory */
805     if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb)))
806     {
807         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
808         SW_BREAKPOINT;
809         return __LINE__;
810     }
811     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.",
812             OUTPUTN * sizeof (*pAstCfg->xOut),
813             HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
815     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
816     return 0;
817 } //PAF_ASOT_initPhaseMalloc
819 // -----------------------------------------------------------------------------
820 // ASOT Initialization Function - Memory Initialization from Configuration
821 //
822 //   Name:      PAF_ASOT_initPhaseConfig
823 //   Purpose:   Audio Stream Output Task Function for initialization of data values
824 //              from parameters.
825 //   From:      audioStream1Task or equivalent
826 //   Uses:      See code.
827 //   States:    x
828 //   Return:    0 on success.
829 //              Other as per initFrame0 and initFrame1.
830 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
831 //              * State information as per parent.
832 //
833 Int
834 PAF_ASOT_initPhaseConfig(
835     const PAF_ASOT_Params *pP, 
836     const PAF_ASOT_Patchs *pQ, 
837     PAF_ASOT_Config *pAsotCfg
840     PAF_AST_Config *pAstCfg;
841     Int as;                     /* Audio Stream Number (1, 2, etc.) */
842     Int z;                      /* input/encode/stream/decode/output counter */
843     Int zMS;
845     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
846     as = pAstCfg->as;
847     zMS = pAstCfg->masterStr;
849     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
851     //
852     // Unspecified elements have been initialized to zero during alloc
853     //
855     for (z=STREAM1; z < STREAMN; z++) 
856     {
857         Int linno;
858         if (linno = pP->fxns->initFrame0(pP, pQ, pAsotCfg, z))
859         {
860             return linno;           
861         }
862         if (linno = pP->fxns->initFrame1(pP, pQ, pAsotCfg, z, -1))
863         {
864             return linno;
865         }
866     }
868     for (z=ENCODE1; z < ENCODEN; z++) 
869     {
870         Int zO = pP->outputsFromEncodes[z];
871         Int zS = pP->streamsFromEncodes[z];
872         pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
873         pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
874         pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
875         pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
876         pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
877         pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
878         pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
879         pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
880     }
882     for (z=OUTPUT1; z < OUTPUTN; z++)
883     {
884         pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
885     }
887     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
888     return 0;
889 } //PAF_ASOT_initPhaseConfig
891 // -----------------------------------------------------------------------------
892 // ASOT Initialization Function - ACP Algorithm Instantiation
893 //
894 //   Name:      PAF_ASOT_initPhaseAcpAlg
895 //   Purpose:   Audio Stream Input Task Function for initialization of ACP by
896 //              instantiation of the algorithm.
897 //   From:      audioStream1Task or equivalent
898 //   Uses:      See code.
899 //   States:    x
900 //   Return:    0 on success.
901 //              Source code line number on ACP Algorithm creation failure.
902 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
903 //              * State information as per parent.
904 //              * Memory allocation errors.
905 //
906 Int
907 PAF_ASOT_initPhaseAcpAlg(
908     const PAF_ASOT_Params *pP, 
909     const PAF_ASOT_Patchs *pQ, 
910     PAF_ASOT_Config *pAsotCfg
913     PAF_AST_Config *pAstCfg;
914     Int as;                     /* Audio Stream Number (1, 2, etc.) */
915     Int z;                      /* input/encode/stream/decode/output counter */
916     Int betaPrimeOffset;
917     ACP_Handle acp;
918     Int zMS;
919     Int zS, zX;
921     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
922     as = pAstCfg->as;
923     zMS = pAstCfg->masterStr;
925     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
927     ACP_MDS_init();
929     if (!(acp = (ACP_Handle )ACP_MDS_create(NULL))) 
930     {
931         TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation  failed", as+zMS);
932         return __LINE__;
933     }
934     pAsotCfg->acp = acp;
936     ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
937         ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
939     for (z=ENCODE1; z < ENCODEN; z++) 
940     {
941         zS = pP->streamsFromEncodes[z];
942         acp->fxns->attach(acp, ACP_SERIES_STD,
943             STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
944             (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
945         acp->fxns->attach(acp, ACP_SERIES_STD,
946             STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
947             (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
948         /* Ignore errors, not reported. */
949     }
951     for (z=OUTPUT1; z < OUTPUTN; z++) 
952     {
953         zS = z;
954         for (zX = ENCODE1; zX < ENCODEN; zX++) 
955         {
956             if (pP->outputsFromEncodes[zX] == z) 
957             {
958                 zS = pP->streamsFromEncodes[zX];
959                 break;
960             }
961         }
962         acp->fxns->attach(acp, ACP_SERIES_STD,
963             STD_BETA_OB + betaPrimeOffset * (as-1+zS),
964             (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
965         /* Ignore errors, not reported. */
966     }
968     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
970     return 0;
971 } //PAF_ASOT_initPhaseAcpAlg
973 // -----------------------------------------------------------------------------
974 // ASOT Initialization Function - Common Memory
975 //
976 //   Name:      PAF_ASOT_initPhaseCommon
977 //   Purpose:   Audio Stream Output Task Function for allocation of common memory.
978 //   From:      audioStream1Task or equivalent
979 //   Uses:      See code.
980 //   States:    x
981 //   Return:    0 on success.
982 //              Source code line number on PAF_ALG_alloc failure.
983 //              Source code line number on PAF_ALG_mallocMemory failure.
984 //              Source code line number on Decode Chain initialization failure.
985 //              Source code line number on ASP Chain initialization failure.
986 //              Source code line number on Encode Chain initialization failure.
987 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
988 //              * State information as per parent.
989 //              * Memory allocation errors.
990 //
991 Int
992 PAF_ASOT_initPhaseCommon(
993     const PAF_ASOT_Params *pP, 
994     const PAF_ASOT_Patchs *pQ, 
995     PAF_ASOT_Config *pAsotCfg
998     PAF_AST_Config *pAstCfg;
999     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1000     Int z;                      /* stream counter */
1001     Int g;                      /* gear */
1002     ACP_Handle acp;
1003     PAF_IALG_Config pafAlgConfig;
1004     IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
1005    
1006     acp = pAsotCfg->acp;
1007     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1008     as = pAstCfg->as;
1010     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
1012     //
1013     // Determine memory needs and instantiate algorithms across audio streams
1014     //
1015     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
1016     PAF_ALG_setup(&pafAlgConfig, 
1017         HEAP_ID_INTERNAL,                 HEAP_INTERNAL, 
1018         HEAP_ID_INTERNAL1,                HEAP_INTERNAL1, 
1019         HEAP_ID_EXTERNAL,                 HEAP_EXTERNAL, 
1020         HEAP_ID_INTERNAL1_SHM,            HEAP_INTERNAL1_SHM, 
1021         HEAP_ID_EXTERNAL_SHM,             HEAP_EXTERNAL_SHM, 
1022         HEAP_ID_EXTERNAL_NONCACHED_SHM,   HEAP_EXTERNAL_NONCACHED_SHM,
1023         HEAP_CLEAR);
1025     if (pP->fxns->headerPrint)
1026     {
1027         pP->fxns->headerPrint();        
1028     }
1030     for (z = STREAM1; z < STREAMN; z++) 
1031     {
1032         //Int zD, zE, zX;
1033         Int zE, zX;
1035         TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
1037         //
1038         // Determine common memory needs for:
1039         //  (1) ASP Algorithms
1040         //  (2) Encode Algorithms
1041         //  (3) Logical Output drivers
1042         //
1043         PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
1045         zE = -1;
1046         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1047         {
1048             if (pP->streamsFromEncodes[zX] == z) 
1049             {
1050                 zE = zX;
1051                 break;
1052             }
1053         }
1055         TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
1056         if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z])) 
1057         {
1058             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
1059             TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
1060             SW_BREAKPOINT;
1061             return __LINE__;
1062         }
1063         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1064         if (pP->fxns->allocPrint)
1065         {
1066             pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
1067         }
1069         if (zE >= 0) 
1070         {
1071             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
1072             if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z])) 
1073             {
1074                 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
1075                 SW_BREAKPOINT;
1076                 return __LINE__;
1077             }
1078             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1079             if (pP->fxns->allocPrint)
1080             {
1081                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
1082             }
1083         }
1085         //
1086         // Determine common memory needs of Logical IO drivers
1087         //
1089         if (OUTPUT1 <= z && z < OUTPUTN)
1090         {
1091             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
1092             if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
1093             {
1094                 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
1095                 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
1096                 SW_BREAKPOINT;
1097                 return __LINE__;
1098             }
1099             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1100             if (pP->fxns->allocPrint)
1101             {
1102                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
1103             }
1104         }
1105     }
1106     {
1107         // Changes made to share scratch between zones
1108         // Assume maximum 3 zones and scratch common memory is at offset 0;
1109         int max=0;
1110         for (z=STREAM1; z<STREAMN; z++)
1111         {
1112             if (max < common[z][0].size)
1113             {
1114                 max = common[z][0].size;
1115             }
1116         }
1117         common[STREAM1][0].size=max;
1118         for (z=STREAM1+1; z<STREAMN; z++)
1119         {
1120             common[z][0].size = 0;            
1121         }
1122     }
1123         
1124     //
1125     // Allocate common memory for:
1126     //  (1) ASP Algorithms
1127     //  (2) Encode Algorithms
1128     //  (3) Logical Output drivers
1129     //
1130     for (z = STREAM1; z < STREAMN; z++) 
1131     {
1132         //Int zD, zE, zX;
1133         Int zE, zX;
1135         TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
1136         if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig)) 
1137         {
1138             TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
1139             TRACE_TERSE3("AS%d: z: %d.  Size 0x%x", as+z, z, common[z][0].size);
1140             SW_BREAKPOINT;
1141             return __LINE__;
1142         }
1143         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1144         // share zone0 scratch with all zones 
1145         common[z][0].base = common[0][0].base;
1146         if (pP->fxns->commonPrint)
1147         {
1148             pP->fxns->commonPrint(common[z], &pafAlgConfig);
1149         }
1151         zE = -1;
1152         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1153         {
1154             if (pP->streamsFromEncodes[zX] == z) 
1155             {
1156                 zE = zX;
1157                 break;
1158             }
1159         }
1161         pAstCfg->xStr[z].aspChain[0] = NULL;
1162         for (g=0; g < GEARS; g++) 
1163         {
1164             PAF_ASP_Chain *chain;
1165             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
1166             chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
1167                 HEAP_INTERNAL, as+z, acp, &trace,
1168                 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
1169             if (!chain) 
1170             {
1171                 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
1172                 return __LINE__;
1173             }
1174             else
1175             {
1176                 pAstCfg->xStr[z].aspChain[g] = chain;
1177             }
1178         }
1180         if (zE >= 0) 
1181         {
1182             PAF_ASP_Chain *chain;
1183             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
1184             chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
1185                 HEAP_INTERNAL, as+z, acp, &trace,
1186                 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
1187             if (!chain) 
1188             {
1189                 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
1190                 return __LINE__;
1191             }
1192         }
1194         //
1195         // Allocate non-common memories for Logical IO drivers
1196         //    Since these structures are used at run-time we allocate from external memory
1197         if (OUTPUT1 <= z && z < OUTPUTN) 
1198         {
1199             PAF_ASP_Chain *chain;
1200             TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
1201                            as+z, z);
1202             chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
1203                         HEAP_EXTERNAL, as+z, acp, &trace,
1204                         outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
1205             if (!chain) 
1206             {
1207                 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
1208                 return __LINE__;
1209             }
1210         }
1211     }
1212     TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
1214     return 0;
1215 } //PAF_ASOT_initPhaseCommon
1217 // -----------------------------------------------------------------------------
1218 // ASOT Initialization Function - Algorithm Keys
1219 //
1220 //   Name:      PAF_ASOT_initPhaseAlgKey
1221 //   Purpose:   Audio Stream Output Task Function for initialization of data values
1222 //              from parameters for Algorithm Keys.
1223 //   From:      audioStream1Task or equivalent
1224 //   Uses:      See code.
1225 //   States:    x
1226 //   Return:    0.
1227 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1228 //              * State information as per parent.
1229 //
1230 // .............................................................................
1231 Int
1232 PAF_ASOT_initPhaseAlgKey(
1233     const PAF_ASOT_Params *pP, 
1234     const PAF_ASOT_Patchs *pQ, 
1235     PAF_ASOT_Config *pAsotCfg
1238     PAF_AST_Config *pAstCfg;
1239     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1240     Int z;                      /* decode/encode counter */
1241     Int s;                      /* key number */
1242     PAF_ASP_Link *that;
1244     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1245     as = pAstCfg->as;
1246     (void)as; // clear compiler warning in case not used with tracing disabled
1248     TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
1250     for (z=ENCODE1; z < ENCODEN; z++) 
1251     {
1252         for (s=0; s < pP->pEncAlgKey->length; s++) 
1253         {
1254             if ((pP->pEncAlgKey->code[s].full != 0) && 
1255                 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
1256             {
1257                 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
1258             }
1259             /* Cast in interface, for now --Kurt */
1260             else
1261             {
1262                 pAstCfg->xEnc[z].encAlg[s] = NULL;                
1263             }
1264         }
1265     }
1267     return 0;
1268 } //PAF_ASOT_initPhaseAlgKey
1270 // -----------------------------------------------------------------------------
1271 // ASOT Initialization Function - I/O Devices
1272 //
1273 //   Name:      PAF_ASOT_initPhaseDevice
1274 //   Purpose:   Audio Stream Output Task Function for initialization of I/O Devices.
1275 //   From:      audioStream1Task or equivalent
1276 //   Uses:      See code.
1277 //   States:    x
1278 //   Return:    0 on success.
1279 //              Source code line number on device allocation failure.
1280 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1281 //              * State information as per parent.
1282 //              * Memory allocation errors.
1283 //
1284 Int
1285 PAF_ASOT_initPhaseDevice(
1286     const PAF_ASOT_Params *pP, 
1287     const PAF_ASOT_Patchs *pQ, 
1288     PAF_ASOT_Config *pAsotCfg
1291     PAF_AST_Config *pAstCfg;
1292     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1293     Int z;                      /* input/output counter */
1294     PAF_SIO_IALG_Obj    *pObj;
1295     PAF_SIO_IALG_Config *pAlgConfig;
1296     PAF_IALG_Config pafAlgConfig;
1298     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1299     as = pAstCfg->as;
1300     (void)as; // clear compiler warning in case not used with tracing disabled
1302     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
1304     if(pP->fxns->bufMemPrint)
1305     {
1306         PAF_ALG_setup (&pafAlgConfig, 
1307             HEAP_ID_INTERNAL,               HEAP_INTERNAL, 
1308             HEAP_ID_INTERNAL1,              HEAP_INTERNAL1,
1309             HEAP_ID_EXTERNAL,               HEAP_EXTERNAL,
1310             HEAP_ID_INTERNAL1_SHM,          HEAP_INTERNAL1_SHM,
1311             HEAP_ID_EXTERNAL_SHM,           HEAP_EXTERNAL_SHM,
1312             HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
1313             HEAP_CLEAR);
1314         TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
1315     }
1316     
1317     for (z=OUTPUT1; z < OUTPUTN; z++) 
1318     {
1319         PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
1321         pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
1322         pAlgConfig = &pObj->config;
1324         pAstCfg->xOut[z].hTxSio = NULL;
1325         pConfig->base.pVoid     = pAlgConfig->pMemRec[0].base;
1326         pConfig->pntr.pVoid     = pAlgConfig->pMemRec[0].base;
1327         pConfig->head.pVoid     = pAlgConfig->pMemRec[0].base;
1328         pConfig->allocation     = pAlgConfig->pMemRec[0].size;
1329         pConfig->sizeofElement  = 3;
1330         pConfig->precision      = 24;
1331         if(pP->fxns->bufMemPrint)
1332         {
1333             pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
1334         }
1335     }
1336     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
1338     return 0;
1339 } //PAF_ASOT_initPhaseDevice
1341 // -----------------------------------------------------------------------------
1342 // ASOT Initialization Function Helper - Initialization of Audio Frame
1343 //
1344 //   Name:      PAF_ASOT_initFrame0
1345 //   Purpose:   Audio Stream Output Task Function for initialization of the Audio
1346 //              Frame(s) by memory allocation and loading of data pointers
1347 //              and values.
1348 //   From:      AST Parameter Function -> decodeInfo
1349 //   Uses:      See code.
1350 //   States:    x
1351 //   Return:    0 on success.
1352 //              Source code line number on MEM_calloc failure.
1353 //              Source code line number on unsupported option.
1354 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1355 //              * Memory allocation errors.
1356 //              * Unsupported option errors.
1357 //
1359 // MID 314
1360 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
1361 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
1363 Int
1364 PAF_ASOT_initFrame0(
1365     const PAF_ASOT_Params *pP, 
1366     const PAF_ASOT_Patchs *pQ, 
1367     PAF_ASOT_Config *pAsotCfg, 
1368     Int z
1371     PAF_AST_Config *pAstCfg;
1372     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1373     Int ch;
1374     //Int aLen;
1375     Int aLen_int=0,aLen_ext=0;
1376     Int aSize = sizeof(PAF_AudioData);
1377     Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
1378     Int maxFrameLength = pP->maxFramelength;
1379     Int zX;
1380     PAF_AudioData *aBuf_int=NULL;
1381     PAF_AudioData *aBuf_ext=NULL;
1382     XDAS_UInt8 *metadataBuf;
1383     char i;
1384     Error_Block    eb;
1386     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1387     as = pAstCfg->as;
1389     // Initialize error block
1390     Error_init(&eb); 
1392     // Compute maximum framelength (needed for ARC support)
1393     maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
1394     //aLen = numchan[z] * maxFrameLength;
1395     for (i=0; i < numchan[z]; i++)
1396     {
1397         if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1398         {
1399             aLen_int += maxFrameLength;
1400         }
1401         else
1402         {
1403             aLen_ext += maxFrameLength;
1404         }
1405     }
1407     //
1408     // Initialize audio frame elements directly
1409     //
1410     pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
1411     pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
1412 ///    pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
1413     pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
1414     pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
1415     pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
1416     pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1418     //
1419     // Allocate memory for and initialize pointers to audio data buffers
1420     //
1421     //   The NUMCHANMASK is used to identify the channels for which data
1422     //   buffers can be allocated. Using this mask and switch statement
1423     //   rather than some other construct allows efficient code generation,
1424     //   providing just the code necessary (with significant savings).
1425     //
1426     if (pP->fxns->bufMemPrint)
1427     {
1428         pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1429         pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1430     }
1432     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1433     
1434     if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1435     {
1436         if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1437         {
1438             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1439             TRACE_TERSE2("  maxFrameLength: %d.  aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1440             SW_BREAKPOINT;
1441             return __LINE__;
1442         }
1443     }
1444         
1445     if (aLen_ext*aSize!=0)
1446     {
1447         if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset
1448         {
1449             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1450             TRACE_TERSE2("  maxFrameLength: %d.  aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1451             SW_BREAKPOINT;
1452             return __LINE__;
1453         }
1454     }
1455     
1456     TRACE_TERSE3("  maxFrameLength: %d.  aLen_int*aSize: %d.  aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1457     TRACE_TERSE3("  maxFrameLength: %d.  aLen_ext*aSize: %d.  aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1459     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1460     if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1461     {
1462         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1463         TRACE_TERSE1("  bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1464         SW_BREAKPOINT;
1465         return __LINE__;
1466     }
1468     {
1469         Int i;
1471 #pragma UNROLL(1)
1472         for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1473         {
1474             pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1475         }
1476     }
1478     // MID 314
1479     if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1)) 
1480     {
1481         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1482         return __LINE__;
1483     }
1484     else 
1485     {
1486         Int j = 0;
1487         Int k = 0;
1488         TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1489         for(i=0;i<numchan[z];i++)
1490         {
1491             char chan = AFChanPtrMap[numchan[z]][i];
1492             if(chan != -1)
1493             {
1494                 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1495                 {
1496                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1497                     j++;
1498                 }
1499                 else
1500                 {        
1501                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1502                     k++;
1503                 }    
1504                 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1505                 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1506             }
1507         }
1508     }
1510     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1511     {
1512         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1513         {
1514             pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1515         }
1516     }
1518     //
1519     // Initialize meta data elements
1520     //
1521     pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1522     pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1523     pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1524     pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1525     pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1526     for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1527     {
1528         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1529         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1530         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1531     }
1533     //
1534     // Initialize decoder elements directly
1535     //
1537     for (zX = DECODE1; zX < DECODEN; zX++) 
1538     {
1539         if (pP->streamsFromDecodes[zX] == z) 
1540         {
1541 #ifdef NOAUDIOSHARE
1542             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1543             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1544 #else /* NOAUDIOSHARE */
1545             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1546             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1547 #endif /* NOAUDIOSHARE */
1548         }
1549     }
1551     return 0;
1552 } //PAF_ASOT_initFrame0
1554 // -----------------------------------------------------------------------------
1555 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1556 // AST Decoding Function              - Reinitialization of Audio Frame
1557 //
1558 //   Name:      PAF_ASOT_initFrame1
1559 //   Purpose:   Audio Stream Task Function for initialization or reinitiali-
1560 //              zation of the Audio Frame(s) by loading of data values of a
1561 //              time-varying nature.
1562 //   From:      audioStream1Task or equivalent
1563 //              AST Parameter Function -> decodeInfo
1564 //              AST Parameter Function -> decodeDecode
1565 //   Uses:      See code.
1566 //   States:    x
1567 //   Return:    0.
1568 //   Trace:     None.
1569 //
1570 Int
1571 PAF_ASOT_initFrame1(
1572     const PAF_ASOT_Params *pP, 
1573     const PAF_ASOT_Patchs *pQ, 
1574     PAF_ASOT_Config *pAsotCfg, 
1575     Int z, 
1576     Int apply
1579     PAF_AST_Config *pAstCfg;
1581     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1583     //
1584     // Reinitialize audio frame elements:
1585     //
1586     //   Channel Configurations during sys init                 = Unknown
1587     //      "          "        during info or decode           = None
1588     //
1589     //   Sample Rate / Count    during sys init, info or decode = Unknown / 0
1590     //
1592     if (apply < 0) 
1593     {
1594         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1595         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1596     }
1597     else 
1598     {
1599         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1600         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1601     }
1603     if (apply < 1) 
1604     {
1605         pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1606         pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1607     }
1609     return 0;
1610 } //PAF_ASOT_initFrame1
1612 // -----------------------------------------------------------------------------
1613 // ASOT Selection Function - Output Device Selection
1614 //
1615 //   Name:      PAF_ASOT_selectDevices
1616 //   Purpose:   Audio Stream Output Task Function for selecting the devices used
1617 //              for output.
1618 //   From:      audioStream1Task or equivalent
1619 //   Uses:      See code.
1620 //   States:    x
1621 //   Return:    Error number in standard form (0 on success).
1622 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1623 //              * State information as per parent.
1624 //
1625 Int
1626 PAF_ASOT_selectDevices(
1627     const PAF_ASOT_Params *pP, 
1628     const PAF_ASOT_Patchs *pQ, 
1629     PAF_ASOT_Config *pAsotCfg
1632     PAF_AST_Config *pAstCfg;
1633     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1634     Int z;                      /* input/output counter */
1635     Int errno = 0;              /* error number */
1636     Int errme;                  /* error number, local */
1637     Int device;
1639     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1640     as = pAstCfg->as;
1641     (void)as;  // clear compiler warning in case not used with tracing disabled
1643     // Select output devices
1644     for (z=OUTPUT1; z < OUTPUTN; z++) 
1645     {
1646         if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0) 
1647         {
1648             TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1650             /* check for valid index into device array */
1651             if (device >= pQ->devout->n)
1652             {
1653                 device = 0; /* treat as device None */
1654             }
1656             errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT, 
1657                 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1658             if (errme)
1659             {
1660                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1661                 if (!errno)
1662                 {
1663                     errno = ASPERR_DEVOUT + errme;
1664                 }
1665                 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1666             }
1667             else 
1668             {
1669                 Int zE;
1671                 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1672                 // register outBufStatus and encodeStatus pointers with output devices
1673                 // This enables proper IEC encapsulation.
1674                 if (pAstCfg->xOut[z].hTxSio) 
1675                 {
1676                     // set max # of output buffers (use override if necessary)
1677                     if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1678                     {
1679                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1680                             (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1681                     }
1682                     else
1683                     {
1684                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1685                             (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1686                     }
1688                     // register PAF_SIO_IALG object address
1689                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1690                         (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1691                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR, 
1692                         (Arg)&pAstCfg->xOut[z].outBufStatus);
1693                     for (zE=ENCODE1; zE < ENCODEN; zE++) 
1694                     {
1695                         if (pP->outputsFromEncodes[zE] == z) 
1696                         {
1697                             SIO_ctrl(pAstCfg->xOut[z].hTxSio, 
1698                                 PAF_SIO_CONTROL_SET_ENCSTATUSADDR, 
1699                                 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1700                             break;
1701                         }
1702                     }
1703                 }
1704             }
1705         }
1707 /* No need to start-clocks here, since only selecting the device. */
1708 #if 0
1709         // if device selected and valid then enable stat tracking if
1710         // required and start clocking
1711         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) 
1712         {
1713             TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1714             errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1715             if (errme)
1716             {
1717                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1718                 SIO_idle(pAstCfg->xOut[z].hTxSio);
1719                 if (!errno)
1720                 {
1721                     errno = ASPERR_DEVOUT + errme;
1722                 }
1723             }
1724         }
1725 #endif
1726     }
1728     return errno;
1729 } //PAF_ASOT_selectDevices
1732 // -----------------------------------------------------------------------------
1733 // ASOT Processing Function - Decode Processing
1734 //
1735 //   Name:      PAF_ASOT_decodeProcessing
1736 //   Purpose:   Audio Stream Output Task Function for processing audio data.
1737 //
1738 Int
1739 PAF_ASOT_decodeProcessing(
1740     const PAF_ASOT_Params *pP, 
1741     const PAF_ASOT_Patchs *pQ, 
1742     PAF_ASOT_Config *pAsotCfg 
1745     PAF_AST_Config *pAstCfg;
1746     Int errno;                          /* error number */
1747     Int getVal;
1748     enum { INIT, STREAM, ENCODE, FINAL, QUIT, OUT_SIO_UPDATE } state;
1749     state = INIT;
1750     errno = 0; /* error number */
1751     Int frame; // (***) FL: formerly -- decoder input frame count
1752     Int block; // decoder output block count / input frame
1753     Int outSioUpdate;
1754     
1755     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1757     for (;;) 
1758     {
1759         //
1760         // Check forward (ASIT) error here, TBD
1761         //
1762         
1763         
1764         // Check if any change in output SIO, e.g. from Output shortcut.
1765         // Changes will break FSM and allow Output reconfiguration.
1766         errno = checkOutSio(pP, pAsotCfg, &outSioUpdate);
1767         if (errno < 0)
1768         {
1769             TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1770             break;
1771         }
1772         else if (outSioUpdate)
1773         {
1774             TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1775             state = OUT_SIO_UPDATE;
1776         }
1777         
1778         // Process commands (encode)
1779         getVal = pP->fxns->encodeCommand(pP, pQ, pAsotCfg);
1780         if (getVal) 
1781         {
1782             /* ignore */;
1783         }
1785         // Process state (decode)
1786         switch (state) 
1787         {
1788             case INIT: // initial state
1789                 gAsopInitCnt++;
1790                 Log_info0("TaskAsop: state=INIT");
1791             
1792                 frame = 0;
1793                 block = 0;
1795 #if 0 // FL: moved to PAF_ASOT_initOutProc()
1796                 // Reset audio frame pointers to original values
1797                 // (may be needed if error occurred).
1798                 resetAfPointers(pP, pAstCfg->xStr);
1799                 // Reset audio frame meta data elements
1800                 resetAfMetadata(pP, pAstCfg->xStr);
1801 #endif
1803                 errno = pP->fxns->decodeInit(pP, pQ, pAsotCfg);
1804                 if (errno)
1805                 {
1806                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInit", errno);
1807                     errno = ASOP_DP_DECINIT_ERR;
1808                     break;
1809                 }
1810                 
1811                 //
1812                 // Setup output: setCheckRateX, start output
1813                 //
1814                 // Establish secondary timing
1815                 errno = pP->fxns->decodeInfo1(pP, pQ, pAsotCfg, frame, block);
1816                 if (errno)
1817                 {
1818                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInfo1", errno);
1819                     break;
1820                 }
1821                 
1822                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");                
1823                 state = STREAM;
1824                 continue;
1825                 
1826             case STREAM: // stream state
1827                 gAsopStreamCnt++;
1828                 Log_info0("TaskAsop: state=STREAM");
1830                 errno = pP->fxns->decodeStream(pP, pQ, pAsotCfg, frame, block);
1831                 if (errno)
1832                 {
1833                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM.  decodeStream err 0x%x", errno);
1834                     errno = ASOP_DP_DECSTREAM_ERR;
1835                     break;
1836                 }
1838                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1839                 state = ENCODE;
1840                 continue;
1841                 
1842             case ENCODE: // encode state
1843                 gAsopEncodeCnt++;
1844                 Log_info0("TaskAsop: state=ENCODE");
1846                 errno = pP->fxns->decodeEncode(pP, pQ, pAsotCfg, frame, block);
1847                 if (errno)
1848                 {
1849                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE.  decodeEncode err 0x%x", errno);
1850                     errno = ASOP_DP_DECENC_ERR;
1851                     break;
1852                 }
1853                 
1854                 // Measure cycles in output processing loop.
1855                 // Only measures cycles spent in loop.
1856                 pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS);
1857                 gNumPfpAsot1--;
1858                 pfpBegin(PFP_ID_ASOT_1, pAsotCfg->taskHandle);
1859                 gNumPfpAsot1++;
1860                 
1861                 // (***) FL: do we need this? 
1862                 //       AF pointers come from CB read, any resets occur in Decoder AF.
1863                 //
1864                 // Reset audio frame pointers to original values
1865                 // (may have been adjusted by ARC or the like).
1866                 resetAfPointers(pP, pAstCfg->xStr);
1868                 // (***) FL: update output (setCheckRateX)
1869                 //           Contained in INFO2 in combined FSM.
1870                 errno = pP->fxns->decodeInfo2(pP, pQ, pAsotCfg, frame, block);
1871                 if (errno)
1872                 {
1873                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1874                     errno = ASOP_DP_DECINFO2_ERR;
1875                     break;
1876                 }
1878                 block++;
1879                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1880                 state = FINAL;
1881                 continue;
1882                 
1883             case FINAL:
1884                 gAsopFinalCnt++;
1885                 Log_info0("TaskAsop: state=FINAL");
1886                 
1887                 //
1888                 // (***) FL: this needs to be fixed.
1889                 //       (1) Only require selected Output to be in this FSM
1890                 //           => Dec Status checks aren't valid, 
1891                 //              will probably always exit FSM if only Output running
1892                 //       (2) Checking Dec Status info asych to input events (maybe ok)
1893                 //
1894                 // Check for final frame, and if indicated:
1895                 // - Update audio flag to cause output buffer flush rather than
1896                 //   the default truncate in "complete" processing.
1897                 // - Exit state machine to "complete" processing.
1898 #if 0
1899                 if (pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block)) 
1900                 {
1901                     for (z=OUTPUT1; z < OUTPUTN; z++)
1902                     {
1903                         if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1904                         {
1905                             TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1906                             pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1907                         }
1908                     }
1909                     break;
1910                 }
1911 #endif
1912                 errno = pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block);
1913                 if (errno < 0)
1914                 {
1915                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL break. errno 0x%x", errno);
1916                     errno = ASOP_DP_DECFINALTEST_ERR;
1917                     break;
1918                 }
1919                 else if (errno == ASOP_DP_CB_DRAINED)
1920                 {
1921                     // EOS, exit normally
1922                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL normal exit. errno 0x%x", errno);
1923                     errno = ASOP_DP_SOK;
1924                     break;
1925                 }
1927                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1928                 state = STREAM;
1929                 continue;
1930                 
1931             case OUT_SIO_UPDATE:
1932                 gAsopOutSioUpdateCnt++;
1933                 Log_info0("TaskAsop: state=OUT_SIO_UPDATE");
1935                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: OUT_SIO_UPDATE");
1936                 errno = ASOP_DP_OUT_SIO_UPDATE;
1937                 break;
1938                 
1939             case QUIT:
1940                 gAsopQuitCnt++;
1941                 Log_info0("TaskAsop: state=QUIT");
1943                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1944                 errno = ASPERR_QUIT;
1945                 break;
1947             default: // unknown state
1948                 // Unknown:
1949                 // - Set error number registers.
1950                 // - Exit state machine to "complete" processing.
1952                 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1953                 errno = ASPERR_UNKNOWNSTATE;
1954                 break;
1956         }  // End of switch (state).
1957         
1958         TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1959         if (pP->fxns->decodeComplete(pP, pQ, pAsotCfg, NULL, frame, block))
1960         {
1961             /* ignored? */;
1962         }
1963         
1964         //pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
1965         //gNumPfpAsot1--;
1966         
1967         //return errno;
1968         break;        
1969     } // End of for (;;)
1970         
1971     pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
1972     gNumPfpAsot1--;
1973         
1974     return errno;
1977 // -----------------------------------------------------------------------------
1978 // ASOT Decoding Function - Encode Command Processing
1979 //
1980 //   Name:      PAF_ASOT_encodeCommand
1981 //   Purpose:   Decoding Function for processing Encode Commands.
1982 //   From:      AST Parameter Function -> decodeProcessing
1983 //   Uses:      See code.
1984 //   States:    x
1985 //   Return:    0.
1986 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1987 //              * Command execution.
1988 //              * SIO control errors.
1989 //              * Error number macros.
1990 //
1991 Int
1992 PAF_ASOT_encodeCommand(
1993     const PAF_ASOT_Params *pP, 
1994     const PAF_ASOT_Patchs *pQ, 
1995     PAF_ASOT_Config *pAsotCfg
1998     PAF_AST_Config *pAstCfg;
1999     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2000     Int z;                      /* encode counter */
2001     Int errno = 0;              /* error number */
2002     Int zO, zS;
2005     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2006     as = pAstCfg->as;
2008     for (z=ENCODE1; z < ENCODEN; z++) 
2009     {
2010         zO = pP->outputsFromEncodes[z];
2011         zS = pP->streamsFromEncodes[z];
2012         if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
2013         {
2014             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
2015             {
2016                 case 0: // command none - process
2017                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2018                     break;
2019                 case 1: // mute command
2020                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
2021                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
2022                         && pAstCfg->xOut[zO].hTxSio
2023                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
2024                     {
2025                         errno = (errno & 0xff) | ASPERR_MUTE;
2026                         /* convert to sensical errno */
2027                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
2028                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
2029                     }
2030                     else 
2031                     {
2032                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
2033                     }
2034                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2035                     break;
2036                 case 2: // unmute command
2037                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
2038                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
2039                         && pAstCfg->xOut[zO].hTxSio
2040                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
2041                     {
2042                         errno = (errno & 0xff) | ASPERR_MUTE;
2043                         /* convert to sensical errno */
2044                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
2045                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
2046                     }
2047                     else 
2048                     {
2049                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
2050                     }
2051                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
2052                     break;
2053                 default: // command unknown - ignore
2054                     break;
2055             }
2056         }
2057     }
2059     ERRNO_RPRT (TaskAsop, errno);
2061     return 0;
2062 } //PAF_ASOT_encodeCommand
2064 //debug -- allow dynamic config
2065 Int16 gStrFrameLen=DEF_STR_FRAME_LEN; // stream frame length (PCM samples)
2067 //   Purpose:   Decoding Function for reinitializing the decoding process.
2068 Int
2069 PAF_ASOT_decodeInit(
2070     const PAF_ASOT_Params *pP, 
2071     const PAF_ASOT_Patchs *pQ, 
2072     PAF_ASOT_Config *pAsotCfg
2075     //PAF_AST_Config *pAstCfg;
2076     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2077     //Int as;                             /* Audio Stream Number (1, 2, etc.) */
2078     Int z;                              /* decode/encode counter */
2079     Int errno;                          /* error number */
2080     //Int zO, zS;
2082     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2083     //as = pAstCfg->as;
2085     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2087     for (z=DECODE1; z < DECODEN; z++)
2088     {
2089         //  FRAMELENGTH: pP->frameLength.
2090         //    Formerly ASIT, now ASOT but same value (PAF_SYS_FRAMELENGTH).
2091         //
2093         // Initialize decoder output circular buffer for stream reads
2094         //errno = cbInitStreamRead(pCbCtl, z, FRAMELENGTH); // use pP->frameLength from ASOT params
2095         errno = cbInitStreamRead(pCbCtl, z, gStrFrameLen);
2096         if (errno)
2097         {
2098             TRACE_TERSE1("PAF_ASOT_decodeInit:cbInitStreamRead() error=%d", errno);
2099             SW_BREAKPOINT; // debug
2100             return errno;
2101         }
2102         
2103         // Start decoder output circular buffer reads
2104         errno = cbReadStart(pCbCtl, z);
2105         if (errno)
2106         {
2107             TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
2108             SW_BREAKPOINT; // debug
2109             return errno;
2110         }
2111         
2112         gCbReadAfErr=0;         // reset read circular buffer error count
2113         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
2114         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
2115         gMasterCbResetCnt=0;    // reset master circular buffer reset count
2117         // FL: debug, log circular buffer control variables
2118         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
2119     }
2120     
2121 #if 0 // moved to PAF_ASOT_outputReset()
2122     // TODO: move this to start of this function so that it doesn't affect IO timing
2123     for (z=ENCODE1; z < ENCODEN; z++) 
2124     {
2125         zO = pP->outputsFromEncodes[z];
2126         zS = pP->streamsFromEncodes[z];
2127         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2128         {
2129             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2130             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2131             ENC_Handle enc = (ENC_Handle )encAlg;
2132             TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
2133             if (encAlg->fxns->algActivate)
2134             {
2135                 encAlg->fxns->algActivate (encAlg);
2136             }
2137             if (enc->fxns->reset)
2138             {
2139                 errno = enc->fxns->reset(enc, NULL, 
2140                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus);
2141                 if (errno)
2142                 {
2143                     return errno;
2144                 }
2145             }
2146         }
2147     }
2148 #endif
2149     
2150     return 0;
2153 // -----------------------------------------------------------------------------
2154 // ASOT Decoding Function - Info Processing, Initial
2155 //
2156 //   Name:      PAF_ASOT_decodeInfo1
2157 //   Purpose:   Decoding Function for processing information in a manner that
2158 //              is unique to initial frames of input data.
2159 //   From:      AST Parameter Function -> decodeProcessing
2160 //   Uses:      See code.
2161 //   States:    x
2162 //   Return:    Error number in standard or SIO form (0 on success).
2163 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2164 //              * State information as per parent.
2165 //
2166 Int
2167 PAF_ASOT_decodeInfo1(
2168     const PAF_ASOT_Params *pP, 
2169     const PAF_ASOT_Patchs *pQ, 
2170     PAF_ASOT_Config *pAsotCfg, 
2171     Int frame, 
2172     Int block
2175     //PAF_AST_Config *pAstCfg;
2176     //Int z;                              /* decode/encode counter */
2177     Int errno;                          /* error number */
2179 #if 0 // moved to PAF_ASOT_outputInfo1()
2180     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2182     // run the chain of ASP's on the stream.
2183     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
2184     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2185         PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);
2186     if (errno)
2187     {
2188         TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
2189         return errno;
2190     }
2192     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
2193     for (z=ENCODE1; z < ENCODEN; z++) 
2194     {
2195         Int zO = pP->outputsFromEncodes[z];
2196         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2197         {
2198             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2199             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2200             ENC_Handle enc = (ENC_Handle )encAlg;
2201             
2202             if (enc->fxns->info)
2203             {
2204                 errno = enc->fxns->info(enc, NULL,
2205                     &pAstCfg->xEnc[z].encodeControl, 
2206                     &pAstCfg->xEnc[z].encodeStatus);
2207                 if (errno)
2208                 {
2209                     TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
2210                     return errno;
2211                 }
2212             }
2213         }
2214     }
2215 #endif    
2217     errno = pP->fxns->setCheckRateX(pP, pQ, pAsotCfg, 0);
2218     if (errno)
2219     {
2220         // ignore if rateX has changed since we haven't, but are about to,
2221         // start the output. If we didn't ignore this case then the state machine
2222         // would restart unnecessarily, e.g. in the case of SRC, resulting in
2223         // added latency.
2224         if (errno != ASPERR_INFO_RATECHANGE)
2225         {
2226             TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
2227             return errno;
2228         }
2229         else
2230         {
2231             TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
2232         }
2233     }
2235     errno = pP->fxns->startOutput(pP, pQ, pAsotCfg);
2236     if (errno) 
2237     {
2238         if (errno == 0x105) 
2239         {
2240             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
2241         }
2242         else
2243         {
2244             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
2245         }
2246         return errno;
2247     }
2248     
2249     return 0;
2252 // -----------------------------------------------------------------------------
2253 // ASOT Decoding Function - Info Processing, Subsequent
2254 //
2255 //   Name:      PAF_ASOT_decodeInfo2
2256 //   Purpose:   Decoding Function for processing information in a manner that
2257 //              is unique to frames of input data other than the initial one.
2258 //   From:      AST Parameter Function -> decodeProcessing
2259 //   Uses:      See code.
2260 //   States:    x
2261 //   Return:    Error number in standard form (0 on success).
2262 //   Trace:     None.
2263 //
2264 Int
2265 PAF_ASOT_decodeInfo2(
2266     const PAF_ASOT_Params *pP, 
2267     const PAF_ASOT_Patchs *pQ, 
2268     PAF_ASOT_Config *pAsotCfg, 
2269     Int frame, 
2270     Int block
2273     //PAF_AST_Config *pAstCfg;
2274     Int errno;
2276     
2277     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2279     errno = pP->fxns->setCheckRateX (pP, pQ, pAsotCfg, 1);
2280     TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
2281     return errno;
2282 } //PAF_ASOT_decodeInfo2
2285 PAF_AST_DecOpCircBufStats gCbStats; // FL: debug
2286 // -----------------------------------------------------------------------------
2287 // ASOT Decoding Function - Stream Processing
2288 //
2289 //   Name:      PAF_ASOT_decodeStream
2290 //   Purpose:   Decoding Function for processing of audio frame data by the
2291 //              ASP Algorithms.
2292 //   From:      AST Parameter Function -> decodeProcessing
2293 //   Uses:      See code.
2294 //   States:    x
2295 //   Return:    Error number in standard form (0 on success).
2296 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2297 //              * State information as per parent/child.
2298 //
2299 Int
2300 PAF_ASOT_decodeStream(
2301     const PAF_ASOT_Params *pP, 
2302     const PAF_ASOT_Patchs *pQ, 
2303     PAF_ASOT_Config *pAsotCfg, 
2304     Int frame, 
2305     Int block
2308     PAF_AST_Config *pAstCfg;
2309     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2310     Int z;                              /* decode/stream counter */
2311     PAF_AudioFrame *pAfRd;
2312     Int cbErrno;
2313     PAF_AST_DecOpCircBufStats cbStats;  /* circular buffer statistics */
2314     Int errno;
2317     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2318     
2319     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2320     
2321     for (z=DECODE1; z < DECODEN; z++) 
2322     {
2323         Int zS = pP->streamsFromDecodes[z];
2324         
2325         //
2326         // Read decoder output circular buffer
2327         //
2328         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
2329         GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
2330         cbErrno = cbReadAf(pCbCtl, z, pAfRd);
2331         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2332         if ((cbErrno < 0) && 
2333             (cbErrno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && 
2334             (cbErrno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
2335         {
2336             gCbReadAfErr++;
2337             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
2338             //SW_BREAKPOINT; // debug
2339             return cbErrno;
2340         }
2342         // Handle underflows
2343         if ((cbErrno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
2344             (cbErrno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
2345         {
2346             // (***) FL: Need to check behavior of cbReset().
2347             // Need to check behavior on exit/re-entry into Output processing.
2348             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
2349             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
2350             {
2351                 // Underflow count above threshold.
2352                 // (1) set max underflow count to threshold
2353                 // (2) reset underflow count
2354                 // (3) reset circular buffer
2355                 
2356                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
2357                 gDecOpCbRdAfUnd = 0; // reset underflow count
2359                 // Reset circular buffer
2360                 cbReset(pCbCtl, z);
2361                 gMasterCbResetCnt++; // increment master circular buffer reset count
2362                 Log_info0("ASOT:cbReset");
2363             
2364                 return cbErrno;
2365             }
2366         }
2367         else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
2368         {
2369             // No underflow detected.
2370             // update max underflow count,
2371             // reset underflow count
2372             
2373             // update max underflow count
2374             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
2375             {
2376                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
2377             }
2378             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
2379         }
2380         //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2381         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2382         Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2383         
2384 #if 0 // (***) FL: shows timing of CB read
2385             // (***) debug // B8
2386             {
2387                 static Uint8 toggleState = 0;
2388                 if (toggleState == 0)
2389                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2390                 else
2391                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2392                 toggleState = ~(toggleState);
2393             }
2394 #endif
2396         // FL: debug
2397         // Get circular buffer statistics (debug)
2398         //cbGetStats(pCbCtl, z, &cbStats);
2399         cbGetStats(pCbCtl, z, &gCbStats);
2401         // debug
2402         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
2403         //if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
2404         //{
2405         //    Log_info0("capAfWrite() error");
2406         //}
2407     }
2408             
2409     TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
2410     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2411         PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
2412     if (errno)
2413     {
2414         TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
2415         return errno;
2416     }
2418     return 0;
2420 } //PAF_ASOT_decodeStream
2422 // -----------------------------------------------------------------------------
2423 // ASOT Decoding Function - Encode Processing
2424 //
2425 //   Name:      PAF_ASOT_decodeEncode
2426 //   Purpose:   Decoding Function for processing of audio frame data by the
2427 //              Encode Algorithm.
2428 //   From:      AST Parameter Function -> decodeProcessing
2429 //   Uses:      See code.
2430 //   States:    x
2431 //   Return:    Error number in standard or SIO form (0 on success).
2432 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2433 //              * State information as per parent.
2434 //
2435 Int
2436 PAF_ASOT_decodeEncode(
2437     const PAF_ASOT_Params *pP, 
2438     const PAF_ASOT_Patchs *pQ, 
2439     PAF_ASOT_Config *pAsotCfg, 
2440     Int frame, 
2441     Int block
2444     PAF_AST_Config *pAstCfg;
2445     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2446     Int z;                      /* encode/output counter */
2447     Int errno;                  /* error number */
2448     Int zX, zE, zS;
2449     UInt32 curTime;
2451     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2452     as = pAstCfg->as;
2454     // Await output buffers (but not first time)
2455     for (z=OUTPUT1; z < OUTPUTN; z++) 
2456     {
2457         // determine encoder associated with this output
2458         zE = z;
2459         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2460         {
2461             if (pP->outputsFromEncodes[zX] == z) 
2462             {
2463                 zE = zX;
2464                 break;
2465             }
2466         }
2467         zS = pP->streamsFromEncodes[zE];
2469         if (pAstCfg->xOut[z].hTxSio) 
2470         {
2471             // update length (e.g. ARC may have changed)
2472             pAstCfg->xOut[z].outBufConfig.lengthofFrame = 
2473                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2474             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
2475             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2476             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
2477             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
2478             if (errno < 0)
2479             {
2480                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2481                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
2482                 return -errno; // SIO negates error codes
2483             }
2484             // TODO: use pC->xOut[z].pOutBuf in following ->encode call
2486 #if 0 // (***) FL: shows timing of Output Rx SIO reclaim
2487             // (***) debug // B8
2488             {
2489                 static Uint8 toggleState = 0;
2490                 if (toggleState == 0)
2491                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2492                 else
2493                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2494                 toggleState = ~(toggleState);
2495             }
2496 #endif            
2498             gAsopTxSioReclaimCnt++;
2500             //
2501             // Simulate Tx SIO_reclaim() pend
2502             //
2503             //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
2504             curTime = Clock_getTicks();
2505             //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
2506             //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
2507         }
2508         else 
2509         {
2510             TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
2511         }
2512     }
2514     // Encode data
2515     for (z=ENCODE1; z < ENCODEN; z++) 
2516     {
2517         Int zO = pP->outputsFromEncodes[z];
2518         Int zS = pP->streamsFromEncodes[z];
2519         (void)zS; // clear compiler warning in case not used with tracing disabled
2520         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2521         {
2522             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2523             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2524             ENC_Handle enc = (ENC_Handle )encAlg;
2525             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
2526             {
2527                 pAstCfg->xEnc[z].encodeControl.encActive = select;
2528                 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
2529                 return (-1);
2530             }
2531             TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
2533             // (MID 1933) temp. workaround for PCE2
2534             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
2536           /*
2537           #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2538             {
2539                 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2540                 int *wp;
2541                 wp = (int*)pAudioFrame->data.sample[0];
2542                 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2543                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2544                 wp = (int*)pAudioFrame->data.sample[1];
2545                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2546                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2547                 wp = (int*)pAudioFrame->data.sample[2];
2548                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2549                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2550             }
2551           #endif
2552           */
2554             if (enc->fxns->encode)
2555             {
2556                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2557                         pP->z_pEncodeStatus[z]->encBypass;
2558                 errno = enc->fxns->encode(enc, NULL, 
2559                     &pAstCfg->xEnc[z].encodeInStruct, 
2560                     &pAstCfg->xEnc[z].encodeOutStruct);
2561                 if (errno)
2562                 {
2563                     if (errno != PCEERR_OUTPUT_POINTERNULL)
2564                     {
2565                         TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2566                         return errno;
2567                     }
2568                 }
2569             /*  #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2570                 else
2571                 {
2572                     int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2573                     TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2574                     TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2575                 }
2576               #endif
2577               */
2578             }
2579         }
2580         else 
2581         {
2582             TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2583                 as+pP->streamsFromEncodes[z], block);
2584         }
2585     }
2587     // Transmit data
2588     for (z=OUTPUT1; z < OUTPUTN; z++) 
2589     {
2590         // determine encoder associated with this output
2591         zE = z;
2592         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2593         {
2594             if (pP->outputsFromEncodes[zX] == z) 
2595             {
2596                 zE = zX;
2597                 break;
2598             }
2599         }
2600         zS = pP->streamsFromEncodes[zE];
2602         if (pAstCfg->xOut[z].hTxSio) 
2603         {
2604             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2605             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
2606             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
2607                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2608             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2609             if (errno)
2610             {
2611                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2612                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
2613                 {
2614 //                    statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2615                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2616                 }
2617                 if (errno > 0)
2618                 {
2619                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2620                     return (ASPERR_ISSUE + (z << 4));
2621                 }
2622                 else if (errno < 0)
2623                 {
2624                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2625                     return -errno; // SIO negates error codes
2626                 }
2627             }
2628             if (errno > 0)
2629             {
2630                 return (ASPERR_ISSUE + (z << 4));
2631             }
2632             else if (errno < 0)
2633             {
2634                 return -errno; // SIO negates error codes
2635             }
2636         }
2637         else 
2638         {
2639             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2640         }
2641     }
2643     return 0;
2644 } //PAF_ASOT_decodeEncode
2646 // -----------------------------------------------------------------------------
2647 // ASOT Decoding Function - Stream-Final Processing
2648 //
2649 //   Name:      PAF_ASOT_decodeComplete
2650 //   Purpose:   Decoding Function for terminating the decoding process.
2651 //   From:      AST Parameter Function -> decodeProcessing
2652 //   Uses:      See code.
2653 //   States:    x
2654 //   Return:    0.
2655 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2656 //              * State information as per parent.
2657 //
2658 Int
2659 PAF_ASOT_decodeComplete(
2660     const PAF_ASOT_Params *pP, 
2661     const PAF_ASOT_Patchs *pQ, 
2662     PAF_ASOT_Config *pAsotCfg, 
2663     ALG_Handle decAlg[], 
2664     Int frame, 
2665     Int block
2668     PAF_AST_Config *pAstCfg;
2669     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2670     Int as;                             /* Audio Stream Number (1, 2, etc.) */
2671     Int z;                              /* decode/encode counter */
2672     Int errno;                          /* error number */
2674     
2675     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2676     as = pAstCfg->as;
2677     (void)as;  // clear compiler warning in case not used with tracing disabled
2679     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2680     
2681     for (z=DECODE1; z < DECODEN; z++)
2682     {
2683         // Stop decoder output circular buffer reads
2684         errno = cbReadStop(pCbCtl, z);
2685         if (errno)
2686         {
2687             TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2688             SW_BREAKPOINT; // FL: debug
2689             return errno;
2690         }
2691         // FL: debug
2692         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2693     }
2694     
2695     pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2697     for (z=ENCODE1; z < ENCODEN; z++) 
2698     {
2699         Int zO = pP->outputsFromEncodes[z];
2700         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2701         {
2702             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2703             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2704 #ifdef PAF_ASP_FINAL
2705             ENC_Handle enc = (ENC_Handle)encAlg;
2706 #endif /* PAF_ASP_FINAL */
2707             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2708 #ifdef PAF_ASP_FINAL
2709             if (enc->fxns->final)
2710                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2711                                  &pAstCfg->xEnc[z].encodeStatus);
2712 #endif /* PAF_ASP_FINAL */
2713             if (encAlg->fxns->algDeactivate)
2714             {
2715                 encAlg->fxns->algDeactivate(encAlg);
2716             }
2717         }
2718         else 
2719         {
2720             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2721         }
2722     }
2724     // wait for remaining data to be output
2725     pP->fxns->stopOutput(pP, pQ, pAsotCfg);
2727     return 0;
2728 } //PAF_ASOT_decodeComplete
2730 // -----------------------------------------------------------------------------
2731 // ASOT Decoding Function Helper - SIO Driver Start
2732 //
2733 //   Name:      PAF_ASOT_startOutput
2734 //   Purpose:   Decoding Function for initiating output.
2735 //   From:      AST Parameter Function -> decodeInfo1
2736 //   Uses:      See code.
2737 //   States:    x
2738 //   Return:    Error number in standard or SIO form (0 on success).
2739 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2740 //              * State information as per parent.
2741 //              * SIO control errors.
2742 //
2743 #define DEC_OUTNUMBUF_MAP(X) \
2744       pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2746 Int
2747 PAF_ASOT_startOutput(
2748     const PAF_ASOT_Params *pP, 
2749     const PAF_ASOT_Patchs *pQ, 
2750     PAF_ASOT_Config *pAsotCfg
2751
2753     PAF_AST_Config *pAstCfg;
2754     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2755     Int z;                      /* output counter */
2756     Int errno,nbufs, errme;            /* error number */
2757     Int zE, zS, zX;
2758     Int zMD;
2759     PAF_SIO_IALG_Obj    *pObj;
2760     PAF_SIO_IALG_Config *pAlgConfig;
2762     
2763     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2764     as = pAstCfg->as;
2765     zMD = pAstCfg->masterDec;
2767     for (z=OUTPUT1; z < OUTPUTN; z++) 
2768     {
2769         if (pAstCfg->xOut[z].hTxSio) 
2770         {
2771             // determine associated encoder and stream
2772             zE = z;
2773             zS = z;
2774             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2775             {
2776                 if (pP->outputsFromEncodes[zX] == z) 
2777                 {
2778                     zE = zX;
2779                     zS = pP->streamsFromEncodes[zE];
2780                     break;
2781                 }
2782             }
2784 // Need to Revisit: Starting Clocks here seems logical & also manages the McASP without spurious underruns .
2786 #if 1
2787             // if device selected and valid then enable stat tracking if
2788                         // required and start clocking
2789                         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
2790                         {
2791                                 TRACE_VERBOSE0("PAF_ASOT_startOutput: start SIO clocks");
2792                                 errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
2793                                 if (errno)
2794                                 {
2795                                         TRACE_VERBOSE2("PAF_ASOT_startOutput: errme 0x%x, errno 0x%x", errme, errno);
2796                                         SIO_idle(pAstCfg->xOut[z].hTxSio);
2797                                         if (!errno)
2798                                         {
2799                                                 errno = ASPERR_DEVOUT + errme;
2800                                         }
2801                                 }
2802                         }
2803 #endif
2804             // Set sample count so that DOB knows how much data to send
2805             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2806                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2808             if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED) 
2809             {
2810                 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2811                 pAlgConfig = &pObj->config;
2812                 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA, 
2813                     pAlgConfig->pMemRec[0].size);
2814             }
2816             // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2817             // decoder. How should we handle the sourceProgram for multiple decoders?
2818             // Override as needed
2819             nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2820             if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2821             {
2822                 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2823             }
2824             SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2826             if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2827                 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0)) 
2828             {
2829                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2830                 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2831                 return errno;
2832             }
2834             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && 
2835                 (errno =  SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
2836             {
2837                 errno = (errno & 0xff) | ASPERR_MUTE;
2838                 /* convert to sensical errno */
2839                 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2840                 return (errno);
2841             }
2842             else
2843             {
2844                 pAstCfg->xOut[z].outBufStatus.audio
2845                     = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;                
2846             }
2848             TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2849         }
2850     }
2852     return 0;
2853 } //PAF_ASOT_startOutput
2855 // -----------------------------------------------------------------------------
2856 // ASOT Decoding Function Helper - SIO Driver Stop
2857 //
2858 //   Name:      PAF_ASOT_stopOutput
2859 //   Purpose:   Decoding Function for terminating output.
2860 //   From:      AST Parameter Function -> decodeProcessing
2861 //              AST Parameter Function -> decodeComplete
2862 //   Uses:      See code.
2863 //   States:    x
2864 //   Return:    Error number in standard or SIO form (0 on success).
2865 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2866 //              * SIO control errors.
2867 //
2868 Int
2869 PAF_ASOT_stopOutput(
2870     const PAF_ASOT_Params *pP, 
2871     const PAF_ASOT_Patchs *pQ, 
2872     PAF_ASOT_Config *pAsotCfg
2875     PAF_AST_Config *pAstCfg;
2876     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2877     Int z;                      /* output counter */
2878     Int errno = 0, getVal;
2879     Int zS, zX;
2880     PAF_SIO_IALG_Obj    *pObj;
2881     PAF_SIO_IALG_Config *pAlgConfig;
2883     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2884     as = pAstCfg->as;
2885     (void)as;  // clear compiler warning in case not used with tracing disabled
2887     for (z=OUTPUT1; z < OUTPUTN; z++) 
2888     {
2889         if (pAstCfg->xOut[z].hTxSio) 
2890         {
2891             // determine associated encoder and stream
2892             zS = z;
2893             (void)zS;
2894             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2895             {
2896                 if (pP->outputsFromEncodes[zX] == z) 
2897                 {
2898                     zS = pP->streamsFromEncodes[zX];
2899                     break;
2900                 }
2901             }
2903             // Mute output before audio data termination in the usual case,
2904             // where such termination is due to decode error or user command.
2905             // Identification of this as the usual case is provided by the
2906             // "decode processing" state machine.
2907             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2908                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2909                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
2910             {
2911                 if (!errno) 
2912                 {
2913                     errno = (getVal & 0xff) | ASPERR_MUTE;
2914                     /* convert to sensical errno */
2915                 }
2916                 TRACE_VERBOSE1("PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2917             }
2919             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2921             // Terminate audio data output, truncating (ignore) or flushing
2922             // (play out) final samples as per (1) control register set by
2923             // the user and (2) the type of audio data termination:
2925 #if 0
2926             // This form is not used because driver support for truncating
2927             // data is not supported for internal clocks, although it is
2928             // for external clocks.
2929             getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2930                 pC->xOut[z].outBufStatus.flush
2931                 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2932                 ? 1 : 0);
2933             /* UNTESTED */
2934 #else
2935             // This form should be used when driver support for truncating
2936             // data is supported for both internal and external clocks.
2937             getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2938                 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2939                 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2940                 ? 1 : 0);
2941             /* TESTED */
2942 #endif
2944             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2946             if (!errno)
2947             {
2948                 errno = getVal;
2949             }
2951             // Mute output after audio data termination in a special case,
2952             // where such termination is due to processing of a final frame
2953             // or user command. Identification of this as a special case is
2954             // provided by the "decode processing" state machine.
2955             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2956                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2957                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2958             {
2959                 if (!errno) 
2960                 {
2961                     errno = (getVal & 0xff) | ASPERR_MUTE;
2962                     /* convert to sensical errno */
2963                 }
2964                 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2965             }
2967             pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2969             // zero output buffers
2970             pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2971             pAlgConfig = &pObj->config;
2972             memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2973         } //pAstCfg->xOut[z].hTxSio
2974     }//OUTPUT
2976     return errno;
2977 } //PAF_ASOT_stopOutput
2980 // -----------------------------------------------------------------------------
2981 // ASOT Decoding Function Helper - SIO Driver Change
2982 //
2983 //   Name:      PAF_ASOT_setCheckRateX
2984 //   Purpose:   Decoding Function for reinitiating output.
2985 //   From:      AST Parameter Function -> decodeInfo1
2986 //              AST Parameter Function -> decodeInfo2
2987 //   Uses:      See code.
2988 //   States:    x
2989 //   Return:    Error number in standard form (0 on success).
2990 //   Trace:     None.
2991 //
2993 /* 0: set, 1: check, unused for now. --Kurt */
2994 Int
2995 PAF_ASOT_setCheckRateX(
2996     const PAF_ASOT_Params *pP, 
2997     const PAF_ASOT_Patchs *pQ, 
2998     PAF_ASOT_Config *pAsotCfg, 
2999     Int check
3002     PAF_AST_Config *pAstCfg;
3003     float rateX;
3004     PAF_SampleRateHz rateO /* std */, rateI /* inv */;
3005     Int z;                              /* output counter */
3006     Int zx;                             /* output re-counter */
3007     Int getVal;
3008     int inputRate, inputCount, outputRate, outputCount;
3009     Int zMD;
3010     Int zMI;
3011     Int zMS;
3012     Int zE, zX;
3014     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3015     zMD = pAstCfg->masterDec;
3016     zMS = pAstCfg->masterStr;
3017     zMI = pP->zone.master;
3019     inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
3020     inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
3021     rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
3022         (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
3024     for (z=OUTPUT1; z < OUTPUTN; z++) 
3025     {
3026         if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) 
3027         {
3028             // determine associated encoder
3029             zE = z;
3030             for (zX = ENCODE1; zX < ENCODEN; zX++) 
3031             {
3032                 if (pP->outputsFromEncodes[zX] == z) 
3033                 {
3034                     zE = zX;
3035                     break;
3036                 }
3037             }
3039             outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
3040             outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
3041             rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
3042                 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
3043             if ((rateI > 0) && (rateO > 0))
3044             {
3045                 rateX = rateO /* std */ * rateI /* inv */;
3046             }
3047             else if (inputCount != 0)
3048             {
3049                 rateX = (float )outputCount / inputCount;
3050             }
3051             else
3052             {
3053                 return ASPERR_INFO_RATERATIO;
3054             }
3056             getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg)&rateX);
3057             if (getVal == DOBERR_RATECHANGE) 
3058             {
3059                 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
3060                 {
3061                     if (pAstCfg->xOut[zx].hTxSio)
3062                     {
3063                         SIO_idle (pAstCfg->xOut[zx].hTxSio);
3064                     }
3065                 }
3067                 // this forces an exit from the calling state machine which will
3068                 // eventually call startOutput which calls setCheckRateX for all outputs
3069                 // and so it is ok, in the presence of a rate change on any output, to
3070                 // exit this loop /function early.
3071                 return ASPERR_INFO_RATECHANGE;
3072             }
3073             else if (getVal != SYS_OK)
3074             {
3075                 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
3076             }
3077         }
3078     }
3080     return 0;
3081 } //PAF_ASOT_setCheckRateX
3083 // -----------------------------------------------------------------------------
3084 // ASOT Decoding Function Helper - Chain Processing
3085 //
3086 //   Name:      PAF_ASOT_streamChainFunction
3087 //   Purpose:   Common Function for processing algorithm chains.
3088 //   From:      AST Parameter Function -> decodeInfo1
3089 //              AST Parameter Function -> decodeStream
3090 //              AST Parameter Function -> decodeComplete
3091 //   Uses:      See code.
3092 //   States:    x
3093 //   Return:    Error number in standard form (0 on success).
3094 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
3095 //              * State information as per parent.
3096 //
3097 Int
3098 PAF_ASOT_streamChainFunction(
3099     const PAF_ASOT_Params *pP, 
3100     const PAF_ASOT_Patchs *pQ, 
3101     PAF_ASOT_Config *pAsotCfg, 
3102     Int iChainFrameFxns, 
3103     Int abortOnError, 
3104     Int logArg
3107     PAF_AST_Config *pAstCfg;
3108     Int as;                     /* Audio Stream Number (1, 2, etc.) */
3109     Int z;                      /* stream counter */
3110     Int errno;                  /* error number */
3111     Int dFlag, eFlag, gear;
3112     Int zX;
3113     Int zS;
3115     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3116     as = pAstCfg->as;
3117     (void)as; // clear compiler warning in case not used with tracing disabled
3119     for (zS = STREAM1; zS < STREAMN; zS++)
3120     {
3121         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
3123         // apply stream
3124         //      unless the stream is associated with a decoder and it is not running
3125         // or
3126         //      unless the stream is associated with an encoder and it is not running
3127         // Also gear control only works for streams with an associated decoder
3128         // if no such association exists then gear 0 (All) is used
3129         dFlag = 1;
3130         gear = 0;
3131         for (zX = DECODE1; zX < DECODEN; zX++) {
3132             if (pP->streamsFromDecodes[zX] == z) {
3133                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
3134                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
3135                 break;
3136             }
3137         }
3138         eFlag = 1;
3139         for (zX = ENCODE1; zX < ENCODEN; zX++) {
3140             if (pP->streamsFromEncodes[zX] == z) {
3141                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
3142                 break;
3143             }
3144         }
3146         if (dFlag && eFlag) {
3147             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
3148             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
3149             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
3150                 chain->fxns->chainFrameFunction[iChainFrameFxns];
3152             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
3153                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
3154                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
3155                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
3156                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
3157                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
3158                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
3159                        as+z, logArg);
3160             errno = (*func) (chain, frame);
3161             TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
3162                 as+z, errno);
3164             if (errno && abortOnError)
3165                 return errno;
3166         }
3167         else {
3168             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
3169                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
3170                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
3171                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
3172                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
3173                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
3174                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
3175                        as+z, logArg);
3176         }
3178         /*
3179         {
3180             void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
3181             PAF_AudioFrameData *afd;
3182             float ** afPtr;
3184             afd = &(pC->xStr->pAudioFrame->data);
3185             afPtr = (float**)afd->sample;
3186             dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
3188         }
3189         */
3191     }
3193     return 0;
3194 } //PAF_ASOT_streamChainFunction
3196 /* Check if at least one output selected */
3197 static Int checkOutSel(
3198     const PAF_ASOT_Params *pP, 
3199     PAF_ASOT_Config *pAsotCfg,
3200     Int *pOutSel
3203     PAF_AST_Config *pAstCfg;
3204     Int outSel;
3205     Int z;
3206     
3207     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3209     outSel = 0;
3210     for (z=OUTPUT1; z < OUTPUTN; z++) 
3211     {
3212         if (pAstCfg->xOut[z].hTxSio)
3213         {
3214             outSel = 1;
3215             break;
3216         }
3217     }
3218     
3219     *pOutSel = outSel;
3221     return ASOP_SOK;
3224 /* Check if at least one output sio changed */
3225 static Int checkOutSio(
3226     const PAF_ASOT_Params *pP, 
3227     PAF_ASOT_Config *pAsotCfg,
3228     Int *pOutSioUpdate
3231     PAF_AST_Config *pAstCfg;
3232     Int outSioUpdate;
3233     Int z;
3234     
3235     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3237     outSioUpdate = 0;
3238     for (z=OUTPUT1; z < OUTPUTN; z++) 
3239     {
3240         if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
3241         {
3242             outSioUpdate = 1;
3243             break;
3244         }
3245     }
3246     
3247     *pOutSioUpdate = outSioUpdate;
3249     return ASOP_SOK;
3252 // Reset audio frames
3253 static Void resetAfs(
3254     const PAF_ASOT_Params *pP, 
3255     PAF_AST_Stream *xStr
3258     // Reset audio frame pointers to original values
3259     // (may be needed if error occurred).
3260     resetAfPointers(pP, xStr);
3261     // Reset audio frame meta data elements
3262     resetAfMetadata(pP, xStr);
3265 // Reset audio frame pointers to original values
3266 static Void resetAfPointers(
3267     const PAF_ASOT_Params *pP, 
3268     PAF_AST_Stream *xStr
3271     Int z;
3272     Int ch;
3274     // Reset audio frame pointers to original values
3275     for (z = STREAM1; z < STREAMN; z++) 
3276     {
3277         for (ch = PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
3278         {
3279             if (xStr[z].audioFrameChannelPointers[ch])
3280             {
3281                 xStr[z].audioFrameChannelPointers[ch] = 
3282                     xStr[z].origAudioFrameChannelPointers[ch];
3283             }
3284         }
3285     }
3288 // Reset audio frame meta data elements
3289 static Void resetAfMetadata(
3290     const PAF_ASOT_Params *pP, 
3291     PAF_AST_Stream *xStr
3294     Int z;
3295     Int i;
3297     for (z = STREAM1; z < STREAMN; z++) 
3298     {
3299         xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
3300         xStr[z].pAudioFrame->numPrivateMetadata = 0;
3301         xStr[z].pAudioFrame->bsMetadata_offset = 0;
3302         xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
3304         for (i = 0; i < pP->pMetadataBufStatus->NumBuf; i++)
3305         {
3306             xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
3307             xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
3308         }
3309     }
3312 // Initialize Output Processing state function
3313 static Int PAF_ASOT_initOutProc(
3314     const PAF_ASOT_Params *pP, 
3315     PAF_AST_Stream *xStr
3318     // Reset audio frames
3319     resetAfs(pP, xStr);