PASDK-577:Add "proof of concept" code for McASP LLD to setCheckRateX
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutDec.c
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
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: 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         TRACE_TERSE1("asopDecOutProcDec1: info returns errno 0x%x ", errno);
219         status = ASOP_DOP_ERR_DEC1_SETRATEX;
220         return status;
221     }
222     
223     // FL, New IO: API for multiple Outputs
224     // FL, New IO: SIO calls need to be checked
225     errno = asopStartOutput(pP, pQ, pAsotCfg);
226     if (errno)
227     {
228         TRACE_TERSE1("asopDecOutProcDec1: asopStartOutput returns errno 0x%x ", errno);
229         status = ASOP_DOP_ERR_DEC1_STARTOUTPUT;
230         return status;
231     }    
232     
233 #if 0
234     // Find first Output associated with Master Stream
235     zO = OUTPUT1;
236     for (z=ENCODE1; z < ENCODEN; z++)
237     {
238         zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
239         if (zS == pAstCfg->masterStr)
240         {
241             // This Encoder is associated with Master Stream.
242             // Note other Encoder can also be associated with Master Stream.
243             zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
244         }
245     }
246     
247     // Initialize Output buffer configuration
248     errno = asopInitOutBufConfig(&pAstCfg->xOut[zO], &pOut[zO]);
249     if (errno)
250     {
251         TRACE_TERSE1("asopDecOutProcInfo1: asopInitOutBufConfig returns errno 0x%x ", errno);
252         status = ASOP_DOP_ERR_DEC1_INITOUTBUFCFG;
253         return status;
254     }
255 #endif    
256     
257     return status;
258 } //asopDecOutProcDec1
260 //   Purpose:   Re-initiate Output
261 Int asopDecOutProcInfo2(
262     const PAF_ASOT_Params *pP, 
263     const PAF_ASOT_Patchs *pQ,  
264     PAF_ASOT_Config *pAsotCfg, 
265     Int frame 
268     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
269     PAF_AST_IoOut  *pOut;       // ASIO IO configuration
270     Int zO, zS;
271     Int z;                      // decode/encode counter
272     Int errno;                  // error number
273     Int status;                 // status code
274     
275     status = ASOP_DOP_SOK;
276     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
277     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
279     // FL, New IO: Something needed in new IO
280     // FL, New IO: API for multiple Outputs
281     // FL, New IO: SIO calls need to be checked
282     errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
283     if (errno)
284     {
285         TRACE_TERSE1("asopDecOutProcInfo2: info returns errno 0x%x ", errno);
286         status = ASOP_DOP_ERR_INFO2_SETRATEX;
287         return status;
288     }
289     
290     // Find first Output associated with Master Stream
291     zO = OUTPUT1;
292     for (z=ENCODE1; z < ENCODEN; z++)
293     {
294         zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
295         if (zS == pAstCfg->masterStr)
296         {
297             // This Encoder is associated with Master Stream.
298             // Note other Encoder can also be associated with Master Stream.
299             zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
300         }
301     }
302     
303     // Start output transfer
304     // FL, New IO: API for single Output
305     asopPhyTransferStart(&pOut[zO]);
306     
307     return status;
310 // Initialize Decoder output processing
311 Int asopDecOutProcInit(
312     const PAF_ASOT_Params *pP,
313     const PAF_ASOT_Patchs *pQ,
314     PAF_ASOT_Config *pAsotCfg, 
315     Int frame 
318     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
319     Int z;                              // decode counter
320     Int errno;                          // error number
321     Int status;                         // status code
323     status = ASOP_DOP_SOK;
324     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
326     for (z=DECODE1; z < DECODEN; z++)
327     {
328 #if 0 // FL: moved to PAF_ASOT_initSyncDecDecode1()
329         // Initialize decoder output circular buffer for stream reads
330         errno = cbInitStreamRead(pCbCtl, z);
331         if (errno)
332         {
333             TRACE_TERSE1("asopDecOutProcInit:cbInitStreamRead() error=%d", errno);
334             status = ASOP_DOP_ERR_INIT_CBINITREAD;
335             return status;
336         }
337 #endif
338         
339         // Start decoder output circular buffer reads
340         errno = cbReadStart(pCbCtl, z);
341         if (errno)
342         {
343             TRACE_TERSE1("asopDecOutProcInit:cbReadStart() error=%d", errno);
344             status = ASOP_DOP_ERR_INIT_CBREADSTART;
345             return status;
346         }
347         
348         gCbReadAfErr=0;         // reset read circular buffer error count
349         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
350         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
351         gMasterCbResetCnt=0;    // reset master circular buffer reset count
353         // debug, log circular buffer control variables
354         cbLog(pCbCtl, z, 1, "asopDecOutProcInit:cbReadStart");
355     }
356         
357     return status;
358 } /* asopDecOutProcInit */
360 // Process Decoder output audio data using ASP chain
361 Int asopDecOutProcStream(
362     const PAF_ASOT_Params *pP, 
363     const PAF_ASOT_Patchs *pQ, 
364     PAF_ASOT_Config *pAsotCfg, 
365     Int frame 
368     PAF_AST_Config *pAstCfg;
369     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
370     Int z;                              // decode/stream counter
371     PAF_AudioFrame *pAfRd;
372     //PAF_AST_DecOpCircBufStats cbStats;  // circular buffer statistics
373     Int errno;                          // error number
374     Int status;                         // status code
376     status = ASOP_DOP_SOK;
377     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration    
378     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
379     
380     for (z=DECODE1; z < DECODEN; z++) 
381     {
382         Int zS = pP->streamsFromDecodes[z];
383         
384         //
385         // Read decoder output circular buffer
386         //
387         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
388         //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
389         errno = cbReadAf(pCbCtl, z, pAfRd);
390         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
391         if ((errno < 0) && 
392             (errno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && 
393             (errno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
394         {
395             gCbReadAfErr++;
396             TRACE_TERSE1("asopDecOutProcStream:cbReadAf() error=%d", errno);
397             //SW_BREAKPOINT; // debug
398             status = ASOP_DOP_ERR_STREAM_CBREAD;
399             return status;
400         }
402         // Handle underflows
403         if ((errno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
404             (errno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
405         {
406             // FL: Need to check behavior of cbReset() on exit/re-entry into Output processing.
407             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
408             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
409             {
410                 // Underflow count above threshold.
411                 // (1) set max underflow count to threshold
412                 // (2) reset underflow count
413                 // (3) reset circular buffer
414                 
415                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
416                 gDecOpCbRdAfUnd = 0; // reset underflow count
418                 // Reset circular buffer
419                 cbReset(pCbCtl, z);
420                 gMasterCbResetCnt++; // increment master circular buffer reset count
421                 Log_info0("asopDecOutProcStream:cbReset()");
422             
423                 status = ASOP_DOP_ERR_STREAM_CBREADUNDTHR;
424                 return status;
425             }
426         }
427         else if ((errno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
428         {
429             // No underflow detected.
430             // update max underflow count,
431             // reset underflow count
432             
433             // update max underflow count
434             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
435             {
436                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
437             }
438             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
439         }
440         //Log_info0("asopDecOutProcStream:cbReadAf() complete.");
441         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
442         Log_info0("asopDecOutProcStream:cbReadAf() complete.");
443         
444 #if 0 // debug
445             // Shows timing of CB read
446             // ADC B8
447             {
448                 static Uint8 toggleState = 0;
449                 if (toggleState == 0)
450                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
451                 else
452                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
453                 toggleState = ~(toggleState);
454             }
455 #endif
457         // debug, get circular buffer statistics
458         //cbGetStats(pCbCtl, z, &cbStats);
459         cbGetStats(pCbCtl, z, &gCbStats);
461         // debug
462         cbLog(pCbCtl, z, 1, "asopDecOutProcStream:cbReadAf()");
463         
464 #if 0 // debug, capture audio frame
465         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
466 //      if (capAfWrite(pAfRd, PAF_RIGHT) != CAP_AF_SOK)
467         {
468             Log_info0("asopDecOutProcStream:capAfWrite() error");
469         }
470 #endif
471     }
472             
473     TRACE_VERBOSE0("asopDecOutProcStream: calling streamChainFunction()");
474     errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, frame);
475     if (errno)
476     {
477         TRACE_TERSE1("asopDecOutProcStream: streamChainFunction() returns errno 0x%x ", errno);
478         status = ASOP_DOP_ERR_STREAM_ASPCHAINAPPLY;
479         return status;
480     }
482 #if 0 // debug, capture audio frame
483     if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
484     {
485         Log_info0("asopDecOutProcStream:capAfWrite() error");
486     }
487 #endif
488     
489     return status;
490 } //asopDecodeStream
492 // -----------------------------------------------------------------------------
493 // ASOT Decoding Function - Encode Processing
494 //
495 //   Name:      PAF_ASOT_decodeEncode
496 //   Purpose:   Decoding Function for processing of audio frame data by the
497 //              Encode Algorithm.
498 //   From:      AST Parameter Function -> decodeProcessing
499 //   Uses:      See code.
500 //   States:    x
501 //   Return:    Error number in standard or SIO form (0 on success).
502 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
503 //              * State information as per parent.
504 //
505 Int asopDecOutProcEncode(
506     const PAF_ASOT_Params *pP, 
507     const PAF_ASOT_Patchs *pQ, 
508     PAF_ASOT_Config *pAsotCfg, 
509     Int frame 
512     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
513     PAF_AST_IoOut  *pOut;       // ASIO IO configuration
514     Int as;                     // Audio Stream Number (1, 2, etc.)
515     Int zX, zE, zS;
516     Int z;                      // encode/output counter
517     Int errno;                  // error number
518     Int status;                 // status code
519     //ioPhyCtl_t ioPhyCtl;
521     status = ASOP_DOP_SOK;
522     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
523     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
524     as = pAstCfg->as;
526     // Await output buffers (but not first time)
527     for (z=OUTPUT1; z < OUTPUTN; z++) 
528     {
529         // determine encoder associated with this output
530         zE = z;
531         for (zX = ENCODE1; zX < ENCODEN; zX++) 
532         {
533             if (pP->outputsFromEncodes[zX] == z) 
534             {
535                 zE = zX;
536                 break;
537             }
538         }
539         zS = pP->streamsFromEncodes[zE];
541         if (pOut[z].hIoPhy)
542         {
543             //uint32_t phyXferSizeOld;
545             // update length (e.g. ARC may have changed) - moved out of this function
546 /*            pAstCfg->xOut[z].outBufConfig.lengthofFrame =
547                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
548 */
549             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- idle", as+zS, frame);
551 #if 0 // FL, New IO: add similar thing to be figured out
552             // Update framework Phy transfer size
553             phyXferSizeOld = pOut[z].phyXferSize;
554             pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * pOut[z].stride * WORD_SIZE_PCM;
555             // Update IO Phy transfer size            
556             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
557             ioPhyCtl.params.xferFrameSize = pOut[z].phyXferSize;
558             ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
559             // Update IO Buff delay to match Phy transfer size
560             if(pOut[z].phyXferSize != phyXferSizeOld) {
561                 ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
562             }
563 /*
564             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
565             if (errno < 0)
566             {
567                 SIO_idle(pAstCfg->xOut[z].hTxSio);
568                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
569                 return -errno; // SIO negates error codes
570             }
571 */
572 #endif
574 #if 0 // debug 
575             // Shows timing of Output Tx SIO reclaim
576             // ADC B8
577             {
578                 static Uint8 toggleState = 0;
579                 if (toggleState == 0)
580                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
581                 else
582                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
583                 toggleState = ~(toggleState);
584             }
585 #endif            
586         }
587         else 
588         {
589             TRACE_VERBOSE2("AS%d: asopDecodeEncode: processing frame %d -- idle <ignored>", as+zS, frame);
590         }
591     }
593     // Encode data
594     for (z=ENCODE1; z < ENCODEN; z++) 
595     {
596 #if 0 // debug, capture audio frame
597         PAF_AudioFrame *pAfRd;
598         pAfRd = pAstCfg->xEnc[z].encodeInStruct.pAudioFrame;
599         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
600         {
601             Log_info0("asopDecOutProcEncode:capAfWrite() error");
602         }
603 #endif
604         
605         Int zS = pP->streamsFromEncodes[z];
606         (void)zS; // clear compiler warning in case not used with tracing disabled
607         if (pAstCfg->xEnc[z].encodeStatus.mode) 
608         {
609             Int select = pAstCfg->xEnc[z].encodeStatus.select;
610             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
611             ENC_Handle enc = (ENC_Handle)encAlg;
612             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
613             {
614                 pAstCfg->xEnc[z].encodeControl.encActive = select;
615                 TRACE_TERSE0("asopDecodeEncode: AS%d: changing selected encoder, return error");
616                 return ASOP_DOP_ERR_ENCODE_ENCSELECT;
617             }
618             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- encode", as+zS, frame);
620             // (MID 1933) temp. workaround for PCE2
621             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
622             //pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = 2;   //JXTODO: make this correct
624             if (enc->fxns->encode)
625             {
626                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
627                         pP->z_pEncodeStatus[z]->encBypass;
628                 errno = enc->fxns->encode(enc, NULL, 
629                     &pAstCfg->xEnc[z].encodeInStruct, 
630                     &pAstCfg->xEnc[z].encodeOutStruct);
631                 if (errno)
632                 {
633                     if (errno != PCEERR_OUTPUT_POINTERNULL)    // errno = PCEERR_OUTPUT_RESULTRANGE
634                     {
635                         TRACE_TERSE1("asopDecodeEncode: encode returns error %d", errno);
636                         status = ASOP_DOP_ERR_ENCODE_ENC;
637                         return status;
638                     }
639                 }
640             }
641         }
642         else 
643         {
644             TRACE_VERBOSE2("asopDecodeEncode: AS%d: processing frame %d -- encode <ignored>",
645                 as+pP->streamsFromEncodes[z], frame);
646         }
647     }
649     // add debug code to dump output samples to memory
651     // Transmit data
652     for (z=OUTPUT1; z < OUTPUTN; z++) 
653     {
654         // determine stream associated with this output
655         zE = z;
656         for (zX = ENCODE1; zX < ENCODEN; zX++) 
657         {
658             if (pP->outputsFromEncodes[zX] == z) 
659             {
660                 zE = zX;
661                 break;
662             }
663         }
664         zS = pP->streamsFromEncodes[zE];
666 #if 0  // FL, New IO: Something needed in new IO
667         if (pAstCfg->xOut[z].hTxSio) 
668         {
669             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output", as+zS, frame);
670             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
671             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
672                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
673             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
674             if (errno)
675             {
676                 SIO_idle(pAstCfg->xOut[z].hTxSio);
677                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
678                 {
679                     //statStruct_LogFullRing(STATSTRUCT_AS1_F2);
680                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
681                 }
682                 if (errno > 0)
683                 {
684                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
685                     return (ASPERR_ISSUE + (z << 4));
686                 }
687                 else if (errno < 0)
688                 {
689                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
690                     return -errno; // SIO negates error codes
691                 }
692             }
693             if (errno > 0)
694             {
695                 return (ASPERR_ISSUE + (z << 4));
696             }
697             else if (errno < 0)
698             {
699                 return -errno; // SIO negates error codes
700             }
701         }
702         else 
703         {
704             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output <ignored>", as+zS, frame);
705         }
706 #endif
707     }
709     return status;
710 } /* asopDecodeEncode */
712 //   Purpose: Check if output processing of current stream is complete
713 Int asopDecOutProcFinalTest(
714     const struct PAF_ASOT_Params *pP, 
715     const struct PAF_ASOT_Patchs *pQ, 
716     struct PAF_ASOT_Config *pAsotCfg, 
717     Int frame
720     PAF_AST_DecOpCircBufCtl *pCbCtl;    // decoder output circular buffer control
721     Int8 drainedFlag;                   // CB drained indicator flag
722     Int zMD;                            // master Dec index
723     Int errno;                          // error number
724     Int status;                         // status code
725     
726     status = ASOP_DOP_SOK;
727     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
728     zMD = pAsotCfg->pAstCfg->masterDec; // get master Dec index
730     // Check circular buffer drain state
731     errno = cbCheckDrainState(pCbCtl, zMD, &drainedFlag);
732     if (errno)
733     {
734         status = ASOP_DOP_ERR_FINALTEST_CBCHKDRAIN;
735         return status;
736     }
737     else if (drainedFlag == 1) // errno == 0
738     {
739         status = ASOP_DOP_ERR_FINALTEST_CBDRAINED;
740         return status;
741     }
742     
743     return status;
744 }    
746 // -----------------------------------------------------------------------------
747 // ASOT Decoding Function - Stream-Final Processing
748 //
749 //   Name:      PAF_ASOT_decodeComplete
750 //   Purpose:   Decoding Function for terminating the decoding process.
751 //   From:      AST Parameter Function -> decodeProcessing
752 //   Uses:      See code.
753 //   States:    x
754 //   Return:    0.
755 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
756 //              * State information as per parent.
757 //
758 Int asopDecOutProcComplete(
759     const PAF_ASOT_Params *pP, 
760     const PAF_ASOT_Patchs *pQ, 
761     PAF_ASOT_Config *pAsotCfg, 
762     Int frame
765     PAF_AST_Config *pAstCfg;            // ASIT/ASOT/ASDT shared configuration
766     PAF_AST_IoOut  *pOut;               // ASIO IO configuration
767     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
768     Int as;                             // Audio Stream Number (1, 2, etc.)
769     Int z;                              // decode/encode counter
770     Int errno;                          // error number
771     Int status;                         // status code
772     
773     status = ASOP_DOP_SOK;
774     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
775     as = pAstCfg->as;
776     (void)as;  // clear compiler warning in case not used with tracing disabled
778     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
779     
780     for (z=DECODE1; z < DECODEN; z++)
781     {
782         // Stop decoder output circular buffer reads
783         errno = cbReadStop(pCbCtl, z);
784         if (errno)
785         {
786             TRACE_TERSE1("asopDecOutProcComplete:cbReadStop() error=%d", errno);
787             //SW_BREAKPOINT; // debug
788             status = ASOP_DOP_ERR_COMPLETE_CBREADSTOP;
789             return status;
790         }
791         // debug
792         cbLog(pCbCtl, z, 1, "asopDecOutProcComplete:cbReadStop");
793     }
794     
795     streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
797     for (z=ENCODE1; z < ENCODEN; z++) 
798     {
799         Int zO = pP->outputsFromEncodes[z];
800         if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode) 
801         {
802             Int select = pAstCfg->xEnc[z].encodeStatus.select;
803             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
804 #ifdef PAF_ASP_FINAL
805             ENC_Handle enc = (ENC_Handle)encAlg;
806 #endif /* PAF_ASP_FINAL */
807             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode", as+z);
808 #ifdef PAF_ASP_FINAL
809             if (enc->fxns->final)
810             {
811                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
812                     &pAstCfg->xEnc[z].encodeStatus);
813             }
814 #endif /* PAF_ASP_FINAL */
815             if (encAlg->fxns->algDeactivate)
816             {
817                 encAlg->fxns->algDeactivate(encAlg);
818             }
819         }
820         else 
821         {
822             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode <ignored>", as+z);
823         }
824     }
826     // wait for remaining data to be output
827     errno = asopStopOutput(pP, pQ, pAsotCfg);
828     if (errno)
829     {
830         status = ASOP_DOP_ERR_COMPLETE_STOPOUTPUT;
831         return status;
832     }
834     return status;
835 } //asopDecOutProcComplete
837 // -----------------------------------------------------------------------------
838 // ASOT Decoding Function - Encode Command Processing
839 //
840 //   Name:      PAF_ASOT_encodeCommand
841 //   Purpose:   Decoding Function for processing Encode Commands.
842 //   From:      AST Parameter Function -> decodeProcessing
843 //   Uses:      See code.
844 //   States:    x
845 //   Return:    0.
846 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
847 //              * Command execution.
848 //              * SIO control errors.
849 //              * Error number macros.
850 //
851 Int asopDecOutProcEncodeCommand(
852     const PAF_ASOT_Params *pP, 
853     const PAF_ASOT_Patchs *pQ, 
854     PAF_ASOT_Config *pAsotCfg
857     PAF_AST_Config *pAstCfg;
858     Int as;                     // Audio Stream Number (1, 2, etc.)
859     Int zO, zS;
860     Int z;                      // encode counter
861     Int errno = 0;              // error number
862     Int status;                 // status code
864     status = ASOP_DOP_SOK;
865     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
866     as = pAstCfg->as;
868     for (z=ENCODE1; z < ENCODEN; z++) 
869     {
870         zO = pP->outputsFromEncodes[z];
871         zS = pP->streamsFromEncodes[z];
872         if (!(pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
873         {
874             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
875             {
876                 case 0: // command none - process
877                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
878                     break;
879                 case 1: // mute command
880                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command mute (0x%02x)", as+zS, 1);
881 #if 0 // FL, New IO: Something needed in new IO
882                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
883                         && pAstCfg->xOut[zO].hTxSio
884                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
885                     {
886                         errno = (errno & 0xff) | ASPERR_MUTE;
887                         /* convert to sensical errno */
888                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (mute)", as+zS);
889                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
890                     }
891                     else 
892                     {
893                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
894                     }
895 #endif
896                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
897                     break;
898                 case 2: // unmute command
899                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command unmute (0x%02x)", as+zS, 2);
900 #if 0 // FL, New IO: Something needed in new IO
901                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
902                         && pAstCfg->xOut[zO].hTxSio
903                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
904                     {
905                         errno = (errno & 0xff) | ASPERR_MUTE;
906                         /* convert to sensical errno */
907                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (unmute)", as+zS);
908                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
909                     }
910                     else 
911                     {
912                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
913                     }
914 #endif
915                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
916                     break;
917                 default: // command unknown - ignore
918                     break;
919             }
920         }
921     }
923     //ERRNO_RPRT (TaskAsop, errno);
925     return status;
926 } //asopDecOutProcEncodeCommand
928 // -----------------------------------------------------------------------------
929 // ASOT Decoding Function Helper - Chain Processing
930 //
931 //   Name:      PAF_ASOT_streamChainFunction
932 //   Purpose:   Common Function for processing algorithm chains.
933 //   From:      AST Parameter Function -> decodeInfo1
934 //              AST Parameter Function -> decodeStream
935 //              AST Parameter Function -> decodeComplete
936 //   Uses:      See code.
937 //   States:    x
938 //   Return:    Error number in standard form (0 on success).
939 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
940 //              * State information as per parent.
941 //
942 static Int streamChainFunction(
943     const PAF_ASOT_Params *pP, 
944     const PAF_ASOT_Patchs *pQ, 
945     PAF_ASOT_Config *pAsotCfg, 
946     Int iChainFrameFxns, 
947     Int abortOnError, 
948     Int logArg
951     PAF_AST_Config *pAstCfg;
952     Int as;                     // Audio Stream Number (1, 2, etc.)
953     Int z;                      // stream counter
954     Int dFlag, eFlag, gear;
955     Int zX;
956     Int zS;
957     Int errno;                  // error number
959     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
960     as = pAstCfg->as;
961     (void)as; // clear compiler warning in case not used with tracing disabled
963     for (zS = STREAM1; zS < STREAMN; zS++)
964     {
965         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
967         // apply stream
968         //      unless the stream is associated with a decoder and it is not running
969         // or
970         //      unless the stream is associated with an encoder and it is not running
971         // Also gear control only works for streams with an associated decoder
972         // if no such association exists then gear 0 (All) is used
973         dFlag = 1;
974         gear = 0;
975         for (zX = DECODE1; zX < DECODEN; zX++) 
976         {
977             if (pP->streamsFromDecodes[zX] == z) 
978             {
979                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
980                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
981                 break;
982             }
983         }
984         eFlag = 1;
985         for (zX = ENCODE1; zX < ENCODEN; zX++) 
986         {
987             if (pP->streamsFromEncodes[zX] == z) 
988             {
989                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
990                 break;
991             }
992         }
994         if (dFlag && eFlag) 
995         {
996             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
997             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
998             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
999                 chain->fxns->chainFrameFunction[iChainFrameFxns];
1001             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1002                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
1003                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1004                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply)"
1005                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1006                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final)"
1007                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
1008                        as+z, logArg);
1009             errno = (*func) (chain, frame);   // ASP chain reset function: SRC is the 1st in the chain and reset
1010             TRACE_VERBOSE2("asopStreamChainFunction: AS%d: errno 0x%x.", as+z, errno);
1012             if (errno && abortOnError)
1013             {
1014                 return errno;
1015             }
1016         }
1017         else 
1018         {
1019             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1020                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
1021                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1022                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply) <ignored>"
1023                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1024                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
1025                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
1026                        as+z, logArg);
1027         }
1028     }
1030     return 0;
1031 } //asopStreamChainFunction
1034 /* nothing past this point */