PASDK-568: added logic and encoder wrapper to handle output buffer wrapping around
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / audioStreamOutProc.c
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
84     
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);
146     
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 );
266    
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
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
351     
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
395                     
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
403                         
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                 }
420                 
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                 }
436                 
437                 break;
438                 
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
448                     
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                     //
455                     
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
463                         
464                         // Starting over with Output device selection in case of error                        
465                         pAsotCfg->state = ASOT_STATE_SEL_OUT_DEV;
466                         break;
467                     }
468                     
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
475                         
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
483                         
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
492                         
493                         pAsotCfg->state = ASOT_STATE_INITSYNC_DEC_INFO1;
494                     }
495                 }
496                 
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                 }
512                 
513                 break;
514                 
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
524                     
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
530                         
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
538                         
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
547                         
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                 }
567                 
568                 break;
569             
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
579                     
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
585                         
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
593                         
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
602                         
603                         pAsotCfg->state = ASOT_STATE_PROC_DEC_OUT;
604                         procOutFirstTime = TRUE;
605                     }
606                 }
607             
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                 }
623                 
624                 break;
625                 
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
634                     
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                                 
646                     
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;
656                             
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                 }
675             
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                 }
684             
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                 }
692             
693                 break;
694                 
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
703                     
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
709                         
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                 }
726             
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                 }
741             
742                 break;
743                 
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++;
749                 
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
755                     
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                 }
766             
767                 break;
768                 
769             default: 
770                 gAsotInvState_Cnt++;
771                 TRACE_TERSE1("TaskAsop: invalid state, state=%u", pAsotCfg->state);
772             
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
778         
779         //
780         // Check forward (ASIT) error, TBD
781         //
782         
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)
818     Event_post(gAsotEvtHandle, Evt_Id_AsotWakeTimer);
821 void asopMcaspCallback(void* arg, MCASP_Packet *mcasp_packet)
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     }
832 // Reset audio frame pointers to original values
833 static Void resetAfPointers(
834     const PAF_ASOT_Params *pP, 
835     PAF_AST_Stream *xStr
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     }
855 // Check if Output device selected
856 static Int checkOutDevSel(
857     PAF_AST_IoOut *pOut,
858     Bool *pOutDevSel
861     *pOutDevSel = (Bool)(pOut->hMcaspChan != NULL);
862     
863     return ASOP_SOK;
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
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;
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
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;
912     
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     }
927     
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         }
937         
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             }
951             
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     }
965     
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     }
974     
975     return ASOP_SOK;
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
992     Int status;
993     
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     }
1002     
1003     // Perform Dec Reset Init-Sync
1004     status = PAF_ASOT_initSyncDecReset(pP, pQ, pAsotCfg, pDecResetAf, frame);
1005     
1006     return status;
1010 // Reset audio frame meta data elements
1011 static Void resetAfMetadata(
1012     const PAF_ASOT_Params *pP, 
1013     PAF_AST_Stream *xStr
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     }
1034 // Reset audio frames
1035 static Void resetAfs(
1036     const PAF_ASOT_Params *pP, 
1037     PAF_AST_Stream *xStr
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);
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
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
1064    
1065     pAstCfg = pAsotCfg->pAstCfg;
1066     zMD = pAstCfg->masterDec;
1067     pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
1068     
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     }
1077     
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;
1086         
1087         // Reset audio frames
1088         // FL, New IO: API for multiple streams.
1089         resetAfs(pP, pAstCfg->xStr);
1090     
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);
1095         
1096         // Enc activate
1097         // Enc reset
1098         status = asopDecOutProcReset(pP, pQ, pAsotCfg, frame);
1099         if (status < 0)
1100         {
1101             return status;
1102         }
1103         
1104         return ASOP_SOK;
1105     }
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
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
1127     
1128     pAstCfg = pAsotCfg->pAstCfg;
1129     zMD = pAstCfg->masterDec;
1130     pOutIsCtl = &pAsotCfg->pAspmCfg->outIsCtl;
1131     
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     }
1140     
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;
1149         
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
1157         
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         }
1172         
1173         return ASOP_SOK;
1174     }
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
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;
1201     
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     }
1210     
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
1233         
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.");
1239         
1240         return ASOP_SOK;
1241     }
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
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
1260     
1261     status = ASOP_SOK;
1262     pAstCfg = pAsotCfg->pAstCfg;
1263     
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     }
1277     
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         }    
1292         
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     }
1300     
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         asopDecOutProcEncodeWrap(pP, pQ, pAsotCfg, frame, zO);
1350         // Mark Output buffers write complete
1351         asopMarkOutBuffsWriteComplete(&pAstCfg->xOut[zO], &pAsotCfg->pIoOut[zO]);
1352     }
1354     if (status == ASOP_SOK)
1355     {
1356         // Execute Info2
1357         errno = asopDecOutProcInfo2(pP, pQ, pAsotCfg, frame);
1358         if (errno < 0)
1359         {
1360             status = errno;
1361         }
1362     }
1364     if (status == ASOP_SOK)
1365     {
1366         errno = asopDecOutProcFinalTest(pP, pQ, pAsotCfg, frame);
1367         if (errno < 0)
1368         {
1369             status = errno;
1370         }
1371     }
1373     if (status != ASOP_SOK)    
1374     {
1375         // Complete Output Processing
1376         errno = asopDecOutProcComplete(pP, pQ, pAsotCfg, frame);
1377         if (errno < 0)
1378         {
1379             status = errno;
1380         }
1381     }
1382     
1383     return status;
1386 static Int asopDecOutProcEncodeWrap(
1387     const PAF_ASOT_Params *pP,
1388     const PAF_ASOT_Patchs *pQ,
1389     PAF_ASOT_Config *pAsotCfg,
1390     Int frame,
1391     Int zO
1394     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
1395     Int errno;                  // error number
1396     Int status;                 // status code
1397     PAF_OutBufConfig *pOutBufCfg;
1398     PAF_AudioFrame * pAf;
1400     status = ASOP_SOK;
1401     pAstCfg = pAsotCfg->pAstCfg;
1402     pOutBufCfg = &(pAstCfg->xOut[zO].outBufConfig);
1403     pAf = pAstCfg->xEnc[zO].encodeInStruct.pAudioFrame;
1405     if(pAsotCfg->pIoOut[zO].buff2 == NULL)
1406     {
1407         // Output buffer won't wrap around - to invoke the encoder once
1408         pOutBufCfg->lengthofFrame = pAf->sampleCount;
1409         pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff1;
1411         // Execute encode
1412         errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1413         if (errno < 0)
1414         {
1415             status = errno;
1416         }
1417     }
1418     else
1419     {
1420         // Output buffer will wrap around - to invoke the encoder twice
1421         XDAS_Int16 sampleCountSave;
1422         PAF_AudioData *afDataAddrSave[16];
1423         PAF_AudioData **afDataAddr;
1424         int i, ch;
1426         sampleCountSave = pAf->sampleCount;  // save sample count for restoring later
1428         // Invoke the encoder to write data to the end of output buffer
1429         pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size1 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
1430         pAf->sampleCount = pOutBufCfg->lengthofFrame;
1431         pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff1;
1433         // Execute encode
1434         errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1435         if (errno < 0)
1436         {
1437             status = errno;
1438         }
1440         // Adjust audio frame buffer addresses for second invoking of the encoder
1441         afDataAddr = pAf->data.sample;
1442         for(i=0; i<pOutBufCfg->stride; i++)
1443         {
1444             ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
1445             afDataAddrSave[i] = afDataAddr[ch];   // save audio frame buffer addresses
1446             afDataAddr[ch] = &afDataAddr[ch][pOutBufCfg->lengthofFrame];
1447         }
1449         // Invoke the encoder to write data to the beginning of output buffer (wrapping around)
1450         pOutBufCfg->lengthofFrame = pAsotCfg->pIoOut[zO].size2 / (pOutBufCfg->stride * pOutBufCfg->sizeofElement);
1451         pAf->sampleCount = pOutBufCfg->lengthofFrame;
1452         pOutBufCfg->pntr.pLgInt   = pAsotCfg->pIoOut[zO].buff2;
1454         // Execute encode
1455         errno = asopDecOutProcEncode(pP, pQ, pAsotCfg, frame);
1456         if (errno < 0)
1457         {
1458             status = errno;
1459         }
1461         // Restore sample count and audio frame buffer addresses
1462         pAf->sampleCount = sampleCountSave;
1463         for(i=0; i<pOutBufCfg->stride; i++)
1464         {
1465             ch = pAstCfg->xEnc[zO].encodeStatus.channelMap.from[i];
1466             afDataAddr[ch] = afDataAddrSave[i];
1467         }
1469         pAsotCfg->pIoOut[zO].ioBuffBuf2AllocCnt++; // debug
1470     }
1472     return status;
1475 // ASOT SM function
1476 //   Purpose:   Init-Sync Re-Sync state function.
1477 //              Performs Init-Sync using stored Dec Reset/Info1 AFs.
1478 static Int PAF_ASOT_initSyncResync(
1479     const PAF_ASOT_Params *pP, 
1480     const PAF_ASOT_Patchs *pQ, 
1481     PAF_ASOT_Config *pAsotCfg,
1482     PAF_AudioFrame *pDecResetAf,
1483     PAF_AudioFrame *pDecInfo1Af,
1484     Int frame
1487     PAF_AST_Config *pAstCfg;    // ASIT/ASOT/ASDT shared configuration
1488     Int zMS;                    // Stream Master index
1489     PAF_AudioFrame *pStrAf;     // stream audio frame
1490     Int status;                 // status code
1492     pAstCfg = pAsotCfg->pAstCfg;
1493     zMS = pAstCfg->masterStr;
1494     pStrAf = pAstCfg->xStr[zMS].pAudioFrame;
1495         
1496     // Reset audio frames
1497     resetAfs(pP, pAstCfg->xStr);
1498     
1499     //
1500     // Dec Reset re-sync using stored Dec Reset AF
1501     //
1502     
1503     // Update Stream Audio Frame.
1504     // Copy Dec Reset AF to Stream AF.
1505     outIsCpyAf(pDecResetAf, pStrAf);
1506     
1507     // Enc activate,
1508     // Enc reset
1509     status = asopDecOutProcReset(pP, pQ, pAsotCfg, frame);
1510     if (status < 0)
1511     {
1512         return status;
1513     }
1514     
1515     //
1516     // Dec Info1 re-sync using stored Dec Info1 AF
1517     //
1518     
1519     // Update Stream Audio Frame.
1520     // Copy Dec Info1 AF to Stream AF.
1521     outIsCpyAf(pDecInfo1Af, pStrAf);
1522     
1523     // outputInfo1():
1524     //      - ASP chain reset,
1525     //      - Enc Info,
1526     //      - Start Output
1527     status = asopDecOutProcInfo1(pP, pQ, pAsotCfg, frame);
1528     if (status < 0)
1529     {
1530         return status;
1531     }
1532     
1533     return ASOP_SOK;    
1536 // ASOT SM function
1537 //   Purpose:   Re-select devices used for Output.
1538 //              Performs Init-Sync using stored Dec Reset/Info1 AFs.
1539 static Int PAF_ASOT_reselectDevices(
1540     const PAF_ASOT_Params *pP, 
1541     const PAF_ASOT_Patchs *pQ, 
1542     PAF_ASOT_Config *pAsotCfg,
1543     PAF_AudioFrame *pDecResetAf,
1544     PAF_AudioFrame *pDecInfo1Af,
1545     Int frame, 
1546     Bool *pOutDevSel
1549     Bool outDevSel;
1550     Int status;
1551     
1552     // Re-select Output devices
1553     status = PAF_ASOT_selectDevices(pP, pQ, pAsotCfg, &outDevSel);
1554     if (status < 0)
1555     {
1556         *pOutDevSel = outDevSel;
1557         return status;
1558     }
1559     else if (outDevSel == FALSE)
1560     {
1561         *pOutDevSel = outDevSel;
1562         return status;
1563     }
1564     else
1565     {
1566         // Init-Sync Resync
1567         status = PAF_ASOT_initSyncResync(pP, pQ, pAsotCfg, pDecResetAf, pDecInfo1Af, frame);
1568         if (status < 0)
1569         {
1570             outDevSel = FALSE;
1571             *pOutDevSel = outDevSel;
1572             return status;
1573         }
1574     }
1575     
1576     *pOutDevSel = outDevSel;
1577     return status;