1e677e35b6875afb4c14869f852ad27cbbd80398
[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 // Generate mute AF on circular buffer read
53 static Void cbReadAfMute(
54     PAF_AudioFrame *pAfRd,      // audio frame into which to read
55     Int16 strFrameLen           // stream frame length (output transaction size)
56 );
59 // Initialize circular buffer control
60 Int cbCtlInit(
61     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
62     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
63 )
64 {
65     GateMP_Params gateParams;
66     GateMP_Handle gateHandle;
67     
68     GateMP_Params_init(&gateParams);
69     gateParams.localProtect = GateMP_LocalProtect_THREAD;
70     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
71     gateParams.name = ASP_DECODE_CB_GATE_NAME;
72     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
73     gateHandle = GateMP_create(&gateParams);
74     if (gateHandle != NULL)
75     {
76         pCbCtl->gateHandle = gateHandle;
77     }
78     else
79     {
80         pCbCtl->gateHandle = NULL;
81         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
82     }
83     
84     pCbCtl->pXDecOpCb = pXDecOpCb;
85     
86     return ASP_DECOP_CB_SOK;
87     
88 }
90 // Initialize circular buffer
91 Int cbInit(
92     PAF_AST_DecOpCircBuf *pCb
93 )
94 {
95     PAF_AudioFrame *pAfCb;
96     PAF_AudioData *pPcmBuf;
97     UInt8 *pMetaBuf;
98     Int8 n;
99     Int8 i;
101     // set source select
102     pCb->sourceSel = DEF_SOURCE_SEL;
104     // set input frame length
105     pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
106     
107     // set output frame length
108     pCb->strFrameLen = DEF_STR_FRAME_LEN;
109     
110     // initialize circular buffer maximum number of audio frames
111     pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
112     pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
113     pCb->afRdIdx = 0;
114     pCb->pcmRdIdx = 0; // 2*256 in behind
115     
116     // initialize audio frames
117     for (n=0; n<pCb->maxNumAfCb; n++)
118     {
119         pAfCb = &pCb->afCb[n];
120         pAfCb->sampleDecode = PAF_SOURCE_PCM;
121         PAF_PROCESS_ZERO(pAfCb->sampleProcess);
122         pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
123         pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
124         pAfCb->channelConfigurationRequest.full = 0;
125         pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
126         pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
127         pAfCb->channelConfigurationStream.full = 0;
128         pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
129         pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
130     }
132     // initialize circular buffer current number of frames
133     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
134     
135     // initialize audio frame PCM buffers
136     pPcmBuf = pCb->pcmBuf;
137     pMetaBuf = pCb->metaBuf; //QIN
138     for (n=0; n<pCb->maxNumAfCb; n++)
139     {
140         pAfCb = &pCb->afCb[n];
141         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
142         pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
143         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
144         {
145             pAfCb->data.sample[i] = pPcmBuf;
146             memset(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN, 0);
147             pPcmBuf += DEF_DEC_OP_FRAME_LEN;
148             
149             pAfCb->data.samsiz[i] = 0;
150         }
151         
152         // Initialize metadata buffers //QIN
153         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
154         {
155             pAfCb->pafPrivateMetadata[i].offset = 0; 
156             pAfCb->pafPrivateMetadata[i].size   = 0; 
157             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
158             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
159         }
160     }
161     
162     // reset read/write flags
163     pCb->writerActiveFlag = 0;
164     pCb->readerActiveFlag = 0;
165     pCb->emptyFlag = 0;
166     
167     // reset error counts
168     pCb->errUndCnt = 0;
169     pCb->errOvrCnt = 0;
170     
171     // (***) FL: revisit
172     // Write back circular buffer configuration
173     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
174     // Write back AF circular buffer
175     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
176     // Write back PCM data
177     for (n=0; n<pCb->maxNumAfCb; n++)
178     {
179         pAfCb = &pCb->afCb[n];
180         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
181         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
182         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
183         {
184             Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
185         }
186         // FL: unnecessary since part of AF
187         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
188         //{
189         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
190         //}
191     }
192     Cache_wait();
194     return ASP_DECOP_CB_SOK;
197 // Initialize circular buffer based on selected source
198 Int cbInitSourceSel(
199     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
200     Int8 cbIdx,                         // decoder output circular buffer index
201     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
202     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
203     Int16 strFrameLen,                  // stream frame length (PCM samples)
204     Int8 resetRwFlags                   // whether to reset reader, writer, and empty flags
207     IArg key;
208     GateMP_Handle gateHandle;
209     PAF_AST_DecOpCircBuf *pCb;
210     PAF_AudioFrame *pAfCb;
211     PAF_AudioData *pPcmBuf;
212     UInt8 *pMetaBuf; //QIN
213     Int8 n;
214     Int8 i;
216     // Get gate handle
217     gateHandle = pCbCtl->gateHandle;
218     // Enter gate
219     key = GateMP_enter(gateHandle);
221     // Get circular buffer base pointer
222     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
223     
224     // Invalidate circular buffer configuration
225     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
226     Cache_wait();
228     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
230     // set source select
231     pCb->sourceSel = sourceSelect;
233     // set input frame length
234     pCb->decOpFrameLen = decOpFrameLen;
235     
236     // set output frame length
237     pCb->strFrameLen = strFrameLen;
238     
239     // initialize circular buffer maximum number of audio frames
240     if (sourceSelect == PAF_SOURCE_PCM)
241     {
242         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
243         // 2*256 in behind
244         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
245         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
246         pCb->pcmRdIdx = 0;
247         
248         // initialize audio frames
249         for (n=0; n<pCb->maxNumAfCb; n++)
250         {
251             pAfCb = &pCb->afCb[n];
252             pAfCb->sampleDecode = sourceSelect;
253             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
254             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
255             pAfCb->sampleCount = decOpFrameLen;
256             pAfCb->channelConfigurationRequest.full = 0;
257             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
258             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
259             pAfCb->channelConfigurationStream.full = 0;
260             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
261             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
262         }
263     }
264     else if (sourceSelect == PAF_SOURCE_DDP)
265     {
266         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
267         // 4*256 in behind
268         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
269         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
270         pCb->pcmRdIdx = decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
271         
272         // initialize audio frames
273         for (n=0; n<pCb->maxNumAfCb; n++)
274         {
275             pAfCb = &pCb->afCb[n];
276             pAfCb->sampleDecode = sourceSelect;
277             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
278             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
279             pAfCb->sampleCount = decOpFrameLen;
280             pAfCb->channelConfigurationRequest.full = 0;
281             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
282             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
283             pAfCb->channelConfigurationStream.full = 0;
284             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
285             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
286         }
287     }
288     else
289     {
290         // Leave the gate
291         GateMP_leave(gateHandle, key);
293         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
294     }
296     // initialize circular buffer current number of frames
297     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
298     
299     // initialize audio frame PCM buffers
300     pPcmBuf = pCb->pcmBuf;
301     pMetaBuf = pCb->metaBuf; //QIN
302     for (n=0; n<pCb->maxNumAfCb; n++)
303     {
304         pAfCb = &pCb->afCb[n];
305         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
306         pAfCb->data.nSamples = decOpFrameLen;
307         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
308         {
309             pAfCb->data.sample[i] = pPcmBuf;
310             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
311             pPcmBuf += decOpFrameLen;
312             
313             pAfCb->data.samsiz[i] = 0;
314         }
315         
316         // Initialize metadata buffers //QIN
317         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
318         {
319             pAfCb->pafPrivateMetadata[i].offset = 0; 
320             pAfCb->pafPrivateMetadata[i].size   = 0; 
321             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
322             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
323         }
324     }
325     
326     // reset read/write flags
327     if (resetRwFlags)
328     {
329         pCb->writerActiveFlag = 0;
330         pCb->readerActiveFlag = 0;
331         pCb->emptyFlag = 0;
332     }
333     
334     // reset error counts
335     pCb->errUndCnt = 0;
336     pCb->errOvrCnt = 0;
337     
338     // (***) FL: revisit
339     // Write back circular buffer configuration
340     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
341     // Write back AF circular buffer
342     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
343     // Write back PCM data
344     for (n=0; n<pCb->maxNumAfCb; n++)
345     {
346         pAfCb = &pCb->afCb[n];
347         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
348         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
349         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
350         {
351             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
352         }
353         // FL: unnecessary since part of AF
354         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
355         //{
356         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
357         //}
358     }
359     Cache_wait();
361     // Leave the gate
362     GateMP_leave(gateHandle, key);
363     
364     return ASP_DECOP_CB_SOK;
367 // Start reads from circular buffer
368 Int cbReadStart(
369     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
370     Int8 cbIdx                          // decoder output circular buffer index
373     IArg key;
374     GateMP_Handle gateHandle;
375     PAF_AST_DecOpCircBuf *pCb;
377     // Get gate handle
378     gateHandle = pCbCtl->gateHandle;
379     // Enter gate
380     key = GateMP_enter(gateHandle);
382     // Get circular buffer base pointer
383     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
384     
385     // Invalidate circular buffer configuration
386     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
387     Cache_wait();
388     
389     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
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     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
429     // update flags
430     pCb->readerActiveFlag = 0;
431     
432     // (***) FL: revisit
433     // Write back circular buffer configuration
434     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
435     Cache_wait();
437     // Leave the gate
438     GateMP_leave(gateHandle, key);
440     return ASP_DECOP_CB_SOK;
443 // Read audio frame from circular buffer
444 Int cbReadAf(
445     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
446     Int8 cbIdx,                         // decoder output circular buffer index
447     PAF_AudioFrame *pAfRd               // audio frame into which to read
450     IArg key;
451     GateMP_Handle gateHandle;
452     PAF_AST_DecOpCircBuf *pCb;
453     PAF_AudioFrame *pAfCb;
454     PAF_ChannelMask_HD streamMask;
455     Int8 i;
456     Int16 j;
458     // Get gate handle
459     gateHandle = pCbCtl->gateHandle;
460     // Enter gate
461     key = GateMP_enter(gateHandle);
463     // Get circular buffer base pointer
464     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
466     // (***) FL: revisit
467     // Invalidate circular buffer configuration.
468     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
469     Cache_wait();
471     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
473     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
474     {
475         // This shouldn't occur:
476         //  writer is active AND draining circular buffer
477         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
478         SW_BREAKPOINT; // FL: debug
479         
480         // Leave the gate
481         GateMP_leave(gateHandle, key);
482         
483         return ASP_DECOP_CB_READ_INVSTATE;
484     }
486     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
487     {
488         //
489         // No active writer, not draining circular buffer.
490         // Skip UNDerflow check, mute output.
491         //
492         cbReadAfMute(pAfRd, pCb->strFrameLen);
493         
494         // Leave the gate
495         GateMP_leave(gateHandle, key);
497         return ASP_DECOP_CB_SOK;
498     }
499     
500     // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
501     // Here we are checking (1,0) state here
502     if ((pCb->writerActiveFlag == 1))
503     {
504         // check underflow
505         if (pCb->numAfCb <= 0)
506         {
507             // 
508             // Increment underflow count.
509             // Mute output on underflow.
510             //
511             pCb->errUndCnt++;
512             cbReadAfMute(pAfRd, pCb->strFrameLen);
513             //SW_BREAKPOINT; // FL: debug
514             
515             // Write back circular buffer configuration.
516             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
517             Cache_wait();    
518             
519             // Leave the gate
520             GateMP_leave(gateHandle, key);
521             
522             return ASP_DECOP_CB_READ_UNDERFLOW;
523         }
524     }
525     
526     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
527     {
528         //
529         // Writer active or draining remaining frames in circular buffer.
530         // Get next output audio frame.
531         //
532         
533         // get pointer to current audio frame in circular buffer
534         pAfCb = &pCb->afCb[pCb->afRdIdx];
536         // (***) FL: revisit
537         // Invalidate audio frame
538         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
539         Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
540         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
541         {
542             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
543             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
544         }
545         Cache_wait();
547         // compute stream mask
548         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
550         // Invalidate PCM data
551         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
552         {
553             if ((streamMask >> i) & 0x1)
554             {
555                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
556             }
557         }
558         Cache_wait();        
559         
560         // read audio frame information updated by decoder
561         pAfRd->sampleDecode = pAfCb->sampleDecode;
562         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
563         pAfRd->sampleRate = pAfCb->sampleRate;
564         pAfRd->sampleCount = pCb->strFrameLen;
565         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
566         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
567         
568         // read metadata information updated by decoder //QIN
569         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
570         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
571         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
572         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
573         
574         // read PCM samples
575         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
576         {
577             if ((streamMask >> i) & 0x1)
578             {
579                 for (j = 0; j < pCb->strFrameLen; j++)
580                 {
581                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
582                 }
584                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
585             }
586         }
587         // read metadata //QIN
588         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
589         {
590             // FL: this is done above
591             ////Invalidate metadata data
592             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
593             //Cache_wait();        
594             
595             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
596                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
597                  &&(pAfCb->pafPrivateMetadata[i].size))
598             {
599                 // FL: this is done above
600                 ////Invalidate metadata data
601                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
602                 //Cache_wait();        
603         
604                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
605                 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
606                 pAfRd->pafPrivateMetadata[i].size   = pAfCb->pafPrivateMetadata[i].size;
607                 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
608             }
609             else //reset un-used buf
610             {
611                 pAfRd->pafPrivateMetadata[i].offset = 0;
612                 pAfRd->pafPrivateMetadata[i].size   = 0;
613             }
614         }
615         
616         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
617         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
618         {
619             // update audio frame read index
620             pCb->afRdIdx++;
621             if (pCb->afRdIdx >= pCb->maxNumAfCb)
622             {
623                 pCb->afRdIdx = 0;
624             }
625             
626             // update PCM read index
627             pCb->pcmRdIdx = 0;
628             
629             // update number of audio frames in circular buffer
630             pCb->numAfCb--;
631         }
632     }
633     
634     if (pCb->emptyFlag == 1)
635     {
636         //
637         // Writer inactive, but remaining frames in circular buffer.
638         // Update empty flag.
639         //
640         if (pCb->numAfCb <= 0)
641         {
642             pCb->emptyFlag = 0;
643         }
644     }
645     
646     // (***) FL: revisit
647     // Write back circular buffer configuration.
648     // NOTE: Probably only a subset of this information needs to be updated.
649     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
650     Cache_wait();    
651         
652     // Leave the gate
653     GateMP_leave(gateHandle, key);
655     return ASP_DECOP_CB_SOK;
658 // Generate mute AF on circular buffer read
659 static Void cbReadAfMute(
660     PAF_AudioFrame *pAfRd,      // audio frame into which to read
661     Int16 strFrameLen           // stream frame length (output transaction size)
664     PAF_ChannelMask_HD streamMask;
665     Int8 i;
666     
667     pAfRd->sampleDecode = PAF_SOURCE_PCM;
668     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
669     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
670     pAfRd->sampleCount = strFrameLen;
671     pAfRd->channelConfigurationRequest.full = 0;
672     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
673     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
674     pAfRd->channelConfigurationStream.full = 0;
675     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
676     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
677     
678     // compute stream mask
679     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
680     // Clear PCM data
681     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
682     {
683         if ((streamMask >> i) & 0x1)
684         {
685             memset(pAfRd->data.sample[i], strFrameLen, 0);
686         }
687         pAfRd->data.samsiz[i] = 0;
688     }