a800d2d7cc7e155337b4d5c957de1382d34fea56
2 /*
3 Copyright (c) 2018, 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 <xdc/runtime/Log.h>
41 #include <ti/sysbios/BIOS.h>
43 #include "aspOutInitSync_master.h"
44 #include "audioStreamProc_common.h"
45 #include "audioStreamOutProc.h"
46 #include "audioStreamOutInit.h"
47 #include "audioStreamOutDec.h"
48 #include "audioStreamOutIo.h"
49 #include "common.h"
51 //#include "pfp/pfp.h"
52 //#include "pfp_app.h" /* contains all PFP ID's */
53 //Int32 gNumPfpAsot1=0; // debug
55 // debug
56 #include "evmc66x_gpio_dbg.h"
58 //#include "ioConfig.h"
60 // -----------------------------------------------------------------------------
61 // Debugging Trace Control, local to this file.
62 //
63 #include "logp.h"
65 // Allow a developer to selectively enable tracing.
66 #define CURRENT_TRACE_MASK 0x07
68 #define TRACE_MASK_TERSE 0x01 // only flag errors and show init
69 #define TRACE_MASK_GENERAL 0x02 // half dozen lines per frame
70 #define TRACE_MASK_VERBOSE 0x04 // trace full operation
72 #if !(CURRENT_TRACE_MASK & TRACE_MASK_TERSE)
73 #undef TRACE_TERSE0
74 #undef TRACE_TERSE1
75 #undef TRACE_TERSE2
76 #undef TRACE_TERSE3
77 #undef TRACE_TERSE4
78 #define TRACE_TERSE0(a)
79 #define TRACE_TERSE1(a,b)
80 #define TRACE_TERSE2(a,b,c)
81 #define TRACE_TERSE3(a,b,c,d)
82 #define TRACE_TERSE4(a,b,c,d,e)
83 #endif
85 #if !(CURRENT_TRACE_MASK & TRACE_MASK_GENERAL)
86 #undef TRACE_GEN0
87 #undef TRACE_GEN1
88 #undef TRACE_GEN2
89 #undef TRACE_GEN3
90 #undef TRACE_GEN4
91 #define TRACE_GEN0(a)
92 #define TRACE_GEN1(a,b)
93 #define TRACE_GEN2(a,b,c)
94 #define TRACE_GEN3(a,b,c,d)
95 #define TRACE_GEN4(a,b,c,d,e)
96 #endif
98 #if !(CURRENT_TRACE_MASK & TRACE_MASK_VERBOSE)
99 #undef TRACE_VERBOSE0
100 #undef TRACE_VERBOSE1
101 #undef TRACE_VERBOSE2
102 #undef TRACE_VERBOSE3
103 #undef TRACE_VERBOSE4
104 #define TRACE_VERBOSE0(a)
105 #define TRACE_VERBOSE1(a,b)
106 #define TRACE_VERBOSE2(a,b,c)
107 #define TRACE_VERBOSE3(a,b,c,d)
108 #define TRACE_VERBOSE4(a,b,c,d,e)
109 #endif
111 // -----------------------------------------------------------------------------
112 //
113 // Audio Stream Output Task definitions
114 //
116 #define __TASK_NAME__ "TaskAsop"
118 // status codes
119 // ASOT FSM
120 #define ASOP_SOK_INITSYNC_NOTREADY ( 1 ) // ok, init-sync not ready
121 #define ASOP_SOK ( 0 ) // ok
122 #define ASOP_ERR_FORWARD_ERR ( -1 ) // error, forward (ASIT) error
123 #define ASOP_ERR_RESETOUTPROC_NOOUTDEVSEL ( -2 ) // error, reset dec out proc, no output device selected
124 #define ASOP_ERR_PROCDECOUT_OUTDEVSELUPD ( -3 ) // error, proc dec out, output device select updated
125 #define ASOP_ERR_PROCDECOUT_IOPHYXFERCOMPLETE ( -4 ) // error, proc dec out, io phy transfer complete
126 #define ASOP_ERR_PROCDECOUT_CHKOUTDEVSELUPD ( -5 ) // error, proc dec out, check output device select update
128 // -----------------------------------------------------------------------------
130 // ASOT FSM states
131 enum
132 {
133 ASOT_STATE_SEL_OUT_DEV,
134 ASOT_STATE_RESET_OUT_PROC,
135 ASOT_STATE_INITSYNC_DEC_INFO1,
136 ASOT_STATE_INITSYNC_DEC_DECODE1,
137 ASOT_STATE_PROC_DEC_OUT,
138 ASOT_STATE_RESEL_OUT_DEV,
139 ASOT_STATE_INITSYNC_RESYNC
140 };
142 // Check if Output device selected
143 static Int checkOutDevSel(
144 PAF_AST_IoOut *pOut,
145 Bool *pOutDevSel);
147 // Check if any Output device selected
148 static Int checkAnyOutDevSel(
149 const PAF_ASOT_Params *pP,
150 PAF_AST_IoOut *pOut,
151 Bool *pOutDevSel);
153 // ASOT SM function
154 // Purpose: Audio Stream Output Task Function for selecting the devices used
155 // for output.
156 static Int PAF_ASOT_selectDevices(
157 const PAF_ASOT_Params *pP,
158 const PAF_ASOT_Patchs *pQ,
159 PAF_ASOT_Config *pAsotCfg,
160 Bool *pOutDevSel
161 );
163 // Reset audio frame pointers to original values
164 static Void resetAfPointers(
165 const PAF_ASOT_Params *pP,
166 PAF_AST_Stream *xStr
167 );
169 // Reset audio frame meta data elements
170 static Void resetAfMetadata(
171 const PAF_ASOT_Params *pP,
172 PAF_AST_Stream *xStr
173 );
175 // Reset audio frames
176 static Void resetAfs(
177 const PAF_ASOT_Params *pP,
178 PAF_AST_Stream *xStr
179 );
181 // used by new OutProc.c, will be changed back to static once refactoring is done
182 // Purpose: Init-Sync Dec Reset state function.
183 // Performs Dec Reset Init-Sync.
184 static Int PAF_ASOT_initSyncDecReset(
185 const PAF_ASOT_Params *pP,
186 const PAF_ASOT_Patchs *pQ,
187 PAF_ASOT_Config *pAsotCfg,
188 PAF_AudioFrame *pDecResetAf,
189 Int frame
190 );
192 // ASOT SM function
193 // Reset Decoder Output processing
194 static Int PAF_ASOT_resetDecOutProc(
195 const PAF_ASOT_Params *pP,
196 const PAF_ASOT_Patchs *pQ,
197 PAF_ASOT_Config *pAsotCfg,
198 PAF_AudioFrame *pDecResetAf,
199 Bool outDevSel,
200 Int frame
201 );
203 // ASOT SM function
204 // Purpose: Init-Sync Dec Info1 state function.
205 // Performs Dec Info1 Init-Sync.
206 static Int PAF_ASOT_initSyncDecInfo1(
207 const PAF_ASOT_Params *pP,
208 const PAF_ASOT_Patchs *pQ,
209 PAF_ASOT_Config *pAsotCfg,
210 PAF_AudioFrame *pDecInfo1Af,
211 Int frame
212 );
214 // ASOT SM function
215 // Purpose: Init-Sync Dec Decode1 state function.
216 // Performs Dec Decode1 Init-Sync.
217 static Int PAF_ASOT_initSyncDecDecode1(
218 const PAF_ASOT_Params *pP,
219 const PAF_ASOT_Patchs *pQ,
220 PAF_ASOT_Config *pAsotCfg,
221 Int frame
222 );
224 // ASOT SM function
225 // Process Decoder output audio data
226 static Int PAF_ASOT_procDecOut(
227 const PAF_ASOT_Params *pP,
228 const PAF_ASOT_Patchs *pQ,
229 PAF_ASOT_Config *pAsotCfg,
230 Bool *pFirstTime,
231 Int frame
232 );
234 // ASOT SM function
235 // Purpose: Init-Sync Re-Sync state function.
236 // Performs Init-Sync using stored Dec Reset/Info1 AFs.
237 static Int PAF_ASOT_initSyncResync(
238 const PAF_ASOT_Params *pP,
239 const PAF_ASOT_Patchs *pQ,
240 PAF_ASOT_Config *pAsotCfg,
241 PAF_AudioFrame *pDecResetAf,
242 PAF_AudioFrame *pDecInfo1Af,
243 Int frame
244 );
246 static Int asopDecOutProcEncodeWrap(
247 const PAF_ASOT_Params *pP,
248 const PAF_ASOT_Patchs *pQ,
249 PAF_ASOT_Config *pAsotCfg,
250 Int frame,
251 Int zO
252 );
254 // ASOT SM function
255 // Purpose: Re-select devices used for Output.
256 // Performs Init-Sync using stored Dec Reset/Info1 AFs.
257 static Int PAF_ASOT_reselectDevices(
258 const PAF_ASOT_Params *pP,
259 const PAF_ASOT_Patchs *pQ,
260 PAF_ASOT_Config *pAsotCfg,
261 PAF_AudioFrame *pDecResetAf,
262 PAF_AudioFrame *pDecInfo1Af,
263 Int frame,
264 Bool *pOutDevSel
265 );
268 // FL: debug, allow modification of Output frame length via JTAG.
269 Int16 gOutFrameLen=PAF_ASOT_FRAMELENGTH; // output frame length (PCM samples)
271 // ASOT configuration
272 #pragma DATA_SECTION(gPAF_ASOT_config, ".globalSectionPafAsotConfig")
273 PAF_ASOT_Config gPAF_ASOT_config = {
274 NULL, // taskHandle
275 0, // asotState
276 NULL, // acp
277 0,0,0, // cbDrainedFlag (size DECODE_MAXN)
278 &gPAF_ASPM_config, // pAspmCfg
279 &gPAF_AST_config // pAstCfg
280 };
282 // ASOT event handle - to put in structure
283 Event_Handle gAsotEvtHandle;
285 extern Int d10Initialized;
287 // For writeDECCommandRestart
288 extern volatile UInt32 gCommandOutputTask_SYNC;
289 extern volatile UInt32 gCommandOutputTask_ACK;
291 LINNO_DEFN(TaskAsop); // Line number macros
292 ERRNO_DEFN(TaskAsop); // Error number macros
294 #define ASOP_DEBUG
295 #ifdef ASOP_DEBUG
296 Int asopLoopCount;
297 #endif
299 // Debug event-in-state counters
300 UInt32 gSelOutDevState_EvtWakeTimer_cnt = 0; // Select Output state, Wake Timer event count
301 UInt32 gSelOutDevState_EvtTxMcaspEdma_invCnt = 0; // Select Output state, invalid Tx McASP EDMA event count
302 UInt32 gSelOutDevState_Evt_invCnt = 0; // Select Output state, invalid other event count
303 UInt32 gResetOutProcState_EvtWakeTimer_cnt = 0; // Select Output state, Wake Timer event count
304 UInt32 gResetOutProcState_EvtTxMcaspEdma_invCnt = 0; // Reset Output Processing state, invalid Tx McASP EDMA event count
305 UInt32 gResetOutProcState_Evt_invCnt = 0; // Reset Output Processing state, invalid other event count
306 UInt32 gInitSyncDecInfo1State_EvtWakeTimer_cnt = 0; // Init-Sync Dec Info1 state, Wake Timer event count
307 UInt32 gInitSyncDecInfo1State_EvtTxMcaspEdma_invCnt = 0; // Init-Sync Dec Info1 state, invalid Tx McASP EDMA event count
308 UInt32 gInitSyncDecInfo1State_Evt_invCnt = 0; // Init-Sync Dec Info1 state, invalid other event count
309 UInt32 gInitSyncDecDecode1State_EvtWakeTimer_cnt = 0; // Init-Sync Dec Decode1 state, Wake Timer event count
310 UInt32 gInitSyncDecDecode1State_EvtTxMcaspEdma_invCnt = 0; // Init-Sync Dec Decode1 state, invalid Tx McASP EDMA event count
311 UInt32 gInitSyncDecDecode1State_Evt_invCnt = 0; // Init-Sync Dec Decode1 state, invalid other event count
312 UInt32 gProcDecOutState_EvtWakeTimer_cnt = 0; // Process Output state, Wake Timer event count
313 UInt32 gProcDecOutState_EvtTxMcaspEdma_cnt = 0; // Process Output state, Tx McASP EDMA event count
314 UInt32 gProcDecOutState_Evt_invCnt = 0; // Process Output state, invalid other event count
315 UInt32 gReselOutDevState_EvtWakeTimer_cnt = 0; // Process Output state, Wake Timer event count
316 UInt32 gReselOutDevState_EvtTxMcaspEdma_invCnt = 0; // Re-select Output state, invalid other event count
317 UInt32 gReselOutDevState_Evt_invCnt = 0; // Re-select Output state, invalid other event count
318 // Debug state counters
319 UInt32 gAsotInitSyncResyncState_Cnt = 0; // Init-Sync Re-sync (Local error) state execution count
320 UInt32 gAsotInvState_Cnt = 0; // invalid state count
323 /*
324 * ======== taskAsopFxn ========
325 * Audio Stream Output Processing task function
326 */
327 Void taskAsopFxn(
328 const PAF_ASOT_Params *pP,
329 const PAF_ASOT_Patchs *pQ
330 )
331 {
332 PAF_ASOT_Config *pAsotCfg; // ASOT configuration pointer
333 PAF_AST_Config *pAstCfg; // Common (shared) configuration pointer
334 Int as; // Audio Stream Number (1, 2, etc.)
335 Int z; // input/encode/stream/decode/output counter
336 Bool outDevSel; // whether output device selected
337 PAF_AudioFrame decResetAf;
338 PAF_AudioFrame decInfo1Af;
339 UInt events; // latched event flags
340 Bool procEvents; // process events flags
341 Bool procOutFirstTime; // first time process output flag
342 Int asopFrameCount; // frame counter
343 Int status; // status code
344 #ifndef ASOP_DEBUG
345 Int asopLoopCount; // debug, ASOT loop counter
346 #endif
348 Log_info0("Enter taskAsopFxn()");
350 taskAsopFxnInit(pP, pQ); // initialization of output task
352 //
353 // Audio Stream Output Task Configuration (*pAsotCfg):
354 //
355 pAsotCfg = &gPAF_ASOT_config; // initialize pointer to task configuration
356 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
357 as = pAstCfg->as; // obtain Audio Stream Number (1, 2, etc.)
359 //
360 // Main processing loop
361 //
362 for (z=STREAM1; z < STREAMN; z++)
363 {
364 TRACE_VERBOSE1("TaskAsop: AS%d: running", as+z);
365 }
367 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // init state
368 procEvents = TRUE; // init proc events flag
369 procOutFirstTime = TRUE; // init first time process output flag
370 asopFrameCount = 0; // init frame counter TBD
371 asopLoopCount = 0; // loop counter
372 for (;;)
373 {
374 // Pend for next event
375 // Evt_Id_AsotWakeTimer : Wakeup timer (poll for Output device selection)
376 // Evt_Id_AsotTxMcaspEdma : Tx McASP EDMA completion
377 if (procEvents == TRUE)
378 {
379 events = Event_pend(gAsotEvtHandle, Event_Id_NONE, (Evt_Id_AsotWakeTimer + Evt_Id_AsotTxMcaspEdma), BIOS_WAIT_FOREVER);
380 }
382 asopLoopCount++;
383 //TRACE_GEN1("TaskAsop (begin Main loop %d)", asopLoopCount);
385 switch (pAsotCfg->state)
386 {
387 //
388 // Select Output Device state
389 //
390 case ASOT_STATE_SEL_OUT_DEV:
391 if (events & Evt_Id_AsotWakeTimer)
392 {
393 gSelOutDevState_EvtWakeTimer_cnt++;
394 events &= ~Evt_Id_AsotWakeTimer; // clear event
396 // Select Output devices
397 // outDevSel==TRUE if Output device selection successful
398 status = PAF_ASOT_selectDevices(pP, pQ, pAsotCfg, &outDevSel);
399 if (status < 0)
400 {
401 // FL, New IO:
402 //Tx status==error message to ASIT; // ASOT initiated message to ASIT, "backward" error
404 // No explicit handling of Select Output Device error, so stay in state and try again
405 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV;
406 break;
407 }
408 else if (outDevSel == TRUE)
409 {
410 // Select successful
411 pAsotCfg->state = ASOT_STATE_RESET_OUT_PROC;
412 }
413 else
414 {
415 // No output device selected (outDevSel == FALSE).
416 // Remain in current state.
417 ;
418 }
419 }
421 // Check for unexpected Tx McASP EDMA event
422 if (events & Evt_Id_AsotTxMcaspEdma)
423 {
424 gSelOutDevState_EvtTxMcaspEdma_invCnt++; // log invalid event count in state
425 TRACE_TERSE2("TaskAsop: invalid Tx McASP EDMA event, state=%u, events=%u", pAsotCfg->state, events);
426 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
427 }
429 // Check for any other unexpected events
430 if (events != 0)
431 {
432 gSelOutDevState_Evt_invCnt++; // log invalid event count in state
433 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
434 events &= ~events; // clear events
435 }
437 break;
439 // FL, New IO: currently using timer event
440 //
441 // Reset Output Processing state
442 //
443 case ASOT_STATE_RESET_OUT_PROC:
444 if (events & Evt_Id_AsotWakeTimer)
445 {
446 gResetOutProcState_EvtWakeTimer_cnt++;
447 events &= ~Evt_Id_AsotWakeTimer; // clear event
449 //
450 // Allow Output device re-selection prior to Output processing.
451 // Output device selection has already been performed in state==ASOT_STATE_SEL_OUT_DEV.
452 // Output device can be re-selected via alpha commands before streaming is initiated.
453 // Here check whether this has occurred.
454 //
456 // Select Output devices
457 // outDevSel==TRUE if Output device selection successful
458 status = PAF_ASOT_selectDevices(pP, pQ, pAsotCfg, &outDevSel);
459 if (status < 0)
460 {
461 // FL, New IO:
462 //Tx status==error message to ASIT; // ASOT initiated message to ASIT, "backward" error
464 // Starting over with Output device selection in case of error
465 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV;
466 break;
467 }
469 // Reset Output processing
470 status = PAF_ASOT_resetDecOutProc(pP, pQ, pAsotCfg, &decResetAf, outDevSel, asopFrameCount);
471 if (status < 0)
472 {
473 // FL, New IO:
474 //Tx status==error message to ASDT; // feedback message ASOT -> ASDT
476 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // starting over with Output device selection in case of error
477 break;
478 }
479 else if (status == ASOP_SOK_INITSYNC_NOTREADY)
480 {
481 // FL, New IO: this is only necessary for Wake Timer, POLLING Init-Sync
482 // FL, New IO: can be removed once Rx ASDT messages are implemented for Init-Sync
484 // Dec Reset Init-Sync not ready.
485 // Remain in current state.
486 ;
487 }
488 else
489 {
490 // FL, New IO:
491 //Tx status==ok message to ASDT; // feedback message ASOT -> ASDT
493 pAsotCfg->state = ASOT_STATE_INITSYNC_DEC_INFO1;
494 }
495 }
497 // Check for unexpected Tx McASP EDMA event
498 if (events & Evt_Id_AsotTxMcaspEdma)
499 {
500 gResetOutProcState_EvtTxMcaspEdma_invCnt++; // log invalid event count in state
501 TRACE_TERSE2("TaskAsop: Tx McASP EDMA event, state=%u, events=%u", pAsotCfg->state, events);
502 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
503 }
505 // Check for any other unexpected events
506 if (events != 0)
507 {
508 gResetOutProcState_Evt_invCnt++; // log invalid event count in state
509 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
510 events &= ~events; // clear events
511 }
513 break;
515 // FL, New IO: currently using timer event
516 //
517 // Init-Sync Info1 state
518 //
519 case ASOT_STATE_INITSYNC_DEC_INFO1:
520 if (events & Evt_Id_AsotWakeTimer)
521 {
522 gInitSyncDecInfo1State_EvtWakeTimer_cnt++;
523 events &= ~Evt_Id_AsotWakeTimer; // clear event
525 status = PAF_ASOT_initSyncDecInfo1(pP, pQ, pAsotCfg, &decInfo1Af, asopFrameCount);
526 if (status < 0)
527 {
528 // FL, New IO:
529 //Tx status==error message to ASDT; // feedback message ASOT -> ASDT
531 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // starting over with Output device selection in case of error
532 break;
533 }
534 else if (status == ASOP_SOK_INITSYNC_NOTREADY)
535 {
536 // FL, New IO: this is only necessary for Wake Timer, POLLING Init-Sync
537 // FL, New IO: can be removed once Rx ASDT messages are implemented for Init-Sync
539 // Dec Reset Init-Sync not ready.
540 // Remain in current state.
541 ;
542 }
543 else
544 {
545 // FL, New IO:
546 //Tx status==ok message to ASDT; // feedback message ASOT -> ASDT
548 pAsotCfg->state = ASOT_STATE_INITSYNC_DEC_DECODE1;
549 }
550 }
552 // Check for unexpected Tx McASP EDMA event
553 if (events & Evt_Id_AsotTxMcaspEdma)
554 {
555 gInitSyncDecInfo1State_EvtTxMcaspEdma_invCnt++; // log invalid event count in state
556 TRACE_TERSE2("TaskAsop: Tx McASP EDMA event, state=%u, events=%u", pAsotCfg->state, events);
557 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
558 }
560 // Check for any other unexpected events
561 if (events != 0)
562 {
563 gInitSyncDecInfo1State_Evt_invCnt++; // log invalid event count in state
564 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
565 events &= ~events; // clear events
566 }
568 break;
570 // FL, New IO: currently using timer event
571 //
572 // Init-Sync Decode1 state
573 //
574 case ASOT_STATE_INITSYNC_DEC_DECODE1:
575 if (events & Evt_Id_AsotWakeTimer)
576 {
577 gInitSyncDecDecode1State_EvtWakeTimer_cnt++;
578 events &= ~Evt_Id_AsotWakeTimer; // clear event
580 status = PAF_ASOT_initSyncDecDecode1(pP, pQ, pAsotCfg, asopFrameCount);
581 if (status < 0)
582 {
583 // FL, New IO:
584 //Tx status==error message to ASDT; // feedback message ASOT -> ASDT
586 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // starting over with Output device selection in case of error
587 break;
588 }
589 else if (status == ASOP_SOK_INITSYNC_NOTREADY)
590 {
591 // FL, New IO: this is only necessary for Wake Timer, POLLING Init-Sync
592 // FL, New IO: can be removed once Rx ASDT messages are implemented for Init-Sync
594 // Dec Reset Init-Sync not ready.
595 // Remain in current state.
596 ;
597 }
598 else
599 {
600 // FL, New IO:
601 //Tx status==ok message to ASDT; // feedback message ASOT -> ASDT
603 pAsotCfg->state = ASOT_STATE_PROC_DEC_OUT;
604 procOutFirstTime = TRUE;
605 }
606 }
608 // Check for unexpected Tx McASP EDMA event
609 if (events & Evt_Id_AsotTxMcaspEdma)
610 {
611 gInitSyncDecDecode1State_EvtTxMcaspEdma_invCnt++; // log invalid event count in state
612 TRACE_TERSE2("TaskAsop: Tx McASP EDMA event, state=%u, events=%u", pAsotCfg->state, events);
613 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
614 }
616 // Check for any other unexpected events
617 if (events != 0)
618 {
619 gInitSyncDecDecode1State_Evt_invCnt++; // log invalid event count in state
620 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
621 events &= ~events; // clear events
622 }
624 break;
626 //
627 // Process Decoder Output state
628 //
629 case ASOT_STATE_PROC_DEC_OUT:
630 if (events & Evt_Id_AsotTxMcaspEdma)
631 {
632 gProcDecOutState_EvtTxMcaspEdma_cnt++;
633 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
635 #if 1 // (***) FL: shows timing of Output (Tx McASP EDMA)
636 // (***) debug // B8
637 {
638 static Uint8 toggleState = 0;
639 if (toggleState == 0)
640 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
641 else
642 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
643 toggleState = ~(toggleState);
644 }
645 #endif
647 // Process Output
648 status = PAF_ASOT_procDecOut(pP, pQ, pAsotCfg, &procOutFirstTime, asopFrameCount);
649 if (status < 0)
650 {
651 if (status == ASOP_DOP_ERR_FINALTEST_CBDRAINED)
652 {
653 // normal completion, CB drained @ EOS
654 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV;
655 break;
657 }
658 else if (status == ASOP_ERR_PROCDECOUT_OUTDEVSELUPD)
659 {
660 // Output re-select
661 pAsotCfg->state = ASOT_STATE_RESEL_OUT_DEV;
662 break;
663 }
664 // FL, New IO: "backward" error handling.
665 // Currently all errors handled locally.
666 else
667 {
668 // Handle ASOT "local" errors
669 pAsotCfg->state = ASOT_STATE_INITSYNC_RESYNC;
670 procEvents = FALSE;
671 break;
672 }
673 }
674 }
676 // Check for Wakeup Timer event.
677 // Wakeup Timer events are allowed to occur, but no processing is
678 // performed in response to such an event.
679 if (events & Evt_Id_AsotWakeTimer)
680 {
681 events &= ~Evt_Id_AsotWakeTimer; // clear event
682 gProcDecOutState_EvtWakeTimer_cnt++; // log event count in state
683 }
685 // Check for any other unexpected events
686 if (events != 0)
687 {
688 gProcDecOutState_Evt_invCnt++; // log invalid event count in state
689 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
690 events &= ~events; // clear events
691 }
693 break;
695 //
696 // Re-Select Output Device state
697 //
698 case ASOT_STATE_RESEL_OUT_DEV:
699 if (events & Evt_Id_AsotWakeTimer)
700 {
701 gReselOutDevState_EvtWakeTimer_cnt++;
702 events &= ~Evt_Id_AsotWakeTimer; // clear event
704 status = PAF_ASOT_reselectDevices(pP, pQ, pAsotCfg, &decResetAf, &decInfo1Af, asopFrameCount, &outDevSel);
705 if (status < 0)
706 {
707 // FL, New IO:
708 //Tx status==error message to ASIT; // ASOT initiated message to ASIT, "backward" error
710 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // starting over with Output device selection in case of error
711 break;
712 }
713 else if (outDevSel == TRUE)
714 {
715 // Re-select successful
716 pAsotCfg->state = ASOT_STATE_PROC_DEC_OUT;
717 procOutFirstTime = TRUE;
718 }
719 else
720 {
721 // No output device selected (outDevSel == FALSE).
722 // Remain in current state.
723 ;
724 }
725 }
727 // Check for unexpected Tx McASP EDMA event
728 if (events & Evt_Id_AsotTxMcaspEdma)
729 {
730 events &= ~Evt_Id_AsotTxMcaspEdma; // clear event
731 gReselOutDevState_EvtTxMcaspEdma_invCnt++; // log invalid event count in state
732 }
734 // Check for any other unexpected events
735 if (events != 0)
736 {
737 gReselOutDevState_Evt_invCnt++; // log invalid event count in state
738 TRACE_TERSE2("TaskAsop: invalid events, state=%u, events=%u", pAsotCfg->state, events);
739 events &= ~events; // clear events
740 }
742 break;
744 //
745 // Init-Sync Re-sync (Process Output Local Error) state
746 //
747 case ASOT_STATE_INITSYNC_RESYNC: // not event driven state
748 gAsotInitSyncResyncState_Cnt++;
750 status = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, &decResetAf, &decInfo1Af, asopFrameCount);
751 if (status < 0)
752 {
753 // FL, New IO:
754 //Tx status==error message to ASIT; // ASIT initiated message to ASOT, "backward" error
756 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // starting over with Output device selection in case of error
757 procEvents = TRUE;
758 break;
759 }
760 else
761 {
762 pAsotCfg->state = ASOT_STATE_PROC_DEC_OUT;
763 procEvents = TRUE;
764 procOutFirstTime = TRUE;
765 }
767 break;
769 default:
770 gAsotInvState_Cnt++;
771 TRACE_TERSE1("TaskAsop: invalid state, state=%u", pAsotCfg->state);
773 break;
774 }
776 // FL, New IO: handle ASIT messages separately in each state
777 // FL, New IO: proper SM clean up can be skipped if forward error / DEC restart is handled in this way
779 //
780 // Check forward (ASIT) error, TBD
781 //
783 // Check writeDECCommandRestart, TBD
784 if (gCommandOutputTask_SYNC)
785 {
786 TRACE_TERSE0("TaskAsop: ack writeDECCommandRestart ... Wait for command de-assert");
787 gCommandOutputTask_ACK = 1;
788 while (gCommandOutputTask_SYNC)
789 {
790 Event_pend(gAsotEvtHandle, Event_Id_NONE, Evt_Id_AsotWakeTimer, BIOS_WAIT_FOREVER);
791 }
792 TRACE_TERSE0("TaskAsop: ack for writeDECCommandRestart ... Sync-ed! Re-start the process");
793 pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV; // init state -- start over
794 status = ASOP_ERR_FORWARD_ERR; // set status -- force flushing of output device
795 }
797 // any error forces idling of output
798 if (status < 0)
799 {
800 for (z=OUTPUT1; z < OUTPUTN; z++)
801 {
802 //if (pAstCfg->xOut[z].hTxSio)
803 if (pAsotCfg->pIoOut[z].hIoPhy)
804 {
805 //SIO_idle(pAstCfg->xOut[z].hTxSio); JX TO DO: implement proper error handling
806 }
807 }
809 TRACE_TERSE1("TaskAsop: Trace stopped at loop %d.", asopLoopCount);
810 //ERRNO_RPRT(TaskAsop, errno);
811 }
812 } // End of main processing loop for (;;)
813 } /* taskAsopFxn */
815 // ASOT wake timer (clock) function
816 Void clkAsotFxn(Void)
817 {
818 Event_post(gAsotEvtHandle, Evt_Id_AsotWakeTimer);
819 }
821 void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
822 {
823 /* post semaphore */
824 if(mcasp_packet->arg == IOPHY_XFER_FINAL) {
825 //Semaphore_post(asopSemTx);
826 Event_post(gAsotEvtHandle, Evt_Id_AsotTxMcaspEdma);
827 } else {
828 ; // intermediate packet due to buffer wrapping around
829 }
830 }
832 // Reset audio frame pointers to original values
833 static Void resetAfPointers(
834 const PAF_ASOT_Params *pP,
835 PAF_AST_Stream *xStr
836 )
837 {
838 Int z;
839 Int ch;
841 // Reset audio frame pointers to original values
842 for (z = STREAM1; z < STREAMN; z++)
843 {
844 for (ch = PAF_LEFT; ch < PAF_MAXNUMCHAN_AF; ch++)
845 {
846 if (xStr[z].audioFrameChannelPointers[ch])
847 {
848 xStr[z].audioFrameChannelPointers[ch] =
849 xStr[z].origAudioFrameChannelPointers[ch];
850 }
851 }
852 }
853 }
855 // Check if Output device selected
856 static Int checkOutDevSel(
857 PAF_AST_IoOut *pOut,
858 Bool *pOutDevSel
859 )
860 {
861 *pOutDevSel = (Bool)(pOut->hMcaspChan != NULL);
863 return ASOP_SOK;
864 }
866 // Check if any Output device selected
867 static Int checkAnyOutDevSel(
868 const PAF_ASOT_Params *pP,
869 PAF_AST_IoOut *pOut,
870 Bool *pOutDevSel
871 )
872 {
873 Bool outDevSel;
874 Int z;
876 outDevSel = FALSE;
877 for (z=OUTPUT1; z < OUTPUTN; z++)
878 {
879 if (pOut[z].hMcaspChan)
880 {
881 outDevSel = TRUE;
882 break;
883 }
884 }
886 *pOutDevSel = outDevSel;
888 return ASOP_SOK;
889 }
891 // ASOT SM function
892 // -----------------------------------------------------------------------------
893 // ASOT Selection Function - Output Device Selection
894 //
895 // Name: PAF_ASOT_selectDevices
896 // Purpose: Audio Stream Output Task Function for selecting the devices used
897 // for output.
898 //
899 static Int PAF_ASOT_selectDevices(
900 const PAF_ASOT_Params *pP,
901 const PAF_ASOT_Patchs *pQ,
902 PAF_ASOT_Config *pAsotCfg,
903 Bool *pOutDevSel
904 )
905 {
906 PAF_AST_Config *pAstCfg; // Common (shared) configuration pointer
907 Int z;
908 Int zS, zO;
909 Int device;
910 Int status;
911 Bool ioPhyInit;
913 pAstCfg = pAsotCfg->pAstCfg; // get pointer to AST common (shared) configuration
915 // Find first Output associated with Master Stream
916 zO = OUTPUT1;
917 for (z=ENCODE1; z < ENCODEN; z++)
918 {
919 zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
920 if (zS == pAstCfg->masterStr)
921 {
922 // This Encoder is associated with Master Stream.
923 // Note other Encoder can also be associated with Master Stream.
924 zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
925 }
926 }
928 ioPhyInit = asopIoPhyCheckInit(); // check if IO Phy is initialized
929 device = pAstCfg->xOut[zO].outBufStatus.sioSelect; // obtain SIO select for Output
930 if ((ioPhyInit == TRUE) && (device >= 0))
931 {
932 // check for valid index into device array
933 if (device >= pQ->devout->n) // DEVOUT_N
934 {
935 device = 0; // treat as device None
936 }
938 if (device > 0)
939 {
940 // Select Output Devices
941 // FL, New IO: Placeholder function, this will be reorganized moving forward.
942 // FL, New IO: API for single Output.
943 // FL, New IO: Doesn't (re-)configure Output driver.
944 status = asopSelectDevices(pQ->devout->x[device]->sio.pConfig, &pAsotCfg->pIoOut[zO]);
945 if (status < 0)
946 {
947 pAstCfg->xOut[zO].outBufStatus.sioSelect = 0x80;
948 *pOutDevSel = FALSE;
949 return status;
950 }
952 // Reset IO Buff & IO Phy
953 // FL, New IO: API for single Output
954 status = asopIoCompsInit(&pAstCfg->xOut[zO], &pAsotCfg->pIoOut[zO]);
955 if (status < 0)
956 {
957 pAstCfg->xOut[zO].outBufStatus.sioSelect = 0x80;
958 *pOutDevSel = FALSE;
959 return status;
960 }
961 }
963 pAstCfg->xOut[zO].outBufStatus.sioSelect = device | 0x80;
964 }
966 // Check if Output device selected
967 // FL, New IO: API for single Output
968 status = checkOutDevSel(&pAsotCfg->pIoOut[zO], pOutDevSel);
969 if (status < 0)
970 {
971 *pOutDevSel = FALSE;
972 return status;
973 }
975 return ASOP_SOK;
976 }
978 // ASOT SM function
979 // Wake Timer + *POLLING* version.
980 // No explicit Rx ASDT message event from ASDT.
981 // ASOT wakes on Wake Timer event and polls for flag set.
982 // Reset Decoder Output processing
983 static Int PAF_ASOT_resetDecOutProc(
984 const PAF_ASOT_Params *pP,
985 const PAF_ASOT_Patchs *pQ,
986 PAF_ASOT_Config *pAsotCfg,
987 PAF_AudioFrame *pDecResetAf,
988 Bool outDevSel,
989 Int frame
990 )
991 {
992 Int status;
994 if (outDevSel == FALSE)
995 {
996 //
997 // Rx Dec Out-IS message before Output selected.
998 // Decoder is producing output, but no Output selected.
999 //
1000 return ASOP_ERR_RESETOUTPROC_NOOUTDEVSEL;
1001 }
1003 // Perform Dec Reset Init-Sync
1004 status = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, pDecResetAf, frame);
1006 return status;
1007 }
1010 // Reset audio frame meta data elements
1011 static Void resetAfMetadata(
1012 const PAF_ASOT_Params *pP,
1013 PAF_AST_Stream *xStr
1014 )
1015 {
1016 Int z;
1017 Int i;
1019 for (z = STREAM1; z < STREAMN; z++)
1020 {
1021 xStr[z].pAudioFrame->pafBsMetadataUpdate = XDAS_FALSE;
1022 xStr[z].pAudioFrame->numPrivateMetadata = 0;
1023 xStr[z].pAudioFrame->bsMetadata_offset = 0;
1024 xStr[z].pAudioFrame->bsMetadata_type = PAF_bsMetadata_channelData;
1026 for (i = 0; i < pP->pMetadataBufStatus->NumBuf; i++)
1027 {
1028 xStr[z].pAudioFrame->pafPrivateMetadata[i].offset = 0;
1029 xStr[z].pAudioFrame->pafPrivateMetadata[i].size = 0;
1030 }
1031 }
1032 }
1034 // Reset audio frames
1035 static Void resetAfs(
1036 const PAF_ASOT_Params *pP,
1037 PAF_AST_Stream *xStr
1038 )
1039 {
1040 // Reset audio frame pointers to original values
1041 // (may be needed if error occurred).
1042 resetAfPointers(pP, xStr);
1043 // Reset audio frame meta data elements
1044 resetAfMetadata(pP, xStr);
1045 }
1047 // Purpose: Performs Dec Reset Init-Sync.
1048 //static Int PAF_ASOT_initSyncDecReset(
1049 // used by new OutProc.c, will be changed back to static once refactoring is done
1050 static Int PAF_ASOT_initSyncDecReset(
1051 const PAF_ASOT_Params *pP,
1052 const PAF_ASOT_Patchs *pQ,
1053 PAF_ASOT_Config *pAsotCfg,
1054 PAF_AudioFrame *pDecResetAf,
1055 Int frame
1056 )
1057 {
1058 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1059 Int zMD, zMS; // Dec and Stream Master indices
1060 PAF_AudioFrame *pStrAf; // stream audio frame
1061 PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control
1062 Int8 decFlag; // dec stage flag
1063 Int status; // status code
1065 pAstCfg = pAsotCfg->pAstCfg;
1066 zMD = pAstCfg->masterDec;
1067 pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
1069 // check for Dec Reset
1070 // store dec reset AF
1071 status = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD,
1072 ASP_OUTIS_DEC_STAGE_RESET_IDX, &decFlag, pDecResetAf);
1073 if (status < 0)
1074 {
1075 return status;
1076 }
1078 if (decFlag == 0)
1079 {
1080 return ASOP_SOK_INITSYNC_NOTREADY;
1081 }
1082 else
1083 {
1084 zMS = pAstCfg->masterStr;
1085 pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
1087 // Reset audio frames
1088 // FL, New IO: API for multiple streams.
1089 resetAfs(pP, pAstCfg->xStr);
1091 // Update Stream Audio Frame.
1092 // Copy Dec Reset AF to Stream AF.
1093 // FL, New IO: Only Master zone (single) stream handled.
1094 outIsCpyAf(pDecResetAf, pStrAf);
1096 // Enc activate
1097 // Enc reset
1098 status = asopDecOutProcReset(pP, pQ, pAsotCfg, frame);
1099 if (status < 0)
1100 {
1101 return status;
1102 }
1104 return ASOP_SOK;
1105 }
1106 }
1108 // ASOT SM function
1109 // Purpose: Init-Sync Dec Info1 state function.
1110 // Wake Timer + *POLLING* version.
1111 // No explicit Rx ASDT message event from ASDT.
1112 // ASOT wakes on Wake Timer event and polls for flag set.
1113 static Int PAF_ASOT_initSyncDecInfo1(
1114 const PAF_ASOT_Params *pP,
1115 const PAF_ASOT_Patchs *pQ,
1116 PAF_ASOT_Config *pAsotCfg,
1117 PAF_AudioFrame *pDecInfo1Af,
1118 Int frame
1119 )
1120 {
1121 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1122 Int zMD, zMS; // Dec and Stream Master indices
1123 PAF_AudioFrame *pStrAf; // stream audio frame
1124 PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control
1125 Int8 decFlag; // dec stage flag
1126 Int status; // status code
1128 pAstCfg = pAsotCfg->pAstCfg;
1129 zMD = pAstCfg->masterDec;
1130 pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
1132 // Check for Dec Reset,
1133 // Store dec reset AF
1134 status = outIsReadDecStageFlagAndAf(pOutIsCtl, zMD,
1135 ASP_OUTIS_DEC_STAGE_INFO1_IDX, &decFlag, pDecInfo1Af);
1136 if (status < 0)
1137 {
1138 return status;
1139 }
1141 if (decFlag == 0)
1142 {
1143 return ASOP_SOK_INITSYNC_NOTREADY;
1144 }
1145 else
1146 {
1147 zMS = pAstCfg->masterStr;
1148 pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
1150 // Set ASOT output frame length.
1151 // THD sets this to 256 (hard-coded in Dec Info)
1152 // DDP sets this to 0 (audio frame pass through, 0 from ASDT AF frame length)
1153 // PCM sets this to 256 (decodeControl.frameLength)
1154 //pDecInfo1Af->sampleCount = pAsotCfg->pAstCfg->xDecOpCb[zMS].strFrameLen; // gOutFrameLen; // !!!! GJ: Revisit !!!!
1155 pDecInfo1Af->sampleCount = 512; // debugging for 96kHz
1156 //pDecInfo1Af->sampleCount = 1024; // debugging for 192kHz
1158 // Update Stream Audio Frame.
1159 // Copy Dec Reset AF to Stream AF.
1160 outIsCpyAf(pDecInfo1Af, pStrAf);
1162 // outputInfo1():
1163 // - ASP chain reset,
1164 // - Enc Info,
1165 // - Start Output
1166 status = asopDecOutProcInfo1(pP, pQ, pAsotCfg, frame);
1168 if (status < 0)
1169 {
1170 return status;
1171 }
1173 return ASOP_SOK;
1174 }
1175 }
1177 // ASOT SM function
1178 // Purpose: Init-Sync Dec Decode1 state function.
1179 // Wake Timer + *POLLING* version.
1180 // No explicit Rx ASDT message event from ASDT.
1181 // ASOT wakes on Wake Timer event and polls for flag set.
1182 //static Int PAF_ASOT_initSyncDecDecode1(
1183 static Int PAF_ASOT_initSyncDecDecode1(
1184 const PAF_ASOT_Params *pP,
1185 const PAF_ASOT_Patchs *pQ,
1186 PAF_ASOT_Config *pAsotCfg,
1187 Int frame
1188 )
1189 {
1190 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1191 Int zMD; // Dec Master index
1192 PAF_AST_OutInitSyncCtl *pOutIsCtl; // Output Init-Sync control
1193 Int8 decFlag; // dec stage flag
1194 Int z;
1195 Int zS, zO;
1196 Int status; // status code
1198 pAstCfg = pAsotCfg->pAstCfg;
1199 zMD = pAstCfg->masterDec;
1200 pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
1202 // Check for Dec Reset,
1203 // Store dec reset AF
1204 status = outIsReadDecStageFlag(pOutIsCtl, zMD,
1205 ASP_OUTIS_DEC_STAGE_DECODE1_IDX, &decFlag);
1206 if (status < 0)
1207 {
1208 return status;
1209 }
1211 if (decFlag == 0)
1212 {
1213 return ASOP_SOK_INITSYNC_NOTREADY;
1214 }
1215 else
1216 {
1217 // Find first Output associated with Master Stream
1218 zO = OUTPUT1;
1219 for (z=ENCODE1; z < ENCODEN; z++)
1220 {
1221 zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
1222 if (zS == pAstCfg->masterStr)
1223 {
1224 // This Encoder is associated with Master Stream.
1225 // Note other Encoder can also be associated with Master Stream.
1226 zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
1227 }
1228 }
1230 // FL, New IO: assumption here is Tx McASP clock dividers &
1231 // Output frame size are set correctly before IO prime,
1232 // i.e. IO prime is not using defaults
1234 // FL, New IO: API for single Output
1236 // I/O physical layer prime operation required by McASP LLD
1237 asopIoPhyPrime(&pAsotCfg->pIoOut[zO]);
1238 TRACE_VERBOSE0("PAF_ASOT_initSyncDecDecode1: ASOP McASP LLD primed.");
1240 return ASOP_SOK;
1241 }
1242 }
1244 // ASOT SM function
1245 // Process Decoder output audio data
1246 static Int PAF_ASOT_procDecOut(
1247 const PAF_ASOT_Params *pP,
1248 const PAF_ASOT_Patchs *pQ,
1249 PAF_ASOT_Config *pAsotCfg,
1250 Bool *pFirstTime,
1251 Int frame
1252 )
1253 {
1254 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1255 Bool outDevSioSelUpdate; // indicates whether Output SIO selection has changed
1256 Int zO, zS;
1257 Int z; // decode/encode counter
1258 Int errno; // error number
1259 Int status; // status code
1261 status = ASOP_SOK;
1262 pAstCfg = pAsotCfg->pAstCfg;
1264 if (*pFirstTime == TRUE)
1265 {
1266 // Initialize Decoder output processing
1267 errno = asopDecOutProcInit(pP, pQ, pAsotCfg, frame);
1268 if (errno < 0)
1269 {
1270 status = errno;
1271 }
1272 else
1273 {
1274 *pFirstTime = FALSE;
1275 }
1276 }
1278 if (status == ASOP_SOK)
1279 {
1280 // Find first Output associated with Master Stream
1281 zO = OUTPUT1;
1282 for (z=ENCODE1; z < ENCODEN; z++)
1283 {
1284 zS = pP->streamsFromEncodes[z]; // get Stream associated with Encoder
1285 if (zS == pAstCfg->masterStr)
1286 {
1287 // This Encoder is associated with Master Stream.
1288 // Note other Encoder can also be associated with Master Stream.
1289 zO = pP->outputsFromEncodes[z]; // get Output associated with Encoder
1290 }
1291 }
1293 // Mark Output transfer complete
1294 errno = ioPhyXferComplete(pAsotCfg->pIoOut[zO].hIoPhy, FALSE);
1295 if (errno)
1296 {
1297 status = ASOP_ERR_PROCDECOUT_IOPHYXFERCOMPLETE;
1298 }
1299 }
1301 if (status == ASOP_SOK)
1302 {
1303 // Check if Output device SIO selection changed
1304 errno = checkOutDevSioSelUpdate(pP, pAsotCfg, zO, &outDevSioSelUpdate);
1305 if (errno)
1306 {
1307 status = ASOP_ERR_PROCDECOUT_CHKOUTDEVSELUPD;
1308 }
1309 else if (outDevSioSelUpdate == TRUE)
1310 {
1311 status = ASOP_ERR_PROCDECOUT_OUTDEVSELUPD;
1312 }
1313 }
1315 if (status == ASOP_SOK)
1316 {
1317 // Process encoder command
1318 errno = asopDecOutProcEncodeCommand(pP, pQ, pAsotCfg);
1319 if (errno < 0)
1320 {
1321 status = errno;
1322 }
1323 }
1325 if (status == ASOP_SOK)
1326 {
1327 // Read CB, execute ASP chain
1328 errno = asopDecOutProcStream(pP, pQ, pAsotCfg, frame);
1329 if (errno < 0)
1330 {
1331 status = errno;
1332 }
1333 }
1335 if (status == ASOP_SOK)
1336 {
1337 size_t totalOutputSize;
1339 // Calculate the total size that encoder will write to output buffer
1340 totalOutputSize = pAstCfg->xEnc[zO].encodeInStruct.pAudioFrame->sampleCount
1341 * pAstCfg->xOut[zO].outBufConfig.stride
1342 * pAstCfg->xOut[zO].outBufConfig.sizeofElement;
1344 // Get output buffer pointers for encoder to write. Pointers are stored in pAsotCfg->pIoOut[zO]
1345 asopGetOutBufPtrs(&pAsotCfg->pIoOut[zO], totalOutputSize);
1347 // Invoke the encoder
1348 errno = asopDecOutProcEncodeWrap(pP, pQ, pAsotCfg, frame, zO);
1349 if (errno < 0)
1350 {
1351 status = errno;
1352 }
1354 // Mark Output buffers write complete
1355 asopMarkOutBuffsWriteComplete(&pAstCfg->xOut[zO], &pAsotCfg->pIoOut[zO]);
1356 }
1358 if (status == ASOP_SOK)
1359 {
1360 // Execute Info2
1361 errno = asopDecOutProcInfo2(pP, pQ, pAsotCfg, frame);
1362 if (errno < 0)
1363 {
1364 status = errno;
1365 }
1366 }
1368 if (status == ASOP_SOK)
1369 {
1370 errno = asopDecOutProcFinalTest(pP, pQ, pAsotCfg, frame);
1371 if (errno < 0)
1372 {
1373 status = errno;
1374 }
1375 }
1377 if (status != ASOP_SOK)
1378 {
1379 // Complete Output Processing
1380 errno = asopDecOutProcComplete(pP, pQ, pAsotCfg, frame);
1381 if (errno < 0)
1382 {
1383 status = errno;
1384 }
1385 }
1387 return status;
1388 }
1390 static Int asopDecOutProcEncodeWrap(
1391 const PAF_ASOT_Params *pP,
1392 const PAF_ASOT_Patchs *pQ,
1393 PAF_ASOT_Config *pAsotCfg,
1394 Int frame,
1395 Int zO
1396 )
1397 {
1398 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1399 Int errno; // error number
1400 Int status; // status code
1401 PAF_OutBufConfig *pOutBufCfg;
1402 PAF_AudioFrame * pAf;
1404 status = ASOP_SOK;
1405 pAstCfg = pAsotCfg->pAstCfg;
1406 pOutBufCfg = &(pAstCfg->xOut[zO].outBufConfig);
1407 pAf = pAstCfg->xEnc[zO].encodeInStruct.pAudioFrame;
1409 if(pAsotCfg->pIoOut[zO].buff2 == NULL)
1410 {
1411 // Output buffer won't wrap around - to invoke the encoder once
1412 pOutBufCfg->lengthofFrame = pAf->sampleCount;
1413 pOutBufCfg->pntr.pLgInt = pAsotCfg->pIoOut[zO].buff1;
1415 // Execute encode
1416 errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1417 if (errno < 0)
1418 {
1419 status = errno;
1420 }
1421 }
1422 else
1423 {
1424 // Output buffer will wrap around - to invoke the encoder twice
1425 XDAS_Int16 sampleCountSave;
1426 PAF_AudioData *afDataAddrSave[16];
1427 PAF_AudioData **afDataAddr;
1428 int i, ch;
1430 sampleCountSave = pAf->sampleCount; // save sample count for restoring later
1432 // Invoke the encoder to write data to the end of output buffer
1433 pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size1 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
1434 pAf->sampleCount = pOutBufCfg->lengthofFrame;
1435 pOutBufCfg->pntr.pLgInt = pAsotCfg->pIoOut[zO].buff1;
1437 // Execute encode
1438 errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1439 if (errno < 0)
1440 {
1441 status = errno;
1442 }
1444 // Adjust audio frame buffer addresses for second invoking of the encoder
1445 afDataAddr = pAf->data.sample;
1446 for(i=0; i<pOutBufCfg->stride; i++)
1447 {
1448 ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
1449 afDataAddrSave[i] = afDataAddr[ch]; // save audio frame buffer addresses
1450 afDataAddr[ch] = &afDataAddr[ch][pOutBufCfg->lengthofFrame];
1451 }
1453 // Invoke the encoder to write data to the beginning of output buffer (wrapping around)
1454 pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size2 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
1455 pAf->sampleCount = pOutBufCfg->lengthofFrame;
1456 pOutBufCfg->pntr.pLgInt = pAsotCfg->pIoOut[zO].buff2;
1458 // Execute encode
1459 errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1460 if (errno < 0)
1461 {
1462 status = errno;
1463 }
1465 // Restore sample count and audio frame buffer addresses
1466 pAf->sampleCount = sampleCountSave;
1467 for(i=0; i<pOutBufCfg->stride; i++)
1468 {
1469 ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
1470 afDataAddr[ch] = afDataAddrSave[i];
1471 }
1473 pAsotCfg->pIoOut[zO].ioBuffBuf2AllocCnt++; // debug
1474 }
1476 return status;
1477 }
1479 // ASOT SM function
1480 // Purpose: Init-Sync Re-Sync state function.
1481 // Performs Init-Sync using stored Dec Reset/Info1 AFs.
1482 static Int PAF_ASOT_initSyncResync(
1483 const PAF_ASOT_Params *pP,
1484 const PAF_ASOT_Patchs *pQ,
1485 PAF_ASOT_Config *pAsotCfg,
1486 PAF_AudioFrame *pDecResetAf,
1487 PAF_AudioFrame *pDecInfo1Af,
1488 Int frame
1489 )
1490 {
1491 PAF_AST_Config *pAstCfg; // ASIT/ASOT/ASDT shared configuration
1492 Int zMS; // Stream Master index
1493 PAF_AudioFrame *pStrAf; // stream audio frame
1494 Int status; // status code
1496 pAstCfg = pAsotCfg->pAstCfg;
1497 zMS = pAstCfg->masterStr;
1498 pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
1500 // Reset audio frames
1501 resetAfs(pP, pAstCfg->xStr);
1503 //
1504 // Dec Reset re-sync using stored Dec Reset AF
1505 //
1507 // Update Stream Audio Frame.
1508 // Copy Dec Reset AF to Stream AF.
1509 outIsCpyAf(pDecResetAf, pStrAf);
1511 // Enc activate,
1512 // Enc reset
1513 status = asopDecOutProcReset(pP, pQ, pAsotCfg, frame);
1514 if (status < 0)
1515 {
1516 return status;
1517 }
1519 //
1520 // Dec Info1 re-sync using stored Dec Info1 AF
1521 //
1523 // Update Stream Audio Frame.
1524 // Copy Dec Info1 AF to Stream AF.
1525 outIsCpyAf(pDecInfo1Af, pStrAf);
1527 // outputInfo1():
1528 // - ASP chain reset,
1529 // - Enc Info,
1530 // - Start Output
1531 status = asopDecOutProcInfo1(pP, pQ, pAsotCfg, frame);
1532 if (status < 0)
1533 {
1534 return status;
1535 }
1537 return ASOP_SOK;
1538 }
1540 // ASOT SM function
1541 // Purpose: Re-select devices used for Output.
1542 // Performs Init-Sync using stored Dec Reset/Info1 AFs.
1543 static Int PAF_ASOT_reselectDevices(
1544 const PAF_ASOT_Params *pP,
1545 const PAF_ASOT_Patchs *pQ,
1546 PAF_ASOT_Config *pAsotCfg,
1547 PAF_AudioFrame *pDecResetAf,
1548 PAF_AudioFrame *pDecInfo1Af,
1549 Int frame,
1550 Bool *pOutDevSel
1551 )
1552 {
1553 Bool outDevSel;
1554 Int status;
1556 // Re-select Output devices
1557 status = PAF_ASOT_selectDevices(pP, pQ, pAsotCfg, &outDevSel);
1558 if (status < 0)
1559 {
1560 *pOutDevSel = outDevSel;
1561 return status;
1562 }
1563 else if (outDevSel == FALSE)
1564 {
1565 *pOutDevSel = outDevSel;
1566 return status;
1567 }
1568 else
1569 {
1570 // Init-Sync Resync
1571 status = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, pDecResetAf, pDecInfo1Af, frame);
1572 if (status < 0)
1573 {
1574 outDevSel = FALSE;
1575 *pOutDevSel = outDevSel;
1576 return status;
1577 }
1578 }
1580 *pOutDevSel = outDevSel;
1581 return status;
1582 }