Merge pull request #37 in PASDK/pasdk_sr from pasdk_663_shalini to pasdk1_3_master
[processor-sdk/performance-audio-sr.git] / pasrc / test_dsp / framework / audioStreamOutDec.c
2 /*
3 Copyright (c) 2018, 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 */
35 /*
36  *  ======== audioStreamOutDec.c ========
37  */
39 #include <string.h> // for memset
40 #include <xdc/runtime/Log.h>
41 #include <xdc/std.h>
43 #include "paferr.h"
44 #include "pafsio_ialg.h"
45 #include "pce.h"
46 #include "stdasp.h"
47 #include "asperr.h"
49 #include "aspDecOpCircBuf_master.h"
50 #include "audioStreamProc_common.h"
51 #include "audioStreamOutProc.h"
52 #include "audioStreamOutIo.h"
53 #include "audioStreamOutDec.h"
54 #include "ioConfig.h"    //TODO: remove this header
55 #include "ioPhy.h"
57 #define ENC_Handle PCE_Handle /* works for all: PCE */
59 // debug
60 #include "evmc66x_gpio_dbg.h"
61 #include "dbgCapAf.h"
62 PAF_AST_DecOpCircBufStats gCbStats; // circular buffer stats
64 // debug
65 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
66 #define DEC_OP_CB_RDAF_UND_THR  ( 80 ) // arbitrary setting
67 UInt32 gCbReadAfErr         =0; // read circular buffer error count, not including underflows
68 UInt32 gDecOpCbRdAfUnd      =0; // decoder output circular buffer underflow count
69 UInt32 gMaxDecOpCbRdAfUnd   =0; // max (consecutive) decoder output circular buffer underflow count
70 UInt32 gMasterCbResetCnt    =0; // master circular buffer reset count
73 //   Purpose:   Common Function for processing algorithm chains
74 static Int streamChainFunction(
75     const PAF_ASOT_Params *pP, 
76     const PAF_ASOT_Patchs *pQ, 
77     PAF_ASOT_Config *pAsotCfg, 
78     Int iChainFrameFxns, 
79     Int abortOnError, 
80     Int logArg
81 );
83 //   Purpose:   ASOT Function for Output reset
84 Int asopDecOutProcReset(
85     const PAF_ASOT_Params *pP, 
86     const PAF_ASOT_Patchs *pQ, 
87     PAF_ASOT_Config *pAsotCfg, 
88     Int frame
89 )
90 {
91     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
92     PAF_AST_IoOut *pOut;        // ASOT IO configuration
93     Int as;                     // Audio Stream Number (1, 2, etc.) */
94     Int zO, zS;
95     Int z;                      // encode counter
96     Int errno;                  // error number
97     Int status;                 // status code
98     
99     status = ASOP_DOP_SOK;
100     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
101     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
102     as = pAstCfg->as;
104     for (z=ENCODE1; z < ENCODEN; z++) 
105     {
106         zO = pP->outputsFromEncodes[z];
107         zS = pP->streamsFromEncodes[z];
108         if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode) 
109         {
110             Int select = pAstCfg->xEnc[z].encodeStatus.select;
111             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
112             ENC_Handle enc = (ENC_Handle )encAlg;
114             TRACE_VERBOSE1("AS%d: PAF_ASOT_outputReset: initializing encode", as+zS);
116             if (encAlg->fxns->algActivate)
117             {
118                 encAlg->fxns->algActivate(encAlg);
119             }
120             
121             if (enc->fxns->reset)
122             {
123                 errno = enc->fxns->reset(enc, NULL, 
124                     &pAstCfg->xEnc[z].encodeControl, 
125                     &pAstCfg->xEnc[z].encodeStatus);
126                 if (errno)
127                 {
128                     status = ASOP_DOP_ERR_RESET_ENCRESET;
129                     return status;
130                 }
131             }
132         }
133     }    
134     
135     return status;
138 //   Purpose:   Dec Info1 stub function
139 Int asopDecOutProcInfo1(
140     const PAF_ASOT_Params *pP, 
141     const PAF_ASOT_Patchs *pQ, 
142     PAF_ASOT_Config *pAsotCfg, 
143     Int frame 
146     return ASOP_DOP_SOK;
149 //   Purpose:   Reset ASP chain, execute ENC info, and initiate Output
150 Int asopDecOutProcDec1(
151     const PAF_ASOT_Params *pP, 
152     const PAF_ASOT_Patchs *pQ, 
153     PAF_ASOT_Config *pAsotCfg, 
154     Int frame 
157     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
158     PAF_AST_IoOut *pOut;        // ASOT IO configuration
159     Int zO, zS; 
160     Int z;                      // decode/encode counter
161     Int errno;                  // error number
162     Int status;                 // status code
163     
164     status = ASOP_DOP_SOK;
165     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
166     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
168     //
169     // Reset ASP chain
170     //
171     TRACE_VERBOSE0("asopDecOutProcDec1: calling streamChainFunction.");
172     errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame);  // SRC reset is called inside;
173     if (errno)
174     {
175         TRACE_TERSE1("asopDecOutProcDec1: streamChainFunction returns errno 0x%x ", errno);
176         status = ASOP_DOP_ERR_DEC1_ASPCHAINRESET;
177         return status;
178     }
180     //
181     // Encode Info
182     //
183     TRACE_VERBOSE0("asopDecOutProcDec1: calling enc->info.");
184     for (z=ENCODE1; z < ENCODEN; z++) 
185     {
186         Int zO = pP->outputsFromEncodes[z];
187         if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode) 
188         {
189             Int select = pAstCfg->xEnc[z].encodeStatus.select;
190             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
191             ENC_Handle enc = (ENC_Handle )encAlg;
192             
193             if (enc->fxns->info)
194             {
195                 errno = enc->fxns->info(enc, NULL,
196                     &pAstCfg->xEnc[z].encodeControl, 
197                     &pAstCfg->xEnc[z].encodeStatus);
198                 if (errno)
199                 {
200                     TRACE_TERSE1("asopDecOutProcDec1: enc info returns errno 0x%x ", errno);
201                     status = ASOP_DOP_ERR_DEC1_ENCINFO;
202                     return status;
203                 }
204             }
205         }
206     }
208     //
209     // Initialize Output components
210     //
212     // FL, New IO: Something needed in new IO
213     // FL, New IO: API for multiple Outputs
214     // FL, New IO: SIO calls need to be checked
215     errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
216     if (errno)
217     {
218         if (errno != ASOP_IO_ERR_RATE_CHANGE)
219         {
220             TRACE_TERSE1("asopDecOutProcDec1: asopSetCheckRateX returns errno 0x%x", errno);
221             status = ASOP_DOP_ERR_DEC1_SETRATEX;
222             return status;
223         }
224         else
225         {
226             TRACE_TERSE1("asopDecOutProcDec1: asopSetCheckRateX returns errno 0x%x, ignoring", errno);            
227         }
228     }
229     
230     // FL, New IO: API for multiple Outputs
231     // FL, New IO: SIO calls need to be checked
232     errno = asopStartOutput(pP, pQ, pAsotCfg);
233     if (errno)
234     {
235         TRACE_TERSE1("asopDecOutProcDec1: asopStartOutput returns errno 0x%x ", errno);
236         status = ASOP_DOP_ERR_DEC1_STARTOUTPUT;
237         return status;
238     }    
239     
240 #if 0
241     // Find first Output associated with Master Stream
242     zO = OUTPUT1;
243     for (z=ENCODE1; z < ENCODEN; z++)
244     {
245         zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
246         if (zS == pAstCfg->masterStr)
247         {
248             // This Encoder is associated with Master Stream.
249             // Note other Encoder can also be associated with Master Stream.
250             zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
251         }
252     }
253     
254     // Initialize Output buffer configuration
255     errno = asopInitOutBufConfig(&pAstCfg->xOut[zO], &pOut[zO]);
256     if (errno)
257     {
258         TRACE_TERSE1("asopDecOutProcInfo1: asopInitOutBufConfig returns errno 0x%x ", errno);
259         status = ASOP_DOP_ERR_DEC1_INITOUTBUFCFG;
260         return status;
261     }
262 #endif    
263     
264     return status;
265 } //asopDecOutProcDec1
267 //   Purpose:   Re-initiate Output
268 Int asopDecOutProcInfo2(
269     const PAF_ASOT_Params *pP, 
270     const PAF_ASOT_Patchs *pQ,  
271     PAF_ASOT_Config *pAsotCfg, 
272     Int frame 
275     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
276     PAF_AST_IoOut  *pOut;       // ASIO IO configuration
277     Int zO, zS;
278     Int z;                      // decode/encode counter
279     Int errno;                  // error number
280     Int status;                 // status code
281     
282     status = ASOP_DOP_SOK;
283     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
284     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
286     // FL, New IO: Something needed in new IO
287     // FL, New IO: API for multiple Outputs
288     // FL, New IO: SIO calls need to be checked
289     errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
290     if (errno)
291     {
292         //
293         // Note Rate change is NOT ignored here
294         //
295         
296         TRACE_TERSE1("asopDecOutProcInfo2: info returns errno 0x%x ", errno);
297         status = ASOP_DOP_ERR_INFO2_SETRATEX;
298         return status;
299     }
300     
301     // Find first Output associated with Master Stream
302     zO = OUTPUT1;
303     for (z=ENCODE1; z < ENCODEN; z++)
304     {
305         zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
306         if (zS == pAstCfg->masterStr)
307         {
308             // This Encoder is associated with Master Stream.
309             // Note other Encoder can also be associated with Master Stream.
310             zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
311         }
312     }
313     
314     // Start output transfer
315     // FL, New IO: API for single Output
316     //asopPhyTransferStart(&pOut[zO]);
317     
318     return status;
321 // Initialize Decoder output processing
322 Int asopDecOutProcInit(
323     const PAF_ASOT_Params *pP,
324     const PAF_ASOT_Patchs *pQ,
325     PAF_ASOT_Config *pAsotCfg, 
326     Int frame 
329     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
330     Int z;                              // decode counter
331     Int errno;                          // error number
332     Int status;                         // status code
334     status = ASOP_DOP_SOK;
335     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
337     for (z=DECODE1; z < DECODEN; z++)
338     {
339 #if 0 // FL: moved to PAF_ASOT_initSyncDecDecode1()
340         // Initialize decoder output circular buffer for stream reads
341         errno = cbInitStreamRead(pCbCtl, z);
342         if (errno)
343         {
344             TRACE_TERSE1("asopDecOutProcInit:cbInitStreamRead() error=%d", errno);
345             status = ASOP_DOP_ERR_INIT_CBINITREAD;
346             return status;
347         }
348 #endif
349         
350         // Start decoder output circular buffer reads
351         errno = cbReadStart(pCbCtl, z);
352         if (errno)
353         {
354             TRACE_TERSE1("asopDecOutProcInit:cbReadStart() error=%d", errno);
355             status = ASOP_DOP_ERR_INIT_CBREADSTART;
356             return status;
357         }
358         
359         gCbReadAfErr=0;         // reset read circular buffer error count
360         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
361         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
362         gMasterCbResetCnt=0;    // reset master circular buffer reset count
364         // debug, log circular buffer control variables
365         cbLog(pCbCtl, z, 1, "asopDecOutProcInit:cbReadStart");
366     }
367         
368     return status;
369 } /* asopDecOutProcInit */
371 // Process Decoder output audio data using ASP chain
372 Int asopDecOutProcStream(
373     const PAF_ASOT_Params *pP, 
374     const PAF_ASOT_Patchs *pQ, 
375     PAF_ASOT_Config *pAsotCfg, 
376     Int frame 
379     PAF_AST_Config *pAstCfg;
380     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
381     Int z;                              // decode/stream counter
382     PAF_AudioFrame *pAfRd;
383     //PAF_AST_DecOpCircBufStats cbStats;  // circular buffer statistics
384     Int errno;                          // error number
385     Int status;                         // status code
387     status = ASOP_DOP_SOK;
388     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration    
389     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
390     
391     for (z=DECODE1; z < DECODEN; z++) 
392     {
393         Int zS = pP->streamsFromDecodes[z];
394         
395         //
396         // Read decoder output circular buffer
397         //
398         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
399         //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
400         errno = cbReadAf(pCbCtl, z, pAfRd);
401         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
402         if ((errno < 0) && 
403             (errno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && 
404             (errno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
405         {
406             gCbReadAfErr++;
407             TRACE_TERSE1("asopDecOutProcStream:cbReadAf() error=%d", errno);
408             //SW_BREAKPOINT; // debug
409             status = ASOP_DOP_ERR_STREAM_CBREAD;
410             return status;
411         }
413         // Handle underflows
414         if ((errno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
415             (errno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
416         {
417             // FL: Need to check behavior of cbReset() on exit/re-entry into Output processing.
418             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
419             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
420             {
421                 // Underflow count above threshold.
422                 // (1) set max underflow count to threshold
423                 // (2) reset underflow count
424                 // (3) reset circular buffer
425                 
426                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
427                 gDecOpCbRdAfUnd = 0; // reset underflow count
429                 // Reset circular buffer
430                 cbReset(pCbCtl, z);
431                 gMasterCbResetCnt++; // increment master circular buffer reset count
432                 Log_info0("asopDecOutProcStream:cbReset()");
433             
434                 status = ASOP_DOP_ERR_STREAM_CBREADUNDTHR;
435                 return status;
436             }
437         }
438         else if ((errno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
439         {
440             // No underflow detected.
441             // update max underflow count,
442             // reset underflow count
443             
444             // update max underflow count
445             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
446             {
447                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
448             }
449             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
450         }
451         //Log_info0("asopDecOutProcStream:cbReadAf() complete.");
452         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
453         Log_info0("asopDecOutProcStream:cbReadAf() complete.");
454         
455 #if 0 // debug
456             // Shows timing of CB read
457             // ADC B8
458             {
459                 static Uint8 toggleState = 0;
460                 if (toggleState == 0)
461                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
462                 else
463                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
464                 toggleState = ~(toggleState);
465             }
466 #endif
468         // debug, get circular buffer statistics
469         //cbGetStats(pCbCtl, z, &cbStats);
470         cbGetStats(pCbCtl, z, &gCbStats);
472         // debug
473         cbLog(pCbCtl, z, 1, "asopDecOutProcStream:cbReadAf()");
474         
475 #if 0 // debug, capture audio frame
476         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
477 //      if (capAfWrite(pAfRd, PAF_RIGHT) != CAP_AF_SOK)
478         {
479             Log_info0("asopDecOutProcStream:capAfWrite() error");
480         }
481 #endif
482     }
483             
484     TRACE_VERBOSE0("asopDecOutProcStream: calling streamChainFunction()");
485     errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, frame);
486     if (errno)
487     {
488         TRACE_TERSE1("asopDecOutProcStream: streamChainFunction() returns errno 0x%x ", errno);
489         status = ASOP_DOP_ERR_STREAM_ASPCHAINAPPLY;
490         return status;
491     }
493 #if 0 // debug, capture audio frame
494     if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
495     {
496         Log_info0("asopDecOutProcStream:capAfWrite() error");
497     }
498 #endif
499     
500     return status;
501 } //asopDecodeStream
503 // -----------------------------------------------------------------------------
504 // ASOT Decoding Function - Encode Processing
505 //
506 //   Name:      PAF_ASOT_decodeEncode
507 //   Purpose:   Decoding Function for processing of audio frame data by the
508 //              Encode Algorithm.
509 //   From:      AST Parameter Function -> decodeProcessing
510 //   Uses:      See code.
511 //   States:    x
512 //   Return:    Error number in standard or SIO form (0 on success).
513 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
514 //              * State information as per parent.
515 //
516 Int asopDecOutProcEncode(
517     const PAF_ASOT_Params *pP, 
518     const PAF_ASOT_Patchs *pQ, 
519     PAF_ASOT_Config *pAsotCfg, 
520     Int frame 
523     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
524     PAF_AST_IoOut  *pOut;       // ASIO IO configuration
525     Int as;                     // Audio Stream Number (1, 2, etc.)
526     Int zX, zE, zS;
527     Int z;                      // encode/output counter
528     Int errno;                  // error number
529     Int status;                 // status code
530     //ioPhyCtl_t ioPhyCtl;
532     status = ASOP_DOP_SOK;
533     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
534     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
535     as = pAstCfg->as;
537     // Await output buffers (but not first time)
538     for (z=OUTPUT1; z < OUTPUTN; z++) 
539     {
540         // determine encoder associated with this output
541         zE = z;
542         for (zX = ENCODE1; zX < ENCODEN; zX++) 
543         {
544             if (pP->outputsFromEncodes[zX] == z) 
545             {
546                 zE = zX;
547                 break;
548             }
549         }
550         zS = pP->streamsFromEncodes[zE];
552         if (pOut[z].hIoPhy)
553         {
554             //uint32_t phyXferSizeOld;
556             // update length (e.g. ARC may have changed) - moved out of this function
557 /*            pAstCfg->xOut[z].outBufConfig.lengthofFrame =
558                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
559 */
560             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- idle", as+zS, frame);
562 #if 0 // FL, New IO: add similar thing to be figured out
563             // Update framework Phy transfer size
564             phyXferSizeOld = pOut[z].phyXferSize;
565             pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * pOut[z].stride * WORD_SIZE_PCM;
566             // Update IO Phy transfer size            
567             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
568             ioPhyCtl.params.xferFrameSize = pOut[z].phyXferSize;
569             ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
570             // Update IO Buff delay to match Phy transfer size
571             if(pOut[z].phyXferSize != phyXferSizeOld) {
572                 ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
573             }
574 /*
575             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
576             if (errno < 0)
577             {
578                 SIO_idle(pAstCfg->xOut[z].hTxSio);
579                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
580                 return -errno; // SIO negates error codes
581             }
582 */
583 #endif
585 #if 0 // debug 
586             // Shows timing of Output Tx SIO reclaim
587             // ADC B8
588             {
589                 static Uint8 toggleState = 0;
590                 if (toggleState == 0)
591                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
592                 else
593                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
594                 toggleState = ~(toggleState);
595             }
596 #endif            
597         }
598         else 
599         {
600             TRACE_VERBOSE2("AS%d: asopDecodeEncode: processing frame %d -- idle <ignored>", as+zS, frame);
601         }
602     }
604     // Encode data
605     for (z=ENCODE1; z < ENCODEN; z++) 
606     {
607 #if 0 // debug, capture audio frame
608         PAF_AudioFrame *pAfRd;
609         pAfRd = pAstCfg->xEnc[z].encodeInStruct.pAudioFrame;
610         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
611         {
612             Log_info0("asopDecOutProcEncode:capAfWrite() error");
613         }
614 #endif
615         
616         Int zS = pP->streamsFromEncodes[z];
617         (void)zS; // clear compiler warning in case not used with tracing disabled
618         if (pAstCfg->xEnc[z].encodeStatus.mode) 
619         {
620             Int select = pAstCfg->xEnc[z].encodeStatus.select;
621             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
622             ENC_Handle enc = (ENC_Handle)encAlg;
623             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
624             {
625                 pAstCfg->xEnc[z].encodeControl.encActive = select;
626                 TRACE_TERSE0("asopDecodeEncode: AS%d: changing selected encoder, return error");
627                 return ASOP_DOP_ERR_ENCODE_ENCSELECT;
628             }
629             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- encode", as+zS, frame);
631             // (MID 1933) temp. workaround for PCE2
632             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
633             //pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = 2;   //JXTODO: make this correct
635             if (enc->fxns->encode)
636             {
637                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
638                         pP->z_pEncodeStatus[z]->encBypass;
639                 errno = enc->fxns->encode(enc, NULL, 
640                     &pAstCfg->xEnc[z].encodeInStruct, 
641                     &pAstCfg->xEnc[z].encodeOutStruct);
642                 if (errno)
643                 {
644                     if (errno != PCEERR_OUTPUT_POINTERNULL)    // errno = PCEERR_OUTPUT_RESULTRANGE
645                     {
646                         TRACE_TERSE1("asopDecodeEncode: encode returns error %d", errno);
647                         status = ASOP_DOP_ERR_ENCODE_ENC;
648                         return status;
649                     }
650                 }
651             }
652         }
653         else 
654         {
655             TRACE_VERBOSE2("asopDecodeEncode: AS%d: processing frame %d -- encode <ignored>",
656                 as+pP->streamsFromEncodes[z], frame);
657         }
658     }
660     // add debug code to dump output samples to memory
662     // Transmit data
663     for (z=OUTPUT1; z < OUTPUTN; z++) 
664     {
665         // determine stream associated with this output
666         zE = z;
667         for (zX = ENCODE1; zX < ENCODEN; zX++) 
668         {
669             if (pP->outputsFromEncodes[zX] == z) 
670             {
671                 zE = zX;
672                 break;
673             }
674         }
675         zS = pP->streamsFromEncodes[zE];
677 #if 0  // FL, New IO: Something needed in new IO
678         if (pAstCfg->xOut[z].hTxSio) 
679         {
680             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output", as+zS, frame);
681             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
682             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
683                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
684             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
685             if (errno)
686             {
687                 SIO_idle(pAstCfg->xOut[z].hTxSio);
688                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
689                 {
690                     //statStruct_LogFullRing(STATSTRUCT_AS1_F2);
691                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
692                 }
693                 if (errno > 0)
694                 {
695                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
696                     return (ASPERR_ISSUE + (z << 4));
697                 }
698                 else if (errno < 0)
699                 {
700                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
701                     return -errno; // SIO negates error codes
702                 }
703             }
704             if (errno > 0)
705             {
706                 return (ASPERR_ISSUE + (z << 4));
707             }
708             else if (errno < 0)
709             {
710                 return -errno; // SIO negates error codes
711             }
712         }
713         else 
714         {
715             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output <ignored>", as+zS, frame);
716         }
717 #endif
718     }
720     return status;
721 } /* asopDecodeEncode */
723 //   Purpose: Check if output processing of current stream is complete
724 Int asopDecOutProcFinalTest(
725     const struct PAF_ASOT_Params *pP, 
726     const struct PAF_ASOT_Patchs *pQ, 
727     struct PAF_ASOT_Config *pAsotCfg, 
728     Int frame
731     PAF_AST_DecOpCircBufCtl *pCbCtl;    // decoder output circular buffer control
732     Int8 drainedFlag;                   // CB drained indicator flag
733     Int zMD;                            // master Dec index
734     Int errno;                          // error number
735     Int status;                         // status code
736     
737     status = ASOP_DOP_SOK;
738     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
739     zMD = pAsotCfg->pAstCfg->masterDec; // get master Dec index
741     // Check circular buffer drain state
742     errno = cbCheckDrainState(pCbCtl, zMD, &drainedFlag);
743     if (errno)
744     {
745         status = ASOP_DOP_ERR_FINALTEST_CBCHKDRAIN;
746         return status;
747     }
748     else if (drainedFlag == 1) // errno == 0
749     {
750         status = ASOP_DOP_ERR_FINALTEST_CBDRAINED;
751         return status;
752     }
753     
754     return status;
755 }    
757 // -----------------------------------------------------------------------------
758 // ASOT Decoding Function - Stream-Final Processing
759 //
760 //   Name:      PAF_ASOT_decodeComplete
761 //   Purpose:   Decoding Function for terminating the decoding process.
762 //   From:      AST Parameter Function -> decodeProcessing
763 //   Uses:      See code.
764 //   States:    x
765 //   Return:    0.
766 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
767 //              * State information as per parent.
768 //
769 Int asopDecOutProcComplete(
770     const PAF_ASOT_Params *pP, 
771     const PAF_ASOT_Patchs *pQ, 
772     PAF_ASOT_Config *pAsotCfg, 
773     Int frame
776     PAF_AST_Config *pAstCfg;            // ASIT/ASOT/ASDT shared configuration
777     PAF_AST_IoOut  *pOut;               // ASIO IO configuration
778     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
779     Int as;                             // Audio Stream Number (1, 2, etc.)
780     Int z;                              // decode/encode counter
781     Int errno;                          // error number
782     Int status;                         // status code
783     
784     status = ASOP_DOP_SOK;
785     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
786     as = pAstCfg->as;
787     (void)as;  // clear compiler warning in case not used with tracing disabled
789     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
790     
791     for (z=DECODE1; z < DECODEN; z++)
792     {
793         // Stop decoder output circular buffer reads
794         errno = cbReadStop(pCbCtl, z);
795         if (errno)
796         {
797             TRACE_TERSE1("asopDecOutProcComplete:cbReadStop() error=%d", errno);
798             //SW_BREAKPOINT; // debug
799             status = ASOP_DOP_ERR_COMPLETE_CBREADSTOP;
800             return status;
801         }
802         // debug
803         cbLog(pCbCtl, z, 1, "asopDecOutProcComplete:cbReadStop");
804     }
805     
806     streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
808     for (z=ENCODE1; z < ENCODEN; z++) 
809     {
810         Int zO = pP->outputsFromEncodes[z];
811         if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode) 
812         {
813             Int select = pAstCfg->xEnc[z].encodeStatus.select;
814             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
815 #ifdef PAF_ASP_FINAL
816             ENC_Handle enc = (ENC_Handle)encAlg;
817 #endif /* PAF_ASP_FINAL */
818             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode", as+z);
819 #ifdef PAF_ASP_FINAL
820             if (enc->fxns->final)
821             {
822                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
823                     &pAstCfg->xEnc[z].encodeStatus);
824             }
825 #endif /* PAF_ASP_FINAL */
826             if (encAlg->fxns->algDeactivate)
827             {
828                 encAlg->fxns->algDeactivate(encAlg);
829             }
830         }
831         else 
832         {
833             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode <ignored>", as+z);
834         }
835     }
837     // wait for remaining data to be output
838     errno = asopStopOutput(pP, pQ, pAsotCfg);
839     if (errno)
840     {
841         status = ASOP_DOP_ERR_COMPLETE_STOPOUTPUT;
842         return status;
843     }
845     return status;
846 } //asopDecOutProcComplete
848 // -----------------------------------------------------------------------------
849 // ASOT Decoding Function - Encode Command Processing
850 //
851 //   Name:      PAF_ASOT_encodeCommand
852 //   Purpose:   Decoding Function for processing Encode Commands.
853 //   From:      AST Parameter Function -> decodeProcessing
854 //   Uses:      See code.
855 //   States:    x
856 //   Return:    0.
857 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
858 //              * Command execution.
859 //              * SIO control errors.
860 //              * Error number macros.
861 //
862 Int asopDecOutProcEncodeCommand(
863     const PAF_ASOT_Params *pP, 
864     const PAF_ASOT_Patchs *pQ, 
865     PAF_ASOT_Config *pAsotCfg
868     PAF_AST_Config *pAstCfg;
869     Int as;                     // Audio Stream Number (1, 2, etc.)
870     Int zO, zS;
871     Int z;                      // encode counter
872     Int errno = 0;              // error number
873     Int status;                 // status code
875     status = ASOP_DOP_SOK;
876     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
877     as = pAstCfg->as;
879     for (z=ENCODE1; z < ENCODEN; z++) 
880     {
881         zO = pP->outputsFromEncodes[z];
882         zS = pP->streamsFromEncodes[z];
883         if (!(pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
884         {
885             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
886             {
887                 case 0: // command none - process
888                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
889                     break;
890                 case 1: // mute command
891                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command mute (0x%02x)", as+zS, 1);
892 #if 0 // FL, New IO: Something needed in new IO
893                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
894                         && pAstCfg->xOut[zO].hTxSio
895                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
896                     {
897                         errno = (errno & 0xff) | ASPERR_MUTE;
898                         /* convert to sensical errno */
899                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (mute)", as+zS);
900                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
901                     }
902                     else 
903                     {
904                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
905                     }
906 #endif
907                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
908                     break;
909                 case 2: // unmute command
910                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command unmute (0x%02x)", as+zS, 2);
911 #if 0 // FL, New IO: Something needed in new IO
912                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
913                         && pAstCfg->xOut[zO].hTxSio
914                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
915                     {
916                         errno = (errno & 0xff) | ASPERR_MUTE;
917                         /* convert to sensical errno */
918                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (unmute)", as+zS);
919                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
920                     }
921                     else 
922                     {
923                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
924                     }
925 #endif
926                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
927                     break;
928                 default: // command unknown - ignore
929                     break;
930             }
931         }
932     }
934     //ERRNO_RPRT (TaskAsop, errno);
936     return status;
937 } //asopDecOutProcEncodeCommand
939 // -----------------------------------------------------------------------------
940 // ASOT Decoding Function Helper - Chain Processing
941 //
942 //   Name:      PAF_ASOT_streamChainFunction
943 //   Purpose:   Common Function for processing algorithm chains.
944 //   From:      AST Parameter Function -> decodeInfo1
945 //              AST Parameter Function -> decodeStream
946 //              AST Parameter Function -> decodeComplete
947 //   Uses:      See code.
948 //   States:    x
949 //   Return:    Error number in standard form (0 on success).
950 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
951 //              * State information as per parent.
952 //
953 static Int streamChainFunction(
954     const PAF_ASOT_Params *pP, 
955     const PAF_ASOT_Patchs *pQ, 
956     PAF_ASOT_Config *pAsotCfg, 
957     Int iChainFrameFxns, 
958     Int abortOnError, 
959     Int logArg
962     PAF_AST_Config *pAstCfg;
963     Int as;                     // Audio Stream Number (1, 2, etc.)
964     Int z;                      // stream counter
965     Int dFlag, eFlag, gear;
966     Int zX;
967     Int zS;
968     Int errno;                  // error number
970     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
971     as = pAstCfg->as;
972     (void)as; // clear compiler warning in case not used with tracing disabled
974     for (zS = STREAM1; zS < STREAMN; zS++)
975     {
976         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
978         // apply stream
979         //      unless the stream is associated with a decoder and it is not running
980         // or
981         //      unless the stream is associated with an encoder and it is not running
982         // Also gear control only works for streams with an associated decoder
983         // if no such association exists then gear 0 (All) is used
984         dFlag = 1;
985         gear = 0;
986         for (zX = DECODE1; zX < DECODEN; zX++) 
987         {
988             if (pP->streamsFromDecodes[zX] == z) 
989             {
990                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
991                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
992                 break;
993             }
994         }
995         eFlag = 1;
996         for (zX = ENCODE1; zX < ENCODEN; zX++) 
997         {
998             if (pP->streamsFromEncodes[zX] == z) 
999             {
1000                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
1001                 break;
1002             }
1003         }
1005         if (dFlag && eFlag) 
1006         {
1007             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
1008             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
1009             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
1010                 chain->fxns->chainFrameFunction[iChainFrameFxns];
1012             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1013                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
1014                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1015                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply)"
1016                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1017                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final)"
1018                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
1019                        as+z, logArg);
1020             errno = (*func) (chain, frame);   // ASP chain reset function: SRC is the 1st in the chain and reset
1021             TRACE_VERBOSE2("asopStreamChainFunction: AS%d: errno 0x%x.", as+z, errno);
1023             if (errno && abortOnError)
1024             {
1025                 return errno;
1026             }
1027         }
1028         else 
1029         {
1030             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1031                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
1032                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1033                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply) <ignored>"
1034                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1035                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
1036                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
1037                        as+z, logArg);
1038         }
1039     }
1041     return 0;
1042 } //asopStreamChainFunction
1045 /* nothing past this point */