975ea2753fba16d6244bc5f56368f07b833a1c7f
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutProc.c
2 /*
3 Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 /*
37  *  ======== audioStreamOutProc.c ========
38  */
40 #include <string.h> // for memset
41 #include <xdc/runtime/Log.h>
42 #include <xdc/runtime/Error.h>
43 #include <xdc/runtime/Memory.h>
44 #include <ti/sysbios/knl/Clock.h>
45 #include <ti/sysbios/knl/Task.h>
47 #include "paferr.h"
48 #include <acp_mds.h>
49 #include <pcm.h>
50 #include <pce.h>
51 #include <pafsio_ialg.h>
52 #include <stdasp.h>
53 #include <doberr.h>
54 #include "asperr.h"
56 #include "common.h"
57 #include "aspMsg_common.h"
58 #include "aspMsg_master.h"
59 #include "aspDecOpCircBuf_master.h"
60 #include "aspOutInitSync_master.h"
61 #include "audioStreamProc_common.h"
62 #include "audioStreamOutProc.h"
64 #include "pfp/pfp.h"
65 #include "pfp_app.h"        /* contains all PFP ID's */
66 Int32 gNumPfpAsot1=0; // debug
68 // FL: debug
69 #include "evmc66x_gpio_dbg.h"
72 #define TRACE_TIME(a)
74 //
75 // Audio Stream Definitions
76 //
78 //
79 // Audio Stream Processing Definitions
80 //
81 #define aspLinkInit pQ->i_aspLinkInit
83 //
84 // Encoder Definitions
85 //
86 #define encLinkInit pQ->i_encLinkInit
88 //
89 // Output Definitions
90 //
91 #define outLinkInit pP->i_outLinkInit
93 /* ---------------------------------------------------------------- */
94 /*              Parameter macro definitions end here.               */
95 /* ---------------------------------------------------------------- */
97 //
98 // Standardized Definitions
99 //
101 #define ENC_Handle PCE_Handle /* works for all: PCE */
103 #define __TASK_NAME__  "TaskAsop"
106 //
107 // Audio Stream Output Task definitions
108 //
110 // status codes
111 // Output FSM
112 #define ASOP_INITSYNC_NOTREADY      (  1 )  // ok, init-sync not ready
113 #define ASOP_SOK                    (  0 )  // ok
114 #define ASOP_FORWARD_ERR            ( -1 )  // forward (ASIT) error
115 #define ASOP_ENCRESET_ERR           ( -2 )  // enc reset error
116 #define ASOP_DECINFO1_ERR           ( -3 )  // dec info1 error
117 // Decode Processing
118 #define ASOP_DP_OUT_SIO_UPDATE      (  3 )  // new output selected
119 #define ASOP_DP_CB_DRAINED          (  2 )  // circular buffer drained
120 #define ASOP_DP_SOK                 (  0 )  // ok
121 #define ASOP_DP_FORWARD_ERR         ( -1 )  // forward (ASIT) error
122 #define ASOP_DP_DECINIT_ERR         ( -2 )  // decode init error
123 #define ASOP_DP_DECSTREAM_ERR       ( -3 )  // decode stream error
124 #define ASOP_DP_DECENC_ERR          ( -4 )  // decode encode error
125 #define ASOP_DP_DECINFO2_ERR        ( -5 )  // decode encode error
126 #define ASOP_DP_DECFINALTEST_ERR    ( -6 )  // decode final error
130 /* Check if at least one output selected */
131 static Int checkOutSel(
132     const PAF_ASOT_Params *pP, 
133     PAF_ASOT_Config *pAsotCfg,
134     Int *pOutSel
135 );
137 /* Check if at least one output sio changed */
138 static Int checkOutSio(
139     const PAF_ASOT_Params *pP, 
140     PAF_ASOT_Config *pAsotCfg,
141     Int *pOutSioUpdate
142 );
144 // Initialize Output Processing state function
145 static Int PAF_ASOT_initOutProc(
146     const PAF_ASOT_Params *pP, 
147     PAF_AST_Stream *xStr
148 );
150 // Initialize Output Processing state function
151 static Int PAF_ASOT_initSyncDecReset(
152     const PAF_ASOT_Params *pP, 
153     const PAF_ASOT_Patchs *pQ, 
154     PAF_ASOT_Config *pAsotCfg,
155     PAF_AudioFrame *pDecResetAf
156 );
158 //   Purpose:   ASOT Function for resetting output processing.
159 static Int PAF_ASOT_outputReset(
160     const PAF_ASOT_Params *pP, 
161     const PAF_ASOT_Patchs *pQ, 
162     PAF_ASOT_Config *pAsotCfg
163 );
165 //   Purpose:   Init-Sync Dec Info1 state function.
166 //              Performes Dec Info1 Init-Sync.
167 static Int PAF_ASOT_initSyncDecInfo1(
168     const PAF_ASOT_Params *pP, 
169     const PAF_ASOT_Patchs *pQ, 
170     PAF_ASOT_Config *pAsotCfg,
171     PAF_AudioFrame *pDecInfo1Af
172 );
174 //   Purpose:   Init-Sync Dec Decode1 state function.
175 //              Performes Dec Decode1 Init-Sync.
176 static Int PAF_ASOT_initSyncDecDecode1(
177     const PAF_ASOT_Params *pP, 
178     const PAF_ASOT_Patchs *pQ, 
179     PAF_ASOT_Config *pAsotCfg
180 );
182 //   Purpose:   Init-Sync Re-Sync state function.
183 //              Peformed Init-Sync using stored Dec Reset/Info1 AFs.
184 static Int PAF_ASOT_initSyncResync(
185     const PAF_ASOT_Params *pP, 
186     const PAF_ASOT_Patchs *pQ, 
187     PAF_ASOT_Config *pAsotCfg,
188     PAF_AudioFrame *pDecResetAf,
189     PAF_AudioFrame *pDecInfo1Af  
190 );
192 #if 0
193 // Init-Sync update audio frame
194 static Int initSyncUpdateAf(
195     PAF_AudioFrame *dstAf, 
196     PAF_AudioFrame *srcAf
197 );
198 #endif
200 // Reset audio frames
201 static Void resetAfs(
202     const PAF_ASOT_Params *pP, 
203     PAF_AST_Stream *xStr
204 );
206 // Reset audio frame pointers to original values
207 static Void resetAfPointers(
208     const PAF_ASOT_Params *pP, 
209     PAF_AST_Stream *xStr
210 );
212 // Reset audio frame meta data elements
213 static Void resetAfMetadata(
214     const PAF_ASOT_Params *pP, 
215     PAF_AST_Stream *xStr
216 );
219 LINNO_DEFN(TaskAsop); /* Line number macros */
220 ERRNO_DEFN(TaskAsop); /* Error number macros */
222 // ASOT configuration
223 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
224 PAF_ASOT_Config gPAF_ASOT_config = {
225     NULL,               // taskHandle
226     NULL,               // acp
227     0,0,0,              // CB drained flags (size DECODE_MAXN)
228     &gPAF_ASPM_config,  // pAspmCfg
229     &gPAF_AST_config    // pAstCfg
230 };
232 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
233 #define DEC_OP_CB_RDAF_UND_THR  ( 80 ) // FL: arbitrary setting
234 UInt32 gCbReadAfErr         =0; // read circular buffer error count, not including underflows
235 UInt32 gDecOpCbRdAfUnd      =0; // decoder output circular buffer underflow count
236 UInt32 gMaxDecOpCbRdAfUnd   =0; // max (consecutive) decoder output circular buffer underflow count
237 UInt32 gMasterCbResetCnt    =0; // master circular buffer reset count
239 // Global debug counters */
240 UInt32 gTaskAsopCnt=0; // debug
241 UInt32 gAsopInitCnt         =0;
242 UInt32 gAsopStreamCnt       =0;
243 UInt32 gAsopEncodeCnt       =0;
244 UInt32 gAsopFinalCnt        =0;
245 UInt32 gAsopQuitCnt         =0;
246 UInt32 gAsopOutSioUpdateCnt =0;
249 /*
250  *  ======== taskAsopFxn ========
251  *  Audio Stream Output Processing task function
252  */
253 Void taskAsopFxn(
254 //    Int betaPrimeValue, // FL: revisit
255     const PAF_ASOT_Params *pP,
256     const PAF_ASOT_Patchs *pQ
259     PAF_ASOT_Config *pAsotCfg;      /* ASOT configuration pointer */
260     PAF_AST_Config *pAstCfg;        /* Common (shared) configuration pointer */
261     Int as;                         /* Audio Stream Number (1, 2, etc.) */
262     Int z;                          /* input/encode/stream/decode/output counter */
263     Int i;                          /* phase */
264     Int errno;                      /* error number */
265     Int zMS;
266     Int loopCount = 0;  // used to stop trace to see startup behavior.        
267     Int outSel;
268     enum { INIT_OUT_PROC_STATE, 
269            INITSYNC_DEC_RESET_STATE, INITSYNC_DEC_INFO1_STATE, INITSYNC_DEC_DECODE1_STATE, 
270            INITSYNC_RESYNC_STATE, 
271            OUT_PROC_STATE } state;
272     PAF_AudioFrame decResetAf;
273     PAF_AudioFrame decInfo1Af;
274     
276     Log_info0("Enter taskAsopFxn()");    
278     //
279     // Audio Stream Output Task Parameters & Patch (*pP, *pQ)
280     //
281     if (!pP) 
282     {
283         TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
284         LINNO_RPRT(TaskAsop, -1);
285         return;
286     }
288     if (!pQ)
289     {
290         TRACE_TERSE0("TaskAsip: No Patchs defined. Exiting.");
291         LINNO_RPRT(TaskAsop, -1);
292         return;
293     }    
295     //
296     // Audio Stream Output Task Configuration (*pAsotCfg):
297     //
298     pAsotCfg = &gPAF_ASOT_config;       // initialize pointer to task configuration
299     pAsotCfg->taskHandle = Task_self(); // set task handle
300     pAstCfg = pAsotCfg->pAstCfg;        // get pointer to AST common (shared) configuration
302     /* Obtain Audio Stream Number (1, 2, etc.) */    
303     as = pAstCfg->as;
304     TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
306     //
307     // Initialize message log trace and line number reporting
308     //
309     for (z=STREAM1; z < STREAMN; z++)
310     {
311         TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
312     }
313     LINNO_RPRT(TaskAsop, -1);
314     
315     //
316     // Determine stream index
317     //
318     zMS = pAstCfg->masterStr;
320     // Initialize as per parametrized phases:
321     //
322     //   In standard form these are:
323     //      - Malloc: Memory Allocation
324     //      - Config: Configuration Initialization
325     //      - AcpAlg: ACP Algorithm Initialization and Local Attachment
326     //      - Common: Common Memory Initialization
327     //      - AlgKey: Dec/Enc chain to Array Initialization
328     //      - Device: I/O Device Initialization
329     //      - Unused: (available)
330     //      - Unused: (available)
331     //
332     LINNO_RPRT(TaskAsop, -2);
333     for (i=0; i < lengthof(pP->fxns->initPhase); i++)
334     {
335         Int linno;
336         if (pP->fxns->initPhase[i])
337         {
338             linno = pP->fxns->initPhase[i](pP, pQ, pAsotCfg);
339             if (linno) 
340             {
341                 LINNO_RPRT(TaskAsop, linno);
342                 return;
343             }
344         }
345         else 
346         {
347             TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
348         }
349         TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
350         LINNO_RPRT(TaskAsop, -i-3);
351     }
352   
353     //
354     // End of Initialization -- display memory usage report.
355     //
356     if (pP->fxns->memStatusPrint)
357     {
358         pP->fxns->memStatusPrint("ASOT MEMSTAT REPORT",
359             HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, 
360             HEAP_INTERNAL1_SHM, HEAP_EXTERNAL_SHM, HEAP_EXTERNAL_NONCACHED_SHM);
361     }
363     //
364     // Main processing loop
365     //   
366     for (z=STREAM1; z < STREAMN; z++)
367     {
368         TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
369     }
370     
371     state = INIT_OUT_PROC_STATE;    // initialize state
372     errno = 0;                      // reset error indicator
373     for (;;)
374     {
375         loopCount++;
376         TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
378         //
379         // Check forward (ASIT) error here, TBD
380         //
381         
382         // any error forces idling of output
383         if (errno) 
384         {
385             for (z=OUTPUT1; z < OUTPUTN; z++)
386             {
387                 if (pAstCfg->xOut[z].hTxSio)
388                 {
389                     SIO_idle(pAstCfg->xOut[z].hTxSio);
390                 }
391             }
392         
393             TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
394             ERRNO_RPRT(TaskAsop, errno);
395         }        
396         
397         TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
398         Task_sleep(1);
400         // select output devices
401         TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
402         errno = pP->fxns->selectDevices(pP, pQ, pAsotCfg);
403         if (errno)
404         {
405             TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
406             continue;
407         }
409         // if no output selected skip remaining processing
410         errno = checkOutSel(pP, pAsotCfg, &outSel);
411         if (errno < 0)
412         {
413             TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
414             continue;
415         }
416         else if (!outSel)
417         {
418             TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);            
419             continue;
420         }
421         
422         switch (state)
423         {
424             case INIT_OUT_PROC_STATE:
425                 Log_info0("TaskAsop: state=INIT_OUT_PROC_STATE");
426                 
427                 //
428                 // Output Processing initialization.
429                 //
430                 errno = PAF_ASOT_initOutProc(pP, pAstCfg->xStr);
431                 if (errno < 0)
432                 {
433                     state = INIT_OUT_PROC_STATE;
434                 }
435                 else
436                 {
437                     state = INITSYNC_DEC_RESET_STATE;
438                 }
439             
440                 break;
441                 
442             case INITSYNC_DEC_RESET_STATE:
443                 Log_info0("TaskAsop: state=INITSYNC_DEC_RESET_STATE");
445                 //
446                 // Dec Reset Init-Sync.
447                 //  
448                 
449                 // Perform Dec Reset init-sync.
450                 // Latch Dec Reset AF.
451                 errno = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, &decResetAf);
452                 if (errno < 0)
453                 {
454                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE errno=%d", errno);
455                     // sync error -- start over
456                     state = INIT_OUT_PROC_STATE;
457                 }
458                 else if (errno == ASOP_INITSYNC_NOTREADY)
459                 {
460                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE not sync'd errno=%d", errno);
461                     // sync not ready -- try again
462                     state = INITSYNC_DEC_RESET_STATE;
463                     errno=0; // FL: temp hack
464                 }
465                 else // errno==0
466                 {
467                     Log_info1("TaskAsop: state=INITSYNC_DEC_RESET_STATE sync'd, errno=%d", errno);
468                     // sync'd -- move on
469                     state = INITSYNC_DEC_INFO1_STATE;
470                 }
471                 
472                 break;
473             
474             case INITSYNC_DEC_INFO1_STATE:
475                 Log_info0("TaskAsop: state=INITSYNC_DEC_INFO1_STATE");
476                 
477                 //
478                 // Dec Info1 Init-Sync.
479                 //
481                 // Perform Dec Info1 init-sync.
482                 // Latch Dec Info1 AF.
483                 errno = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af);
484                 if (errno < 0)
485                 {
486                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE errno=%d", errno);
487                     // sync error -- start over
488                     state = INIT_OUT_PROC_STATE;
489                 }
490                 else if (errno == ASOP_INITSYNC_NOTREADY)
491                 {
492                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE not sync'd errno=%d", errno);
493                     // sync not ready -- try again
494                     state = INITSYNC_DEC_INFO1_STATE;
495                     errno=0; // FL: temp hack
496                 }
497                 else // errno = 0
498                 {
499                     Log_info1("TaskAsop: state=INITSYNC_DEC_INFO1_STATE sync'd errno=%d", errno);
500                     // sync'd -- move on
501                     state = INITSYNC_DEC_DECODE1_STATE;
502                 }
503                 
504                 break;
505             
506             case INITSYNC_DEC_DECODE1_STATE:
507                 Log_info0("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE");
508                 
509                 //
510                 // Dec Info1 Init-Sync.
511                 //
513                 // Perform Dec Info1 init-sync.
514                 // Latch Dec Info1 AF.
515                 errno = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg);
516                 if (errno < 0)
517                 {
518                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE errno=%d", errno);
519                     // sync error -- start over
520                     state = INIT_OUT_PROC_STATE;
521                 }
522                 else if (errno == ASOP_INITSYNC_NOTREADY)
523                 {
524                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE not sync'd errno=%d", errno);
525                     // sync not ready -- try again
526                     state = INITSYNC_DEC_DECODE1_STATE;
527                     errno=0; // FL: temp hack
528                 }
529                 else // errno = 0
530                 {
531                     Log_info1("TaskAsop: state=INITSYNC_DEC_DECODE1_STATE sync'd errno=%d", errno);
532                     // sync'd -- move on
533                     state = OUT_PROC_STATE;
534                 }
535                 
536                 break;
537             
538             case INITSYNC_RESYNC_STATE:
539                 Log_info0("TaskAsop: state=INITSYNC_RESYNC_STATE");
541                 //
542                 // Re-Sync.
543                 // Use stored AF info from init-sync.
544                 // This is done in case of local error.
545                 //
546                 
547                 // Perform Dec Info1 init-sync.
548                 errno = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf, 
549                     &decInfo1Af);
550                 if (errno < 0)
551                 {
552                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE errno=%d", errno);
553                     // sync error -- start over
554                     state = INIT_OUT_PROC_STATE;
555                 }
556                 else
557                 {
558                     Log_info1("TaskAsop: state=INITSYNC_RESYNC_STATE sync'd errno=%d", errno);
559                     // re-sync'd -- move on
560                     state = OUT_PROC_STATE;
561                 }
562                     
563                 break;
564             
565             case OUT_PROC_STATE:        
566                 Log_info0("TaskAsop: state=OUT_PROC_STATE");
567                 
568                 //
569                 // Output Processing.
570                 //
572                 TRACE_VERBOSE0("TaskAsop: calling decodeProcessing.");
573                 errno = pP->fxns->decodeProcessing(pP, pQ, pAsotCfg);
574                 if (errno < 0)
575                 {
576                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
577                     
578                     //
579                     // Output Processing exit, due to error
580                     //
581                     
582                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);
583                     if (errno == ASOP_DP_FORWARD_ERR)
584                     {
585                         // forward (ASIT) error -- start over
586                         state = INIT_OUT_PROC_STATE;
587                     }
588                     else
589                     {
590                         // local (ASOT) error
591                         state = INITSYNC_RESYNC_STATE;    
592                     }        
593                 }
594                 else if (errno > 0)
595                 {
596                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
598                     //
599                     // Output Processing exit, not due to error
600                     //
602                     TRACE_TERSE1("TaskAsop: decodeProcessing returns 0x%x, continue", errno);                    
603                     if (errno == ASOP_DP_OUT_SIO_UPDATE)
604                     {
605                         // skip re-sync
606                         // resume output processing after new output selected
607                         state = OUT_PROC_STATE;
608                     }
609                 }
610                 else
611                 {
612                     Log_info1("TaskAsop: state=OUT_PROC_STATE errno=%d", errno);
614                     //
615                     // Output Processing exit, normal
616                     //
617                     
618                     TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
619                     
620                     // no error returned if CB drained 
621                     // (i.e. CB drained is normal behavior)
622                     state = OUT_PROC_STATE;
623                 }
624                 
625                 break;
626             
627             default: // unknown state
628                 TRACE_TERSE2("TaskAsop: AS%d: state: unknown, 0x%x", as+zMS, state);
629                 break;
630         }
631     } // End of main processing loop for (;;)
632     
633     //Log_info0("Exit taskAsopFxn()");
636 // -----------------------------------------------------------------------------
637 // AST Initialization Function - Memory Allocation
638 //
639 //   Name:      PAF_ASOT_initPhaseMalloc
640 //   Purpose:   Audio Stream Output Task Function for initialization of data pointers
641 //              by allocation of memory.
642 //   From:      audioStream1Task or equivalent
643 //   Uses:      See code.
644 //   States:    x
645 //   Return:    0 on success.
646 //              Source code line number on MEM_calloc failure.
647 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
648 //              * State information as per parent.
649 //              * Memory allocation errors.
650 //
652 Int
653 PAF_ASOT_initPhaseMalloc (
654     const PAF_ASOT_Params *pP, 
655     const PAF_ASOT_Patchs *pQ, 
656     PAF_ASOT_Config *pAsotCfg
659     PAF_AST_Config *pAstCfg;
660     Int as;                     /* Audio Stream Number (1, 2, etc.) */
661     Int zMS;
662     Error_Block    eb;
663     //Int i;
665     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
666     as = pAstCfg->as;
667     zMS = pAstCfg->masterStr;
669     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
671     // Initialize error block
672     Error_init(&eb); 
674     /* Stream memory */
675     if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
676     {
677         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
678         SW_BREAKPOINT;
679         return __LINE__;
680     }
681     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
682             STREAMN * sizeof (*pAstCfg->xStr),
683             HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
685     {
686         Int z;                          /* stream counter */
688         PAF_AudioFrame *fBuf;
690         if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
691         {
692             TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
693             SW_BREAKPOINT;
694             return __LINE__;
695         }
696         TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
697                 STREAMS * sizeof (*fBuf),
698                 HEAP_ID_INTERNAL, (IArg)fBuf);
700         for (z=STREAM1; z < STREAMN; z++)
701         {
702             pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
703             TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
704         }
705     }
707     /* Encode memory */
708     if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
709     {
710         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
711         SW_BREAKPOINT;
712         return __LINE__;
713     }
714     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
715             ENCODEN * sizeof (*pAstCfg->xEnc),
716             HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
718     /* Output memory */
719     if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb)))
720     {
721         TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
722         SW_BREAKPOINT;
723         return __LINE__;
724     }
725     TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.",
726             OUTPUTN * sizeof (*pAstCfg->xOut),
727             HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
729     TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
730     return 0;
731 } //PAF_ASOT_initPhaseMalloc
733 // -----------------------------------------------------------------------------
734 // ASOT Initialization Function - Memory Initialization from Configuration
735 //
736 //   Name:      PAF_ASOT_initPhaseConfig
737 //   Purpose:   Audio Stream Output Task Function for initialization of data values
738 //              from parameters.
739 //   From:      audioStream1Task or equivalent
740 //   Uses:      See code.
741 //   States:    x
742 //   Return:    0 on success.
743 //              Other as per initFrame0 and initFrame1.
744 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
745 //              * State information as per parent.
746 //
747 Int
748 PAF_ASOT_initPhaseConfig(
749     const PAF_ASOT_Params *pP, 
750     const PAF_ASOT_Patchs *pQ, 
751     PAF_ASOT_Config *pAsotCfg
754     PAF_AST_Config *pAstCfg;
755     Int as;                     /* Audio Stream Number (1, 2, etc.) */
756     Int z;                      /* input/encode/stream/decode/output counter */
757     Int zMS;
759     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
760     as = pAstCfg->as;
761     zMS = pAstCfg->masterStr;
763     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
765     //
766     // Unspecified elements have been initialized to zero during alloc
767     //
769     for (z=STREAM1; z < STREAMN; z++) 
770     {
771         Int linno;
772         if (linno = pP->fxns->initFrame0(pP, pQ, pAsotCfg, z))
773         {
774             return linno;           
775         }
776         if (linno = pP->fxns->initFrame1(pP, pQ, pAsotCfg, z, -1))
777         {
778             return linno;
779         }
780     }
782     for (z=ENCODE1; z < ENCODEN; z++) 
783     {
784         Int zO = pP->outputsFromEncodes[z];
785         Int zS = pP->streamsFromEncodes[z];
786         pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
787         pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
788         pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
789         pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
790         pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
791         pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
792         pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
793         pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
794     }
796     for (z=OUTPUT1; z < OUTPUTN; z++)
797     {
798         pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
799     }
801     TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
802     return 0;
803 } //PAF_ASOT_initPhaseConfig
805 // -----------------------------------------------------------------------------
806 // ASOT Initialization Function - ACP Algorithm Instantiation
807 //
808 //   Name:      PAF_ASOT_initPhaseAcpAlg
809 //   Purpose:   Audio Stream Input Task Function for initialization of ACP by
810 //              instantiation of the algorithm.
811 //   From:      audioStream1Task or equivalent
812 //   Uses:      See code.
813 //   States:    x
814 //   Return:    0 on success.
815 //              Source code line number on ACP Algorithm creation failure.
816 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
817 //              * State information as per parent.
818 //              * Memory allocation errors.
819 //
820 Int
821 PAF_ASOT_initPhaseAcpAlg(
822     const PAF_ASOT_Params *pP, 
823     const PAF_ASOT_Patchs *pQ, 
824     PAF_ASOT_Config *pAsotCfg
827     PAF_AST_Config *pAstCfg;
828     Int as;                     /* Audio Stream Number (1, 2, etc.) */
829     Int z;                      /* input/encode/stream/decode/output counter */
830     Int betaPrimeOffset;
831     ACP_Handle acp;
832     Int zMS;
833     Int zS, zX;
835     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
836     as = pAstCfg->as;
837     zMS = pAstCfg->masterStr;
839     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
841     ACP_MDS_init();
843     if (!(acp = (ACP_Handle )ACP_MDS_create(NULL))) 
844     {
845         TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation  failed", as+zMS);
846         return __LINE__;
847     }
848     pAsotCfg->acp = acp;
850     ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
851         ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
853     for (z=ENCODE1; z < ENCODEN; z++) 
854     {
855         zS = pP->streamsFromEncodes[z];
856         acp->fxns->attach(acp, ACP_SERIES_STD,
857             STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
858             (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
859         acp->fxns->attach(acp, ACP_SERIES_STD,
860             STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
861             (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
862         /* Ignore errors, not reported. */
863     }
865     for (z=OUTPUT1; z < OUTPUTN; z++) 
866     {
867         zS = z;
868         for (zX = ENCODE1; zX < ENCODEN; zX++) 
869         {
870             if (pP->outputsFromEncodes[zX] == z) 
871             {
872                 zS = pP->streamsFromEncodes[zX];
873                 break;
874             }
875         }
876         acp->fxns->attach(acp, ACP_SERIES_STD,
877             STD_BETA_OB + betaPrimeOffset * (as-1+zS),
878             (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
879         /* Ignore errors, not reported. */
880     }
882     TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
884     return 0;
885 } //PAF_ASOT_initPhaseAcpAlg
887 // -----------------------------------------------------------------------------
888 // ASOT Initialization Function - Common Memory
889 //
890 //   Name:      PAF_ASOT_initPhaseCommon
891 //   Purpose:   Audio Stream Output Task Function for allocation of common memory.
892 //   From:      audioStream1Task or equivalent
893 //   Uses:      See code.
894 //   States:    x
895 //   Return:    0 on success.
896 //              Source code line number on PAF_ALG_alloc failure.
897 //              Source code line number on PAF_ALG_mallocMemory failure.
898 //              Source code line number on Decode Chain initialization failure.
899 //              Source code line number on ASP Chain initialization failure.
900 //              Source code line number on Encode Chain initialization failure.
901 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
902 //              * State information as per parent.
903 //              * Memory allocation errors.
904 //
905 Int
906 PAF_ASOT_initPhaseCommon(
907     const PAF_ASOT_Params *pP, 
908     const PAF_ASOT_Patchs *pQ, 
909     PAF_ASOT_Config *pAsotCfg
912     PAF_AST_Config *pAstCfg;
913     Int as;                     /* Audio Stream Number (1, 2, etc.) */
914     Int z;                      /* stream counter */
915     Int g;                      /* gear */
916     ACP_Handle acp;
917     PAF_IALG_Config pafAlgConfig;
918     IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
919    
920     acp = pAsotCfg->acp;
921     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
922     as = pAstCfg->as;
924     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
926     //
927     // Determine memory needs and instantiate algorithms across audio streams
928     //
929     TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
930     PAF_ALG_setup(&pafAlgConfig, 
931         HEAP_ID_INTERNAL,                 HEAP_INTERNAL, 
932         HEAP_ID_INTERNAL1,                HEAP_INTERNAL1, 
933         HEAP_ID_EXTERNAL,                 HEAP_EXTERNAL, 
934         HEAP_ID_INTERNAL1_SHM,            HEAP_INTERNAL1_SHM, 
935         HEAP_ID_EXTERNAL_SHM,             HEAP_EXTERNAL_SHM, 
936         HEAP_ID_EXTERNAL_NONCACHED_SHM,   HEAP_EXTERNAL_NONCACHED_SHM,
937         HEAP_CLEAR);
939     if (pP->fxns->headerPrint)
940     {
941         pP->fxns->headerPrint();        
942     }
944     for (z = STREAM1; z < STREAMN; z++) 
945     {
946         //Int zD, zE, zX;
947         Int zE, zX;
949         TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
951         //
952         // Determine common memory needs for:
953         //  (1) ASP Algorithms
954         //  (2) Encode Algorithms
955         //  (3) Logical Output drivers
956         //
957         PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
959         zE = -1;
960         for (zX = ENCODE1; zX < ENCODEN; zX++) 
961         {
962             if (pP->streamsFromEncodes[zX] == z) 
963             {
964                 zE = zX;
965                 break;
966             }
967         }
969         TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
970         if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z])) 
971         {
972             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
973             TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
974             SW_BREAKPOINT;
975             return __LINE__;
976         }
977         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
978         if (pP->fxns->allocPrint)
979         {
980             pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
981         }
983         if (zE >= 0) 
984         {
985             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
986             if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z])) 
987             {
988                 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
989                 SW_BREAKPOINT;
990                 return __LINE__;
991             }
992             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
993             if (pP->fxns->allocPrint)
994             {
995                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
996             }
997         }
999         //
1000         // Determine common memory needs of Logical IO drivers
1001         //
1003         if (OUTPUT1 <= z && z < OUTPUTN)
1004         {
1005             TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
1006             if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
1007             {
1008                 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
1009                 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
1010                 SW_BREAKPOINT;
1011                 return __LINE__;
1012             }
1013             TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1014             if (pP->fxns->allocPrint)
1015             {
1016                 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
1017             }
1018         }
1019     }
1020     {
1021         // Changes made to share scratch between zones
1022         // Assume maximum 3 zones and scratch common memory is at offset 0;
1023         int max=0;
1024         for (z=STREAM1; z<STREAMN; z++)
1025         {
1026             if (max < common[z][0].size)
1027             {
1028                 max = common[z][0].size;
1029             }
1030         }
1031         common[STREAM1][0].size=max;
1032         for (z=STREAM1+1; z<STREAMN; z++)
1033         {
1034             common[z][0].size = 0;            
1035         }
1036     }
1037         
1038     //
1039     // Allocate common memory for:
1040     //  (1) ASP Algorithms
1041     //  (2) Encode Algorithms
1042     //  (3) Logical Output drivers
1043     //
1044     for (z = STREAM1; z < STREAMN; z++) 
1045     {
1046         //Int zD, zE, zX;
1047         Int zE, zX;
1049         TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
1050         if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig)) 
1051         {
1052             TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
1053             TRACE_TERSE3("AS%d: z: %d.  Size 0x%x", as+z, z, common[z][0].size);
1054             SW_BREAKPOINT;
1055             return __LINE__;
1056         }
1057         TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
1058         // share zone0 scratch with all zones 
1059         common[z][0].base = common[0][0].base;
1060         if (pP->fxns->commonPrint)
1061         {
1062             pP->fxns->commonPrint(common[z], &pafAlgConfig);
1063         }
1065         zE = -1;
1066         for (zX = ENCODE1; zX < ENCODEN; zX++) 
1067         {
1068             if (pP->streamsFromEncodes[zX] == z) 
1069             {
1070                 zE = zX;
1071                 break;
1072             }
1073         }
1075         pAstCfg->xStr[z].aspChain[0] = NULL;
1076         for (g=0; g < GEARS; g++) 
1077         {
1078             PAF_ASP_Chain *chain;
1079             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
1080             chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
1081                 HEAP_INTERNAL, as+z, acp, &trace,
1082                 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
1083             if (!chain) 
1084             {
1085                 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
1086                 return __LINE__;
1087             }
1088             else
1089             {
1090                 pAstCfg->xStr[z].aspChain[g] = chain;
1091             }
1092         }
1094         if (zE >= 0) 
1095         {
1096             PAF_ASP_Chain *chain;
1097             TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
1098             chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
1099                 HEAP_INTERNAL, as+z, acp, &trace,
1100                 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
1101             if (!chain) 
1102             {
1103                 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
1104                 return __LINE__;
1105             }
1106         }
1108         //
1109         // Allocate non-common memories for Logical IO drivers
1110         //    Since these structures are used at run-time we allocate from external memory
1111         if (OUTPUT1 <= z && z < OUTPUTN) 
1112         {
1113             PAF_ASP_Chain *chain;
1114             TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
1115                            as+z, z);
1116             chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
1117                         HEAP_EXTERNAL, as+z, acp, &trace,
1118                         outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
1119             if (!chain) 
1120             {
1121                 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
1122                 return __LINE__;
1123             }
1124         }
1125     }
1126     TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
1128     return 0;
1129 } //PAF_ASOT_initPhaseCommon
1131 // -----------------------------------------------------------------------------
1132 // ASOT Initialization Function - Algorithm Keys
1133 //
1134 //   Name:      PAF_ASOT_initPhaseAlgKey
1135 //   Purpose:   Audio Stream Output Task Function for initialization of data values
1136 //              from parameters for Algorithm Keys.
1137 //   From:      audioStream1Task or equivalent
1138 //   Uses:      See code.
1139 //   States:    x
1140 //   Return:    0.
1141 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1142 //              * State information as per parent.
1143 //
1144 // .............................................................................
1145 Int
1146 PAF_ASOT_initPhaseAlgKey(
1147     const PAF_ASOT_Params *pP, 
1148     const PAF_ASOT_Patchs *pQ, 
1149     PAF_ASOT_Config *pAsotCfg
1152     PAF_AST_Config *pAstCfg;
1153     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1154     Int z;                      /* decode/encode counter */
1155     Int s;                      /* key number */
1156     PAF_ASP_Link *that;
1158     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1159     as = pAstCfg->as;
1160     (void)as; // clear compiler warning in case not used with tracing disabled
1162     TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
1164     for (z=ENCODE1; z < ENCODEN; z++) 
1165     {
1166         for (s=0; s < pP->pEncAlgKey->length; s++) 
1167         {
1168             if ((pP->pEncAlgKey->code[s].full != 0) && 
1169                 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
1170             {
1171                 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
1172             }
1173             /* Cast in interface, for now --Kurt */
1174             else
1175             {
1176                 pAstCfg->xEnc[z].encAlg[s] = NULL;                
1177             }
1178         }
1179     }
1181     return 0;
1182 } //PAF_ASOT_initPhaseAlgKey
1184 // -----------------------------------------------------------------------------
1185 // ASOT Initialization Function - I/O Devices
1186 //
1187 //   Name:      PAF_ASOT_initPhaseDevice
1188 //   Purpose:   Audio Stream Output Task Function for initialization of I/O Devices.
1189 //   From:      audioStream1Task or equivalent
1190 //   Uses:      See code.
1191 //   States:    x
1192 //   Return:    0 on success.
1193 //              Source code line number on device allocation failure.
1194 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1195 //              * State information as per parent.
1196 //              * Memory allocation errors.
1197 //
1198 Int
1199 PAF_ASOT_initPhaseDevice(
1200     const PAF_ASOT_Params *pP, 
1201     const PAF_ASOT_Patchs *pQ, 
1202     PAF_ASOT_Config *pAsotCfg
1205     PAF_AST_Config *pAstCfg;
1206     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1207     Int z;                      /* input/output counter */
1208     PAF_SIO_IALG_Obj    *pObj;
1209     PAF_SIO_IALG_Config *pAlgConfig;
1210     PAF_IALG_Config pafAlgConfig;
1212     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1213     as = pAstCfg->as;
1214     (void)as; // clear compiler warning in case not used with tracing disabled
1216     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
1218     if(pP->fxns->bufMemPrint)
1219     {
1220         PAF_ALG_setup (&pafAlgConfig, 
1221             HEAP_ID_INTERNAL,               HEAP_INTERNAL, 
1222             HEAP_ID_INTERNAL1,              HEAP_INTERNAL1,
1223             HEAP_ID_EXTERNAL,               HEAP_EXTERNAL,
1224             HEAP_ID_INTERNAL1_SHM,          HEAP_INTERNAL1_SHM,
1225             HEAP_ID_EXTERNAL_SHM,           HEAP_EXTERNAL_SHM,
1226             HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
1227             HEAP_CLEAR);
1228         TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
1229     }
1230     
1231     for (z=OUTPUT1; z < OUTPUTN; z++) 
1232     {
1233         PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
1235         pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
1236         pAlgConfig = &pObj->config;
1238         pAstCfg->xOut[z].hTxSio = NULL;
1239         pConfig->base.pVoid     = pAlgConfig->pMemRec[0].base;
1240         pConfig->pntr.pVoid     = pAlgConfig->pMemRec[0].base;
1241         pConfig->head.pVoid     = pAlgConfig->pMemRec[0].base;
1242         pConfig->allocation     = pAlgConfig->pMemRec[0].size;
1243         pConfig->sizeofElement  = 3;
1244         pConfig->precision      = 24;
1245         if(pP->fxns->bufMemPrint)
1246         {
1247             pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
1248         }
1249     }
1250     TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
1252     return 0;
1253 } //PAF_ASOT_initPhaseDevice
1255 // -----------------------------------------------------------------------------
1256 // ASOT Initialization Function Helper - Initialization of Audio Frame
1257 //
1258 //   Name:      PAF_ASOT_initFrame0
1259 //   Purpose:   Audio Stream Output Task Function for initialization of the Audio
1260 //              Frame(s) by memory allocation and loading of data pointers
1261 //              and values.
1262 //   From:      AST Parameter Function -> decodeInfo
1263 //   Uses:      See code.
1264 //   States:    x
1265 //   Return:    0 on success.
1266 //              Source code line number on MEM_calloc failure.
1267 //              Source code line number on unsupported option.
1268 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1269 //              * Memory allocation errors.
1270 //              * Unsupported option errors.
1271 //
1273 // MID 314
1274 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
1275 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
1277 Int
1278 PAF_ASOT_initFrame0(
1279     const PAF_ASOT_Params *pP, 
1280     const PAF_ASOT_Patchs *pQ, 
1281     PAF_ASOT_Config *pAsotCfg, 
1282     Int z
1285     PAF_AST_Config *pAstCfg;
1286     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1287     Int ch;
1288     //Int aLen;
1289     Int aLen_int=0,aLen_ext=0;
1290     Int aSize = sizeof(PAF_AudioData);
1291     Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
1292     Int maxFrameLength = pP->maxFramelength;
1293     Int zX;
1294     PAF_AudioData *aBuf_int=NULL;
1295     PAF_AudioData *aBuf_ext=NULL;
1296     XDAS_UInt8 *metadataBuf;
1297     char i;
1298     Error_Block    eb;
1300     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1301     as = pAstCfg->as;
1303     // Initialize error block
1304     Error_init(&eb); 
1306     // Compute maximum framelength (needed for ARC support)
1307     maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
1308     //aLen = numchan[z] * maxFrameLength;
1309     for (i=0; i < numchan[z]; i++)
1310     {
1311         if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1312         {
1313             aLen_int += maxFrameLength;
1314         }
1315         else
1316         {
1317             aLen_ext += maxFrameLength;
1318         }
1319     }
1321     //
1322     // Initialize audio frame elements directly
1323     //
1324     pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
1325     pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
1326 ///    pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
1327     pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
1328     pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
1329     pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
1330     pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1332     //
1333     // Allocate memory for and initialize pointers to audio data buffers
1334     //
1335     //   The NUMCHANMASK is used to identify the channels for which data
1336     //   buffers can be allocated. Using this mask and switch statement
1337     //   rather than some other construct allows efficient code generation,
1338     //   providing just the code necessary (with significant savings).
1339     //
1340     if (pP->fxns->bufMemPrint)
1341     {
1342         pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1343         pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1344     }
1346     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1347     
1348     if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1349     {
1350         if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1351         {
1352             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1353             TRACE_TERSE2("  maxFrameLength: %d.  aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1354             SW_BREAKPOINT;
1355             return __LINE__;
1356         }
1357     }
1358         
1359     if (aLen_ext*aSize!=0)
1360     {
1361         if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset
1362         {
1363             TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1364             TRACE_TERSE2("  maxFrameLength: %d.  aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1365             SW_BREAKPOINT;
1366             return __LINE__;
1367         }
1368     }
1369     
1370     TRACE_TERSE3("  maxFrameLength: %d.  aLen_int*aSize: %d.  aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1371     TRACE_TERSE3("  maxFrameLength: %d.  aLen_ext*aSize: %d.  aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1373     TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1374     if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1375     {
1376         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1377         TRACE_TERSE1("  bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1378         SW_BREAKPOINT;
1379         return __LINE__;
1380     }
1382     {
1383         Int i;
1385 #pragma UNROLL(1)
1386         for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1387         {
1388             pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1389         }
1390     }
1392     // MID 314
1393     if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1)) 
1394     {
1395         TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1396         return __LINE__;
1397     }
1398     else 
1399     {
1400         Int j = 0;
1401         Int k = 0;
1402         TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1403         for(i=0;i<numchan[z];i++)
1404         {
1405             char chan = AFChanPtrMap[numchan[z]][i];
1406             if(chan != -1)
1407             {
1408                 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1409                 {
1410                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1411                     j++;
1412                 }
1413                 else
1414                 {        
1415                     pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1416                     k++;
1417                 }    
1418                 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1419                 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1420             }
1421         }
1422     }
1424     for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
1425     {
1426         if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1427         {
1428             pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1429         }
1430     }
1432     //
1433     // Initialize meta data elements
1434     //
1435     pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1436     pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1437     pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1438     pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1439     pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1440     for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1441     {
1442         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1443         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1444         pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1445     }
1447     //
1448     // Initialize decoder elements directly
1449     //
1451     for (zX = DECODE1; zX < DECODEN; zX++) 
1452     {
1453         if (pP->streamsFromDecodes[zX] == z) 
1454         {
1455 #ifdef NOAUDIOSHARE
1456             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1457             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1458 #else /* NOAUDIOSHARE */
1459             pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1460             pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1461 #endif /* NOAUDIOSHARE */
1462         }
1463     }
1465     return 0;
1466 } //PAF_ASOT_initFrame0
1468 // -----------------------------------------------------------------------------
1469 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1470 // AST Decoding Function              - Reinitialization of Audio Frame
1471 //
1472 //   Name:      PAF_ASOT_initFrame1
1473 //   Purpose:   Audio Stream Task Function for initialization or reinitiali-
1474 //              zation of the Audio Frame(s) by loading of data values of a
1475 //              time-varying nature.
1476 //   From:      audioStream1Task or equivalent
1477 //              AST Parameter Function -> decodeInfo
1478 //              AST Parameter Function -> decodeDecode
1479 //   Uses:      See code.
1480 //   States:    x
1481 //   Return:    0.
1482 //   Trace:     None.
1483 //
1484 Int
1485 PAF_ASOT_initFrame1(
1486     const PAF_ASOT_Params *pP, 
1487     const PAF_ASOT_Patchs *pQ, 
1488     PAF_ASOT_Config *pAsotCfg, 
1489     Int z, 
1490     Int apply
1493     PAF_AST_Config *pAstCfg;
1495     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1497     //
1498     // Reinitialize audio frame elements:
1499     //
1500     //   Channel Configurations during sys init                 = Unknown
1501     //      "          "        during info or decode           = None
1502     //
1503     //   Sample Rate / Count    during sys init, info or decode = Unknown / 0
1504     //
1506     if (apply < 0) 
1507     {
1508         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1509         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1510     }
1511     else 
1512     {
1513         pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1514         pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1515     }
1517     if (apply < 1) 
1518     {
1519         pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1520         pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1521     }
1523     return 0;
1524 } //PAF_ASOT_initFrame1
1526 // -----------------------------------------------------------------------------
1527 // ASOT Selection Function - Output Device Selection
1528 //
1529 //   Name:      PAF_ASOT_selectDevices
1530 //   Purpose:   Audio Stream Output Task Function for selecting the devices used
1531 //              for output.
1532 //   From:      audioStream1Task or equivalent
1533 //   Uses:      See code.
1534 //   States:    x
1535 //   Return:    Error number in standard form (0 on success).
1536 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1537 //              * State information as per parent.
1538 //
1539 Int
1540 PAF_ASOT_selectDevices(
1541     const PAF_ASOT_Params *pP, 
1542     const PAF_ASOT_Patchs *pQ, 
1543     PAF_ASOT_Config *pAsotCfg
1546     PAF_AST_Config *pAstCfg;
1547     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1548     Int z;                      /* input/output counter */
1549     Int errno = 0;              /* error number */
1550     Int errme;                  /* error number, local */
1551     Int device;
1553     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1554     as = pAstCfg->as;
1555     (void)as;  // clear compiler warning in case not used with tracing disabled
1557     // Select output devices
1558     for (z=OUTPUT1; z < OUTPUTN; z++) 
1559     {
1560         if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0) 
1561         {
1562             TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1564             /* check for valid index into device array */
1565             if (device >= pQ->devout->n)
1566             {
1567                 device = 0; /* treat as device None */
1568             }
1570             errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT, 
1571                 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1572             if (errme)
1573             {
1574                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1575                 if (!errno)
1576                 {
1577                     errno = ASPERR_DEVOUT + errme;
1578                 }
1579                 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1580             }
1581             else 
1582             {
1583                 Int zE;
1585                 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1586                 // register outBufStatus and encodeStatus pointers with output devices
1587                 // This enables proper IEC encapsulation.
1588                 if (pAstCfg->xOut[z].hTxSio) 
1589                 {
1590                     // set max # of output buffers (use override if necessary)
1591                     if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1592                     {
1593                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1594                             (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1595                     }
1596                     else
1597                     {
1598                         SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1599                             (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1600                     }
1602                     // register PAF_SIO_IALG object address
1603                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1604                         (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1605                     SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR, 
1606                         (Arg)&pAstCfg->xOut[z].outBufStatus);
1607                     for (zE=ENCODE1; zE < ENCODEN; zE++) 
1608                     {
1609                         if (pP->outputsFromEncodes[zE] == z) 
1610                         {
1611                             SIO_ctrl(pAstCfg->xOut[z].hTxSio, 
1612                                 PAF_SIO_CONTROL_SET_ENCSTATUSADDR, 
1613                                 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1614                             break;
1615                         }
1616                     }
1617                 }
1618             }
1619         }
1621         // if device selected and valid then enable stat tracking if
1622         // required and start clocking
1623         if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio)) 
1624         {
1625             TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1626             errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1627             if (errme)
1628             {
1629                 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1630                 SIO_idle(pAstCfg->xOut[z].hTxSio);
1631                 if (!errno)
1632                 {
1633                     errno = ASPERR_DEVOUT + errme;
1634                 }
1635             }
1636         }
1637     }
1639     return errno;
1640 } //PAF_ASOT_selectDevices
1643 // -----------------------------------------------------------------------------
1644 // ASOT Processing Function - Decode Processing
1645 //
1646 //   Name:      PAF_ASOT_decodeProcessing
1647 //   Purpose:   Audio Stream Output Task Function for processing audio data.
1648 //
1649 Int
1650 PAF_ASOT_decodeProcessing(
1651     const PAF_ASOT_Params *pP, 
1652     const PAF_ASOT_Patchs *pQ, 
1653     PAF_ASOT_Config *pAsotCfg 
1656     PAF_AST_Config *pAstCfg;
1657     Int errno;                          /* error number */
1658     Int getVal;
1659     enum { INIT, STREAM, ENCODE, FINAL, QUIT, OUT_SIO_UPDATE } state;
1660     state = INIT;
1661     errno = 0; /* error number */
1662     Int frame; // (***) FL: formerly -- decoder input frame count
1663     Int block; // decoder output block count / input frame
1664     Int outSioUpdate;
1665     
1666     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1668     for (;;) 
1669     {
1670         //
1671         // Check forward (ASIT) error here, TBD
1672         //
1673         
1674         
1675         // Check if any change in output SIO, e.g. from Output shortcut.
1676         // Changes will break FSM and allow Output reconfiguration.
1677         errno = checkOutSio(pP, pAsotCfg, &outSioUpdate);
1678         if (errno < 0)
1679         {
1680             TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1681             break;
1682         }
1683         else if (outSioUpdate)
1684         {
1685             TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1686             state = OUT_SIO_UPDATE;
1687         }
1688         
1689         // Process commands (encode)
1690         getVal = pP->fxns->encodeCommand(pP, pQ, pAsotCfg);
1691         if (getVal) 
1692         {
1693             /* ignore */;
1694         }
1696         // Process state (decode)
1697         switch (state) 
1698         {
1699             case INIT: // initial state
1700                 gAsopInitCnt++;
1701                 Log_info0("TaskAsop: state=INIT");
1702             
1703                 frame = 0;
1704                 block = 0;
1706 #if 0 // FL: moved to PAF_ASOT_initOutProc()
1707                 // Reset audio frame pointers to original values
1708                 // (may be needed if error occurred).
1709                 resetAfPointers(pP, pAstCfg->xStr);
1710                 // Reset audio frame meta data elements
1711                 resetAfMetadata(pP, pAstCfg->xStr);
1712 #endif
1714                 errno = pP->fxns->decodeInit(pP, pQ, pAsotCfg);
1715                 if (errno)
1716                 {
1717                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInit", errno);
1718                     errno = ASOP_DP_DECINIT_ERR;
1719                     break;
1720                 }
1721                 
1722 #if 0 // FL: moved to PAF_ASOT_initSyncDecInfo1()
1723                 //
1724                 // Setup output: ASP chain reset, ENC reset, setCheckRateX, start output
1725                 //
1726                 // Establish secondary timing
1727                 errno = pP->fxns->decodeInfo1(pP, pQ, pAsotCfg, frame, block);
1728                 if (errno)
1729                 {
1730                     TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInfo1", errno);
1731                     break;
1732                 }
1733 #endif
1734                 
1735                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");                
1736                 state = STREAM;
1737                 continue;
1738                 
1739             case STREAM: // stream state
1740                 gAsopStreamCnt++;
1741                 Log_info0("TaskAsop: state=STREAM");
1743                 errno = pP->fxns->decodeStream(pP, pQ, pAsotCfg, frame, block);
1744                 if (errno)
1745                 {
1746                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM.  decodeStream err 0x%x", errno);
1747                     errno = ASOP_DP_DECSTREAM_ERR;
1748                     break;
1749                 }
1751                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1752                 state = ENCODE;
1753                 continue;
1754                 
1755             case ENCODE: // encode state
1756                 gAsopEncodeCnt++;
1757                 Log_info0("TaskAsop: state=ENCODE");
1759                 errno = pP->fxns->decodeEncode(pP, pQ, pAsotCfg, frame, block);
1760                 if (errno)
1761                 {
1762                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE.  decodeEncode err 0x%x", errno);
1763                     errno = ASOP_DP_DECENC_ERR;
1764                     break;
1765                 }
1766                 
1767                 // Measure cycles in output processing loop.
1768                 // Only measures cycles spent in loop.
1769                 pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS);
1770                 gNumPfpAsot1--;
1771                 pfpBegin(PFP_ID_ASOT_1, pAsotCfg->taskHandle);
1772                 gNumPfpAsot1++;
1773                 
1774                 // (***) FL: do we need this? 
1775                 //       AF pointers come from CB read, any resets occur in Decoder AF.
1776                 //
1777                 // Reset audio frame pointers to original values
1778                 // (may have been adjusted by ARC or the like).
1779                 resetAfPointers(pP, pAstCfg->xStr);
1781                 // (***) FL: update output (setCheckRateX)
1782                 //           Contained in INFO2 in combined FSM.
1783                 errno = pP->fxns->decodeInfo2(pP, pQ, pAsotCfg, frame, block);
1784                 if (errno)
1785                 {
1786                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1787                     errno = ASOP_DP_DECINFO2_ERR;
1788                     break;
1789                 }
1791                 block++;
1792                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1793                 state = FINAL;
1794                 continue;
1795                 
1796             case FINAL:
1797                 gAsopFinalCnt++;
1798                 Log_info0("TaskAsop: state=FINAL");
1799                 
1800                 //
1801                 // (***) FL: this needs to be fixed.
1802                 //       (1) Only require selected Output to be in this FSM
1803                 //           => Dec Status checks aren't valid, 
1804                 //              will probably always exit FSM if only Output running
1805                 //       (2) Checking Dec Status info asych to input events (maybe ok)
1806                 //
1807                 // Check for final frame, and if indicated:
1808                 // - Update audio flag to cause output buffer flush rather than
1809                 //   the default truncate in "complete" processing.
1810                 // - Exit state machine to "complete" processing.
1811 #if 0
1812                 if (pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block)) 
1813                 {
1814                     for (z=OUTPUT1; z < OUTPUTN; z++)
1815                     {
1816                         if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1817                         {
1818                             TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1819                             pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1820                         }
1821                     }
1822                     break;
1823                 }
1824 #endif
1825                 errno = pP->fxns->decodeFinalTest(pP, pQ, pAsotCfg, frame, block);
1826                 if (errno < 0)
1827                 {
1828                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL break. errno 0x%x", errno);
1829                     errno = ASOP_DP_DECFINALTEST_ERR;
1830                     break;
1831                 }
1832                 else if (errno == ASOP_DP_CB_DRAINED)
1833                 {
1834                     // EOS, exit normally
1835                     TRACE_TERSE1("PAF_ASOT_decodeProcessing: DECODE FINAL normal exit. errno 0x%x", errno);
1836                     errno = ASOP_DP_SOK;
1837                     break;
1838                 }
1840                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1841                 state = STREAM;
1842                 continue;
1843                 
1844             case OUT_SIO_UPDATE:
1845                 gAsopOutSioUpdateCnt++;
1846                 Log_info0("TaskAsop: state=OUT_SIO_UPDATE");
1848                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: OUT_SIO_UPDATE");
1849                 errno = ASOP_DP_OUT_SIO_UPDATE;
1850                 break;
1851                 
1852             case QUIT:
1853                 gAsopQuitCnt++;
1854                 Log_info0("TaskAsop: state=QUIT");
1856                 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1857                 errno = ASPERR_QUIT;
1858                 break;
1860             default: // unknown state
1861                 // Unknown:
1862                 // - Set error number registers.
1863                 // - Exit state machine to "complete" processing.
1865                 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1866                 errno = ASPERR_UNKNOWNSTATE;
1867                 break;
1869         }  // End of switch (state).
1870         
1871         TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1872         if (pP->fxns->decodeComplete(pP, pQ, pAsotCfg, NULL, frame, block))
1873         {
1874             /* ignored? */;
1875         }
1876         
1877         //pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
1878         //gNumPfpAsot1--;
1879         
1880         //return errno;
1881         break;        
1882     } // End of for (;;)
1883         
1884     pfpEnd(PFP_ID_ASOT_1, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
1885     gNumPfpAsot1--;
1886         
1887     return errno;
1890 // -----------------------------------------------------------------------------
1891 // ASOT Decoding Function - Encode Command Processing
1892 //
1893 //   Name:      PAF_ASOT_encodeCommand
1894 //   Purpose:   Decoding Function for processing Encode Commands.
1895 //   From:      AST Parameter Function -> decodeProcessing
1896 //   Uses:      See code.
1897 //   States:    x
1898 //   Return:    0.
1899 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
1900 //              * Command execution.
1901 //              * SIO control errors.
1902 //              * Error number macros.
1903 //
1904 Int
1905 PAF_ASOT_encodeCommand(
1906     const PAF_ASOT_Params *pP, 
1907     const PAF_ASOT_Patchs *pQ, 
1908     PAF_ASOT_Config *pAsotCfg
1911     PAF_AST_Config *pAstCfg;
1912     Int as;                     /* Audio Stream Number (1, 2, etc.) */
1913     Int z;                      /* encode counter */
1914     Int errno = 0;              /* error number */
1915     Int zO, zS;
1918     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1919     as = pAstCfg->as;
1921     for (z=ENCODE1; z < ENCODEN; z++) 
1922     {
1923         zO = pP->outputsFromEncodes[z];
1924         zS = pP->streamsFromEncodes[z];
1925         if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
1926         {
1927             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
1928             {
1929                 case 0: // command none - process
1930                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1931                     break;
1932                 case 1: // mute command
1933                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
1934                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1935                         && pAstCfg->xOut[zO].hTxSio
1936                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
1937                     {
1938                         errno = (errno & 0xff) | ASPERR_MUTE;
1939                         /* convert to sensical errno */
1940                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
1941                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1942                     }
1943                     else 
1944                     {
1945                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
1946                     }
1947                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1948                     break;
1949                 case 2: // unmute command
1950                     TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
1951                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1952                         && pAstCfg->xOut[zO].hTxSio
1953                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
1954                     {
1955                         errno = (errno & 0xff) | ASPERR_MUTE;
1956                         /* convert to sensical errno */
1957                         TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
1958                         TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1959                     }
1960                     else 
1961                     {
1962                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
1963                     }
1964                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1965                     break;
1966                 default: // command unknown - ignore
1967                     break;
1968             }
1969         }
1970     }
1972     ERRNO_RPRT (TaskAsop, errno);
1974     return 0;
1975 } //PAF_ASOT_encodeCommand
1977 //   Purpose:   Decoding Function for reinitializing the decoding process.
1978 Int
1979 PAF_ASOT_decodeInit(
1980     const PAF_ASOT_Params *pP, 
1981     const PAF_ASOT_Patchs *pQ, 
1982     PAF_ASOT_Config *pAsotCfg
1985     //PAF_AST_Config *pAstCfg;
1986     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
1987     //Int as;                             /* Audio Stream Number (1, 2, etc.) */
1988     Int z;                              /* decode/encode counter */
1989     Int errno;                          /* error number */
1990     //Int zO, zS;
1992     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
1993     //as = pAstCfg->as;
1995     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1997     for (z=DECODE1; z < DECODEN; z++)
1998     {
1999         // Start decoder output circular buffer reads
2000         errno = cbReadStart(pCbCtl, z);
2001         if (errno)
2002         {
2003             TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
2004             SW_BREAKPOINT; // debug
2005             return errno;
2006         }
2007         gCbReadAfErr=0;         // reset read circular buffer error count
2008         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
2009         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
2010         gMasterCbResetCnt=0;    // reset master circular buffer reset count
2012         // FL: debug, log circular buffer control variables
2013         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
2014     }
2015     
2016 #if 0 // moved to PAF_ASOT_outputReset()
2017     // TODO: move this to start of this function so that it doesn't affect IO timing
2018     for (z=ENCODE1; z < ENCODEN; z++) 
2019     {
2020         zO = pP->outputsFromEncodes[z];
2021         zS = pP->streamsFromEncodes[z];
2022         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2023         {
2024             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2025             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2026             ENC_Handle enc = (ENC_Handle )encAlg;
2027             TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
2028             if (encAlg->fxns->algActivate)
2029             {
2030                 encAlg->fxns->algActivate (encAlg);
2031             }
2032             if (enc->fxns->reset)
2033             {
2034                 errno = enc->fxns->reset(enc, NULL, 
2035                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus);
2036                 if (errno)
2037                 {
2038                     return errno;
2039                 }
2040             }
2041         }
2042     }
2043 #endif
2044     
2045     return 0;
2048 // -----------------------------------------------------------------------------
2049 // ASOT Decoding Function - Info Processing, Initial
2050 //
2051 //   Name:      PAF_ASOT_decodeInfo1
2052 //   Purpose:   Decoding Function for processing information in a manner that
2053 //              is unique to initial frames of input data.
2054 //   From:      AST Parameter Function -> decodeProcessing
2055 //   Uses:      See code.
2056 //   States:    x
2057 //   Return:    Error number in standard or SIO form (0 on success).
2058 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2059 //              * State information as per parent.
2060 //
2061 Int
2062 PAF_ASOT_decodeInfo1(
2063     const PAF_ASOT_Params *pP, 
2064     const PAF_ASOT_Patchs *pQ, 
2065     PAF_ASOT_Config *pAsotCfg, 
2066     Int frame, 
2067     Int block
2070     PAF_AST_Config *pAstCfg;
2071     Int z;                              /* decode/encode counter */
2072     Int errno;                          /* error number */
2074     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2076     // run the chain of ASP's on the stream.
2077     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
2078     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2079         PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);
2080     if (errno)
2081     {
2082         TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
2083         return errno;
2084     }
2086     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
2087     for (z=ENCODE1; z < ENCODEN; z++) 
2088     {
2089         Int zO = pP->outputsFromEncodes[z];
2090         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2091         {
2092             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2093             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2094             ENC_Handle enc = (ENC_Handle )encAlg;
2095             
2096             if (enc->fxns->info)
2097             {
2098                 errno = enc->fxns->info(enc, NULL,
2099                     &pAstCfg->xEnc[z].encodeControl, 
2100                     &pAstCfg->xEnc[z].encodeStatus);
2101                 if (errno)
2102                 {
2103                     TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
2104                     return errno;
2105                 }
2106             }
2107         }
2108     }
2110     errno = pP->fxns->setCheckRateX(pP, pQ, pAsotCfg, 0);
2111     if (errno)
2112     {
2113         // ignore if rateX has changed since we haven't, but are about to,
2114         // start the output. If we didn't ignore this case then the state machine
2115         // would restart unnecessarily, e.g. in the case of SRC, resulting in
2116         // added latency.
2117         if (errno != ASPERR_INFO_RATECHANGE)
2118         {
2119             TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
2120             return errno;
2121         }
2122         else
2123         {
2124             TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
2125         }
2126     }
2128     errno = pP->fxns->startOutput(pP, pQ, pAsotCfg);
2129     if (errno) 
2130     {
2131         if (errno == 0x105) 
2132         {
2133             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
2134         }
2135         else
2136         {
2137             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
2138         }
2139         return errno;
2140     }    
2141     
2142     return 0;
2145 // -----------------------------------------------------------------------------
2146 // ASOT Decoding Function - Info Processing, Subsequent
2147 //
2148 //   Name:      PAF_ASOT_decodeInfo2
2149 //   Purpose:   Decoding Function for processing information in a manner that
2150 //              is unique to frames of input data other than the initial one.
2151 //   From:      AST Parameter Function -> decodeProcessing
2152 //   Uses:      See code.
2153 //   States:    x
2154 //   Return:    Error number in standard form (0 on success).
2155 //   Trace:     None.
2156 //
2157 Int
2158 PAF_ASOT_decodeInfo2(
2159     const PAF_ASOT_Params *pP, 
2160     const PAF_ASOT_Patchs *pQ, 
2161     PAF_ASOT_Config *pAsotCfg, 
2162     Int frame, 
2163     Int block
2166     //PAF_AST_Config *pAstCfg;
2167     Int errno;
2169     
2170     //pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2172     errno = pP->fxns->setCheckRateX (pP, pQ, pAsotCfg, 1);
2173     TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
2174     return errno;
2175 } //PAF_ASOT_decodeInfo2
2178 PAF_AST_DecOpCircBufStats gCbStats; // FL: debug
2179 // -----------------------------------------------------------------------------
2180 // ASOT Decoding Function - Stream Processing
2181 //
2182 //   Name:      PAF_ASOT_decodeStream
2183 //   Purpose:   Decoding Function for processing of audio frame data by the
2184 //              ASP Algorithms.
2185 //   From:      AST Parameter Function -> decodeProcessing
2186 //   Uses:      See code.
2187 //   States:    x
2188 //   Return:    Error number in standard form (0 on success).
2189 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2190 //              * State information as per parent/child.
2191 //
2192 Int
2193 PAF_ASOT_decodeStream(
2194     const PAF_ASOT_Params *pP, 
2195     const PAF_ASOT_Patchs *pQ, 
2196     PAF_ASOT_Config *pAsotCfg, 
2197     Int frame, 
2198     Int block
2201     PAF_AST_Config *pAstCfg;
2202     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2203     Int z;                              /* decode/stream counter */
2204     PAF_AudioFrame *pAfRd;
2205     Int cbErrno;
2206     PAF_AST_DecOpCircBufStats cbStats;  /* circular buffer statistics */
2207     Int errno;
2210     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2211     
2212     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2213     
2214     for (z=DECODE1; z < DECODEN; z++) 
2215     {
2216         Int zS = pP->streamsFromDecodes[z];
2217         
2218         //
2219         // Read decoder output circular buffer
2220         //
2221         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
2222         //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2223         cbErrno = cbReadAf(pCbCtl, z, pAfRd);
2224         if ((cbErrno < 0) && (cbErrno != ASP_DECOP_CB_READ_UNDERFLOW))
2225         {
2226             gCbReadAfErr++;
2227             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
2228             //SW_BREAKPOINT; // FL: debug
2229             return cbErrno;
2230         }
2232         // Handle underflows
2233         if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
2234         {
2235             // FL: some number of underflows alway occur on start of stream when ASOT only depends on configured Output.
2236             //     DDP: ~2 underflows
2237             //     MAT-THD: ~16 underflows
2238             // Need to check behavior of cbReset().
2239             // Need to check behavior on exit/re-entry into Output processing.
2240             
2241             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
2242             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
2243             {
2244                 // Underflow count above threshold.
2245                 // (1) set max underflow count to threshold
2246                 // (2) reset underflow count
2247                 // (3) reset circular buffer
2248                 
2249                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
2250                 gDecOpCbRdAfUnd = 0; // reset underflow count
2252                 // Reset circular buffer
2253                 cbReset(pCbCtl, z);
2254                 gMasterCbResetCnt++; // increment master circular buffer reset count
2255                 Log_info0("ASOT:cbReset");
2256             
2257                 return cbErrno;
2258             }
2259         }
2260         else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
2261         {
2262             // No underflow detected.
2263             // update max underflow count,
2264             // reset underflow count
2265             
2266             // update max underflow count
2267             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
2268             {
2269                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
2270             }
2271             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
2272         }
2273         //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2274         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2275         Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
2276         
2277 #if 0 // (***) FL: shows timing of CB read
2278             // (***) debug // B8
2279             {
2280                 static Uint8 toggleState = 0;
2281                 if (toggleState == 0)
2282                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2283                 else
2284                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2285                 toggleState = ~(toggleState);
2286             }
2287 #endif
2289         // FL: debug
2290         // Get circular buffer statistics (debug)
2291         //cbGetStats(pCbCtl, z, &cbStats);
2292         cbGetStats(pCbCtl, z, &gCbStats);
2294         // FL: debug
2295         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
2296         //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
2297         //{
2298         //    Log_info0("capAfWrite() error");
2299         //}
2300     }
2301             
2302     TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
2303     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, 
2304         PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
2305     if (errno)
2306     {
2307         TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
2308         return errno;
2309     }
2311     return 0;
2313 } //PAF_ASOT_decodeStream
2315 // -----------------------------------------------------------------------------
2316 // ASOT Decoding Function - Encode Processing
2317 //
2318 //   Name:      PAF_ASOT_decodeEncode
2319 //   Purpose:   Decoding Function for processing of audio frame data by the
2320 //              Encode Algorithm.
2321 //   From:      AST Parameter Function -> decodeProcessing
2322 //   Uses:      See code.
2323 //   States:    x
2324 //   Return:    Error number in standard or SIO form (0 on success).
2325 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2326 //              * State information as per parent.
2327 //
2328 Int
2329 PAF_ASOT_decodeEncode(
2330     const PAF_ASOT_Params *pP, 
2331     const PAF_ASOT_Patchs *pQ, 
2332     PAF_ASOT_Config *pAsotCfg, 
2333     Int frame, 
2334     Int block
2337     PAF_AST_Config *pAstCfg;
2338     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2339     Int z;                      /* encode/output counter */
2340     Int errno;                  /* error number */
2341     Int zX, zE, zS;
2342     UInt32 curTime;
2344     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2345     as = pAstCfg->as;
2347     // Await output buffers (but not first time)
2348     for (z=OUTPUT1; z < OUTPUTN; z++) 
2349     {
2350         // determine encoder associated with this output
2351         zE = z;
2352         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2353         {
2354             if (pP->outputsFromEncodes[zX] == z) 
2355             {
2356                 zE = zX;
2357                 break;
2358             }
2359         }
2360         zS = pP->streamsFromEncodes[zE];
2362         if (pAstCfg->xOut[z].hTxSio) 
2363         {
2364             // update length (e.g. ARC may have changed)
2365             pAstCfg->xOut[z].outBufConfig.lengthofFrame = 
2366                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2367             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
2368             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
2369             if (errno < 0)
2370             {
2371                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2372                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
2373                 return -errno; // SIO negates error codes
2374             }
2375             // TODO: use pC->xOut[z].pOutBuf in following ->encode call
2377 #if 0 // (***) FL: shows timing of Output Rx SIO reclaim
2378             // (***) debug // B8
2379             {
2380                 static Uint8 toggleState = 0;
2381                 if (toggleState == 0)
2382                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2383                 else
2384                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2385                 toggleState = ~(toggleState);
2386             }
2387 #endif            
2389             //
2390             // Simulate Tx SIO_reclaim() pend
2391             //
2392             //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER); 
2393             gTaskAsopCnt++;
2394             curTime = Clock_getTicks();
2395             //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
2396             //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
2397         }
2398         else 
2399         {
2400             TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
2401         }
2402     }
2404     // Encode data
2405     for (z=ENCODE1; z < ENCODEN; z++) 
2406     {
2407         Int zO = pP->outputsFromEncodes[z];
2408         Int zS = pP->streamsFromEncodes[z];
2409         (void)zS; // clear compiler warning in case not used with tracing disabled
2410         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2411         {
2412             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2413             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2414             ENC_Handle enc = (ENC_Handle )encAlg;
2415             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
2416             {
2417                 pAstCfg->xEnc[z].encodeControl.encActive = select;
2418                 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
2419                 return (-1);
2420             }
2421             TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
2423             // (MID 1933) temp. workaround for PCE2
2424             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
2426           /*
2427           #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2428             {
2429                 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2430                 int *wp;
2431                 wp = (int*)pAudioFrame->data.sample[0];
2432                 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2433                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2434                 wp = (int*)pAudioFrame->data.sample[1];
2435                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2436                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2437                 wp = (int*)pAudioFrame->data.sample[2];
2438                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2439                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2440             }
2441           #endif
2442           */
2444             if (enc->fxns->encode)
2445             {
2446                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2447                         pP->z_pEncodeStatus[z]->encBypass;
2448                 errno = enc->fxns->encode(enc, NULL, 
2449                     &pAstCfg->xEnc[z].encodeInStruct, 
2450                     &pAstCfg->xEnc[z].encodeOutStruct);
2451                 if (errno)
2452                 {
2453                     if (errno != PCEERR_OUTPUT_POINTERNULL)
2454                     {
2455                         TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2456                         return errno;
2457                     }
2458                 }
2459             /*  #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2460                 else
2461                 {
2462                     int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2463                     TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2464                     TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2465                 }
2466               #endif
2467               */
2468             }
2469         }
2470         else 
2471         {
2472             TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2473                 as+pP->streamsFromEncodes[z], block);
2474         }
2475     }
2477     // Transmit data
2478     for (z=OUTPUT1; z < OUTPUTN; z++) 
2479     {
2480         // determine encoder associated with this output
2481         zE = z;
2482         for (zX = ENCODE1; zX < ENCODEN; zX++) 
2483         {
2484             if (pP->outputsFromEncodes[zX] == z) 
2485             {
2486                 zE = zX;
2487                 break;
2488             }
2489         }
2490         zS = pP->streamsFromEncodes[zE];
2492         if (pAstCfg->xOut[z].hTxSio) 
2493         {
2494             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2495             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
2496                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2497             if (errno)
2498             {
2499                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2500                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
2501                 {
2502 //                    statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2503                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2504                 }
2505                 if (errno > 0)
2506                 {
2507                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2508                     return (ASPERR_ISSUE + (z << 4));
2509                 }
2510                 else if (errno < 0)
2511                 {
2512                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2513                     return -errno; // SIO negates error codes
2514                 }
2515             }
2516             if (errno > 0)
2517             {
2518                 return (ASPERR_ISSUE + (z << 4));
2519             }
2520             else if (errno < 0)
2521             {
2522                 return -errno; // SIO negates error codes
2523             }
2524         }
2525         else 
2526         {
2527             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2528         }
2529     }
2531     return 0;
2532 } //PAF_ASOT_decodeEncode
2534 // -----------------------------------------------------------------------------
2535 // ASOT Decoding Function - Stream-Final Processing
2536 //
2537 //   Name:      PAF_ASOT_decodeComplete
2538 //   Purpose:   Decoding Function for terminating the decoding process.
2539 //   From:      AST Parameter Function -> decodeProcessing
2540 //   Uses:      See code.
2541 //   States:    x
2542 //   Return:    0.
2543 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2544 //              * State information as per parent.
2545 //
2546 Int
2547 PAF_ASOT_decodeComplete(
2548     const PAF_ASOT_Params *pP, 
2549     const PAF_ASOT_Patchs *pQ, 
2550     PAF_ASOT_Config *pAsotCfg, 
2551     ALG_Handle decAlg[], 
2552     Int frame, 
2553     Int block
2556     PAF_AST_Config *pAstCfg;
2557     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
2558     Int as;                             /* Audio Stream Number (1, 2, etc.) */
2559     Int z;                              /* decode/encode counter */
2560     Int errno;                          /* error number */
2562     
2563     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2564     as = pAstCfg->as;
2565     (void)as;  // clear compiler warning in case not used with tracing disabled
2567     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2568     
2569     for (z=DECODE1; z < DECODEN; z++)
2570     {
2571         // Stop decoder output circular buffer reads
2572         errno = cbReadStop(pCbCtl, z);
2573         if (errno)
2574         {
2575             TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2576             SW_BREAKPOINT; // FL: debug
2577             return errno;
2578         }
2579         // FL: debug
2580         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2581     }
2582     
2583     pP->fxns->streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2585     for (z=ENCODE1; z < ENCODEN; z++) 
2586     {
2587         Int zO = pP->outputsFromEncodes[z];
2588         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
2589         {
2590             Int select = pAstCfg->xEnc[z].encodeStatus.select;
2591             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2592 #ifdef PAF_ASP_FINAL
2593             ENC_Handle enc = (ENC_Handle)encAlg;
2594 #endif /* PAF_ASP_FINAL */
2595             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2596 #ifdef PAF_ASP_FINAL
2597             if (enc->fxns->final)
2598                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2599                                  &pAstCfg->xEnc[z].encodeStatus);
2600 #endif /* PAF_ASP_FINAL */
2601             if (encAlg->fxns->algDeactivate)
2602             {
2603                 encAlg->fxns->algDeactivate(encAlg);
2604             }
2605         }
2606         else 
2607         {
2608             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2609         }
2610     }
2612     // wait for remaining data to be output
2613     pP->fxns->stopOutput(pP, pQ, pAsotCfg);
2615     return 0;
2616 } //PAF_ASOT_decodeComplete
2618 // -----------------------------------------------------------------------------
2619 // ASOT Decoding Function Helper - SIO Driver Start
2620 //
2621 //   Name:      PAF_ASOT_startOutput
2622 //   Purpose:   Decoding Function for initiating output.
2623 //   From:      AST Parameter Function -> decodeInfo1
2624 //   Uses:      See code.
2625 //   States:    x
2626 //   Return:    Error number in standard or SIO form (0 on success).
2627 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2628 //              * State information as per parent.
2629 //              * SIO control errors.
2630 //
2631 #define DEC_OUTNUMBUF_MAP(X) \
2632       pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2634 Int
2635 PAF_ASOT_startOutput(
2636     const PAF_ASOT_Params *pP, 
2637     const PAF_ASOT_Patchs *pQ, 
2638     PAF_ASOT_Config *pAsotCfg
2639
2641     PAF_AST_Config *pAstCfg;
2642     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2643     Int z;                      /* output counter */
2644     Int errno,nbufs;            /* error number */
2645     Int zE, zS, zX;
2646     Int zMD;
2647     PAF_SIO_IALG_Obj    *pObj;
2648     PAF_SIO_IALG_Config *pAlgConfig;
2650     
2651     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2652     as = pAstCfg->as;
2653     zMD = pAstCfg->masterDec;
2655     for (z=OUTPUT1; z < OUTPUTN; z++) 
2656     {
2657         if (pAstCfg->xOut[z].hTxSio) 
2658         {
2659             // determine associated encoder and stream
2660             zE = z;
2661             zS = z;
2662             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2663             {
2664                 if (pP->outputsFromEncodes[zX] == z) 
2665                 {
2666                     zE = zX;
2667                     zS = pP->streamsFromEncodes[zE];
2668                     break;
2669                 }
2670             }
2672             // Set sample count so that DOB knows how much data to send
2673             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2674                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2676             if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED) 
2677             {
2678                 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2679                 pAlgConfig = &pObj->config;
2680                 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA, 
2681                     pAlgConfig->pMemRec[0].size);
2682             }
2684             // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2685             // decoder. How should we handle the sourceProgram for multiple decoders?
2686             // Override as needed
2687             nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2688             if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2689             {
2690                 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2691             }
2692             SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2694             if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2695                 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0)) 
2696             {
2697                 SIO_idle(pAstCfg->xOut[z].hTxSio);
2698                 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2699                 return errno;
2700             }
2702             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) && 
2703                 (errno =  SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
2704             {
2705                 errno = (errno & 0xff) | ASPERR_MUTE;
2706                 /* convert to sensical errno */
2707                 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2708                 return (errno);
2709             }
2710             else
2711             {
2712                 pAstCfg->xOut[z].outBufStatus.audio
2713                     = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;                
2714             }
2716             TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2717         }
2718     }
2720     return 0;
2721 } //PAF_ASOT_startOutput
2723 // -----------------------------------------------------------------------------
2724 // ASOT Decoding Function Helper - SIO Driver Stop
2725 //
2726 //   Name:      PAF_ASOT_stopOutput
2727 //   Purpose:   Decoding Function for terminating output.
2728 //   From:      AST Parameter Function -> decodeProcessing
2729 //              AST Parameter Function -> decodeComplete
2730 //   Uses:      See code.
2731 //   States:    x
2732 //   Return:    Error number in standard or SIO form (0 on success).
2733 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2734 //              * SIO control errors.
2735 //
2736 Int
2737 PAF_ASOT_stopOutput(
2738     const PAF_ASOT_Params *pP, 
2739     const PAF_ASOT_Patchs *pQ, 
2740     PAF_ASOT_Config *pAsotCfg
2743     PAF_AST_Config *pAstCfg;
2744     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2745     Int z;                      /* output counter */
2746     Int errno = 0, getVal;
2747     Int zS, zX;
2748     PAF_SIO_IALG_Obj    *pObj;
2749     PAF_SIO_IALG_Config *pAlgConfig;
2751     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2752     as = pAstCfg->as;
2753     (void)as;  // clear compiler warning in case not used with tracing disabled
2755     for (z=OUTPUT1; z < OUTPUTN; z++) 
2756     {
2757         if (pAstCfg->xOut[z].hTxSio) 
2758         {
2759             // determine associated encoder and stream
2760             zS = z;
2761             (void)zS;
2762             for (zX = ENCODE1; zX < ENCODEN; zX++) 
2763             {
2764                 if (pP->outputsFromEncodes[zX] == z) 
2765                 {
2766                     zS = pP->streamsFromEncodes[zX];
2767                     break;
2768                 }
2769             }
2771             // Mute output before audio data termination in the usual case,
2772             // where such termination is due to decode error or user command.
2773             // Identification of this as the usual case is provided by the
2774             // "decode processing" state machine.
2775             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2776                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2777                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
2778             {
2779                 if (!errno) 
2780                 {
2781                     errno = (getVal & 0xff) | ASPERR_MUTE;
2782                     /* convert to sensical errno */
2783                 }
2784                 TRACE_VERBOSE1("PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2785             }
2787             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2789             // Terminate audio data output, truncating (ignore) or flushing
2790             // (play out) final samples as per (1) control register set by
2791             // the user and (2) the type of audio data termination:
2793 #if 0
2794             // This form is not used because driver support for truncating
2795             // data is not supported for internal clocks, although it is
2796             // for external clocks.
2797             getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2798                 pC->xOut[z].outBufStatus.flush
2799                 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2800                 ? 1 : 0);
2801             /* UNTESTED */
2802 #else
2803             // This form should be used when driver support for truncating
2804             // data is supported for both internal and external clocks.
2805             getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2806                 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2807                 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2808                 ? 1 : 0);
2809             /* TESTED */
2810 #endif
2812             TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2814             if (!errno)
2815             {
2816                 errno = getVal;
2817             }
2819             // Mute output after audio data termination in a special case,
2820             // where such termination is due to processing of a final frame
2821             // or user command. Identification of this as a special case is
2822             // provided by the "decode processing" state machine.
2823             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2824                 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2825                 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2826             {
2827                 if (!errno) 
2828                 {
2829                     errno = (getVal & 0xff) | ASPERR_MUTE;
2830                     /* convert to sensical errno */
2831                 }
2832                 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput:  AS%d: SIO control failed (mute)", as+zS);
2833             }
2835             pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2837             // zero output buffers
2838             pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2839             pAlgConfig = &pObj->config;
2840             memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2841         } //pAstCfg->xOut[z].hTxSio
2842     }//OUTPUT
2844     return errno;
2845 } //PAF_ASOT_stopOutput
2847 // -----------------------------------------------------------------------------
2848 // ASOT Decoding Function Helper - SIO Driver Change
2849 //
2850 //   Name:      PAF_ASOT_setCheckRateX
2851 //   Purpose:   Decoding Function for reinitiating output.
2852 //   From:      AST Parameter Function -> decodeInfo1
2853 //              AST Parameter Function -> decodeInfo2
2854 //   Uses:      See code.
2855 //   States:    x
2856 //   Return:    Error number in standard form (0 on success).
2857 //   Trace:     None.
2858 //
2860 /* 0: set, 1: check, unused for now. --Kurt */
2861 Int
2862 PAF_ASOT_setCheckRateX(
2863     const PAF_ASOT_Params *pP, 
2864     const PAF_ASOT_Patchs *pQ, 
2865     PAF_ASOT_Config *pAsotCfg, 
2866     Int check
2869     PAF_AST_Config *pAstCfg;
2870     float rateX;
2871     PAF_SampleRateHz rateO /* std */, rateI /* inv */;
2872     Int z;                              /* output counter */
2873     Int zx;                             /* output re-counter */
2874     Int getVal;
2875     int inputRate, inputCount, outputRate, outputCount;
2876     Int zMD;
2877     Int zMI;
2878     Int zMS;
2879     Int zE, zX;
2881     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2882     zMD = pAstCfg->masterDec;
2883     zMS = pAstCfg->masterStr;
2884     zMI = pP->zone.master;
2886     inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
2887     inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
2888     rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2889         (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
2891     for (z=OUTPUT1; z < OUTPUTN; z++) {
2892         if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) {
2894             // determine associated encoder
2895             zE = z;
2896             for (zX = ENCODE1; zX < ENCODEN; zX++) {
2897                 if (pP->outputsFromEncodes[zX] == z) {
2898                     zE = zX;
2899                     break;
2900                 }
2901             }
2903             outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
2904             outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
2905             rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2906                 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
2907             if (rateI > 0 && rateO > 0)
2908                 rateX = rateO /* std */ * rateI /* inv */;
2909             else if (inputCount != 0)
2910                 rateX = (float )outputCount / inputCount;
2911             else
2912                 return ( ASPERR_INFO_RATERATIO );
2914             getVal = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg) &rateX);
2915             if (getVal == DOBERR_RATECHANGE) {
2916                 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
2917                     if (pAstCfg->xOut[zx].hTxSio)
2918                         SIO_idle (pAstCfg->xOut[zx].hTxSio);
2920                 // this forces an exit from the calling state machine which will
2921                 // eventually call startOutput which calls setCheckRateX for all outputs
2922                 // and so it is ok, in the presence of a rate change on any output, to
2923                 // exit this loop /function early.
2924                 return ASPERR_INFO_RATECHANGE;
2925             }
2926             else if( getVal != SYS_OK )
2927                 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
2928         }
2929     }
2931     return 0;
2932 } //PAF_ASOT_setCheckRateX
2934 // -----------------------------------------------------------------------------
2935 // ASOT Decoding Function Helper - Chain Processing
2936 //
2937 //   Name:      PAF_ASOT_streamChainFunction
2938 //   Purpose:   Common Function for processing algorithm chains.
2939 //   From:      AST Parameter Function -> decodeInfo1
2940 //              AST Parameter Function -> decodeStream
2941 //              AST Parameter Function -> decodeComplete
2942 //   Uses:      See code.
2943 //   States:    x
2944 //   Return:    Error number in standard form (0 on success).
2945 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
2946 //              * State information as per parent.
2947 //
2948 Int
2949 PAF_ASOT_streamChainFunction(
2950     const PAF_ASOT_Params *pP, 
2951     const PAF_ASOT_Patchs *pQ, 
2952     PAF_ASOT_Config *pAsotCfg, 
2953     Int iChainFrameFxns, 
2954     Int abortOnError, 
2955     Int logArg
2958     PAF_AST_Config *pAstCfg;
2959     Int as;                     /* Audio Stream Number (1, 2, etc.) */
2960     Int z;                      /* stream counter */
2961     Int errno;                  /* error number */
2962     Int dFlag, eFlag, gear;
2963     Int zX;
2964     Int zS;
2966     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
2967     as = pAstCfg->as;
2968     (void)as; // clear compiler warning in case not used with tracing disabled
2970     for (zS = STREAM1; zS < STREAMN; zS++)
2971     {
2972         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
2974         // apply stream
2975         //      unless the stream is associated with a decoder and it is not running
2976         // or
2977         //      unless the stream is associated with an encoder and it is not running
2978         // Also gear control only works for streams with an associated decoder
2979         // if no such association exists then gear 0 (All) is used
2980         dFlag = 1;
2981         gear = 0;
2982         for (zX = DECODE1; zX < DECODEN; zX++) {
2983             if (pP->streamsFromDecodes[zX] == z) {
2984                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
2985                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
2986                 break;
2987             }
2988         }
2989         eFlag = 1;
2990         for (zX = ENCODE1; zX < ENCODEN; zX++) {
2991             if (pP->streamsFromEncodes[zX] == z) {
2992                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
2993                 break;
2994             }
2995         }
2997         if (dFlag && eFlag) {
2998             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
2999             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
3000             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
3001                 chain->fxns->chainFrameFunction[iChainFrameFxns];
3003             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
3004                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
3005                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
3006                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
3007                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
3008                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
3009                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
3010                        as+z, logArg);
3011             errno = (*func) (chain, frame);
3012             TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
3013                 as+z, errno);
3015             if (errno && abortOnError)
3016                 return errno;
3017         }
3018         else {
3019             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
3020                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
3021                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
3022                        ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
3023                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
3024                        ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
3025                        : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
3026                        as+z, logArg);
3027         }
3029         /*
3030         {
3031             void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
3032             PAF_AudioFrameData *afd;
3033             float ** afPtr;
3035             afd = &(pC->xStr->pAudioFrame->data);
3036             afPtr = (float**)afd->sample;
3037             dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
3039         }
3040         */
3042     }
3044     return 0;
3045 } //PAF_ASOT_streamChainFunction
3047 /* Check if at least one output selected */
3048 static Int checkOutSel(
3049     const PAF_ASOT_Params *pP, 
3050     PAF_ASOT_Config *pAsotCfg,
3051     Int *pOutSel
3054     PAF_AST_Config *pAstCfg;
3055     Int outSel;
3056     Int z;
3057     
3058     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3060     outSel = 0;
3061     for (z=OUTPUT1; z < OUTPUTN; z++) 
3062     {
3063         if (pAstCfg->xOut[z].hTxSio)
3064         {
3065             outSel = 1;
3066             break;
3067         }
3068     }
3069     
3070     *pOutSel = outSel;
3072     return ASOP_SOK;
3075 /* Check if at least one output sio changed */
3076 static Int checkOutSio(
3077     const PAF_ASOT_Params *pP, 
3078     PAF_ASOT_Config *pAsotCfg,
3079     Int *pOutSioUpdate
3082     PAF_AST_Config *pAstCfg;
3083     Int outSioUpdate;
3084     Int z;
3085     
3086     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3088     outSioUpdate = 0;
3089     for (z=OUTPUT1; z < OUTPUTN; z++) 
3090     {
3091         if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
3092         {
3093             outSioUpdate = 1;
3094             break;
3095         }
3096     }
3097     
3098     *pOutSioUpdate = outSioUpdate;
3100     return ASOP_SOK;
3103 // Reset audio frames
3104 static Void resetAfs(
3105     const PAF_ASOT_Params *pP, 
3106     PAF_AST_Stream *xStr
3109     // Reset audio frame pointers to original values
3110     // (may be needed if error occurred).
3111     resetAfPointers(pP, xStr);
3112     // Reset audio frame meta data elements
3113     resetAfMetadata(pP, xStr);
3116 // Reset audio frame pointers to original values
3117 static Void resetAfPointers(
3118     const PAF_ASOT_Params *pP, 
3119     PAF_AST_Stream *xStr
3122     Int z;
3123     Int ch;
3125     // Reset audio frame pointers to original values
3126     for (z = STREAM1; z < STREAMN; z++) 
3127     {
3128         for (ch = PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++) 
3129         {
3130             if (xStr[z].audioFrameChannelPointers[ch])
3131             {
3132                 xStr[z].audioFrameChannelPointers[ch] = 
3133                     xStr[z].origAudioFrameChannelPointers[ch];
3134             }
3135         }
3136     }
3139 // Reset audio frame meta data elements
3140 static Void resetAfMetadata(
3141     const PAF_ASOT_Params *pP, 
3142     PAF_AST_Stream *xStr
3145     Int z;
3146     Int i;
3148     for (z = STREAM1; z < STREAMN; z++) 
3149     {
3150         xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
3151         xStr[z].pAudioFrame->numPrivateMetadata = 0;
3152         xStr[z].pAudioFrame->bsMetadata_offset = 0;
3153         xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
3155         for (i = 0; i < pP->pMetadataBufStatus->NumBuf; i++)
3156         {
3157             xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
3158             xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
3159         }
3160     }
3163 // Initialize Output Processing state function
3164 static Int PAF_ASOT_initOutProc(
3165     const PAF_ASOT_Params *pP, 
3166     PAF_AST_Stream *xStr
3169     // Reset audio frames
3170     resetAfs(pP, xStr);
3171     
3172     return ASOP_SOK;
3175 #if 0
3176 // Init-Sync update audio frame
3177 static Int initSyncUpdateAf(
3178     PAF_AudioFrame *dstAf, 
3179     PAF_AudioFrame *srcAf
3182     memcpy(dstAf, srcAf, sizeof(PAF_AudioFrame));
3183     
3184     return ASOP_SOK;
3186 #endif
3188 //   Purpose:   Init-Sync Dec Reset state function.
3189 //              Performes Dec Reset Init-Sync.
3190 static Int PAF_ASOT_initSyncDecReset(
3191     const PAF_ASOT_Params *pP, 
3192     const PAF_ASOT_Patchs *pQ, 
3193     PAF_ASOT_Config *pAsotCfg,
3194     PAF_AudioFrame *pDecResetAf
3197     PAF_AST_Config *pAstCfg;            // ASIT/ASOT/ASDT shared configuration
3198     Int zMD, zMS;                       // Dec and Stream Master indices
3199     PAF_AudioFrame *pStrAf;             // stream audio frame
3200     PAF_AST_OutInitSyncCtl *pOutIsCtl;  // Output Init-Sync control
3201     Int8 decFlag;                       // dec stage flag
3202     Int errno;                          // error number
3204     
3205     pAstCfg = pAsotCfg->pAstCfg;
3206     zMD = pAstCfg->masterDec;
3207     pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
3208     
3209     // check for Dec Reset
3210     // store dec reset AF
3211     errno = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD,
3212         ASP_OUTIS_DEC_STAGE_RESET_IDX, &decFlag, pDecResetAf);
3213     if (errno < 0)
3214     {
3215         return errno;
3216     }
3217     
3218     if (decFlag == 0)
3219     {
3220         return ASOP_INITSYNC_NOTREADY;
3221     }
3222     else
3223     {
3224         zMS = pAstCfg->masterStr;
3225         pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
3226         
3227         // Update Stream Audio Frame.
3228         // Copy Dec Reset AF to Stream AF.
3229         //errno = initSyncUpdateAf(pStrAf, pDecResetAf);
3230         //if (errno < 0)
3231         //{
3232         //    return errno;
3233         //}
3234         outIsCpyAf(pDecResetAf, pStrAf);
3235         
3236         // Enc activate
3237         // Enc reset
3238         errno = PAF_ASOT_outputReset(pP, pQ, pAsotCfg);
3239         if (errno < 0)
3240         {
3241             return errno;
3242         }
3243         
3244         return ASOP_SOK;
3245     }
3248 //   Purpose:   ASOT Function for resetting output processing.
3249 static Int PAF_ASOT_outputReset(
3250     const PAF_ASOT_Params *pP, 
3251     const PAF_ASOT_Patchs *pQ, 
3252     PAF_ASOT_Config *pAsotCfg
3255     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
3256     Int as;                     // Audio Stream Number (1, 2, etc.) */
3257     Int z;                      // encode counter
3258     Int errno;                  // error number
3259     Int zO, zS;
3262     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
3263     as = pAstCfg->as;
3265     for (z=ENCODE1; z < ENCODEN; z++) 
3266     {
3267         zO = pP->outputsFromEncodes[z];
3268         zS = pP->streamsFromEncodes[z];
3269         if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode) 
3270         {
3271             Int select = pAstCfg->xEnc[z].encodeStatus.select;
3272             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
3273             ENC_Handle enc = (ENC_Handle )encAlg;
3275             TRACE_VERBOSE1("AS%d: PAF_ASOT_outputReset: initializing encode", as+zS);
3277             if (encAlg->fxns->algActivate)
3278             {
3279                 encAlg->fxns->algActivate(encAlg);
3280             }
3281             
3282             if (enc->fxns->reset)
3283             {
3284                 errno = enc->fxns->reset(enc, NULL, 
3285                     &pAstCfg->xEnc[z].encodeControl, 
3286                     &pAstCfg->xEnc[z].encodeStatus);
3287                 if (errno)
3288                 {
3289                     return ASOP_ENCRESET_ERR;
3290                 }
3291             }
3292         }
3293     }    
3294     
3295     return ASOP_SOK;
3298 //   Purpose:   Init-Sync Dec Info1 state function.
3299 //              Performes Dec Info1 Init-Sync.
3300 static Int PAF_ASOT_initSyncDecInfo1(
3301     const PAF_ASOT_Params *pP, 
3302     const PAF_ASOT_Patchs *pQ, 
3303     PAF_ASOT_Config *pAsotCfg,
3304     PAF_AudioFrame *pDecInfo1Af
3307     PAF_AST_Config *pAstCfg;            // ASIT/ASOT/ASDT shared configuration
3308     Int zMD, zMS;                       // Dec and Stream Master indices
3309     PAF_AudioFrame *pStrAf;             // stream audio frame
3310     PAF_AST_OutInitSyncCtl *pOutIsCtl;  // Output Init-Sync control
3311     Int8 decFlag;                       // dec stage flag
3312     Int errno;                          // error number
3314     
3315     pAstCfg = pAsotCfg->pAstCfg;
3316     zMD = pAstCfg->masterDec;
3317     pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
3318     
3319     // Check for Dec Reset, 
3320     // Store dec reset AF
3321     errno = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD,
3322         ASP_OUTIS_DEC_STAGE_INFO1_IDX, &decFlag, pDecInfo1Af);
3323     if (errno < 0)
3324     {
3325         return errno;
3326     }
3327     
3328     if (decFlag == 0)
3329     {
3330         return ASOP_INITSYNC_NOTREADY;
3331     }
3332     else
3333     {
3334         zMS = pAstCfg->masterStr;
3335         pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
3336         
3337         // Update Stream Audio Frame.
3338         // Copy Dec Reset AF to Stream AF.
3339         //errno = initSyncUpdateAf(pStrAf, pDecInfo1Af);
3340         //if (errno < 0)
3341         //{