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