2 /*
3 Copyright (c) 2018, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
35 /*
36 * ======== audioStreamOutDec.c ========
37 */
39 #include <string.h> // for memset
40 #include <xdc/runtime/Log.h>
41 #include <xdc/std.h>
43 #include "paferr.h"
44 #include "pafsio_ialg.h"
45 #include "pce.h"
46 #include "stdasp.h"
47 #include "asperr.h"
49 #include "aspDecOpCircBuf_master.h"
50 #include "audioStreamProc_common.h"
51 #include "audioStreamOutProc.h"
52 #include "audioStreamOutIo.h"
53 #include "audioStreamOutDec.h"
54 #include "ioConfig.h" //TODO: remove this header
55 #include "ioPhy.h"
57 #define ENC_Handle PCE_Handle /* works for all: PCE */
59 // debug
60 #include "evmc66x_gpio_dbg.h"
61 #include "dbgCapAf.h"
62 PAF_AST_DecOpCircBufStats gCbStats; // circular buffer stats
64 // debug
65 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
66 #define DEC_OP_CB_RDAF_UND_THR ( 80 ) // arbitrary setting
67 UInt32 gCbReadAfErr =0; // read circular buffer error count, not including underflows
68 UInt32 gDecOpCbRdAfUnd =0; // decoder output circular buffer underflow count
69 UInt32 gMaxDecOpCbRdAfUnd =0; // max (consecutive) decoder output circular buffer underflow count
70 UInt32 gMasterCbResetCnt =0; // master circular buffer reset count
73 // Purpose: Common Function for processing algorithm chains
74 static Int streamChainFunction(
75 const PAF_ASOT_Params *pP,
76 const PAF_ASOT_Patchs *pQ,
77 PAF_ASOT_Config *pAsotCfg,
78 Int iChainFrameFxns,
79 Int abortOnError,
80 Int logArg
81 );
83 // Purpose: ASOT Function for Output reset
84 Int asopDecOutProcReset(
85 const PAF_ASOT_Params *pP,
86 const PAF_ASOT_Patchs *pQ,
87 PAF_ASOT_Config *pAsotCfg,
88 Int frame
89 )
90 {
91 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
92 PAF_AST_IoOut *pOut; // ASOT IO configuration
93 Int as; // Audio Stream Number (1, 2, etc.) */
94 Int zO, zS;
95 Int z; // encode counter
96 Int errno; // error number
97 Int status; // status code
99 status = ASOP_DOP_SOK;
100 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
101 pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
102 as = pAstCfg->as;
104 for (z=ENCODE1; z < ENCODEN; z++)
105 {
106 zO = pP->outputsFromEncodes[z];
107 zS = pP->streamsFromEncodes[z];
108 if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
109 {
110 Int select = pAstCfg->xEnc[z].encodeStatus.select;
111 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
112 ENC_Handle enc = (ENC_Handle )encAlg;
114 TRACE_VERBOSE1("AS%d: PAF_ASOT_outputReset: initializing encode", as+zS);
116 if (encAlg->fxns->algActivate)
117 {
118 encAlg->fxns->algActivate(encAlg);
119 }
121 if (enc->fxns->reset)
122 {
123 errno = enc->fxns->reset(enc, NULL,
124 &pAstCfg->xEnc[z].encodeControl,
125 &pAstCfg->xEnc[z].encodeStatus);
126 if (errno)
127 {
128 status = ASOP_DOP_ERR_RESET_ENCRESET;
129 return status;
130 }
131 }
132 }
133 }
135 return status;
136 }
138 // Purpose: Dec Info1 stub function
139 Int asopDecOutProcInfo1(
140 const PAF_ASOT_Params *pP,
141 const PAF_ASOT_Patchs *pQ,
142 PAF_ASOT_Config *pAsotCfg,
143 Int frame
144 )
145 {
146 return ASOP_DOP_SOK;
147 }
149 // Purpose: Reset ASP chain, execute ENC info, and initiate Output
150 Int asopDecOutProcDec1(
151 const PAF_ASOT_Params *pP,
152 const PAF_ASOT_Patchs *pQ,
153 PAF_ASOT_Config *pAsotCfg,
154 Int frame
155 )
156 {
157 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
158 PAF_AST_IoOut *pOut; // ASOT IO configuration
159 Int zO, zS;
160 Int z; // decode/encode counter
161 Int errno; // error number
162 Int status; // status code
164 status = ASOP_DOP_SOK;
165 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
166 pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
168 //
169 // Reset ASP chain
170 //
171 TRACE_VERBOSE0("asopDecOutProcDec1: calling streamChainFunction.");
172 errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame); // SRC reset is called inside;
173 if (errno)
174 {
175 TRACE_TERSE1("asopDecOutProcDec1: streamChainFunction returns errno 0x%x ", errno);
176 status = ASOP_DOP_ERR_DEC1_ASPCHAINRESET;
177 return status;
178 }
180 //
181 // Encode Info
182 //
183 TRACE_VERBOSE0("asopDecOutProcDec1: calling enc->info.");
184 for (z=ENCODE1; z < ENCODEN; z++)
185 {
186 Int zO = pP->outputsFromEncodes[z];
187 if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
188 {
189 Int select = pAstCfg->xEnc[z].encodeStatus.select;
190 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
191 ENC_Handle enc = (ENC_Handle )encAlg;
193 if (enc->fxns->info)
194 {
195 errno = enc->fxns->info(enc, NULL,
196 &pAstCfg->xEnc[z].encodeControl,
197 &pAstCfg->xEnc[z].encodeStatus);
198 if (errno)
199 {
200 TRACE_TERSE1("asopDecOutProcDec1: enc info returns errno 0x%x ", errno);
201 status = ASOP_DOP_ERR_DEC1_ENCINFO;
202 return status;
203 }
204 }
205 }
206 }
208 //
209 // Initialize Output components
210 //
212 // FL, New IO: Something needed in new IO
213 // FL, New IO: API for multiple Outputs
214 // FL, New IO: SIO calls need to be checked
215 errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
216 if (errno)
217 {
218 if (errno != ASOP_IO_ERR_RATE_CHANGE)
219 {
220 TRACE_TERSE1("asopDecOutProcDec1: asopSetCheckRateX returns errno 0x%x", errno);
221 status = ASOP_DOP_ERR_DEC1_SETRATEX;
222 return status;
223 }
224 else
225 {
226 TRACE_TERSE1("asopDecOutProcDec1: asopSetCheckRateX returns errno 0x%x, ignoring", errno);
227 }
228 }
230 // FL, New IO: API for multiple Outputs
231 // FL, New IO: SIO calls need to be checked
232 errno = asopStartOutput(pP, pQ, pAsotCfg);
233 if (errno)
234 {
235 TRACE_TERSE1("asopDecOutProcDec1: asopStartOutput returns errno 0x%x ", errno);
236 status = ASOP_DOP_ERR_DEC1_STARTOUTPUT;
237 return status;
238 }
240 #if 0
241 // Find first Output associated with Master Stream
242 zO = OUTPUT1;
243 for (z=ENCODE1; z < ENCODEN; z++)
244 {
245 zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
246 if (zS == pAstCfg->masterStr)
247 {
248 // This Encoder is associated with Master Stream.
249 // Note other Encoder can also be associated with Master Stream.
250 zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
251 }
252 }
254 // Initialize Output buffer configuration
255 errno = asopInitOutBufConfig(&pAstCfg->xOut[zO], &pOut[zO]);
256 if (errno)
257 {
258 TRACE_TERSE1("asopDecOutProcInfo1: asopInitOutBufConfig returns errno 0x%x ", errno);
259 status = ASOP_DOP_ERR_DEC1_INITOUTBUFCFG;
260 return status;
261 }
262 #endif
264 return status;
265 } //asopDecOutProcDec1
267 // Purpose: Re-initiate Output
268 Int asopDecOutProcInfo2(
269 const PAF_ASOT_Params *pP,
270 const PAF_ASOT_Patchs *pQ,
271 PAF_ASOT_Config *pAsotCfg,
272 Int frame
273 )
274 {
275 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
276 PAF_AST_IoOut *pOut; // ASIO IO configuration
277 Int zO, zS;
278 Int z; // decode/encode counter
279 Int errno; // error number
280 Int status; // status code
282 status = ASOP_DOP_SOK;
283 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
284 pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
286 // FL, New IO: Something needed in new IO
287 // FL, New IO: API for multiple Outputs
288 // FL, New IO: SIO calls need to be checked
289 errno = asopSetCheckRateX(pP, pQ, pAsotCfg, 0);
290 if (errno)
291 {
292 //
293 // Note Rate change is NOT ignored here
294 //
296 TRACE_TERSE1("asopDecOutProcInfo2: info returns errno 0x%x ", errno);
297 status = ASOP_DOP_ERR_INFO2_SETRATEX;
298 return status;
299 }
301 // Find first Output associated with Master Stream
302 zO = OUTPUT1;
303 for (z=ENCODE1; z < ENCODEN; z++)
304 {
305 zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
306 if (zS == pAstCfg->masterStr)
307 {
308 // This Encoder is associated with Master Stream.
309 // Note other Encoder can also be associated with Master Stream.
310 zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
311 }
312 }
314 // Start output transfer
315 // FL, New IO: API for single Output
316 asopPhyTransferStart(&pOut[zO]);
318 return status;
319 }
321 // Initialize Decoder output processing
322 Int asopDecOutProcInit(
323 const PAF_ASOT_Params *pP,
324 const PAF_ASOT_Patchs *pQ,
325 PAF_ASOT_Config *pAsotCfg,
326 Int frame
327 )
328 {
329 PAF_AST_DecOpCircBufCtl *pCbCtl; // Decoder output circular buffer control
330 Int z; // decode counter
331 Int errno; // error number
332 Int status; // status code
334 status = ASOP_DOP_SOK;
335 pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
337 for (z=DECODE1; z < DECODEN; z++)
338 {
339 #if 0 // FL: moved to PAF_ASOT_initSyncDecDecode1()
340 // Initialize decoder output circular buffer for stream reads
341 errno = cbInitStreamRead(pCbCtl, z);
342 if (errno)
343 {
344 TRACE_TERSE1("asopDecOutProcInit:cbInitStreamRead() error=%d", errno);
345 status = ASOP_DOP_ERR_INIT_CBINITREAD;
346 return status;
347 }
348 #endif
350 // Start decoder output circular buffer reads
351 errno = cbReadStart(pCbCtl, z);
352 if (errno)
353 {
354 TRACE_TERSE1("asopDecOutProcInit:cbReadStart() error=%d", errno);
355 status = ASOP_DOP_ERR_INIT_CBREADSTART;
356 return status;
357 }
359 gCbReadAfErr=0; // reset read circular buffer error count
360 gDecOpCbRdAfUnd=0; // reset decoder output circular buffer underflow count
361 gMaxDecOpCbRdAfUnd=0; // reset max decoder output circular buffer underflow count
362 gMasterCbResetCnt=0; // reset master circular buffer reset count
364 // debug, log circular buffer control variables
365 cbLog(pCbCtl, z, 1, "asopDecOutProcInit:cbReadStart");
366 }
368 return status;
369 } /* asopDecOutProcInit */
371 // Process Decoder output audio data using ASP chain
372 Int asopDecOutProcStream(
373 const PAF_ASOT_Params *pP,
374 const PAF_ASOT_Patchs *pQ,
375 PAF_ASOT_Config *pAsotCfg,
376 Int frame
377 )
378 {
379 PAF_AST_Config *pAstCfg;
380 PAF_AST_DecOpCircBufCtl *pCbCtl; // Decoder output circular buffer control
381 Int z; // decode/stream counter
382 PAF_AudioFrame *pAfRd;
383 //PAF_AST_DecOpCircBufStats cbStats; // circular buffer statistics
384 Int errno; // error number
385 Int status; // status code
387 status = ASOP_DOP_SOK;
388 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
389 pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
391 for (z=DECODE1; z < DECODEN; z++)
392 {
393 Int zS = pP->streamsFromDecodes[z];
395 //
396 // Read decoder output circular buffer
397 //
398 pAfRd = pAstCfg->xStr[zS].pAudioFrame;
399 //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
400 errno = cbReadAf(pCbCtl, z, pAfRd);
401 //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
402 if ((errno < 0) &&
403 (errno != ASP_DECOP_CB_AF_READ_UNDERFLOW) &&
404 (errno != ASP_DECOP_CB_PCM_READ_UNDERFLOW))
405 {
406 gCbReadAfErr++;
407 TRACE_TERSE1("asopDecOutProcStream:cbReadAf() error=%d", errno);
408 //SW_BREAKPOINT; // debug
409 status = ASOP_DOP_ERR_STREAM_CBREAD;
410 return status;
411 }
413 // Handle underflows
414 if ((errno == ASP_DECOP_CB_AF_READ_UNDERFLOW) ||
415 (errno == ASP_DECOP_CB_PCM_READ_UNDERFLOW))
416 {
417 // FL: Need to check behavior of cbReset() on exit/re-entry into Output processing.
418 gDecOpCbRdAfUnd++; // increment circular buffer underflow count
419 if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR)
420 {
421 // Underflow count above threshold.
422 // (1) set max underflow count to threshold
423 // (2) reset underflow count
424 // (3) reset circular buffer
426 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
427 gDecOpCbRdAfUnd = 0; // reset underflow count
429 // Reset circular buffer
430 cbReset(pCbCtl, z);
431 gMasterCbResetCnt++; // increment master circular buffer reset count
432 Log_info0("asopDecOutProcStream:cbReset()");
434 status = ASOP_DOP_ERR_STREAM_CBREADUNDTHR;
435 return status;
436 }
437 }
438 else if ((errno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
439 {
440 // No underflow detected.
441 // update max underflow count,
442 // reset underflow count
444 // update max underflow count
445 if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
446 {
447 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
448 }
449 gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
450 }
451 //Log_info0("asopDecOutProcStream:cbReadAf() complete.");
452 //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
453 Log_info0("asopDecOutProcStream:cbReadAf() complete.");
455 #if 0 // debug
456 // Shows timing of CB read
457 // ADC B8
458 {
459 static Uint8 toggleState = 0;
460 if (toggleState == 0)
461 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
462 else
463 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
464 toggleState = ~(toggleState);
465 }
466 #endif
468 // debug, get circular buffer statistics
469 //cbGetStats(pCbCtl, z, &cbStats);
470 cbGetStats(pCbCtl, z, &gCbStats);
472 // debug
473 cbLog(pCbCtl, z, 1, "asopDecOutProcStream:cbReadAf()");
475 #if 0 // debug, capture audio frame
476 if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
477 // if (capAfWrite(pAfRd, PAF_RIGHT) != CAP_AF_SOK)
478 {
479 Log_info0("asopDecOutProcStream:capAfWrite() error");
480 }
481 #endif
482 }
484 TRACE_VERBOSE0("asopDecOutProcStream: calling streamChainFunction()");
485 errno = streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, frame);
486 if (errno)
487 {
488 TRACE_TERSE1("asopDecOutProcStream: streamChainFunction() returns errno 0x%x ", errno);
489 status = ASOP_DOP_ERR_STREAM_ASPCHAINAPPLY;
490 return status;
491 }
493 #if 0 // debug, capture audio frame
494 if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
495 {
496 Log_info0("asopDecOutProcStream:capAfWrite() error");
497 }
498 #endif
500 return status;
501 } //asopDecodeStream
503 // -----------------------------------------------------------------------------
504 // ASOT Decoding Function - Encode Processing
505 //
506 // Name: PAF_ASOT_decodeEncode
507 // Purpose: Decoding Function for processing of audio frame data by the
508 // Encode Algorithm.
509 // From: AST Parameter Function -> decodeProcessing
510 // Uses: See code.
511 // States: x
512 // Return: Error number in standard or SIO form (0 on success).
513 // Trace: Message Log "trace" in Debug Project Configuration reports:
514 // * State information as per parent.
515 //
516 Int asopDecOutProcEncode(
517 const PAF_ASOT_Params *pP,
518 const PAF_ASOT_Patchs *pQ,
519 PAF_ASOT_Config *pAsotCfg,
520 Int frame
521 )
522 {
523 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
524 PAF_AST_IoOut *pOut; // ASIO IO configuration
525 Int as; // Audio Stream Number (1, 2, etc.)
526 Int zX, zE, zS;
527 Int z; // encode/output counter
528 Int errno; // error number
529 Int status; // status code
530 //ioPhyCtl_t ioPhyCtl;
532 status = ASOP_DOP_SOK;
533 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
534 pOut = pAsotCfg->pIoOut; // get pointer to ASOT IO configuration
535 as = pAstCfg->as;
537 // Await output buffers (but not first time)
538 for (z=OUTPUT1; z < OUTPUTN; z++)
539 {
540 // determine encoder associated with this output
541 zE = z;
542 for (zX = ENCODE1; zX < ENCODEN; zX++)
543 {
544 if (pP->outputsFromEncodes[zX] == z)
545 {
546 zE = zX;
547 break;
548 }
549 }
550 zS = pP->streamsFromEncodes[zE];
552 if (pOut[z].hIoPhy)
553 {
554 //uint32_t phyXferSizeOld;
556 // update length (e.g. ARC may have changed) - moved out of this function
557 /* pAstCfg->xOut[z].outBufConfig.lengthofFrame =
558 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
559 */
560 TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- idle", as+zS, frame);
562 #if 0 // FL, New IO: add similar thing to be figured out
563 // Update framework Phy transfer size
564 phyXferSizeOld = pOut[z].phyXferSize;
565 pOut[z].phyXferSize = pAstCfg->xOut[z].outBufConfig.lengthofFrame * pOut[z].stride * WORD_SIZE_PCM;
566 // Update IO Phy transfer size
567 ioPhyCtl.code = IOPHY_CTL_FRAME_SIZE;
568 ioPhyCtl.params.xferFrameSize = pOut[z].phyXferSize;
569 ioPhyControl(pOut[z].hIoPhy, &ioPhyCtl);
570 // Update IO Buff delay to match Phy transfer size
571 if(pOut[z].phyXferSize != phyXferSizeOld) {
572 ioBuffAdjustDelay(pOut[z].hIoBuff, pOut[z].phyXferSize * (NUM_PRIME_XFERS+1));
573 }
574 /*
575 errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
576 if (errno < 0)
577 {
578 SIO_idle(pAstCfg->xOut[z].hTxSio);
579 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
580 return -errno; // SIO negates error codes
581 }
582 */
583 #endif
585 #if 0 // debug
586 // Shows timing of Output Tx SIO reclaim
587 // ADC B8
588 {
589 static Uint8 toggleState = 0;
590 if (toggleState == 0)
591 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
592 else
593 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
594 toggleState = ~(toggleState);
595 }
596 #endif
597 }
598 else
599 {
600 TRACE_VERBOSE2("AS%d: asopDecodeEncode: processing frame %d -- idle <ignored>", as+zS, frame);
601 }
602 }
604 // Encode data
605 for (z=ENCODE1; z < ENCODEN; z++)
606 {
607 #if 0 // debug, capture audio frame
608 PAF_AudioFrame *pAfRd;
609 pAfRd = pAstCfg->xEnc[z].encodeInStruct.pAudioFrame;
610 if (capAfWrite(pAfRd, PAF_LEFT) != CAP_AF_SOK)
611 {
612 Log_info0("asopDecOutProcEncode:capAfWrite() error");
613 }
614 #endif
616 Int zS = pP->streamsFromEncodes[z];
617 (void)zS; // clear compiler warning in case not used with tracing disabled
618 if (pAstCfg->xEnc[z].encodeStatus.mode)
619 {
620 Int select = pAstCfg->xEnc[z].encodeStatus.select;
621 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
622 ENC_Handle enc = (ENC_Handle)encAlg;
623 if (select != pAstCfg->xEnc[z].encodeControl.encActive)
624 {
625 pAstCfg->xEnc[z].encodeControl.encActive = select;
626 TRACE_TERSE0("asopDecodeEncode: AS%d: changing selected encoder, return error");
627 return ASOP_DOP_ERR_ENCODE_ENCSELECT;
628 }
629 TRACE_GEN2("asopDecodeEncode: AS%d: processing frame %d -- encode", as+zS, frame);
631 // (MID 1933) temp. workaround for PCE2
632 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
633 //pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = 2; //JXTODO: make this correct
635 if (enc->fxns->encode)
636 {
637 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
638 pP->z_pEncodeStatus[z]->encBypass;
639 errno = enc->fxns->encode(enc, NULL,
640 &pAstCfg->xEnc[z].encodeInStruct,
641 &pAstCfg->xEnc[z].encodeOutStruct);
642 if (errno)
643 {
644 if (errno != PCEERR_OUTPUT_POINTERNULL) // errno = PCEERR_OUTPUT_RESULTRANGE
645 {
646 TRACE_TERSE1("asopDecodeEncode: encode returns error %d", errno);
647 status = ASOP_DOP_ERR_ENCODE_ENC;
648 return status;
649 }
650 }
651 }
652 }
653 else
654 {
655 TRACE_VERBOSE2("asopDecodeEncode: AS%d: processing frame %d -- encode <ignored>",
656 as+pP->streamsFromEncodes[z], frame);
657 }
658 }
660 // add debug code to dump output samples to memory
662 // Transmit data
663 for (z=OUTPUT1; z < OUTPUTN; z++)
664 {
665 // determine stream associated with this output
666 zE = z;
667 for (zX = ENCODE1; zX < ENCODEN; zX++)
668 {
669 if (pP->outputsFromEncodes[zX] == z)
670 {
671 zE = zX;
672 break;
673 }
674 }
675 zS = pP->streamsFromEncodes[zE];
677 #if 0 // FL, New IO: Something needed in new IO
678 if (pAstCfg->xOut[z].hTxSio)
679 {
680 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output", as+zS, frame);
681 //GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
682 errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
683 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
684 //GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106); // debug
685 if (errno)
686 {
687 SIO_idle(pAstCfg->xOut[z].hTxSio);
688 if (errno == 0x105) // 0x105 == RINGIO_EBUFFULL
689 {
690 //statStruct_LogFullRing(STATSTRUCT_AS1_F2);
691 TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
692 }
693 if (errno > 0)
694 {
695 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
696 return (ASPERR_ISSUE + (z << 4));
697 }
698 else if (errno < 0)
699 {
700 TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
701 return -errno; // SIO negates error codes
702 }
703 }
704 if (errno > 0)
705 {
706 return (ASPERR_ISSUE + (z << 4));
707 }
708 else if (errno < 0)
709 {
710 return -errno; // SIO negates error codes
711 }
712 }
713 else
714 {
715 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing frame %d -- output <ignored>", as+zS, frame);
716 }
717 #endif
718 }
720 return status;
721 } /* asopDecodeEncode */
723 // Purpose: Check if output processing of current stream is complete
724 Int asopDecOutProcFinalTest(
725 const struct PAF_ASOT_Params *pP,
726 const struct PAF_ASOT_Patchs *pQ,
727 struct PAF_ASOT_Config *pAsotCfg,
728 Int frame
729 )
730 {
731 PAF_AST_DecOpCircBufCtl *pCbCtl; // decoder output circular buffer control
732 Int8 drainedFlag; // CB drained indicator flag
733 Int zMD; // master Dec index
734 Int errno; // error number
735 Int status; // status code
737 status = ASOP_DOP_SOK;
738 pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
739 zMD = pAsotCfg->pAstCfg->masterDec; // get master Dec index
741 // Check circular buffer drain state
742 errno = cbCheckDrainState(pCbCtl, zMD, &drainedFlag);
743 if (errno)
744 {
745 status = ASOP_DOP_ERR_FINALTEST_CBCHKDRAIN;
746 return status;
747 }
748 else if (drainedFlag == 1) // errno == 0
749 {
750 status = ASOP_DOP_ERR_FINALTEST_CBDRAINED;
751 return status;
752 }
754 return status;
755 }
757 // -----------------------------------------------------------------------------
758 // ASOT Decoding Function - Stream-Final Processing
759 //
760 // Name: PAF_ASOT_decodeComplete
761 // Purpose: Decoding Function for terminating the decoding process.
762 // From: AST Parameter Function -> decodeProcessing
763 // Uses: See code.
764 // States: x
765 // Return: 0.
766 // Trace: Message Log "trace" in Debug Project Configuration reports:
767 // * State information as per parent.
768 //
769 Int asopDecOutProcComplete(
770 const PAF_ASOT_Params *pP,
771 const PAF_ASOT_Patchs *pQ,
772 PAF_ASOT_Config *pAsotCfg,
773 Int frame
774 )
775 {
776 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
777 PAF_AST_IoOut *pOut; // ASIO IO configuration
778 PAF_AST_DecOpCircBufCtl *pCbCtl; // Decoder output circular buffer control
779 Int as; // Audio Stream Number (1, 2, etc.)
780 Int z; // decode/encode counter
781 Int errno; // error number
782 Int status; // status code
784 status = ASOP_DOP_SOK;
785 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
786 as = pAstCfg->as;
787 (void)as; // clear compiler warning in case not used with tracing disabled
789 pCbCtl = &pAsotCfg->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
791 for (z=DECODE1; z < DECODEN; z++)
792 {
793 // Stop decoder output circular buffer reads
794 errno = cbReadStop(pCbCtl, z);
795 if (errno)
796 {
797 TRACE_TERSE1("asopDecOutProcComplete:cbReadStop() error=%d", errno);
798 //SW_BREAKPOINT; // debug
799 status = ASOP_DOP_ERR_COMPLETE_CBREADSTOP;
800 return status;
801 }
802 // debug
803 cbLog(pCbCtl, z, 1, "asopDecOutProcComplete:cbReadStop");
804 }
806 streamChainFunction(pP, pQ, pAsotCfg, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
808 for (z=ENCODE1; z < ENCODEN; z++)
809 {
810 Int zO = pP->outputsFromEncodes[z];
811 if (pOut[zO].hIoPhy && pAstCfg->xEnc[z].encodeStatus.mode)
812 {
813 Int select = pAstCfg->xEnc[z].encodeStatus.select;
814 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
815 #ifdef PAF_ASP_FINAL
816 ENC_Handle enc = (ENC_Handle)encAlg;
817 #endif /* PAF_ASP_FINAL */
818 TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode", as+z);
819 #ifdef PAF_ASP_FINAL
820 if (enc->fxns->final)
821 {
822 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
823 &pAstCfg->xEnc[z].encodeStatus);
824 }
825 #endif /* PAF_ASP_FINAL */
826 if (encAlg->fxns->algDeactivate)
827 {
828 encAlg->fxns->algDeactivate(encAlg);
829 }
830 }
831 else
832 {
833 TRACE_VERBOSE1("asopDecOutProcComplete: AS%d: finalizing encode <ignored>", as+z);
834 }
835 }
837 // wait for remaining data to be output
838 errno = asopStopOutput(pP, pQ, pAsotCfg);
839 if (errno)
840 {
841 status = ASOP_DOP_ERR_COMPLETE_STOPOUTPUT;
842 return status;
843 }
845 return status;
846 } //asopDecOutProcComplete
848 // -----------------------------------------------------------------------------
849 // ASOT Decoding Function - Encode Command Processing
850 //
851 // Name: PAF_ASOT_encodeCommand
852 // Purpose: Decoding Function for processing Encode Commands.
853 // From: AST Parameter Function -> decodeProcessing
854 // Uses: See code.
855 // States: x
856 // Return: 0.
857 // Trace: Message Log "trace" in Debug Project Configuration reports:
858 // * Command execution.
859 // * SIO control errors.
860 // * Error number macros.
861 //
862 Int asopDecOutProcEncodeCommand(
863 const PAF_ASOT_Params *pP,
864 const PAF_ASOT_Patchs *pQ,
865 PAF_ASOT_Config *pAsotCfg
866 )
867 {
868 PAF_AST_Config *pAstCfg;
869 Int as; // Audio Stream Number (1, 2, etc.)
870 Int zO, zS;
871 Int z; // encode counter
872 Int errno = 0; // error number
873 Int status; // status code
875 status = ASOP_DOP_SOK;
876 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
877 as = pAstCfg->as;
879 for (z=ENCODE1; z < ENCODEN; z++)
880 {
881 zO = pP->outputsFromEncodes[z];
882 zS = pP->streamsFromEncodes[z];
883 if (!(pAstCfg->xEnc[z].encodeStatus.command2 & 0x80))
884 {
885 switch (pAstCfg->xEnc[z].encodeStatus.command2)
886 {
887 case 0: // command none - process
888 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
889 break;
890 case 1: // mute command
891 TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command mute (0x%02x)", as+zS, 1);
892 #if 0 // FL, New IO: Something needed in new IO
893 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
894 && pAstCfg->xOut[zO].hTxSio
895 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
896 {
897 errno = (errno & 0xff) | ASPERR_MUTE;
898 /* convert to sensical errno */
899 TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (mute)", as+zS);
900 TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
901 }
902 else
903 {
904 pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
905 }
906 #endif
907 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
908 break;
909 case 2: // unmute command
910 TRACE_VERBOSE2("asopDecOutProcEncodeCommand: AS%d: encode command unmute (0x%02x)", as+zS, 2);
911 #if 0 // FL, New IO: Something needed in new IO
912 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
913 && pAstCfg->xOut[zO].hTxSio
914 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
915 {
916 errno = (errno & 0xff) | ASPERR_MUTE;
917 /* convert to sensical errno */
918 TRACE_TERSE1("asopDecOutProcEncodeCommand: AS%d: SIO control failed (unmute)", as+zS);
919 TRACE_TERSE2("asopDecOutProcEncodeCommand: AS%d: errno = 0x%04x <ignored>", as+zS, errno);
920 }
921 else
922 {
923 pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
924 }
925 #endif
926 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
927 break;
928 default: // command unknown - ignore
929 break;
930 }
931 }
932 }
934 //ERRNO_RPRT (TaskAsop, errno);
936 return status;
937 } //asopDecOutProcEncodeCommand
939 // -----------------------------------------------------------------------------
940 // ASOT Decoding Function Helper - Chain Processing
941 //
942 // Name: PAF_ASOT_streamChainFunction
943 // Purpose: Common Function for processing algorithm chains.
944 // From: AST Parameter Function -> decodeInfo1
945 // AST Parameter Function -> decodeStream
946 // AST Parameter Function -> decodeComplete
947 // Uses: See code.
948 // States: x
949 // Return: Error number in standard form (0 on success).
950 // Trace: Message Log "trace" in Debug Project Configuration reports:
951 // * State information as per parent.
952 //
953 static Int streamChainFunction(
954 const PAF_ASOT_Params *pP,
955 const PAF_ASOT_Patchs *pQ,
956 PAF_ASOT_Config *pAsotCfg,
957 Int iChainFrameFxns,
958 Int abortOnError,
959 Int logArg
960 )
961 {
962 PAF_AST_Config *pAstCfg;
963 Int as; // Audio Stream Number (1, 2, etc.)
964 Int z; // stream counter
965 Int dFlag, eFlag, gear;
966 Int zX;
967 Int zS;
968 Int errno; // error number
970 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
971 as = pAstCfg->as;
972 (void)as; // clear compiler warning in case not used with tracing disabled
974 for (zS = STREAM1; zS < STREAMN; zS++)
975 {
976 z = pP->streamOrder[zS]; // Select stream order from streamOrder parameter - MID 788
978 // apply stream
979 // unless the stream is associated with a decoder and it is not running
980 // or
981 // unless the stream is associated with an encoder and it is not running
982 // Also gear control only works for streams with an associated decoder
983 // if no such association exists then gear 0 (All) is used
984 dFlag = 1;
985 gear = 0;
986 for (zX = DECODE1; zX < DECODEN; zX++)
987 {
988 if (pP->streamsFromDecodes[zX] == z)
989 {
990 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
991 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
992 break;
993 }
994 }
995 eFlag = 1;
996 for (zX = ENCODE1; zX < ENCODEN; zX++)
997 {
998 if (pP->streamsFromEncodes[zX] == z)
999 {
1000 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
1001 break;
1002 }
1003 }
1005 if (dFlag && eFlag)
1006 {
1007 PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
1008 PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
1009 Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
1010 chain->fxns->chainFrameFunction[iChainFrameFxns];
1012 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1013 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
1014 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1015 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply)"
1016 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1017 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final)"
1018 : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
1019 as+z, logArg);
1020 errno = (*func) (chain, frame); // ASP chain reset function: SRC is the 1st in the chain and reset
1021 TRACE_VERBOSE2("asopStreamChainFunction: AS%d: errno 0x%x.", as+z, errno);
1023 if (errno && abortOnError)
1024 {
1025 return errno;
1026 }
1027 }
1028 else
1029 {
1030 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
1031 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
1032 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
1033 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (apply) <ignored>"
1034 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
1035 ? "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
1036 : "asopStreamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
1037 as+z, logArg);
1038 }
1039 }
1041 return 0;
1042 } //asopStreamChainFunction
1045 /* nothing past this point */