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