0d2c6726ef2bd4d29c637124acf3fe755d7d24bf
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / aspDecOpCircBuf_master.c
2 /*
3 Copyright (c) 2017, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 #include <string.h> // for memset()
37 #include <xdc/std.h>
38 #include <xdc/runtime/Log.h>
39 #include <ti/sysbios/hal/Cache.h>
40 #include <ti/uia/events/UIAEvt.h>
41 #include <ti/ipc/GateMP.h>
43 #include "common.h"
44 #include "paftyp.h"
45 #include "pafdec.h"
46 #include "aspDecOpCircBuf_master.h"
48 #include "evmc66x_gpio_dbg.h" // Debug
50 #ifdef CB_RW_OP_CAP_PP // debug
51 // Global variables
52 Uint32 *gCB_samples_op = NULL;
53 Uint8 *gCB_op_owner = NULL;
54 Uint32 *gCB_opCnt = 0;
55 Uint8 *gCB_afRdIdx = NULL;
56 Uint8 *gCB_afWrtIdx = NULL;
57 Uint8 *gCB_numAfCb = NULL;
58 #endif
60 #if 0
61 // Generate mute AF on circular buffer read
62 static Void cbReadAfMute(
63     PAF_AudioFrame *pAfRd,      // audio frame into which to read
64     Int16 strFrameLen           // stream frame length (output transaction size)
65 );
66 #endif
68 #if 0
69 // Init last audio frame configuration info 
70 static Void cbInitLastAfInfo(
71     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
72 );
73 #endif
75 // Update last audio frame configuration info 
76 static Void cbUpdateLastAfInfo(
77     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
78     PAF_AudioFrame *pAfUpd      // audio frame used for update
79 );
81 // Generate mute AF on circular buffer read using the last AF configuration info 
82 static Void cbReadMuteWithLastAfInfo(
83     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
84     PAF_AudioFrame *pAfRd         // audio frame into which to read
85 );
87 #if 0 // FL: moved to common
88 // Initialize circular buffer control
89 Int cbCtlInit(
90     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
91     Int8 numCb,                         // number of circular buffers
92     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
93 )
94 {
95     GateMP_Params gateParams;
96     GateMP_Handle gateHandle;
97     
98     GateMP_Params_init(&gateParams);
99     gateParams.localProtect = GateMP_LocalProtect_THREAD;
100     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
101     gateParams.name = ASP_DECODE_CB_GATE_NAME;
102     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
103     gateHandle = GateMP_create(&gateParams);
104     if (gateHandle != NULL)
105     {
106         pCbCtl->gateHandle = gateHandle;
107     }
108     else
109     {
110         pCbCtl->gateHandle = NULL;
111         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
112     }
113     
114     pCbCtl->numCb = numCb;          // init number of circular buffers
115     pCbCtl->pXDecOpCb = pXDecOpCb;  // init base address of circular buffers
116     
117     return ASP_DECOP_CB_SOK;    
119 #endif
121 // Initialize circular buffer
122 Int cbInit(
123     PAF_AST_DecOpCircBuf *pCb
126 #if 0 // FL: unused
127     PAF_AudioFrame *pAfCb;
128     PAF_AudioData *pPcmBuf;
129     UInt8 *pMetaBuf;
130     Int8 n;
131     Int8 i;
133     // set source select
134     pCb->sourceSel = DEF_SOURCE_SEL;
136     // set input frame length
137     pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
138     
139     // set output frame length
140     pCb->strFrameLen = DEF_STR_FRAME_LEN;
141     
142     // initialize circular buffer maximum number of audio frames
143     pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD; //ASP_DECOP_CB_MAX_NUM_AF_PCM;
144     pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
145     pCb->afRdIdx = 0;
146     pCb->pcmRdIdx = 0;
148     // Initialize CB primed flag
149     pCb->primedFlag = 0;
150     // Initialize delta samples
151     pCb->deltaSamps = 0;
152     
153     // set default value to PCM configuration
154     pCb->maxAFChanNum   = ASP_DECOP_CB_MAX_NUM_PCM_CH;
155     pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
156     // initialize audio frames
157     for (n=0; n<pCb->maxNumAfCb; n++)
158     {
159         pAfCb = &pCb->afCb[n];
160         pAfCb->sampleDecode = PAF_SOURCE_PCM;
161         PAF_PROCESS_ZERO(pAfCb->sampleProcess);
162         pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
163         pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
164         pAfCb->channelConfigurationRequest.full = 0;
165         pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
166         pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
167         pAfCb->channelConfigurationStream.full = 0;
168         pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
169         pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
170     }
172     // initialize circular buffer current number of frames
173     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
174     
175     // initialize audio frame PCM buffers
176     pPcmBuf = pCb->pcmBuf;
177     pMetaBuf = pCb->metaBuf;
178     for (n=0; n<pCb->maxNumAfCb; n++)
179     {
180         pAfCb = &pCb->afCb[n];
181         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
182         pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
183         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
184         {
185             pAfCb->data.sample[i] = pPcmBuf;
186             memset(pAfCb->data.sample[i], 0, DEF_DEC_OP_FRAME_LEN);
187             pPcmBuf += DEF_DEC_OP_FRAME_LEN;
188             
189             pAfCb->data.samsiz[i] = 0;
190         }
191         
192         // write metadata information updated by decoder
193         pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
194         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
195         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
196         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
197         
198         // Initialize metadata buffers
199         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
200         {
201             pAfCb->pafPrivateMetadata[i].offset = 0; 
202             pAfCb->pafPrivateMetadata[i].size   = 0; 
203             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
204             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
205         }
206     }
207     
208     // reset read/write flags
209     pCb->writerActiveFlag = 0;
210     pCb->readerActiveFlag = 0;
211     pCb->drainFlag = 0;
212     
213     // reset stats
214     pCb->readAfWriterInactiveCnt = 0;
215     pCb->readAfNdCnt = 0;
216     pCb->wrtAfReaderInactiveCnt = 0;
217     pCb->wrtAfZeroSampsCnt = 0;
218     pCb->errUndCnt = 0;
219     pCb->errOvrCnt = 0;
220     
221     #ifdef CB_RW_OP_CAP_PP // debug
222     // Get address in global variables
223     gCB_samples_op = pCb->cb_samples_op;
224     gCB_op_owner = pCb->cb_op_owner;
225     gCB_opCnt = &pCb->cb_opCnt;
226     gCB_afRdIdx = pCb->cb_afRdIdx;
227     gCB_afWrtIdx = pCb->cb_afWrtIdx;
228     gCB_numAfCb = pCb->cb_numAfCb;
229     #endif
231     cbInitLastAfInfo(&pCb->lastAf);
233     // Write back circular buffer configuration
234     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
235     // Write back AF circular buffer
236     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
237     // Write back PCM data
238     for (n=0; n<pCb->maxNumAfCb; n++)
239     {
240         pAfCb = &pCb->afCb[n];
241         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
242         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
243         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
244         {
245             Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
246         }
247     }
248     Cache_wait();
249 #endif
251     // set source select
252     pCb->sourceSel = PAF_SOURCE_UNKNOWN;
254     #ifdef CB_RW_OP_CAP_PP // debug
255     // Get address in global variables
256     gCB_samples_op = pCb->cb_samples_op;
257     gCB_op_owner = pCb->cb_op_owner;
258     gCB_opCnt = &pCb->cb_opCnt;
259     gCB_afRdIdx = pCb->cb_afRdIdx;
260     gCB_afWrtIdx = pCb->cb_afWrtIdx;
261     gCB_numAfCb = pCb->cb_numAfCb;
262     #endif
263     
264     // Write back circular buffer configuration
265     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
266     Cache_wait();
268     return ASP_DECOP_CB_SOK;
271 #if 0 // FL: moved to ARM
272 // debug
273 //Int8 gCbInitSourceSelCnt=0;
274 //Int8 gCbInitSourceSelThdCnt=0;
276 // Initialize circular buffer based on selected source
277 Int cbInitSourceSel(
278     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
279     Int8 cbIdx,                         // decoder output circular buffer index
280     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
281     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
282     Int16 strFrameLen,                  // stream frame length (PCM samples)
283     Int8 resetRwFlags                   // whether to reset reader, writer, and drain flags
286     IArg key;
287     GateMP_Handle gateHandle;
288     PAF_AST_DecOpCircBuf *pCb;
289     PAF_AudioFrame *pAfCb;
290     PAF_AudioData *pPcmBuf;
291     UInt8 *pMetaBuf;
292     Int8 n;
293     Int8 i;
295     //gCbInitSourceSelCnt++; // debug
296     
297     // Get gate handle
298     gateHandle = pCbCtl->gateHandle;
299     // Enter gate
300     key = GateMP_enter(gateHandle);
302     // Get circular buffer base pointer
303     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
304     
305     // Invalidate circular buffer configuration
306     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
307     Cache_wait();
309     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
311     // set source select
312     pCb->sourceSel = sourceSelect;
314     // set input frame length
315     pCb->decOpFrameLen = decOpFrameLen;
316     
317     // set output frame length
318     pCb->strFrameLen = strFrameLen;
320     //pCb->afInitialLag = 0;  // default No lag
321     //pCb->afLagIdx = 0;
322     // Initialize CB primed flag
323     pCb->primedFlag = 0;
324     // Initialize delta samples
325     pCb->deltaSamps = 0;
326     
327     // initialize circular buffer maximum number of audio frames
328     if (sourceSelect == PAF_SOURCE_PCM)
329     {
330         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
331         
332         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
333         // Initialize target nominal delay
334         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
335         
336         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
337         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
338         pCb->pcmRdIdx = 0;
339         
340         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
341         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
342         
343         // initialize audio frames
344         for (n=0; n<pCb->maxNumAfCb; n++)
345         {
346             pAfCb = &pCb->afCb[n];
347             pAfCb->sampleDecode = sourceSelect;
348             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
349             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
350             pAfCb->sampleCount = decOpFrameLen;
351             pAfCb->channelConfigurationRequest.full = 0;
352             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
353             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
354             pAfCb->channelConfigurationStream.full = 0;
355             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
356             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
357             
358             // write metadata information updated by decoder
359             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
360             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
361             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
362             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
363         }
364     }
365     else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
366     {
367         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
368         
369         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
370         // Initialize target nominal delay
371         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kDDP;
372         
373         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
374         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
375         pCb->pcmRdIdx = 0;
376         
377         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
378         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
379         
380         // initialize audio frames
381         for (n=0; n<pCb->maxNumAfCb; n++)
382         {
383             pAfCb = &pCb->afCb[n];
384             pAfCb->sampleDecode = sourceSelect;
385             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
386             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
387             pAfCb->sampleCount = decOpFrameLen;
388             pAfCb->channelConfigurationRequest.full = 0;
389             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
390             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
391             pAfCb->channelConfigurationStream.full = 0;
392             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
393             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
394             
395             // write metadata information updated by decoder
396             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
397             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
398             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
399             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
400         }
401     }
402     else if (sourceSelect == PAF_SOURCE_THD)
403     {
404         //gCbInitSourceSelThdCnt++; //debug
405         
406         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
407         
408         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
409         // Initialize target nominal delay
410         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
411         
412         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
413         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
414         pCb->pcmRdIdx = 0;
415         
416         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
417         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
418         
419         // initialize audio frames
420         for (n=0; n<pCb->maxNumAfCb; n++)
421         {
422             pAfCb = &pCb->afCb[n];
423             pAfCb->sampleDecode = sourceSelect;
424             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
425             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
426             pAfCb->sampleCount = decOpFrameLen;
427             pAfCb->channelConfigurationRequest.full = 0;
428             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
429             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
430             pAfCb->channelConfigurationStream.full = 0;
431             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
432             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
433             
434             // write metadata information updated by decoder
435             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
436             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
437             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
438             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
439         }
440     }
441     else
442     {
443         SW_BREAKPOINT;
444         
445         // Leave the gate
446         GateMP_leave(gateHandle, key);
448         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
449     }
451     // initialize circular buffer current number of frames
452     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
453     
454     // initialize audio frame PCM buffers
455     pPcmBuf = pCb->pcmBuf;
456     pMetaBuf = pCb->metaBuf;
457     for (n=0; n<pCb->maxNumAfCb; n++)
458     {
459         pAfCb = &pCb->afCb[n];
460         pAfCb->data.nChannels = pCb->maxAFChanNum;
461         pAfCb->data.nSamples = decOpFrameLen;
462         for (i=0; i<pCb->maxAFChanNum; i++)
463         {
464             pAfCb->data.sample[i] = pPcmBuf;
465             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
466             pPcmBuf += pCb->maxAFSampCount;
467             
468             pAfCb->data.samsiz[i] = 0;
469         }
470         
471         // Initialize metadata buffers
472         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
473         {
474             pAfCb->pafPrivateMetadata[i].offset = 0; 
475             pAfCb->pafPrivateMetadata[i].size   = 0; 
476             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
477             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
478         }
479     }
480     
481     // reset read/write flags
482     if (resetRwFlags)
483     {
484         pCb->writerActiveFlag = 0;
485         pCb->readerActiveFlag = 0;
486         pCb->drainFlag = 0;
487     }
488     
489     // reset stats
490     pCb->readAfWriterInactiveCnt = 0;
491     pCb->readAfNdCnt = 0;
492     pCb->wrtAfReaderInactiveCnt = 0;
493     pCb->wrtAfZeroSampsCnt = 0;
494     pCb->errUndCnt = 0;
495     pCb->errOvrCnt = 0;
496     
497     // Write back circular buffer configuration
498     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
499     // Write back AF circular buffer
500     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
501     // Write back PCM data
502     for (n=0; n<pCb->maxNumAfCb; n++)
503     {
504         pAfCb = &pCb->afCb[n];
505         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
506         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
507         for (i=0; i<pCb->maxAFChanNum; i++)
508         {
509             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
510         }
511     }
512     Cache_wait();
514     // Leave the gate
515     GateMP_leave(gateHandle, key);
516     
517     return ASP_DECOP_CB_SOK;
519 #endif
521 // Initialize circular buffer for Stream reads
522 Int cbInitStreamRead(
523     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
524     Int8 cbIdx                          // decoder output circular buffer index
527     IArg key;
528     GateMP_Handle gateHandle;
529     PAF_AST_DecOpCircBuf *pCb;
530     
531     // Get gate handle
532     gateHandle = pCbCtl->gateHandle;
533     // Enter gate
534     key = GateMP_enter(gateHandle);
536     // Get circular buffer base pointer
537     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
538     
539     // Invalidate circular buffer configuration
540     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
541     Cache_wait();
543     // Set output frame length
544     pCb->strFrameLen = pCb->cbStatus.strFrameLen;
546     // Write back circular buffer configuration
547     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
548     Cache_wait();
550     // Leave the gate
551     GateMP_leave(gateHandle, key);
552     
553     //return ret;
554     return ASP_DECOP_CB_SOK;
557 // Start reads from circular buffer
558 Int cbReadStart(
559     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
560     Int8 cbIdx                          // decoder output circular buffer index
563     IArg key;
564     GateMP_Handle gateHandle;
565     PAF_AST_DecOpCircBuf *pCb;
567     // Get gate handle
568     gateHandle = pCbCtl->gateHandle;
569     // Enter gate
570     key = GateMP_enter(gateHandle);
572     // Get circular buffer base pointer
573     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
574     
575     // Invalidate circular buffer configuration
576     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
577     Cache_wait();
578     
579     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
581     // update flags
582     pCb->readerActiveFlag = 1;
583     
584     // Write back circular buffer configuration
585     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
586     Cache_wait();
588     // Leave the gate
589     GateMP_leave(gateHandle, key);
591     return ASP_DECOP_CB_SOK;
594 // Stop reads from circular buffer
595 Int cbReadStop(
596     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
597     Int8 cbIdx                          // decoder output circular buffer index
600     IArg key;
601     GateMP_Handle gateHandle;
602     PAF_AST_DecOpCircBuf *pCb;
604     // Get gate handle
605     gateHandle = pCbCtl->gateHandle;
606     // Enter gate
607     key = GateMP_enter(gateHandle);
609     // Get circular buffer base pointer
610     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
612     // Invalidate circular buffer configuration
613     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
614     Cache_wait();
615     
616     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
618     // update flags
619     pCb->readerActiveFlag = 0;
620     
621     // Write back circular buffer configuration
622     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
623     Cache_wait();
625     // Leave the gate
626     GateMP_leave(gateHandle, key);
628     return ASP_DECOP_CB_SOK;
631 // debug
632 //Int16 gDeltaSampsBuf[20];
633 //Int8 gDeltaSampsBufIdx=0;
635 // Read audio frame from circular buffer
636 Int cbReadAf(
637     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
638     Int8 cbIdx,                         // decoder output circular buffer index
639     PAF_AudioFrame *pAfRd               // audio frame into which to read
642     IArg key;
643     GateMP_Handle gateHandle;           // CB gate handle to arbitrate CB r/w access
644     PAF_AST_DecOpCircBuf *pCb;          // pointer to CB
645     PAF_AudioFrame *pAfCb;              // pointer to current CB AF
646     PAF_ChannelMask_HD streamMask;      // CB AF stream mask
647     Int16 numSampsRd;                   // number of samples to read from current CB AF
648     Int16 totNumSampsRd;                // total number of samples read from CB
649     Int16 pcmWrtIdx;                    // read audio frame PCM write index
650     Int8 prvMdWrtIdx;                   // read audio frame metadata write index
651     Int8 i;
652     Int16 j;
653     
654     // Get gate handle
655     gateHandle = pCbCtl->gateHandle;
656     // Enter gate
657     key = GateMP_enter(gateHandle);
659     // Get circular buffer base pointer
660     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
662     // Invalidate circular buffer configuration.
663     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
664     Cache_wait();
666     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
668     //
669     // Check (writerActiveFlag,drainFlag)=(1,1)
670     //
671     if ((pCb->writerActiveFlag == 1) && (pCb->drainFlag == 1))
672     {
673         //
674         // This shouldn't occur:
675         // writer is active AND draining circular buffer
676         //
677         
678         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, drainFlag=%d", pCb->writerActiveFlag, pCb->drainFlag); // debug
679         SW_BREAKPOINT; // debug
680         
681         // Leave the gate
682         GateMP_leave(gateHandle, key);
683         
684         return ASP_DECOP_CB_READ_INVSTATE;
685     }
687     //
688     // Check (writerActiveFlag,drainFlag)=(0,0)
689     //
690     //if (((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
691     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0))
692     {
693         //
694         // Writer inactive, not draining circular buffer.
695         // Skip UNDerflow check, mute output.
696         //
697         
698         pCb->readAfWriterInactiveCnt++;
699         
700         // Mute output if write inactive and not draining CB
701         //cbReadAfMute(pAfRd, pCb->strFrameLen);
702         cbReadMuteWithLastAfInfo(pCb, pAfRd);
703         
704         // Write back circular buffer configuration.
705         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
706         Cache_wait();
708         // Leave the gate
709         GateMP_leave(gateHandle, key);
711         return ASP_DECOP_CB_SOK;
712     }
714     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 1))
715     {
716         //
717         // Writer inactive, but remaining frames in circular buffer.
718         // Update drain flag.
719         //
720         
721         if (pCb->numAfCb <= 0)
722         {
723             pCb->drainFlag = 0;
725             // Mute output if CB drained
726             cbReadMuteWithLastAfInfo(pCb, pAfRd);
728             // Write back circular buffer configuration.
729             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
730             Cache_wait();    
732             // Leave the gate
733             GateMP_leave(gateHandle, key);
735             return ASP_DECOP_CB_SOK;
736         }
737     }
738     
739     //
740     // Hold off read of PCM samples from CB until Nominal Delay satisfied
741     //
742     if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
743     {
744         pCb->readAfNdCnt++;
745         
746         cbReadMuteWithLastAfInfo(pCb, pAfRd);
747         
748         // Write back circular buffer configuration.
749         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
750         Cache_wait();
751         
752         // Leave the gate
753         GateMP_leave(gateHandle, key);
755         return ASP_DECOP_CB_SOK;
756     }
757     
758     //
759     // (writerActiveFlag,drainFlag)= (0,0) and (1,1) states checked above
760     // (writerActiveFlag,drainFlag)=(1,0) and (0,1) states are left
761     // Checking (writerActiveFlag,drainFlag)=(1,0) state here
762     //
763     if (pCb->writerActiveFlag == 1)
764     {
765         // check underflow
766         if (pCb->numAfCb <= 0)
767         {
768             // 
769             // Increment underflow count
770             //
771             pCb->errAfUndCnt++;
772             // Mute output on underflow
773             //cbReadAfMute(pAfRd, pCb->strFrameLen);
774             cbReadMuteWithLastAfInfo(pCb, pAfRd);
775             //SW_BREAKPOINT; // debug
776             
777 #if 0 // also for CB_RW_OP_CAP_PP (***) FL: shows timing of CB underflow
778             // debug
779             {
780                 static Uint8 toggleState = 0;
781                 if (toggleState == 0)
782                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
783                 else
784                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
785                 toggleState = ~(toggleState);
786             }
787 #endif
789             #ifdef CB_RW_OP_CAP_PP // debug
790             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
791             {
792                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
793                 {
794                     // log sample count
795                     pCb->cb_samples_op[pCb->cb_opCnt] = 0;  // due to underflow
796                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
797                     // log idxs
798                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
799                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
800                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
801                     pCb->cb_opCnt++;
802                 }
803             }
804             #endif
806             // Write back circular buffer configuration.
807             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
808             Cache_wait();    
809             
810             // Leave the gate
811             GateMP_leave(gateHandle, key);
812             
813             return ASP_DECOP_CB_AF_READ_UNDERFLOW;
814         }
815     }
816     
817     //
818     // Checking (writerActiveFlag,drainFlag)=(1,0) state above and here
819     // Checking (writerActiveFlag,drainFlag)=(0,1) state here
820     //
821     if ((pCb->writerActiveFlag == 1) || (pCb->drainFlag == 1))
822     {
823         //
824         // Writer active or draining remaining frames in circular buffer.
825         // Read next audio frame.
826         //
828         //
829         // Read Audio Frame from CB Audio Frames.
830         // Read PCM & associated metadata from CB AFs until Read AF is filled.
831         //
832         // If multiple CB AFs are read in creating Read AF, CB AF parameters 
833         // can *change* between read CB AFs. Since only one Read AF is produced 
834         // per CB read, this is a "data collision", i.e. can't have more than 
835         // one set of CB AF parameters in Read AF.
836         //
837         // Currently applying parameters from earliest read CB AF to Read Af.
838         // This can result in delay (or skip) w.r.t. application of additional 
839         // CB AF parameters not used for creating Read AF. This is reasonable 
840         // given there's no way to "interpolate" AF parameters, e.g. how to 
841         // interpolation change in in bit-stream metadata type, or CC stream?
842         //
843         
844         // Get pointer to current CB Audio Frame
845         pAfCb = &pCb->afCb[pCb->afRdIdx];
847         // Cache invalidate CB AF
848         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
849         Cache_wait();
850         
851         // Read CB AF information updated by decoder
852         pAfRd->sampleDecode = pAfCb->sampleDecode;
853         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
854         pAfRd->sampleRate = pAfCb->sampleRate;
855         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
856         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
857         // Read CB AF bit-stream metadata information updated by decoder
858         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if private metadata is attached. */
859         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
860         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
861         //Following parameters are used in DTSX
862         pAfRd->mode = pAfCb->mode;                                       /* mode is used in DTSX to pass info to PARMA */
863         pAfRd->numChansUsedForMetadata = pAfCb->numChansUsedForMetadata; /* if metadata is used in DTSX */
864         pAfRd->pafBsFixedData = pAfCb->pafBsFixedData;                   /* if true, do not convert float to fixed in DTSX metadata transfer */
865         pAfRd->root = pAfCb->root;                                       /* used for channel MASK in DTSX. BAD IDEA, need fix */
866         pAfRd->resetCount = pAfCb->resetCount;                           /* used for communication between DTSX and PARMA */
868         // Compute stream mask for current CB AF.
869         // Mask indicates which channels are present in AF.
870         // Mask needed for cache invalidate and read of PCM samples in AF.
871         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
873         // Cache invalidate CB AF samsiz (volume scaling exponent) array
874         Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
875         Cache_wait();
876         
877                 if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
878                 {
879                         //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
880                         for (i = 0; i < pAfCb->data.nChannels; i++)
881                         { 
882                            pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
883                         }
884                 }
885                 else
886                 {
887                         // Read CB AF samsiz array
888                         for (i = 0; i < pCb->maxAFChanNum; i++)
889                         {
890                                 if ((streamMask >> i) & 0x1)
891                                 {
892                                         pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
893                                 }
894                         }
895                 }
896         // FL: brute force clear of Read AF PCM data
897         // Reset Read AF PCM data
898         //for (i = 0; i < pCb->maxAFChanNum; i++)
899         //{
900         //    if ((streamMask >> i) & 0x1)
901         //    {
902         //        memset(pAfRd->data.sample[i], 0, pCb->strFrameLen);
903         //    }
904         //}
905         
906         // FL: This brute force approach shouldn't be necessary if
907         //     decoders properly set, and downstream components
908         //     properly use, number of private metadata in frame
909         // Reset Read AF metadata
910         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
911         {
912             pAfRd->pafPrivateMetadata[i].offset = 0;
913             pAfRd->pafPrivateMetadata[i].size   = 0;
914         }
915         
916         totNumSampsRd = 0;  // init total number of samples read from CB
917         pcmWrtIdx = 0;      // init Read AF PCM write index
918         prvMdWrtIdx = 0;    // init Read AF metadata write index
919         while ((totNumSampsRd < pCb->strFrameLen) && (pCb->numAfCb > 0))
920         {
921             // Compute how many PCM samples can be read from CB AF
922             //  Number of samples left in current CB AF: pAfCb->sampleCount - pCb->pcmRdIdx
923             //  Number of samples left to write to Read AF: pCb->strFrameLen - totNumSampsRd
924             numSampsRd = (pAfCb->sampleCount - pCb->pcmRdIdx) < (pCb->strFrameLen - totNumSampsRd) ? 
925                 (pAfCb->sampleCount - pCb->pcmRdIdx) : (pCb->strFrameLen - totNumSampsRd);
927             // Cache invalidate CB AF PCM sample channel pointers
928             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
929             Cache_wait();
931             // Cache invalidate CB AF PCM samples
932                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
933                         {
934                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
935                                 for (i = 0; i < pAfCb->data.nChannels; i++)
936                                 { 
937                                         Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], numSampsRd*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
938                                 }
939                         }
940                         else
941                         {
942                                 for (i = 0; i < pCb->maxAFChanNum; i++)
943                                 {
944                                         if ((streamMask >> i) & 0x1)
945                                         {
946                                                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], numSampsRd*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
947                                         }
948                                 }
949                         }
950             Cache_wait();
952             // Read PCM samples from CB AF
953                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
954                         {
955                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
956                                 for (i = 0; i < pAfCb->data.nChannels; i++)
957                                 { 
958                                         for (j = 0; j < numSampsRd; j++)
959                                         {
960                                                 pAfRd->data.sample[i][pcmWrtIdx+j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
961                                         }
962                                 }
963                         }
964                         else
965                         {
966                                 for (i = 0; i < pCb->maxAFChanNum; i++)
967                                 {
968                                         if ((streamMask >> i) & 0x1)
969                                         {
970                                                 for (j = 0; j < numSampsRd; j++)
971                                                 {
972                                                         pAfRd->data.sample[i][pcmWrtIdx+j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
973                                                 }
974                                         }
975                                 }
976                         }
977             // Cache invalidate CB AF unused metadata
978             for (i = pCb->prvMdRdIdx; i < pAfCb->numPrivateMetadata; i++)
979             {
980                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
981             }
982             Cache_wait();
984             // Read CB AF metadata
985             while (((pCb->prvMdRdIdx < pAfCb->numPrivateMetadata) && 
986                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset >= pCb->pcmRdIdx) &&
987                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset < (pCb->pcmRdIdx + numSampsRd)) &&
988                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size)) &&
989                 (prvMdWrtIdx < PAF_MAX_NUM_PRIVATE_MD))
990             {
991                 // Write Read AF metadata offset.
992                 //  Compute relative offset of PCM samples being read from CB AF.
993                 //  Compute absolute offset of PCM samples written to Read AF by 
994                 //  adding relative offset to Read AF PCM write index.
995                 pAfRd->pafPrivateMetadata[prvMdWrtIdx].offset = 
996                     (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset - pCb->pcmRdIdx) +   // offset relative to samples being read from CB AF
997                     pcmWrtIdx;                                                              // absolute offset into samples being written to read AF
998                 // Write Read AF metadata size    
999                 pAfRd->pafPrivateMetadata[prvMdWrtIdx].size = pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size;
1000                 // Write Read AF metadata payload
1001                 memcpy(pAfRd->pafPrivateMetadata[prvMdWrtIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size);
1002                 
1003                 pCb->prvMdRdIdx++;  // update CB metadata read index
1004                 prvMdWrtIdx++;      // update CB metadata write index
1005             }
1006             
1007             // Update CB control
1008             pCb->pcmRdIdx += numSampsRd; // update PCM read index
1009             if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
1010             {
1011                 // Finished reading PCM samples from current CB AF.
1012                 // Move to next AF in CB.
1013                 
1014                 // Update audio frame read index.
1015                 // Wrap index if required.
1016                 pCb->afRdIdx++;
1017                 if (pCb->afRdIdx >= pCb->maxNumAfCb)
1018                 {
1019                     pCb->afRdIdx = 0;
1020                 }
1021                 
1022                 // Reset PCM read index
1023                 pCb->pcmRdIdx = 0;
1024                 // Reset metadata read index
1025                 pCb->prvMdRdIdx = 0;
1026                 
1027                 // Update number of audio frames in circular buffer
1028                 pCb->numAfCb--;
1029             }
1030             
1031             // Update PCM write index
1032             pcmWrtIdx += numSampsRd;
1034             // Update total number of samples read
1035             totNumSampsRd += numSampsRd;
1036             
1037             if (totNumSampsRd < pCb->strFrameLen)
1038             {
1039                 //
1040                 // Need to read another AF from CB to obtain all PCM/metadata for Read AF
1041                 //
1042                 
1043                 // Get pointer to current CB Audio Frame
1044                 pAfCb = &pCb->afCb[pCb->afRdIdx];
1045                 
1046                 // Cache invalidate CB AF
1047                 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
1048                 Cache_wait();
1049             }
1050         }
1051        
1052         pAfRd->sampleCount = totNumSampsRd;         // write Read AF sample count
1053         pAfRd->numPrivateMetadata = prvMdWrtIdx;    // write Read AF number of metadata
1054         
1055         pCb->numPcmSampsPerCh -= totNumSampsRd;     // update PCM samples per channel
1056        
1057         if (totNumSampsRd < pCb->strFrameLen)
1058         {
1059             // Clear remaining Read AF PCM samples
1060                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
1061                         {
1062                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
1063                                 for (i = 0; i < pAfCb->data.nChannels; i++)
1064                                 { 
1065                                         memset(&pAfRd->data.sample[i][pcmWrtIdx], 0, (pCb->strFrameLen-totNumSampsRd));
1066                                 }
1067                         }
1068                         else{
1069                                 for (i = 0; i < pCb->maxAFChanNum; i++)
1070                                 {
1071                                         if ((streamMask >> i) & 0x1)
1072                                         {
1073                                                 memset(&pAfRd->data.sample[i][pcmWrtIdx], 0, (pCb->strFrameLen-totNumSampsRd));
1074                                         }
1075                                 }
1076                         }        
1077             if (pCb->writerActiveFlag == 1)
1078             {
1079                 //
1080                 // UNDerflow, 
1081                 // read stopped due to insufficient PCM samples in CB to fill Read AF
1082                 //
1083             
1084                 // 
1085                 // Increment underflow count
1086                 //
1087                 pCb->errPcmUndCnt++;
1089                 // Mute output on underflow
1090                 cbReadMuteWithLastAfInfo(pCb, pAfRd);
1091                 
1092 #if 0 // also for CB_RW_OP_CAP_PP (***) FL: shows timing of CB underflow
1093                 // debug
1094                 {
1095                     static Uint8 toggleState = 0;
1096                     if (toggleState == 0)
1097                         GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
1098                     else
1099                         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
1100                     toggleState = ~(toggleState);
1101                 }
1102 #endif
1104                 #ifdef CB_RW_OP_CAP_PP // debug
1105                 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
1106                 {
1107                     if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
1108                     {
1109                         // log sample count
1110                         pCb->cb_samples_op[pCb->cb_opCnt] = 0;  // due to underflow
1111                         pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
1112                         // log idxs
1113                         pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
1114                         pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
1115                         pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
1116                         pCb->cb_opCnt++;
1117                     }
1118                 }
1119                 #endif
1121                 // Write back circular buffer configuration.
1122                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1123                 Cache_wait();    
1124                 
1125                 // Leave the gate
1126                 GateMP_leave(gateHandle, key);
1127                 
1128                 return ASP_DECOP_CB_PCM_READ_UNDERFLOW;
1129             }
1130         }
1131         
1132         // Read AF complete, update Last CB AF Info
1133         cbUpdateLastAfInfo(pCb, pAfRd);
1135 #if 0 // also for CB_RW_OP_CAP_PP (***) FL: shows timing of successful CB read
1136         {
1137             static Uint8 toggleState = 0;
1138             if (toggleState == 0)
1139                 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
1140             else
1141                 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
1142             toggleState = ~(toggleState);
1143         }
1144 #endif
1146 #ifdef CB_RW_OP_CAP_PP // debug
1147         if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
1148         {
1149             if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
1150             {
1151                 // log sample count
1152                 pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
1153                 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
1154                 // log idxs
1155                 pCb->cb_afRdIdx[pCb->cb_opCnt] = (pCb->pcmRdIdx == 0) ? (pCb->afRdIdx-1) : (pCb->afRdIdx);
1156                 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
1157                 pCb->cb_numAfCb[pCb->cb_opCnt] = (pCb->pcmRdIdx == 0) ? (pCb->numAfCb+1) : (pCb->numAfCb); // numAfCb might not be pointing to this instance
1158                 pCb->cb_opCnt++;
1159             }
1160         }
1161 #endif
1162     }
1163     
1164 #if 0
1165     if (pCb->drainFlag == 1)
1166     {
1167         //
1168         // Writer inactive, but remaining frames in circular buffer.
1169         // Update drain flag.
1170         //
1171         if (pCb->numAfCb <= 0)
1172         {
1173             pCb->drainFlag = 0;
1174         }
1175     }
1176 #endif
1177     
1178     // Write back circular buffer configuration.
1179     // NOTE: Probably only a subset of this information needs to be updated.
1180     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1181     Cache_wait();    
1182         
1183     // Leave the gate
1184     GateMP_leave(gateHandle, key);
1186     return ASP_DECOP_CB_SOK;
1189 #if 0
1190 // Generate mute AF on circular buffer read
1191 static Void cbReadAfMute(
1192     PAF_AudioFrame *pAfRd,      // audio frame into which to read
1193     Int16 strFrameLen           // stream frame length (output transaction size)
1196     PAF_ChannelMask_HD streamMask;
1197     Int8 i;
1198     
1199     pAfRd->sampleDecode = PAF_SOURCE_PCM;
1200     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
1201     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
1202     pAfRd->sampleCount = strFrameLen;
1203     pAfRd->channelConfigurationRequest.full = 0;
1204     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
1205     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
1206     pAfRd->channelConfigurationStream.full = 0;
1207     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
1208     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
1209     
1210     // compute stream mask
1211     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
1212     // Clear PCM data
1213     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
1214     {
1215         if ((streamMask >> i) & 0x1)
1216                 {
1217             memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
1218         }
1219         pAfRd->data.samsiz[i] = 0;
1220     }
1221     // write metadata information updated by decoder
1222     pAfRd->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
1223     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
1224     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
1225     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
1227 #endif
1229 #if 0 // FL: unused
1230 // Init last audio frame configuration info 
1231 static Void cbInitLastAfInfo(
1232     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
1235     pAfRd->sampleDecode = PAF_SOURCE_PCM;
1236     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
1237     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
1238     pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
1239     pAfRd->channelConfigurationRequest.full = 0;
1240     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
1241     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
1242     pAfRd->channelConfigurationStream.full = 0;
1243     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
1244     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
1246     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
1247     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
1248     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
1249     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
1251 #endif
1253 // Update last audio frame configuration info 
1254 static Void cbUpdateLastAfInfo(
1255     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
1256     PAF_AudioFrame *pAfUpd      // audio frame used for update
1259     // FL: full copy shouldn't be necessary
1260     //  Note currently (data.nChannels, data.nSamples)=(32,256) is fixed in ASOT stream AF.
1261     //  There parameters aren't copied from CB on CB read.
1262     //memcpy (&pCb->lastAf, pAfUpd, sizeof(PAF_AudioFrame));
1264     // These are parameters used in cbReadMuteWithLastAfInfo()
1265     pCb->lastAf.sampleDecode = pAfUpd->sampleDecode;
1266     pCb->lastAf.sampleRate = pAfUpd->sampleRate;
1267     pCb->lastAf.channelConfigurationRequest.full = pAfUpd->channelConfigurationRequest.full;
1268     pCb->lastAf.channelConfigurationStream.full = pAfUpd->channelConfigurationStream.full;
1271 // Generate mute AF on circular buffer read using the last AF configuration info 
1272 static Void cbReadMuteWithLastAfInfo(
1273     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
1274     PAF_AudioFrame *pAfRd         // audio frame into which to read
1277     PAF_ChannelMask_HD streamMask;
1278     Int8 i;
1280     pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
1281     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
1282     pAfRd->sampleRate  = pCb->lastAf.sampleRate;
1283     pAfRd->sampleCount = pCb->strFrameLen;
1284     pAfRd->channelConfigurationRequest.full     = pCb->lastAf.channelConfigurationRequest.full;
1285     //pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat; // FL: not necessary since full in union already copied
1286     //pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
1287     pAfRd->channelConfigurationStream.full      = pCb->lastAf.channelConfigurationStream.full;
1288     //pAfRd->channelConfigurationStream.part.sat  = pCb->lastAf.channelConfigurationStream.part.sat;
1289     //pAfRd->channelConfigurationStream.part.sub  = pCb->lastAf.channelConfigurationStream.part.sub;
1290     
1291     // compute stream mask
1292     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
1293     // Clear PCM data
1294     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
1295     {
1296         if ((streamMask >> i) & 0x1)
1297                 {
1298             memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
1299         }
1300         pAfRd->data.samsiz[i] = 0;
1301     }
1302     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
1303     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
1304     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
1305     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
1306     //Following parameters are used in DTSX
1307         pAfRd->mode = 0;                                            /* mode used by PARMA */
1308         pAfRd->numChansUsedForMetadata = 15;                        /* constant of 15 */
1309         pAfRd->pafBsFixedData = TRUE;                               /* if true, do not convert float to fixed in DTSX metadata transfer */
1310         pAfRd->root = 0x1BF;                                        /* used for channel MASK in DTSX. 0x1BF = 7.1 as defined in dtshd_dec_api_common.h */
1311     pAfRd->resetCount = 0;                                      /* used for communication between DTSX and PARMA */
1314 // Check circular buffer drain state
1315 Int cbCheckDrainState(
1316     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
1317     Int8 cbIdx,                         // decoder output circular buffer index, or indicator combined drain state desired
1318     Int8 *pDrainedFlag                  // output drain state indicator (combined or for selected circular buffer)
1321     IArg key;
1322     GateMP_Handle gateHandle;
1323     PAF_AST_DecOpCircBuf *pCb;
1324     Int8 drainedFlag;
1325     Int8 i;
1326     
1327     // Get gate handle
1328     gateHandle = pCbCtl->gateHandle;
1329     // Enter gate
1330     key = GateMP_enter(gateHandle);
1332     if (cbIdx != ASP_DECOP_CHECK_DRAINSTATE_ALL)
1333     {
1334         //
1335         // Check drain state for selected circular buffer
1336         //
1337         
1338         // Get circular buffer base pointer
1339         pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
1341         // Invalidate circular buffer configuration
1342         Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1343         Cache_wait();
1345         drainedFlag = !pCb->writerActiveFlag && !pCb->drainFlag;
1346     }
1347     else
1348     {
1349         //
1350         // Check combined drain state for all circular buffers.
1351         // Combined drain state is logical AND of drain state for all circular buffers.
1352         //
1354         drainedFlag = 1; // init combined drained flag to TRUE
1355         for (i = 0; i < pCbCtl->numDecOpCb; i++)
1356         {
1357             // Get circular buffer base pointer
1358             pCb = &((*pCbCtl->pXDecOpCb)[i]);
1360             // Invalidate circular buffer configuration
1361             Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1362             Cache_wait();
1363             
1364             // Update combined drain state
1365             drainedFlag = drainedFlag && (!pCb->writerActiveFlag && !pCb->drainFlag);
1366         }
1367     }
1368     
1369     *pDrainedFlag = drainedFlag;
1370     
1371     // Leave the gate
1372     GateMP_leave(gateHandle, key);
1374     return ASP_DECOP_CB_SOK;