[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / framework / audioStreamOutProc.c
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_CLEAR);
606 if (pP->fxns->headerPrint)
607 {
608 pP->fxns->headerPrint();
609 }
611 for (z = STREAM1; z < STREAMN; z++)
612 {
613 //Int zD, zE, zX;
614 Int zE, zX;
616 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: initialization phase - Common Memory", as+z);
618 //
619 // Determine common memory needs for:
620 // (1) ASP Algorithms
621 // (2) Encode Algorithms
622 // (3) Logical Output drivers
623 //
624 PAF_ALG_init(common[z], lengthof(common[z]), COMMONSPACE);
626 zE = -1;
627 for (zX = ENCODE1; zX < ENCODEN; zX++)
628 {
629 if (pP->streamsFromEncodes[zX] == z)
630 {
631 zE = zX;
632 break;
633 }
634 }
636 TRACE_TERSE1("Calling PAF_ALG_ALLOC for stream common[%d].", z);
637 if (PAF_ALG_ALLOC(aspLinkInit[z-STREAM1][0], common[z]))
638 {
639 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
640 TRACE_TERSE2("Failed to alloc %d bytes from space %d ", common[z]->size, common[z]->space);
641 SW_BREAKPOINT;
642 return __LINE__;
643 }
644 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
645 if (pP->fxns->allocPrint)
646 {
647 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(aspLinkInit[z-STREAM1][0]), sizeof (*(aspLinkInit[z-STREAM1][0])), &pafAlgConfig);
648 }
650 if (zE >= 0)
651 {
652 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC/ for encoder common[%d].", z);
653 if (PAF_ALG_ALLOC(encLinkInit[zE-ENCODE1], common[z]))
654 {
655 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: AS%d: PAF_ALG_alloc failed", as+z);
656 SW_BREAKPOINT;
657 return __LINE__;
658 }
659 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
660 if (pP->fxns->allocPrint)
661 {
662 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(encLinkInit[z-ENCODE1]), sizeof (*(encLinkInit[z-ENCODE1])), &pafAlgConfig);
663 }
664 }
666 //
667 // Determine common memory needs of Logical IO drivers
668 //
670 if (OUTPUT1 <= z && z < OUTPUTN)
671 {
672 TRACE_TERSE1("PAF_ASOT_initPhaseCommon: calling PAF_ALG_ALLOC outLinkInit common[%d].", z);
673 if (PAF_ALG_ALLOC(outLinkInit[z-OUTPUT1], common[z]))
674 {
675 TRACE_TERSE1("PAF_ASOT_initPhaseMalloc: AS%d: PAF_ALG_alloc failed", as+z);
676 TRACE_TERSE2("Failed to alloc %d bytes from space %d", common[z]->size, (IArg)common[z]->space);
677 SW_BREAKPOINT;
678 return __LINE__;
679 }
680 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
681 if (pP->fxns->allocPrint)
682 {
683 pP->fxns->allocPrint((const PAF_ALG_AllocInit *)(outLinkInit[z-INPUT1]), sizeof (*(outLinkInit[z-INPUT1])), &pafAlgConfig);
684 }
685 }
686 }
687 {
688 // Changes made to share scratch between zones
689 // Assume maximum 3 zones and scratch common memory is at offset 0;
690 int max=0;
691 for (z=STREAM1; z<STREAMN; z++)
692 {
693 if (max < common[z][0].size)
694 {
695 max = common[z][0].size;
696 }
697 }
698 common[STREAM1][0].size=max;
699 for (z=STREAM1+1; z<STREAMN; z++)
700 {
701 common[z][0].size = 0;
702 }
703 }
705 //
706 // Allocate common memory for:
707 // (1) ASP Algorithms
708 // (2) Encode Algorithms
709 // (3) Logical Output drivers
710 //
711 for (z = STREAM1; z < STREAMN; z++)
712 {
713 //Int zD, zE, zX;
714 Int zE, zX;
716 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ALG_mallocMemory for common space.");
717 if (PAF_ALG_mallocMemory(common[z], &pafAlgConfig))
718 {
719 TRACE_TERSE1("AS%d: PAF_ALG_mallocMemory failed", as+z);
720 TRACE_TERSE3("AS%d: z: %d. Size 0x%x", as+z, z, common[z][0].size);
721 SW_BREAKPOINT;
722 return __LINE__;
723 }
724 TRACE_TERSE3("alloced %d bytes from space %d at 0x%x", common[z]->size, common[z]->space, (IArg)common[z]->base);
725 // share zone0 scratch with all zones
726 common[z][0].base = common[0][0].base;
727 if (pP->fxns->commonPrint)
728 {
729 pP->fxns->commonPrint(common[z], &pafAlgConfig);
730 }
732 zE = -1;
733 for (zX = ENCODE1; zX < ENCODEN; zX++)
734 {
735 if (pP->streamsFromEncodes[zX] == z)
736 {
737 zE = zX;
738 break;
739 }
740 }
742 pAstCfg->xStr[z].aspChain[0] = NULL;
743 for (g=0; g < GEARS; g++)
744 {
745 PAF_ASP_Chain *chain;
746 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for ASPs.");
747 chain = PAF_ASP_chainInit(&pAstCfg->xStr[z].aspChainData[g], pP->pChainFxns,
748 HEAP_INTERNAL, as+z, acp, &trace,
749 aspLinkInit[z-STREAM1][g], pAstCfg->xStr[z].aspChain[0], common[z], &pafAlgConfig);
750 if (!chain)
751 {
752 TRACE_TERSE2("AS%d: ASP chain %d initialization failed", as+z, g);
753 return __LINE__;
754 }
755 else
756 {
757 pAstCfg->xStr[z].aspChain[g] = chain;
758 }
759 }
761 if (zE >= 0)
762 {
763 PAF_ASP_Chain *chain;
764 TRACE_TERSE0("PAF_ASOT_initPhaseCommon: calling PAF_ASP_chainInit for encode.");
765 chain = PAF_ASP_chainInit(&pAstCfg->xEnc[zE].encChainData, pP->pChainFxns,
766 HEAP_INTERNAL, as+z, acp, &trace,
767 encLinkInit[zE-ENCODE1], NULL, common[z], &pafAlgConfig);
768 if (!chain)
769 {
770 TRACE_TERSE1("AS%d: Encode chain initialization failed", as+z);
771 return __LINE__;
772 }
773 }
775 //
776 // Allocate non-common memories for Logical IO drivers
777 // Since these structures are used at run-time we allocate from external memory
778 if (OUTPUT1 <= z && z < OUTPUTN)
779 {
780 PAF_ASP_Chain *chain;
781 TRACE_TERSE2("PAF_ASOT_initPhaseMalloc: AS%d: non-common output chain init for %d",
782 as+z, z);
783 chain = PAF_ASP_chainInit (&pAstCfg->xOut[z].outChainData, pP->pChainFxns,
784 HEAP_EXTERNAL, as+z, acp, &trace,
785 outLinkInit[z-OUTPUT1], NULL, common[z], &pafAlgConfig);
786 if (!chain)
787 {
788 TRACE_TERSE1("AS%d: Output chain initialization failed", as+z);
789 return __LINE__;
790 }
791 }
792 }
793 TRACE_TERSE1("AS%d: PAF_ASOT_initPhaseCommon: Returning complete.", as+z);
795 return 0;
796 } //PAF_ASOT_initPhaseCommon
798 // -----------------------------------------------------------------------------
799 // ASOT Initialization Function - Algorithm Keys
800 //
801 // Name: PAF_ASOT_initPhaseAlgKey
802 // Purpose: Audio Stream Output Task Function for initialization of data values
803 // from parameters for Algorithm Keys.
804 // From: audioStream1Task or equivalent
805 // Uses: See code.
806 // States: x
807 // Return: 0.
808 // Trace: Message Log "trace" in Debug Project Configuration reports:
809 // * State information as per parent.
810 //
811 // .............................................................................
812 Int
813 PAF_ASOT_initPhaseAlgKey(
814 const PAF_ASOT_Params *pP,
815 const PAF_ASOT_Patchs *pQ,
816 PAF_ASOT_Config *pC
817 )
818 {
819 PAF_AST_Config *pAstCfg;
820 Int as; /* Audio Stream Number (1, 2, etc.) */
821 Int z; /* decode/encode counter */
822 Int s; /* key number */
823 PAF_ASP_Link *that;
825 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
826 as = pAstCfg->as;
827 (void)as; // clear compiler warning in case not used with tracing disabled
829 TRACE_VERBOSE1("PAF_ASOT_initPhaseAlgKey: AS%d: initialization phase - Algorithm Keys", as);
831 for (z=ENCODE1; z < ENCODEN; z++)
832 {
833 for (s=0; s < pP->pEncAlgKey->length; s++)
834 {
835 if ((pP->pEncAlgKey->code[s].full != 0) &&
836 (that = PAF_ASP_chainFind(&pAstCfg->xEnc[z].encChainData, pP->pEncAlgKey->code[s])))
837 {
838 pAstCfg->xEnc[z].encAlg[s] = (ALG_Handle )that->alg;
839 }
840 /* Cast in interface, for now --Kurt */
841 else
842 {
843 pAstCfg->xEnc[z].encAlg[s] = NULL;
844 }
845 }
846 }
848 return 0;
849 } //PAF_ASOT_initPhaseAlgKey
851 // -----------------------------------------------------------------------------
852 // ASOT Initialization Function - I/O Devices
853 //
854 // Name: PAF_ASOT_initPhaseDevice
855 // Purpose: Audio Stream Output Task Function for initialization of I/O Devices.
856 // From: audioStream1Task or equivalent
857 // Uses: See code.
858 // States: x
859 // Return: 0 on success.
860 // Source code line number on device allocation failure.
861 // Trace: Message Log "trace" in Debug Project Configuration reports:
862 // * State information as per parent.
863 // * Memory allocation errors.
864 //
865 Int
866 PAF_ASOT_initPhaseDevice(
867 const PAF_ASOT_Params *pP,
868 const PAF_ASOT_Patchs *pQ,
869 PAF_ASOT_Config *pC
870 )
871 {
872 PAF_AST_Config *pAstCfg;
873 Int as; /* Audio Stream Number (1, 2, etc.) */
874 Int z; /* input/output counter */
875 PAF_SIO_IALG_Obj *pObj;
876 PAF_SIO_IALG_Config *pAlgConfig;
877 PAF_IALG_Config pafAlgConfig;
879 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
880 as = pAstCfg->as;
881 (void)as; // clear compiler warning in case not used with tracing disabled
883 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices", as);
885 if(pP->fxns->bufMemPrint)
886 {
887 PAF_ALG_setup (&pafAlgConfig,
888 HEAP_ID_INTERNAL, HEAP_INTERNAL,
889 HEAP_ID_INTERNAL1, HEAP_INTERNAL1,
890 HEAP_ID_EXTERNAL, HEAP_EXTERNAL,
891 HEAP_ID_INTERNAL1_SHM, HEAP_INTERNAL1_SHM,
892 HEAP_CLEAR);
893 TRACE_TERSE2("PAF_ASOT_initPhaseDevice: AS%d: calling PAF_ALG_setup with clear at %d.", as, HEAP_CLEAR);
894 }
896 for (z=OUTPUT1; z < OUTPUTN; z++)
897 {
898 PAF_OutBufConfig *pConfig = &pAstCfg->xOut[z].outBufConfig;
900 pObj = (PAF_SIO_IALG_Obj *)pAstCfg->xOut[z].outChainData.head->alg;
901 pAlgConfig = &pObj->config;
903 pAstCfg->xOut[z].hTxSio = NULL;
904 pConfig->base.pVoid = pAlgConfig->pMemRec[0].base;
905 pConfig->pntr.pVoid = pAlgConfig->pMemRec[0].base;
906 pConfig->head.pVoid = pAlgConfig->pMemRec[0].base;
907 pConfig->allocation = pAlgConfig->pMemRec[0].size;
908 pConfig->sizeofElement = 3;
909 pConfig->precision = 24;
910 if(pP->fxns->bufMemPrint)
911 {
912 pP->fxns->bufMemPrint(z,pAlgConfig->pMemRec[0].size,PAF_ALG_memSpaceToHeapId(&pafAlgConfig,pAlgConfig->pMemRec[0].space),1);
913 }
914 }
915 TRACE_TERSE1("PAF_ASOT_initPhaseDevice: AS%d: initialization phase - I/O Devices complete.", as);
917 return 0;
918 } //PAF_ASOT_initPhaseDevice
920 // -----------------------------------------------------------------------------
921 // ASOT Initialization Function Helper - Initialization of Audio Frame
922 //
923 // Name: PAF_ASOT_initFrame0
924 // Purpose: Audio Stream Output Task Function for initialization of the Audio
925 // Frame(s) by memory allocation and loading of data pointers
926 // and values.
927 // From: AST Parameter Function -> decodeInfo
928 // Uses: See code.
929 // States: x
930 // Return: 0 on success.
931 // Source code line number on MEM_calloc failure.
932 // Source code line number on unsupported option.
933 // Trace: Message Log "trace" in Debug Project Configuration reports:
934 // * Memory allocation errors.
935 // * Unsupported option errors.
936 //
938 // MID 314
939 extern const char AFChanPtrMap[PAF_MAXNUMCHAN+1][PAF_MAXNUMCHAN];
940 extern PAF_ChannelConfigurationMaskTable PAF_ASP_stdCCMT_patch;
942 Int
943 PAF_ASOT_initFrame0(
944 const PAF_ASOT_Params *pP,
945 const PAF_ASOT_Patchs *pQ,
946 PAF_ASOT_Config *pC,
947 Int z
948 )
949 {
950 PAF_AST_Config *pAstCfg;
951 Int as; /* Audio Stream Number (1, 2, etc.) */
952 Int ch;
953 //Int aLen;
954 Int aLen_int=0,aLen_ext=0;
955 Int aSize = sizeof(PAF_AudioData);
956 Int aAlign = aSize < sizeof (int) ? sizeof (int) : aSize;
957 Int maxFrameLength = pP->maxFramelength;
958 Int zX;
959 PAF_AudioData *aBuf_int=NULL;
960 PAF_AudioData *aBuf_ext=NULL;
961 XDAS_UInt8 *metadataBuf;
962 char i;
963 Error_Block eb;
965 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
966 as = pAstCfg->as;
968 // Initialize error block
969 Error_init(&eb);
971 // Compute maximum framelength (needed for ARC support)
972 maxFrameLength += PA_MODULO - maxFrameLength % PA_MODULO;
973 //aLen = numchan[z] * maxFrameLength;
974 for (i=0; i < numchan[z]; i++)
975 {
976 if (pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
977 {
978 aLen_int += maxFrameLength;
979 }
980 else
981 {
982 aLen_ext += maxFrameLength;
983 }
984 }
986 //
987 // Initialize audio frame elements directly
988 //
989 pAstCfg->xStr[z].pAudioFrame->fxns = pP->pAudioFrameFunctions;
990 pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN; ///
991 /// pAstCfg->xStr[z].pAudioFrame->data.nChannels = PAF_MAXNUMCHAN_AF;
992 pAstCfg->xStr[z].pAudioFrame->data.nSamples = FRAMELENGTH;
993 pAstCfg->xStr[z].pAudioFrame->data.sample = pAstCfg->xStr[z].audioFrameChannelPointers;
994 pAstCfg->xStr[z].pAudioFrame->data.samsiz = pAstCfg->xStr[z].audioFrameChannelSizes;
995 pAstCfg->xStr[z].pAudioFrame->pChannelConfigurationMaskTable = &PAF_ASP_stdCCMT;
997 //
998 // Allocate memory for and initialize pointers to audio data buffers
999 //
1000 // The NUMCHANMASK is used to identify the channels for which data
1001 // buffers can be allocated. Using this mask and switch statement
1002 // rather than some other construct allows efficient code generation,
1003 // providing just the code necessary (with significant savings).
1004 //
1005 if (pP->fxns->bufMemPrint)
1006 {
1007 pP->fxns->bufMemPrint(z, aLen_int*aSize, HEAP_ID_FRMBUF, 2);
1008 pP->fxns->bufMemPrint(z, aLen_ext*aSize, HEAP_ID_EXTERNAL, 2);
1009 }
1011 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for audio buffers", as+z);
1013 if (aLen_int*aSize!=0) // check size != 0, otherwise malloc throws fatal error
1014 {
1015 if (!(aBuf_int = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_FRMBUF, aLen_int*aSize, aAlign, &eb)))
1016 {
1017 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1018 TRACE_TERSE2(" maxFrameLength: %d. aLen_int*aSize: %d", maxFrameLength, aLen_int*aSize);
1019 SW_BREAKPOINT;
1020 return __LINE__;
1021 }
1022 }
1024 if (aLen_ext*aSize!=0)
1025 {
1026 if (!(aBuf_ext = (PAF_AudioData *)Memory_calloc((IHeap_Handle)HEAP_EXTERNAL, aLen_ext*aSize, aAlign, &eb)))
1027 {
1028 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1029 TRACE_TERSE2(" maxFrameLength: %d. aLen_ext*aSize: %d", maxFrameLength, aLen_ext*aSize);
1030 SW_BREAKPOINT;
1031 return __LINE__;
1032 }
1033 }
1035 TRACE_TERSE3(" maxFrameLength: %d. aLen_int*aSize: %d. aBuf_int: 0x%x", maxFrameLength, aLen_int*aSize, (IArg)aBuf_int);
1036 TRACE_TERSE3(" maxFrameLength: %d. aLen_ext*aSize: %d. aBuf_ext: 0x%x", maxFrameLength, aLen_ext*aSize, (IArg)aBuf_ext);
1038 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc for metadata buffers", as+z);
1039 //if (! (metadataBuf = (XDAS_UInt8 *)MEM_calloc (*(pP->pMetadataBufStatus->pSpace), pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment))) {
1040 if (!(metadataBuf = (XDAS_UInt8 *)Memory_calloc((IHeap_Handle)HEAP_MDBUF, pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf, pP->pMetadataBufStatus->alignment, &eb)))
1041 {
1042 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: Memory_calloc failed", as+z);
1043 TRACE_TERSE1(" bufSize*NumBuf: %d", pP->pMetadataBufStatus->bufSize*pP->pMetadataBufStatus->NumBuf);
1044 SW_BREAKPOINT;
1045 return __LINE__;
1046 }
1048 {
1049 Int i;
1051 #pragma UNROLL(1)
1052 for (i=0; i < PAF_MAXNUMCHAN_AF; i++)
1053 {
1054 pAstCfg->xStr[z].audioFrameChannelPointers[i] = NULL;
1055 }
1056 }
1058 // MID 314
1059 if((numchan[z] > PAF_MAXNUMCHAN) || (numchan[z] < 1))
1060 {
1061 TRACE_TERSE1("PAF_ASOT_initFrame0: AS%d: unsupported option", as+z);
1062 return __LINE__;
1063 }
1064 else
1065 {
1066 Int j = 0;
1067 Int k = 0;
1068 TRACE_TERSE1("PAF_ASOT_initFrame0: AFChanPtrMap[%d][i]", numchan[z]);
1069 for(i=0;i<numchan[z];i++)
1070 {
1071 char chan = AFChanPtrMap[numchan[z]][i];
1072 if(chan != -1)
1073 {
1074 if(pP->pAudioFrameBufStatus->space[i] == IALG_SARAM)
1075 {
1076 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_int + maxFrameLength*(j+1) - FRAMELENGTH;
1077 j++;
1078 }
1079 else
1080 {
1081 pAstCfg->xStr[z].audioFrameChannelPointers[chan] = aBuf_ext + maxFrameLength*(k+1) - FRAMELENGTH;
1082 k++;
1083 }
1084 TRACE_TERSE3("PAF_ASOT_initFrame0: chan = %d = AFChanPtrMap[%d][%d].", chan, numchan[z], i);
1085 TRACE_TERSE2("PAF_ASOT_initFrame0: audioFrameChannelPointers[%d]: 0x%x", chan, (IArg)pAstCfg->xStr[z].audioFrameChannelPointers[chan]);
1086 }
1087 }
1088 }
1090 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1091 {
1092 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1093 {
1094 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch] = pAstCfg->xStr[z].audioFrameChannelPointers[ch];
1095 }
1096 }
1098 //
1099 // Initialize meta data elements
1100 //
1101 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1102 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1103 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1104 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1105 pAstCfg->xStr[z].pAudioFrame->privateMetadataBufSize = pP->pMetadataBufStatus->bufSize;
1106 for(i=0;i<pP->pMetadataBufStatus->NumBuf;i++)
1107 {
1108 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1109 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1110 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].pMdBuf = metadataBuf + pP->pMetadataBufStatus->bufSize*i;
1111 }
1113 //
1114 // Initialize decoder elements directly
1115 //
1117 for (zX = DECODE1; zX < DECODEN; zX++)
1118 {
1119 if (pP->streamsFromDecodes[zX] == z)
1120 {
1121 #ifdef NOAUDIOSHARE
1122 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = 0;
1123 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = NULL;
1124 #else /* NOAUDIOSHARE */
1125 pAstCfg->xDec[zX].decodeInStruct.audioShare.nSamples = aLen_int;
1126 pAstCfg->xDec[zX].decodeInStruct.audioShare.sample = aBuf_int;
1127 #endif /* NOAUDIOSHARE */
1128 }
1129 }
1131 return 0;
1132 } //PAF_ASOT_initFrame0
1134 // -----------------------------------------------------------------------------
1135 // ASOT Initialization Function Helper - Reinitialization of Audio Frame
1136 // AST Decoding Function - Reinitialization of Audio Frame
1137 //
1138 // Name: PAF_ASOT_initFrame1
1139 // Purpose: Audio Stream Task Function for initialization or reinitiali-
1140 // zation of the Audio Frame(s) by loading of data values of a
1141 // time-varying nature.
1142 // From: audioStream1Task or equivalent
1143 // AST Parameter Function -> decodeInfo
1144 // AST Parameter Function -> decodeDecode
1145 // Uses: See code.
1146 // States: x
1147 // Return: 0.
1148 // Trace: None.
1149 //
1150 Int
1151 PAF_ASOT_initFrame1(
1152 const PAF_ASOT_Params *pP,
1153 const PAF_ASOT_Patchs *pQ,
1154 PAF_ASOT_Config *pC,
1155 Int z,
1156 Int apply
1157 )
1158 {
1159 PAF_AST_Config *pAstCfg;
1161 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1163 //
1164 // Reinitialize audio frame elements:
1165 //
1166 // Channel Configurations during sys init = Unknown
1167 // " " during info or decode = None
1168 //
1169 // Sample Rate / Count during sys init, info or decode = Unknown / 0
1170 //
1172 if (apply < 0)
1173 {
1174 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_UNKNOWN;
1175 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_UNKNOWN;
1176 }
1177 else
1178 {
1179 pAstCfg->xStr[z].pAudioFrame->channelConfigurationRequest.legacy = PAF_CC_NONE;
1180 pAstCfg->xStr[z].pAudioFrame->channelConfigurationStream.legacy = PAF_CC_NONE;
1181 }
1183 if (apply < 1)
1184 {
1185 pAstCfg->xStr[z].pAudioFrame->sampleRate = PAF_SAMPLERATE_UNKNOWN;
1186 pAstCfg->xStr[z].pAudioFrame->sampleCount = 0;
1187 }
1189 return 0;
1190 } //PAF_ASOT_initFrame1
1192 // -----------------------------------------------------------------------------
1193 // ASOT Selection Function - Output Device Selection
1194 //
1195 // Name: PAF_ASOT_selectDevices
1196 // Purpose: Audio Stream Output Task Function for selecting the devices used
1197 // for output.
1198 // From: audioStream1Task or equivalent
1199 // Uses: See code.
1200 // States: x
1201 // Return: Error number in standard form (0 on success).
1202 // Trace: Message Log "trace" in Debug Project Configuration reports:
1203 // * State information as per parent.
1204 //
1205 Int
1206 PAF_ASOT_selectDevices(
1207 const PAF_ASOT_Params *pP,
1208 const PAF_ASOT_Patchs *pQ,
1209 PAF_ASOT_Config *pC
1210 )
1211 {
1212 PAF_AST_Config *pAstCfg;
1213 Int as; /* Audio Stream Number (1, 2, etc.) */
1214 Int z; /* input/output counter */
1215 Int errno = 0; /* error number */
1216 Int errme; /* error number, local */
1217 Int device;
1219 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1220 as = pAstCfg->as;
1221 (void)as; // clear compiler warning in case not used with tracing disabled
1223 // Select output devices
1224 for (z=OUTPUT1; z < OUTPUTN; z++)
1225 {
1226 if ((device = pAstCfg->xOut[z].outBufStatus.sioSelect) >= 0)
1227 {
1228 TRACE_VERBOSE2("PAF_ASOT_selectDevices: AS%d: output device %d selecting ...", as+z, device);
1230 /* check for valid index into device array */
1231 if (device >= pQ->devout->n)
1232 {
1233 device = 0; /* treat as device None */
1234 }
1236 errme = pP->fxns->deviceSelect(&pAstCfg->xOut[z].hTxSio, SIO_OUTPUT,
1237 HEAP_ID_OUTBUF, (Ptr)pQ->devout->x[device]);
1238 if (errme)
1239 {
1240 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1241 if (!errno)
1242 {
1243 errno = ASPERR_DEVOUT + errme;
1244 }
1245 pAstCfg->xOut[z].outBufStatus.sioSelect = 0x80;
1246 }
1247 else
1248 {
1249 Int zE;
1251 pAstCfg->xOut[z].outBufStatus.sioSelect = device | 0x80;
1252 // register outBufStatus and encodeStatus pointers with output devices
1253 // This enables proper IEC encapsulation.
1254 if (pAstCfg->xOut[z].hTxSio)
1255 {
1256 // set max # of output buffers (use override if necessary)
1257 if (pAstCfg->xOut[z].outBufStatus.maxNumBufOverride == 0)
1258 {
1259 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1260 (Arg)pP->poutNumBufMap[z]->maxNumBuf);
1261 }
1262 else
1263 {
1264 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_MAX_NUMBUF,
1265 (Arg)pAstCfg->xOut[z].outBufStatus.maxNumBufOverride);
1266 }
1268 // register PAF_SIO_IALG object address
1269 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_IALGADDR,
1270 (Arg)pAstCfg->xOut[z].outChainData.head->alg);
1271 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_BUFSTATUSADDR,
1272 (Arg)&pAstCfg->xOut[z].outBufStatus);
1273 for (zE=ENCODE1; zE < ENCODEN; zE++)
1274 {
1275 if (pP->outputsFromEncodes[zE] == z)
1276 {
1277 SIO_ctrl(pAstCfg->xOut[z].hTxSio,
1278 PAF_SIO_CONTROL_SET_ENCSTATUSADDR,
1279 (Arg)&pAstCfg->xEnc[zE].encodeStatus);
1280 break;
1281 }
1282 }
1283 }
1284 }
1285 }
1287 // if device selected and valid then enable stat tracking if
1288 // required and start clocking
1289 if ((pAstCfg->xOut[z].outBufStatus.sioSelect < 0) && (pAstCfg->xOut[z].hTxSio))
1290 {
1291 TRACE_VERBOSE0("PAF_ASOT_selectDevices: start SIO clocks");
1292 errme = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_OUTPUT_START_CLOCKS, 0);
1293 if (errme)
1294 {
1295 TRACE_VERBOSE2("PAF_ASOT_selectDevices: errme 0x%x, errno 0x%x", errme, errno);
1296 SIO_idle(pAstCfg->xOut[z].hTxSio);
1297 if (!errno)
1298 {
1299 errno = ASPERR_DEVOUT + errme;
1300 }
1301 }
1302 }
1303 }
1305 return errno;
1306 } //PAF_ASOT_selectDevices
1308 // -----------------------------------------------------------------------------
1309 // ASOT Processing Function - Decode Processing
1310 //
1311 // Name: PAF_ASOT_decodeProcessing
1312 // Purpose: Audio Stream Output Task Function for processing audio data.
1313 //
1314 Int
1315 PAF_ASOT_decodeProcessing(
1316 const PAF_ASOT_Params *pP,
1317 const PAF_ASOT_Patchs *pQ,
1318 PAF_ASOT_Config *pC,
1319 Int sourceSelect
1320 )
1321 {
1322 PAF_AST_Config *pAstCfg;
1323 Int z; /* decode counter */
1324 Int errno; /* error number */
1325 Int getVal;
1326 enum { INIT, STREAM, ENCODE, FINAL, QUIT } state;
1327 state = INIT;
1328 errno = 0; /* error number */
1329 Int frame; // (***) FL: formerly -- decoder input frame count
1330 Int block; // decoder output block count / input frame
1331 Int outSioUpdate;
1333 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1335 for (;;)
1336 {
1337 // FL: Check if any change in output SIO, e.g. from Output shortcut.
1338 // Changes will break FSM and allow Output reconfiguration.
1339 if (errno = checkOutSio(pP, pC, &outSioUpdate))
1340 {
1341 TRACE_TERSE1("PAF_ASOT_decodeProcessing: checkOutSio returned errno = 0x%04x", errno);
1342 break;
1343 }
1344 else if (outSioUpdate)
1345 {
1346 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Change in Output SIO selection");
1347 state = QUIT;
1348 }
1350 // Process commands (encode)
1351 if (getVal = pP->fxns->encodeCommand(pP, pQ, pC))
1352 {
1353 /* ignore */;
1354 }
1356 // Process state (decode)
1357 switch (state)
1358 {
1359 case INIT: // initial state
1360 gAsopInitCnt++;
1361 Log_info0("TaskAsop: state=INIT");
1363 // Reset audio frame pointers to original values
1364 // (may be needed if error occurred).
1365 for (z=STREAM1; z < STREAMN; z++)
1366 {
1367 Int ch;
1368 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1369 {
1370 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1371 {
1372 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1373 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1374 }
1375 }
1376 }
1378 // Reset audio frame meta data elements
1379 {
1380 Int i;
1382 for (z=STREAM1; z < STREAMN; z++)
1383 {
1384 pAstCfg->xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1385 pAstCfg->xStr[z].pAudioFrame->numPrivateMetadata = 0;
1386 pAstCfg->xStr[z].pAudioFrame->bsMetadata_offset = 0;
1387 pAstCfg->xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1389 for (i=0; i<pP->pMetadataBufStatus->NumBuf; i++)
1390 {
1391 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1392 pAstCfg->xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1393 }
1394 }
1395 }
1397 if (errno = pP->fxns->decodeInit(pP, pQ, pC, sourceSelect))
1398 {
1399 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInit", errno);
1400 break;
1401 }
1403 // (***) FL: setup output (ASP chain reset, ENC reset, setCheckRateX, start output)
1404 // Contained in INFO1 in combined FSM.
1405 // Establish secondary timing
1406 if (errno = pP->fxns->decodeInfo1(pP, pQ, pC, frame, block))
1407 {
1408 TRACE_VERBOSE1("PAF_ASOT_decodeProcessing: INIT, errno 0x%x. break after decodeInfo1", errno);
1409 break;
1410 }
1412 frame = 0;
1413 block = 0;
1415 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: INIT->STREAM");
1416 state = STREAM;
1417 continue;
1419 case STREAM: // stream state
1420 gAsopStreamCnt++;
1421 Log_info0("TaskAsop: state=STREAM");
1423 if (errno = pP->fxns->decodeStream(pP, pQ, pC, frame, block))
1424 {
1425 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: STREAM. decodeStream err 0x%x", errno);
1426 break;
1427 }
1429 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: STREAM->ENCODE");
1430 state = ENCODE;
1431 continue;
1433 case ENCODE: // encode state
1434 gAsopEncodeCnt++;
1435 Log_info0("TaskAsop: state=ENCODE");
1437 if (errno = pP->fxns->decodeEncode(pP, pQ, pC, frame, block))
1438 {
1439 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: ENCODE. decodeEncode err 0x%x", errno);
1440 break;
1441 }
1443 // (***) FL: do we need this?
1444 // AF pointers come from CB read, any resets occur in Decoder AF.
1445 // Reset audio frame pointers to original values
1446 // (may have been adjusted by ARC or the like).
1447 for (z=STREAM1; z < STREAMN; z++)
1448 {
1449 Int ch;
1450 for (ch=PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
1451 {
1452 if (pAstCfg->xStr[z].audioFrameChannelPointers[ch])
1453 {
1454 pAstCfg->xStr[z].audioFrameChannelPointers[ch] =
1455 pAstCfg->xStr[z].origAudioFrameChannelPointers[ch];
1456 }
1457 }
1458 }
1460 //
1461 // (***) FL: update output (setCheckRateX)
1462 // Contained in INFO2 in combined FSM.
1463 if (errno = pP->fxns->decodeInfo2(pP, pQ, pC, frame, block))
1464 {
1465 TRACE_TERSE1("PAF_ASOT_decodeProcessing: ENCODE break on decodeInfo2. errno 0x%x", errno);
1466 break;
1467 }
1469 block++;
1470 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: ENCODE->FINAL");
1471 state = FINAL;
1472 continue;
1474 case FINAL:
1475 gAsopFinalCnt++;
1476 Log_info0("TaskAsop: state=FINAL");
1478 //
1479 // (***) FL: this needs to be fixed.
1480 // (1) Only require selected Output to be in this FSM
1481 // => Dec Status checks aren't valid,
1482 // will probably always exit FSM if only Output running
1483 // (2) Checking Dec Status info asych to input events (maybe ok)
1484 //
1485 #if 0
1486 // Check for final frame, and if indicated:
1487 // - Update audio flag to cause output buffer flush rather than
1488 // the default truncate in "complete" processing.
1489 // - Exit state machine to "complete" processing.
1490 if (pP->fxns->decodeFinalTest(pP, pQ, pC, frame, block))
1491 {
1492 for (z=OUTPUT1; z < OUTPUTN; z++)
1493 {
1494 if ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND)
1495 {
1496 TRACE_VERBOSE0("PAF_ASOT_outputProcessing: state: FINAL: SOUND -> QUIET");
1497 pAstCfg->xOut[z].outBufStatus.audio++; // SOUND -> QUIET
1498 }
1499 }
1500 break;
1501 }
1502 #endif
1504 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: FINAL->STREAM");
1505 state = STREAM;
1506 continue;
1508 case QUIT:
1509 gAsopQuitCnt++;
1510 Log_info0("TaskAsop: state=QUIT");
1512 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: state: QUIT");
1513 errno = ASPERR_QUIT;
1514 break;
1516 default: // unknown state
1517 // Unknown:
1518 // - Set error number registers.
1519 // - Exit state machine to "complete" processing.
1521 TRACE_TERSE1("PAF_ASOT_decodeProcessing: state: unknown, 0x%x", state);
1522 errno = ASPERR_UNKNOWNSTATE;
1523 break;
1525 } // End of switch (state).
1527 TRACE_VERBOSE0("PAF_ASOT_decodeProcessing: Calling decode complete");
1528 if (pP->fxns->decodeComplete(pP, pQ, pC, NULL, frame, block))
1529 {
1530 /* ignored? */;
1531 }
1533 return errno;
1534 } // End of for (;;)
1536 return errno;
1537 }
1539 // -----------------------------------------------------------------------------
1540 // ASOT Decoding Function - Encode Command Processing
1541 //
1542 // Name: PAF_ASOT_encodeCommand
1543 // Purpose: Decoding Function for processing Encode Commands.
1544 // From: AST Parameter Function -> decodeProcessing
1545 // Uses: See code.
1546 // States: x
1547 // Return: 0.
1548 // Trace: Message Log "trace" in Debug Project Configuration reports:
1549 // * Command execution.
1550 // * SIO control errors.
1551 // * Error number macros.
1552 //
1553 Int
1554 PAF_ASOT_encodeCommand(
1555 const PAF_ASOT_Params *pP,
1556 const PAF_ASOT_Patchs *pQ,
1557 PAF_ASOT_Config *pC
1558 )
1559 {
1560 PAF_AST_Config *pAstCfg;
1561 Int as; /* Audio Stream Number (1, 2, etc.) */
1562 Int z; /* encode counter */
1563 Int errno = 0; /* error number */
1564 Int zO, zS;
1567 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1568 as = pAstCfg->as;
1570 for (z=ENCODE1; z < ENCODEN; z++)
1571 {
1572 zO = pP->outputsFromEncodes[z];
1573 zS = pP->streamsFromEncodes[z];
1574 if (! (pAstCfg->xEnc[z].encodeStatus.command2 & 0x80))
1575 {
1576 switch (pAstCfg->xEnc[z].encodeStatus.command2)
1577 {
1578 case 0: // command none - process
1579 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1580 break;
1581 case 1: // mute command
1582 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command mute (0x%02x)", as+zS, 1);
1583 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1584 && pAstCfg->xOut[zO].hTxSio
1585 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
1586 {
1587 errno = (errno & 0xff) | ASPERR_MUTE;
1588 /* convert to sensical errno */
1589 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (mute)", as+zS);
1590 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1591 }
1592 else
1593 {
1594 pAstCfg->xOut[zO].outBufStatus.audio |= PAF_OB_AUDIO_MUTED;
1595 }
1596 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1597 break;
1598 case 2: // unmute command
1599 TRACE_VERBOSE2("AS%d: PAF_ASOT_encodeCommand: encode command unmute (0x%02x)", as+zS, 2);
1600 if ((pAstCfg->xOut[zO].outBufStatus.audio & 0x0f) != PAF_OB_AUDIO_QUIET
1601 && pAstCfg->xOut[zO].hTxSio
1602 && (errno = SIO_ctrl (pAstCfg->xOut[zO].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
1603 {
1604 errno = (errno & 0xff) | ASPERR_MUTE;
1605 /* convert to sensical errno */
1606 TRACE_TERSE1("AS%d: PAF_ASOT_encodeCommand: SIO control failed (unmute)", as+zS);
1607 TRACE_TERSE2("AS%d: PAF_ASOT_encodeCommand: errno = 0x%04x <ignored>", as+zS, errno);
1608 }
1609 else
1610 {
1611 pAstCfg->xOut[zO].outBufStatus.audio &= ~PAF_OB_AUDIO_MUTED;
1612 }
1613 pAstCfg->xEnc[z].encodeStatus.command2 |= 0x80;
1614 break;
1615 default: // command unknown - ignore
1616 break;
1617 }
1618 }
1619 }
1621 ERRNO_RPRT (TaskAsop, errno);
1623 return 0;
1624 } //PAF_ASOT_encodeCommand
1626 // Purpose: Decoding Function for reinitializing the decoding process.
1627 Int
1628 PAF_ASOT_decodeInit(
1629 const PAF_ASOT_Params *pP,
1630 const PAF_ASOT_Patchs *pQ,
1631 PAF_ASOT_Config *pC,
1632 Int sourceSelect
1633 )
1634 {
1635 PAF_AST_Config *pAstCfg;
1636 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1637 Int as; /* Audio Stream Number (1, 2, etc.) */
1638 Int z; /* decode/encode counter */
1639 Int errno; /* error number */
1640 Int zO, zS;
1643 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1644 as = pAstCfg->as;
1646 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1648 for (z=DECODE1; z < DECODEN; z++)
1649 {
1650 // Start decoder output circular buffer reads
1651 errno = cbReadStart(pCbCtl, z);
1652 if (errno)
1653 {
1654 TRACE_TERSE1("PAF_ASOT_decodeInit:cbReadStart() error=%d", errno);
1655 SW_BREAKPOINT; // FL: debug
1656 return errno;
1657 }
1658 // FL: debug
1659 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeInit:cbReadStart");
1660 }
1662 // TODO: move this to start of this function so that it doesn't affect IO timing
1663 for (z=ENCODE1; z < ENCODEN; z++)
1664 {
1665 zO = pP->outputsFromEncodes[z];
1666 zS = pP->streamsFromEncodes[z];
1667 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1668 {
1669 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1670 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1671 ENC_Handle enc = (ENC_Handle )encAlg;
1672 TRACE_VERBOSE1("AS%d: PAF_ASOT_decodeInit: initializing encode", as+zS);
1673 if (encAlg->fxns->algActivate)
1674 {
1675 encAlg->fxns->algActivate (encAlg);
1676 }
1677 if (enc->fxns->reset
1678 && (errno = enc->fxns->reset(enc, NULL,
1679 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1680 {
1681 return errno;
1682 }
1683 }
1684 }
1686 return 0;
1687 }
1689 // -----------------------------------------------------------------------------
1690 // ASOT Decoding Function - Info Processing, Initial
1691 //
1692 // Name: PAF_ASOT_decodeInfo1
1693 // Purpose: Decoding Function for processing information in a manner that
1694 // is unique to initial frames of input data.
1695 // From: AST Parameter Function -> decodeProcessing
1696 // Uses: See code.
1697 // States: x
1698 // Return: Error number in standard or SIO form (0 on success).
1699 // Trace: Message Log "trace" in Debug Project Configuration reports:
1700 // * State information as per parent.
1701 //
1702 Int
1703 PAF_ASOT_decodeInfo1(
1704 const PAF_ASOT_Params *pP,
1705 const PAF_ASOT_Patchs *pQ,
1706 PAF_ASOT_Config *pC,
1707 Int frame,
1708 Int block
1709 )
1710 {
1711 PAF_AST_Config *pAstCfg;
1712 Int z; /* decode/encode counter */
1713 Int errno; /* error number */
1715 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1717 // run the chain of ASP's on the stream.
1718 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling streamChainFunction.");
1719 if (errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1720 PAF_ASP_CHAINFRAMEFXNS_RESET, 1, frame))
1721 {
1722 TRACE_TERSE1("PAF_ASOT_decodeInfo1: streamChainFunction returns errno 0x%x ", errno);
1723 return errno;
1724 }
1726 TRACE_VERBOSE0("PAF_ASOT_decodeInfo1: calling enc->info.");
1727 for (z=ENCODE1; z < ENCODEN; z++)
1728 {
1729 Int zO = pP->outputsFromEncodes[z];
1730 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1731 {
1732 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1733 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1734 ENC_Handle enc = (ENC_Handle )encAlg;
1735 if (enc->fxns->info
1736 && (errno = enc->fxns->info(enc, NULL,
1737 &pAstCfg->xEnc[z].encodeControl, &pAstCfg->xEnc[z].encodeStatus)))
1738 {
1739 TRACE_TERSE1("PAF_ASOT_decodeInfo1: info returns errno 0x%x ", errno);
1740 return errno;
1741 }
1742 }
1743 }
1745 if (errno = pP->fxns->setCheckRateX(pP, pQ, pC, 0))
1746 {
1747 // ignore if rateX has changed since we haven't, but are about to,
1748 // start the output. If we didn't ignore this case then the state machine
1749 // would restart unnecessarily, e.g. in the case of SRC, resulting in
1750 // added latency.
1751 if (errno != ASPERR_INFO_RATECHANGE)
1752 {
1753 TRACE_TERSE1("PAF_ASOT_decodeInfo1: setCheckRateX returns errno 0x%x, not RATECHANGE", errno);
1754 return errno;
1755 }
1756 else
1757 {
1758 TRACE_TERSE0("PAF_ASOT_decodeInfo1: RATECHANGE returns RATECHANGE, ignoring");
1759 }
1760 }
1762 if (errno = pP->fxns->startOutput(pP, pQ, pC))
1763 {
1764 if (errno == 0x105)
1765 {
1766 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns RING BUFFER FULL (0x%x)", errno);
1767 }
1768 else
1769 {
1770 TRACE_TERSE1("PAF_ASOT_decodeInfo1: startOutput returns errno 0x%x", errno);
1771 }
1772 return errno;
1773 }
1775 return 0;
1776 }
1778 // -----------------------------------------------------------------------------
1779 // ASOT Decoding Function - Info Processing, Subsequent
1780 //
1781 // Name: PAF_ASOT_decodeInfo2
1782 // Purpose: Decoding Function for processing information in a manner that
1783 // is unique to frames of input data other than the initial one.
1784 // From: AST Parameter Function -> decodeProcessing
1785 // Uses: See code.
1786 // States: x
1787 // Return: Error number in standard form (0 on success).
1788 // Trace: None.
1789 //
1790 Int
1791 PAF_ASOT_decodeInfo2(
1792 const PAF_ASOT_Params *pP,
1793 const PAF_ASOT_Patchs *pQ,
1794 PAF_ASOT_Config *pC,
1795 Int frame,
1796 Int block
1797 )
1798 {
1799 //PAF_AST_Config *pAstCfg;
1800 Int errno;
1803 //pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1805 errno = pP->fxns->setCheckRateX (pP, pQ, pC, 1);
1806 TRACE_VERBOSE1("PAF_ASOT_decodeInfo2: return 0x%x", errno);
1807 return errno;
1808 } //PAF_ASOT_decodeInfo2
1810 // -----------------------------------------------------------------------------
1811 // ASOT Decoding Function - Stream Processing
1812 //
1813 // Name: PAF_ASOT_decodeStream
1814 // Purpose: Decoding Function for processing of audio frame data by the
1815 // ASP Algorithms.
1816 // From: AST Parameter Function -> decodeProcessing
1817 // Uses: See code.
1818 // States: x
1819 // Return: Error number in standard form (0 on success).
1820 // Trace: Message Log "trace" in Debug Project Configuration reports:
1821 // * State information as per parent/child.
1822 //
1823 Int
1824 PAF_ASOT_decodeStream(
1825 const PAF_ASOT_Params *pP,
1826 const PAF_ASOT_Patchs *pQ,
1827 PAF_ASOT_Config *pC,
1828 Int frame,
1829 Int block
1830 )
1831 {
1832 PAF_AST_Config *pAstCfg;
1833 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
1834 Int z; /* decode/stream counter */
1835 PAF_AudioFrame *pAfRd;
1836 Int cbErrno;
1837 Int errno;
1840 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1842 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
1844 for (z=DECODE1; z < DECODEN; z++)
1845 {
1846 Int zS = pP->streamsFromDecodes[z];
1848 //
1849 // Read decoder output circular buffer
1850 //
1851 pAfRd = pAstCfg->xStr[zS].pAudioFrame;
1852 cbErrno = cbReadAf(pCbCtl, z, pAfRd);
1853 if (cbErrno != 0)
1854 {
1855 TRACE_TERSE1("PAF_ASOT_decodeStream:cbReadAf() error=%d", cbErrno);
1856 //SW_BREAKPOINT; // FL: debug
1858 if (cbErrno == ASP_DECOP_CB_READ_UNDERFLOW)
1859 {
1860 // Reset circular buffer
1861 cbReset(pCbCtl, z);
1863 // Update underflow count, return if above threshold
1864 gDecOpCbRdAfUnd++;
1865 if (gDecOpCbRdAfUnd == DEC_OP_CB_RDAF_UND_THR)
1866 {
1867 gDecOpCbRdAfUnd = 0;
1868 return cbErrno;
1869 }
1870 }
1871 }
1872 //Log_info0("PAF_ASOT_decodeStream:cbReadAf() complete.");
1874 // FL: debug
1875 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeStream:cbReadAf");
1876 //if (capAfWrite(pAfRd, 0) != CAP_AF_SOK)
1877 //{
1878 // Log_info0("capAfWrite() error");
1879 //}
1880 }
1882 TRACE_VERBOSE0("PAF_ASOT_outputStream: calling streamChainFunction.");
1883 errno = pP->fxns->streamChainFunction(pP, pQ, pC,
1884 PAF_ASP_CHAINFRAMEFXNS_APPLY, 1, block);
1885 if (errno)
1886 {
1887 TRACE_TERSE1("PAF_ASOT_outputStream: streamChainFunction returns errno 0x%x ", errno);
1888 return errno;
1889 }
1891 return 0;
1893 } //PAF_ASOT_decodeStream
1895 // -----------------------------------------------------------------------------
1896 // ASOT Decoding Function - Encode Processing
1897 //
1898 // Name: PAF_ASOT_decodeEncode
1899 // Purpose: Decoding Function for processing of audio frame data by the
1900 // Encode Algorithm.
1901 // From: AST Parameter Function -> decodeProcessing
1902 // Uses: See code.
1903 // States: x
1904 // Return: Error number in standard or SIO form (0 on success).
1905 // Trace: Message Log "trace" in Debug Project Configuration reports:
1906 // * State information as per parent.
1907 //
1908 Int
1909 PAF_ASOT_decodeEncode(
1910 const PAF_ASOT_Params *pP,
1911 const PAF_ASOT_Patchs *pQ,
1912 PAF_ASOT_Config *pC,
1913 Int frame,
1914 Int block
1915 )
1916 {
1917 PAF_AST_Config *pAstCfg;
1918 Int as; /* Audio Stream Number (1, 2, etc.) */
1919 Int z; /* encode/output counter */
1920 Int errno; /* error number */
1921 Int zX, zE, zS;
1922 UInt32 curTime;
1924 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
1925 as = pAstCfg->as;
1927 // Await output buffers (but not first time)
1928 for (z=OUTPUT1; z < OUTPUTN; z++)
1929 {
1930 // determine encoder associated with this output
1931 zE = z;
1932 for (zX = ENCODE1; zX < ENCODEN; zX++)
1933 {
1934 if (pP->outputsFromEncodes[zX] == z)
1935 {
1936 zE = zX;
1937 break;
1938 }
1939 }
1940 zS = pP->streamsFromEncodes[zE];
1942 if (pAstCfg->xOut[z].hTxSio)
1943 {
1944 // update length (e.g. ARC may have changed)
1945 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
1946 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
1947 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- idle", as+zS, block);
1948 errno = SIO_reclaim(pAstCfg->xOut[z].hTxSio,(Ptr *) &pAstCfg->xOut[z].pOutBuf, NULL);
1949 if (errno < 0)
1950 {
1951 SIO_idle(pAstCfg->xOut[z].hTxSio);
1952 TRACE_TERSE2("PAF_ASOT_decodeEncode: AS%d: SIO_reclaim returns error %d", as+zS, -errno);
1953 return -errno; // SIO negates error codes
1954 }
1955 // TODO: use pC->xOut[z].pOutBuf in following ->encode call
1957 //
1958 // Simulate Tx SIO_reclaim() pend
1959 //
1960 //Semaphore_pend(semaphoreTxAudio, BIOS_WAIT_FOREVER);
1961 gTaskAsopCnt++;
1962 curTime = Clock_getTicks();
1963 //System_printf("System time in TaskAsipFxn Tx audio = %lu\n", (ULong)curTime);
1964 //Log_info1("outputEncode():Tx SIO reclaim(), system time = %u", curTime);
1965 }
1966 else
1967 {
1968 TRACE_VERBOSE2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- idle <ignored>", as+zS, block);
1969 }
1970 }
1972 // Encode data
1973 for (z=ENCODE1; z < ENCODEN; z++)
1974 {
1975 Int zO = pP->outputsFromEncodes[z];
1976 Int zS = pP->streamsFromEncodes[z];
1977 (void)zS; // clear compiler warning in case not used with tracing disabled
1978 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
1979 {
1980 Int select = pAstCfg->xEnc[z].encodeStatus.select;
1981 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
1982 ENC_Handle enc = (ENC_Handle )encAlg;
1983 if (select != pAstCfg->xEnc[z].encodeControl.encActive)
1984 {
1985 pAstCfg->xEnc[z].encodeControl.encActive = select;
1986 TRACE_TERSE0("PAF_ASOT_decodeEncode: return error");
1987 return (-1);
1988 }
1989 TRACE_GEN2("AS%d: PAF_ASOT_decodeEncode: processing block %d -- encode", as+zS, block);
1991 // (MID 1933) temp. workaround for PCE2
1992 pAstCfg->xEnc[z].encodeInStruct.pAudioFrame->data.nChannels = PAF_MAXNUMCHAN;
1994 /*
1995 #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
1996 {
1997 PAF_AudioFrame *pAudioFrame = pC->xEnc[z].encodeInStruct.pAudioFrame;
1998 int *wp;
1999 wp = (int*)pAudioFrame->data.sample[0];
2000 TRACE_DATA((&TR_MOD, "as1-f2: AS%d PAF_ASOT_outputEncode: encoding from ch 0 0x%x. line %d", z, wp, __LINE__));
2001 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch0)", wp[0], wp[16], wp[99]));
2002 wp = (int*)pAudioFrame->data.sample[1];
2003 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 1 0x%x. line %d", wp, __LINE__));
2004 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch1)", wp[0], wp[16], wp[99]));
2005 wp = (int*)pAudioFrame->data.sample[2];
2006 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoding from ch 2 0x%x. line %d", wp, __LINE__));
2007 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x (ch2)", wp[0], wp[16], wp[99]));
2008 }
2009 #endif
2010 */
2012 if (enc->fxns->encode)
2013 {
2014 pAstCfg->xEnc[z].encodeOutStruct.bypassFlag =
2015 pP->z_pEncodeStatus[z]->encBypass;
2016 if (errno = enc->fxns->encode(enc, NULL,
2017 &pAstCfg->xEnc[z].encodeInStruct, &pAstCfg->xEnc[z].encodeOutStruct))
2018 {
2019 if (errno != PCEERR_OUTPUT_POINTERNULL)
2020 {
2021 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error %d line %d", errno);
2022 return errno;
2023 }
2024 }
2025 /* #if (CURRENT_TRACE_MASK & TRACE_MASK_DATA)
2026 else
2027 {
2028 int *wp = (int*)pC->xOut[z].pOutBuf->pntr.pVoid;
2029 TRACE_DATA((&TR_MOD, "as1-f2: PAF_ASOT_outputEncode: encoded to 0x%x. line %d", wp, __LINE__));
2030 TRACE_DATA((&TR_MOD, "as1-f2: [0]: 0x%x, [16]: 0x%x, [99]: 0x%x", wp[0], wp[16], wp[99]));
2031 }
2032 #endif
2033 */
2034 }
2035 }
2036 else
2037 {
2038 TRACE_VERBOSE2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- encode <ignored>",
2039 as+pP->streamsFromEncodes[z], block);
2040 }
2041 }
2043 // Transmit data
2044 for (z=OUTPUT1; z < OUTPUTN; z++)
2045 {
2046 // determine encoder associated with this output
2047 zE = z;
2048 for (zX = ENCODE1; zX < ENCODEN; zX++)
2049 {
2050 if (pP->outputsFromEncodes[zX] == z)
2051 {
2052 zE = zX;
2053 break;
2054 }
2055 }
2056 zS = pP->streamsFromEncodes[zE];
2058 if (pAstCfg->xOut[z].hTxSio)
2059 {
2060 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output", as+zS, block);
2061 errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2062 &pAstCfg->xOut[z].outBufConfig, sizeof (pAstCfg->xOut[z].outBufConfig), 0);
2063 if (errno)
2064 {
2065 SIO_idle(pAstCfg->xOut[z].hTxSio);
2066 if (errno == 0x105) // 0x105 == RINGIO_EBUFFULL
2067 {
2068 // statStruct_LogFullRing(STATSTRUCT_AS1_F2);
2069 TRACE_TERSE1("PAF_ASOT_decodeEncode: SIO_idle returned RINGIO_EBUFFULL (0x%x)", errno);
2070 }
2071 if (errno > 0)
2072 {
2073 TRACE_TERSE1("PAF_ASOT_decodeEncode: return error 0x%x line %d", errno);
2074 return (ASPERR_ISSUE + (z << 4));
2075 }
2076 else if (errno < 0)
2077 {
2078 TRACE_TERSE1("PAF_ASOT_decodeEncode: return neg error 0x%x line %d", -errno);
2079 return -errno; // SIO negates error codes
2080 }
2081 }
2082 if (errno > 0)
2083 {
2084 return (ASPERR_ISSUE + (z << 4));
2085 }
2086 else if (errno < 0)
2087 {
2088 return -errno; // SIO negates error codes
2089 }
2090 }
2091 else
2092 {
2093 TRACE_GEN2("PAF_ASOT_decodeEncode: AS%d: processing block %d -- output <ignored>", as+zS, block);
2094 }
2095 }
2097 return 0;
2098 } //PAF_ASOT_decodeEncode
2100 // -----------------------------------------------------------------------------
2101 // ASOT Decoding Function - Stream-Final Processing
2102 //
2103 // Name: PAF_ASOT_decodeComplete
2104 // Purpose: Decoding Function for terminating the decoding process.
2105 // From: AST Parameter Function -> decodeProcessing
2106 // Uses: See code.
2107 // States: x
2108 // Return: 0.
2109 // Trace: Message Log "trace" in Debug Project Configuration reports:
2110 // * State information as per parent.
2111 //
2112 Int
2113 PAF_ASOT_decodeComplete(
2114 const PAF_ASOT_Params *pP,
2115 const PAF_ASOT_Patchs *pQ,
2116 PAF_ASOT_Config *pC,
2117 ALG_Handle decAlg[],
2118 Int frame,
2119 Int block
2120 )
2121 {
2122 PAF_AST_Config *pAstCfg;
2123 PAF_AST_DecOpCircBufCtl *pCbCtl; /* Decoder output circular buffer control */
2124 Int as; /* Audio Stream Number (1, 2, etc.) */
2125 Int z; /* decode/encode counter */
2126 Int errno; /* error number */
2129 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2130 as = pAstCfg->as;
2131 (void)as; // clear compiler warning in case not used with tracing disabled
2133 pCbCtl = &pC->pAspmCfg->decOpCircBufCtl; // get pointer to circular buffer control
2135 for (z=DECODE1; z < DECODEN; z++)
2136 {
2137 // Stop decoder output circular buffer reads
2138 errno = cbReadStop(pCbCtl, z);
2139 if (errno)
2140 {
2141 TRACE_TERSE1("PAF_ASOT_decodeComplete:cbReadStop() error=%d", errno);
2142 SW_BREAKPOINT; // FL: debug
2143 return errno;
2144 }
2145 // FL: debug
2146 cbLog(pCbCtl, z, 1, "PAF_ASOT_decodeComplete:cbReadStop");
2147 }
2149 pP->fxns->streamChainFunction(pP, pQ, pC, PAF_ASP_CHAINFRAMEFXNS_FINAL, 0, frame);
2151 for (z=ENCODE1; z < ENCODEN; z++)
2152 {
2153 Int zO = pP->outputsFromEncodes[z];
2154 if (pAstCfg->xOut[zO].hTxSio && pAstCfg->xEnc[z].encodeStatus.mode)
2155 {
2156 Int select = pAstCfg->xEnc[z].encodeStatus.select;
2157 ALG_Handle encAlg = pAstCfg->xEnc[z].encAlg[select];
2158 #ifdef PAF_ASP_FINAL
2159 ENC_Handle enc = (ENC_Handle)encAlg;
2160 #endif /* PAF_ASP_FINAL */
2161 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode", as+z);
2162 #ifdef PAF_ASP_FINAL
2163 if (enc->fxns->final)
2164 enc->fxns->final(enc, NULL, &pAstCfg->xEnc[z].encodeControl,
2165 &pAstCfg->xEnc[z].encodeStatus);
2166 #endif /* PAF_ASP_FINAL */
2167 if (encAlg->fxns->algDeactivate)
2168 {
2169 encAlg->fxns->algDeactivate(encAlg);
2170 }
2171 }
2172 else
2173 {
2174 TRACE_VERBOSE1("PAF_ASOT_decodeComplete: AS%d: finalizing encode <ignored>", as+z);
2175 }
2176 }
2178 // wait for remaining data to be output
2179 pP->fxns->stopOutput(pP, pQ, pC);
2181 return 0;
2182 } //PAF_ASOT_decodeComplete
2184 // -----------------------------------------------------------------------------
2185 // ASOT Decoding Function Helper - SIO Driver Start
2186 //
2187 // Name: PAF_ASOT_startOutput
2188 // Purpose: Decoding Function for initiating output.
2189 // From: AST Parameter Function -> decodeInfo1
2190 // Uses: See code.
2191 // States: x
2192 // Return: Error number in standard or SIO form (0 on success).
2193 // Trace: Message Log "trace" in Debug Project Configuration reports:
2194 // * State information as per parent.
2195 // * SIO control errors.
2196 //
2197 #define DEC_OUTNUMBUF_MAP(X) \
2198 pP->poutNumBufMap[z]->map[(X) >= pP->poutNumBufMap[z]->length ? 0 : (X)]
2200 Int
2201 PAF_ASOT_startOutput(
2202 const PAF_ASOT_Params *pP,
2203 const PAF_ASOT_Patchs *pQ,
2204 PAF_ASOT_Config *pC
2205 )
2206 {
2207 PAF_AST_Config *pAstCfg;
2208 Int as; /* Audio Stream Number (1, 2, etc.) */
2209 Int z; /* output counter */
2210 Int errno,nbufs; /* error number */
2211 Int zE, zS, zX;
2212 Int zMD;
2213 PAF_SIO_IALG_Obj *pObj;
2214 PAF_SIO_IALG_Config *pAlgConfig;
2217 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2218 as = pAstCfg->as;
2219 zMD = pAstCfg->masterDec;
2221 for (z=OUTPUT1; z < OUTPUTN; z++)
2222 {
2223 if (pAstCfg->xOut[z].hTxSio)
2224 {
2225 // determine associated encoder and stream
2226 zE = z;
2227 zS = z;
2228 for (zX = ENCODE1; zX < ENCODEN; zX++)
2229 {
2230 if (pP->outputsFromEncodes[zX] == z)
2231 {
2232 zE = zX;
2233 zS = pP->streamsFromEncodes[zE];
2234 break;
2235 }
2236 }
2238 // Set sample count so that DOB knows how much data to send
2239 pAstCfg->xOut[z].outBufConfig.lengthofFrame =
2240 pAstCfg->xEnc[zE].encodeInStruct.pAudioFrame->sampleCount;
2242 if (pAstCfg->xOut[z].outBufStatus.markerMode == PAF_OB_MARKER_ENABLED)
2243 {
2244 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2245 pAlgConfig = &pObj->config;
2246 memset(pAstCfg->xOut[z].outBufConfig.base.pVoid, 0xAA,
2247 pAlgConfig->pMemRec[0].size);
2248 }
2250 // The index to DEC_OUTNUMBUF_MAP will always come from the primary/master
2251 // decoder. How should we handle the sourceProgram for multiple decoders?
2252 // Override as needed
2253 nbufs = DEC_OUTNUMBUF_MAP(pAstCfg->xDec[zMD].decodeStatus.sourceProgram);
2254 if (pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram] > 0)
2255 {
2256 nbufs = pAstCfg->xOut[z].outBufStatus.numBufOverride[pAstCfg->xDec[zMD].decodeStatus.sourceProgram];
2257 }
2258 SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_NUMBUF, nbufs);
2260 if (errno = SIO_issue(pAstCfg->xOut[z].hTxSio,
2261 &pAstCfg->xOut[z].outBufConfig, sizeof(pAstCfg->xOut[z].outBufConfig), 0))
2262 {
2263 SIO_idle(pAstCfg->xOut[z].hTxSio);
2264 TRACE_TERSE2("PAF_ASOT_startOutput: AS%d: SIO_issue failed (0x%x)", as+zS, errno);
2265 return errno;
2266 }
2268 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2269 (errno = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_UNMUTE, 0)))
2270 {
2271 errno = (errno & 0xff) | ASPERR_MUTE;
2272 /* convert to sensical errno */
2273 TRACE_TERSE2("as1-f2: PAF_ASOT_startOutput: AS%d: SIO control failed (unmute) 0x%x", as+zS, errno);
2274 return (errno);
2275 }
2276 else
2277 {
2278 pAstCfg->xOut[z].outBufStatus.audio
2279 = (pAstCfg->xOut[z].outBufStatus.audio & 0xf0) | PAF_OB_AUDIO_SOUND;
2280 }
2282 TRACE_VERBOSE1("PAF_ASOT_startOutput: AS%d: output started", as+zS);
2283 }
2284 }
2286 return 0;
2287 } //PAF_ASOT_startOutput
2289 // -----------------------------------------------------------------------------
2290 // ASOT Decoding Function Helper - SIO Driver Stop
2291 //
2292 // Name: PAF_ASOT_stopOutput
2293 // Purpose: Decoding Function for terminating output.
2294 // From: AST Parameter Function -> decodeProcessing
2295 // AST Parameter Function -> decodeComplete
2296 // Uses: See code.
2297 // States: x
2298 // Return: Error number in standard or SIO form (0 on success).
2299 // Trace: Message Log "trace" in Debug Project Configuration reports:
2300 // * SIO control errors.
2301 //
2302 Int
2303 PAF_ASOT_stopOutput(
2304 const PAF_ASOT_Params *pP,
2305 const PAF_ASOT_Patchs *pQ,
2306 PAF_ASOT_Config *pC
2307 )
2308 {
2309 PAF_AST_Config *pAstCfg;
2310 Int as; /* Audio Stream Number (1, 2, etc.) */
2311 Int z; /* output counter */
2312 Int errno = 0, getVal;
2313 Int zS, zX;
2314 PAF_SIO_IALG_Obj *pObj;
2315 PAF_SIO_IALG_Config *pAlgConfig;
2317 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2318 as = pAstCfg->as;
2319 (void)as; // clear compiler warning in case not used with tracing disabled
2321 for (z=OUTPUT1; z < OUTPUTN; z++)
2322 {
2323 if (pAstCfg->xOut[z].hTxSio)
2324 {
2325 // determine associated encoder and stream
2326 zS = z;
2327 (void)zS;
2328 for (zX = ENCODE1; zX < ENCODEN; zX++)
2329 {
2330 if (pP->outputsFromEncodes[zX] == z)
2331 {
2332 zS = pP->streamsFromEncodes[zX];
2333 break;
2334 }
2335 }
2337 // Mute output before audio data termination in the usual case,
2338 // where such termination is due to decode error or user command.
2339 // Identification of this as the usual case is provided by the
2340 // "decode processing" state machine.
2341 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2342 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_SOUND) &&
2343 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2344 {
2345 if (!errno)
2346 {
2347 errno = (getVal & 0xff) | ASPERR_MUTE;
2348 /* convert to sensical errno */
2349 }
2350 TRACE_VERBOSE1("PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2351 }
2353 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- begin PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2355 // Terminate audio data output, truncating (ignore) or flushing
2356 // (play out) final samples as per (1) control register set by
2357 // the user and (2) the type of audio data termination:
2359 #if 0
2360 // This form is not used because driver support for truncating
2361 // data is not supported for internal clocks, although it is
2362 // for external clocks.
2363 getVal = SIO_ctrl(pC->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2364 pC->xOut[z].outBufStatus.flush
2365 & (pC->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2366 ? 1 : 0);
2367 /* UNTESTED */
2368 #else
2369 // This form should be used when driver support for truncating
2370 // data is supported for both internal and external clocks.
2371 getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_IDLE,
2372 pAstCfg->xOut[z].outBufStatus.flush ? 1 :
2373 (pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH
2374 ? 1 : 0);
2375 /* TESTED */
2376 #endif
2378 TRACE_TIME((&TIME_MOD, "... + %d = %d (stopOutput -- after PAF_SIO_CONTROL_IDLE)", dtime(), TSK_time()));
2380 if (!errno)
2381 {
2382 errno = getVal;
2383 }
2385 // Mute output after audio data termination in a special case,
2386 // where such termination is due to processing of a final frame
2387 // or user command. Identification of this as a special case is
2388 // provided by the "decode processing" state machine.
2389 if (!(pAstCfg->xOut[z].outBufStatus.audio & 0xf0) &&
2390 ((pAstCfg->xOut[z].outBufStatus.audio & 0x0f) == PAF_OB_AUDIO_FLUSH) &&
2391 (getVal = SIO_ctrl(pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_MUTE, 0)))
2392 {
2393 if (!errno)
2394 {
2395 errno = (getVal & 0xff) | ASPERR_MUTE;
2396 /* convert to sensical errno */
2397 }
2398 TRACE_VERBOSE1("as1-f2: PAF_ASOT_stopOutput: AS%d: SIO control failed (mute)", as+zS);
2399 }
2401 pAstCfg->xOut[z].outBufStatus.audio &= ~0x0f;
2403 // zero output buffers
2404 pObj = (PAF_SIO_IALG_Obj *) pAstCfg->xOut[z].outChainData.head->alg;
2405 pAlgConfig = &pObj->config;
2406 memset (pAstCfg->xOut[z].outBufConfig.base.pVoid, 0, pAlgConfig->pMemRec[0].size);
2407 } //pAstCfg->xOut[z].hTxSio
2408 }//OUTPUT
2410 return errno;
2411 } //PAF_ASOT_stopOutput
2413 // -----------------------------------------------------------------------------
2414 // ASOT Decoding Function Helper - SIO Driver Change
2415 //
2416 // Name: PAF_ASOT_setCheckRateX
2417 // Purpose: Decoding Function for reinitiating output.
2418 // From: AST Parameter Function -> decodeInfo1
2419 // AST Parameter Function -> decodeInfo2
2420 // Uses: See code.
2421 // States: x
2422 // Return: Error number in standard form (0 on success).
2423 // Trace: None.
2424 //
2426 /* 0: set, 1: check, unused for now. --Kurt */
2427 Int
2428 PAF_ASOT_setCheckRateX(
2429 const PAF_ASOT_Params *pP,
2430 const PAF_ASOT_Patchs *pQ,
2431 PAF_ASOT_Config *pC,
2432 Int check
2433 )
2434 {
2435 PAF_AST_Config *pAstCfg;
2436 float rateX;
2437 PAF_SampleRateHz rateO /* std */, rateI /* inv */;
2438 Int z; /* output counter */
2439 Int zx; /* output re-counter */
2440 Int getVal;
2441 int inputRate, inputCount, outputRate, outputCount;
2442 Int zMD;
2443 Int zMI;
2444 Int zMS;
2445 Int zE, zX;
2447 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2448 zMD = pAstCfg->masterDec;
2449 zMS = pAstCfg->masterStr;
2450 zMI = pP->zone.master;
2452 inputRate = pAstCfg->xInp[zMI].inpBufStatus.sampleRateStatus;
2453 inputCount = pAstCfg->xDec[zMD].decodeStatus.frameLength;
2454 rateI = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2455 (pAstCfg->xStr[zMS].pAudioFrame, inputRate, PAF_SAMPLERATEHZ_INV);
2457 for (z=OUTPUT1; z < OUTPUTN; z++) {
2458 if (pAstCfg->xOut[z].hTxSio && (pAstCfg->xOut[z].outBufStatus.clock & 0x01)) {
2460 // determine associated encoder
2461 zE = z;
2462 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2463 if (pP->outputsFromEncodes[zX] == z) {
2464 zE = zX;
2465 break;
2466 }
2467 }
2469 outputRate = pAstCfg->xEnc[zE].encodeStatus.sampleRate;
2470 outputCount = pAstCfg->xEnc[zE].encodeStatus.frameLength;
2471 rateO = pAstCfg->xStr[zMS].pAudioFrame->fxns->sampleRateHz
2472 (pAstCfg->xStr[zMS].pAudioFrame, outputRate, PAF_SAMPLERATEHZ_STD);
2473 if (rateI > 0 && rateO > 0)
2474 rateX = rateO /* std */ * rateI /* inv */;
2475 else if (inputCount != 0)
2476 rateX = (float )outputCount / inputCount;
2477 else
2478 return ( ASPERR_INFO_RATERATIO );
2480 getVal = SIO_ctrl (pAstCfg->xOut[z].hTxSio, PAF_SIO_CONTROL_SET_RATEX, (Arg) &rateX);
2481 if (getVal == DOBERR_RATECHANGE) {
2482 for (zx=OUTPUT1; zx < OUTPUTN; zx++)
2483 if (pAstCfg->xOut[zx].hTxSio)
2484 SIO_idle (pAstCfg->xOut[zx].hTxSio);
2486 // this forces an exit from the calling state machine which will
2487 // eventually call startOutput which calls setCheckRateX for all outputs
2488 // and so it is ok, in the presence of a rate change on any output, to
2489 // exit this loop /function early.
2490 return ASPERR_INFO_RATECHANGE;
2491 }
2492 else if( getVal != SYS_OK )
2493 return ((getVal & 0xff) | ASPERR_RATE_CHECK);
2494 }
2495 }
2497 return 0;
2498 } //PAF_ASOT_setCheckRateX
2500 // -----------------------------------------------------------------------------
2501 // ASOT Decoding Function Helper - Chain Processing
2502 //
2503 // Name: PAF_ASOT_streamChainFunction
2504 // Purpose: Common Function for processing algorithm chains.
2505 // From: AST Parameter Function -> decodeInfo1
2506 // AST Parameter Function -> decodeStream
2507 // AST Parameter Function -> decodeComplete
2508 // Uses: See code.
2509 // States: x
2510 // Return: Error number in standard form (0 on success).
2511 // Trace: Message Log "trace" in Debug Project Configuration reports:
2512 // * State information as per parent.
2513 //
2514 Int
2515 PAF_ASOT_streamChainFunction(
2516 const PAF_ASOT_Params *pP,
2517 const PAF_ASOT_Patchs *pQ,
2518 PAF_ASOT_Config *pC,
2519 Int iChainFrameFxns,
2520 Int abortOnError,
2521 Int logArg
2522 )
2523 {
2524 PAF_AST_Config *pAstCfg;
2525 Int as; /* Audio Stream Number (1, 2, etc.) */
2526 Int z; /* stream counter */
2527 Int errno; /* error number */
2528 Int dFlag, eFlag, gear;
2529 Int zX;
2530 Int zS;
2532 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2533 as = pAstCfg->as;
2534 (void)as; // clear compiler warning in case not used with tracing disabled
2536 for (zS = STREAM1; zS < STREAMN; zS++)
2537 {
2538 z = pP->streamOrder[zS]; // Select stream order from streamOrder parameter - MID 788
2540 // apply stream
2541 // unless the stream is associated with a decoder and it is not running
2542 // or
2543 // unless the stream is associated with an encoder and it is not running
2544 // Also gear control only works for streams with an associated decoder
2545 // if no such association exists then gear 0 (All) is used
2546 dFlag = 1;
2547 gear = 0;
2548 for (zX = DECODE1; zX < DECODEN; zX++) {
2549 if (pP->streamsFromDecodes[zX] == z) {
2550 dFlag = pAstCfg->xDec[zX].decodeStatus.mode;
2551 gear = pAstCfg->xDec[zX].decodeStatus.aspGearStatus;
2552 break;
2553 }
2554 }
2555 eFlag = 1;
2556 for (zX = ENCODE1; zX < ENCODEN; zX++) {
2557 if (pP->streamsFromEncodes[zX] == z) {
2558 eFlag = pAstCfg->xEnc[zX].encodeStatus.mode;
2559 break;
2560 }
2561 }
2563 if (dFlag && eFlag) {
2564 PAF_ASP_Chain *chain = pAstCfg->xStr[z].aspChain[gear];
2565 PAF_AudioFrame *frame = pAstCfg->xStr[z].pAudioFrame;
2566 Int (*func) (PAF_ASP_Chain *, PAF_AudioFrame *) =
2567 chain->fxns->chainFrameFunction[iChainFrameFxns];
2569 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2570 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset)"
2571 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2572 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply)"
2573 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2574 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final)"
2575 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????)",
2576 as+z, logArg);
2577 errno = (*func) (chain, frame);
2578 TRACE_VERBOSE2("PAF_ASOT_streamChainFunction: AS%d: errno 0x%x.",
2579 as+z, errno);
2581 if (errno && abortOnError)
2582 return errno;
2583 }
2584 else {
2585 TRACE_GEN2(iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_RESET
2586 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (reset) <ignored>"
2587 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_APPLY
2588 ? "PAF_ASOT_streamChainFunction: AS%d: processing block %d -- audio stream (apply) <ignored>"
2589 : iChainFrameFxns == PAF_ASP_CHAINFRAMEFXNS_FINAL
2590 ? "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (final) <ignored>"
2591 : "PAF_ASOT_streamChainFunction: AS%d: processing frame %d -- audio stream (?????) <ignored>",
2592 as+z, logArg);
2593 }
2595 /*
2596 {
2597 void dp_tracePAF_Data(float *lBuf, float *rBuf, int count);
2598 PAF_AudioFrameData *afd;
2599 float ** afPtr;
2601 afd = &(pC->xStr->pAudioFrame->data);
2602 afPtr = (float**)afd->sample;
2603 dp_tracePAF_Data(afPtr[4], afPtr[5], 256);
2605 }
2606 */
2608 }
2610 return 0;
2611 } //PAF_ASOT_streamChainFunction
2613 /* FL: Check if at least one output selected */
2614 static Int checkOutSel(
2615 const PAF_ASOT_Params *pP,
2616 PAF_ASOT_Config *pC,
2617 Int *pOutSel
2618 )
2619 {
2620 PAF_AST_Config *pAstCfg;
2621 Int outSel;
2622 Int z;
2624 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2626 outSel = 0;
2627 for (z=OUTPUT1; z < OUTPUTN; z++)
2628 {
2629 if (pAstCfg->xOut[z].hTxSio)
2630 {
2631 outSel = 1;
2632 break;
2633 }
2634 }
2636 *pOutSel = outSel;
2638 return 0;
2639 }
2641 /* FL: Check if at least one output sio changed */
2642 static Int checkOutSio(
2643 const PAF_ASOT_Params *pP,
2644 PAF_ASOT_Config *pC,
2645 Int *pOutSioUpdate
2646 )
2647 {
2648 PAF_AST_Config *pAstCfg;
2649 Int outSioUpdate;
2650 Int z;
2652 pAstCfg = pC->pAstCfg; // get pointer to common (shared) configuration
2654 outSioUpdate = 0;
2655 for (z=OUTPUT1; z < OUTPUTN; z++)
2656 {
2657 if (pAstCfg->xOut[z].outBufStatus.sioSelect >= 0)
2658 {
2659 outSioUpdate = 1;
2660 break;
2661 }
2662 }
2664 *pOutSioUpdate = outSioUpdate;
2666 return 0;
2667 }