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