2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
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 #define TRACE_TIME(a)
65 //
66 // Audio Stream Definitions
67 //
69 //
70 // Audio Stream Processing Definitions
71 //
72 #define aspLinkInit pQ->i_aspLinkInit
74 //
75 // Encoder Definitions
76 //
77 #define encLinkInit pQ->i_encLinkInit
79 //
80 // Output Definitions
81 //
82 #define outLinkInit pP->i_outLinkInit
84 /* ---------------------------------------------------------------- */
85 /* Parameter macro definitions end here. */
86 /* ---------------------------------------------------------------- */
88 //
89 // Standardized Definitions
90 //
92 #define ENC_Handle PCE_Handle /* works for all: PCE */
94 #define __TASK_NAME__ "TaskAsop"
97 /* FL: Check if at least one output selected */
98 static Int checkOutSel(
99 const PAF_ASOT_Params *pP,
100 PAF_ASOT_Config *pC,
101 Int *pOutSel
102 );
104 /* FL: Check if at least one output sio changed */
105 static Int checkOutSio(
106 const PAF_ASOT_Params *pP,
107 PAF_ASOT_Config *pC,
108 Int *pOutSioUpdate
109 );
111 LINNO_DEFN(TaskAsop); /* Line number macros */
112 ERRNO_DEFN(TaskAsop); /* Error number macros */
114 // ASOT configuration
115 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
116 PAF_ASOT_Config gPAF_ASOT_config = {
117 NULL, // acp
118 &gPAF_ASPM_config, // pAspmCfg
119 &gPAF_AST_config // pAstCfg
120 };
122 // Underflow threshold before returning error to Top-Level FSM
123 #define DEC_OP_CB_RDAF_UND_THR ( 20 ) // FL: arbitrary setting
124 UInt32 gDecOpCbRdAfUnd =0; // decoder output circular buffer underflow count
126 // Global debug counters */
127 UInt32 gTaskAsopCnt=0; // debug
128 UInt32 gAsopInitCnt =0;
129 UInt32 gAsopStreamCnt =0;
130 UInt32 gAsopEncodeCnt =0;
131 UInt32 gAsopFinalCnt =0;
132 UInt32 gAsopQuitCnt =0;
135 /*
136 * ======== taskAsopFxn ========
137 * Audio Stream Output Processing task function
138 */
139 Void taskAsopFxn(
140 // Int betaPrimeValue, // FL: revisit
141 const PAF_ASOT_Params *pP,
142 const PAF_ASOT_Patchs *pQ
143 )
144 {
145 PAF_ASOT_Config *pC; /* Local configuration pointer */
146 PAF_AST_Config *pAstCfg; /* Common (shared) configuration pointer */
147 Int as; /* Audio Stream Number (1, 2, etc.) */
148 Int z; /* input/encode/stream/decode/output counter */
149 Int i; /* phase */
150 Int errno; /* error number */
151 Int zMS;
152 Int loopCount = 0; // used to stop trace to see startup behavior.
154 Log_info0("Enter taskAsopFxn()");
156 //
157 // Audio Framework Parameters & Patch (*pP, *pQ)
158 //
159 if (!pP)
160 {
161 TRACE_TERSE0("TaskAsop: No Parameters defined. Exiting.");
162 LINNO_RPRT(TaskAsop, -1);
163 return;
164 }
166 if (!pQ)
167 {
168 TRACE_TERSE0("TaskAsip: No Patchs defined. Exiting.");
169 LINNO_RPRT(TaskAsop, -1);
170 return;
171 }
173 //
174 // Audio Framework Configuration (*pC):
175 //
176 pC = &gPAF_ASOT_config;
177 pAstCfg = pC->pAstCfg;
179 /* Obtain Audio Stream Number (1, 2, etc.) */
180 as = pAstCfg->as;
181 TRACE_TERSE1("TaskAsop: Started with AS%d.", as);
183 //
184 // Initialize message log trace and line number reporting
185 //
186 for (z=STREAM1; z < STREAMN; z++)
187 {
188 TRACE_TERSE1("TaskAsop: AS%d: initiated", as+z);
189 }
190 LINNO_RPRT(TaskAsop, -1);
192 //
193 // Determine stream index
194 //
195 zMS = pAstCfg->masterStr;
197 // Initialize as per parametrized phases:
198 //
199 // In standard form these are:
200 // - Malloc: Memory Allocation
201 // - Config: Configuration Initialization
202 // - AcpAlg: ACP Algorithm Initialization and Local Attachment
203 // - Common: Common Memory Initialization
204 // - AlgKey: Dec/Enc chain to Array Initialization
205 // - Device: I/O Device Initialization
206 // - Unused: (available)
207 // - Unused: (available)
208 //
209 LINNO_RPRT(TaskAsop, -2);
210 for (i=0; i < lengthof(pP->fxns->initPhase); i++)
211 {
212 Int linno;
213 if (pP->fxns->initPhase[i])
214 {
215 if (linno = pP->fxns->initPhase[i](pP, pQ, pC))
216 {
217 LINNO_RPRT(TaskAsop, linno);
218 return;
219 }
220 }
221 else
222 {
223 TRACE_TERSE1("TaskAsop: AS%d: initialization phase - null", as+zMS);
224 }
225 TRACE_TERSE2("TaskAsop: AS%d: initialization phase - %d completed", as+zMS, i);
226 LINNO_RPRT(TaskAsop, -i-3);
227 }
229 //
230 // End of Initialization -- display memory usage report.
231 //
232 if (pP->fxns->memStatusPrint)
233 {
234 pP->fxns->memStatusPrint(HEAP_INTERNAL, HEAP_INTERNAL1, HEAP_EXTERNAL, HEAP_INTERNAL1_SHM);
235 }
237 //
238 // Main processing loop
239 //
240 for (z=STREAM1; z < STREAMN; z++)
241 {
242 TRACE_VERBOSE1("TaskAsip: AS%d: running", as+z);
243 }
245 errno = 0;
246 for (;;)
247 {
248 Int outSel;
250 loopCount++;
251 TRACE_GEN2("TaskAsop (begin Main loop %d) (errno 0x%x)", loopCount, errno);
253 // any error forces idling of output
254 if (errno)
255 {
256 for (z=OUTPUT1; z < OUTPUTN; z++)
257 {
258 if (pAstCfg->xOut[z].hTxSio)
259 {
260 SIO_idle(pAstCfg->xOut[z].hTxSio);
261 }
262 }
264 TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", loopCount);
265 ERRNO_RPRT(TaskAsop, errno);
266 }
268 TRACE_VERBOSE1("TaskAsop: AS%d: ... sleeping ...", as+zMS);
269 Task_sleep(1);
271 TRACE_GEN1("TaskAsop: AS%d: Output device selection ...", as+zMS);
272 if (errno = pP->fxns->selectDevices(pP, pQ, pC))
273 {
274 TRACE_TERSE2("TaskAsop: AS%d: selectDevices returned errno = 0x%04x", as+zMS, errno);
275 continue;
276 }
278 // if no output selected skip any remaining processing
279 if (errno = checkOutSel(pP, pC, &outSel))
280 {
281 TRACE_TERSE2("TaskAsop: AS%d: checkOutSel returned errno = 0x%04x", as+zMS, errno);
282 continue;
283 }
284 else if (!outSel)
285 {
286 TRACE_VERBOSE1("TaskAsop: AS%d: No output selected...", as+zMS);
287 continue;
288 }
290 TRACE_VERBOSE0("TaskAsop: calling outputProcessing.");
291 errno = pP->fxns->decodeProcessing(pP, pQ, pC, -1);
292 if (errno)
293 {
294 TRACE_TERSE1("TaskAsop: outputProcessing returns 0x%x, continue", errno);
295 }
296 else
297 {
298 TRACE_VERBOSE0("TaskAsop: outputProcessing complete with no error.");
299 }
300 } // End of main processing loop for (;;)
302 Log_info0("Exit taskAsopFxn()");
303 }
305 // -----------------------------------------------------------------------------
306 // AST Initialization Function - Memory Allocation
307 //
308 // Name: PAF_ASOT_initPhaseMalloc
309 // Purpose: Audio Stream Output Task Function for initialization of data pointers
310 // by allocation of memory.
311 // From: audioStream1Task or equivalent
312 // Uses: See code.
313 // States: x
314 // Return: 0 on success.
315 // Source code line number on MEM_calloc failure.
316 // Trace: Message Log "trace" in Debug Project Configuration reports:
317 // * State information as per parent.
318 // * Memory allocation errors.
319 //
321 Int
322 PAF_ASOT_initPhaseMalloc (
323 const PAF_ASOT_Params *pP,
324 const PAF_ASOT_Patchs *pQ,
325 PAF_ASOT_Config *pC
326 )
327 {
328 PAF_AST_Config *pAstCfg;
329 Int as; /* Audio Stream Number (1, 2, etc.) */
330 Int zMS;
331 Error_Block eb;
332 //Int i;
334 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
335 as = pAstCfg->as;
336 zMS = pAstCfg->masterStr;
338 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation", as+zMS);
340 // Initialize error block
341 Error_init(&eb);
343 /* Stream memory */
344 if (!(pAstCfg->xStr = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMN * sizeof (*pAstCfg->xStr), 4, &eb)))
345 {
346 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
347 SW_BREAKPOINT;
348 return __LINE__;
349 }
350 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xStr) %d bytes from space %d at 0x%x.",
351 STREAMN * sizeof (*pAstCfg->xStr),
352 HEAP_ID_INTERNAL, (IArg)pAstCfg->xStr);
354 {
355 Int z; /* stream counter */
357 PAF_AudioFrame *fBuf;
359 if (!(fBuf = (PAF_AudioFrame *)Memory_calloc((IHeap_Handle)HEAP_INTERNAL, STREAMS * sizeof (*fBuf), 4, &eb)))
360 {
361 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
362 SW_BREAKPOINT;
363 return __LINE__;
364 }
365 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (fBuf) %d bytes from space %d at 0x%x.",
366 STREAMS * sizeof (*fBuf),
367 HEAP_ID_INTERNAL, (IArg)fBuf);
369 for (z=STREAM1; z < STREAMN; z++)
370 {
371 pAstCfg->xStr[z].pAudioFrame = &fBuf[z-STREAM1];
372 TRACE_TERSE2("pAstCfg->xStr[%d].pAudioFrame = 0x%x", z, (IArg)pAstCfg->xStr[z].pAudioFrame);
373 }
374 }
376 /* Encode memory */
377 if (!(pAstCfg->xEnc = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, ENCODEN * sizeof (*pAstCfg->xEnc), 4, &eb)))
378 {
379 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: Memory_calloc failed", as+zMS);
380 SW_BREAKPOINT;
381 return __LINE__;
382 }
383 TRACE_TERSE3("PAF_ASOT_initPhaseMalloc. (pAstCfg->xEnc) %d bytes from space %d at 0x%x.",
384 ENCODEN * sizeof (*pAstCfg->xEnc),
385 HEAP_ID_INTERNAL, (IArg)pAstCfg->xEnc);
387 /* Output memory */
388 if (!(pAstCfg->xOut = Memory_calloc((IHeap_Handle)HEAP_INTERNAL, OUTPUTN * sizeof (*pAstCfg->xOut), 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->xOut) %d bytes from space %d at 0x%x.",
395 OUTPUTN * sizeof (*pAstCfg->xOut),
396 HEAP_ID_INTERNAL, (IArg)pAstCfg->xOut);
398 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: initialization phase - memory allocation complete.", as+zMS);
399 return 0;
400 } //PAF_ASOT_initPhaseMalloc
402 // -----------------------------------------------------------------------------
403 // ASOT Initialization Function - Memory Initialization from Configuration
404 //
405 // Name: PAF_ASOT_initPhaseConfig
406 // Purpose: Audio Stream Output Task Function for initialization of data values
407 // from parameters.
408 // From: audioStream1Task or equivalent
409 // Uses: See code.
410 // States: x
411 // Return: 0 on success.
412 // Other as per initFrame0 and initFrame1.
413 // Trace: Message Log "trace" in Debug Project Configuration reports:
414 // * State information as per parent.
415 //
416 Int
417 PAF_ASOT_initPhaseConfig(
418 const PAF_ASOT_Params *pP,
419 const PAF_ASOT_Patchs *pQ,
420 PAF_ASOT_Config *pC
421 )
422 {
423 PAF_AST_Config *pAstCfg;
424 Int as; /* Audio Stream Number (1, 2, etc.) */
425 Int z; /* input/encode/stream/decode/output counter */
426 Int zMS;
428 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
429 as = pAstCfg->as;
430 zMS = pAstCfg->masterStr;
432 TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration", as+zMS);
434 //
435 // Unspecified elements have been initialized to zero during alloc
436 //
438 for (z=STREAM1; z < STREAMN; z++)
439 {
440 Int linno;
441 if (linno = pP->fxns->initFrame0(pP, pQ, pC, z))
442 {
443 return linno;
444 }
445 if (linno = pP->fxns->initFrame1(pP, pQ, pC, z, -1))
446 {
447 return linno;
448 }
449 }
451 for (z=ENCODE1; z < ENCODEN; z++)
452 {
453 Int zO = pP->outputsFromEncodes[z];
454 Int zS = pP->streamsFromEncodes[z];
455 pAstCfg->xEnc[z].encodeControl.size = sizeof(pAstCfg->xEnc[z].encodeControl);
456 pAstCfg->xEnc[z].encodeControl.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
457 pAstCfg->xEnc[z].encodeControl.pVolumeStatus = &pAstCfg->xEnc[z].volumeStatus;
458 pAstCfg->xEnc[z].encodeControl.pOutBufConfig = &pAstCfg->xOut[zO].outBufConfig;
459 pAstCfg->xEnc[z].encodeStatus = *pP->z_pEncodeStatus[z];
460 pAstCfg->xEnc[z].encodeControl.encActive = pAstCfg->xEnc[z].encodeStatus.select;
461 pAstCfg->xEnc[z].volumeStatus = *pP->pVolumeStatus;
462 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame = pAstCfg->xStr[zS].pAudioFrame;
463 }
465 for (z=OUTPUT1; z < OUTPUTN; z++)
466 {
467 pAstCfg->xOut[z].outBufStatus = *pP->pOutBufStatus;
468 }
470 TRACE_TERSE1("PAF_ASOT_initPhaseConfig: AS%d: initialization phase - configuration complete.", as+zMS);
471 return 0;
472 } //PAF_ASOT_initPhaseConfig
474 // -----------------------------------------------------------------------------
475 // ASOT Initialization Function - ACP Algorithm Instantiation
476 //
477 // Name: PAF_ASOT_initPhaseAcpAlg
478 // Purpose: Audio Stream Input Task Function for initialization of ACP by
479 // instantiation of the algorithm.
480 // From: audioStream1Task or equivalent
481 // Uses: See code.
482 // States: x
483 // Return: 0 on success.
484 // Source code line number on ACP Algorithm creation failure.
485 // Trace: Message Log "trace" in Debug Project Configuration reports:
486 // * State information as per parent.
487 // * Memory allocation errors.
488 //
489 Int
490 PAF_ASOT_initPhaseAcpAlg(
491 const PAF_ASOT_Params *pP,
492 const PAF_ASOT_Patchs *pQ,
493 PAF_ASOT_Config *pC
494 )
495 {
496 PAF_AST_Config *pAstCfg;
497 Int as; /* Audio Stream Number (1, 2, etc.) */
498 Int z; /* input/encode/stream/decode/output counter */
499 Int betaPrimeOffset;
500 ACP_Handle acp;
501 Int zMS;
502 Int zS, zX;
504 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
505 as = pAstCfg->as;
506 zMS = pAstCfg->masterStr;
508 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm", as+zMS);
510 ACP_MDS_init();
512 if (!(acp = (ACP_Handle )ACP_MDS_create(NULL)))
513 {
514 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: ACP algorithm instance creation failed", as+zMS);
515 return __LINE__;
516 }
517 pC->acp = acp;
519 ((ALG_Handle)acp)->fxns->algControl((ALG_Handle) acp,
520 ACP_GETBETAPRIMEOFFSET, (IALG_Status *)&betaPrimeOffset);
522 for (z=ENCODE1; z < ENCODEN; z++)
523 {
524 zS = pP->streamsFromEncodes[z];
525 acp->fxns->attach(acp, ACP_SERIES_STD,
526 STD_BETA_ENCODE + betaPrimeOffset * (as-1+zS),
527 (IALG_Status *)&pAstCfg->xEnc[z].encodeStatus);
528 acp->fxns->attach(acp, ACP_SERIES_STD,
529 STD_BETA_VOLUME + betaPrimeOffset * (as-1+zS),
530 (IALG_Status *)&pAstCfg->xEnc[z].volumeStatus);
531 /* Ignore errors, not reported. */
532 }
534 for (z=OUTPUT1; z < OUTPUTN; z++)
535 {
536 zS = z;
537 for (zX = ENCODE1; zX < ENCODEN; zX++)
538 {
539 if (pP->outputsFromEncodes[zX] == z)
540 {
541 zS = pP->streamsFromEncodes[zX];
542 break;
543 }
544 }
545 acp->fxns->attach(acp, ACP_SERIES_STD,
546 STD_BETA_OB + betaPrimeOffset * (as-1+zS),
547 (IALG_Status *)&pAstCfg->xOut[z].outBufStatus);
548 /* Ignore errors, not reported. */
549 }
551 TRACE_TERSE1("PAF_ASOT_initPhaseAcpAlg: AS%d: initialization phase - ACP Algorithm complete.", as+zMS);
553 return 0;
554 } //PAF_ASOT_initPhaseAcpAlg
556 // -----------------------------------------------------------------------------
557 // ASOT Initialization Function - Common Memory
558 //
559 // Name: PAF_ASOT_initPhaseCommon
560 // Purpose: Audio Stream Output Task Function for allocation of common memory.
561 // From: audioStream1Task or equivalent
562 // Uses: See code.
563 // States: x
564 // Return: 0 on success.
565 // Source code line number on PAF_ALG_alloc failure.
566 // Source code line number on PAF_ALG_mallocMemory failure.
567 // Source code line number on Decode Chain initialization failure.
568 // Source code line number on ASP Chain initialization failure.
569 // Source code line number on Encode Chain initialization failure.
570 // Trace: Message Log "trace" in Debug Project Configuration reports:
571 // * State information as per parent.
572 // * Memory allocation errors.
573 //
574 Int
575 PAF_ASOT_initPhaseCommon(
576 const PAF_ASOT_Params *pP,
577 const PAF_ASOT_Patchs *pQ,
578 PAF_ASOT_Config *pC
579 )
580 {
581 PAF_AST_Config *pAstCfg;
582 Int as; /* Audio Stream Number (1, 2, etc.) */
583 Int z; /* stream counter */
584 Int g; /* gear */
585 ACP_Handle acp;
586 PAF_IALG_Config pafAlgConfig;
587 IALG_MemRec common[3][PAF_IALG_COMMON_MEMN+1];
589 acp = pC->acp;
590 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
591 as = pAstCfg->as;
593 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: initialization phase - Common Memory");
595 //
596 // Determine memory needs and instantiate algorithms across audio streams
597 //
598 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_setup.");
599 PAF_ALG_setup(&pafAlgConfig,
600 HEAP_ID_INTERNAL, HEAP_INTERNAL,
601 HEAP_ID_INTERNAL1, HEAP_INTERNAL1,
602 HEAP_ID_EXTERNAL, HEAP_EXTERNAL,
603 HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM,
604 HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM,
605 HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
606 HEAP_CLEAR);
608 if (pP->fxns->headerPrint)
609 {
610 pP->fxns->headerPrint();
611 }
613 for (z = STREAM1; z < STREAMN; z++)
614 {
615 //Int zD, zE, zX;
616 Int zE, zX;
618 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
620 //
621 // Determine common memory needs for:
622 // (1) ASP Algorithms
623 // (2) Encode Algorithms
624 // (3) Logical Output drivers
625 //
626 PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
628 zE = -1;
629 for (zX = ENCODE1; zX < ENCODEN; zX++)
630 {
631 if (pP->streamsFromEncodes[zX] == z)
632 {
633 zE = zX;
634 break;
635 }
636 }
638 TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
639 if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z]))
640 {
641 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
642 TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
643 SW_BREAKPOINT;
644 return __LINE__;
645 }
646 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
647 if (pP->fxns->allocPrint)
648 {
649 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
650 }
652 if (zE >= 0)
653 {
654 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
655 if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z]))
656 {
657 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
658 SW_BREAKPOINT;
659 return __LINE__;
660 }
661 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
662 if (pP->fxns->allocPrint)
663 {
664 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
665 }
666 }
668 //
669 // Determine common memory needs of Logical IO drivers
670 //
672 if (OUTPUT1 <= z && z < OUTPUTN)
673 {
674 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
675 if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
676 {
677 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
678 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
679 SW_BREAKPOINT;
680 return __LINE__;
681 }
682 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
683 if (pP->fxns->allocPrint)
684 {
685 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
686 }
687 }
688 }
689 {
690 // Changes made to share scratch between zones
691 // Assume maximum 3 zones and scratch common memory is at offset 0;
692 int max=0;
693 for (z=STREAM1; z<STREAMN; z++)
694 {
695 if (max < common[z][0].size)
696 {
697 max = common[z][0].size;
698 }
699 }
700 common[STREAM1][0].size=max;
701 for (z=STREAM1+1; z<STREAMN; z++)
702 {
703 common[z][0].size = 0;
704 }
705 }
707 //
708 // Allocate common memory for:
709 // (1) ASP Algorithms
710 // (2) Encode Algorithms
711 // (3) Logical Output drivers
712 //
713 for (z = STREAM1; z < STREAMN; z++)
714 {
715 //Int zD, zE, zX;
716 Int zE, zX;
718 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
719 if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig))
720 {
721 TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
722 TRACE_TERSE3("AS%d: z: %d. Size 0x%x", as+z, z, common[z][0].size);
723 SW_BREAKPOINT;
724 return __LINE__;
725 }
726 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
727 // share zone0 scratch with all zones
728 common[z][0].base = common[0][0].base;
729 if (pP->fxns->commonPrint)
730 {
731 pP->fxns->commonPrint(common[z], &pafAlgConfig);
732 }
734 zE = -1;
735 for (zX = ENCODE1; zX < ENCODEN; zX++)
736 {
737 if (pP->streamsFromEncodes[zX] == z)
738 {
739 zE = zX;
740 break;
741 }
742 }
744 pAstCfg->xStr[z].aspChain[0] = NULL;
745 for (g=0; g < GEARS; g++)
746 {
747 PAF_ASP_Chain *chain;
748 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
749 chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
750 HEAP_INTERNAL, as+z, acp, &trace,
751 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
752 if (!chain)
753 {
754 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
755 return __LINE__;
756 }
757 else
758 {
759 pAstCfg->xStr[z].aspChain[g] = chain;
760 }
761 }
763 if (zE >= 0)
764 {
765 PAF_ASP_Chain *chain;
766 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
767 chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
768 HEAP_INTERNAL, as+z, acp, &trace,
769 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
770 if (!chain)
771 {
772 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
773 return __LINE__;
774 }
775 }
777 //
778 // Allocate non-common memories for Logical IO drivers
779 // Since these structures are used at run-time we allocate from external memory
780 if (OUTPUT1 <= z && z < OUTPUTN)
781 {
782 PAF_ASP_Chain *chain;
783 TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
784 as+z, z);
785 chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
786 HEAP_EXTERNAL, as+z, acp, &trace,
787 outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
788 if (!chain)
789 {
790 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
791 return __LINE__;
792 }
793 }
794 }
795 TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
797 return 0;
798 } //PAF_ASOT_initPhaseCommon
800 // -----------------------------------------------------------------------------
801 // ASOT Initialization Function - Algorithm Keys
802 //
803 // Name: PAF_ASOT_initPhaseAlgKey
804 // Purpose: Audio Stream Output Task Function for initialization of data values
805 // from parameters for Algorithm Keys.
806 // From: audioStream1Task or equivalent
807 // Uses: See code.
808 // States: x
809 // Return: 0.
810 // Trace: Message Log "trace" in Debug Project Configuration reports:
811 // * State information as per parent.
812 //
813 // .............................................................................
814 Int
815 PAF_ASOT_initPhaseAlgKey(
816 const PAF_ASOT_Params *pP,
817 const PAF_ASOT_Patchs *pQ,
818 PAF_ASOT_Config *pC
819 )
820 {
821 PAF_AST_Config *pAstCfg;
822 Int as; /* Audio Stream Number (1, 2, etc.) */
823 Int z; /* decode/encode counter */
824 Int s; /* key number */
825 PAF_ASP_Link *that;
827 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
828 as = pAstCfg->as;
829 (void)as; // clear compiler warning in case not used with tracing disabled
831 TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
833 for (z=ENCODE1; z < ENCODEN; z++)
834 {
835 for (s=0; s < pP->pEncAlgKey->length; s++)
836 {
837 if ((pP->pEncAlgKey->code[s].full != 0) &&
838 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
839 {
840 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
841 }
842 /* Cast in interface, for now --Kurt */
843 else
844 {
845 pAstCfg->xEnc[z].encAlg[s] = NULL;
846 }
847 }
848 }
850 return 0;
851 } //PAF_ASOT_initPhaseAlgKey
853 // -----------------------------------------------------------------------------
854 // ASOT Initialization Function - I/O Devices
855 //
856 // Name: PAF_ASOT_initPhaseDevice
857 // Purpose: Audio Stream Output Task Function for initialization of I/O Devices.
858 // From: audioStream1Task or equivalent
859 // Uses: See code.
860 // States: x
861 // Return: 0 on success.
862 // Source code line number on device allocation failure.
863 // Trace: Message Log "trace" in Debug Project Configuration reports:
864 // * State information as per parent.
865 // * Memory allocation errors.
866 //
867 Int
868 PAF_ASOT_initPhaseDevice(
869 const PAF_ASOT_Params *pP,
870 const PAF_ASOT_Patchs *pQ,
871 PAF_ASOT_Config *pC
872 )
873 {
874 PAF_AST_Config *pAstCfg;
875 Int as; /* Audio Stream Number (1, 2, etc.) */
876 Int z; /* input/output counter */
877 PAF_SIO_IALG_Obj *pObj;
878 PAF_SIO_IALG_Config *pAlgConfig;
879 PAF_IALG_Config pafAlgConfig;
881 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
882 as = pAstCfg->as;
883 (void)as; // clear compiler warning in case not used with tracing disabled
885 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
887 if(pP->fxns->bufMemPrint)
888 {
889 PAF_ALG_setup (&pafAlgConfig,
890 HEAP_ID_INTERNAL, HEAP_INTERNAL,
891 HEAP_ID_INTERNAL1, HEAP_INTERNAL1,
892 HEAP_ID_EXTERNAL, HEAP_EXTERNAL,
893 HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM,
894 HEAP_ID_EXTERNAL_SHM, HEAP_EXTERNAL_SHM,
895 HEAP_ID_EXTERNAL_NONCACHED_SHM, HEAP_EXTERNAL_NONCACHED_SHM,
896 HEAP_CLEAR);
897 TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
898 }
900 for (z=OUTPUT1; z < OUTPUTN; z++)
901 {
902 PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
904 pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
905 pAlgConfig = &pObj->config;
907 pAstCfg->xOut[z].hTxSio = NULL;
908 pConfig->base.pVoid = pAlgConfig->pMemRec[0].base;
909 pConfig->pntr.pVoid = pAlgConfig->pMemRec[0].base;
910 pConfig->head.pVoid = pAlgConfig->pMemRec[0].base;
911 pConfig->allocation = pAlgConfig->pMemRec[0].size;
912 pConfig->sizeofElement = 3;
913 pConfig->precision = 24;
914 if(pP->fxns->bufMemPrint)
915 {
916 pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
917 }
918 }
919 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
921 return 0;
922 } //PAF_ASOT_initPhaseDevice
924 // -----------------------------------------------------------------------------
925 // ASOT Initialization Function Helper - Initialization of Audio Frame
926 //
927 // Name: PAF_ASOT_initFrame0
928 // Purpose: Audio Stream Output Task Function for initialization of the Audio
929 // Frame(s) by memory allocation and loading of data pointers
930 // and values.
931 // From: AST Parameter Function -> decodeInfo
932 // Uses: See code.
933 // States: x
934 // Return: 0 on success.
935 // Source code line number on MEM_calloc failure.
936 // Source code line number on unsupported option.
937 // Trace: Message Log "trace" in Debug Project Configuration reports:
938 // * Memory allocation errors.
939 // * Unsupported option errors.
940 //
942 // MID 314
943 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
944 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
946 Int
947 PAF_ASOT_initFrame0(
948 const PAF_ASOT_Params *pP,
949 const PAF_ASOT_Patchs *pQ,
950 PAF_ASOT_Config *pC,
951 Int z
952 )
953 {
954 PAF_AST_Config *pAstCfg;
955 Int as; /* Audio Stream Number (1, 2, etc.) */
956 Int ch;
957 //Int aLen;
958 Int aLen_int=0,aLen_ext=0;
959 Int aSize = sizeof(PAF_AudioData);
960 Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
961 Int maxFrameLength = pP->maxFramelength;
962 Int zX;
963 PAF_AudioData *aBuf_int=NULL;
964 PAF_AudioData *aBuf_ext=NULL;
965 XDAS_UInt8 *metadataBuf;
966 char i;
967 Error_Block eb;
969 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
970 as = pAstCfg->as;
972 // Initialize error block
973 Error_init(&eb);
975 // Compute maximum framelength (needed for ARC support)
976 maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
977 //aLen = numchan[z] * maxFrameLength;
978 for (i=0; i < numchan[z]; i++)
979 {
980 if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
981 {
982 aLen_int += maxFrameLength;
983 }
984 else
985 {
986 aLen_ext += maxFrameLength;
987 }
988 }
990 //
991 // Initialize audio frame elements directly
992 //
993 pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
994 pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
995 /// pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
996 pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
997 pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
998 pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
999 pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
1001 //
1002 // Allocate memory for and initialize pointers to audio data buffers
1003 //
1004 // The NUMCHANMASK is used to identify the channels for which data
1005 // buffers can be allocated. Using this mask and switch statement
1006 // rather than some other construct allows efficient code generation,
1007 // providing just the code necessary (with significant savings).
1008 //
1009 if (pP->fxns->bufMemPrint)
1010 {
1011 pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1012 pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1013 }
1015 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1017 if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1018 {
1019 if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, aAlign, &eb))) //Qin: Add start offset
1020 {
1021 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1022 TRACE_TERSE2(" maxFrameLength: %d. aLen_int*aSize: %d", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize);
1023 SW_BREAKPOINT;
1024 return __LINE__;
1025 }
1026 }
1028 if (aLen_ext*aSize!=0)
1029 {
1030 if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, (aLen_ext+(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_ext*aSize: %d", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize);
1034 SW_BREAKPOINT;
1035 return __LINE__;
1036 }
1037 }
1039 TRACE_TERSE3(" maxFrameLength: %d. aLen_int*aSize: %d. aBuf_int: 0x%x", maxFrameLength, (aLen_int+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_int);
1040 TRACE_TERSE3(" maxFrameLength: %d. aLen_ext*aSize: %d. aBuf_ext: 0x%x", maxFrameLength, (aLen_ext+(maxFrameLength-FRAMELENGTH))*aSize, (IArg)aBuf_ext);
1042 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1043 if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1044 {
1045 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1046 TRACE_TERSE1(" bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1047 SW_BREAKPOINT;
1048 return __LINE__;
1049 }
1051 {
1052 Int i;
1054 #pragma UNROLL(1)
1055 for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1056 {
1057 pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1058 }
1059 }
1061 // MID 314
1062 if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1))
1063 {
1064 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1065 return __LINE__;
1066 }
1067 else
1068 {
1069 Int j = 0;
1070 Int k = 0;
1071 TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1072 for(i=0;i<numchan[z];i++)
1073 {
1074 char chan = AFChanPtrMap[numchan[z]][i];
1075 if(chan != -1)
1076 {
1077 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1078 {
1079 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1080 j++;
1081 }
1082 else
1083 {
1084 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1085 k++;
1086 }
1087 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1088 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1089 }
1090 }
1091 }
1093 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1094 {
1095 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1096 {
1097 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1098 }
1099 }
1101 //
1102 // Initialize meta data elements
1103 //
1104 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1105 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1106 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1107 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1108 pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1109 for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1110 {
1111 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1112 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1113 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1114 }
1116 //
1117 // Initialize decoder elements directly
1118 //
1120 for (zX = DECODE1; zX < DECODEN; zX++)
1121 {
1122 if (pP->streamsFromDecodes[zX] == z)
1123 {
1124 #ifdef NOAUDIOSHARE
1125 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1126 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1127 #else /* NOAUDIOSHARE */
1128 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1129 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1130 #endif /* NOAUDIOSHARE */
1131 }
1132 }
1134 return 0;
1135 } //PAF_ASOT_initFrame0
1137 // -----------------------------------------------------------------------------
1138 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1139 // AST Decoding Function - Reinitialization of Audio Frame
1140 //
1141 // Name: PAF_ASOT_initFrame1
1142 // Purpose: Audio Stream Task Function for initialization or reinitiali-
1143 // zation of the Audio Frame(s) by loading of data values of a
1144 // time-varying nature.
1145 // From: audioStream1Task or equivalent
1146 // AST Parameter Function -> decodeInfo
1147 // AST Parameter Function -> decodeDecode
1148 // Uses: See code.
1149 // States: x
1150 // Return: 0.
1151 // Trace: None.
1152 //
1153 Int
1154 PAF_ASOT_initFrame1(
1155 const PAF_ASOT_Params *pP,
1156 const PAF_ASOT_Patchs *pQ,
1157 PAF_ASOT_Config *pC,
1158 Int z,
1159 Int apply
1160 )
1161 {
1162 PAF_AST_Config *pAstCfg;
1164 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1166 //
1167 // Reinitialize audio frame elements:
1168 //
1169 // Channel Configurations during sys init = Unknown
1170 // " " during info or decode = None
1171 //
1172 // Sample Rate / Count during sys init, info or decode = Unknown / 0
1173 //
1175 if (apply < 0)
1176 {
1177 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1178 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1179 }
1180 else
1181 {
1182 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1183 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1184 }
1186 if (apply < 1)
1187 {
1188 pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1189 pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1190 }
1192 return 0;
1193 } //PAF_ASOT_initFrame1
1195 // -----------------------------------------------------------------------------
1196 // ASOT Selection Function - Output Device Selection
1197 //
1198 // Name: PAF_ASOT_selectDevices
1199 // Purpose: Audio Stream Output Task Function for selecting the devices used
1200 // for output.
1201 // From: audioStream1Task or equivalent
1202 // Uses: See code.
1203 // States: x
1204 // Return: Error number in standard form (0 on success).
1205 // Trace: Message Log "trace" in Debug Project Configuration reports:
1206 // * State information as per parent.
1207 //
1208 Int
1209 PAF_ASOT_selectDevices(
1210 const PAF_ASOT_Params *pP,
1211 const PAF_ASOT_Patchs *pQ,
1212 PAF_ASOT_Config *pC
1213 )
1214 {
1215 PAF_AST_Config *pAstCfg;
1216 Int as; /* Audio Stream Number (1, 2, etc.) */
1217 Int z; /* input/output counter */
1218 Int errno = 0; /* error number */
1219 Int errme; /* error number, local */
1220 Int device;
1222 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1223 as = pAstCfg->as;
1224 (void)as; // clear compiler warning in case not used with tracing disabled
1226 // Select output devices
1227 for (z=OUTPUT1; z < OUTPUTN; z++)
1228 {
1229 if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0)
1230 {
1231 TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1233 /* check for valid index into device array */
1234 if (device >= pQ->devout->n)
1235 {
1236 device = 0; /* treat as device None */
1237 }
1239 errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT,
1240 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1241 if (errme)
1242 {
1243 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1244 if (!errno)
1245 {
1246 errno = ASPERR_DEVOUT + errme;
1247 }
1248 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1249 }
1250 else
1251 {
1252 Int zE;
1254 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1255 // register outBufStatus and encodeStatus pointers with output devices
1256 // This enables proper IEC encapsulation.
1257 if (pAstCfg->xOut[z].hTxSio)
1258 {
1259 // set max # of output buffers (use override if necessary)
1260 if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1261 {
1262 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1263 (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1264 }
1265 else
1266 {
1267 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1268 (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1269 }
1271 // register PAF_SIO_IALG object address
1272 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1273 (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1274 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR,
1275 (Arg)&pAstCfg->xOut[z].outBufStatus);
1276 for (zE=ENCODE1; zE < ENCODEN; zE++)
1277 {
1278 if (pP->outputsFromEncodes[zE] == z)
1279 {
1280 SIO_ctrl(pAstCfg->xOut[z].hTxSio,
1281 PAF_SIO_CONTROL_SET_ENCSTATUSADDR,
1282 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1283 break;
1284 }
1285 }
1286 }
1287 }
1288 }
1290 // if device selected and valid then enable stat tracking if
1291 // required and start clocking
1292 if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
1293 {
1294 TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1295 errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1296 if (errme)
1297 {
1298 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1299 SIO_idle(pAstCfg->xOut[z].hTxSio);
1300 if (!errno)
1301 {
1302 errno = ASPERR_DEVOUT + errme;
1303 }
1304 }
1305 }
1306 }
1308 return errno;
1309 } //PAF_ASOT_selectDevices
1311 // -----------------------------------------------------------------------------
1312 // ASOT Processing Function - Decode Processing
1313 //
1314 // Name: PAF_ASOT_decodeProcessing
1315 // Purpose: Audio Stream Output Task Function for processing audio data.
1316 //
1317 Int
1318 PAF_ASOT_decodeProcessing(
1319 const PAF_ASOT_Params *pP,
1320 const PAF_ASOT_Patchs *pQ,
1321 PAF_ASOT_Config *pC,
1322 Int sourceSelect
1323 )
1324 {
1325 PAF_AST_Config *pAstCfg;
1326 Int z; /* decode counter */
1327 Int errno; /* error number */
1328 Int getVal;
1329 enum { INIT, STREAM, ENCODE, FINAL, QUIT } state;
1330 state = INIT;
1331 errno = 0; /* error number */
1332 Int frame; // (***) FL: formerly -- decoder input frame count
1333 Int block; // decoder output block count / input frame
1334 Int outSioUpdate;
1336 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1338 for (;;)
1339 {
1340 // FL: Check if any change in output SIO, e.g. from Output shortcut.
1341 // Changes will break FSM and allow Output reconfiguration.
1342 if (errno = checkOutSio(pP, pC, &outSioUpdate))
1343 {
1344 TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1345 break;
1346 }
1347 else if (outSioUpdate)
1348 {
1349 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1350 state = QUIT;
1351 }
1353 // Process commands (encode)
1354 if (getVal = pP->fxns->encodeCommand(pP, pQ, pC))
1355 {
1356 /* ignore */;
1357 }
1359 // Process state (decode)
1360 switch (state)
1361 {
1362 case INIT: // initial state
1363 gAsopInitCnt++;
1364 Log_info0("TaskAsop: state=INIT");
1366 // Reset audio frame pointers to original values
1367 // (may be needed if error occurred).
1368 for (z=STREAM1; z < STREAMN; z++)
1369 {
1370 Int ch;
1371 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1372 {
1373 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1374 {
1375 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1376 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1377 }
1378 }
1379 }
1381 // Reset audio frame meta data elements
1382 {
1383 Int i;
1385 for (z=STREAM1; z < STREAMN; z++)
1386 {
1387 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1388 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1389 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1390 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1392 for (i=0; i<pP->pMetadataBufStatus->NumBuf; i++)
1393 {
1394 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1395 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1396 }
1397 }
1398 }
1400 if (errno = pP->fxns->decodeInit(pP, pQ, pC, sourceSelect))
1401 {
1402 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInit", errno);
1403 break;
1404 }
1406 // (***) FL: setup output (ASP chain reset, ENC reset, setCheckRateX, start output)
1407 // Contained in INFO1 in combined FSM.
1408 // Establish secondary timing
1409 if (errno = pP->fxns->decodeInfo1(pP, pQ, pC, frame, block))
1410 {
1411 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInfo1", errno);
1412 break;
1413 }
1415 frame = 0;
1416 block = 0;
1418 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");
1419 state = STREAM;
1420 continue;
1422 case STREAM: // stream state
1423 gAsopStreamCnt++;
1424 Log_info0("TaskAsop: state=STREAM");
1426 if (errno = pP->fxns->decodeStream(pP, pQ, pC, frame, block))
1427 {
1428 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM. decodeStream err 0x%x", errno);
1429 break;
1430 }
1432 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1433 state = ENCODE;
1434 continue;
1436 case ENCODE: // encode state
1437 gAsopEncodeCnt++;
1438 Log_info0("TaskAsop: state=ENCODE");
1440 if (errno = pP->fxns->decodeEncode(pP, pQ, pC, frame, block))
1441 {
1442 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE. decodeEncode err 0x%x", errno);
1443 break;
1444 }
1446 // (***) FL: do we need this?
1447 // AF pointers come from CB read, any resets occur in Decoder AF.
1448 // Reset audio frame pointers to original values
1449 // (may have been adjusted by ARC or the like).
1450 for (z=STREAM1; z < STREAMN; z++)
1451 {
1452 Int ch;
1453 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1454 {
1455 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1456 {
1457 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1458 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1459 }
1460 }
1461 }
1463 //
1464 // (***) FL: update output (setCheckRateX)
1465 // Contained in INFO2 in combined FSM.
1466 if (errno = pP->fxns->decodeInfo2(pP, pQ, pC, frame, block))
1467 {
1468 TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1469 break;
1470 }
1472 block++;
1473 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1474 state = FINAL;
1475 continue;
1477 case FINAL:
1478 gAsopFinalCnt++;
1479 Log_info0("TaskAsop: state=FINAL");
1481 //
1482 // (***) FL: this needs to be fixed.
1483 // (1) Only require selected Output to be in this FSM
1484 // => Dec Status checks aren't valid,
1485 // will probably always exit FSM if only Output running
1486 // (2) Checking Dec Status info asych to input events (maybe ok)
1487 //
1488 #if 0
1489 // Check for final frame, and if indicated:
1490 // - Update audio flag to cause output buffer flush rather than
1491 // the default truncate in "complete" processing.
1492 // - Exit state machine to "complete" processing.
1493 if (pP->fxns->decodeFinalTest(pP, pQ, pC, frame, block))
1494 {
1495 for (z=OUTPUT1; z < OUTPUTN; z++)
1496 {
1497 if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1498 {
1499 TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1500 pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1501 }
1502 }
1503 break;
1504 }
1505 #endif
1507 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1508 state = STREAM;
1509 continue;
1511 case QUIT:
1512 gAsopQuitCnt++;
1513 Log_info0("TaskAsop: state=QUIT");
1515 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1516 errno = ASPERR_QUIT;
1517 break;
1519 default: // unknown state
1520 // Unknown:
1521 // - Set error number registers.
1522 // - Exit state machine to "complete" processing.
1524 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1525 errno = ASPERR_UNKNOWNSTATE;
1526 break;
1528 } // End of switch (state).
1530 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1531 if (pP->fxns->decodeComplete(pP, pQ, pC, NULL, frame, block))
1532 {
1533 /* ignored? */;
1534 }
1536 return errno;
1537 } // End of for (;;)
1539 return errno;
1540 }
1542 // -----------------------------------------------------------------------------
1543 // ASOT Decoding Function - Encode Command Processing
1544 //
1545 // Name: PAF_ASOT_encodeCommand
1546 // Purpose: Decoding Function for processing Encode Commands.
1547 // From: AST Parameter Function -> decodeProcessing
1548 // Uses: See code.
1549 // States: x
1550 // Return: 0.
1551 // Trace: Message Log "trace" in Debug Project Configuration reports:
1552 // * Command execution.
1553 // * SIO control errors.
1554 // * Error number macros.
1555 //
1556 Int
1557 PAF_ASOT_encodeCommand(
1558 const PAF_ASOT_Params *pP,
1559 const PAF_ASOT_Patchs *pQ,
1560 PAF_ASOT_Config *pC
1561 )
1562 {
1563 PAF_AST_Config *pAstCfg;
1564 Int as; /* Audio Stream Number (1, 2, etc.) */
1565 Int z; /* encode counter */
1566 Int errno = 0; /* error number */
1567 Int zO, zS;
1570 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1571 as = pAstCfg->as;
1573 for (z=ENCODE1; z < ENCODEN; z++)
1574 {
1575 zO = pP->outputsFromEncodes[z];
1576 zS = pP->streamsFromEncodes[z];
1577 if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80))
1578 {
1579 switch (pAstCfg->xEnc[z].encodeStatus.command2)
1580 {
1581 case 0: // command none - process
1582 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1583 break;
1584 case 1: // mute command
1585 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
1586 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1587 && pAstCfg->xOut[zO].hTxSio
1588 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
1589 {
1590 errno = (errno & 0xff) | ASPERR_MUTE;
1591 /* convert to sensical errno */
1592 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
1593 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1594 }
1595 else
1596 {
1597 pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
1598 }
1599 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1600 break;
1601 case 2: // unmute command
1602 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
1603 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1604 && pAstCfg->xOut[zO].hTxSio
1605 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
1606 {
1607 errno = (errno & 0xff) | ASPERR_MUTE;
1608 /* convert to sensical errno */
1609 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
1610 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1611 }
1612 else
1613 {
1614 pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
1615 }
1616 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1617 break;
1618 default: // command unknown - ignore
1619 break;
1620 }
1621 }
1622 }
1624 ERRNO_RPRT (TaskAsop, errno);
1626 return 0;
1627 } //PAF_ASOT_encodeCommand
1629 // Purpose: Decoding Function for reinitializing the decoding process.
1630 Int
1631 PAF_ASOT_decodeInit(
1632 const PAF_ASOT_Params *pP,
1633 const PAF_ASOT_Patchs *pQ,
1634 PAF_ASOT_Config *pC,
1635 Int sourceSelect
1636 )
1637 {
1638 PAF_AST_Config *pAstCfg;
1639 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1640 Int as; /* Audio Stream Number (1, 2, etc.) */
1641 Int z; /* decode/encode counter */
1642 Int errno; /* error number */
1643 Int zO, zS;
1646 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1647 as = pAstCfg->as;
1649 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1651 for (z=DECODE1; z < DECODEN; z++)
1652 {
1653 // Start decoder output circular buffer reads
1654 errno = cbReadStart(pCbCtl, z);
1655 if (errno)
1656 {
1657 TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
1658 SW_BREAKPOINT; // FL: debug
1659 return errno;
1660 }
1661 // FL: debug
1662 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
1663 }
1665 // TODO: move this to start of this function so that it doesn't affect IO timing
1666 for (z=ENCODE1; z < ENCODEN; z++)
1667 {
1668 zO = pP->outputsFromEncodes[z];
1669 zS = pP->streamsFromEncodes[z];
1670 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1671 {
1672 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1673 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1674 ENC_Handle enc = (ENC_Handle )encAlg;
1675 TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
1676 if (encAlg->fxns->algActivate)
1677 {
1678 encAlg->fxns->algActivate (encAlg);
1679 }
1680 if (enc->fxns->reset
1681 && (errno = enc->fxns->reset(enc, NULL,
1682 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1683 {
1684 return errno;
1685 }
1686 }
1687 }
1689 return 0;
1690 }
1692 // -----------------------------------------------------------------------------
1693 // ASOT Decoding Function - Info Processing, Initial
1694 //
1695 // Name: PAF_ASOT_decodeInfo1
1696 // Purpose: Decoding Function for processing information in a manner that
1697 // is unique to initial frames of input data.
1698 // From: AST Parameter Function -> decodeProcessing
1699 // Uses: See code.
1700 // States: x
1701 // Return: Error number in standard or SIO form (0 on success).
1702 // Trace: Message Log "trace" in Debug Project Configuration reports:
1703 // * State information as per parent.
1704 //
1705 Int
1706 PAF_ASOT_decodeInfo1(
1707 const PAF_ASOT_Params *pP,
1708 const PAF_ASOT_Patchs *pQ,
1709 PAF_ASOT_Config *pC,
1710 Int frame,
1711 Int block
1712 )
1713 {
1714 PAF_AST_Config *pAstCfg;
1715 Int z; /* decode/encode counter */
1716 Int errno; /* error number */
1718 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1720 // run the chain of ASP's on the stream.
1721 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
1722 if (errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1723 PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame))
1724 {
1725 TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
1726 return errno;
1727 }
1729 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
1730 for (z=ENCODE1; z < ENCODEN; z++)
1731 {
1732 Int zO = pP->outputsFromEncodes[z];
1733 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1734 {
1735 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1736 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1737 ENC_Handle enc = (ENC_Handle )encAlg;
1738 if (enc->fxns->info
1739 && (errno = enc->fxns->info(enc, NULL,
1740 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1741 {
1742 TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
1743 return errno;
1744 }
1745 }
1746 }
1748 if (errno = pP->fxns->setCheckRateX(pP, pQ, pC, 0))
1749 {
1750 // ignore if rateX has changed since we haven't, but are about to,
1751 // start the output. If we didn't ignore this case then the state machine
1752 // would restart unnecessarily, e.g. in the case of SRC, resulting in
1753 // added latency.
1754 if (errno != ASPERR_INFO_RATECHANGE)
1755 {
1756 TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
1757 return errno;
1758 }
1759 else
1760 {
1761 TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
1762 }
1763 }
1765 if (errno = pP->fxns->startOutput(pP, pQ, pC))
1766 {
1767 if (errno == 0x105)
1768 {
1769 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
1770 }
1771 else
1772 {
1773 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
1774 }
1775 return errno;
1776 }
1778 return 0;
1779 }
1781 // -----------------------------------------------------------------------------
1782 // ASOT Decoding Function - Info Processing, Subsequent
1783 //
1784 // Name: PAF_ASOT_decodeInfo2
1785 // Purpose: Decoding Function for processing information in a manner that
1786 // is unique to frames of input data other than the initial one.
1787 // From: AST Parameter Function -> decodeProcessing
1788 // Uses: See code.
1789 // States: x
1790 // Return: Error number in standard form (0 on success).
1791 // Trace: None.
1792 //
1793 Int
1794 PAF_ASOT_decodeInfo2(
1795 const PAF_ASOT_Params *pP,
1796 const PAF_ASOT_Patchs *pQ,
1797 PAF_ASOT_Config *pC,
1798 Int frame,
1799 Int block
1800 )
1801 {
1802 //PAF_AST_Config *pAstCfg;
1803 Int errno;
1806 //pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1808 errno = pP->fxns->setCheckRateX (pP, pQ, pC, 1);
1809 TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
1810 return errno;
1811 } //PAF_ASOT_decodeInfo2
1813 // -----------------------------------------------------------------------------
1814 // ASOT Decoding Function - Stream Processing
1815 //
1816 // Name: PAF_ASOT_decodeStream
1817 // Purpose: Decoding Function for processing of audio frame data by the
1818 // ASP Algorithms.
1819 // From: AST Parameter Function -> decodeProcessing
1820 // Uses: See code.
1821 // States: x
1822 // Return: Error number in standard form (0 on success).
1823 // Trace: Message Log "trace" in Debug Project Configuration reports:
1824 // * State information as per parent/child.
1825 //
1826 Int
1827 PAF_ASOT_decodeStream(
1828 const PAF_ASOT_Params *pP,
1829 const PAF_ASOT_Patchs *pQ,
1830 PAF_ASOT_Config *pC,
1831 Int frame,
1832 Int block
1833 )
1834 {
1835 PAF_AST_Config *pAstCfg;
1836 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1837 Int z; /* decode/stream counter */
1838 PAF_AudioFrame *pAfRd;
1839 Int cbErrno;
1840 Int errno;
1843 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1845 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1847 for (z=DECODE1; z < DECODEN; z++)
1848 {
1849 Int zS = pP->streamsFromDecodes[z];
1851 //
1852 // Read decoder output circular buffer
1853 //
1854 pAfRd = pAstCfg->xStr[zS].pAudioFrame;
1855 cbErrno = cbReadAf(pCbCtl, z, pAfRd);
1856 if (cbErrno != 0)
1857 {
1858 TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
1859 //SW_BREAKPOINT; // FL: debug
1861 if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
1862 {
1863 // Reset circular buffer
1864 cbReset(pCbCtl, z);
1865 Log_info0("PAF_ASOT_decodeStream:cbReset");
1867 // Update underflow count, return if above threshold
1868 gDecOpCbRdAfUnd++;
1869 if (gDecOpCbRdAfUnd == DEC_OP_CB_RDAF_UND_THR)
1870 {
1871 gDecOpCbRdAfUnd = 0;
1872 return cbErrno;
1873 }
1874 }
1875 }
1876 //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
1878 // FL: debug
1879 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
1880 //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
1881 //{
1882 // Log_info0("capAfWrite() error");
1883 //}
1884 }
1886 TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
1887 errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1888 PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
1889 if (errno)
1890 {
1891 TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
1892 return errno;
1893 }
1895 return 0;
1897 } //PAF_ASOT_decodeStream
1899 // -----------------------------------------------------------------------------
1900 // ASOT Decoding Function - Encode Processing
1901 //
1902 // Name: PAF_ASOT_decodeEncode
1903 // Purpose: Decoding Function for processing of audio frame data by the
1904 // Encode Algorithm.
1905 // From: AST Parameter Function -> decodeProcessing
1906 // Uses: See code.
1907 // States: x
1908 // Return: Error number in standard or SIO form (0 on success).
1909 // Trace: Message Log "trace" in Debug Project Configuration reports:
1910 // * State information as per parent.
1911 //
1912 Int
1913 PAF_ASOT_decodeEncode(
1914 const PAF_ASOT_Params *pP,
1915 const PAF_ASOT_Patchs *pQ,
1916 PAF_ASOT_Config *pC,
1917 Int frame,
1918 Int block
1919 )
1920 {
1921 PAF_AST_Config *pAstCfg;
1922 Int as; /* Audio Stream Number (1, 2, etc.) */
1923 Int z; /* encode/output counter */
1924 Int errno; /* error number */
1925 Int zX, zE, zS;
1926 UInt32 curTime;
1928 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1929 as = pAstCfg->as;
1931 // Await output buffers (but not first time)
1932 for (z=OUTPUT1; z < OUTPUTN; z++)
1933 {
1934 // determine encoder associated with this output
1935 zE = z;
1936 for (zX = ENCODE1; zX < ENCODEN; zX++)
1937 {
1938 if (pP->outputsFromEncodes[zX] == z)
1939 {
1940 zE = zX;
1941 break;
1942 }
1943 }
1944 zS = pP->streamsFromEncodes[zE];
1946 if (pAstCfg->xOut[z].hTxSio)
1947 {
1948 // update length (e.g. ARC may have changed)
1949 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
1950 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
1951 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
1952 errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
1953 if (errno < 0)
1954 {
1955 SIO_idle(pAstCfg->xOut[z].hTxSio);
1956 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
1957 return -errno; // SIO negates error codes
1958 }
1959 // TODO: use pC->xOut[z].pOutBuf in following ->encode call
1961 //
1962 // Simulate Tx SIO_reclaim() pend
1963 //
1964 //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
1965 gTaskAsopCnt++;
1966 curTime = Clock_getTicks();
1967 //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
1968 //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
1969 }
1970 else
1971 {
1972 TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
1973 }
1974 }
1976 // Encode data
1977 for (z=ENCODE1; z < ENCODEN; z++)
1978 {
1979 Int zO = pP->outputsFromEncodes[z];
1980 Int zS = pP->streamsFromEncodes[z];
1981 (void)zS; // clear compiler warning in case not used with tracing disabled
1982 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1983 {
1984 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1985 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1986 ENC_Handle enc = (ENC_Handle )encAlg;
1987 if (select != pAstCfg->xEnc[z].encodeControl.encActive)
1988 {
1989 pAstCfg->xEnc[z].encodeControl.encActive = select;
1990 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
1991 return (-1);
1992 }
1993 TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
1995 // (MID 1933) temp. workaround for PCE2
1996 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
1998 /*
1999 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2000 {
2001 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
2002 int *wp;
2003 wp = (int*)pAudioFrame->data.sample[0];
2004 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2005 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2006 wp = (int*)pAudioFrame->data.sample[1];
2007 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2008 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2009 wp = (int*)pAudioFrame->data.sample[2];
2010 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2011 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2012 }
2013 #endif
2014 */
2016 if (enc->fxns->encode)
2017 {
2018 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2019 pP->z_pEncodeStatus[z]->encBypass;
2020 if (errno = enc->fxns->encode(enc, NULL,
2021 &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct))
2022 {
2023 if (errno != PCEERR_OUTPUT_POINTERNULL)
2024 {
2025 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2026 return errno;
2027 }
2028 }
2029 /* #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2030 else
2031 {
2032 int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2033 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2034 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2035 }
2036 #endif
2037 */
2038 }
2039 }
2040 else
2041 {
2042 TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2043 as+pP->streamsFromEncodes[z], block);
2044 }
2045 }
2047 // Transmit data
2048 for (z=OUTPUT1; z < OUTPUTN; z++)
2049 {
2050 // determine encoder associated with this output
2051 zE = z;
2052 for (zX = ENCODE1; zX < ENCODEN; zX++)
2053 {
2054 if (pP->outputsFromEncodes[zX] == z)
2055 {
2056 zE = zX;
2057 break;
2058 }
2059 }
2060 zS = pP->streamsFromEncodes[zE];
2062 if (pAstCfg->xOut[z].hTxSio)
2063 {
2064 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2065 errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2066 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2067 if (errno)
2068 {
2069 SIO_idle(pAstCfg->xOut[z].hTxSio);
2070 if (errno == 0x105) // 0x105 == RINGIO_EBUFFULL
2071 {
2072 // statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2073 TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2074 }
2075 if (errno > 0)
2076 {
2077 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2078 return (ASPERR_ISSUE + (z << 4));
2079 }
2080 else if (errno < 0)
2081 {
2082 TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2083 return -errno; // SIO negates error codes
2084 }
2085 }
2086 if (errno > 0)
2087 {
2088 return (ASPERR_ISSUE + (z << 4));
2089 }
2090 else if (errno < 0)
2091 {
2092 return -errno; // SIO negates error codes
2093 }
2094 }
2095 else
2096 {
2097 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2098 }
2099 }
2101 return 0;
2102 } //PAF_ASOT_decodeEncode
2104 // -----------------------------------------------------------------------------
2105 // ASOT Decoding Function - Stream-Final Processing
2106 //
2107 // Name: PAF_ASOT_decodeComplete
2108 // Purpose: Decoding Function for terminating the decoding process.
2109 // From: AST Parameter Function -> decodeProcessing
2110 // Uses: See code.
2111 // States: x
2112 // Return: 0.
2113 // Trace: Message Log "trace" in Debug Project Configuration reports:
2114 // * State information as per parent.
2115 //
2116 Int
2117 PAF_ASOT_decodeComplete(
2118 const PAF_ASOT_Params *pP,
2119 const PAF_ASOT_Patchs *pQ,
2120 PAF_ASOT_Config *pC,
2121 ALG_Handle decAlg[],
2122 Int frame,
2123 Int block
2124 )
2125 {
2126 PAF_AST_Config *pAstCfg;
2127 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
2128 Int as; /* Audio Stream Number (1, 2, etc.) */
2129 Int z; /* decode/encode counter */
2130 Int errno; /* error number */
2133 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2134 as = pAstCfg->as;
2135 (void)as; // clear compiler warning in case not used with tracing disabled
2137 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2139 for (z=DECODE1; z < DECODEN; z++)
2140 {
2141 // Stop decoder output circular buffer reads
2142 errno = cbReadStop(pCbCtl, z);
2143 if (errno)
2144 {
2145 TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2146 SW_BREAKPOINT; // FL: debug
2147 return errno;
2148 }
2149 // FL: debug
2150 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2151 }
2153 pP->fxns->streamChainFunction(pP, pQ, pC, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2155 for (z=ENCODE1; z < ENCODEN; z++)
2156 {
2157 Int zO = pP->outputsFromEncodes[z];
2158 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
2159 {
2160 Int select = pAstCfg->xEnc[z].encodeStatus.select;
2161 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2162 #ifdef PAF_ASP_FINAL
2163 ENC_Handle enc = (ENC_Handle)encAlg;
2164 #endif /* PAF_ASP_FINAL */
2165 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2166 #ifdef PAF_ASP_FINAL
2167 if (enc->fxns->final)
2168 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2169 &pAstCfg->xEnc[z].encodeStatus);
2170 #endif /* PAF_ASP_FINAL */
2171 if (encAlg->fxns->algDeactivate)
2172 {
2173 encAlg->fxns->algDeactivate(encAlg);
2174 }
2175 }
2176 else
2177 {
2178 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2179 }
2180 }
2182 // wait for remaining data to be output
2183 pP->fxns->stopOutput(pP, pQ, pC);
2185 return 0;
2186 } //PAF_ASOT_decodeComplete
2188 // -----------------------------------------------------------------------------
2189 // ASOT Decoding Function Helper - SIO Driver Start
2190 //
2191 // Name: PAF_ASOT_startOutput
2192 // Purpose: Decoding Function for initiating output.
2193 // From: AST Parameter Function -> decodeInfo1
2194 // Uses: See code.
2195 // States: x
2196 // Return: Error number in standard or SIO form (0 on success).
2197 // Trace: Message Log "trace" in Debug Project Configuration reports:
2198 // * State information as per parent.
2199 // * SIO control errors.
2200 //
2201 #define DEC_OUTNUMBUF_MAP(X) \
2202 pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2204 Int
2205 PAF_ASOT_startOutput(
2206 const PAF_ASOT_Params *pP,
2207 const PAF_ASOT_Patchs *pQ,
2208 PAF_ASOT_Config *pC
2209 )
2210 {
2211 PAF_AST_Config *pAstCfg;
2212 Int as; /* Audio Stream Number (1, 2, etc.) */
2213 Int z; /* output counter */
2214 Int errno,nbufs; /* error number */
2215 Int zE, zS, zX;
2216 Int zMD;
2217 PAF_SIO_IALG_Obj *pObj;
2218 PAF_SIO_IALG_Config *pAlgConfig;
2221 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2222 as = pAstCfg->as;
2223 zMD = pAstCfg->masterDec;
2225 for (z=OUTPUT1; z < OUTPUTN; z++)
2226 {
2227 if (pAstCfg->xOut[z].hTxSio)
2228 {
2229 // determine associated encoder and stream
2230 zE = z;
2231 zS = z;
2232 for (zX = ENCODE1; zX < ENCODEN; zX++)
2233 {
2234 if (pP->outputsFromEncodes[zX] == z)
2235 {
2236 zE = zX;
2237 zS = pP->streamsFromEncodes[zE];
2238 break;
2239 }
2240 }
2242 // Set sample count so that DOB knows how much data to send
2243 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2244 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2246 if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED)
2247 {
2248 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2249 pAlgConfig = &pObj->config;
2250 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA,
2251 pAlgConfig->pMemRec[0].size);
2252 }
2254 // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2255 // decoder. How should we handle the sourceProgram for multiple decoders?
2256 // Override as needed
2257 nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2258 if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2259 {
2260 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2261 }
2262 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2264 if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2265 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0))
2266 {
2267 SIO_idle(pAstCfg->xOut[z].hTxSio);
2268 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2269 return errno;
2270 }
2272 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2273 (errno = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
2274 {
2275 errno = (errno & 0xff) | ASPERR_MUTE;
2276 /* convert to sensical errno */
2277 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2278 return (errno);
2279 }
2280 else
2281 {
2282 pAstCfg->xOut[z].outBufStatus.audio
2283 = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;
2284 }
2286 TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2287 }
2288 }
2290 return 0;
2291 } //PAF_ASOT_startOutput
2293 // -----------------------------------------------------------------------------
2294 // ASOT Decoding Function Helper - SIO Driver Stop
2295 //
2296 // Name: PAF_ASOT_stopOutput
2297 // Purpose: Decoding Function for terminating output.
2298 // From: AST Parameter Function -> decodeProcessing
2299 // AST Parameter Function -> decodeComplete
2300 // Uses: See code.
2301 // States: x
2302 // Return: Error number in standard or SIO form (0 on success).
2303 // Trace: Message Log "trace" in Debug Project Configuration reports:
2304 // * SIO control errors.
2305 //
2306 Int
2307 PAF_ASOT_stopOutput(
2308 const PAF_ASOT_Params *pP,
2309 const PAF_ASOT_Patchs *pQ,
2310 PAF_ASOT_Config *pC
2311 )
2312 {
2313 PAF_AST_Config *pAstCfg;
2314 Int as; /* Audio Stream Number (1, 2, etc.) */
2315 Int z; /* output counter */
2316 Int errno = 0, getVal;
2317 Int zS, zX;
2318 PAF_SIO_IALG_Obj *pObj;
2319 PAF_SIO_IALG_Config *pAlgConfig;
2321 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2322 as = pAstCfg->as;
2323 (void)as; // clear compiler warning in case not used with tracing disabled
2325 for (z=OUTPUT1; z < OUTPUTN; z++)
2326 {
2327 if (pAstCfg->xOut[z].hTxSio)
2328 {
2329 // determine associated encoder and stream
2330 zS = z;
2331 (void)zS;
2332 for (zX = ENCODE1; zX < ENCODEN; zX++)
2333 {
2334 if (pP->outputsFromEncodes[zX] == z)
2335 {
2336 zS = pP->streamsFromEncodes[zX];
2337 break;
2338 }
2339 }
2341 // Mute output before audio data termination in the usual case,
2342 // where such termination is due to decode error or user command.
2343 // Identification of this as the usual case is provided by the
2344 // "decode processing" state machine.
2345 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2346 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2347 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2348 {
2349 if (!errno)
2350 {
2351 errno = (getVal & 0xff) | ASPERR_MUTE;
2352 /* convert to sensical errno */
2353 }
2354 TRACE_VERBOSE1("PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2355 }
2357 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2359 // Terminate audio data output, truncating (ignore) or flushing
2360 // (play out) final samples as per (1) control register set by
2361 // the user and (2) the type of audio data termination:
2363 #if 0
2364 // This form is not used because driver support for truncating
2365 // data is not supported for internal clocks, although it is
2366 // for external clocks.
2367 getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2368 pC->xOut[z].outBufStatus.flush
2369 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2370 ? 1 : 0);
2371 /* UNTESTED */
2372 #else
2373 // This form should be used when driver support for truncating
2374 // data is supported for both internal and external clocks.
2375 getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2376 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2377 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2378 ? 1 : 0);
2379 /* TESTED */
2380 #endif
2382 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2384 if (!errno)
2385 {
2386 errno = getVal;
2387 }
2389 // Mute output after audio data termination in a special case,
2390 // where such termination is due to processing of a final frame
2391 // or user command. Identification of this as a special case is
2392 // provided by the "decode processing" state machine.
2393 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2394 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2395 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2396 {
2397 if (!errno)
2398 {
2399 errno = (getVal & 0xff) | ASPERR_MUTE;
2400 /* convert to sensical errno */
2401 }
2402 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2403 }
2405 pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2407 // zero output buffers
2408 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2409 pAlgConfig = &pObj->config;
2410 memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2411 } //pAstCfg->xOut[z].hTxSio
2412 }//OUTPUT
2414 return errno;
2415 } //PAF_ASOT_stopOutput
2417 // -----------------------------------------------------------------------------
2418 // ASOT Decoding Function Helper - SIO Driver Change
2419 //
2420 // Name: PAF_ASOT_setCheckRateX
2421 // Purpose: Decoding Function for reinitiating output.
2422 // From: AST Parameter Function -> decodeInfo1
2423 // AST Parameter Function -> decodeInfo2
2424 // Uses: See code.
2425 // States: x
2426 // Return: Error number in standard form (0 on success).
2427 // Trace: None.
2428 //
2430 /* 0: set, 1: check, unused for now. --Kurt */
2431 Int
2432 PAF_ASOT_setCheckRateX(
2433 const PAF_ASOT_Params *pP,
2434 const PAF_ASOT_Patchs *pQ,
2435 PAF_ASOT_Config *pC,
2436 Int check
2437 )
2438 {
2439 PAF_AST_Config *pAstCfg;
2440 float rateX;
2441 PAF_SampleRateHz rateO /* std */, rateI /* inv */;
2442 Int z; /* output counter */
2443 Int zx; /* output re-counter */
2444 Int getVal;
2445 int inputRate, inputCount, outputRate, outputCount;
2446 Int zMD;
2447 Int zMI;
2448 Int zMS;
2449 Int zE, zX;
2451 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2452 zMD = pAstCfg->masterDec;
2453 zMS = pAstCfg->masterStr;
2454 zMI = pP->zone.master;
2456 inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
2457 inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
2458 rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2459 (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
2461 for (z=OUTPUT1; z < OUTPUTN; z++) {
2462 if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) {
2464 // determine associated encoder
2465 zE = z;
2466 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2467 if (pP->outputsFromEncodes[zX] == z) {
2468 zE = zX;
2469 break;
2470 }
2471 }
2473 outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
2474 outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
2475 rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2476 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
2477 if (rateI > 0 && rateO > 0)
2478 rateX = rateO /* std */ * rateI /* inv */;
2479 else if (inputCount != 0)
2480 rateX = (float )outputCount / inputCount;
2481 else
2482 return ( ASPERR_INFO_RATERATIO );
2484 getVal = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg) &rateX);
2485 if (getVal == DOBERR_RATECHANGE) {
2486 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
2487 if (pAstCfg->xOut[zx].hTxSio)
2488 SIO_idle (pAstCfg->xOut[zx].hTxSio);
2490 // this forces an exit from the calling state machine which will
2491 // eventually call startOutput which calls setCheckRateX for all outputs
2492 // and so it is ok, in the presence of a rate change on any output, to
2493 // exit this loop /function early.
2494 return ASPERR_INFO_RATECHANGE;
2495 }
2496 else if( getVal != SYS_OK )
2497 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
2498 }
2499 }
2501 return 0;
2502 } //PAF_ASOT_setCheckRateX
2504 // -----------------------------------------------------------------------------
2505 // ASOT Decoding Function Helper - Chain Processing
2506 //
2507 // Name: PAF_ASOT_streamChainFunction
2508 // Purpose: Common Function for processing algorithm chains.
2509 // From: AST Parameter Function -> decodeInfo1
2510 // AST Parameter Function -> decodeStream
2511 // AST Parameter Function -> decodeComplete
2512 // Uses: See code.
2513 // States: x
2514 // Return: Error number in standard form (0 on success).
2515 // Trace: Message Log "trace" in Debug Project Configuration reports:
2516 // * State information as per parent.
2517 //
2518 Int
2519 PAF_ASOT_streamChainFunction(
2520 const PAF_ASOT_Params *pP,
2521 const PAF_ASOT_Patchs *pQ,
2522 PAF_ASOT_Config *pC,
2523 Int iChainFrameFxns,
2524 Int abortOnError,
2525 Int logArg
2526 )
2527 {
2528 PAF_AST_Config *pAstCfg;
2529 Int as; /* Audio Stream Number (1, 2, etc.) */
2530 Int z; /* stream counter */
2531 Int errno; /* error number */
2532 Int dFlag, eFlag, gear;
2533 Int zX;
2534 Int zS;
2536 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2537 as = pAstCfg->as;
2538 (void)as; // clear compiler warning in case not used with tracing disabled
2540 for (zS = STREAM1; zS < STREAMN; zS++)
2541 {
2542 z = pP->streamOrder[zS]; // Select stream order from streamOrder parameter - MID 788
2544 // apply stream
2545 // unless the stream is associated with a decoder and it is not running
2546 // or
2547 // unless the stream is associated with an encoder and it is not running
2548 // Also gear control only works for streams with an associated decoder
2549 // if no such association exists then gear 0 (All) is used
2550 dFlag = 1;
2551 gear = 0;
2552 for (zX = DECODE1; zX < DECODEN; zX++) {
2553 if (pP->streamsFromDecodes[zX] == z) {
2554 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
2555 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
2556 break;
2557 }
2558 }
2559 eFlag = 1;
2560 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2561 if (pP->streamsFromEncodes[zX] == z) {
2562 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
2563 break;
2564 }
2565 }
2567 if (dFlag && eFlag) {
2568 PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
2569 PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
2570 Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
2571 chain->fxns->chainFrameFunction[iChainFrameFxns];
2573 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2574 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
2575 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2576 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
2577 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2578 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
2579 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
2580 as+z, logArg);
2581 errno = (*func) (chain, frame);
2582 TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
2583 as+z, errno);
2585 if (errno && abortOnError)
2586 return errno;
2587 }
2588 else {
2589 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2590 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
2591 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2592 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
2593 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2594 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
2595 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
2596 as+z, logArg);
2597 }
2599 /*
2600 {
2601 void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
2602 PAF_AudioFrameData *afd;
2603 float ** afPtr;
2605 afd = &(pC->xStr->pAudioFrame->data);
2606 afPtr = (float**)afd->sample;
2607 dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
2609 }
2610 */
2612 }
2614 return 0;
2615 } //PAF_ASOT_streamChainFunction
2617 /* FL: Check if at least one output selected */
2618 static Int checkOutSel(
2619 const PAF_ASOT_Params *pP,
2620 PAF_ASOT_Config *pC,
2621 Int *pOutSel
2622 )
2623 {
2624 PAF_AST_Config *pAstCfg;
2625 Int outSel;
2626 Int z;
2628 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2630 outSel = 0;
2631 for (z=OUTPUT1; z < OUTPUTN; z++)
2632 {
2633 if (pAstCfg->xOut[z].hTxSio)
2634 {
2635 outSel = 1;
2636 break;
2637 }
2638 }
2640 *pOutSel = outSel;
2642 return 0;
2643 }
2645 /* FL: Check if at least one output sio changed */
2646 static Int checkOutSio(
2647 const PAF_ASOT_Params *pP,
2648 PAF_ASOT_Config *pC,
2649 Int *pOutSioUpdate
2650 )
2651 {
2652 PAF_AST_Config *pAstCfg;
2653 Int outSioUpdate;
2654 Int z;
2656 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2658 outSioUpdate = 0;
2659 for (z=OUTPUT1; z < OUTPUTN; z++)
2660 {
2661 if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
2662 {
2663 outSioUpdate = 1;
2664 break;
2665 }
2666 }
2668 *pOutSioUpdate = outSioUpdate;
2670 return 0;
2671 }