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