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