d7510c8c99f09f237d965863e614dbf62f91e816
[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  *  ======== audioStreamOutProcDec.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     // Start output transfer
231     // FL, New IO: API for single Output
232     asopPhyTransferStart(&pOut[zO]);
233     
234     return status;
235 } //asopDecOutProcInfo1
237 //   Purpose:   Re-initiate Output
238 Int asopDecOutProcInfo2(
239     const PAF_ASOT_Params *pP, 
240     const PAF_ASOT_Patchs *pQ,  
241     PAF_ASOT_Config *pAsotCfg, 
242     Int frame 
245     PAF_AST_Config *pAstCfg;
246     PAF_AST_IoOut  *pOut;
247     Int zO, zS;
248     Int z;                              // decode/encode counter
249     Int errno;                          // error number
250     Int status;                         // status code
251     
252     status = ASOP_DOP_SOK;
253     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
254     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
256     // FL, New IO: Something needed in new IO
257     // FL, New IO: API for multiple Outputs
258     // FL, New IO: SIO calls need to be checked
259     errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
260     if (errno)
261     {
262         TRACE_TERSE1("asopDecOutProcInfo2: info returns errno 0x%x ", errno);
263         status = ASOP_DOP_ERR_INFO2_SETRATEX;
264         return status;
265     }
266     
267     // Find first Output associated with Master Stream
268     zO = OUTPUT1;
269     for (z=ENCODE1; z < ENCODEN; z++)
270     {
271         zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
272         if (zS == pAstCfg->masterStr)
273         {
274             // This Encoder is associated with Master Stream.
275             // Note other Encoder can also be associated with Master Stream.
276             zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
277         }
278     }
279     
280     // Start output transfer
281     // FL, New IO: API for single Output
282     asopPhyTransferStart(&pOut[zO]);
283     
284     return status;
287 // Initialize Decoder output processing
288 Int asopDecOutProcInit(
289     const PAF_ASOT_Params *pP,
290     const PAF_ASOT_Patchs *pQ,
291     PAF_ASOT_Config *pAsotCfg, 
292     Int frame 
295     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
296     Int z;                              // decode counter
297     Int errno;                          // error number
298     Int status;                         // status code
300     status = ASOP_DOP_SOK;
301     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
303     for (z=DECODE1; z < DECODEN; z++)
304     {
305         // Initialize decoder output circular buffer for stream reads
306         errno = cbInitStreamRead(pCbCtl, z);
307         if (errno)
308         {
309             TRACE_TERSE1("asopDecOutProcInit:cbInitStreamRead() error=%d", errno);
310             status = ASOP_DOP_ERR_INIT_CBINITREAD;
311             return status;
312         }
313         
314         // Start decoder output circular buffer reads
315         errno = cbReadStart(pCbCtl, z);
316         if (errno)
317         {
318             TRACE_TERSE1("asopDecOutProcInit:cbReadStart() error=%d", errno);
319             status = ASOP_DOP_ERR_INIT_CBREADSTART;
320             return status;
321         }
322         
323         gCbReadAfErr=0;         // reset read circular buffer error count
324         gDecOpCbRdAfUnd=0;      // reset decoder output circular buffer underflow count
325         gMaxDecOpCbRdAfUnd=0;   // reset max decoder output circular buffer underflow count
326         gMasterCbResetCnt=0;    // reset master circular buffer reset count
328         // debug, log circular buffer control variables
329         cbLog(pCbCtl, z, 1, "asopDecOutProcInit:cbReadStart");
330     }
331         
332     return status;
333 } /* asopDecOutProcInit */
335 // Process Decoder output audio data using ASP chain
336 Int asopDecOutProcStream(
337     const PAF_ASOT_Params *pP, 
338     const PAF_ASOT_Patchs *pQ, 
339     PAF_ASOT_Config *pAsotCfg, 
340     Int frame 
343     PAF_AST_Config *pAstCfg;
344     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
345     Int z;                              // decode/stream counter
346     PAF_AudioFrame *pAfRd;
347     //PAF_AST_DecOpCircBufStats cbStats;  // circular buffer statistics
348     Int errno;                          // error number
349     Int status;                         // status code
351     status = ASOP_DOP_SOK;
352     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration    
353     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
354     
355     for (z=DECODE1; z < DECODEN; z++) 
356     {
357         Int zS = pP->streamsFromDecodes[z];
358         
359         //
360         // Read decoder output circular buffer
361         //
362         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
363         //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
364         errno = cbReadAf(pCbCtl, z, pAfRd);
365         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
366         if ((errno < 0) && 
367             (errno != ASP_DECOP_CB_AF_READ_UNDERFLOW) && 
368             (errno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
369         {
370             gCbReadAfErr++;
371             TRACE_TERSE1("asopDecOutProcStream:cbReadAf() error=%d", errno);
372             //SW_BREAKPOINT; // debug
373             status = ASOP_DOP_ERR_STREAM_CBREAD;
374             return status;
375         }
377         // Handle underflows
378         if ((errno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
379             (errno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
380         {
381             // FL: Need to check behavior of cbReset() on exit/re-entry into Output processing.
382             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
383             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR) 
384             {
385                 // Underflow count above threshold.
386                 // (1) set max underflow count to threshold
387                 // (2) reset underflow count
388                 // (3) reset circular buffer
389                 
390                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
391                 gDecOpCbRdAfUnd = 0; // reset underflow count
393                 // Reset circular buffer
394                 cbReset(pCbCtl, z);
395                 gMasterCbResetCnt++; // increment master circular buffer reset count
396                 Log_info0("asopDecOutProcStream:cbReset()");
397             
398                 status = ASOP_DOP_ERR_STREAM_CBREADUNDTHR;
399                 return status;
400             }
401         }
402         else if ((errno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
403         {
404             // No underflow detected.
405             // update max underflow count,
406             // reset underflow count
407             
408             // update max underflow count
409             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
410             {
411                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
412             }
413             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
414         }
415         //Log_info0("asopDecOutProcStream:cbReadAf() complete.");
416         //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);   // debug
417         Log_info0("asopDecOutProcStream:cbReadAf() complete.");
418         
419 #if 0 // debug
420             // Shows timing of CB read
421             // ADC B8
422             {
423                 static Uint8 toggleState = 0;
424                 if (toggleState == 0)
425                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
426                 else
427                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
428                 toggleState = ~(toggleState);
429             }
430 #endif
432         // debug, get circular buffer statistics
433         //cbGetStats(pCbCtl, z, &cbStats);
434         cbGetStats(pCbCtl, z, &gCbStats);
436         // debug
437         cbLog(pCbCtl, z, 1, "asopDecOutProcStream:cbReadAf()");
438         
439 #if 0 // debug, capture audio frame
440         if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
441         {
442             Log_info0("asopDecOutProcStream:capAfWrite() error");
443         }
444 #endif
445     }
446             
447     TRACE_VERBOSE0("asopDecOutProcStream: calling streamChainFunction()");
448     errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, frame);
449     if (errno)
450     {
451         TRACE_TERSE1("asopDecOutProcStream: streamChainFunction() returns errno 0x%x ", errno);
452         status = ASOP_DOP_ERR_STREAM_ASPCHAINAPPLY;
453         return status;
454     }
456     return status;
457 } //asopDecodeStream
459 // -----------------------------------------------------------------------------
460 // ASOT Decoding Function - Encode Processing
461 //
462 //   Name:      PAF_ASOT_decodeEncode
463 //   Purpose:   Decoding Function for processing of audio frame data by the
464 //              Encode Algorithm.
465 //   From:      AST Parameter Function -> decodeProcessing
466 //   Uses:      See code.
467 //   States:    x
468 //   Return:    Error number in standard or SIO form (0 on success).
469 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
470 //              * State information as per parent.
471 //
472 Int asopDecOutProcEncode(
473     const PAF_ASOT_Params *pP, 
474     const PAF_ASOT_Patchs *pQ, 
475     PAF_ASOT_Config *pAsotCfg, 
476     Int frame 
479     PAF_AST_Config *pAstCfg;
480     PAF_AST_IoOut  *pOut;
481     Int as;                     // Audio Stream Number (1, 2, etc.)
482     Int zX, zE, zS;
483     Int z;                      // encode/output counter
484     Int errno;                  // error number
485     Int status;                 // status code
486     //ioPhyCtl_t ioPhyCtl;
488     status = ASOP_DOP_SOK;
489     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
490     pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
491     as = pAstCfg->as;
493     // Await output buffers (but not first time)
494     for (z=OUTPUT1; z < OUTPUTN; z++) 
495     {
496         // determine encoder associated with this output
497         zE = z;
498         for (zX = ENCODE1; zX < ENCODEN; zX++) 
499         {
500             if (pP->outputsFromEncodes[zX] == z) 
501             {
502                 zE = zX;
503                 break;
504             }
505         }
506         zS = pP->streamsFromEncodes[zE];
508         if (pOut[z].hIoPhy)
509         {
510             // update length (e.g. ARC may have changed)
511             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
512                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
513                 
514             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- idle", as+zS, frame);
516 #if 0 // FL NEWIO: add similar thing to be figured out
517             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
518             ioPhyCtl.params.xferFrameSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame
519                                                 * ASOP_OUTBUF_STRIDE * ASOP_NUM_BYTES_PCM_SAMPLE;
520             ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
522             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
523             if (errno < 0)
524             {
525                 SIO_idle(pAstCfg->xOut[z].hTxSio);
526                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
527                 return -errno; // SIO negates error codes
528             }
529 #endif
531 #if 0 // debug 
532             // Shows timing of Output Tx SIO reclaim
533             // ADC B8
534             {
535                 static Uint8 toggleState = 0;
536                 if (toggleState == 0)
537                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
538                 else
539                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
540                 toggleState = ~(toggleState);
541             }
542 #endif            
543         }
544         else 
545         {
546             TRACE_VERBOSE2("AS%d: asopDecodeEncode: processing frame %d -- idle <ignored>", as+zS, frame);
547         }
548     }
550     // Encode data
551     for (z=ENCODE1; z < ENCODEN; z++) 
552     {
553         Int zS = pP->streamsFromEncodes[z];
554         (void)zS; // clear compiler warning in case not used with tracing disabled
555         if (pAstCfg->xEnc[z].encodeStatus.mode) 
556         {
557             Int select = pAstCfg->xEnc[z].encodeStatus.select;
558             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
559             ENC_Handle enc = (ENC_Handle)encAlg;
560             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
561             {
562                 pAstCfg->xEnc[z].encodeControl.encActive = select;
563                 TRACE_TERSE0("asopDecodeEncode: AS%d: changing selected encoder, return error");
564                 return ASOP_DOP_ERR_ENCODE_ENCSELECT;
565             }
566             TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- encode", as+zS, frame);
568             // (MID 1933) temp. workaround for PCE2
569             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
570             //pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = 2;   //JXTODO: make this correct
572             if (enc->fxns->encode)
573             {
574                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
575                         pP->z_pEncodeStatus[z]->encBypass;
576                 errno = enc->fxns->encode(enc, NULL, 
577                     &pAstCfg->xEnc[z].encodeInStruct, 
578                     &pAstCfg->xEnc[z].encodeOutStruct);
579                 if (errno)
580                 {
581                     if (errno != PCEERR_OUTPUT_POINTERNULL)    // errno = PCEERR_OUTPUT_RESULTRANGE
582                     {
583                         TRACE_TERSE1("asopDecodeEncode: encode returns error %d", errno);
584                         status = ASOP_DOP_ERR_ENCODE_ENC;
585                         return status;
586                     }
587                 }
588             }
589         }
590         else 
591         {
592             TRACE_VERBOSE2("asopDecodeEncode: AS%d: processing frame %d -- encode <ignored>",
593                 as+pP->streamsFromEncodes[z], frame);
594         }
595     }
597     // add debug code to dump output samples to memory
599     // Transmit data
600     for (z=OUTPUT1; z < OUTPUTN; z++) 
601     {
602         // determine stream associated with this output
603         zE = z;
604         for (zX = ENCODE1; zX < ENCODEN; zX++) 
605         {
606             if (pP->outputsFromEncodes[zX] == z) 
607             {
608                 zE = zX;
609                 break;
610             }
611         }
612         zS = pP->streamsFromEncodes[zE];
614 #if 0  // FL, New IO: Something needed in new IO
615         if (pAstCfg->xOut[z].hTxSio) 
616         {
617             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output", as+zS, frame);
618             //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);       // debug
619             errno = SIO_issue(pAstCfg->xOut[z].hTxSio, 
620                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
621             //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);     // debug
622             if (errno)
623             {
624                 SIO_idle(pAstCfg->xOut[z].hTxSio);
625                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
626                 {
627                     //statStruct_LogFullRing(STATSTRUCT_AS1_F2);
628                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
629                 }
630                 if (errno > 0)
631                 {
632                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
633                     return (ASPERR_ISSUE + (z << 4));
634                 }
635                 else if (errno < 0)
636                 {
637                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
638                     return -errno; // SIO negates error codes
639                 }
640             }
641             if (errno > 0)
642             {
643                 return (ASPERR_ISSUE + (z << 4));
644             }
645             else if (errno < 0)
646             {
647                 return -errno; // SIO negates error codes
648             }
649         }
650         else 
651         {
652             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output <ignored>", as+zS, frame);
653         }
654 #endif
655         if (pOut[z].hIoPhy)
656         {
657             TRACE_GEN2("asopDecOutProcEncode: AS%d: processing frame %d -- output", as+zS, frame);
658             errno = asopWriteOpBuffers(&pAstCfg->xOut[z].outBufConfig, &pOut[z]);
659             if (errno)
660             {
661                 status = ASOP_DOP_ERR_ENCODE_WRTOPBUFS;
662                 return status;
663             }
664         }
665     }
667     return status;
668 } /* asopDecodeEncode */
670 //   Purpose: Check if output processing of current stream is complete
671 Int asopDecOutProcFinalTest(
672     const struct PAF_ASOT_Params *pP, 
673     const struct PAF_ASOT_Patchs *pQ, 
674     struct PAF_ASOT_Config *pAsotCfg, 
675     Int frame
678     PAF_AST_DecOpCircBufCtl *pCbCtl;    // decoder output circular buffer control
679     Int8 drainedFlag;                   // CB drained indicator flag
680     Int zMD;                            // master Dec index
681     Int errno;                          // error number
682     Int status;                         // status code
683     
684     status = ASOP_DOP_SOK;
685     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
686     zMD = pAsotCfg->pAstCfg->masterDec; // get master Dec index
688     // Check circular buffer drain state
689     errno = cbCheckDrainState(pCbCtl, zMD, &drainedFlag);
690     if (errno)
691     {
692         status = ASOP_DOP_ERR_FINALTEST_CBCHKDRAIN;
693         return status;
694     }
695     else if (drainedFlag == 1) // errno == 0
696     {
697         status = ASOP_DOP_ERR_FINALTEST_CBDRAINED;
698         return status;
699     }
700     
701     return status;
702 }    
704 // -----------------------------------------------------------------------------
705 // ASOT Decoding Function - Stream-Final Processing
706 //
707 //   Name:      PAF_ASOT_decodeComplete
708 //   Purpose:   Decoding Function for terminating the decoding process.
709 //   From:      AST Parameter Function -> decodeProcessing
710 //   Uses:      See code.
711 //   States:    x
712 //   Return:    0.
713 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
714 //              * State information as per parent.
715 //
716 Int asopDecOutProcComplete(
717     const PAF_ASOT_Params *pP, 
718     const PAF_ASOT_Patchs *pQ, 
719     PAF_ASOT_Config *pAsotCfg, 
720     Int frame
723     PAF_AST_Config *pAstCfg;
724     PAF_AST_IoOut  *pOut;
725     PAF_AST_DecOpCircBufCtl *pCbCtl;    // Decoder output circular buffer control
726     Int as;                             // Audio Stream Number (1, 2, etc.)
727     Int z;                              // decode/encode counter
728     Int errno;                          // error number
729     Int status;                         // status code
730     
731     status = ASOP_DOP_SOK;
732     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
733     as = pAstCfg->as;
734     (void)as;  // clear compiler warning in case not used with tracing disabled
736     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
737     
738     for (z=DECODE1; z < DECODEN; z++)
739     {
740         // Stop decoder output circular buffer reads
741         errno = cbReadStop(pCbCtl, z);
742         if (errno)
743         {
744             TRACE_TERSE1("asopDecOutProcComplete:cbReadStop() error=%d", errno);
745             //SW_BREAKPOINT; // debug
746             status = ASOP_DOP_ERR_COMPLETE_CBREADSTOP;
747             return status;
748         }
749         // debug
750         cbLog(pCbCtl, z, 1, "asopDecOutProcComplete:cbReadStop");
751     }
752     
753     streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
755     for (z=ENCODE1; z < ENCODEN; z++) 
756     {
757         Int zO = pP->outputsFromEncodes[z];
758         if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode) 
759         {
760             Int select = pAstCfg->xEnc[z].encodeStatus.select;
761             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
762 #ifdef PAF_ASP_FINAL
763             ENC_Handle enc = (ENC_Handle)encAlg;
764 #endif /* PAF_ASP_FINAL */
765             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode", as+z);
766 #ifdef PAF_ASP_FINAL
767             if (enc->fxns->final)
768             {
769                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
770                     &pAstCfg->xEnc[z].encodeStatus);
771             }
772 #endif /* PAF_ASP_FINAL */
773             if (encAlg->fxns->algDeactivate)
774             {
775                 encAlg->fxns->algDeactivate(encAlg);
776             }
777         }
778         else 
779         {
780             TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode <ignored>", as+z);
781         }
782     }
784     // wait for remaining data to be output
785     errno = asopStopOutput(pP, pQ, pAsotCfg);
786     if (errno)
787     {
788         status = ASOP_DOP_ERR_COMPLETE_STOPOUTPUT;
789         return status;
790     }
792     return status;
793 } //asopDecOutProcComplete
795 // -----------------------------------------------------------------------------
796 // ASOT Decoding Function - Encode Command Processing
797 //
798 //   Name:      PAF_ASOT_encodeCommand
799 //   Purpose:   Decoding Function for processing Encode Commands.
800 //   From:      AST Parameter Function -> decodeProcessing
801 //   Uses:      See code.
802 //   States:    x
803 //   Return:    0.
804 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
805 //              * Command execution.
806 //              * SIO control errors.
807 //              * Error number macros.
808 //
809 Int asopDecOutProcEncodeCommand(
810     const PAF_ASOT_Params *pP, 
811     const PAF_ASOT_Patchs *pQ, 
812     PAF_ASOT_Config *pAsotCfg
815     PAF_AST_Config *pAstCfg;
816     Int as;                     // Audio Stream Number (1, 2, etc.)
817     Int zO, zS;
818     Int z;                      // encode counter
819     Int errno = 0;              // error number
820     Int status;                 // status code
822     status = ASOP_DOP_SOK;
823     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
824     as = pAstCfg->as;
826     for (z=ENCODE1; z < ENCODEN; z++) 
827     {
828         zO = pP->outputsFromEncodes[z];
829         zS = pP->streamsFromEncodes[z];
830         if (!(pAstCfg->xEnc[z].encodeStatus.command2 & 0x80)) 
831         {
832             switch (pAstCfg->xEnc[z].encodeStatus.command2) 
833             {
834                 case 0: // command none - process
835                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
836                     break;
837                 case 1: // mute command
838                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command mute (0x%02x)", as+zS, 1);
839 #if 0 // FL, New IO: Something needed in new IO
840                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
841                         && pAstCfg->xOut[zO].hTxSio
842                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0))) 
843                     {
844                         errno = (errno & 0xff) | ASPERR_MUTE;
845                         /* convert to sensical errno */
846                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (mute)", as+zS);
847                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
848                     }
849                     else 
850                     {
851                         pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
852                     }
853 #endif
854                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
855                     break;
856                 case 2: // unmute command
857                     TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command unmute (0x%02x)", as+zS, 2);
858 #if 0 // FL, New IO: Something needed in new IO
859                     if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
860                         && pAstCfg->xOut[zO].hTxSio
861                         && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0))) 
862                     {
863                         errno = (errno & 0xff) | ASPERR_MUTE;
864                         /* convert to sensical errno */
865                         TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (unmute)", as+zS);
866                         TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
867                     }
868                     else 
869                     {
870                         pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
871                     }
872 #endif
873                     pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
874                     break;
875                 default: // command unknown - ignore
876                     break;
877             }
878         }
879     }
881     //ERRNO_RPRT (TaskAsop, errno);
883     return status;
884 } //asopDecOutProcEncodeCommand
886 // -----------------------------------------------------------------------------
887 // ASOT Decoding Function Helper - Chain Processing
888 //
889 //   Name:      PAF_ASOT_streamChainFunction
890 //   Purpose:   Common Function for processing algorithm chains.
891 //   From:      AST Parameter Function -> decodeInfo1
892 //              AST Parameter Function -> decodeStream
893 //              AST Parameter Function -> decodeComplete
894 //   Uses:      See code.
895 //   States:    x
896 //   Return:    Error number in standard form (0 on success).
897 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
898 //              * State information as per parent.
899 //
900 static Int streamChainFunction(
901     const PAF_ASOT_Params *pP, 
902     const PAF_ASOT_Patchs *pQ, 
903     PAF_ASOT_Config *pAsotCfg, 
904     Int iChainFrameFxns, 
905     Int abortOnError, 
906     Int logArg
909     PAF_AST_Config *pAstCfg;
910     Int as;                     // Audio Stream Number (1, 2, etc.)
911     Int z;                      // stream counter
912     Int dFlag, eFlag, gear;
913     Int zX;
914     Int zS;
915     Int errno;                  // error number
917     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
918     as = pAstCfg->as;
919     (void)as; // clear compiler warning in case not used with tracing disabled
921     for (zS = STREAM1; zS < STREAMN; zS++)
922     {
923         z = pP->streamOrder[zS];  // Select stream order from streamOrder parameter - MID 788
925         // apply stream
926         //      unless the stream is associated with a decoder and it is not running
927         // or
928         //      unless the stream is associated with an encoder and it is not running
929         // Also gear control only works for streams with an associated decoder
930         // if no such association exists then gear 0 (All) is used
931         dFlag = 1;
932         gear = 0;
933         for (zX = DECODE1; zX < DECODEN; zX++) 
934         {
935             if (pP->streamsFromDecodes[zX] == z) 
936             {
937                 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
938                 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
939                 break;
940             }
941         }
942         eFlag = 1;
943         for (zX = ENCODE1; zX < ENCODEN; zX++) 
944         {
945             if (pP->streamsFromEncodes[zX] == z) 
946             {
947                 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
948                 break;
949             }
950         }
952         if (dFlag && eFlag) 
953         {
954             PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
955             PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
956             Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
957                 chain->fxns->chainFrameFunction[iChainFrameFxns];
959             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
960                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
961                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
962                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply)"
963                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
964                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final)"
965                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
966                        as+z, logArg);
967             errno = (*func) (chain, frame);
968             TRACE_VERBOSE2("asopStreamChainFunction: AS%d: errno 0x%x.", as+z, errno);
970             if (errno && abortOnError)
971             {
972                 return errno;
973             }
974         }
975         else 
976         {
977             TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
978                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
979                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
980                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply) <ignored>"
981                        : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
982                        ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
983                        : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
984                        as+z, logArg);
985         }
986     }
988     return 0;
989 } //asopStreamChainFunction
992 /* nothing past this point */