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