PASDK-218:Retain cbInit() API, but remove functionality since unused.
[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;
272 #if 0 // FL: moved to ARM
273 // debug
274 //Int8 gCbInitSourceSelCnt=0;
275 //Int8 gCbInitSourceSelThdCnt=0;
277 // Initialize circular buffer based on selected source
278 Int cbInitSourceSel(
279     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
280     Int8 cbIdx,                         // decoder output circular buffer index
281     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
282     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
283     Int16 strFrameLen,                  // stream frame length (PCM samples)
284     Int8 resetRwFlags                   // whether to reset reader, writer, and drain flags
287     IArg key;
288     GateMP_Handle gateHandle;
289     PAF_AST_DecOpCircBuf *pCb;
290     PAF_AudioFrame *pAfCb;
291     PAF_AudioData *pPcmBuf;
292     UInt8 *pMetaBuf;
293     Int8 n;
294     Int8 i;
296     //gCbInitSourceSelCnt++; // debug
297     
298     // Get gate handle
299     gateHandle = pCbCtl->gateHandle;
300     // Enter gate
301     key = GateMP_enter(gateHandle);
303     // Get circular buffer base pointer
304     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
305     
306     // Invalidate circular buffer configuration
307     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
308     Cache_wait();
310     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
312     // set source select
313     pCb->sourceSel = sourceSelect;
315     // set input frame length
316     pCb->decOpFrameLen = decOpFrameLen;
317     
318     // set output frame length
319     pCb->strFrameLen = strFrameLen;
321     //pCb->afInitialLag = 0;  // default No lag
322     //pCb->afLagIdx = 0;
323     // Initialize CB primed flag
324     pCb->primedFlag = 0;
325     // Initialize delta samples
326     pCb->deltaSamps = 0;
327     
328     // initialize circular buffer maximum number of audio frames
329     if (sourceSelect == PAF_SOURCE_PCM)
330     {
331         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
332         
333         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
334         // Initialize target nominal delay
335         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
336         
337         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
338         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
339         pCb->pcmRdIdx = 0;
340         
341         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
342         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
343         
344         // initialize audio frames
345         for (n=0; n<pCb->maxNumAfCb; n++)
346         {
347             pAfCb = &pCb->afCb[n];
348             pAfCb->sampleDecode = sourceSelect;
349             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
350             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
351             pAfCb->sampleCount = decOpFrameLen;
352             pAfCb->channelConfigurationRequest.full = 0;
353             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
354             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
355             pAfCb->channelConfigurationStream.full = 0;
356             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
357             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
358             
359             // write metadata information updated by decoder
360             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
361             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
362             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
363             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
364         }
365     }
366     else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
367     {
368         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
369         
370         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
371         // Initialize target nominal delay
372         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kDDP;
373         
374         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
375         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
376         pCb->pcmRdIdx = 0;
377         
378         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
379         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
380         
381         // initialize audio frames
382         for (n=0; n<pCb->maxNumAfCb; n++)
383         {
384             pAfCb = &pCb->afCb[n];
385             pAfCb->sampleDecode = sourceSelect;
386             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
387             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
388             pAfCb->sampleCount = decOpFrameLen;
389             pAfCb->channelConfigurationRequest.full = 0;
390             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
391             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
392             pAfCb->channelConfigurationStream.full = 0;
393             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
394             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
395             
396             // write metadata information updated by decoder
397             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
398             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
399             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
400             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
401         }
402     }
403     else if (sourceSelect == PAF_SOURCE_THD)
404     {
405         //gCbInitSourceSelThdCnt++; //debug
406         
407         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
408         
409         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
410         // Initialize target nominal delay
411         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
412         
413         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
414         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
415         pCb->pcmRdIdx = 0;
416         
417         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
418         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
419         
420         // initialize audio frames
421         for (n=0; n<pCb->maxNumAfCb; n++)
422         {
423             pAfCb = &pCb->afCb[n];
424             pAfCb->sampleDecode = sourceSelect;
425             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
426             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
427             pAfCb->sampleCount = decOpFrameLen;
428             pAfCb->channelConfigurationRequest.full = 0;
429             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
430             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
431             pAfCb->channelConfigurationStream.full = 0;
432             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
433             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
434             
435             // write metadata information updated by decoder
436             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
437             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
438             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
439             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
440         }
441     }
442     else
443     {
444         SW_BREAKPOINT;
445         
446         // Leave the gate
447         GateMP_leave(gateHandle, key);
449         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
450     }
452     // initialize circular buffer current number of frames
453     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
454     
455     // initialize audio frame PCM buffers
456     pPcmBuf = pCb->pcmBuf;
457     pMetaBuf = pCb->metaBuf;
458     for (n=0; n<pCb->maxNumAfCb; n++)
459     {
460         pAfCb = &pCb->afCb[n];
461         pAfCb->data.nChannels = pCb->maxAFChanNum;
462         pAfCb->data.nSamples = decOpFrameLen;
463         for (i=0; i<pCb->maxAFChanNum; i++)
464         {
465             pAfCb->data.sample[i] = pPcmBuf;
466             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
467             pPcmBuf += pCb->maxAFSampCount;
468             
469             pAfCb->data.samsiz[i] = 0;
470         }
471         
472         // Initialize metadata buffers
473         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
474         {
475             pAfCb->pafPrivateMetadata[i].offset = 0; 
476             pAfCb->pafPrivateMetadata[i].size   = 0; 
477             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
478             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
479         }
480     }
481     
482     // reset read/write flags
483     if (resetRwFlags)
484     {
485         pCb->writerActiveFlag = 0;
486         pCb->readerActiveFlag = 0;
487         pCb->drainFlag = 0;
488     }
489     
490     // reset stats
491     pCb->readAfWriterInactiveCnt = 0;
492     pCb->readAfNdCnt = 0;
493     pCb->wrtAfReaderInactiveCnt = 0;
494     pCb->wrtAfZeroSampsCnt = 0;
495     pCb->errUndCnt = 0;
496     pCb->errOvrCnt = 0;
497     
498     // Write back circular buffer configuration
499     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
500     // Write back AF circular buffer
501     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
502     // Write back PCM data
503     for (n=0; n<pCb->maxNumAfCb; n++)
504     {
505         pAfCb = &pCb->afCb[n];
506         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
507         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
508         for (i=0; i<pCb->maxAFChanNum; i++)
509         {
510             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
511         }
512     }
513     Cache_wait();
515     // Leave the gate
516     GateMP_leave(gateHandle, key);
517     
518     return ASP_DECOP_CB_SOK;
520 #endif
522 // Start reads from circular buffer
523 Int cbReadStart(
524     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
525     Int8 cbIdx                          // decoder output circular buffer index
528     IArg key;
529     GateMP_Handle gateHandle;
530     PAF_AST_DecOpCircBuf *pCb;
532     // Get gate handle
533     gateHandle = pCbCtl->gateHandle;
534     // Enter gate
535     key = GateMP_enter(gateHandle);
537     // Get circular buffer base pointer
538     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
539     
540     // Invalidate circular buffer configuration
541     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
542     Cache_wait();
543     
544     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
546     // update flags
547     pCb->readerActiveFlag = 1;
548     
549     // Write back circular buffer configuration
550     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
551     Cache_wait();
553     // Leave the gate
554     GateMP_leave(gateHandle, key);
556     return ASP_DECOP_CB_SOK;
559 // Stop reads from circular buffer
560 Int cbReadStop(
561     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
562     Int8 cbIdx                          // decoder output circular buffer index
565     IArg key;
566     GateMP_Handle gateHandle;
567     PAF_AST_DecOpCircBuf *pCb;
569     // Get gate handle
570     gateHandle = pCbCtl->gateHandle;
571     // Enter gate
572     key = GateMP_enter(gateHandle);
574     // Get circular buffer base pointer
575     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
577     // Invalidate circular buffer configuration
578     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
579     Cache_wait();
580     
581     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
583     // update flags
584     pCb->readerActiveFlag = 0;
585     
586     // Write back circular buffer configuration
587     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
588     Cache_wait();
590     // Leave the gate
591     GateMP_leave(gateHandle, key);
593     return ASP_DECOP_CB_SOK;
596 // debug
597 //Int16 gDeltaSampsBuf[20];
598 //Int8 gDeltaSampsBufIdx=0;
600 // Read audio frame from circular buffer
601 Int cbReadAf(
602     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
603     Int8 cbIdx,                         // decoder output circular buffer index
604     PAF_AudioFrame *pAfRd               // audio frame into which to read
607     IArg key;
608     GateMP_Handle gateHandle;
609     PAF_AST_DecOpCircBuf *pCb;
610     PAF_AudioFrame *pAfCb;
611     PAF_ChannelMask_HD streamMask;
612     Int8 i;
613     Int16 j;
614     Int8 numMetadata = 0;
615     
616     // Get gate handle
617     gateHandle = pCbCtl->gateHandle;
618     // Enter gate
619     key = GateMP_enter(gateHandle);
621     // Get circular buffer base pointer
622     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
624     // Invalidate circular buffer configuration.
625     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
626     Cache_wait();
628     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
630     // Check (writerActiveFlag,drainFlag)=(1,1)
631     if ((pCb->writerActiveFlag == 1) && (pCb->drainFlag == 1))
632     {
633         //
634         // This shouldn't occur:
635         // writer is active AND draining circular buffer
636         //
637         
638         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, drainFlag=%d", pCb->writerActiveFlag, pCb->drainFlag); // FL: debug
639         SW_BREAKPOINT; // FL: debug
640         
641         // Leave the gate
642         GateMP_leave(gateHandle, key);
643         
644         return ASP_DECOP_CB_READ_INVSTATE;
645     }
647     // Check (writerActiveFlag,drainFlag)=(0,0)
648     //if (((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
649     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0))
650     {
651         //
652         // Writer inactive, not draining circular buffer.
653         // Skip UNDerflow check, mute output.
654         //
655         
656         pCb->readAfWriterInactiveCnt++;
657         
658         //cbReadAfMute(pAfRd, pCb->strFrameLen);
659         cbReadMuteWithLastAfInfo(pCb, pAfRd);
660         
661         // Write back circular buffer configuration.
662         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
663         Cache_wait();    
665         // Leave the gate
666         GateMP_leave(gateHandle, key);
668         return ASP_DECOP_CB_SOK;
669     }
670     
671     //if ((pCb->primedFlag == 0) || ((pCb->primedFlag==1) && (pCb->deltaSamps > 0))
672     if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
673     {
674         pCb->readAfNdCnt++;
675         
676         if (pCb->primedFlag == 1)
677         {
678             pCb->deltaSamps = pCb->deltaSamps - pCb->strFrameLen;
679             
680             // debug
681             //gDeltaSampsBuf[gDeltaSampsBufIdx] = pCb->deltaSamps;
682             //if (gDeltaSampsBufIdx < 20)
683             //    gDeltaSampsBufIdx++;
684         }
685         
686         cbReadMuteWithLastAfInfo(pCb, pAfRd);
687         
688         // Write back circular buffer configuration.
689         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
690         Cache_wait();    
691         
692         // Leave the gate
693         GateMP_leave(gateHandle, key);
695         return ASP_DECOP_CB_SOK;
696     }
697     
698     // (writerActiveFlag,drainFlag)= (0,0) and (1,1) checked above
699     // (writerActiveFlag,drainFlag)=(1,0) and (0,1) are left
700     // Checking (writerActiveFlag,drainFlag)=(1,0) state here
701     if (pCb->writerActiveFlag == 1)
702     {
703         // check underflow
704         if (pCb->numAfCb <= 0)
705         {
706             // 
707             // Increment underflow count.
708             // Mute output on underflow.
709             //
710             pCb->errUndCnt++;
711             //cbReadAfMute(pAfRd, pCb->strFrameLen);
712             cbReadMuteWithLastAfInfo(pCb, pAfRd);
713             //SW_BREAKPOINT; // FL: debug
714             
715             // debug
716             {
717                 static Uint8 toggleState = 0;
718                 if (toggleState == 0)
719                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
720                 else
721                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
722                 toggleState = ~(toggleState);
723             }
725             #ifdef CB_RW_OP_CAP_PP // debug
726             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
727             {
728                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
729                 {
730                     // log sample count
731                     pCb->cb_samples_op[pCb->cb_opCnt] = 0;  // due to underflow
732                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
733                     // log idxs
734                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
735                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
736                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
737                     pCb->cb_opCnt++;
738                 }
739             }
740             #endif
742             // Write back circular buffer configuration.
743             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
744             Cache_wait();    
745             
746             // Leave the gate
747             GateMP_leave(gateHandle, key);
748             
749             return ASP_DECOP_CB_READ_UNDERFLOW;
750         }
751     }
752     
753     // Checking (writerActiveFlag,drainFlag)=(1,0) state above and here
754     // Checking (writerActiveFlag,drainFlag)=(0,1) state here
755     if ((pCb->writerActiveFlag == 1) || (pCb->drainFlag == 1))
756     {
757         //
758         // Writer active or draining remaining frames in circular buffer.
759         // Get next output audio frame.
760         //
761         
762         // get pointer to current audio frame in circular buffer
763         pAfCb = &pCb->afCb[pCb->afRdIdx];
765         // Invalidate audio frame
766         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
767         Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
768         for (i=0; i<pAfCb->numPrivateMetadata; i++) // only invalidate numPrivateMetadata
769         {
770             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
771         }
772         Cache_wait();
774         // compute stream mask
775         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
777         // Invalidate channel pointers
778         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
779         Cache_wait();
781         // Invalidate PCM data
782         for (i = 0; i < pCb->maxAFChanNum; i++)
783         {
784             if ((streamMask >> i) & 0x1)
785             {
786                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
787             }
788         }
789         Cache_wait();        
790         
791         // read audio frame information updated by decoder
792         pAfRd->sampleDecode = pAfCb->sampleDecode;
793         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
794         pAfRd->sampleRate = pAfCb->sampleRate;
795         pAfRd->sampleCount = pCb->strFrameLen;
796         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
797         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
798         
799         // read metadata information updated by decoder
800         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
801         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
802         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
803         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
804         
805         #ifdef CB_RW_OP_CAP_PP // debug
806         if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
807         {
808             if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
809             {
810                 // log sample count
811                 pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
812                 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
813                 // log idxs
814                 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
815                 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
816                 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
817                 pCb->cb_opCnt++;
818             }
819         }
820         #endif
822         //// update Last Cb info as per actual stream
823         //pCb->lastAf.sampleCount = pCb->strFrameLen; // FL: last AF sample count isn't used (see cbReadMuteWithLastAfInfo())
824         //pCb->lastAf.sampleRate = pAfCb->sampleRate; // FL: moved inside cbUpdateLastAfInfo() along with other params from memcpy below
825         // Update last audio frame configuration info
826         cbUpdateLastAfInfo(pCb, pAfRd);
828         // read PCM samples
829         for (i = 0; i < pCb->maxAFChanNum; i++)
830         {
831             if ((streamMask >> i) & 0x1)
832             {
833                 for (j = 0; j < pCb->strFrameLen; j++)
834                 {
835                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
836                 }
838                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
839             }
840         }
841         
842         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
843         {
844             pAfRd->pafPrivateMetadata[i].offset = 0;
845             pAfRd->pafPrivateMetadata[i].size   = 0;
846         }
847         
848         // read metadata
849         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only read numPrivateMetadata
850         {
851             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
852                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
853                  &&(pAfCb->pafPrivateMetadata[i].size))
854             {
855                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
856                 pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
857                 pAfRd->pafPrivateMetadata[numMetadata].size   = pAfCb->pafPrivateMetadata[i].size;
858                 memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
859                 numMetadata++; //number of metadata associated with current 256 segment of audio samples
860             }
861             else //reset un-used buf
862             {
863                 pAfRd->pafPrivateMetadata[i].offset = 0;
864                 pAfRd->pafPrivateMetadata[i].size   = 0;
865             }
867         }
868         pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
869         
870         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
871         if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
872         {
873             // update audio frame read index
874             pCb->afRdIdx++;
875             if (pCb->afRdIdx >= pCb->maxNumAfCb)
876             {
877                 pCb->afRdIdx = 0;
878             }
879             
880             // update PCM read index
881             pCb->pcmRdIdx = 0;
882             
883             // update number of audio frames in circular buffer
884             pCb->numAfCb--;
885         }
886         
887         // FL: this update of Last AF is handled above
888         //memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
890         {
891             static Uint8 toggleState = 0;
892             if (toggleState == 0)
893                 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
894             else
895                 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
896             toggleState = ~(toggleState);
897         }
898     }
899     
900     if (pCb->drainFlag == 1)
901     {
902         //
903         // Writer inactive, but remaining frames in circular buffer.
904         // Update drain flag.
905         //
906         if (pCb->numAfCb <= 0)
907         {
908             pCb->drainFlag = 0;
909         }
910     }
911     
912     // Write back circular buffer configuration.
913     // NOTE: Probably only a subset of this information needs to be updated.
914     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
915     Cache_wait();    
916         
917     // Leave the gate
918     GateMP_leave(gateHandle, key);
920     return ASP_DECOP_CB_SOK;
923 #if 0
924 // Generate mute AF on circular buffer read
925 static Void cbReadAfMute(
926     PAF_AudioFrame *pAfRd,      // audio frame into which to read
927     Int16 strFrameLen           // stream frame length (output transaction size)
930     PAF_ChannelMask_HD streamMask;
931     Int8 i;
932     
933     pAfRd->sampleDecode = PAF_SOURCE_PCM;
934     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
935     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
936     pAfRd->sampleCount = strFrameLen;
937     pAfRd->channelConfigurationRequest.full = 0;
938     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
939     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
940     pAfRd->channelConfigurationStream.full = 0;
941     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
942     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
943     
944     // compute stream mask
945     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
946     // Clear PCM data
947     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
948     {
949         if ((streamMask >> i) & 0x1)
950         {
951             memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
952         }
953         pAfRd->data.samsiz[i] = 0;
954     }
955     // write metadata information updated by decoder
956     pAfRd->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
957     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
958     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
959     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
961 #endif
963 #if 0 // FL: unused
964 // Init last audio frame configuration info 
965 static Void cbInitLastAfInfo(
966     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
969     pAfRd->sampleDecode = PAF_SOURCE_PCM;
970     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
971     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
972     pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
973     pAfRd->channelConfigurationRequest.full = 0;
974     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
975     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
976     pAfRd->channelConfigurationStream.full = 0;
977     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
978     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
980     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
981     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
982     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
983     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
985 #endif
987 // Update last audio frame configuration info 
988 static Void cbUpdateLastAfInfo(
989     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
990     PAF_AudioFrame *pAfUpd      // audio frame used for update
993     // FL: full copy shouldn't be necessary
994     //  Note currently (data.nChannels, data.nSamples)=(32,256) is fixed in ASOT stream AF.
995     //  There parameters aren't copied from CB on CB read.
996     //memcpy (&pCb->lastAf, pAfUpd, sizeof(PAF_AudioFrame));
998     // These are parameters used in cbReadMuteWithLastAfInfo()
999     pCb->lastAf.sampleDecode = pAfUpd->sampleDecode;
1000     pCb->lastAf.sampleRate = pAfUpd->sampleRate;
1001     pCb->lastAf.channelConfigurationRequest.full = pAfUpd->channelConfigurationRequest.full;
1002     pCb->lastAf.channelConfigurationStream.full = pAfUpd->channelConfigurationStream.full;
1005 // Generate mute AF on circular buffer read using the last AF configuration info 
1006 static Void cbReadMuteWithLastAfInfo(
1007     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
1008     PAF_AudioFrame *pAfRd         // audio frame into which to read
1011     PAF_ChannelMask_HD streamMask;
1012     Int8 i;
1014     pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
1015     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
1016     pAfRd->sampleRate  = pCb->lastAf.sampleRate;
1017     pAfRd->sampleCount = pCb->strFrameLen;
1018     pAfRd->channelConfigurationRequest.full     = pCb->lastAf.channelConfigurationRequest.full;
1019     //pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat; // FL: not necessary since full in union already copied
1020     //pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
1021     pAfRd->channelConfigurationStream.full      = pCb->lastAf.channelConfigurationStream.full;
1022     //pAfRd->channelConfigurationStream.part.sat  = pCb->lastAf.channelConfigurationStream.part.sat;
1023     //pAfRd->channelConfigurationStream.part.sub  = pCb->lastAf.channelConfigurationStream.part.sub;
1024     
1025     // compute stream mask
1026     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
1027     // Clear PCM data
1028     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
1029     {
1030         if ((streamMask >> i) & 0x1)
1031         {
1032             memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
1033         }
1034         pAfRd->data.samsiz[i] = 0;
1035     }
1036     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
1037     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
1038     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
1039     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
1042 // Check circular buffer drain state
1043 Int cbCheckDrainState(
1044     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
1045     Int8 cbIdx,                         // decoder output circular buffer index, or indicator combined drain state desired
1046     Int8 *pDrainedFlag                  // output drain state indicator (combined or for selected circular buffer)
1049     IArg key;
1050     GateMP_Handle gateHandle;
1051     PAF_AST_DecOpCircBuf *pCb;
1052     Int8 drainedFlag;
1053     Int8 i;
1054     
1055     // Get gate handle
1056     gateHandle = pCbCtl->gateHandle;
1057     // Enter gate
1058     key = GateMP_enter(gateHandle);
1060     if (cbIdx != ASP_DECOP_CHECK_DRAINSTATE_ALL)
1061     {
1062         //
1063         // Check drain state for selected circular buffer
1064         //
1065         
1066         // Get circular buffer base pointer
1067         pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
1069         // Invalidate circular buffer configuration
1070         Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1071         Cache_wait();
1073         drainedFlag = !pCb->writerActiveFlag && !pCb->drainFlag;
1074     }
1075     else
1076     {
1077         //
1078         // Check combined drain state for all circular buffers.
1079         // Combined drain state is logical AND of drain state for all circular buffers.
1080         //
1082         drainedFlag = 1; // init combined drained flag to TRUE
1083         for (i = 0; i < pCbCtl->numDecOpCb; i++)
1084         {
1085             // Get circular buffer base pointer
1086             pCb = &((*pCbCtl->pXDecOpCb)[i]);
1088             // Invalidate circular buffer configuration
1089             Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
1090             Cache_wait();
1091             
1092             // Update combined drain state
1093             drainedFlag = drainedFlag && (!pCb->writerActiveFlag && !pCb->drainFlag);
1094         }
1095     }
1096     
1097     *pDrainedFlag = drainedFlag;
1098     
1099     // Leave the gate
1100     GateMP_leave(gateHandle, key);
1102     return ASP_DECOP_CB_SOK;