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