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