Fixed loss of SYNC problem and restart problem. ASIT FSM works fine with
[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 #if 0
36 /*
37  *  ======== audioStreamOutProc.c ========
38  */
40 #include <string.h> // for memset
41 #include <xdc/runtime/Log.h>
42 #include <xdc/runtime/Error.h>
43 #include <xdc/runtime/Memory.h>
44 #include <ti/sysbios/knl/Clock.h>
45 #include <ti/sysbios/knl/Task.h>
47 #include "paferr.h"
48 #include <acp_mds.h>
49 #include <pcm.h>
50 #include <pce.h>
51 #include <pafsio_ialg.h>
52 #include <stdasp.h>
53 #include <doberr.h>
54 #include "asperr.h"
56 #include "common.h"
57 #include "aspMsg_common.h"
58 #include "aspMsg_master.h"
59 #include "aspDecOpCircBuf_master.h"
60 #include "audioStreamProc_common.h"
61 #include "audioStreamOutProc.h"
63 // FL: debug
64 #include "evmc66x_gpio_dbg.h"
65 #define ENC_Handle PCE_Handle /* works for all: PCE */
67 extern UInt32 gCbReadAfErr      ; // read circular buffer error count, not including underflows
68 extern UInt32 gDecOpCbRdAfUnd   ; // decoder output circular buffer underflow count
69 extern UInt32 gMaxDecOpCbRdAfUnd; // max (consecutive) decoder output circular buffer underflow count
71 extern PAF_AST_OutIO *outIOtemp;    /* Output I/O */
73 Int
74 asopDecodeInit(
75     const PAF_ASOT_Params *pP,
76     const PAF_ASOT_Patchs *pQ,
77     PAF_ASOT_Config *pC,
78         asopDecProc_t *dec
79 )
80 {
81     PAF_AST_Config *pAstCfg;
82     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
83     Int as;                             /* Audio Stream Number (1, 2, etc.) */
84     Int z;                              /* decode counter */
85     Int errno;                          /* error number */
86     Int zO, zS;
88     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
90     // Reset audio frame pointers to original values
91     // (may be needed if error occurred).
92     for (z=STREAM1; z < STREAMN; z++)
93     {
94         Int ch;
95         for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
96         {
97             if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
98             {
99                 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
100                     pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
101             }
102         }
103     }
105     // Reset audio frame meta data elements
106     {
107         Int i;
109         for (z=STREAM1; z < STREAMN; z++)
110         {
111             pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
112             pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
113             pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
114             pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
116             for (i=0; i<pP->pMetadataBufStatus->NumBuf; i++)
117             {
118                 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
119                 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
120             }
121         }
122     }
124     as = pAstCfg->as;
125     pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
127     for (z=DECODE1; z < DECODEN; z++)
128     {
129         // Start decoder output circular buffer reads
130         errno = cbReadStart(pCbCtl, z);
131         if (errno) {
132             TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
133             SW_BREAKPOINT; // FL: debug
134             return errno;
135         }
137         gCbReadAfErr = 0;         // reset read circular buffer error count
138         gDecOpCbRdAfUnd = 0;      // reset decoder output circular buffer underflow count
139         gMaxDecOpCbRdAfUnd = 0;   // reset max decoder output circular buffer underflow count
141         // FL: debug
142         //cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
143     }
145     // TODO: move this to start of this function so that it doesn't affect IO timing
146     for (z=ENCODE1; z < ENCODEN; z++)
147     {
148         zO = pP->outputsFromEncodes[z];
149         zS = pP->streamsFromEncodes[z];
150         //if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
151         if (outIOtemp[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
152         {
153             Int select = pAstCfg->xEnc[z].encodeStatus.select;
154             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
155             ENC_Handle enc = (ENC_Handle )encAlg;
156             TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
157             if (encAlg->fxns->algActivate)
158             {
159                 encAlg->fxns->algActivate (encAlg);
160             }
161             if (enc->fxns->reset
162                 && (errno = enc->fxns->reset(enc, NULL,
163                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
164             {
165                 return errno;
166             }
167         }
168     }
170     //JXTODO: move decodeInfo1 to output task state machine
171     /*if (errno = pP->fxns->decodeInfo1(pP, pQ, pC, frame, block))
172     {
173         TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x.  break after decodeInfo1", errno);
174         break;
175     }*/
177     dec->frame = 0;
178     dec->block = 0;
180         return ASOP_DECODE_NO_ERR;
181 } /* asopDecodeInit */
184 // -----------------------------------------------------------------------------
185 // ASOT Decoding Function - Info Processing, Initial
186 //
187 //   Name:      PAF_ASOT_decodeInfo1
188 //   Purpose:   Decoding Function for processing information in a manner that
189 //              is unique to initial frames of input data.
190 //   From:      AST Parameter Function -> decodeProcessing
191 //   Uses:      See code.
192 //   States:    x
193 //   Return:    Error number in standard or SIO form (0 on success).
194 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
195 //              * State information as per parent.
196 //
197 // (***) FL: setup output (ASP chain reset, ENC reset, setCheckRateX, start output)
198 //           Contained in INFO1 in combined FSM.
199 // Establish secondary timing
200 Int
201 asopDecodeInfo1(
202     const PAF_ASOT_Params *pP,
203     const PAF_ASOT_Patchs *pQ,
204     PAF_ASOT_Config *pC,
205     Int frame
208     PAF_AST_Config *pAstCfg;
209     Int z;                              /* decode/encode counter */
210     Int errno;                          /* error number */
212     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
214     // run the chain of ASP's on the stream.
215     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
216     if (errno = pP->fxns->streamChainFunction(pP, pQ, pC,
217         PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame))
218     {
219         TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
220         return errno;
221     }
223     TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
224     for (z=ENCODE1; z < ENCODEN; z++)
225     {
226         Int zO = pP->outputsFromEncodes[z];
227         if (outIOtemp[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
228         {
229             Int select = pAstCfg->xEnc[z].encodeStatus.select;
230             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
231             ENC_Handle enc = (ENC_Handle )encAlg;
232             if (enc->fxns->info
233                 && (errno = enc->fxns->info(enc, NULL,
234                     &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
235             {
236                 TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
237                 return errno;
238             }
239         }
240     }
242     if (errno = pP->fxns->setCheckRateX(pP, pQ, pC, 0))
243     {
244         // ignore if rateX has changed since we haven't, but are about to,
245         // start the output. If we didn't ignore this case then the state machine
246         // would restart unnecessarily, e.g. in the case of SRC, resulting in
247         // added latency.
248         if (errno != ASPERR_INFO_RATECHANGE)
249         {
250             TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
251             return errno;
252         }
253         else
254         {
255             TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
256         }
257     }
258 /*
259     if (errno = pP->fxns->startOutput(pP, pQ, pC)) // PAF_ASOT_startOutput, SIO_issue() call inside
260     {
261         if (errno == 0x105)
262         {
263             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
264         }
265         else
266         {
267             TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
268         }
269         return errno;
270     }
271 */
272     return ASOP_DECODE_NO_ERR;
273 } /* asopDecodeInfo1 */
275 // -----------------------------------------------------------------------------
276 // ASOT Decoding Function Helper - SIO Driver Start
277 //
278 //   Name:      PAF_ASOT_startOutput
279 //   Purpose:   Decoding Function for initiating output.
280 //   From:      AST Parameter Function -> decodeInfo1
281 //   Uses:      See code.
282 //   States:    x
283 //   Return:    Error number in standard or SIO form (0 on success).
284 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
285 //              * State information as per parent.
286 //              * SIO control errors.
287 //
288 #define DEC_OUTNUMBUF_MAP(X) \
289       pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
291 Int
292 asopStartOutput(
293     const PAF_ASOT_Params *pP,
294     const PAF_ASOT_Patchs *pQ,
295     PAF_ASOT_Config *pC
298     PAF_AST_Config *pAstCfg;
299     Int as;                     /* Audio Stream Number (1, 2, etc.) */
300     Int z;                      /* output counter */
301     Int nbufs;
302     Int zE, zS, zX;
303     Int zMD;
304     PAF_SIO_IALG_Obj    *pObj;
305     PAF_SIO_IALG_Config *pAlgConfig;
308     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
309     as = pAstCfg->as;
310     zMD = pAstCfg->masterDec;
312     for (z=OUTPUT1; z < OUTPUTN; z++)
313     {
314         if (outIOtemp[z].hIoPhy)
315         {
316             // determine associated encoder and stream
317             zE = z;
318             zS = z;
319             for (zX = ENCODE1; zX < ENCODEN; zX++)
320             {
321                 if (pP->outputsFromEncodes[zX] == z)
322                 {
323                     zE = zX;
324                     zS = pP->streamsFromEncodes[zE];
325                     break;
326                 }
327             }
329             // Set sample count so that DOB knows how much data to send
330             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
331                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
333             if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED)
334             {
335                 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
336                 pAlgConfig = &pObj->config;
337                 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA,
338                     pAlgConfig->pMemRec[0].size);
339             }
341             // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
342             // decoder. How should we handle the sourceProgram for multiple decoders?
343             // Override as needed
344             nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
345             if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
346             {
347                 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
348             }
349             //JXTODO: add similar thing to be figured out
350             //SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
352             //JXTODO: data transfer start to be moved to output task state machine
353             /*if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
354                 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0))
355             {
356                 SIO_idle(pAstCfg->xOut[z].hTxSio);
357                 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
358                 return errno;
359             } */
361             //JXTODO: add similar thing to be figured out
362 #if 0
363             if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
364                 (errno =  SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
365             {
366                 errno = (errno & 0xff) | ASPERR_MUTE;
367                 /* convert to sensical errno */
368                 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
369                 return (errno);
370             }
371             else
372             {
373                 pAstCfg->xOut[z].outBufStatus.audio
374                     = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;
375             }
376 #endif
377             TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
378         }
379     }
381     return ASOP_DECODE_NO_ERR;
382 } /* asopStartOutput */
384 // -----------------------------------------------------------------------------
385 // ASOT Decoding Function - Encode Processing
386 //
387 //   Name:      PAF_ASOT_decodeEncode
388 //   Purpose:   Decoding Function for processing of audio frame data by the
389 //              Encode Algorithm.
390 //   From:      AST Parameter Function -> decodeProcessing
391 //   Uses:      See code.
392 //   States:    x
393 //   Return:    Error number in standard or SIO form (0 on success).
394 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
395 //              * State information as per parent.
396 //
397 Int
398 asopDecodeEncode(
399     const PAF_ASOT_Params *pP,
400     const PAF_ASOT_Patchs *pQ,
401     PAF_ASOT_Config *pC,
402     Int frame,
403     Int block
406     PAF_AST_Config *pAstCfg;
407     Int as;                     /* Audio Stream Number (1, 2, etc.) */
408     Int z;                      /* encode/output counter */
409     Int errno;                  /* error number */
410     Int zX, zE, zS;
411     ioPhyCtl_t ioPhyCtl;
413     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
414     as = pAstCfg->as;
416     // Await output buffers (but not first time)
417     for (z=OUTPUT1; z < OUTPUTN; z++)
418     {
419         // determine encoder associated with this output
420         zE = z;
421         for (zX = ENCODE1; zX < ENCODEN; zX++)
422         {
423             if (pP->outputsFromEncodes[zX] == z)
424             {
425                 zE = zX;
426                 break;
427             }
428         }
429         zS = pP->streamsFromEncodes[zE];
431         if (outIOtemp[z].hIoPhy)   // TODO: put hIoPhy into structure or replace with API call to check if I/O is ready
432         {
433             // update length (e.g. ARC may have changed)
434             pAstCfg->xOut[z].outBufConfig.lengthofFrame =
435                 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
436             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
438             ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
439             ioPhyCtl.params.xferFrameSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame
440                                                 * ASOP_OUTBUF_STRIDE * ASOP_NUM_BYTES_PCM_SAMPLE;
441             ioPhyControl(outIOtemp[z].hIoPhy, &ioPhyCtl);
443 #if 0
444             errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
445             if (errno < 0)
446             {
447                 SIO_idle(pAstCfg->xOut[z].hTxSio);
448                 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
449                 return -errno; // SIO negates error codes
450             }
451 #endif
452             // TODO: use pC->xOut[z].pOutBuf in following ->encode call
454 #if 0 // (***) FL: shows timing of Input Rx SIO reclaim after decoding has started (autodet complete)
455             // (***) debug // B8
456             {
457                 static Uint8 toggleState = 0;
458                 if (toggleState == 0)
459                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
460                 else
461                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
462                 toggleState = ~(toggleState);
463             }
464 #endif
466             //
467             // Simulate Tx SIO_reclaim() pend
468             //
469             //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
470             gTaskAsopCnt++;
471             //curTime = Clock_getTicks();
472             //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
473             //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
474         }
475         else
476         {
477             TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
478         }
479     }
481     // Encode data
482     for (z=ENCODE1; z < ENCODEN; z++)
483     {
484         Int zO = pP->outputsFromEncodes[z];
485         Int zS = pP->streamsFromEncodes[z];
486         (void)zS; // clear compiler warning in case not used with tracing disabled
487         if (outIOtemp[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)    // TODO: put hIoPhy into structure or replace with API call to check if I/O is ready
488         {
489             Int select = pAstCfg->xEnc[z].encodeStatus.select;
490             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
491             ENC_Handle enc = (ENC_Handle )encAlg;
492             if (select != pAstCfg->xEnc[z].encodeControl.encActive)
493             {
494                 pAstCfg->xEnc[z].encodeControl.encActive = select;
495                 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
496                 return (-1);
497             }
498             TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
500             // (MID 1933) temp. workaround for PCE2
501             //pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
502             pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = 2;   //JXTODO: make this correct
504           /*
505           #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
506             {
507                 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
508                 int *wp;
509                 wp = (int*)pAudioFrame->data.sample[0];
510                 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
511                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
512                 wp = (int*)pAudioFrame->data.sample[1];
513                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
514                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
515                 wp = (int*)pAudioFrame->data.sample[2];
516                 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
517                 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
518             }
519           #endif
520           */
522             if (enc->fxns->encode)
523             {
524                 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
525                         pP->z_pEncodeStatus[z]->encBypass;
526                 if (errno = enc->fxns->encode(enc, NULL,
527                     &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct))
528                 {
529                     if (errno != PCEERR_OUTPUT_POINTERNULL)    // errno = PCEERR_OUTPUT_RESULTRANGE
530                     {
531                         TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
532                         return errno;
533                     }
534                 }
535             /*  #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
536                 else
537                 {
538                     int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
539                     TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
540                     TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
541                 }
542               #endif
543               */
544             }
545         }
546         else
547         {
548             TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
549                 as+pP->streamsFromEncodes[z], block);
550         }
551     }
553     // add debug code to dump output samples to memory
555     // Transmit data
556     for (z=OUTPUT1; z < OUTPUTN; z++)
557     {
558         // determine encoder associated with this output
559         zE = z;
560         for (zX = ENCODE1; zX < ENCODEN; zX++)
561         {
562             if (pP->outputsFromEncodes[zX] == z)
563             {
564                 zE = zX;
565                 break;
566             }
567         }
568         zS = pP->streamsFromEncodes[zE];
570 #if 0
571         if (pAstCfg->xOut[z].hTxSio)
572         {
573             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
574             errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
575                 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
576             if (errno)
577             {
578                 SIO_idle(pAstCfg->xOut[z].hTxSio);
579                 if (errno == 0x105)     // 0x105 == RINGIO_EBUFFULL
580                 {
581 //                    statStruct_LogFullRing(STATSTRUCT_AS1_F2);
582                     TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
583                 }
584                 if (errno > 0)
585                 {
586                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
587                     return (ASPERR_ISSUE + (z << 4));
588                 }
589                 else if (errno < 0)
590                 {
591                     TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
592                     return -errno; // SIO negates error codes
593                 }
594             }
595             if (errno > 0)
596             {
597                 return (ASPERR_ISSUE + (z << 4));
598             }
599             else if (errno < 0)
600             {
601                 return -errno; // SIO negates error codes
602             }
603         }
604         else
605         {
606             TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
607         }
608 #endif
609     }
611     return ASOP_DECODE_NO_ERR;
612 } /* asopDecodeEncode */
615 // -----------------------------------------------------------------------------
616 // ASOT Decoding Function - Stream-Final Processing
617 //
618 //   Name:      PAF_ASOT_decodeComplete
619 //   Purpose:   Decoding Function for terminating the decoding process.
620 //   From:      AST Parameter Function -> decodeProcessing
621 //   Uses:      See code.
622 //   States:    x
623 //   Return:    0.
624 //   Trace:     Message Log "trace" in Debug Project Configuration reports:
625 //              * State information as per parent.
626 //
627 Int
628 asopDecodeComplete(
629     const PAF_ASOT_Params *pP,
630     const PAF_ASOT_Patchs *pQ,
631     PAF_ASOT_Config *pC,
632     ALG_Handle decAlg[],
633     Int frame,
634     Int block
637     PAF_AST_Config *pAstCfg;
638     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
639     Int as;                             /* Audio Stream Number (1, 2, etc.) */
640     Int z;                              /* decode/encode counter */
641     Int errno;                          /* error number */
644     pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
645     as = pAstCfg->as;
646     (void)as;  // clear compiler warning in case not used with tracing disabled
648     pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
650     for (z=DECODE1; z < DECODEN; z++)
651     {
652         // Stop decoder output circular buffer reads
653         errno = cbReadStop(pCbCtl, z);
654         if (errno)
655         {
656             TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
657             SW_BREAKPOINT; // FL: debug
658             return errno;
659         }
660         // FL: debug
661         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
662     }
664     pP->fxns->streamChainFunction(pP, pQ, pC, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
666     for (z=ENCODE1; z < ENCODEN; z++)
667     {
668         Int zO = pP->outputsFromEncodes[z];
669         if (outIOtemp[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
670         {
671             Int select = pAstCfg->xEnc[z].encodeStatus.select;
672             ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
673 #ifdef PAF_ASP_FINAL
674             ENC_Handle enc = (ENC_Handle)encAlg;
675 #endif /* PAF_ASP_FINAL */
676             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
677 #ifdef PAF_ASP_FINAL
678             if (enc->fxns->final)
679                 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
680                                  &pAstCfg->xEnc[z].encodeStatus);
681 #endif /* PAF_ASP_FINAL */
682             if (encAlg->fxns->algDeactivate)
683             {
684                 encAlg->fxns->algDeactivate(encAlg);
685             }
686         }
687         else
688         {
689             TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
690         }
691     }
693     // wait for remaining data to be output
694     //pP->fxns->stopOutput(pP, pQ, pC);    //JXTODO: implement similar function using new I/O components
696     return 0;
697 } //asopDecodeComplete
699 Int
700 asotDecodeStream(
701     const PAF_ASOT_Params *pP,
702     const PAF_ASOT_Patchs *pQ,
703     PAF_ASOT_Config *pAsotCfg,
704     Int frame,
705     Int block
708     PAF_AST_Config *pAstCfg;
709     PAF_AST_DecOpCircBufCtl *pCbCtl;    /* Decoder output circular buffer control */
710     Int z;                              /* decode/stream counter */
711     PAF_AudioFrame *pAfRd;
712     Int cbErrno;
713     Int errno;
716     pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
718     pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
720     for (z=DECODE1; z < DECODEN; z++)
721     {
722         Int zS = pP->streamsFromDecodes[z];
724         //
725         // Read decoder output circular buffer
726         //
727         pAfRd = pAstCfg->xStr[zS].pAudioFrame;
728         GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
729         cbErrno = cbReadAf(pCbCtl, z, pAfRd);
730         if ((cbErrno < 0) && (cbErrno != ASP_DECOP_CB_READ_UNDERFLOW))
731         {
732             gCbReadAfErr++;
733             TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
734             //SW_BREAKPOINT; // FL: debug
735             return cbErrno;
736         }
738         // Handle underflows
739         if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
740         {
741             // FL: some number of underflows alway occur on start of stream when ASOT only depends on configured Output.
742             //     DDP: ~2 underflows
743             //     MAT-THD: ~16 underflows
744             // Need to check behavior of cbReset().
745             // Need to check behavior on exit/re-entry into Output processing.
747             gDecOpCbRdAfUnd++; // increment circular buffer underflow count
748             if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR)
749             {
750                 // Underflow count above threshold.
751                 // (1) set max underflow count to threshold
752                 // (2) reset underflow count
753                 // (3) reset circular buffer
755                 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
756                 gDecOpCbRdAfUnd = 0; // reset underflow count
758                 // Reset circular buffer
759                 cbReset(pCbCtl, z);
760                 Log_info0("PAF_ASOT_decodeStream:cbReset");
762                 return cbErrno;
763             }
764         }
765         else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
766         {
767             // No underflow detected.
768             // update max underflow count,
769             // reset underflow count
771             // update max underflow count
772             if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
773             {
774                 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
775             }
776             gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
777         }
778         //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
779         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
780         Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
782 #if 0 // (***) FL: shows timing of CB read
783             // (***) debug // B8
784             {
785                 static Uint8 toggleState = 0;
786                 if (toggleState == 0)
787                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
788                 else
789                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
790                 toggleState = ~(toggleState);
791             }
792 #endif
794         // FL: debug
795         cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
796         //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
797         //{
798         //    Log_info0("capAfWrite() error");
799         //}
800     }
801 /*
802     TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
803     errno = pP->fxns->streamChainFunction(pP, pQ, pAsotCfg,
804         PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
805     if (errno)
806     {
807         TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
808         return errno;
809     }
810 */
811     return 0;
813 } //asotDecodeStream
814 /* nothing past this point */
815 #endif