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