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