Fix various bugs:
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / framework / aspDecOpCircBuf_master.c
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 #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 #define DEF_SOURCE_SEL          ( PAF_SOURCE_PCM ) // default source select
49 #define DEF_DEC_OP_FRAME_LEN    ( 256 )     // default decoder output frame length
50 #define DEF_STR_FRAME_LEN       ( 256 )     // default stream frame length
52 #define MAX_NUM_AF_PCM      ( 4 )
53 #define CB_INIT_RD_LAG_PCM  ( 2 ) // 0...3
55 #define MAX_NUM_AF_DDP      ( 2 )
56 #define CB_INIT_RD_LAG_DDP  ( 4 ) // 0...5
58 // Generate mute AF on circular buffer read
59 static Void cbReadAfMute(
60     PAF_AudioFrame *pAfRd,      // audio frame into which to read
61     Int16 strFrameLen           // stream frame length (output transaction size)
62 );
65 // Initialize circular buffer control
66 Int cbCtlInit(
67     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
68     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
69 )
70 {
71     GateMP_Params gateParams;
72     GateMP_Handle gateHandle;
73     
74     GateMP_Params_init(&gateParams);
75     gateParams.localProtect = GateMP_LocalProtect_THREAD;
76     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
77     gateParams.name = ASP_DECODE_CB_GATE_NAME;
78     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
79     gateHandle = GateMP_create(&gateParams);
80     if (gateHandle != NULL)
81     {
82         pCbCtl->gateHandle = gateHandle;
83     }
84     else
85     {
86         pCbCtl->gateHandle = NULL;
87         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
88     }
89     
90     pCbCtl->pXDecOpCb = pXDecOpCb;
91     
92     return ASP_DECOP_CB_SOK;
93     
94 }
96 // Initialize circular buffer
97 Int cbInit(
98     PAF_AST_DecOpCircBuf *pCb
99 )
101     PAF_AudioFrame *pAfCb;
102     PAF_AudioData *pPcmBuf;
103     UInt8 *pMetaBuf;
104     Int8 n;
105     Int8 i;
107     // set source select
108     pCb->sourceSel = DEF_SOURCE_SEL;
110     // set input frame length
111     pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
112     
113     // set output frame length
114     pCb->strFrameLen = DEF_STR_FRAME_LEN;
115     
116     // initialize circular buffer maximum number of audio frames
117     pCb->maxNumAfCb = MAX_NUM_AF_PCM;
118     pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
119     pCb->afRdIdx = 0;
120     pCb->pcmRdIdx = 0; // 2*256 in behind
121     
122     // initialize audio frames
123     for (n=0; n<pCb->maxNumAfCb; n++)
124     {
125         pAfCb = &pCb->afCb[n];
126         pAfCb->sampleDecode = PAF_SOURCE_PCM;
127         PAF_PROCESS_ZERO(pAfCb->sampleProcess);
128         pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
129         pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
130         pAfCb->channelConfigurationRequest.full = 0;
131         pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
132         pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
133         pAfCb->channelConfigurationStream.full = 0;
134         pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
135         pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
136     }
138     // initialize circular buffer current number of frames
139     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
140     
141     // initialize audio frame PCM buffers
142     pPcmBuf = pCb->pcmBuf;
143     pMetaBuf = pCb->metaBuf; //QIN
144     for (n=0; n<pCb->maxNumAfCb; n++)
145     {
146         pAfCb = &pCb->afCb[n];
147         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
148         pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
149         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
150         {
151             pAfCb->data.sample[i] = pPcmBuf;
152             memset(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN, 0);
153             pPcmBuf += DEF_DEC_OP_FRAME_LEN;
154             
155             pAfCb->data.samsiz[i] = 0;
156         }
157         
158         // Initialize metadata buffers //QIN
159         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
160         {
161             pAfCb->pafPrivateMetadata[i].offset = 0; 
162             pAfCb->pafPrivateMetadata[i].size   = 0; 
163             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
164             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
165         }
166     }
167     
168     // reset read/write flags
169     pCb->writerActiveFlag = 0;
170     pCb->readerActiveFlag = 0;
171     pCb->emptyFlag = 0;
172     
173     // reset error counts
174     pCb->errUndCnt = 0;
175     pCb->errOvrCnt = 0;
176     
177     // (***) FL: revisit
178     // Write back circular buffer configuration
179     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
180     // Write back AF circular buffer
181     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
182     // Write back PCM data
183     for (n=0; n<pCb->maxNumAfCb; n++)
184     {
185         pAfCb = &pCb->afCb[n];
186         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
187         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
188         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
189         {
190             Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
191         }
192         // FL: unnecessary since part of AF
193         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
194         //{
195         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
196         //}
197     }
198     Cache_wait();
200     return ASP_DECOP_CB_SOK;
203 // Initialize circular buffer based on selected source
204 Int cbInitSourceSel(
205     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
206     Int8 cbIdx,                         // decoder output circular buffer index
207     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
208     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
209     Int16 strFrameLen,                  // stream frame length (PCM samples)
210     Int8 resetRwFlags                   // whether to reset reader, writer, and empty flags
213     IArg key;
214     GateMP_Handle gateHandle;
215     PAF_AST_DecOpCircBuf *pCb;
216     PAF_AudioFrame *pAfCb;
217     PAF_AudioData *pPcmBuf;
218     UInt8 *pMetaBuf; //QIN
219     Int8 n;
220     Int8 i;
222     // Get gate handle
223     gateHandle = pCbCtl->gateHandle;
224     // Enter gate
225     key = GateMP_enter(gateHandle);
227     // Get circular buffer base pointer
228     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
229     
230     // Invalidate circular buffer configuration
231     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
232     Cache_wait();
234     // set source select
235     pCb->sourceSel = sourceSelect;
237     // set input frame length
238     pCb->decOpFrameLen = decOpFrameLen;
239     
240     // set output frame length
241     pCb->strFrameLen = strFrameLen;
242     
243     // initialize circular buffer maximum number of audio frames
244     if (sourceSelect == PAF_SOURCE_PCM)
245     {
246         pCb->maxNumAfCb = MAX_NUM_AF_PCM;
247         pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
248         pCb->afRdIdx = 0;
249         pCb->pcmRdIdx = 0; // 2*256 in behind
250         
251         // initialize audio frames
252         for (n=0; n<pCb->maxNumAfCb; n++)
253         {
254             pAfCb = &pCb->afCb[n];
255             pAfCb->sampleDecode = PAF_SOURCE_PCM;
256             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
257             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
258             pAfCb->sampleCount = decOpFrameLen;
259             pAfCb->channelConfigurationRequest.full = 0;
260             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
261             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
262             pAfCb->channelConfigurationStream.full = 0;
263             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
264             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
265         }
266     }
267     else if (sourceSelect == PAF_SOURCE_DDP)
268     {
269         pCb->maxNumAfCb = MAX_NUM_AF_DDP;
270         pCb->afWrtIdx = 1;
271         pCb->afRdIdx = 0;
272         pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG_DDP*strFrameLen; // 4*256 behind
273         
274         // initialize audio frames
275         for (n=0; n<pCb->maxNumAfCb; n++)
276         {
277             pAfCb = &pCb->afCb[n];
278             pAfCb->sampleDecode = PAF_SOURCE_DDP;
279             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
280             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
281             pAfCb->sampleCount = decOpFrameLen;
282             pAfCb->channelConfigurationRequest.full = 0;
283             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
284             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
285             pAfCb->channelConfigurationStream.full = 0;
286             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
287             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
288         }
289     }
290     else
291     {
292         // Leave the gate
293         GateMP_leave(gateHandle, key);
295         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
296     }
298     // initialize circular buffer current number of frames
299     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
300     
301     // initialize audio frame PCM buffers
302     pPcmBuf = pCb->pcmBuf;
303     pMetaBuf = pCb->metaBuf; //QIN
304     for (n=0; n<pCb->maxNumAfCb; n++)
305     {
306         pAfCb = &pCb->afCb[n];
307         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
308         pAfCb->data.nSamples = decOpFrameLen;
309         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
310         {
311             pAfCb->data.sample[i] = pPcmBuf;
312             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
313             pPcmBuf += decOpFrameLen;
314             
315             pAfCb->data.samsiz[i] = 0;
316         }
317         
318         // Initialize metadata buffers //QIN
319         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
320         {
321             pAfCb->pafPrivateMetadata[i].offset = 0; 
322             pAfCb->pafPrivateMetadata[i].size   = 0; 
323             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
324             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
325         }
326     }
327     
328     // reset read/write flags
329     if (resetRwFlags)
330     {
331         pCb->writerActiveFlag = 0;
332         pCb->readerActiveFlag = 0;
333         pCb->emptyFlag = 0;
334     }
335     
336     // reset error counts
337     pCb->errUndCnt = 0;
338     pCb->errOvrCnt = 0;
339     
340     // (***) FL: revisit
341     // Write back circular buffer configuration
342     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
343     // Write back AF circular buffer
344     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
345     // Write back PCM data
346     for (n=0; n<pCb->maxNumAfCb; n++)
347     {
348         pAfCb = &pCb->afCb[n];
349         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
350         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
351         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
352         {
353             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
354         }
355         // FL: unnecessary since part of AF
356         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
357         //{
358         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
359         //}
360     }
361     Cache_wait();
363     // Leave the gate
364     GateMP_leave(gateHandle, key);
365     
366     return ASP_DECOP_CB_SOK;
369 // Start reads from circular buffer
370 Int cbReadStart(
371     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
372     Int8 cbIdx                          // decoder output circular buffer index
375     IArg key;
376     GateMP_Handle gateHandle;
377     PAF_AST_DecOpCircBuf *pCb;
379     // Get gate handle
380     gateHandle = pCbCtl->gateHandle;
381     // Enter gate
382     key = GateMP_enter(gateHandle);
384     // Get circular buffer base pointer
385     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
386     
387     // Invalidate circular buffer configuration
388     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
389     Cache_wait();
390     
391     // update flags
392     pCb->readerActiveFlag = 1;
393     
394     // (***) FL: revisit
395     // Write back circular buffer configuration
396     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
397     Cache_wait();
399     // Leave the gate
400     GateMP_leave(gateHandle, key);
402     return ASP_DECOP_CB_SOK;
405 // Stop reads from circular buffer
406 Int cbReadStop(
407     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
408     Int8 cbIdx                          // decoder output circular buffer index
411     IArg key;
412     GateMP_Handle gateHandle;
413     PAF_AST_DecOpCircBuf *pCb;
415     // Get gate handle
416     gateHandle = pCbCtl->gateHandle;
417     // Enter gate
418     key = GateMP_enter(gateHandle);
420     // Get circular buffer base pointer
421     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
423     // Invalidate circular buffer configuration
424     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
425     Cache_wait();
426     
427     // update flags
428     pCb->readerActiveFlag = 0;
429     
430     // (***) FL: revisit
431     // Write back circular buffer configuration
432     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
433     Cache_wait();
435     // Leave the gate
436     GateMP_leave(gateHandle, key);
438     return ASP_DECOP_CB_SOK;
441 // Read audio frame from circular buffer
442 Int cbReadAf(
443     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
444     Int8 cbIdx,                         // decoder output circular buffer index
445     PAF_AudioFrame *pAfRd               // audio frame into which to read
448     IArg key;
449     GateMP_Handle gateHandle;
450     PAF_AST_DecOpCircBuf *pCb;
451     PAF_AudioFrame *pAfCb;
452     PAF_ChannelMask_HD streamMask;
453     Int8 i;
454     Int16 j;
456     // Get gate handle
457     gateHandle = pCbCtl->gateHandle;
458     // Enter gate
459     key = GateMP_enter(gateHandle);
461     // Get circular buffer base pointer
462     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
464     // (***) FL: revisit
465     // Invalidate circular buffer configuration.
466     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
467     Cache_wait();
469     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
470     {
471         // This shouldn't occur:
472         //  writer is active AND draining circular buffer
473         Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
474         SW_BREAKPOINT; // FL: debug
475         
476         // Leave the gate
477         GateMP_leave(gateHandle, key);
478         
479         return ASP_DECOP_CB_READ_INVSTATE;
480     }
482     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
483     {
484         //
485         // No active writer, not draining circular buffer.
486         // Skip UNDerflow check, mute output.
487         //
488         cbReadAfMute(pAfRd, pCb->strFrameLen);
489         
490         // Leave the gate
491         GateMP_leave(gateHandle, key);
493         return ASP_DECOP_CB_SOK;
494     }
495     
496     // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
497     // Here we are checking (1,0) state here
498     if ((pCb->writerActiveFlag == 1))
499     {
500         // check underflow
501         if (pCb->numAfCb <= 0)
502         {
503             // 
504             // Increment underflow count.
505             // Mute output on underflow.
506             //
507             pCb->errUndCnt++;
508             cbReadAfMute(pAfRd, pCb->strFrameLen);
509             //SW_BREAKPOINT; // FL: debug
510             
511             // Write back circular buffer configuration.
512             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
513             Cache_wait();    
514             
515             // Leave the gate
516             GateMP_leave(gateHandle, key);
517             
518             return ASP_DECOP_CB_READ_UNDERFLOW;
519         }
520     }
521     
522     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
523     {
524         //
525         // Writer active or draining remaining frames in circular buffer.
526         // Get next output audio frame.
527         //
528         
529         // get pointer to current audio frame in circular buffer
530         pAfCb = &pCb->afCb[pCb->afRdIdx];
532         // (***) FL: revisit
533         // Invalidate audio frame
534         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
535         Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
536         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
537         {
538             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
539             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
540         }
541         Cache_wait();
543         // compute stream mask
544         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
546         // Invalidate PCM data
547         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
548         {
549             if ((streamMask >> i) & 0x1)
550             {
551                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
552             }
553         }
554         Cache_wait();        
555         
556         // read audio frame information updated by decoder
557         pAfRd->sampleDecode = pAfCb->sampleDecode;
558         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
559         pAfRd->sampleRate = pAfCb->sampleRate;
560         pAfRd->sampleCount = pCb->strFrameLen;
561         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
562         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
563         
564         // read metadata information updated by decoder //QIN
565         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
566         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
567         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
568         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
569         
570         // read PCM samples
571         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
572         {
573             if ((streamMask >> i) & 0x1)
574             {
575                 for (j = 0; j < pCb->strFrameLen; j++)
576                 {
577                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
578                 }
580                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
581             }
582         }
583         // read metadata //QIN
584         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
585         {
586             // FL: this is done above
587             ////Invalidate metadata data
588             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
589             //Cache_wait();        
590             
591             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
592                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
593                  &&(pAfCb->pafPrivateMetadata[i].size))
594             {
595                 // FL: this is done above
596                 ////Invalidate metadata data
597                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
598                 //Cache_wait();        
599         
600                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
601                 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
602                 pAfRd->pafPrivateMetadata[i].size   = pAfCb->pafPrivateMetadata[i].size;
603                 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
604             }
605             else //reset un-used buf
606             {
607                 pAfRd->pafPrivateMetadata[i].offset = 0;
608                 pAfRd->pafPrivateMetadata[i].size   = 0;
609             }
610         }
611         
612         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
613         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
614         {
615             // update audio frame read index
616             pCb->afRdIdx++;
617             if (pCb->afRdIdx >= pCb->maxNumAfCb)
618             {
619                 pCb->afRdIdx = 0;
620             }
621             
622             // update PCM read index
623             pCb->pcmRdIdx = 0;
624             
625             // update number of audio frames in circular buffer
626             pCb->numAfCb--;
627         }
628     }
629     
630     if (pCb->emptyFlag == 1)
631     {
632         //
633         // Writer inactive, but remaining frames in circular buffer.
634         // Update empty flag.
635         //
636         if (pCb->numAfCb <= 0)
637         {
638             pCb->emptyFlag = 0;
639         }
640     }
641     
642     // (***) FL: revisit
643     // Write back circular buffer configuration.
644     // NOTE: Probably only a subset of this information needs to be updated.
645     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
646     Cache_wait();    
647         
648     // Leave the gate
649     GateMP_leave(gateHandle, key);
651     return ASP_DECOP_CB_SOK;
654 // Generate mute AF on circular buffer read
655 static Void cbReadAfMute(
656     PAF_AudioFrame *pAfRd,      // audio frame into which to read
657     Int16 strFrameLen           // stream frame length (output transaction size)
660     PAF_ChannelMask_HD streamMask;
661     Int8 i;
662     
663     pAfRd->sampleDecode = PAF_SOURCE_PCM;
664     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
665     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
666     pAfRd->sampleCount = strFrameLen;
667     pAfRd->channelConfigurationRequest.full = 0;
668     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
669     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
670     pAfRd->channelConfigurationStream.full = 0;
671     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
672     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
673     
674     // compute stream mask
675     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
676     // Clear PCM data
677     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
678     {
679         if ((streamMask >> i) & 0x1)
680         {
681             memset(pAfRd->data.sample[i], strFrameLen, 0);
682         }
683         pAfRd->data.samsiz[i] = 0;
684     }