c63e826d115cda05ccdc3c83a01242ad7b152695
2 /*
3 Copyright (c) 2017, 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 */
36 /*
37 * ======== audioStreamOutProc.c ========
38 */
40 #include <string.h> // for memset
41 #include <xdc/runtime/Log.h>
42 #include <xdc/runtime/Error.h>
43 #include <xdc/runtime/Memory.h>
44 #include <ti/sysbios/knl/Clock.h>
45 #include <ti/sysbios/knl/Task.h>
47 #include "paferr.h"
48 #include <acp_mds.h>
49 #include <pcm.h>
50 #include <pce.h>
51 #include <pafsio_ialg.h>
52 #include <stdasp.h>
53 #include <doberr.h>
54 #include "asperr.h"
56 #include "common.h"
57 #include "aspMsg_common.h"
58 #include "aspMsg_master.h"
59 #include "aspDecOpCircBuf_master.h"
60 #include "audioStreamProc_common.h"
61 #include "audioStreamOutProc.h"
63 #include "pfp/pfp.h"
64 #include "pfp_app.h" /* contains all PFP ID's */
66 // FL: debug
67 #include "evmc66x_gpio_dbg.h"
70 #define TRACE_TIME(a)
72 //
73 // Audio Stream Definitions
74 //
76 //
77 // Audio Stream Processing Definitions
78 //
79 #define aspLinkInit pQ->i_aspLinkInit
81 //
82 // Encoder Definitions
83 //
84 #define encLinkInit pQ->i_encLinkInit
86 //
87 // Output Definitions
88 //
89 #define outLinkInit pP->i_outLinkInit
91 /* ---------------------------------------------------------------- */
92 /* Parameter macro definitions end here. */
93 /* ---------------------------------------------------------------- */
95 //
96 // Standardized Definitions
97 //
99 #define ENC_Handle PCE_Handle /* works for all: PCE */
101 #define __TASK_NAME__ "TaskAsop"
104 /* FL: Check if at least one output selected */
105 static Int checkOutSel(
106 const PAF_ASOT_Params *pP,
107 PAF_ASOT_Config *pC,
108 Int *pOutSel
109 );
111 /* FL: Check if at least one output sio changed */
112 static Int checkOutSio(
113 const PAF_ASOT_Params *pP,
114 PAF_ASOT_Config *pC,
115 Int *pOutSioUpdate
116 );
118 LINNO_DEFN(TaskAsop); /* Line number macros */
119 ERRNO_DEFN(TaskAsop); /* Error number macros */
121 // ASOT configuration
122 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
123 PAF_ASOT_Config gPAF_ASOT_config = {
124 NULL, // taskHandle
125 NULL, // acp
126 &gPAF_ASPM_config, // pAspmCfg
127 &gPAF_AST_config // pAstCfg
128 };
130 // Underflow threshold before circular buffer reset and return error to Top-Level FSM
131 #define DEC_OP_CB_RDAF_UND_THR ( 80 ) // FL: arbitrary setting
132 UInt32 gCbReadAfErr =0; // read circular buffer error count, not including underflows
133 UInt32 gDecOpCbRdAfUnd =0; // decoder output circular buffer underflow count
134 UInt32 gMaxDecOpCbRdAfUnd =0; // max (consecutive) decoder output circular buffer underflow count
136 // Global debug counters */
137 UInt32 gTaskAsopCnt=0; // debug
138 UInt32 gAsopInitCnt =0;
139 UInt32 gAsopStreamCnt =0;
140 UInt32 gAsopEncodeCnt =0;
141 UInt32 gAsopFinalCnt =0;
142 UInt32 gAsopQuitCnt =0;
145 /*
146 * ======== taskAsopFxn ========
147 * Audio Stream Output Processing task function
148 */
149 Void taskAsopFxn(
150 // Int betaPrimeValue, // FL: revisit
151 const PAF_ASOT_Params *pP,
152 const PAF_ASOT_Patchs *pQ
153 )
154 {
155 PAF_ASOT_Config *pC; /* Local configuration pointer */
156 PAF_AST_Config *pAstCfg; /* Common (shared) configuration pointer */
157 Int as; /* Audio Stream Number (1, 2, etc.) */
158 Int z; /* input/encode/stream/decode/output counter */
159 Int i; /* phase */
160 Int errno; /* error number */
161 Int zMS;
162 Int loopCount = 0; // used to stop trace to see startup behavior.
164 Log_info0("Enter taskAsopFxn()");
166 //
167 // Audio Framework Parameters & Patch (*pP, *pQ)
168 //
169 if (!pP)
170 {
171 TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
172 LINNO_RPRT(TaskAsop, -1);
173 return;
174 }
176 if (!pQ)
177 {
178 TRACE_TERSE0("TaskAsip: No Patchs defined. Exiting.");
179 LINNO_RPRT(TaskAsop, -1);
180 return;
181 }
183 //
184 // Audio Framework Configuration (*pC):
185 //
186 pC = &gPAF_ASOT_config; // initialize pointer to task configuration
187 pC->taskHandle = Task_self(); // set task handle
188 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
190 /* Obtain Audio Stream Number (1, 2, etc.) */
191 as = pAstCfg->as;
192 TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
194 //
195 // Initialize message log trace and line number reporting
196 //
197 for (z=STREAM1; z < STREAMN; z++)
198 {
199 TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
200 }
201 LINNO_RPRT(TaskAsop, -1);
203 //
204 // Determine stream index
205 //
206 zMS = pAstCfg->masterStr;
208 // Initialize as per parametrized phases:
209 //
210 // In standard form these are:
211 // - Malloc: Memory Allocation
212 // - Config: Configuration Initialization
213 // - AcpAlg: ACP Algorithm Initialization and Local Attachment
214 // - Common: Common Memory Initialization
215 // - AlgKey: Dec/Enc chain to Array Initialization
216 // - Device: I/O Device Initialization
217 // - Unused: (available)
218 // - Unused: (available)
219 //
220 LINNO_RPRT(TaskAsop, -2);
221 for (i=0; i < lengthof(pP->fxns->initPhase); i++)
222 {
223 Int linno;
224 if (pP->fxns->initPhase[i])
225 {
226 if (linno = pP->fxns->initPhase[i](pP, pQ, pC))
227 {
228 LINNO_RPRT(TaskAsop, linno);
229 return;
230 }
231 }
232 else
233 {
234 TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
235 }
236 TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
237 LINNO_RPRT(TaskAsop, -i-3);
238 }
240 //
241 // End of Initialization -- display memory usage report.
242 //
243 if (pP->fxns->memStatusPrint)
244 {
245 pP->fxns->memStatusPrint(HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, HEAP_INTERNAL1_SHM);
246 }
248 //
249 // Main processing loop
250 //
251 for (z=STREAM1; z < STREAMN; z++)
252 {
253 TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
254 }
256 errno = 0;
257 for (;;)
258 {
259 Int outSel;
261 loopCount++;
262 TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
264 // any error forces idling of output
265 if (errno)
266 {
267 for (z=OUTPUT1; z < OUTPUTN; z++)
268 {
269 if (pAstCfg->xOut[z].hTxSio)
270 {
271 SIO_idle(pAstCfg->xOut[z].hTxSio);
272 }
273 }
275 TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
276 ERRNO_RPRT(TaskAsop, errno);
277 }
279 TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
280 Task_sleep(1);
282 TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
283 if (errno = pP->fxns->selectDevices(pP, pQ, pC))
284 {
285 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
286 continue;
287 }
289 // if no output selected skip any remaining processing
290 if (errno = checkOutSel(pP, pC, &outSel))
291 {
292 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
293 continue;
294 }
295 else if (!outSel)
296 {
297 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
298 continue;
299 }
301 TRACE_VERBOSE0("TaskAsop: calling outputProcessing.");
302 errno = pP->fxns->decodeProcessing(pP, pQ, pC, -1);
303 if (errno)
304 {
305 TRACE_TERSE1("TaskAsop: outputProcessing returns 0x%x, continue", errno);
306 }
307 else
308 {
309 TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
310 }
311 } // End of main processing loop for (;;)
313 Log_info0("Exit taskAsopFxn()");
314 }
316 // -----------------------------------------------------------------------------
317 // AST Initialization Function - Memory Allocation
318 //
319 // Name: PAF_ASOT_initPhaseMalloc
320 // Purpose: Audio Stream Output Task Function for initialization of data pointers
321 // by allocation of memory.
322 // From: audioStream1Task or equivalent
323 // Uses: See code.
324 // States: x
325 // Return: 0 on success.
326 // Source code line number on MEM_calloc failure.
327 // Trace: Message Log "trace" in Debug Project Configuration reports:
328 // * State information as per parent.
329 // * Memory allocation errors.
330 //
332 Int
333 PAF_ASOT_initPhaseMalloc (
334 const PAF_ASOT_Params *pP,
335 const PAF_ASOT_Patchs *pQ,
336 PAF_ASOT_Config *pC
337 )
338 {
339 PAF_AST_Config *pAstCfg;
340 Int as; /* Audio Stream Number (1, 2, etc.) */
341 Int zMS;
342 Error_Block eb;
343 //Int i;
345 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
346 as = pAstCfg->as;
347 zMS = pAstCfg->masterStr;
349 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
351 // Initialize error block
352 Error_init(&eb);
354 /* Stream memory */
355 if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
356 {
357 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
358 SW_BREAKPOINT;
359 return __LINE__;
360 }
361 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
362 STREAMN * sizeof (*pAstCfg->xStr),
363 HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
365 {
366 Int z; /* stream counter */
368 PAF_AudioFrame *fBuf;
370 if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
371 {
372 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
373 SW_BREAKPOINT;
374 return __LINE__;
375 }
376 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
377 STREAMS * sizeof (*fBuf),
378 HEAP_ID_INTERNAL, (IArg)fBuf);
380 for (z=STREAM1; z < STREAMN; z++)
381 {
382 pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
383 TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
384 }
385 }
387 /* Encode memory */
388 if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
389 {
390 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
391 SW_BREAKPOINT;
392 return __LINE__;
393 }
394 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
395 ENCODEN * sizeof (*pAstCfg->xEnc),
396 HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
398 /* Output memory */
399 if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 4, &eb)))
400 {
401 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
402 SW_BREAKPOINT;
403 return __LINE__;
404 }
405 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xOut) %d bytes from space %d at 0x%x.",
406 OUTPUTN * sizeof (*pAstCfg->xOut),
407 HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
409 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
410 return 0;
411 } //PAF_ASOT_initPhaseMalloc
413 // -----------------------------------------------------------------------------
414 // ASOT Initialization Function - Memory Initialization from Configuration
415 //
416 // Name: PAF_ASOT_initPhaseConfig
417 // Purpose: Audio Stream Output Task Function for initialization of data values
418 // from parameters.
419 // From: audioStream1Task or equivalent
420 // Uses: See code.
421 // States: x
422 // Return: 0 on success.
423 // Other as per initFrame0 and initFrame1.
424 // Trace: Message Log "trace" in Debug Project Configuration reports:
425 // * State information as per parent.
426 //
427 Int
428 PAF_ASOT_initPhaseConfig(
429 const PAF_ASOT_Params *pP,
430 const PAF_ASOT_Patchs *pQ,
431 PAF_ASOT_Config *pC
432 )
433 {
434 PAF_AST_Config *pAstCfg;
435 Int as; /* Audio Stream Number (1, 2, etc.) */
436 Int z; /* input/encode/stream/decode/output counter */
437 Int zMS;
439 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
440 as = pAstCfg->as;
441 zMS = pAstCfg->masterStr;
443 TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
445 //
446 // Unspecified elements have been initialized to zero during alloc
447 //
449 for (z=STREAM1; z < STREAMN; z++)
450 {
451 Int linno;
452 if (linno = pP->fxns->initFrame0(pP, pQ, pC, z))
453 {
454 return linno;
455 }
456 if (linno = pP->fxns->initFrame1(pP, pQ, pC, z, -1))
457 {
458 return linno;
459 }
460 }
462 for (z=ENCODE1; z < ENCODEN; z++)
463 {
464 Int zO = pP->outputsFromEncodes[z];
465 Int zS = pP->streamsFromEncodes[z];
466 pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
467 pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
468 pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
469 pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
470 pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
471 pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
472 pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
473 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
474 }
476 for (z=OUTPUT1; z < OUTPUTN; z++)
477 {
478 pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
479 }
481 TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
482 return 0;
483 } //PAF_ASOT_initPhaseConfig
485 // -----------------------------------------------------------------------------
486 // ASOT Initialization Function - ACP Algorithm Instantiation
487 //
488 // Name: PAF_ASOT_initPhaseAcpAlg
489 // Purpose: Audio Stream Input Task Function for initialization of ACP by
490 // instantiation of the algorithm.
491 // From: audioStream1Task or equivalent
492 // Uses: See code.
493 // States: x
494 // Return: 0 on success.
495 // Source code line number on ACP Algorithm creation failure.
496 // Trace: Message Log "trace" in Debug Project Configuration reports:
497 // * State information as per parent.
498 // * Memory allocation errors.
499 //
500 Int
501 PAF_ASOT_initPhaseAcpAlg(
502 const PAF_ASOT_Params *pP,
503 const PAF_ASOT_Patchs *pQ,
504 PAF_ASOT_Config *pC
505 )
506 {
507 PAF_AST_Config *pAstCfg;
508 Int as; /* Audio Stream Number (1, 2, etc.) */
509 Int z; /* input/encode/stream/decode/output counter */
510 Int betaPrimeOffset;
511 ACP_Handle acp;
512 Int zMS;
513 Int zS, zX;
515 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
516 as = pAstCfg->as;
517 zMS = pAstCfg->masterStr;
519 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
521 ACP_MDS_init();
523 if (!(acp = (ACP_Handle )ACP_MDS_create(NULL)))
524 {
525 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation failed", as+zMS);
526 return __LINE__;
527 }
528 pC->acp = acp;
530 ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
531 ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
533 for (z=ENCODE1; z < ENCODEN; z++)
534 {
535 zS = pP->streamsFromEncodes[z];
536 acp->fxns->attach(acp, ACP_SERIES_STD,
537 STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
538 (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
539 acp->fxns->attach(acp, ACP_SERIES_STD,
540 STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
541 (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
542 /* Ignore errors, not reported. */
543 }
545 for (z=OUTPUT1; z < OUTPUTN; z++)
546 {
547 zS = z;
548 for (zX = ENCODE1; zX < ENCODEN; zX++)
549 {
550 if (pP->outputsFromEncodes[zX] == z)
551 {
552 zS = pP->streamsFromEncodes[zX];
553 break;
554 }
555 }
556 acp->fxns->attach(acp, ACP_SERIES_STD,
557 STD_BETA_OB + betaPrimeOffset * (as-1+zS),
558 (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
559 /* Ignore errors, not reported. */
560 }
562 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
564 return 0;
565 } //PAF_ASOT_initPhaseAcpAlg
567 // -----------------------------------------------------------------------------
568 // ASOT Initialization Function - Common Memory
569 //
570 // Name: PAF_ASOT_initPhaseCommon
571 // Purpose: Audio Stream Output Task Function for allocation of common memory.
572 // From: audioStream1Task or equivalent
573 // Uses: See code.
574 // States: x
575 // Return: 0 on success.
576 // Source code line number on PAF_ALG_alloc failure.
577 // Source code line number on PAF_ALG_mallocMemory failure.
578 // Source code line number on Decode Chain initialization failure.
579 // Source code line number on ASP Chain initialization failure.
580 // Source code line number on Encode Chain initialization failure.
581 // Trace: Message Log "trace" in Debug Project Configuration reports:
582 // * State information as per parent.
583 // * Memory allocation errors.
584 //
585 Int
586 PAF_ASOT_initPhaseCommon(
587 const PAF_ASOT_Params *pP,
588 const PAF_ASOT_Patchs *pQ,
589 PAF_ASOT_Config *pC
590 )
591 {
592 PAF_AST_Config *pAstCfg;
593 Int as; /* Audio Stream Number (1, 2, etc.) */
594 Int z; /* stream counter */
595 Int g; /* gear */
596 ACP_Handle acp;
597 PAF_IALG_Config pafAlgConfig;
598 IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
600 acp = pC->acp;
601 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
602 as = pAstCfg->as;
604 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
606 //
607 // Determine memory needs and instantiate algorithms across audio streams
608 //
609 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
610 PAF_ALG_setup(&pafAlgConfig,
611 HEAP_ID_INTERNAL, HEAP_INTERNAL,
612 HEAP_ID_INTERNAL1, HEAP_INTERNAL1,
613 HEAP_ID_EXTERNAL, HEAP_EXTERNAL,
614 HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM,
615 HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM,
616 HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
617 HEAP_CLEAR);
619 if (pP->fxns->headerPrint)
620 {
621 pP->fxns->headerPrint();
622 }
624 for (z = STREAM1; z < STREAMN; z++)
625 {
626 //Int zD, zE, zX;
627 Int zE, zX;
629 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
631 //
632 // Determine common memory needs for:
633 // (1) ASP Algorithms
634 // (2) Encode Algorithms
635 // (3) Logical Output drivers
636 //
637 PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
639 zE = -1;
640 for (zX = ENCODE1; zX < ENCODEN; zX++)
641 {
642 if (pP->streamsFromEncodes[zX] == z)
643 {
644 zE = zX;
645 break;
646 }
647 }
649 TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
650 if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z]))
651 {
652 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
653 TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
654 SW_BREAKPOINT;
655 return __LINE__;
656 }
657 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
658 if (pP->fxns->allocPrint)
659 {
660 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
661 }
663 if (zE >= 0)
664 {
665 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
666 if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z]))
667 {
668 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
669 SW_BREAKPOINT;
670 return __LINE__;
671 }
672 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
673 if (pP->fxns->allocPrint)
674 {
675 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
676 }
677 }
679 //
680 // Determine common memory needs of Logical IO drivers
681 //
683 if (OUTPUT1 <= z && z < OUTPUTN)
684 {
685 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
686 if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
687 {
688 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
689 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
690 SW_BREAKPOINT;
691 return __LINE__;
692 }
693 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
694 if (pP->fxns->allocPrint)
695 {
696 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
697 }
698 }
699 }
700 {
701 // Changes made to share scratch between zones
702 // Assume maximum 3 zones and scratch common memory is at offset 0;
703 int max=0;
704 for (z=STREAM1; z<STREAMN; z++)
705 {
706 if (max < common[z][0].size)
707 {
708 max = common[z][0].size;
709 }
710 }
711 common[STREAM1][0].size=max;
712 for (z=STREAM1+1; z<STREAMN; z++)
713 {
714 common[z][0].size = 0;
715 }
716 }
718 //
719 // Allocate common memory for:
720 // (1) ASP Algorithms
721 // (2) Encode Algorithms
722 // (3) Logical Output drivers
723 //
724 for (z = STREAM1; z < STREAMN; z++)
725 {
726 //Int zD, zE, zX;
727 Int zE, zX;
729 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
730 if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig))
731 {
732 TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
733 TRACE_TERSE3("AS%d: z: %d. Size 0x%x", as+z, z, common[z][0].size);
734 SW_BREAKPOINT;
735 return __LINE__;
736 }
737 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
738 // share zone0 scratch with all zones
739 common[z][0].base = common[0][0].base;
740 if (pP->fxns->commonPrint)
741 {
742 pP->fxns->commonPrint(common[z], &pafAlgConfig);
743 }
745 zE = -1;
746 for (zX = ENCODE1; zX < ENCODEN; zX++)
747 {
748 if (pP->streamsFromEncodes[zX] == z)
749 {
750 zE = zX;
751 break;
752 }
753 }
755 pAstCfg->xStr[z].aspChain[0] = NULL;
756 for (g=0; g < GEARS; g++)
757 {
758 PAF_ASP_Chain *chain;
759 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
760 chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
761 HEAP_INTERNAL, as+z, acp, &trace,
762 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
763 if (!chain)
764 {
765 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
766 return __LINE__;
767 }
768 else
769 {
770 pAstCfg->xStr[z].aspChain[g] = chain;
771 }
772 }
774 if (zE >= 0)
775 {
776 PAF_ASP_Chain *chain;
777 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
778 chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
779 HEAP_INTERNAL, as+z, acp, &trace,
780 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
781 if (!chain)
782 {
783 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
784 return __LINE__;
785 }
786 }
788 //
789 // Allocate non-common memories for Logical IO drivers
790 // Since these structures are used at run-time we allocate from external memory
791 if (OUTPUT1 <= z && z < OUTPUTN)
792 {
793 PAF_ASP_Chain *chain;
794 TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
795 as+z, z);
796 chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
797 HEAP_EXTERNAL, as+z, acp, &trace,
798 outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
799 if (!chain)
800 {
801 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
802 return __LINE__;
803 }
804 }
805 }
806 TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
808 return 0;
809 } //PAF_ASOT_initPhaseCommon
811 // -----------------------------------------------------------------------------
812 // ASOT Initialization Function - Algorithm Keys
813 //
814 // Name: PAF_ASOT_initPhaseAlgKey
815 // Purpose: Audio Stream Output Task Function for initialization of data values
816 // from parameters for Algorithm Keys.
817 // From: audioStream1Task or equivalent
818 // Uses: See code.
819 // States: x
820 // Return: 0.
821 // Trace: Message Log "trace" in Debug Project Configuration reports:
822 // * State information as per parent.
823 //
824 // .............................................................................
825 Int
826 PAF_ASOT_initPhaseAlgKey(
827 const PAF_ASOT_Params *pP,
828 const PAF_ASOT_Patchs *pQ,
829 PAF_ASOT_Config *pC
830 )
831 {
832 PAF_AST_Config *pAstCfg;
833 Int as; /* Audio Stream Number (1, 2, etc.) */
834 Int z; /* decode/encode counter */
835 Int s; /* key number */
836 PAF_ASP_Link *that;
838 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
839 as = pAstCfg->as;
840 (void)as; // clear compiler warning in case not used with tracing disabled
842 TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
844 for (z=ENCODE1; z < ENCODEN; z++)
845 {
846 for (s=0; s < pP->pEncAlgKey->length; s++)
847 {
848 if ((pP->pEncAlgKey->code[s].full != 0) &&
849 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
850 {
851 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
852 }
853 /* Cast in interface, for now --Kurt */
854 else
855 {
856 pAstCfg->xEnc[z].encAlg[s] = NULL;
857 }
858 }
859 }
861 return 0;
862 } //PAF_ASOT_initPhaseAlgKey
864 // -----------------------------------------------------------------------------
865 // ASOT Initialization Function - I/O Devices
866 //
867 // Name: PAF_ASOT_initPhaseDevice
868 // Purpose: Audio Stream Output Task Function for initialization of I/O Devices.
869 // From: audioStream1Task or equivalent
870 // Uses: See code.
871 // States: x
872 // Return: 0 on success.
873 // Source code line number on device allocation failure.
874 // Trace: Message Log "trace" in Debug Project Configuration reports:
875 // * State information as per parent.
876 // * Memory allocation errors.
877 //
878 Int
879 PAF_ASOT_initPhaseDevice(
880 const PAF_ASOT_Params *pP,
881 const PAF_ASOT_Patchs *pQ,
882 PAF_ASOT_Config *pC
883 )
884 {
885 PAF_AST_Config *pAstCfg;
886 Int as; /* Audio Stream Number (1, 2, etc.) */
887 Int z; /* input/output counter */
888 PAF_SIO_IALG_Obj *pObj;
889 PAF_SIO_IALG_Config *pAlgConfig;
890 PAF_IALG_Config pafAlgConfig;
892 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
893 as = pAstCfg->as;
894 (void)as; // clear compiler warning in case not used with tracing disabled
896 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
898 if(pP->fxns->bufMemPrint)
899 {
900 PAF_ALG_setup (&pafAlgConfig,
901 HEAP_ID_INTERNAL, HEAP_INTERNAL,
902 HEAP_ID_INTERNAL1, HEAP_INTERNAL1,
903 HEAP_ID_EXTERNAL, HEAP_EXTERNAL,
904 HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM,
905 HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM,
906 HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
907 HEAP_CLEAR);
908 TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
909 }
911 for (z=OUTPUT1; z < OUTPUTN; z++)
912 {
913 PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
915 pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
916 pAlgConfig = &pObj->config;
918 pAstCfg->xOut[z].hTxSio = NULL;
919 pConfig->base.pVoid = pAlgConfig->pMemRec[0].base;
920 pConfig->pntr.pVoid = pAlgConfig->pMemRec[0].base;
921 pConfig->head.pVoid = pAlgConfig->pMemRec[0].base;
922 pConfig->allocation = pAlgConfig->pMemRec[0].size;
923 pConfig->sizeofElement = 3;
924 pConfig->precision = 24;
925 if(pP->fxns->bufMemPrint)
926 {
927 pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
928 }
929 }
930 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
932 return 0;
933 } //PAF_ASOT_initPhaseDevice
935 // -----------------------------------------------------------------------------
936 // ASOT Initialization Function Helper - Initialization of Audio Frame
937 //
938 // Name: PAF_ASOT_initFrame0
939 // Purpose: Audio Stream Output Task Function for initialization of the Audio
940 // Frame(s) by memory allocation and loading of data pointers
941 // and values.
942 // From: AST Parameter Function -> decodeInfo
943 // Uses: See code.
944 // States: x
945 // Return: 0 on success.
946 // Source code line number on MEM_calloc failure.
947 // Source code line number on unsupported option.
948 // Trace: Message Log "trace" in Debug Project Configuration reports:
949 // * Memory allocation errors.
950 // * Unsupported option errors.
951 //
953 // MID 314
954 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
955 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
957 Int
958 PAF_ASOT_initFrame0(
959 const PAF_ASOT_Params *pP,
960 const PAF_ASOT_Patchs *pQ,
961 PAF_ASOT_Config *pC,
962 Int z
963 )
964 {
965 PAF_AST_Config *pAstCfg;
966 Int as; /* Audio Stream Number (1, 2, etc.) */
967 Int ch;
968 //Int aLen;
969 Int aLen_int=0,aLen_ext=0;
970 Int aSize = sizeof(PAF_AudioData);
971 Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
972 Int maxFrameLength = pP->maxFramelength;
973 Int zX;
974 PAF_AudioData *aBuf_int=NULL;
975 PAF_AudioData *aBuf_ext=NULL;
976 XDAS_UInt8 *metadataBuf;
977 char i;
978 Error_Block eb;
980 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
981 as = pAstCfg->as;
983 // Initialize error block
984 Error_init(&eb);
986 // Compute maximum framelength (needed for ARC support)
987 maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
988 //aLen = numchan[z] * maxFrameLength;
989 for (i=0; i < numchan[z]; i++)
990 {
991 if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
992 {
993 aLen_int += maxFrameLength;
994 }
995 else
996 {
997 aLen_ext += maxFrameLength;
998 }
999 }
1001 //
1002 // Initialize audio frame elements directly
1003 //
1004 pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
1005 pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
1006 /// pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
1007 pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
1008 pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
1009 pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
1010 pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1012 //
1013 // Allocate memory for and initialize pointers to audio data buffers
1014 //
1015 // The NUMCHANMASK is used to identify the channels for which data
1016 // buffers can be allocated. Using this mask and switch statement
1017 // rather than some other construct allows efficient code generation,
1018 // providing just the code necessary (with significant savings).
1019 //
1020 if (pP->fxns->bufMemPrint)
1021 {
1022 pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1023 pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1024 }
1026 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1028 if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1029 {
1030 if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1031 {
1032 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1033 TRACE_TERSE2(" maxFrameLength: %d. aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1034 SW_BREAKPOINT;
1035 return __LINE__;
1036 }
1037 }
1039 if (aLen_ext*aSize!=0)
1040 {
1041 if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb)))//Qin: Add start offset
1042 {
1043 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1044 TRACE_TERSE2(" maxFrameLength: %d. aLen_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1045 SW_BREAKPOINT;
1046 return __LINE__;
1047 }
1048 }
1050 TRACE_TERSE3(" maxFrameLength: %d. aLen_int*aSize: %d. aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1051 TRACE_TERSE3(" maxFrameLength: %d. aLen_ext*aSize: %d. aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1053 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1054 if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1055 {
1056 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1057 TRACE_TERSE1(" bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1058 SW_BREAKPOINT;
1059 return __LINE__;
1060 }
1062 {
1063 Int i;
1065 #pragma UNROLL(1)
1066 for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1067 {
1068 pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1069 }
1070 }
1072 // MID 314
1073 if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1))
1074 {
1075 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1076 return __LINE__;
1077 }
1078 else
1079 {
1080 Int j = 0;
1081 Int k = 0;
1082 TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1083 for(i=0;i<numchan[z];i++)
1084 {
1085 char chan = AFChanPtrMap[numchan[z]][i];
1086 if(chan != -1)
1087 {
1088 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1089 {
1090 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1091 j++;
1092 }
1093 else
1094 {
1095 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1096 k++;
1097 }
1098 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1099 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1100 }
1101 }
1102 }
1104 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1105 {
1106 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1107 {
1108 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1109 }
1110 }
1112 //
1113 // Initialize meta data elements
1114 //
1115 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1116 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1117 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1118 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1119 pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1120 for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1121 {
1122 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1123 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1124 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1125 }
1127 //
1128 // Initialize decoder elements directly
1129 //
1131 for (zX = DECODE1; zX < DECODEN; zX++)
1132 {
1133 if (pP->streamsFromDecodes[zX] == z)
1134 {
1135 #ifdef NOAUDIOSHARE
1136 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1137 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1138 #else /* NOAUDIOSHARE */
1139 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1140 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1141 #endif /* NOAUDIOSHARE */
1142 }
1143 }
1145 return 0;
1146 } //PAF_ASOT_initFrame0
1148 // -----------------------------------------------------------------------------
1149 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1150 // AST Decoding Function - Reinitialization of Audio Frame
1151 //
1152 // Name: PAF_ASOT_initFrame1
1153 // Purpose: Audio Stream Task Function for initialization or reinitiali-
1154 // zation of the Audio Frame(s) by loading of data values of a
1155 // time-varying nature.
1156 // From: audioStream1Task or equivalent
1157 // AST Parameter Function -> decodeInfo
1158 // AST Parameter Function -> decodeDecode
1159 // Uses: See code.
1160 // States: x
1161 // Return: 0.
1162 // Trace: None.
1163 //
1164 Int
1165 PAF_ASOT_initFrame1(
1166 const PAF_ASOT_Params *pP,
1167 const PAF_ASOT_Patchs *pQ,
1168 PAF_ASOT_Config *pC,
1169 Int z,
1170 Int apply
1171 )
1172 {
1173 PAF_AST_Config *pAstCfg;
1175 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1177 //
1178 // Reinitialize audio frame elements:
1179 //
1180 // Channel Configurations during sys init = Unknown
1181 // " " during info or decode = None
1182 //
1183 // Sample Rate / Count during sys init, info or decode = Unknown / 0
1184 //
1186 if (apply < 0)
1187 {
1188 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1189 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1190 }
1191 else
1192 {
1193 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1194 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1195 }
1197 if (apply < 1)
1198 {
1199 pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1200 pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1201 }
1203 return 0;
1204 } //PAF_ASOT_initFrame1
1206 // -----------------------------------------------------------------------------
1207 // ASOT Selection Function - Output Device Selection
1208 //
1209 // Name: PAF_ASOT_selectDevices
1210 // Purpose: Audio Stream Output Task Function for selecting the devices used
1211 // for output.
1212 // From: audioStream1Task or equivalent
1213 // Uses: See code.
1214 // States: x
1215 // Return: Error number in standard form (0 on success).
1216 // Trace: Message Log "trace" in Debug Project Configuration reports:
1217 // * State information as per parent.
1218 //
1219 Int
1220 PAF_ASOT_selectDevices(
1221 const PAF_ASOT_Params *pP,
1222 const PAF_ASOT_Patchs *pQ,
1223 PAF_ASOT_Config *pC
1224 )
1225 {
1226 PAF_AST_Config *pAstCfg;
1227 Int as; /* Audio Stream Number (1, 2, etc.) */
1228 Int z; /* input/output counter */
1229 Int errno = 0; /* error number */
1230 Int errme; /* error number, local */
1231 Int device;
1233 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1234 as = pAstCfg->as;
1235 (void)as; // clear compiler warning in case not used with tracing disabled
1237 // Select output devices
1238 for (z=OUTPUT1; z < OUTPUTN; z++)
1239 {
1240 if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0)
1241 {
1242 TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1244 /* check for valid index into device array */
1245 if (device >= pQ->devout->n)
1246 {
1247 device = 0; /* treat as device None */
1248 }
1250 errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT,
1251 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1252 if (errme)
1253 {
1254 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1255 if (!errno)
1256 {
1257 errno = ASPERR_DEVOUT + errme;
1258 }
1259 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1260 }
1261 else
1262 {
1263 Int zE;
1265 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1266 // register outBufStatus and encodeStatus pointers with output devices
1267 // This enables proper IEC encapsulation.
1268 if (pAstCfg->xOut[z].hTxSio)
1269 {
1270 // set max # of output buffers (use override if necessary)
1271 if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1272 {
1273 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1274 (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1275 }
1276 else
1277 {
1278 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1279 (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1280 }
1282 // register PAF_SIO_IALG object address
1283 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1284 (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1285 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR,
1286 (Arg)&pAstCfg->xOut[z].outBufStatus);
1287 for (zE=ENCODE1; zE < ENCODEN; zE++)
1288 {
1289 if (pP->outputsFromEncodes[zE] == z)
1290 {
1291 SIO_ctrl(pAstCfg->xOut[z].hTxSio,
1292 PAF_SIO_CONTROL_SET_ENCSTATUSADDR,
1293 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1294 break;
1295 }
1296 }
1297 }
1298 }
1299 }
1301 // if device selected and valid then enable stat tracking if
1302 // required and start clocking
1303 if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
1304 {
1305 TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1306 errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1307 if (errme)
1308 {
1309 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1310 SIO_idle(pAstCfg->xOut[z].hTxSio);
1311 if (!errno)
1312 {
1313 errno = ASPERR_DEVOUT + errme;
1314 }
1315 }
1316 }
1317 }
1319 return errno;
1320 } //PAF_ASOT_selectDevices
1323 // -----------------------------------------------------------------------------
1324 // ASOT Processing Function - Decode Processing
1325 //
1326 // Name: PAF_ASOT_decodeProcessing
1327 // Purpose: Audio Stream Output Task Function for processing audio data.
1328 //
1329 Int
1330 PAF_ASOT_decodeProcessing(
1331 const PAF_ASOT_Params *pP,
1332 const PAF_ASOT_Patchs *pQ,
1333 PAF_ASOT_Config *pC,
1334 Int sourceSelect
1335 )
1336 {
1337 PAF_AST_Config *pAstCfg;
1338 Int z; /* decode counter */
1339 Int errno; /* error number */
1340 Int getVal;
1341 enum { INIT, STREAM, ENCODE, FINAL, QUIT } state;
1342 state = INIT;
1343 errno = 0; /* error number */
1344 Int frame; // (***) FL: formerly -- decoder input frame count
1345 Int block; // decoder output block count / input frame
1346 Int outSioUpdate;
1348 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1350 for (;;)
1351 {
1352 // FL: Check if any change in output SIO, e.g. from Output shortcut.
1353 // Changes will break FSM and allow Output reconfiguration.
1354 if (errno = checkOutSio(pP, pC, &outSioUpdate))
1355 {
1356 TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1357 break;
1358 }
1359 else if (outSioUpdate)
1360 {
1361 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1362 state = QUIT;
1363 }
1365 // Process commands (encode)
1366 if (getVal = pP->fxns->encodeCommand(pP, pQ, pC))
1367 {
1368 /* ignore */;
1369 }
1371 // Process state (decode)
1372 switch (state)
1373 {
1374 case INIT: // initial state
1375 gAsopInitCnt++;
1376 Log_info0("TaskAsop: state=INIT");
1378 // Reset audio frame pointers to original values
1379 // (may be needed if error occurred).
1380 for (z=STREAM1; z < STREAMN; z++)
1381 {
1382 Int ch;
1383 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1384 {
1385 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1386 {
1387 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1388 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1389 }
1390 }
1391 }
1393 // Reset audio frame meta data elements
1394 {
1395 Int i;
1397 for (z=STREAM1; z < STREAMN; z++)
1398 {
1399 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1400 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1401 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1402 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1404 for (i=0; i<pP->pMetadataBufStatus->NumBuf; i++)
1405 {
1406 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1407 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1408 }
1409 }
1410 }
1412 if (errno = pP->fxns->decodeInit(pP, pQ, pC, sourceSelect))
1413 {
1414 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInit", errno);
1415 break;
1416 }
1418 // (***) FL: setup output (ASP chain reset, ENC reset, setCheckRateX, start output)
1419 // Contained in INFO1 in combined FSM.
1420 // Establish secondary timing
1421 if (errno = pP->fxns->decodeInfo1(pP, pQ, pC, frame, block))
1422 {
1423 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInfo1", errno);
1424 break;
1425 }
1427 frame = 0;
1428 block = 0;
1430 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");
1431 state = STREAM;
1432 continue;
1434 case STREAM: // stream state
1435 gAsopStreamCnt++;
1436 Log_info0("TaskAsop: state=STREAM");
1438 if (errno = pP->fxns->decodeStream(pP, pQ, pC, frame, block))
1439 {
1440 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM. decodeStream err 0x%x", errno);
1441 break;
1442 }
1444 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1445 state = ENCODE;
1446 continue;
1448 case ENCODE: // encode state
1449 gAsopEncodeCnt++;
1450 Log_info0("TaskAsop: state=ENCODE");
1452 if (errno = pP->fxns->decodeEncode(pP, pQ, pC, frame, block))
1453 {
1454 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE. decodeEncode err 0x%x", errno);
1455 break;
1456 }
1458 // Measure cycles in output processing loop.
1459 // Only measures cycles spent in loop.
1460 pfpEnd(PFP_ID_ASOT_0, PFP_FINISH_MEAS);
1461 pfpBegin(PFP_ID_ASOT_0, pC->taskHandle);
1463 // (***) FL: do we need this?
1464 // AF pointers come from CB read, any resets occur in Decoder AF.
1465 // Reset audio frame pointers to original values
1466 // (may have been adjusted by ARC or the like).
1467 for (z=STREAM1; z < STREAMN; z++)
1468 {
1469 Int ch;
1470 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1471 {
1472 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1473 {
1474 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1475 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1476 }
1477 }
1478 }
1480 //
1481 // (***) FL: update output (setCheckRateX)
1482 // Contained in INFO2 in combined FSM.
1483 if (errno = pP->fxns->decodeInfo2(pP, pQ, pC, frame, block))
1484 {
1485 TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1486 break;
1487 }
1489 block++;
1490 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1491 state = FINAL;
1492 continue;
1494 case FINAL:
1495 gAsopFinalCnt++;
1496 Log_info0("TaskAsop: state=FINAL");
1498 //
1499 // (***) FL: this needs to be fixed.
1500 // (1) Only require selected Output to be in this FSM
1501 // => Dec Status checks aren't valid,
1502 // will probably always exit FSM if only Output running
1503 // (2) Checking Dec Status info asych to input events (maybe ok)
1504 //
1505 #if 0
1506 // Check for final frame, and if indicated:
1507 // - Update audio flag to cause output buffer flush rather than
1508 // the default truncate in "complete" processing.
1509 // - Exit state machine to "complete" processing.
1510 if (pP->fxns->decodeFinalTest(pP, pQ, pC, frame, block))
1511 {
1512 for (z=OUTPUT1; z < OUTPUTN; z++)
1513 {
1514 if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1515 {
1516 TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1517 pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1518 }
1519 }
1520 break;
1521 }
1522 #endif
1524 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1525 state = STREAM;
1526 continue;
1528 case QUIT:
1529 gAsopQuitCnt++;
1530 Log_info0("TaskAsop: state=QUIT");
1532 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1533 errno = ASPERR_QUIT;
1534 break;
1536 default: // unknown state
1537 // Unknown:
1538 // - Set error number registers.
1539 // - Exit state machine to "complete" processing.
1541 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1542 errno = ASPERR_UNKNOWNSTATE;
1543 break;
1545 } // End of switch (state).
1547 pfpEnd(PFP_ID_ASOT_0, PFP_FINISH_MEAS); // PFP end -- outside of PFP for errors, EOS, or Output SIO change
1549 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1550 if (pP->fxns->decodeComplete(pP, pQ, pC, NULL, frame, block))
1551 {
1552 /* ignored? */;
1553 }
1555 return errno;
1556 } // End of for (;;)
1558 return errno;
1559 }
1561 // -----------------------------------------------------------------------------
1562 // ASOT Decoding Function - Encode Command Processing
1563 //
1564 // Name: PAF_ASOT_encodeCommand
1565 // Purpose: Decoding Function for processing Encode Commands.
1566 // From: AST Parameter Function -> decodeProcessing
1567 // Uses: See code.
1568 // States: x
1569 // Return: 0.
1570 // Trace: Message Log "trace" in Debug Project Configuration reports:
1571 // * Command execution.
1572 // * SIO control errors.
1573 // * Error number macros.
1574 //
1575 Int
1576 PAF_ASOT_encodeCommand(
1577 const PAF_ASOT_Params *pP,
1578 const PAF_ASOT_Patchs *pQ,
1579 PAF_ASOT_Config *pC
1580 )
1581 {
1582 PAF_AST_Config *pAstCfg;
1583 Int as; /* Audio Stream Number (1, 2, etc.) */
1584 Int z; /* encode counter */
1585 Int errno = 0; /* error number */
1586 Int zO, zS;
1589 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1590 as = pAstCfg->as;
1592 for (z=ENCODE1; z < ENCODEN; z++)
1593 {
1594 zO = pP->outputsFromEncodes[z];
1595 zS = pP->streamsFromEncodes[z];
1596 if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80))
1597 {
1598 switch (pAstCfg->xEnc[z].encodeStatus.command2)
1599 {
1600 case 0: // command none - process
1601 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1602 break;
1603 case 1: // mute command
1604 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
1605 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1606 && pAstCfg->xOut[zO].hTxSio
1607 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
1608 {
1609 errno = (errno & 0xff) | ASPERR_MUTE;
1610 /* convert to sensical errno */
1611 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
1612 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1613 }
1614 else
1615 {
1616 pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
1617 }
1618 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1619 break;
1620 case 2: // unmute command
1621 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
1622 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1623 && pAstCfg->xOut[zO].hTxSio
1624 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
1625 {
1626 errno = (errno & 0xff) | ASPERR_MUTE;
1627 /* convert to sensical errno */
1628 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
1629 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1630 }
1631 else
1632 {
1633 pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
1634 }
1635 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1636 break;
1637 default: // command unknown - ignore
1638 break;
1639 }
1640 }
1641 }
1643 ERRNO_RPRT (TaskAsop, errno);
1645 return 0;
1646 } //PAF_ASOT_encodeCommand
1648 // Purpose: Decoding Function for reinitializing the decoding process.
1649 Int
1650 PAF_ASOT_decodeInit(
1651 const PAF_ASOT_Params *pP,
1652 const PAF_ASOT_Patchs *pQ,
1653 PAF_ASOT_Config *pC,
1654 Int sourceSelect
1655 )
1656 {
1657 PAF_AST_Config *pAstCfg;
1658 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1659 Int as; /* Audio Stream Number (1, 2, etc.) */
1660 Int z; /* decode/encode counter */
1661 Int errno; /* error number */
1662 Int zO, zS;
1665 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1666 as = pAstCfg->as;
1668 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1670 for (z=DECODE1; z < DECODEN; z++)
1671 {
1672 // Start decoder output circular buffer reads
1673 errno = cbReadStart(pCbCtl, z);
1674 if (errno)
1675 {
1676 TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
1677 SW_BREAKPOINT; // FL: debug
1678 return errno;
1679 }
1680 gCbReadAfErr=0; // reset read circular buffer error count
1681 gDecOpCbRdAfUnd=0; // reset decoder output circular buffer underflow count
1682 gMaxDecOpCbRdAfUnd=0; // reset max decoder output circular buffer underflow count
1684 // FL: debug
1685 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
1686 }
1688 // TODO: move this to start of this function so that it doesn't affect IO timing
1689 for (z=ENCODE1; z < ENCODEN; z++)
1690 {
1691 zO = pP->outputsFromEncodes[z];
1692 zS = pP->streamsFromEncodes[z];
1693 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1694 {
1695 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1696 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1697 ENC_Handle enc = (ENC_Handle )encAlg;
1698 TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
1699 if (encAlg->fxns->algActivate)
1700 {
1701 encAlg->fxns->algActivate (encAlg);
1702 }
1703 if (enc->fxns->reset
1704 && (errno = enc->fxns->reset(enc, NULL,
1705 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1706 {
1707 return errno;
1708 }
1709 }
1710 }
1713 return 0;
1714 }
1716 // -----------------------------------------------------------------------------
1717 // ASOT Decoding Function - Info Processing, Initial
1718 //
1719 // Name: PAF_ASOT_decodeInfo1
1720 // Purpose: Decoding Function for processing information in a manner that
1721 // is unique to initial frames of input data.
1722 // From: AST Parameter Function -> decodeProcessing
1723 // Uses: See code.
1724 // States: x
1725 // Return: Error number in standard or SIO form (0 on success).
1726 // Trace: Message Log "trace" in Debug Project Configuration reports:
1727 // * State information as per parent.
1728 //
1729 Int
1730 PAF_ASOT_decodeInfo1(
1731 const PAF_ASOT_Params *pP,
1732 const PAF_ASOT_Patchs *pQ,
1733 PAF_ASOT_Config *pC,
1734 Int frame,
1735 Int block
1736 )
1737 {
1738 PAF_AST_Config *pAstCfg;
1739 Int z; /* decode/encode counter */
1740 Int errno; /* error number */
1742 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1744 // run the chain of ASP's on the stream.
1745 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
1746 if (errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1747 PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame))
1748 {
1749 TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
1750 return errno;
1751 }
1753 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
1754 for (z=ENCODE1; z < ENCODEN; z++)
1755 {
1756 Int zO = pP->outputsFromEncodes[z];
1757 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1758 {
1759 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1760 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1761 ENC_Handle enc = (ENC_Handle )encAlg;
1762 if (enc->fxns->info
1763 && (errno = enc->fxns->info(enc, NULL,
1764 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1765 {
1766 TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
1767 return errno;
1768 }
1769 }
1770 }
1772 if (errno = pP->fxns->setCheckRateX(pP, pQ, pC, 0))
1773 {
1774 // ignore if rateX has changed since we haven't, but are about to,
1775 // start the output. If we didn't ignore this case then the state machine
1776 // would restart unnecessarily, e.g. in the case of SRC, resulting in
1777 // added latency.
1778 if (errno != ASPERR_INFO_RATECHANGE)
1779 {
1780 TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
1781 return errno;
1782 }
1783 else
1784 {
1785 TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
1786 }
1787 }
1789 if (errno = pP->fxns->startOutput(pP, pQ, pC))
1790 {
1791 if (errno == 0x105)
1792 {
1793 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
1794 }
1795 else
1796 {
1797 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
1798 }
1799 return errno;
1800 }
1802 return 0;
1803 }
1805 // -----------------------------------------------------------------------------
1806 // ASOT Decoding Function - Info Processing, Subsequent
1807 //
1808 // Name: PAF_ASOT_decodeInfo2
1809 // Purpose: Decoding Function for processing information in a manner that
1810 // is unique to frames of input data other than the initial one.
1811 // From: AST Parameter Function -> decodeProcessing
1812 // Uses: See code.
1813 // States: x
1814 // Return: Error number in standard form (0 on success).
1815 // Trace: None.
1816 //
1817 Int
1818 PAF_ASOT_decodeInfo2(
1819 const PAF_ASOT_Params *pP,
1820 const PAF_ASOT_Patchs *pQ,
1821 PAF_ASOT_Config *pC,
1822 Int frame,
1823 Int block
1824 )
1825 {
1826 //PAF_AST_Config *pAstCfg;
1827 Int errno;
1830 //pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1832 errno = pP->fxns->setCheckRateX (pP, pQ, pC, 1);
1833 TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
1834 return errno;
1835 } //PAF_ASOT_decodeInfo2
1837 // -----------------------------------------------------------------------------
1838 // ASOT Decoding Function - Stream Processing
1839 //
1840 // Name: PAF_ASOT_decodeStream
1841 // Purpose: Decoding Function for processing of audio frame data by the
1842 // ASP Algorithms.
1843 // From: AST Parameter Function -> decodeProcessing
1844 // Uses: See code.
1845 // States: x
1846 // Return: Error number in standard form (0 on success).
1847 // Trace: Message Log "trace" in Debug Project Configuration reports:
1848 // * State information as per parent/child.
1849 //
1850 Int
1851 PAF_ASOT_decodeStream(
1852 const PAF_ASOT_Params *pP,
1853 const PAF_ASOT_Patchs *pQ,
1854 PAF_ASOT_Config *pC,
1855 Int frame,
1856 Int block
1857 )
1858 {
1859 PAF_AST_Config *pAstCfg;
1860 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1861 Int z; /* decode/stream counter */
1862 PAF_AudioFrame *pAfRd;
1863 Int cbErrno;
1864 Int errno;
1867 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1869 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1871 for (z=DECODE1; z < DECODEN; z++)
1872 {
1873 Int zS = pP->streamsFromDecodes[z];
1875 //
1876 // Read decoder output circular buffer
1877 //
1878 pAfRd = pAstCfg->xStr[zS].pAudioFrame;
1879 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
1880 cbErrno = cbReadAf(pCbCtl, z, pAfRd);
1881 if ((cbErrno < 0) && (cbErrno != ASP_DECOP_CB_READ_UNDERFLOW))
1882 {
1883 gCbReadAfErr++;
1884 TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
1885 //SW_BREAKPOINT; // FL: debug
1886 return cbErrno;
1887 }
1889 // Handle underflows
1890 if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
1891 {
1892 // FL: some number of underflows alway occur on start of stream when ASOT only depends on configured Output.
1893 // DDP: ~2 underflows
1894 // MAT-THD: ~16 underflows
1895 // Need to check behavior of cbReset().
1896 // Need to check behavior on exit/re-entry into Output processing.
1898 gDecOpCbRdAfUnd++; // increment circular buffer underflow count
1899 if (gDecOpCbRdAfUnd >= DEC_OP_CB_RDAF_UND_THR)
1900 {
1901 // Underflow count above threshold.
1902 // (1) set max underflow count to threshold
1903 // (2) reset underflow count
1904 // (3) reset circular buffer
1906 gMaxDecOpCbRdAfUnd = DEC_OP_CB_RDAF_UND_THR; // update max underflow count
1907 gDecOpCbRdAfUnd = 0; // reset underflow count
1909 // Reset circular buffer
1910 cbReset(pCbCtl, z);
1911 Log_info0("PAF_ASOT_decodeStream:cbReset");
1913 return cbErrno;
1914 }
1915 }
1916 else if ((cbErrno == ASP_DECOP_CB_SOK) && (gDecOpCbRdAfUnd > 0))
1917 {
1918 // No underflow detected.
1919 // update max underflow count,
1920 // reset underflow count
1922 // update max underflow count
1923 if (gDecOpCbRdAfUnd > gMaxDecOpCbRdAfUnd)
1924 {
1925 gMaxDecOpCbRdAfUnd = gDecOpCbRdAfUnd;
1926 }
1927 gDecOpCbRdAfUnd = 0; // reset circular buffer underflow count
1928 }
1929 //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
1930 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1931 Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
1933 #if 0 // (***) FL: shows timing of CB read
1934 // (***) debug // B8
1935 {
1936 static Uint8 toggleState = 0;
1937 if (toggleState == 0)
1938 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
1939 else
1940 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1941 toggleState = ~(toggleState);
1942 }
1943 #endif
1945 // FL: debug
1946 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
1947 //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
1948 //{
1949 // Log_info0("capAfWrite() error");
1950 //}
1951 }
1953 TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
1954 errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1955 PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
1956 if (errno)
1957 {
1958 TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
1959 return errno;
1960 }
1962 return 0;
1964 } //PAF_ASOT_decodeStream
1966 // -----------------------------------------------------------------------------
1967 // ASOT Decoding Function - Encode Processing
1968 //
1969 // Name: PAF_ASOT_decodeEncode
1970 // Purpose: Decoding Function for processing of audio frame data by the
1971 // Encode Algorithm.
1972 // From: AST Parameter Function -> decodeProcessing
1973 // Uses: See code.
1974 // States: x
1975 // Return: Error number in standard or SIO form (0 on success).
1976 // Trace: Message Log "trace" in Debug Project Configuration reports:
1977 // * State information as per parent.
1978 //
1979 Int
1980 PAF_ASOT_decodeEncode(
1981 const PAF_ASOT_Params *pP,
1982 const PAF_ASOT_Patchs *pQ,
1983 PAF_ASOT_Config *pC,
1984 Int frame,
1985 Int block
1986 )
1987 {
1988 PAF_AST_Config *pAstCfg;
1989 Int as; /* Audio Stream Number (1, 2, etc.) */
1990 Int z; /* encode/output counter */
1991 Int errno; /* error number */
1992 Int zX, zE, zS;
1993 UInt32 curTime;
1995 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1996 as = pAstCfg->as;
1998 // Await output buffers (but not first time)
1999 for (z=OUTPUT1; z < OUTPUTN; z++)
2000 {
2001 // determine encoder associated with this output
2002 zE = z;
2003 for (zX = ENCODE1; zX < ENCODEN; zX++)
2004 {
2005 if (pP->outputsFromEncodes[zX] == z)
2006 {
2007 zE = zX;
2008 break;
2009 }
2010 }
2011 zS = pP->streamsFromEncodes[zE];
2013 if (pAstCfg->xOut[z].hTxSio)
2014 {
2015 // update length (e.g. ARC may have changed)
2016 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2017 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2018 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
2019 errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
2020 if (errno < 0)
2021 {
2022 SIO_idle(pAstCfg->xOut[z].hTxSio);
2023 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
2024 return -errno; // SIO negates error codes
2025 }
2026 // TODO: use pC->xOut[z].pOutBuf in following ->encode call
2028 #if 0 // (***) FL: shows timing of Output Rx SIO reclaim
2029 // (***) debug // B8
2030 {
2031 static Uint8 toggleState = 0;
2032 if (toggleState == 0)
2033 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
2034 else
2035 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
2036 toggleState = ~(toggleState);
2037 }
2038 #endif
2040 //
2041 // Simulate Tx SIO_reclaim() pend
2042 //
2043 //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
2044 gTaskAsopCnt++;
2045 curTime = Clock_getTicks();
2046 //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
2047 //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
2048 }
2049 else
2050 {
2051 TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
2052 }
2053 }
2055 // Encode data
2056 for (z=ENCODE1; z < ENCODEN; z++)
2057 {
2058 Int zO = pP->outputsFromEncodes[z];
2059 Int zS = pP->streamsFromEncodes[z];
2060 (void)zS; // clear compiler warning in case not used with tracing disabled
2061 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
2062 {
2063 Int select = pAstCfg->xEnc[z].encodeStatus.select;
2064 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2065 ENC_Handle enc = (ENC_Handle )encAlg;
2066 if (select != pAstCfg->xEnc[z].encodeControl.encActive)
2067 {
2068 pAstCfg->xEnc[z].encodeControl.encActive = select;
2069 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
2070 return (-1);
2071 }
2072 TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
2074 // (MID 1933) temp. workaround for PCE2
2075 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
2077 /*
2078 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2079 {
2080 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2081 int *wp;
2082 wp = (int*)pAudioFrame->data.sample[0];
2083 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2084 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2085 wp = (int*)pAudioFrame->data.sample[1];
2086 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2087 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2088 wp = (int*)pAudioFrame->data.sample[2];
2089 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2090 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2091 }
2092 #endif
2093 */
2095 if (enc->fxns->encode)
2096 {
2097 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2098 pP->z_pEncodeStatus[z]->encBypass;
2099 if (errno = enc->fxns->encode(enc, NULL,
2100 &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct))
2101 {
2102 if (errno != PCEERR_OUTPUT_POINTERNULL)
2103 {
2104 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2105 return errno;
2106 }
2107 }
2108 /* #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2109 else
2110 {
2111 int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2112 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2113 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2114 }
2115 #endif
2116 */
2117 }
2118 }
2119 else
2120 {
2121 TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2122 as+pP->streamsFromEncodes[z], block);
2123 }
2124 }
2126 // Transmit data
2127 for (z=OUTPUT1; z < OUTPUTN; z++)
2128 {
2129 // determine encoder associated with this output
2130 zE = z;
2131 for (zX = ENCODE1; zX < ENCODEN; zX++)
2132 {
2133 if (pP->outputsFromEncodes[zX] == z)
2134 {
2135 zE = zX;
2136 break;
2137 }
2138 }
2139 zS = pP->streamsFromEncodes[zE];
2141 if (pAstCfg->xOut[z].hTxSio)
2142 {
2143 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2144 errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2145 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2146 if (errno)
2147 {
2148 SIO_idle(pAstCfg->xOut[z].hTxSio);
2149 if (errno == 0x105) // 0x105 == RINGIO_EBUFFULL
2150 {
2151 // statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2152 TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2153 }
2154 if (errno > 0)
2155 {
2156 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2157 return (ASPERR_ISSUE + (z << 4));
2158 }
2159 else if (errno < 0)
2160 {
2161 TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2162 return -errno; // SIO negates error codes
2163 }
2164 }
2165 if (errno > 0)
2166 {
2167 return (ASPERR_ISSUE + (z << 4));
2168 }
2169 else if (errno < 0)
2170 {
2171 return -errno; // SIO negates error codes
2172 }
2173 }
2174 else
2175 {
2176 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2177 }
2178 }
2180 return 0;
2181 } //PAF_ASOT_decodeEncode
2183 // -----------------------------------------------------------------------------
2184 // ASOT Decoding Function - Stream-Final Processing
2185 //
2186 // Name: PAF_ASOT_decodeComplete
2187 // Purpose: Decoding Function for terminating the decoding process.
2188 // From: AST Parameter Function -> decodeProcessing
2189 // Uses: See code.
2190 // States: x
2191 // Return: 0.
2192 // Trace: Message Log "trace" in Debug Project Configuration reports:
2193 // * State information as per parent.
2194 //
2195 Int
2196 PAF_ASOT_decodeComplete(
2197 const PAF_ASOT_Params *pP,
2198 const PAF_ASOT_Patchs *pQ,
2199 PAF_ASOT_Config *pC,
2200 ALG_Handle decAlg[],
2201 Int frame,
2202 Int block
2203 )
2204 {
2205 PAF_AST_Config *pAstCfg;
2206 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
2207 Int as; /* Audio Stream Number (1, 2, etc.) */
2208 Int z; /* decode/encode counter */
2209 Int errno; /* error number */
2212 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2213 as = pAstCfg->as;
2214 (void)as; // clear compiler warning in case not used with tracing disabled
2216 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2218 for (z=DECODE1; z < DECODEN; z++)
2219 {
2220 // Stop decoder output circular buffer reads
2221 errno = cbReadStop(pCbCtl, z);
2222 if (errno)
2223 {
2224 TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2225 SW_BREAKPOINT; // FL: debug
2226 return errno;
2227 }
2228 // FL: debug
2229 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2230 }
2232 pP->fxns->streamChainFunction(pP, pQ, pC, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2234 for (z=ENCODE1; z < ENCODEN; z++)
2235 {
2236 Int zO = pP->outputsFromEncodes[z];
2237 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
2238 {
2239 Int select = pAstCfg->xEnc[z].encodeStatus.select;
2240 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2241 #ifdef PAF_ASP_FINAL
2242 ENC_Handle enc = (ENC_Handle)encAlg;
2243 #endif /* PAF_ASP_FINAL */
2244 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2245 #ifdef PAF_ASP_FINAL
2246 if (enc->fxns->final)
2247 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2248 &pAstCfg->xEnc[z].encodeStatus);
2249 #endif /* PAF_ASP_FINAL */
2250 if (encAlg->fxns->algDeactivate)
2251 {
2252 encAlg->fxns->algDeactivate(encAlg);
2253 }
2254 }
2255 else
2256 {
2257 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2258 }
2259 }
2261 // wait for remaining data to be output
2262 pP->fxns->stopOutput(pP, pQ, pC);
2264 return 0;
2265 } //PAF_ASOT_decodeComplete
2267 // -----------------------------------------------------------------------------
2268 // ASOT Decoding Function Helper - SIO Driver Start
2269 //
2270 // Name: PAF_ASOT_startOutput
2271 // Purpose: Decoding Function for initiating output.
2272 // From: AST Parameter Function -> decodeInfo1
2273 // Uses: See code.
2274 // States: x
2275 // Return: Error number in standard or SIO form (0 on success).
2276 // Trace: Message Log "trace" in Debug Project Configuration reports:
2277 // * State information as per parent.
2278 // * SIO control errors.
2279 //
2280 #define DEC_OUTNUMBUF_MAP(X) \
2281 pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2283 Int
2284 PAF_ASOT_startOutput(
2285 const PAF_ASOT_Params *pP,
2286 const PAF_ASOT_Patchs *pQ,
2287 PAF_ASOT_Config *pC
2288 )
2289 {
2290 PAF_AST_Config *pAstCfg;
2291 Int as; /* Audio Stream Number (1, 2, etc.) */
2292 Int z; /* output counter */
2293 Int errno,nbufs; /* error number */
2294 Int zE, zS, zX;
2295 Int zMD;
2296 PAF_SIO_IALG_Obj *pObj;
2297 PAF_SIO_IALG_Config *pAlgConfig;
2300 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2301 as = pAstCfg->as;
2302 zMD = pAstCfg->masterDec;
2304 for (z=OUTPUT1; z < OUTPUTN; z++)
2305 {
2306 if (pAstCfg->xOut[z].hTxSio)
2307 {
2308 // determine associated encoder and stream
2309 zE = z;
2310 zS = z;
2311 for (zX = ENCODE1; zX < ENCODEN; zX++)
2312 {
2313 if (pP->outputsFromEncodes[zX] == z)
2314 {
2315 zE = zX;
2316 zS = pP->streamsFromEncodes[zE];
2317 break;
2318 }
2319 }
2321 // Set sample count so that DOB knows how much data to send
2322 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2323 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2325 if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED)
2326 {
2327 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2328 pAlgConfig = &pObj->config;
2329 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA,
2330 pAlgConfig->pMemRec[0].size);
2331 }
2333 // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2334 // decoder. How should we handle the sourceProgram for multiple decoders?
2335 // Override as needed
2336 nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2337 if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2338 {
2339 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2340 }
2341 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2343 if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2344 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0))
2345 {
2346 SIO_idle(pAstCfg->xOut[z].hTxSio);
2347 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2348 return errno;
2349 }
2351 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2352 (errno = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
2353 {
2354 errno = (errno & 0xff) | ASPERR_MUTE;
2355 /* convert to sensical errno */
2356 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2357 return (errno);
2358 }
2359 else
2360 {
2361 pAstCfg->xOut[z].outBufStatus.audio
2362 = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;
2363 }
2365 TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2366 }
2367 }
2369 return 0;
2370 } //PAF_ASOT_startOutput
2372 // -----------------------------------------------------------------------------
2373 // ASOT Decoding Function Helper - SIO Driver Stop
2374 //
2375 // Name: PAF_ASOT_stopOutput
2376 // Purpose: Decoding Function for terminating output.
2377 // From: AST Parameter Function -> decodeProcessing
2378 // AST Parameter Function -> decodeComplete
2379 // Uses: See code.
2380 // States: x
2381 // Return: Error number in standard or SIO form (0 on success).
2382 // Trace: Message Log "trace" in Debug Project Configuration reports:
2383 // * SIO control errors.
2384 //
2385 Int
2386 PAF_ASOT_stopOutput(
2387 const PAF_ASOT_Params *pP,
2388 const PAF_ASOT_Patchs *pQ,
2389 PAF_ASOT_Config *pC
2390 )
2391 {
2392 PAF_AST_Config *pAstCfg;
2393 Int as; /* Audio Stream Number (1, 2, etc.) */
2394 Int z; /* output counter */
2395 Int errno = 0, getVal;
2396 Int zS, zX;
2397 PAF_SIO_IALG_Obj *pObj;
2398 PAF_SIO_IALG_Config *pAlgConfig;
2400 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2401 as = pAstCfg->as;
2402 (void)as; // clear compiler warning in case not used with tracing disabled
2404 for (z=OUTPUT1; z < OUTPUTN; z++)
2405 {
2406 if (pAstCfg->xOut[z].hTxSio)
2407 {
2408 // determine associated encoder and stream
2409 zS = z;
2410 (void)zS;
2411 for (zX = ENCODE1; zX < ENCODEN; zX++)
2412 {
2413 if (pP->outputsFromEncodes[zX] == z)
2414 {
2415 zS = pP->streamsFromEncodes[zX];
2416 break;
2417 }
2418 }
2420 // Mute output before audio data termination in the usual case,
2421 // where such termination is due to decode error or user command.
2422 // Identification of this as the usual case is provided by the
2423 // "decode processing" state machine.
2424 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2425 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2426 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2427 {
2428 if (!errno)
2429 {
2430 errno = (getVal & 0xff) | ASPERR_MUTE;
2431 /* convert to sensical errno */
2432 }
2433 TRACE_VERBOSE1("PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2434 }
2436 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2438 // Terminate audio data output, truncating (ignore) or flushing
2439 // (play out) final samples as per (1) control register set by
2440 // the user and (2) the type of audio data termination:
2442 #if 0
2443 // This form is not used because driver support for truncating
2444 // data is not supported for internal clocks, although it is
2445 // for external clocks.
2446 getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2447 pC->xOut[z].outBufStatus.flush
2448 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2449 ? 1 : 0);
2450 /* UNTESTED */
2451 #else
2452 // This form should be used when driver support for truncating
2453 // data is supported for both internal and external clocks.
2454 getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2455 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2456 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2457 ? 1 : 0);
2458 /* TESTED */
2459 #endif
2461 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2463 if (!errno)
2464 {
2465 errno = getVal;
2466 }
2468 // Mute output after audio data termination in a special case,
2469 // where such termination is due to processing of a final frame
2470 // or user command. Identification of this as a special case is
2471 // provided by the "decode processing" state machine.
2472 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2473 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2474 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2475 {
2476 if (!errno)
2477 {
2478 errno = (getVal & 0xff) | ASPERR_MUTE;
2479 /* convert to sensical errno */
2480 }
2481 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2482 }
2484 pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2486 // zero output buffers
2487 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2488 pAlgConfig = &pObj->config;
2489 memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2490 } //pAstCfg->xOut[z].hTxSio
2491 }//OUTPUT
2493 return errno;
2494 } //PAF_ASOT_stopOutput
2496 // -----------------------------------------------------------------------------
2497 // ASOT Decoding Function Helper - SIO Driver Change
2498 //
2499 // Name: PAF_ASOT_setCheckRateX
2500 // Purpose: Decoding Function for reinitiating output.
2501 // From: AST Parameter Function -> decodeInfo1
2502 // AST Parameter Function -> decodeInfo2
2503 // Uses: See code.
2504 // States: x
2505 // Return: Error number in standard form (0 on success).
2506 // Trace: None.
2507 //
2509 /* 0: set, 1: check, unused for now. --Kurt */
2510 Int
2511 PAF_ASOT_setCheckRateX(
2512 const PAF_ASOT_Params *pP,
2513 const PAF_ASOT_Patchs *pQ,
2514 PAF_ASOT_Config *pC,
2515 Int check
2516 )
2517 {
2518 PAF_AST_Config *pAstCfg;
2519 float rateX;
2520 PAF_SampleRateHz rateO /* std */, rateI /* inv */;
2521 Int z; /* output counter */
2522 Int zx; /* output re-counter */
2523 Int getVal;
2524 int inputRate, inputCount, outputRate, outputCount;
2525 Int zMD;
2526 Int zMI;
2527 Int zMS;
2528 Int zE, zX;
2530 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2531 zMD = pAstCfg->masterDec;
2532 zMS = pAstCfg->masterStr;
2533 zMI = pP->zone.master;
2535 inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
2536 inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
2537 rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2538 (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
2540 for (z=OUTPUT1; z < OUTPUTN; z++) {
2541 if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) {
2543 // determine associated encoder
2544 zE = z;
2545 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2546 if (pP->outputsFromEncodes[zX] == z) {
2547 zE = zX;
2548 break;
2549 }
2550 }
2552 outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
2553 outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
2554 rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2555 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
2556 if (rateI > 0 && rateO > 0)
2557 rateX = rateO /* std */ * rateI /* inv */;
2558 else if (inputCount != 0)
2559 rateX = (float )outputCount / inputCount;
2560 else
2561 return ( ASPERR_INFO_RATERATIO );
2563 getVal = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg) &rateX);
2564 if (getVal == DOBERR_RATECHANGE) {
2565 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
2566 if (pAstCfg->xOut[zx].hTxSio)
2567 SIO_idle (pAstCfg->xOut[zx].hTxSio);
2569 // this forces an exit from the calling state machine which will
2570 // eventually call startOutput which calls setCheckRateX for all outputs
2571 // and so it is ok, in the presence of a rate change on any output, to
2572 // exit this loop /function early.
2573 return ASPERR_INFO_RATECHANGE;
2574 }
2575 else if( getVal != SYS_OK )
2576 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
2577 }
2578 }
2580 return 0;
2581 } //PAF_ASOT_setCheckRateX
2583 // -----------------------------------------------------------------------------
2584 // ASOT Decoding Function Helper - Chain Processing
2585 //
2586 // Name: PAF_ASOT_streamChainFunction
2587 // Purpose: Common Function for processing algorithm chains.
2588 // From: AST Parameter Function -> decodeInfo1
2589 // AST Parameter Function -> decodeStream
2590 // AST Parameter Function -> decodeComplete
2591 // Uses: See code.
2592 // States: x
2593 // Return: Error number in standard form (0 on success).
2594 // Trace: Message Log "trace" in Debug Project Configuration reports:
2595 // * State information as per parent.
2596 //
2597 Int
2598 PAF_ASOT_streamChainFunction(
2599 const PAF_ASOT_Params *pP,
2600 const PAF_ASOT_Patchs *pQ,
2601 PAF_ASOT_Config *pC,
2602 Int iChainFrameFxns,
2603 Int abortOnError,
2604 Int logArg
2605 )
2606 {
2607 PAF_AST_Config *pAstCfg;
2608 Int as; /* Audio Stream Number (1, 2, etc.) */
2609 Int z; /* stream counter */
2610 Int errno; /* error number */
2611 Int dFlag, eFlag, gear;
2612 Int zX;
2613 Int zS;
2615 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2616 as = pAstCfg->as;
2617 (void)as; // clear compiler warning in case not used with tracing disabled
2619 for (zS = STREAM1; zS < STREAMN; zS++)
2620 {
2621 z = pP->streamOrder[zS]; // Select stream order from streamOrder parameter - MID 788
2623 // apply stream
2624 // unless the stream is associated with a decoder and it is not running
2625 // or
2626 // unless the stream is associated with an encoder and it is not running
2627 // Also gear control only works for streams with an associated decoder
2628 // if no such association exists then gear 0 (All) is used
2629 dFlag = 1;
2630 gear = 0;
2631 for (zX = DECODE1; zX < DECODEN; zX++) {
2632 if (pP->streamsFromDecodes[zX] == z) {
2633 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
2634 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
2635 break;
2636 }
2637 }
2638 eFlag = 1;
2639 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2640 if (pP->streamsFromEncodes[zX] == z) {
2641 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
2642 break;
2643 }
2644 }
2646 if (dFlag && eFlag) {
2647 PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
2648 PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
2649 Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
2650 chain->fxns->chainFrameFunction[iChainFrameFxns];
2652 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2653 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
2654 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2655 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
2656 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2657 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
2658 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
2659 as+z, logArg);
2660 errno = (*func) (chain, frame);
2661 TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
2662 as+z, errno);
2664 if (errno && abortOnError)
2665 return errno;
2666 }
2667 else {
2668 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2669 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
2670 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2671 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
2672 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2673 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
2674 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
2675 as+z, logArg);
2676 }
2678 /*
2679 {
2680 void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
2681 PAF_AudioFrameData *afd;
2682 float ** afPtr;
2684 afd = &(pC->xStr->pAudioFrame->data);
2685 afPtr = (float**)afd->sample;
2686 dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
2688 }
2689 */
2691 }
2693 return 0;
2694 } //PAF_ASOT_streamChainFunction
2696 /* FL: Check if at least one output selected */
2697 static Int checkOutSel(
2698 const PAF_ASOT_Params *pP,
2699 PAF_ASOT_Config *pC,
2700 Int *pOutSel
2701 )
2702 {
2703 PAF_AST_Config *pAstCfg;
2704 Int outSel;
2705 Int z;
2707 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2709 outSel = 0;
2710 for (z=OUTPUT1; z < OUTPUTN; z++)
2711 {
2712 if (pAstCfg->xOut[z].hTxSio)
2713 {
2714 outSel = 1;
2715 break;
2716 }
2717 }
2719 *pOutSel = outSel;
2721 return 0;
2722 }
2724 /* FL: Check if at least one output sio changed */
2725 static Int checkOutSio(
2726 const PAF_ASOT_Params *pP,
2727 PAF_ASOT_Config *pC,
2728 Int *pOutSioUpdate
2729 )
2730 {
2731 PAF_AST_Config *pAstCfg;
2732 Int outSioUpdate;
2733 Int z;
2735 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2737 outSioUpdate = 0;
2738 for (z=OUTPUT1; z < OUTPUTN; z++)
2739 {
2740 if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
2741 {
2742 outSioUpdate = 1;
2743 break;
2744 }
2745 }
2747 *pOutSioUpdate = outSioUpdate;
2749 return 0;
2750 }