]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - processor_audio_sdk_1_00_00_00/pasdk/test_dsp/framework/aspDecOpCircBuf_master.c
Change Gate SR to 0, comment out debug traces
[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     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
236     // set source select
237     pCb->sourceSel = sourceSelect;
239     // set input frame length
240     pCb->decOpFrameLen = decOpFrameLen;
241     
242     // set output frame length
243     pCb->strFrameLen = strFrameLen;
244     
245     // initialize circular buffer maximum number of audio frames
246     if (sourceSelect == PAF_SOURCE_PCM)
247     {
248         pCb->maxNumAfCb = MAX_NUM_AF_PCM;
249         pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
250         pCb->afRdIdx = 0;
251         pCb->pcmRdIdx = 0; // 2*256 in behind
252         
253         // initialize audio frames
254         for (n=0; n<pCb->maxNumAfCb; n++)
255         {
256             pAfCb = &pCb->afCb[n];
257             pAfCb->sampleDecode = PAF_SOURCE_PCM;
258             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
259             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
260             pAfCb->sampleCount = decOpFrameLen;
261             pAfCb->channelConfigurationRequest.full = 0;
262             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
263             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
264             pAfCb->channelConfigurationStream.full = 0;
265             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
266             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
267         }
268     }
269     else if (sourceSelect == PAF_SOURCE_DDP)
270     {
271         pCb->maxNumAfCb = MAX_NUM_AF_DDP;
272         pCb->afWrtIdx = 1;
273         pCb->afRdIdx = 0;
274         pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG_DDP*strFrameLen; // 4*256 behind
275         
276         // initialize audio frames
277         for (n=0; n<pCb->maxNumAfCb; n++)
278         {
279             pAfCb = &pCb->afCb[n];
280             pAfCb->sampleDecode = PAF_SOURCE_DDP;
281             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
282             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
283             pAfCb->sampleCount = decOpFrameLen;
284             pAfCb->channelConfigurationRequest.full = 0;
285             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
286             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
287             pAfCb->channelConfigurationStream.full = 0;
288             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
289             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
290         }
291     }
292     else
293     {
294         // Leave the gate
295         GateMP_leave(gateHandle, key);
297         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
298     }
300     // initialize circular buffer current number of frames
301     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
302     
303     // initialize audio frame PCM buffers
304     pPcmBuf = pCb->pcmBuf;
305     pMetaBuf = pCb->metaBuf; //QIN
306     for (n=0; n<pCb->maxNumAfCb; n++)
307     {
308         pAfCb = &pCb->afCb[n];
309         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
310         pAfCb->data.nSamples = decOpFrameLen;
311         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
312         {
313             pAfCb->data.sample[i] = pPcmBuf;
314             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
315             pPcmBuf += decOpFrameLen;
316             
317             pAfCb->data.samsiz[i] = 0;
318         }
319         
320         // Initialize metadata buffers //QIN
321         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
322         {
323             pAfCb->pafPrivateMetadata[i].offset = 0; 
324             pAfCb->pafPrivateMetadata[i].size   = 0; 
325             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
326             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
327         }
328     }
329     
330     // reset read/write flags
331     if (resetRwFlags)
332     {
333         pCb->writerActiveFlag = 0;
334         pCb->readerActiveFlag = 0;
335         pCb->emptyFlag = 0;
336     }
337     
338     // reset error counts
339     pCb->errUndCnt = 0;
340     pCb->errOvrCnt = 0;
341     
342     // (***) FL: revisit
343     // Write back circular buffer configuration
344     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
345     // Write back AF circular buffer
346     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
347     // Write back PCM data
348     for (n=0; n<pCb->maxNumAfCb; n++)
349     {
350         pAfCb = &pCb->afCb[n];
351         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
352         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
353         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
354         {
355             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
356         }
357         // FL: unnecessary since part of AF
358         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
359         //{
360         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
361         //}
362     }
363     Cache_wait();
365     // Leave the gate
366     GateMP_leave(gateHandle, key);
367     
368     return ASP_DECOP_CB_SOK;
371 // Start reads from circular buffer
372 Int cbReadStart(
373     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
374     Int8 cbIdx                          // decoder output circular buffer index
377     IArg key;
378     GateMP_Handle gateHandle;
379     PAF_AST_DecOpCircBuf *pCb;
381     // Get gate handle
382     gateHandle = pCbCtl->gateHandle;
383     // Enter gate
384     key = GateMP_enter(gateHandle);
386     // Get circular buffer base pointer
387     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
388     
389     // Invalidate circular buffer configuration
390     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
391     Cache_wait();
392     
393     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
395     // update flags
396     pCb->readerActiveFlag = 1;
397     
398     // (***) FL: revisit
399     // Write back circular buffer configuration
400     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
401     Cache_wait();
403     // Leave the gate
404     GateMP_leave(gateHandle, key);
406     return ASP_DECOP_CB_SOK;
409 // Stop reads from circular buffer
410 Int cbReadStop(
411     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
412     Int8 cbIdx                          // decoder output circular buffer index
415     IArg key;
416     GateMP_Handle gateHandle;
417     PAF_AST_DecOpCircBuf *pCb;
419     // Get gate handle
420     gateHandle = pCbCtl->gateHandle;
421     // Enter gate
422     key = GateMP_enter(gateHandle);
424     // Get circular buffer base pointer
425     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
427     // Invalidate circular buffer configuration
428     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
429     Cache_wait();
430     
431     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
433     // update flags
434     pCb->readerActiveFlag = 0;
435     
436     // (***) FL: revisit
437     // Write back circular buffer configuration
438     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
439     Cache_wait();
441     // Leave the gate
442     GateMP_leave(gateHandle, key);
444     return ASP_DECOP_CB_SOK;
447 // Read audio frame from circular buffer
448 Int cbReadAf(
449     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
450     Int8 cbIdx,                         // decoder output circular buffer index
451     PAF_AudioFrame *pAfRd               // audio frame into which to read
454     IArg key;
455     GateMP_Handle gateHandle;
456     PAF_AST_DecOpCircBuf *pCb;
457     PAF_AudioFrame *pAfCb;
458     PAF_ChannelMask_HD streamMask;
459     Int8 i;
460     Int16 j;
462     // Get gate handle
463     gateHandle = pCbCtl->gateHandle;
464     // Enter gate
465     key = GateMP_enter(gateHandle);
467     // Get circular buffer base pointer
468     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
470     // (***) FL: revisit
471     // Invalidate circular buffer configuration.
472     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
473     Cache_wait();
475     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
477     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
478     {
479         // This shouldn't occur:
480         //  writer is active AND draining circular buffer
481         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
482         SW_BREAKPOINT; // FL: debug
483         
484         // Leave the gate
485         GateMP_leave(gateHandle, key);
486         
487         return ASP_DECOP_CB_READ_INVSTATE;
488     }
490     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
491     {
492         //
493         // No active writer, not draining circular buffer.
494         // Skip UNDerflow check, mute output.
495         //
496         cbReadAfMute(pAfRd, pCb->strFrameLen);
497         
498         // Leave the gate
499         GateMP_leave(gateHandle, key);
501         return ASP_DECOP_CB_SOK;
502     }
503     
504     // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
505     // Here we are checking (1,0) state here
506     if ((pCb->writerActiveFlag == 1))
507     {
508         // check underflow
509         if (pCb->numAfCb <= 0)
510         {
511             // 
512             // Increment underflow count.
513             // Mute output on underflow.
514             //
515             pCb->errUndCnt++;
516             cbReadAfMute(pAfRd, pCb->strFrameLen);
517             //SW_BREAKPOINT; // FL: debug
518             
519             // Write back circular buffer configuration.
520             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
521             Cache_wait();    
522             
523             // Leave the gate
524             GateMP_leave(gateHandle, key);
525             
526             return ASP_DECOP_CB_READ_UNDERFLOW;
527         }
528     }
529     
530     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
531     {
532         //
533         // Writer active or draining remaining frames in circular buffer.
534         // Get next output audio frame.
535         //
536         
537         // get pointer to current audio frame in circular buffer
538         pAfCb = &pCb->afCb[pCb->afRdIdx];
540         // (***) FL: revisit
541         // Invalidate audio frame
542         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
543         Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
544         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
545         {
546             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
547             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
548         }
549         Cache_wait();
551         // compute stream mask
552         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
554         // Invalidate PCM data
555         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
556         {
557             if ((streamMask >> i) & 0x1)
558             {
559                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
560             }
561         }
562         Cache_wait();        
563         
564         // read audio frame information updated by decoder
565         pAfRd->sampleDecode = pAfCb->sampleDecode;
566         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
567         pAfRd->sampleRate = pAfCb->sampleRate;
568         pAfRd->sampleCount = pCb->strFrameLen;
569         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
570         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
571         
572         // read metadata information updated by decoder //QIN
573         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
574         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
575         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
576         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
577         
578         // read PCM samples
579         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
580         {
581             if ((streamMask >> i) & 0x1)
582             {
583                 for (j = 0; j < pCb->strFrameLen; j++)
584                 {
585                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
586                 }
588                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
589             }
590         }
591         // read metadata //QIN
592         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
593         {
594             // FL: this is done above
595             ////Invalidate metadata data
596             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
597             //Cache_wait();        
598             
599             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
600                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
601                  &&(pAfCb->pafPrivateMetadata[i].size))
602             {
603                 // FL: this is done above
604                 ////Invalidate metadata data
605                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
606                 //Cache_wait();        
607         
608                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
609                 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
610                 pAfRd->pafPrivateMetadata[i].size   = pAfCb->pafPrivateMetadata[i].size;
611                 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
612             }
613             else //reset un-used buf
614             {
615                 pAfRd->pafPrivateMetadata[i].offset = 0;
616                 pAfRd->pafPrivateMetadata[i].size   = 0;
617             }
618         }
619         
620         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
621         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
622         {
623             // update audio frame read index
624             pCb->afRdIdx++;
625             if (pCb->afRdIdx >= pCb->maxNumAfCb)
626             {
627                 pCb->afRdIdx = 0;
628             }
629             
630             // update PCM read index
631             pCb->pcmRdIdx = 0;
632             
633             // update number of audio frames in circular buffer
634             pCb->numAfCb--;
635         }
636     }
637     
638     if (pCb->emptyFlag == 1)
639     {
640         //
641         // Writer inactive, but remaining frames in circular buffer.
642         // Update empty flag.
643         //
644         if (pCb->numAfCb <= 0)
645         {
646             pCb->emptyFlag = 0;
647         }
648     }
649     
650     // (***) FL: revisit
651     // Write back circular buffer configuration.
652     // NOTE: Probably only a subset of this information needs to be updated.
653     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
654     Cache_wait();    
655         
656     // Leave the gate
657     GateMP_leave(gateHandle, key);
659     return ASP_DECOP_CB_SOK;
662 // Generate mute AF on circular buffer read
663 static Void cbReadAfMute(
664     PAF_AudioFrame *pAfRd,      // audio frame into which to read
665     Int16 strFrameLen           // stream frame length (output transaction size)
668     PAF_ChannelMask_HD streamMask;
669     Int8 i;
670     
671     pAfRd->sampleDecode = PAF_SOURCE_PCM;
672     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
673     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
674     pAfRd->sampleCount = strFrameLen;
675     pAfRd->channelConfigurationRequest.full = 0;
676     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
677     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
678     pAfRd->channelConfigurationStream.full = 0;
679     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
680     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
681     
682     // compute stream mask
683     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
684     // Clear PCM data
685     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
686     {
687         if ((streamMask >> i) & 0x1)
688         {
689             memset(pAfRd->data.sample[i], strFrameLen, 0);
690         }
691         pAfRd->data.samsiz[i] = 0;
692     }