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
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 }
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 }
133 return status;
134 }
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
142 )
143 {
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
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;
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 }
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 }
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 }
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 }
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
251 )
252 {
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
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 }
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 }
288 // Start output transfer
289 // FL, New IO: API for single Output
290 asopPhyTransferStart(&pOut[zO]);
292 return status;
293 }
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
301 )
302 {
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 }
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 }
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 }
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
349 )
350 {
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
363 for (z=DECODE1; z < DECODEN; z++)
364 {
365 Int zS = pP->streamsFromDecodes[z];
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
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()");
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
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.");
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()");
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 }
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
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
492 )
493 {
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;
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
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
694 )
695 {
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
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 }
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
739 )
740 {
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
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
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 }
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
831 )
832 {
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
925 )
926 {
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 */