Circular buffer read cleanup from Build #38 (work on PASDK-53).
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutProc.c
2 /*
3 Copyright (c) 2016, 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 "audioStreamProc_common.h"
61 #include "audioStreamOutProc.h"
63 #define TRACE_TIME(a)
65 //
66 // Audio Stream Definitions
67 //
69 //
70 // Audio Stream Processing Definitions
71 //
72 #define aspLinkInit pQ->i_aspLinkInit
74 //
75 // Encoder Definitions
76 //
77 #define encLinkInit pQ->i_encLinkInit
79 //
80 // Output Definitions
81 //
82 #define outLinkInit pP->i_outLinkInit
84 /* ---------------------------------------------------------------- */
85 /*              Parameter macro definitions end here.               */
86 /* ---------------------------------------------------------------- */
88 //
89 // Standardized Definitions
90 //
92 #define ENC_Handle PCE_Handle /* works for all: PCE */
94 #define __TASK_NAME__  "TaskAsop"
97 /* FL: Check if at least one output selected */
98 static Int checkOutSel(
99     const PAF_ASOT_Params *pP, 
100     PAF_ASOT_Config *pC,
101     Int *pOutSel
102 );
104 /* FL: Check if at least one output sio changed */
105 static Int checkOutSio(
106     const PAF_ASOT_Params *pP, 
107     PAF_ASOT_Config *pC,
108     Int *pOutSioUpdate
109 );
111 LINNO_DEFN(TaskAsop); /* Line number macros */
112 ERRNO_DEFN(TaskAsop); /* Error number macros */
114 // ASOT configuration
115 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
116 PAF_ASOT_Config gPAF_ASOT_config = {
117     NULL,               // acp
118     &gPAF_ASPM_config,  // pAspmCfg
119     &gPAF_AST_config    // pAstCfg
120 };
122 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
123 #define DEC_OP_CB_RDAF_UND_THR  ( 80 ) // FL: arbitrary setting
124 UInt32 gCbReadAfErr         =0; // read circular buffer error count, not including underflows
125 UInt32 gDecOpCbRdAfUnd      =0; // decoder output circular buffer underflow count
126 UInt32 gMaxDecOpCbRdAfUnd   =0; // max (consecutive) decoder output circular buffer underflow count
128 // Global debug counters */
129 UInt32 gTaskAsopCnt=0; // debug
130 UInt32 gAsopInitCnt     =0;
131 UInt32 gAsopStreamCnt   =0;
132 UInt32 gAsopEncodeCnt   =0;
133 UInt32 gAsopFinalCnt    =0;
134 UInt32 gAsopQuitCnt     =0;
136 // FL: (***) debug
137 #include "evmc66x_gpio_dbg.h"
139 /*
140  *  ======== taskAsopFxn ========
141  *  Audio Stream Output Processing task function
142  */
143 Void taskAsopFxn(
144 //    Int betaPrimeValue, // FL: revisit
145     const PAF_ASOT_Params *pP,
146     const PAF_ASOT_Patchs *pQ
149     PAF_ASOT_Config *pC;            /* Local configuration pointer */
150     PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
151     Int as;                         /* Audio Stream Number (1, 2, etc.) */
152     Int z;                          /* input/encode/stream/decode/output counter */
153     Int i;                          /* phase */
154     Int errno;                      /* error number */
155     Int zMS;
156     Int loopCount = 0;  // used to stop trace to see startup behavior.        
158     Log_info0("Enter taskAsopFxn()");    
160     //
161     // Audio Framework Parameters & Patch (*pP, *pQ)
162     //
163     if (!pP) 
164     {
165         TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
166         LINNO_RPRT(TaskAsop, -1);
167         return;
168     }
170     if (!pQ)
171     {
172         TRACE_TERSE0("TaskAsip: No Patchs defined. Exiting.");
173         LINNO_RPRT(TaskAsop, -1);
174         return;
175     }    
177     //
178     // Audio Framework Configuration (*pC):
179     //
180     pC = &gPAF_ASOT_config;
181     pAstCfg = pC->pAstCfg;
183     /* Obtain Audio Stream Number (1, 2, etc.) */    
184     as = pAstCfg->as;
185     TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
187     //
188     // Initialize message log trace and line number reporting
189     //
190     for (z=STREAM1; z < STREAMN; z++)
191     {
192         TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
193     }
194     LINNO_RPRT(TaskAsop, -1);
195     
196     //
197     // Determine stream index
198     //
199     zMS = pAstCfg->masterStr;
201     // Initialize as per parametrized phases:
202     //
203     //   In standard form these are:
204     //      - Malloc: Memory Allocation
205     //      - Config: Configuration Initialization
206     //      - AcpAlg: ACP Algorithm Initialization and Local Attachment
207     //      - Common: Common Memory Initialization
208     //      - AlgKey: Dec/Enc chain to Array Initialization
209     //      - Device: I/O Device Initialization
210     //      - Unused: (available)
211     //      - Unused: (available)
212     //
213     LINNO_RPRT(TaskAsop, -2);
214     for (i=0; i < lengthof(pP->fxns->initPhase); i++)
215     {
216         Int linno;
217         if (pP->fxns->initPhase[i])
218         {
219             if (linno = pP->fxns->initPhase[i](pP, pQ, pC)) 
220             {
221                 LINNO_RPRT(TaskAsop, linno);
222                 return;
223             }
224         }
225         else 
226         {
227             TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
228         }
229         TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
230         LINNO_RPRT(TaskAsop, -i-3);
231     }
232   
233     //
234     // End of Initialization -- display memory usage report.
235     //
236     if (pP->fxns->memStatusPrint)
237     {
238         pP->fxns->memStatusPrint(HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, HEAP_INTERNAL1_SHM);
239     }
241     //
242     // Main processing loop
243     //   
244     for (z=STREAM1; z < STREAMN; z++)
245     {
246         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
247     }
248     
249     errno = 0;
250     for (;;)
251     {
252         Int outSel;
254         loopCount++;
255         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
257         // any error forces idling of output
258         if (errno) 
259         {
260             for (z=OUTPUT1; z < OUTPUTN; z++)
261             {
262                 if (pAstCfg->xOut[z].hTxSio)
263                 {
264                     SIO_idle(pAstCfg->xOut[z].hTxSio);
265                 }
266             }
267         
268             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
269             ERRNO_RPRT(TaskAsop, errno);
270         }        
271         
272         TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
273         Task_sleep(1);
275         TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
276         if (errno = pP->fxns->selectDevices(pP, pQ, pC))
277         {
278             TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
279             continue;
280         }
282         // if no output selected skip any remaining processing
283         if (errno = checkOutSel(pP, pC, &outSel))
284         {
285             TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
286             continue;
287         }
288         else if (!outSel)
289         {
290             TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);            
291             continue;
292         }
293         
294         TRACE_VERBOSE0("TaskAsop: calling outputProcessing.");
295         errno = pP->fxns->decodeProcessing(pP, pQ, pC, -1);
296         if (errno) 
297         {
298             TRACE_TERSE1("TaskAsop: outputProcessing returns 0x%x, continue", errno);
299         }
300         else
301         {
302             TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
303         }        
304     } // End of main processing loop for (;;)
305     
306     Log_info0("Exit taskAsopFxn()");
309 // -----------------------------------------------------------------------------
310 // AST Initialization Function - Memory Allocation
311 //
312 //   Name:      PAF_ASOT_initPhaseMalloc
313 //   Purpose:   Audio Stream Output Task Function for initialization of data pointers
314 //              by allocation of memory.
315 //   From:      audioStream1Task or equivalent
316 //   Uses:      See code.
317 //   States:    x
318 //   Return:    0 on success.
319 //              Source code line number on MEM_calloc failure.
320 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
321 //              * State information as per parent.
322 //              * Memory allocation errors.
323 //
325 Int
326 PAF_ASOT_initPhaseMalloc (
327     const PAF_ASOT_Params *pP, 
328     const PAF_ASOT_Patchs *pQ, 
329     PAF_ASOT_Config *pC
332     PAF_AST_Config *pAstCfg;
333     Int as;                     /* Audio Stream Number (1, 2, etc.) */
334     Int zMS;
335     Error_Block    eb;
336     //Int i;
338     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
339     as = pAstCfg->as;
340     zMS = pAstCfg->masterStr;
342     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
344     // Initialize error block
345     Error_init(&eb); 
347     /* Stream memory */
348     if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
349     {
350         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
351         SW_BREAKPOINT;
352         return __LINE__;
353     }
354     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
355             STREAMN * sizeof (*pAstCfg->xStr),
356             HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
358     {
359         Int z;                          /* stream counter */
361         PAF_AudioFrame *fBuf;
363         if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
364         {
365             TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
366             SW_BREAKPOINT;
367             return __LINE__;
368         }
369         TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
370                 STREAMS * sizeof (*fBuf),
371                 HEAP_ID_INTERNAL, (IArg)fBuf);
373         for (z=STREAM1; z < STREAMN; z++)
374         {
375             pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
376             TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
377         }
378     }
380     /* Encode memory */
381     if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
382     {
383         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
384         SW_BREAKPOINT;
385         return __LINE__;
386     }
387     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
388             ENCODEN * sizeof (*pAstCfg->xEnc),
389             HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
391     /* Output memory */
392     if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb)))
393     {
394         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
395         SW_BREAKPOINT;
396         return __LINE__;
397     }
398     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.",
399             OUTPUTN * sizeof (*pAstCfg->xOut),
400             HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
402     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
403     return 0;
404 } //PAF_ASOT_initPhaseMalloc
406 // -----------------------------------------------------------------------------
407 // ASOT Initialization Function - Memory Initialization from Configuration
408 //
409 //   Name:      PAF_ASOT_initPhaseConfig
410 //   Purpose:   Audio Stream Output Task Function for initialization of data values
411 //              from parameters.
412 //   From:      audioStream1Task or equivalent
413 //   Uses:      See code.
414 //   States:    x
415 //   Return:    0 on success.
416 //              Other as per initFrame0 and initFrame1.
417 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
418 //              * State information as per parent.
419 //
420 Int
421 PAF_ASOT_initPhaseConfig(
422     const PAF_ASOT_Params *pP, 
423     const PAF_ASOT_Patchs *pQ, 
424     PAF_ASOT_Config *pC
427     PAF_AST_Config *pAstCfg;
428     Int as;                     /* Audio Stream Number (1, 2, etc.) */
429     Int z;                      /* input/encode/stream/decode/output counter */
430     Int zMS;
432     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
433     as = pAstCfg->as;
434     zMS = pAstCfg->masterStr;
436     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
438     //
439     // Unspecified elements have been initialized to zero during alloc
440     //
442     for (z=STREAM1; z < STREAMN; z++) 
443     {
444         Int linno;
445         if (linno = pP->fxns->initFrame0(pP, pQ, pC, z))
446         {
447             return linno;           
448         }
449         if (linno = pP->fxns->initFrame1(pP, pQ, pC, z, -1))
450         {
451             return linno;
452         }
453     }
455     for (z=ENCODE1; z < ENCODEN; z++) 
456     {
457         Int zO = pP->outputsFromEncodes[z];
458         Int zS = pP->streamsFromEncodes[z];
459         pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
460         pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
461         pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
462         pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
463         pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
464         pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
465         pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
466         pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
467     }
469     for (z=OUTPUT1; z < OUTPUTN; z++)
470     {
471         pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
472     }
474     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
475     return 0;
476 } //PAF_ASOT_initPhaseConfig
478 // -----------------------------------------------------------------------------
479 // ASOT Initialization Function - ACP Algorithm Instantiation
480 //
481 //   Name:      PAF_ASOT_initPhaseAcpAlg
482 //   Purpose:   Audio Stream Input Task Function for initialization of ACP by
483 //              instantiation of the algorithm.
484 //   From:      audioStream1Task or equivalent
485 //   Uses:      See code.
486 //   States:    x
487 //   Return:    0 on success.
488 //              Source code line number on ACP Algorithm creation failure.
489 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
490 //              * State information as per parent.
491 //              * Memory allocation errors.
492 //
493 Int
494 PAF_ASOT_initPhaseAcpAlg(
495     const PAF_ASOT_Params *pP, 
496     const PAF_ASOT_Patchs *pQ, 
497     PAF_ASOT_Config *pC
500     PAF_AST_Config *pAstCfg;
501     Int as;                     /* Audio Stream Number (1, 2, etc.) */
502     Int z;                      /* input/encode/stream/decode/output counter */
503     Int betaPrimeOffset;
504     ACP_Handle acp;
505     Int zMS;
506     Int zS, zX;
508     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
509     as = pAstCfg->as;
510     zMS = pAstCfg->masterStr;
512     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
514     ACP_MDS_init();
516     if (!(acp = (ACP_Handle )ACP_MDS_create(NULL))) 
517     {
518         TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation  failed", as+zMS);
519         return __LINE__;
520     }
521     pC->acp = acp;
523     ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
524         ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
526     for (z=ENCODE1; z < ENCODEN; z++) 
527     {
528         zS = pP->streamsFromEncodes[z];
529         acp->fxns->attach(acp, ACP_SERIES_STD,
530             STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
531             (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
532         acp->fxns->attach(acp, ACP_SERIES_STD,
533             STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
534             (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
535         /* Ignore errors, not reported. */
536     }
538     for (z=OUTPUT1; z < OUTPUTN; z++) 
539     {
540         zS = z;
541         for (zX = ENCODE1; zX < ENCODEN; zX++) 
542         {
543             if (pP->outputsFromEncodes[zX] == z) 
544             {
545                 zS = pP->streamsFromEncodes[zX];
546                 break;
547             }
548         }
549         acp->fxns->attach(acp, ACP_SERIES_STD,
550             STD_BETA_OB + betaPrimeOffset * (as-1+zS),
551             (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
552         /* Ignore errors, not reported. */
553     }
555     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
557     return 0;
558 } //PAF_ASOT_initPhaseAcpAlg
560 // -----------------------------------------------------------------------------
561 // ASOT Initialization Function - Common Memory
562 //
563 //   Name:      PAF_ASOT_initPhaseCommon
564 //   Purpose:   Audio Stream Output Task Function for allocation of common memory.
565 //   From:      audioStream1Task or equivalent
566 //   Uses:      See code.
567 //   States:    x
568 //   Return:    0 on success.
569 //              Source code line number on PAF_ALG_alloc failure.
570 //              Source code line number on PAF_ALG_mallocMemory failure.
571 //              Source code line number on Decode Chain initialization failure.
572 //              Source code line number on ASP Chain initialization failure.
573 //              Source code line number on Encode Chain initialization failure.
574 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
575 //              * State information as per parent.
576 //              * Memory allocation errors.
577 //
578 Int
579 PAF_ASOT_initPhaseCommon(
580     const PAF_ASOT_Params *pP, 
581     const PAF_ASOT_Patchs *pQ, 
582     PAF_ASOT_Config *pC
585     PAF_AST_Config *pAstCfg;
586     Int as;                     /* Audio Stream Number (1, 2, etc.) */
587     Int z;                      /* stream counter */
588     Int g;                      /* gear */
589     ACP_Handle acp;
590     PAF_IALG_Config pafAlgConfig;
591     IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
592    
593     acp = pC->acp;
594     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
595     as = pAstCfg->as;
597     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
599     //
600     // Determine memory needs and instantiate algorithms across audio streams
601     //
602     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
603     PAF_ALG_setup(&pafAlgConfig, 
604         HEAP_ID_INTERNAL,                 HEAP_INTERNAL, 
605         HEAP_ID_INTERNAL1,                HEAP_INTERNAL1, 
606         HEAP_ID_EXTERNAL,                 HEAP_EXTERNAL, 
607         HEAP_ID_INTERNAL1_SHM,            HEAP_INTERNAL1_SHM, 
608         HEAP_ID_EXTERNAL_SHM,             HEAP_EXTERNAL_SHM, 
609         HEAP_ID_EXTERNAL_NONCACHED_SHM,   HEAP_EXTERNAL_NONCACHED_SHM,
610         HEAP_CLEAR);
612     if (pP->fxns->headerPrint)
613     {
614         pP->fxns->headerPrint();        
615     }
617     for (z = STREAM1; z < STREAMN; z++) 
618     {
619         //Int zD, zE, zX;
620         Int zE, zX;
622         TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
624         //
625         // Determine common memory needs for:
626         //  (1) ASP Algorithms
627         //  (2) Encode Algorithms
628         //  (3) Logical Output drivers
629         //
630         PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
632         zE = -1;
633         for (zX = ENCODE1; zX < ENCODEN; zX++) 
634         {
635             if (pP->streamsFromEncodes[zX] == z) 
636             {
637                 zE = zX;
638                 break;
639             }
640         }
642         TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
643         if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z])) 
644         {
645             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
646             TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
647             SW_BREAKPOINT;
648             return __LINE__;
649         }
650         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
651         if (pP->fxns->allocPrint)
652         {
653             pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
654         }
656         if (zE >= 0) 
657         {
658             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
659             if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z])) 
660             {
661                 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
662                 SW_BREAKPOINT;
663                 return __LINE__;
664             }
665             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
666             if (pP->fxns->allocPrint)
667             {
668                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
669             }
670         }
672         //
673         // Determine common memory needs of Logical IO drivers
674         //
676         if (OUTPUT1 <= z && z < OUTPUTN)
677         {
678             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
679             if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
680             {
681                 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
682                 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
683                 SW_BREAKPOINT;
684                 return __LINE__;
685             }
686             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
687             if (pP->fxns->allocPrint)
688             {
689                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
690             }
691         }
692     }
693     {
694         // Changes made to share scratch between zones
695         // Assume maximum 3 zones and scratch common memory is at offset 0;
696         int max=0;
697         for (z=STREAM1; z<STREAMN; z++)
698         {
699             if (max < common[z][0].size)
700             {
701                 max = common[z][0].size;
702             }
703         }
704         common[STREAM1][0].size=max;
705         for (z=STREAM1+1; z<STREAMN; z++)
706         {
707             common[z][0].size = 0;            
708         }
709     }
710         
711     //
712     // Allocate common memory for:
713     //  (1) ASP Algorithms
714     //  (2) Encode Algorithms
715     //  (3) Logical Output drivers
716     //
717     for (z = STREAM1; z < STREAMN; z++) 
718     {
719         //Int zD, zE, zX;
720         Int zE, zX;
722         TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
723         if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig)) 
724         {
725             TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
726             TRACE_TERSE3("AS%d: z: %d.  Size 0x%x", as+z, z, common[z][0].size);
727             SW_BREAKPOINT;
728             return __LINE__;
729         }
730         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
731         // share zone0 scratch with all zones 
732         common[z][0].base = common[0][0].base;
733         if (pP->fxns->commonPrint)
734         {
735             pP->fxns->commonPrint(common[z], &pafAlgConfig);
736         }
738         zE = -1;
739         for (zX = ENCODE1; zX < ENCODEN; zX++) 
740         {
741             if (pP->streamsFromEncodes[zX] == z) 
742             {
743                 zE = zX;
744                 break;
745             }
746         }
748         pAstCfg->xStr[z].aspChain[0] = NULL;
749         for (g=0; g < GEARS; g++) 
750         {
751             PAF_ASP_Chain *chain;
752             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
753             chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
754                 HEAP_INTERNAL, as+z, acp, &trace,
755                 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
756             if (!chain) 
757             {
758                 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
759                 return __LINE__;
760             }
761             else
762             {
763                 pAstCfg->xStr[z].aspChain[g] = chain;
764             }
765         }
767         if (zE >= 0) 
768         {
769             PAF_ASP_Chain *chain;
770             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
771             chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
772                 HEAP_INTERNAL, as+z, acp, &trace,
773                 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
774             if (!chain) 
775             {
776                 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
777                 return __LINE__;
778             }
779         }
781         //
782         // Allocate non-common memories for Logical IO drivers
783         //    Since these structures are used at run-time we allocate from external memory
784         if (OUTPUT1 <= z && z < OUTPUTN) 
785         {
786             PAF_ASP_Chain *chain;
787             TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
788                            as+z, z);
789             chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
790                         HEAP_EXTERNAL, as+z, acp, &trace,
791                         outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
792             if (!chain) 
793             {
794                 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
795                 return __LINE__;
796             }
797         }
798     }
799     TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
801     return 0;
802 } //PAF_ASOT_initPhaseCommon
804 // -----------------------------------------------------------------------------
805 // ASOT Initialization Function - Algorithm Keys
806 //
807 //   Name:      PAF_ASOT_initPhaseAlgKey
808 //   Purpose:   Audio Stream Output Task Function for initialization of data values
809 //              from parameters for Algorithm Keys.
810 //   From:      audioStream1Task or equivalent
811 //   Uses:      See code.
812 //   States:    x
813 //   Return:    0.
814 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
815 //              * State information as per parent.
816 //
817 // .............................................................................
818 Int
819 PAF_ASOT_initPhaseAlgKey(
820     const PAF_ASOT_Params *pP, 
821     const PAF_ASOT_Patchs *pQ, 
822     PAF_ASOT_Config *pC
825     PAF_AST_Config *pAstCfg;
826     Int as;                     /* Audio Stream Number (1, 2, etc.) */
827     Int z;                      /* decode/encode counter */
828     Int s;                      /* key number */
829     PAF_ASP_Link *that;
831     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
832     as = pAstCfg->as;
833     (void)as; // clear compiler warning in case not used with tracing disabled
835     TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
837     for (z=ENCODE1; z < ENCODEN; z++) 
838     {
839         for (s=0; s < pP->pEncAlgKey->length; s++) 
840         {
841             if ((pP->pEncAlgKey->code[s].full != 0) && 
842                 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
843             {
844                 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
845             }
846             /* Cast in interface, for now --Kurt */
847             else
848             {
849                 pAstCfg->xEnc[z].encAlg[s] = NULL;                
850             }
851         }
852     }
854     return 0;
855 } //PAF_ASOT_initPhaseAlgKey
857 // -----------------------------------------------------------------------------
858 // ASOT Initialization Function - I/O Devices
859 //
860 //   Name:      PAF_ASOT_initPhaseDevice
861 //   Purpose:   Audio Stream Output Task Function for initialization of I/O Devices.
862 //   From:      audioStream1Task or equivalent
863 //   Uses:      See code.
864 //   States:    x
865 //   Return:    0 on success.
866 //              Source code line number on device allocation failure.
867 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
868 //              * State information as per parent.
869 //              * Memory allocation errors.
870 //
871 Int
872 PAF_ASOT_initPhaseDevice(
873     const PAF_ASOT_Params *pP, 
874     const PAF_ASOT_Patchs *pQ, 
875     PAF_ASOT_Config *pC
878     PAF_AST_Config *pAstCfg;
879     Int as;                     /* Audio Stream Number (1, 2, etc.) */
880     Int z;                      /* input/output counter */
881     PAF_SIO_IALG_Obj    *pObj;
882     PAF_SIO_IALG_Config *pAlgConfig;
883     PAF_IALG_Config pafAlgConfig;
885     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
886     as = pAstCfg->as;
887     (void)as; // clear compiler warning in case not used with tracing disabled
889     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
891     if(pP->fxns->bufMemPrint)
892     {
893         PAF_ALG_setup (&pafAlgConfig, 
894             HEAP_ID_INTERNAL,               HEAP_INTERNAL, 
895             HEAP_ID_INTERNAL1,              HEAP_INTERNAL1,
896             HEAP_ID_EXTERNAL,               HEAP_EXTERNAL,
897             HEAP_ID_INTERNAL1_SHM,          HEAP_INTERNAL1_SHM,
898             HEAP_ID_EXTERNAL_SHM,           HEAP_EXTERNAL_SHM,
899             HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
900             HEAP_CLEAR);
901         TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
902     }
903     
904     for (z=OUTPUT1; z < OUTPUTN; z++) 
905     {
906         PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
908         pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
909         pAlgConfig = &pObj->config;
911         pAstCfg->xOut[z].hTxSio = NULL;
912         pConfig->base.pVoid     = pAlgConfig->pMemRec[0].base;
913         pConfig->pntr.pVoid     = pAlgConfig->pMemRec[0].base;
914         pConfig->head.pVoid     = pAlgConfig->pMemRec[0].base;
915         pConfig->allocation     = pAlgConfig->pMemRec[0].size;
916         pConfig->sizeofElement  = 3;
917         pConfig->precision      = 24;
918         if(pP->fxns->bufMemPrint)
919         {
920             pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
921         }
922     }
923     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
925     return 0;
926 } //PAF_ASOT_initPhaseDevice
928 // -----------------------------------------------------------------------------
929 // ASOT Initialization Function Helper - Initialization of Audio Frame
930 //
931 //   Name:      PAF_ASOT_initFrame0
932 //   Purpose:   Audio Stream Output Task Function for initialization of the Audio
933 //              Frame(s) by memory allocation and loading of data pointers
934 //              and values.
935 //   From:      AST Parameter Function -> decodeInfo
936 //   Uses:      See code.
937 //   States:    x
938 //   Return:    0 on success.
939 //              Source code line number on MEM_calloc failure.
940 //              Source code line number on unsupported option.
941 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
942 //              * Memory allocation errors.
943 //              * Unsupported option errors.
944 //
946 // MID 314
947 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
948 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
950 Int
951 PAF_ASOT_initFrame0(
952     const PAF_ASOT_Params *pP, 
953     const PAF_ASOT_Patchs *pQ, 
954     PAF_ASOT_Config *pC, 
955     Int z
958     PAF_AST_Config *pAstCfg;
959     Int as;                     /* Audio Stream Number (1, 2, etc.) */
960     Int ch;
961     //Int aLen;
962     Int aLen_int=0,aLen_ext=0;
963     Int aSize = sizeof(PAF_AudioData);
964     Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
965     Int maxFrameLength = pP->maxFramelength;
966     Int zX;
967     PAF_AudioData *aBuf_int=NULL;
968     PAF_AudioData *aBuf_ext=NULL;
969     XDAS_UInt8 *metadataBuf;
970     char i;
971     Error_Block    eb;
973     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
974     as = pAstCfg->as;
976     // Initialize error block
977     Error_init(&eb); 
979     // Compute maximum framelength (needed for ARC support)
980     maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
981     //aLen = numchan[z] * maxFrameLength;
982     for (i=0; i < numchan[z]; i++)
983     {
984         if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
985         {
986             aLen_int += maxFrameLength;
987         }
988         else
989         {
990             aLen_ext += maxFrameLength;
991         }
992     }
994     //
995     // Initialize audio frame elements directly
996     //
997     pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
998     pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
999 ///    pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
1000     pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
1001     pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
1002     pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
1003     pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1005     //
1006     // Allocate memory for and initialize pointers to audio data buffers
1007     //
1008     //   The NUMCHANMASK is used to identify the channels for which data
1009     //   buffers can be allocated. Using this mask and switch statement
1010     //   rather than some other construct allows efficient code generation,
1011     //   providing just the code necessary (with significant savings).
1012     //
1013     if (pP->fxns->bufMemPrint)
1014     {
1015         pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1016         pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1017     }
1019     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1020     
1021     if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1022     {
1023         if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1024         {
1025             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1026             TRACE_TERSE2("  maxFrameLength: %d.  aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1027             SW_BREAKPOINT;
1028             return __LINE__;
1029         }
1030     }
1031         
1032     if (aLen_ext*aSize!=0)
1033     {
1034         if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset
1035         {
1036             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1037             TRACE_TERSE2("  maxFrameLength: %d.  aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1038             SW_BREAKPOINT;
1039             return __LINE__;
1040         }
1041     }
1042     
1043     TRACE_TERSE3("  maxFrameLength: %d.  aLen_int*aSize: %d.  aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1044     TRACE_TERSE3("  maxFrameLength: %d.  aLen_ext*aSize: %d.  aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1046     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1047     if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1048     {
1049         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1050         TRACE_TERSE1("  bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1051         SW_BREAKPOINT;
1052         return __LINE__;
1053     }
1055     {
1056         Int i;
1058 #pragma UNROLL(1)
1059         for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1060         {
1061             pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1062         }
1063     }
1065     // MID 314
1066     if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1)) 
1067     {
1068         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1069         return __LINE__;
1070     }
1071     else 
1072     {
1073         Int j = 0;
1074         Int k = 0;
1075         TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1076         for(i=0;i<numchan[z];i++)
1077         {
1078             char chan = AFChanPtrMap[numchan[z]][i];
1079             if(chan != -1)
1080             {
1081                 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1082                 {
1083                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1084                     j++;
1085                 }
1086                 else
1087                 {        
1088                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1089                     k++;
1090                 }    
1091                 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1092                 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1093             }
1094         }
1095     }
1097     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1098     {
1099         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1100         {
1101             pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1102         }
1103     }
1105     //
1106     // Initialize meta data elements
1107     //
1108     pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1109     pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1110     pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1111     pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1112     pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1113     for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1114     {
1115         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1116         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1117         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1118     }
1120     //
1121     // Initialize decoder elements directly
1122     //
1124     for (zX = DECODE1; zX < DECODEN; zX++) 
1125     {
1126         if (pP->streamsFromDecodes[zX] == z) 
1127         {
1128 #ifdef NOAUDIOSHARE
1129             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1130             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1131 #else /* NOAUDIOSHARE */
1132             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1133             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1134 #endif /* NOAUDIOSHARE */
1135         }
1136     }
1138     return 0;
1139 } //PAF_ASOT_initFrame0
1141 // -----------------------------------------------------------------------------
1142 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1143 // AST Decoding Function              - Reinitialization of Audio Frame
1144 //
1145 //   Name:      PAF_ASOT_initFrame1
1146 //   Purpose:   Audio Stream Task Function for initialization or reinitiali-
1147 //              zation of the Audio Frame(s) by loading of data values of a
1148 //              time-varying nature.
1149 //   From:      audioStream1Task or equivalent
1150 //              AST Parameter Function -> decodeInfo
1151 //              AST Parameter Function -> decodeDecode
1152 //   Uses:      See code.
1153 //   States:    x
1154 //   Return:    0.
1155 //   Trace:     None.
1156 //
1157 Int
1158 PAF_ASOT_initFrame1(
1159     const PAF_ASOT_Params *pP, 
1160     const PAF_ASOT_Patchs *pQ, 
1161     PAF_ASOT_Config *pC, 
1162     Int z, 
1163     Int apply
1166     PAF_AST_Config *pAstCfg;
1168     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1170     //
1171     // Reinitialize audio frame elements:
1172     //
1173     //   Channel Configurations during sys init                 = Unknown
1174     //      "          "        during info or decode           = None
1175     //
1176     //   Sample Rate / Count    during sys init, info or decode = Unknown / 0
1177     //
1179     if (apply < 0) 
1180     {
1181         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1182         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1183     }
1184     else 
1185     {
1186         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1187         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1188     }
1190     if (apply < 1) 
1191     {
1192         pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1193         pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1194     }
1196     return 0;
1197 } //PAF_ASOT_initFrame1
1199 // -----------------------------------------------------------------------------
1200 // ASOT Selection Function - Output Device Selection
1201 //
1202 //   Name:      PAF_ASOT_selectDevices
1203 //   Purpose:   Audio Stream Output Task Function for selecting the devices used
1204 //              for output.
1205 //   From:      audioStream1Task or equivalent
1206 //   Uses:      See code.
1207 //   States:    x
1208 //   Return:    Error number in standard form (0 on success).
1209 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1210 //              * State information as per parent.
1211 //
1212 Int
1213 PAF_ASOT_selectDevices(
1214     const PAF_ASOT_Params *pP, 
1215     const PAF_ASOT_Patchs *pQ, 
1216     PAF_ASOT_Config *pC
1219     PAF_AST_Config *pAstCfg;
1220     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1221     Int z;                      /* input/output counter */
1222     Int errno = 0;              /* error number */
1223     Int errme;                  /* error number, local */
1224     Int device;
1226     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1227     as = pAstCfg->as;
1228     (void)as;  // clear compiler warning in case not used with tracing disabled
1230     // Select output devices
1231     for (z=OUTPUT1; z < OUTPUTN; z++) 
1232     {
1233         if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0) 
1234         {
1235             TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1237             /* check for valid index into device array */
1238             if (device >= pQ->devout->n)
1239             {
1240                 device = 0; /* treat as device None */
1241             }
1243             errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT, 
1244                 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1245             if (errme)
1246             {
1247                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1248                 if (!errno)
1249                 {
1250                     errno = ASPERR_DEVOUT + errme;
1251                 }
1252                 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1253             }
1254             else 
1255             {
1256                 Int zE;
1258                 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1259                 // register outBufStatus and encodeStatus pointers with output devices
1260                 // This enables proper IEC encapsulation.
1261                 if (pAstCfg->xOut[z].hTxSio) 
1262                 {
1263                     // set max # of output buffers (use override if necessary)
1264                     if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1265                     {
1266                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1267                             (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1268                     }
1269                     else
1270                     {
1271                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1272                             (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1273                     }
1275                     // register PAF_SIO_IALG object address
1276                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1277                         (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1278                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR, 
1279                         (Arg)&pAstCfg->xOut[z].outBufStatus);
1280                     for (zE=ENCODE1; zE < ENCODEN; zE++) 
1281                     {
1282                         if (pP->outputsFromEncodes[zE] == z) 
1283                         {
1284                             SIO_ctrl(pAstCfg->xOut[z].hTxSio, 
1285                                 PAF_SIO_CONTROL_SET_ENCSTATUSADDR, 
1286                                 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1287                             break;
1288                         }
1289                     }
1290                 }
1291             }
1292         }
1294         // if device selected and valid then enable stat tracking if
1295         // required and start clocking
1296         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) 
1297         {
1298             TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1299             errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1300             if (errme)
1301             {
1302                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1303                 SIO_idle(pAstCfg->xOut[z].hTxSio);
1304                 if (!errno)
1305                 {
1306                     errno = ASPERR_DEVOUT + errme;
1307                 }
1308             }
1309         }
1310     }
1312     return errno;
1313 } //PAF_ASOT_selectDevices
1315 // -----------------------------------------------------------------------------
1316 // ASOT Processing Function - Decode Processing
1317 //
1318 //   Name:      PAF_ASOT_decodeProcessing
1319 //   Purpose:   Audio Stream Output Task Function for processing audio data.
1320 //
1321 Int
1322 PAF_ASOT_decodeProcessing(
1323     const PAF_ASOT_Params *pP, 
1324     const PAF_ASOT_Patchs *pQ, 
1325     PAF_ASOT_Config *pC, 
1326     Int sourceSelect
1329     PAF_AST_Config *pAstCfg;
1330     Int z;                              /* decode counter */
1331     Int errno;                          /* error number */
1332     Int getVal;
1333     enum { INIT, STREAM, ENCODE, FINAL, QUIT } state;
1334     state = INIT;
1335     errno = 0; /* error number */
1336     Int frame; // (***) FL: formerly -- decoder input frame count
1337     Int block; // decoder output block count / input frame
1338     Int outSioUpdate;
1339     
1340     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1342     for (;;) 
1343     {
1344         // FL: Check if any change in output SIO, e.g. from Output shortcut.
1345         // Changes will break FSM and allow Output reconfiguration.
1346         if (errno = checkOutSio(pP, pC, &outSioUpdate))
1347         {
1348             TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1349             break;
1350         }
1351         else if (outSioUpdate)
1352         {
1353             TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1354             state = QUIT;
1355         }
1356         
1357         // Process commands (encode)
1358         if (getVal = pP->fxns->encodeCommand(pP, pQ, pC)) 
1359         {
1360             /* ignore */;
1361         }
1363         // Process state (decode)
1364         switch (state) 
1365         {
1366             case INIT: // initial state
1367                 gAsopInitCnt++;
1368                 Log_info0("TaskAsop: state=INIT");
1369             
1370                 // Reset audio frame pointers to original values
1371                 // (may be needed if error occurred).
1372                 for (z=STREAM1; z < STREAMN; z++) 
1373                 {
1374                     Int ch;
1375                     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1376                     {
1377                         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1378                         {
1379                             pAstCfg->xStr[z].audioFrameChannelPointers[ch] = 
1380                                 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1381                         }
1382                     }
1383                 }
1384                 
1385                 // Reset audio frame meta data elements
1386                 {
1387                     Int i;
1388                     
1389                     for (z=STREAM1; z < STREAMN; z++) 
1390                     {
1391                         pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1392                         pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1393                         pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1394                         pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1396                         for (i=0; i<pP->pMetadataBufStatus->NumBuf; i++)
1397                         {
1398                             pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1399                             pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1400                         }
1401                     }
1402                 }
1403                 
1404                 if (errno = pP->fxns->decodeInit(pP, pQ, pC, sourceSelect))
1405                 {
1406                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInit", errno);
1407                     break;
1408                 }
1409                 
1410                 // (***) FL: setup output (ASP chain reset, ENC reset, setCheckRateX, start output)
1411                 //           Contained in INFO1 in combined FSM.
1412                 // Establish secondary timing
1413                 if (errno = pP->fxns->decodeInfo1(pP, pQ, pC, frame, block))
1414                 {
1415                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInfo1", errno);
1416                     break;
1417                 }
1419                 frame = 0;
1420                 block = 0;
1422                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");                
1423                 state = STREAM;
1424                 continue;
1425                 
1426             case STREAM: // stream state
1427                 gAsopStreamCnt++;
1428                 Log_info0("TaskAsop: state=STREAM");
1430                 if (errno = pP->fxns->decodeStream(pP, pQ, pC, frame, block))
1431                 {
1432                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM.  decodeStream err 0x%x", errno);
1433                     break;
1434                 }
1436                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1437                 state = ENCODE;
1438                 continue;
1439                 
1440             case ENCODE: // encode state
1441                 gAsopEncodeCnt++;
1442                 Log_info0("TaskAsop: state=ENCODE");
1444                 if (errno = pP->fxns->decodeEncode(pP, pQ, pC, frame, block))
1445                 {
1446                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE.  decodeEncode err 0x%x", errno);
1447                     break;
1448                 }
1450                 // (***) FL: do we need this? 
1451                 //       AF pointers come from CB read, any resets occur in Decoder AF.
1452                 // Reset audio frame pointers to original values
1453                 // (may have been adjusted by ARC or the like).
1454                 for (z=STREAM1; z < STREAMN; z++) 
1455                 {
1456                     Int ch;
1457                     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1458                     {
1459                         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1460                         {
1461                             pAstCfg->xStr[z].audioFrameChannelPointers[ch] = 
1462                                 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1463                         }
1464                     }
1465                 }
1467                 //
1468                 // (***) FL: update output (setCheckRateX)
1469                 //           Contained in INFO2 in combined FSM.
1470                 if (errno = pP->fxns->decodeInfo2(pP, pQ, pC, frame, block))
1471                 {
1472                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1473                     break;
1474                 }
1476                 block++;
1477                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1478                 state = FINAL;
1479                 continue;
1480                 
1481             case FINAL:
1482                 gAsopFinalCnt++;
1483                 Log_info0("TaskAsop: state=FINAL");
1484                 
1485                 //
1486                 // (***) FL: this needs to be fixed.
1487                 //       (1) Only require selected Output to be in this FSM
1488                 //           => Dec Status checks aren't valid, 
1489                 //              will probably always exit FSM if only Output running
1490                 //       (2) Checking Dec Status info asych to input events (maybe ok)
1491                 //
1492 #if 0
1493                 // Check for final frame, and if indicated:
1494                 // - Update audio flag to cause output buffer flush rather than
1495                 //   the default truncate in "complete" processing.
1496                 // - Exit state machine to "complete" processing.
1497                 if (pP->fxns->decodeFinalTest(pP, pQ, pC, frame, block)) 
1498                 {
1499                     for (z=OUTPUT1; z < OUTPUTN; z++)
1500                     {
1501                         if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1502                         {
1503                             TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1504                             pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1505                         }
1506                     }
1507                     break;
1508                 }
1509 #endif                
1511                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1512                 state = STREAM;
1513                 continue;
1514                 
1515             case QUIT:
1516                 gAsopQuitCnt++;
1517                 Log_info0("TaskAsop: state=QUIT");
1519                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1520                 errno = ASPERR_QUIT;
1521                 break;
1523             default: // unknown state
1524                 // Unknown:
1525                 // - Set error number registers.
1526                 // - Exit state machine to "complete" processing.
1528                 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1529                 errno = ASPERR_UNKNOWNSTATE;
1530                 break;
1532         }  // End of switch (state).
1533         
1534         TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1535         if (pP->fxns->decodeComplete(pP, pQ, pC, NULL, frame, block))
1536         {
1537             /* ignored? */;
1538         }
1539         
1540         return errno;
1541     } // End of for (;;)
1542         
1543     return errno;
1546 // -----------------------------------------------------------------------------
1547 // ASOT Decoding Function - Encode Command Processing
1548 //
1549 //   Name:      PAF_ASOT_encodeCommand
1550 //   Purpose:   Decoding Function for processing Encode Commands.
1551 //   From:      AST Parameter Function -> decodeProcessing
1552 //   Uses:      See code.
1553 //   States:    x
1554 //   Return:    0.
1555 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1556 //              * Command execution.
1557 //              * SIO control errors.
1558 //              * Error number macros.
1559 //
1560 Int
1561 PAF_ASOT_encodeCommand(
1562     const PAF_ASOT_Params *pP, 
1563     const PAF_ASOT_Patchs *pQ, 
1564     PAF_ASOT_Config *pC
1567     PAF_AST_Config *pAstCfg;
1568     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1569     Int z;                      /* encode counter */
1570     Int errno = 0;              /* error number */
1571     Int zO, zS;
1574     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1575     as = pAstCfg->as;
1577     for (z=ENCODE1; z < ENCODEN; z++) 
1578     {
1579         zO = pP->outputsFromEncodes[z];
1580         zS = pP->streamsFromEncodes[z];
1581         if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
1582         {
1583             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
1584             {
1585                 case 0: // command none - process
1586                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1587                     break;
1588                 case 1: // mute command
1589                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
1590                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1591                         && pAstCfg->xOut[zO].hTxSio
1592                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
1593                     {
1594                         errno = (errno & 0xff) | ASPERR_MUTE;
1595                         /* convert to sensical errno */
1596                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
1597                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1598                     }
1599                     else 
1600                     {
1601                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
1602                     }
1603                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1604                     break;
1605                 case 2: // unmute command
1606                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
1607                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1608                         && pAstCfg->xOut[zO].hTxSio
1609                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
1610                     {
1611                         errno = (errno & 0xff) | ASPERR_MUTE;
1612                         /* convert to sensical errno */
1613                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
1614                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1615                     }
1616                     else 
1617                     {
1618                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
1619                     }
1620                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1621                     break;
1622                 default: // command unknown - ignore
1623                     break;
1624             }
1625         }
1626     }
1628     ERRNO_RPRT (TaskAsop, errno);
1630     return 0;
1631 } //PAF_ASOT_encodeCommand
1633 //   Purpose:   Decoding Function for reinitializing the decoding process.
1634 Int
1635 PAF_ASOT_decodeInit(
1636     const PAF_ASOT_Params *pP, 
1637     const PAF_ASOT_Patchs *pQ, 
1638     PAF_ASOT_Config *pC, 
1639     Int sourceSelect
1642     PAF_AST_Config *pAstCfg;
1643     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
1644     Int as;                             /* Audio Stream Number (1, 2, etc.) */
1645     Int z;                              /* decode/encode counter */
1646     Int errno;                          /* error number */
1647     Int zO, zS;
1650     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1651     as = pAstCfg->as;
1653     pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1655     for (z=DECODE1; z < DECODEN; z++)
1656     {
1657         // Start decoder output circular buffer reads
1658         errno = cbReadStart(pCbCtl, z);
1659         if (errno)
1660         {
1661             TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
1662             SW_BREAKPOINT; // FL: debug
1663             return errno;
1664         }
1665         gCbReadAfErr=0;         // reset read circular buffer error count
1666         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
1667         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
1668         
1669         // FL: debug
1670         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
1671     }
1672     
1673     // TODO: move this to start of this function so that it doesn't affect IO timing
1674     for (z=ENCODE1; z < ENCODEN; z++) 
1675     {
1676         zO = pP->outputsFromEncodes[z];
1677         zS = pP->streamsFromEncodes[z];
1678         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
1679         {
1680             Int select = pAstCfg->xEnc[z].encodeStatus.select;
1681             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1682             ENC_Handle enc = (ENC_Handle )encAlg;
1683             TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
1684             if (encAlg->fxns->algActivate)
1685             {
1686                 encAlg->fxns->algActivate (encAlg);
1687             }
1688             if (enc->fxns->reset
1689                 && (errno = enc->fxns->reset(enc, NULL,
1690                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1691             {
1692                 return errno;
1693             }
1694         }
1695     }
1696     
1697     return 0;
1700 // -----------------------------------------------------------------------------
1701 // ASOT Decoding Function - Info Processing, Initial
1702 //
1703 //   Name:      PAF_ASOT_decodeInfo1
1704 //   Purpose:   Decoding Function for processing information in a manner that
1705 //              is unique to initial frames of input data.
1706 //   From:      AST Parameter Function -> decodeProcessing
1707 //   Uses:      See code.
1708 //   States:    x
1709 //   Return:    Error number in standard or SIO form (0 on success).
1710 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1711 //              * State information as per parent.
1712 //
1713 Int
1714 PAF_ASOT_decodeInfo1(
1715     const PAF_ASOT_Params *pP, 
1716     const PAF_ASOT_Patchs *pQ, 
1717     PAF_ASOT_Config *pC, 
1718     Int frame, 
1719     Int block
1722     PAF_AST_Config *pAstCfg;
1723     Int z;                              /* decode/encode counter */
1724     Int errno;                          /* error number */
1726     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1728     // run the chain of ASP's on the stream.
1729     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
1730     if (errno = pP->fxns->streamChainFunction(pP, pQ, pC, 
1731         PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame))
1732     {
1733         TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
1734         return errno;
1735     }
1737     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
1738     for (z=ENCODE1; z < ENCODEN; z++) 
1739     {
1740         Int zO = pP->outputsFromEncodes[z];
1741         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
1742         {
1743             Int select = pAstCfg->xEnc[z].encodeStatus.select;
1744             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1745             ENC_Handle enc = (ENC_Handle )encAlg;
1746             if (enc->fxns->info
1747                 && (errno = enc->fxns->info(enc, NULL,
1748                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1749             {
1750                 TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
1751                 return errno;
1752             }
1753         }
1754     }
1756     if (errno = pP->fxns->setCheckRateX(pP, pQ, pC, 0))
1757     {
1758         // ignore if rateX has changed since we haven't, but are about to,
1759         // start the output. If we didn't ignore this case then the state machine
1760         // would restart unnecessarily, e.g. in the case of SRC, resulting in
1761         // added latency.
1762         if (errno != ASPERR_INFO_RATECHANGE)
1763         {
1764             TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
1765             return errno;
1766         }
1767         else
1768         {
1769             TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
1770         }
1771     }
1773     if (errno = pP->fxns->startOutput(pP, pQ, pC)) 
1774     {
1775         if (errno == 0x105) 
1776         {
1777             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
1778         }
1779         else
1780         {
1781             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
1782         }
1783         return errno;
1784     }    
1785     
1786     return 0;
1789 // -----------------------------------------------------------------------------
1790 // ASOT Decoding Function - Info Processing, Subsequent
1791 //
1792 //   Name:      PAF_ASOT_decodeInfo2
1793 //   Purpose:   Decoding Function for processing information in a manner that
1794 //              is unique to frames of input data other than the initial one.
1795 //   From:      AST Parameter Function -> decodeProcessing
1796 //   Uses:      See code.
1797 //   States:    x
1798 //   Return:    Error number in standard form (0 on success).
1799 //   Trace:     None.
1800 //
1801 Int
1802 PAF_ASOT_decodeInfo2(
1803     const PAF_ASOT_Params *pP, 
1804     const PAF_ASOT_Patchs *pQ, 
1805     PAF_ASOT_Config *pC, 
1806     Int frame, 
1807     Int block
1810     //PAF_AST_Config *pAstCfg;
1811     Int errno;
1813     
1814     //pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1816     errno = pP->fxns->setCheckRateX (pP, pQ, pC, 1);
1817     TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
1818     return errno;
1819 } //PAF_ASOT_decodeInfo2
1821 // -----------------------------------------------------------------------------
1822 // ASOT Decoding Function - Stream Processing
1823 //
1824 //   Name:      PAF_ASOT_decodeStream
1825 //   Purpose:   Decoding Function for processing of audio frame data by the
1826 //              ASP Algorithms.
1827 //   From:      AST Parameter Function -> decodeProcessing
1828 //   Uses:      See code.
1829 //   States:    x
1830 //   Return:    Error number in standard form (0 on success).
1831 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1832 //              * State information as per parent/child.
1833 //
1834 Int
1835 PAF_ASOT_decodeStream(
1836     const PAF_ASOT_Params *pP, 
1837     const PAF_ASOT_Patchs *pQ, 
1838     PAF_ASOT_Config *pC, 
1839     Int frame, 
1840     Int block
1843     PAF_AST_Config *pAstCfg;
1844     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
1845     Int z;                              /* decode/stream counter */
1846     PAF_AudioFrame *pAfRd;
1847     Int cbErrno;
1848     Int errno;
1851     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1852     
1853     pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1855     for (z=DECODE1; z < DECODEN; z++) 
1856     {
1857         Int zS = pP->streamsFromDecodes[z];
1858         
1859         //
1860         // Read decoder output circular buffer
1861         //
1862         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
1863         GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
1864         cbErrno = cbReadAf(pCbCtl, z, pAfRd);
1865         if ((cbErrno < 0) && (cbErrno != ASP_DECOP_CB_READ_UNDERFLOW))
1866         {
1867             gCbReadAfErr++;
1868             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
1869             //SW_BREAKPOINT; // FL: debug
1870             return cbErrno;
1871         }
1873         // Handle underflows
1874         if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
1875         {
1876             // FL: some number of underflows alway occur on start of stream when ASOT only depends on configured Output.
1877             //     DDP: ~2 underflows
1878             //     MAT-THD: ~16 underflows
1879             // Need to check behavior of cbReset().
1880             // Need to check behavior on exit/re-entry into Output processing.
1881             
1882             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
1883             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
1884             {
1885                 // Underflow count above threshold.
1886                 // (1) set max underflow count to threshold
1887                 // (2) reset underflow count
1888                 // (3) reset circular buffer
1889                 
1890                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
1891                 gDecOpCbRdAfUnd = 0; // reset underflow count
1893                 // Reset circular buffer
1894                 cbReset(pCbCtl, z);
1895                 Log_info0("PAF_ASOT_decodeStream:cbReset");
1896             
1897                 return cbErrno;
1898             }
1899         }
1900         else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
1901         {
1902             // No underflow detected.
1903             // update max underflow count,
1904             // reset underflow count
1905             
1906             // update max underflow count
1907             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
1908             {
1909                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
1910             }
1911             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
1912         }
1913         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1914         
1915         
1916 #if 0
1917         if (cbErrno != 0)
1918         {
1919             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
1920             //SW_BREAKPOINT; // FL: debug
1921             
1922             if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
1923             {
1924                 // Reset circular buffer
1925                 cbReset(pCbCtl, z);
1926                 Log_info0("PAF_ASOT_decodeStream:cbReset");
1928                 // Update underflow count, return if above threshold
1929                 gDecOpCbRdAfUnd++;
1930                 if (gDecOpCbRdAfUnd == DEC_OP_CB_RDAF_UND_THR)
1931                 {
1932                     gDecOpCbRdAfUnd = 0;
1933                     return cbErrno;
1934                 }
1935             }
1936         }
1937         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1938         Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
1939 #endif
1940         
1943 #if 1 // (***) FL: shows timing of CB read
1944             //// (***) debug // B8
1945             //{
1946             //    static Uint8 toggleState = 0;
1947             //    if (toggleState == 0)
1948             //        GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
1949             //    else
1950             //        GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1951             //    toggleState = ~(toggleState);
1952             //}
1953 #endif
1955         // FL: debug
1956         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
1957         //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
1958         //{
1959         //    Log_info0("capAfWrite() error");
1960         //}
1961     }
1962             
1963     TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
1964     errno = pP->fxns->streamChainFunction(pP, pQ, pC, 
1965         PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
1966     if (errno)
1967     {
1968         TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
1969         return errno;
1970     }
1972     return 0;
1974 } //PAF_ASOT_decodeStream
1976 // -----------------------------------------------------------------------------
1977 // ASOT Decoding Function - Encode Processing
1978 //
1979 //   Name:      PAF_ASOT_decodeEncode
1980 //   Purpose:   Decoding Function for processing of audio frame data by the
1981 //              Encode Algorithm.
1982 //   From:      AST Parameter Function -> decodeProcessing
1983 //   Uses:      See code.
1984 //   States:    x
1985 //   Return:    Error number in standard or SIO form (0 on success).
1986 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1987 //              * State information as per parent.
1988 //
1989 Int
1990 PAF_ASOT_decodeEncode(
1991     const PAF_ASOT_Params *pP, 
1992     const PAF_ASOT_Patchs *pQ, 
1993     PAF_ASOT_Config *pC, 
1994     Int frame, 
1995     Int block
1998     PAF_AST_Config *pAstCfg;
1999     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2000     Int z;                      /* encode/output counter */
2001     Int errno;                  /* error number */
2002     Int zX, zE, zS;
2003     UInt32 curTime;
2005     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2006     as = pAstCfg->as;
2008     // Await output buffers (but not first time)
2009     for (z=OUTPUT1; z < OUTPUTN; z++) 
2010     {
2011         // determine encoder associated with this output
2012         zE = z;
2013         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2014         {
2015             if (pP->outputsFromEncodes[zX] == z) 
2016             {
2017                 zE = zX;
2018                 break;
2019             }
2020         }
2021         zS = pP->streamsFromEncodes[zE];
2023         if (pAstCfg->xOut[z].hTxSio) 
2024         {
2025             // update length (e.g. ARC may have changed)
2026             pAstCfg->xOut[z].outBufConfig.lengthofFrame = 
2027                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2028             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
2029             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
2030             if (errno < 0)
2031             {
2032                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2033                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
2034                 return -errno; // SIO negates error codes
2035             }
2036             // TODO: use pC->xOut[z].pOutBuf in following ->encode call
2038             //
2039             // Simulate Tx SIO_reclaim() pend
2040             //
2041             //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER); 
2042             gTaskAsopCnt++;
2043             curTime = Clock_getTicks();
2044             //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
2045             //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
2046         }
2047         else 
2048         {
2049             TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
2050         }
2051     }
2053     // Encode data
2054     for (z=ENCODE1; z < ENCODEN; z++) 
2055     {
2056         Int zO = pP->outputsFromEncodes[z];
2057         Int zS = pP->streamsFromEncodes[z];
2058         (void)zS; // clear compiler warning in case not used with tracing disabled
2059         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2060         {
2061             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2062             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2063             ENC_Handle enc = (ENC_Handle )encAlg;
2064             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
2065             {
2066                 pAstCfg->xEnc[z].encodeControl.encActive = select;
2067                 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
2068                 return (-1);
2069             }
2070             TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
2072             // (MID 1933) temp. workaround for PCE2
2073             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
2075           /*
2076           #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2077             {
2078                 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2079                 int *wp;
2080                 wp = (int*)pAudioFrame->data.sample[0];
2081                 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2082                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2083                 wp = (int*)pAudioFrame->data.sample[1];
2084                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2085                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2086                 wp = (int*)pAudioFrame->data.sample[2];
2087                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2088                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2089             }
2090           #endif
2091           */
2093             if (enc->fxns->encode)
2094             {
2095                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2096                         pP->z_pEncodeStatus[z]->encBypass;
2097                 if (errno = enc->fxns->encode(enc, NULL, 
2098                     &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct))
2099                 {
2100                     if (errno != PCEERR_OUTPUT_POINTERNULL)
2101                     {
2102                         TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2103                         return errno;
2104                     }
2105                 }
2106             /*  #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2107                 else
2108                 {
2109                     int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2110                     TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2111                     TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2112                 }
2113               #endif
2114               */
2115             }
2116         }
2117         else 
2118         {
2119             TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2120                 as+pP->streamsFromEncodes[z], block);
2121         }
2122     }
2124     // Transmit data
2125     for (z=OUTPUT1; z < OUTPUTN; z++) 
2126     {
2127         // determine encoder associated with this output
2128         zE = z;
2129         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2130         {
2131             if (pP->outputsFromEncodes[zX] == z) 
2132             {
2133                 zE = zX;
2134                 break;
2135             }
2136         }
2137         zS = pP->streamsFromEncodes[zE];
2139         if (pAstCfg->xOut[z].hTxSio) 
2140         {
2141             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2142             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
2143                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2144             if (errno)
2145             {
2146                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2147                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
2148                 {
2149 //                    statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2150                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2151                 }
2152                 if (errno > 0)
2153                 {
2154                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2155                     return (ASPERR_ISSUE + (z << 4));
2156                 }
2157                 else if (errno < 0)
2158                 {
2159                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2160                     return -errno; // SIO negates error codes
2161                 }
2162             }
2163             if (errno > 0)
2164             {
2165                 return (ASPERR_ISSUE + (z << 4));
2166             }
2167             else if (errno < 0)
2168             {
2169                 return -errno; // SIO negates error codes
2170             }
2171         }
2172         else 
2173         {
2174             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2175         }
2176     }
2178     return 0;
2179 } //PAF_ASOT_decodeEncode
2181 // -----------------------------------------------------------------------------
2182 // ASOT Decoding Function - Stream-Final Processing
2183 //
2184 //   Name:      PAF_ASOT_decodeComplete
2185 //   Purpose:   Decoding Function for terminating the decoding process.
2186 //   From:      AST Parameter Function -> decodeProcessing
2187 //   Uses:      See code.
2188 //   States:    x
2189 //   Return:    0.
2190 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2191 //              * State information as per parent.
2192 //
2193 Int
2194 PAF_ASOT_decodeComplete(
2195     const PAF_ASOT_Params *pP, 
2196     const PAF_ASOT_Patchs *pQ, 
2197     PAF_ASOT_Config *pC, 
2198     ALG_Handle decAlg[], 
2199     Int frame, 
2200     Int block
2203     PAF_AST_Config *pAstCfg;
2204     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2205     Int as;                             /* Audio Stream Number (1, 2, etc.) */
2206     Int z;                              /* decode/encode counter */
2207     Int errno;                          /* error number */
2209     
2210     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2211     as = pAstCfg->as;
2212     (void)as;  // clear compiler warning in case not used with tracing disabled
2214     pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2215     
2216     for (z=DECODE1; z < DECODEN; z++)
2217     {
2218         // Stop decoder output circular buffer reads
2219         errno = cbReadStop(pCbCtl, z);
2220         if (errno)
2221         {
2222             TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2223             SW_BREAKPOINT; // FL: debug
2224             return errno;
2225         }
2226         // FL: debug
2227         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2228     }
2229     
2230     pP->fxns->streamChainFunction(pP, pQ, pC, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2232     for (z=ENCODE1; z < ENCODEN; z++) 
2233     {
2234         Int zO = pP->outputsFromEncodes[z];
2235         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2236         {
2237             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2238             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2239 #ifdef PAF_ASP_FINAL
2240             ENC_Handle enc = (ENC_Handle)encAlg;
2241 #endif /* PAF_ASP_FINAL */
2242             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2243 #ifdef PAF_ASP_FINAL
2244             if (enc->fxns->final)
2245                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2246                                  &pAstCfg->xEnc[z].encodeStatus);
2247 #endif /* PAF_ASP_FINAL */
2248             if (encAlg->fxns->algDeactivate)
2249             {
2250                 encAlg->fxns->algDeactivate(encAlg);
2251             }
2252         }
2253         else 
2254         {
2255             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2256         }
2257     }
2259     // wait for remaining data to be output
2260     pP->fxns->stopOutput(pP, pQ, pC);
2262     return 0;
2263 } //PAF_ASOT_decodeComplete
2265 // -----------------------------------------------------------------------------
2266 // ASOT Decoding Function Helper - SIO Driver Start
2267 //
2268 //   Name:      PAF_ASOT_startOutput
2269 //   Purpose:   Decoding Function for initiating output.
2270 //   From:      AST Parameter Function -> decodeInfo1
2271 //   Uses:      See code.
2272 //   States:    x
2273 //   Return:    Error number in standard or SIO form (0 on success).
2274 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2275 //              * State information as per parent.
2276 //              * SIO control errors.
2277 //
2278 #define DEC_OUTNUMBUF_MAP(X) \
2279       pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2281 Int
2282 PAF_ASOT_startOutput(
2283     const PAF_ASOT_Params *pP, 
2284     const PAF_ASOT_Patchs *pQ, 
2285     PAF_ASOT_Config *pC
2286
2288     PAF_AST_Config *pAstCfg;
2289     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2290     Int z;                      /* output counter */
2291     Int errno,nbufs;            /* error number */
2292     Int zE, zS, zX;
2293     Int zMD;
2294     PAF_SIO_IALG_Obj    *pObj;
2295     PAF_SIO_IALG_Config *pAlgConfig;
2297     
2298     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2299     as = pAstCfg->as;
2300     zMD = pAstCfg->masterDec;
2302     for (z=OUTPUT1; z < OUTPUTN; z++) 
2303     {
2304         if (pAstCfg->xOut[z].hTxSio) 
2305         {
2306             // determine associated encoder and stream
2307             zE = z;
2308             zS = z;
2309             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2310             {
2311                 if (pP->outputsFromEncodes[zX] == z) 
2312                 {
2313                     zE = zX;
2314                     zS = pP->streamsFromEncodes[zE];
2315                     break;
2316                 }
2317             }
2319             // Set sample count so that DOB knows how much data to send
2320             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2321                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2323             if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED) 
2324             {
2325                 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2326                 pAlgConfig = &pObj->config;
2327                 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA, 
2328                     pAlgConfig->pMemRec[0].size);
2329             }
2331             // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2332             // decoder. How should we handle the sourceProgram for multiple decoders?
2333             // Override as needed
2334             nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2335             if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2336             {
2337                 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2338             }
2339             SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2341             if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2342                 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0)) 
2343             {
2344                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2345                 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2346                 return errno;
2347             }
2349             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && 
2350                 (errno =  SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
2351             {
2352                 errno = (errno & 0xff) | ASPERR_MUTE;
2353                 /* convert to sensical errno */
2354                 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2355                 return (errno);
2356             }
2357             else
2358             {
2359                 pAstCfg->xOut[z].outBufStatus.audio
2360                     = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;                
2361             }
2363             TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2364         }
2365     }
2367     return 0;
2368 } //PAF_ASOT_startOutput
2370 // -----------------------------------------------------------------------------
2371 // ASOT Decoding Function Helper - SIO Driver Stop
2372 //
2373 //   Name:      PAF_ASOT_stopOutput
2374 //   Purpose:   Decoding Function for terminating output.
2375 //   From:      AST Parameter Function -> decodeProcessing
2376 //              AST Parameter Function -> decodeComplete
2377 //   Uses:      See code.
2378 //   States:    x
2379 //   Return:    Error number in standard or SIO form (0 on success).
2380 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2381 //              * SIO control errors.
2382 //
2383 Int
2384 PAF_ASOT_stopOutput(
2385     const PAF_ASOT_Params *pP, 
2386     const PAF_ASOT_Patchs *pQ, 
2387     PAF_ASOT_Config *pC
2390     PAF_AST_Config *pAstCfg;
2391     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2392     Int z;                      /* output counter */
2393     Int errno = 0, getVal;
2394     Int zS, zX;
2395     PAF_SIO_IALG_Obj    *pObj;
2396     PAF_SIO_IALG_Config *pAlgConfig;
2398     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2399     as = pAstCfg->as;
2400     (void)as;  // clear compiler warning in case not used with tracing disabled
2402     for (z=OUTPUT1; z < OUTPUTN; z++) 
2403     {
2404         if (pAstCfg->xOut[z].hTxSio) 
2405         {
2406             // determine associated encoder and stream
2407             zS = z;
2408             (void)zS;
2409             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2410             {
2411                 if (pP->outputsFromEncodes[zX] == z) 
2412                 {
2413                     zS = pP->streamsFromEncodes[zX];
2414                     break;
2415                 }
2416             }
2418             // Mute output before audio data termination in the usual case,
2419             // where such termination is due to decode error or user command.
2420             // Identification of this as the usual case is provided by the
2421             // "decode processing" state machine.
2422             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2423                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2424                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
2425             {
2426                 if (!errno) 
2427                 {
2428                     errno = (getVal & 0xff) | ASPERR_MUTE;
2429                     /* convert to sensical errno */
2430                 }
2431                 TRACE_VERBOSE1("PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2432             }
2434             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2436             // Terminate audio data output, truncating (ignore) or flushing
2437             // (play out) final samples as per (1) control register set by
2438             // the user and (2) the type of audio data termination:
2440 #if 0
2441             // This form is not used because driver support for truncating
2442             // data is not supported for internal clocks, although it is
2443             // for external clocks.
2444             getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2445                 pC->xOut[z].outBufStatus.flush
2446                 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2447                 ? 1 : 0);
2448             /* UNTESTED */
2449 #else
2450             // This form should be used when driver support for truncating
2451             // data is supported for both internal and external clocks.
2452             getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2453                 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2454                 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2455                 ? 1 : 0);
2456             /* TESTED */
2457 #endif
2459             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2461             if (!errno)
2462             {
2463                 errno = getVal;
2464             }
2466             // Mute output after audio data termination in a special case,
2467             // where such termination is due to processing of a final frame
2468             // or user command. Identification of this as a special case is
2469             // provided by the "decode processing" state machine.
2470             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2471                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2472                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2473             {
2474                 if (!errno) 
2475                 {
2476                     errno = (getVal & 0xff) | ASPERR_MUTE;
2477                     /* convert to sensical errno */
2478                 }
2479                 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2480             }
2482             pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2484             // zero output buffers
2485             pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2486             pAlgConfig = &pObj->config;
2487             memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2488         } //pAstCfg->xOut[z].hTxSio
2489     }//OUTPUT
2491     return errno;
2492 } //PAF_ASOT_stopOutput
2494 // -----------------------------------------------------------------------------
2495 // ASOT Decoding Function Helper - SIO Driver Change
2496 //
2497 //   Name:      PAF_ASOT_setCheckRateX
2498 //   Purpose:   Decoding Function for reinitiating output.
2499 //   From:      AST Parameter Function -> decodeInfo1
2500 //              AST Parameter Function -> decodeInfo2
2501 //   Uses:      See code.
2502 //   States:    x
2503 //   Return:    Error number in standard form (0 on success).
2504 //   Trace:     None.
2505 //
2507 /* 0: set, 1: check, unused for now. --Kurt */
2508 Int
2509 PAF_ASOT_setCheckRateX(
2510     const PAF_ASOT_Params *pP, 
2511     const PAF_ASOT_Patchs *pQ, 
2512     PAF_ASOT_Config *pC, 
2513     Int check
2516     PAF_AST_Config *pAstCfg;
2517     float rateX;
2518     PAF_SampleRateHz rateO /* std */, rateI /* inv */;
2519     Int z;                              /* output counter */
2520     Int zx;                             /* output re-counter */
2521     Int getVal;
2522     int inputRate, inputCount, outputRate, outputCount;
2523     Int zMD;
2524     Int zMI;
2525     Int zMS;
2526     Int zE, zX;
2528     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2529     zMD = pAstCfg->masterDec;
2530     zMS = pAstCfg->masterStr;
2531     zMI = pP->zone.master;
2533     inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
2534     inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
2535     rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2536         (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
2538     for (z=OUTPUT1; z < OUTPUTN; z++) {
2539         if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) {
2541             // determine associated encoder
2542             zE = z;
2543             for (zX = ENCODE1; zX < ENCODEN; zX++) {
2544                 if (pP->outputsFromEncodes[zX] == z) {
2545                     zE = zX;
2546                     break;
2547                 }
2548             }
2550             outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
2551             outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
2552             rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2553                 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
2554             if (rateI > 0 && rateO > 0)
2555                 rateX = rateO /* std */ * rateI /* inv */;
2556             else if (inputCount != 0)
2557                 rateX = (float )outputCount / inputCount;
2558             else
2559                 return ( ASPERR_INFO_RATERATIO );
2561             getVal = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg) &rateX);
2562             if (getVal == DOBERR_RATECHANGE) {
2563                 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
2564                     if (pAstCfg->xOut[zx].hTxSio)
2565                         SIO_idle (pAstCfg->xOut[zx].hTxSio);
2567                 // this forces an exit from the calling state machine which will
2568                 // eventually call startOutput which calls setCheckRateX for all outputs
2569                 // and so it is ok, in the presence of a rate change on any output, to
2570                 // exit this loop /function early.
2571                 return ASPERR_INFO_RATECHANGE;
2572             }
2573             else if( getVal != SYS_OK )
2574                 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
2575         }
2576     }
2578     return 0;
2579 } //PAF_ASOT_setCheckRateX
2581 // -----------------------------------------------------------------------------
2582 // ASOT Decoding Function Helper - Chain Processing
2583 //
2584 //   Name:      PAF_ASOT_streamChainFunction
2585 //   Purpose:   Common Function for processing algorithm chains.
2586 //   From:      AST Parameter Function -> decodeInfo1
2587 //              AST Parameter Function -> decodeStream
2588 //              AST Parameter Function -> decodeComplete
2589 //   Uses:      See code.
2590 //   States:    x
2591 //   Return:    Error number in standard form (0 on success).
2592 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2593 //              * State information as per parent.
2594 //
2595 Int
2596 PAF_ASOT_streamChainFunction(
2597     const PAF_ASOT_Params *pP, 
2598     const PAF_ASOT_Patchs *pQ, 
2599     PAF_ASOT_Config *pC, 
2600     Int iChainFrameFxns, 
2601     Int abortOnError, 
2602     Int logArg
2605     PAF_AST_Config *pAstCfg;
2606     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2607     Int z;                      /* stream counter */
2608     Int errno;                  /* error number */
2609     Int dFlag, eFlag, gear;
2610     Int zX;
2611     Int zS;
2613     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2614     as = pAstCfg->as;
2615     (void)as; // clear compiler warning in case not used with tracing disabled
2617     for (zS = STREAM1; zS < STREAMN; zS++)
2618     {
2619         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
2621         // apply stream
2622         //      unless the stream is associated with a decoder and it is not running
2623         // or
2624         //      unless the stream is associated with an encoder and it is not running
2625         // Also gear control only works for streams with an associated decoder
2626         // if no such association exists then gear 0 (All) is used
2627         dFlag = 1;
2628         gear = 0;
2629         for (zX = DECODE1; zX < DECODEN; zX++) {
2630             if (pP->streamsFromDecodes[zX] == z) {
2631                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
2632                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
2633                 break;
2634             }
2635         }
2636         eFlag = 1;
2637         for (zX = ENCODE1; zX < ENCODEN; zX++) {
2638             if (pP->streamsFromEncodes[zX] == z) {
2639                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
2640                 break;
2641             }
2642         }
2644         if (dFlag && eFlag) {
2645             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
2646             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
2647             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
2648                 chain->fxns->chainFrameFunction[iChainFrameFxns];
2650             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2651                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
2652                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2653                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
2654                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2655                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
2656                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
2657                        as+z, logArg);
2658             errno = (*func) (chain, frame);
2659             TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
2660                 as+z, errno);
2662             if (errno && abortOnError)
2663                 return errno;
2664         }
2665         else {
2666             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2667                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
2668                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2669                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
2670                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2671                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
2672                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
2673                        as+z, logArg);
2674         }
2676         /*
2677         {
2678             void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
2679             PAF_AudioFrameData *afd;
2680             float ** afPtr;
2682             afd = &(pC->xStr->pAudioFrame->data);
2683             afPtr = (float**)afd->sample;
2684             dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
2686         }
2687         */
2689     }
2691     return 0;
2692 } //PAF_ASOT_streamChainFunction
2694 /* FL: Check if at least one output selected */
2695 static Int checkOutSel(
2696     const PAF_ASOT_Params *pP, 
2697     PAF_ASOT_Config *pC,
2698     Int *pOutSel
2701     PAF_AST_Config *pAstCfg;
2702     Int outSel;
2703     Int z;
2704     
2705     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2707     outSel = 0;
2708     for (z=OUTPUT1; z < OUTPUTN; z++) 
2709     {
2710         if (pAstCfg->xOut[z].hTxSio)
2711         {
2712             outSel = 1;
2713             break;
2714         }
2715     }
2716     
2717     *pOutSel = outSel;
2719     return 0;
2722 /* FL: Check if at least one output sio changed */
2723 static Int checkOutSio(
2724     const PAF_ASOT_Params *pP, 
2725     PAF_ASOT_Config *pC,
2726     Int *pOutSioUpdate
2729     PAF_AST_Config *pAstCfg;
2730     Int outSioUpdate;
2731     Int z;
2732     
2733     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2735     outSioUpdate = 0;
2736     for (z=OUTPUT1; z < OUTPUTN; z++) 
2737     {
2738         if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
2739         {
2740             outSioUpdate = 1;
2741             break;
2742         }
2743     }
2744     
2745     *pOutSioUpdate = outSioUpdate;
2747     return 0;