PASDK-258:Merge remote-tracking branch 'origin/dev_pasdk_pp_pasdk258HigherSampleRateS...
[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 "dbgBenchmark.h" // PCM high-sampling rate + SRC + CAR benchmarking
50 #define DEF_SOURCE_SEL          ( PAF_SOURCE_PCM ) // default source select
51 #define DEF_DEC_OP_FRAME_LEN    ( PAF_SYS_FRAMELENGTH )   // ( 256 )     // default decoder output frame length
52 #define DEF_STR_FRAME_LEN       ( PAF_SYS_FRAMELENGTH )     // default stream frame length
54 // Generate mute AF on circular buffer read
55 static Void cbReadAfMute(
56     PAF_AudioFrame *pAfRd,      // audio frame into which to read
57     Int16 strFrameLen           // stream frame length (output transaction size)
58 );
60 // Init last audio frame configuration info 
61 static Void cbInitLastAfInfo(
62     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
63 );
65 // Generate mute AF on circular buffer read using the last AF configuration info 
66 static Void cbReadMuteWithLastAfInfo (
67     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
68     PAF_AudioFrame *pAfRd         // audio frame into which to read
69 );
71 // Initialize circular buffer control
72 Int cbCtlInit(
73     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
74     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
75 )
76 {
77     GateMP_Params gateParams;
78     GateMP_Handle gateHandle;
79     
80     GateMP_Params_init(&gateParams);
81     gateParams.localProtect = GateMP_LocalProtect_THREAD;
82     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
83     gateParams.name = ASP_DECODE_CB_GATE_NAME;
84     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
85     gateHandle = GateMP_create(&gateParams);
86     if (gateHandle != NULL)
87     {
88         pCbCtl->gateHandle = gateHandle;
89     }
90     else
91     {
92         pCbCtl->gateHandle = NULL;
93         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
94     }
95     
96     pCbCtl->pXDecOpCb = pXDecOpCb;
97     
98     return ASP_DECOP_CB_SOK;
99     
102 // Initialize circular buffer
103 Int cbInit(
104     PAF_AST_DecOpCircBuf *pCb
107     PAF_AudioFrame *pAfCb;
108     PAF_AudioData *pPcmBuf;
109     UInt8 *pMetaBuf;
110     Int8 n;
111     Int8 i;
113     // set source select
114     pCb->sourceSel = DEF_SOURCE_SEL;
116     // set input frame length
117     pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
118     
119     // set output frame length
120     pCb->strFrameLen = DEF_STR_FRAME_LEN;
121     
122     // initialize circular buffer maximum number of audio frames
123     pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;//ASP_DECOP_CB_MAX_NUM_AF_PCM;
124     pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
125     pCb->afRdIdx = 0;
126     pCb->pcmRdIdx = 0; // 2*256 in behind
127     
128     // set default value to PCM configuration
129     pCb->maxAFChanNum   = ASP_DECOP_CB_MAX_NUM_PCM_CH;
130     pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
131     // initialize audio frames
132     for (n=0; n<pCb->maxNumAfCb; n++)
133     {
134         pAfCb = &pCb->afCb[n];
135         pAfCb->sampleDecode = PAF_SOURCE_PCM;
136         PAF_PROCESS_ZERO(pAfCb->sampleProcess);
137         pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
138         pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
139         pAfCb->channelConfigurationRequest.full = 0;
140         pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
141         pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
142         pAfCb->channelConfigurationStream.full = 0;
143         pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
144         pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
145     }
147     // initialize circular buffer current number of frames
148     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
149     
150     // initialize audio frame PCM buffers
151     pPcmBuf = pCb->pcmBuf;
152     pMetaBuf = pCb->metaBuf; //QIN
153     for (n=0; n<pCb->maxNumAfCb; n++)
154     {
155         pAfCb = &pCb->afCb[n];
156         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
157         pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
158         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
159         {
160             pAfCb->data.sample[i] = pPcmBuf;
161             memset(pAfCb->data.sample[i], 0, DEF_DEC_OP_FRAME_LEN);
162             pPcmBuf += DEF_DEC_OP_FRAME_LEN;
163             
164             pAfCb->data.samsiz[i] = 0;
165         }
166         
167         // write metadata information updated by decoder
168         pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
169         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
170         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
171         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
172         
173         // Initialize metadata buffers //QIN
174         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
175         {
176             pAfCb->pafPrivateMetadata[i].offset = 0; 
177             pAfCb->pafPrivateMetadata[i].size   = 0; 
178             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
179             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
180         }
181     }
182     
183     // reset read/write flags
184     pCb->writerActiveFlag = 0;
185     pCb->readerActiveFlag = 0;
186     pCb->emptyFlag = 0;
187     
188     // reset error counts
189     pCb->errUndCnt = 0;
190     pCb->errOvrCnt = 0;
191     
192     cbInitLastAfInfo(&pCb->lastAf);
194     // (***) FL: revisit
195     // Write back circular buffer configuration
196     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
197     // Write back AF circular buffer
198     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
199     // Write back PCM data
200     for (n=0; n<pCb->maxNumAfCb; n++)
201     {
202         pAfCb = &pCb->afCb[n];
203         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
204         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
205         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
206         {
207             Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
208         }
209         // FL: unnecessary since part of AF
210         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
211         //{
212         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
213         //}
214     }
215     Cache_wait();
217     return ASP_DECOP_CB_SOK;
220 // Initialize circular buffer based on selected source
221 Int cbInitSourceSel(
222     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
223     Int8 cbIdx,                         // decoder output circular buffer index
224     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
225     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
226     Int16 strFrameLen,                  // stream frame length (PCM samples)
227     Int8 resetRwFlags                   // whether to reset reader, writer, and empty flags
230     IArg key;
231     GateMP_Handle gateHandle;
232     PAF_AST_DecOpCircBuf *pCb;
233     PAF_AudioFrame *pAfCb;
234     PAF_AudioData *pPcmBuf;
235     UInt8 *pMetaBuf; //QIN
236     Int8 n;
237     Int8 i;
239     // Get gate handle
240     gateHandle = pCbCtl->gateHandle;
241     // Enter gate
242     key = GateMP_enter(gateHandle);
244     // Get circular buffer base pointer
245     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
246     
247     // Invalidate circular buffer configuration
248     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
249     Cache_wait();
251     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
253     // set source select
254     pCb->sourceSel = sourceSelect;
256     // set input frame length
257     pCb->decOpFrameLen = decOpFrameLen;
258     
259     // set output frame length
260     pCb->strFrameLen = strFrameLen;
261     
262     // initialize circular buffer maximum number of audio frames
263     if (sourceSelect == PAF_SOURCE_PCM)
264     {
265         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
266         // 2*256 in behind
267         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
268         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
269         pCb->pcmRdIdx = 0;
270         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
271         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
272         
273         // initialize audio frames
274         for (n=0; n<pCb->maxNumAfCb; n++)
275         {
276             pAfCb = &pCb->afCb[n];
277             pAfCb->sampleDecode = sourceSelect;
278             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
279             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
280             pAfCb->sampleCount = decOpFrameLen;
281             pAfCb->channelConfigurationRequest.full = 0;
282             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
283             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
284             pAfCb->channelConfigurationStream.full = 0;
285             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
286             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
287             
288             // write metadata information updated by decoder
289             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
290             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
291             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
292             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
293         }
294     }
295     else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
296     {
297         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
298         // 4*256 in behind
299         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
300         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
301         pCb->pcmRdIdx = decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
302         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
303         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
304         
305         // initialize audio frames
306         for (n=0; n<pCb->maxNumAfCb; n++)
307         {
308             pAfCb = &pCb->afCb[n];
309             pAfCb->sampleDecode = sourceSelect;
310             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
311             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
312             pAfCb->sampleCount = decOpFrameLen;
313             pAfCb->channelConfigurationRequest.full = 0;
314             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
315             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
316             pAfCb->channelConfigurationStream.full = 0;
317             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
318             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
319             
320             // write metadata information updated by decoder
321             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
322             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
323             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
324             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
325         }
326     }
327     else if (sourceSelect == PAF_SOURCE_THD)
328     {
329         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
330         // 0 in behind
331         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
332         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
333         pCb->pcmRdIdx = 0;
334         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
335         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
336         
337         // initialize audio frames
338         for (n=0; n<pCb->maxNumAfCb; n++)
339         {
340             pAfCb = &pCb->afCb[n];
341             pAfCb->sampleDecode = sourceSelect;
342             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
343             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
344             pAfCb->sampleCount = decOpFrameLen;
345             pAfCb->channelConfigurationRequest.full = 0;
346             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
347             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
348             pAfCb->channelConfigurationStream.full = 0;
349             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
350             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
351             
352             // write metadata information updated by decoder
353             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
354             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
355             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
356             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
357         }
358     }
359     else
360     {
361         SW_BREAKPOINT;
362         
363         // Leave the gate
364         GateMP_leave(gateHandle, key);
366         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
367     }
369     // initialize circular buffer current number of frames
370     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
371     
372     // initialize audio frame PCM buffers
373     pPcmBuf = pCb->pcmBuf;
374     pMetaBuf = pCb->metaBuf; //QIN
375     for (n=0; n<pCb->maxNumAfCb; n++)
376     {
377         pAfCb = &pCb->afCb[n];
378         pAfCb->data.nChannels = pCb->maxAFChanNum;
379         pAfCb->data.nSamples = decOpFrameLen;
380         for (i=0; i<pCb->maxAFChanNum; i++)
381         {
382             pAfCb->data.sample[i] = pPcmBuf;
383             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
384             pPcmBuf += pCb->maxAFSampCount;
385             
386             pAfCb->data.samsiz[i] = 0;
387         }
388         
389         // Initialize metadata buffers //QIN
390         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
391         {
392             pAfCb->pafPrivateMetadata[i].offset = 0; 
393             pAfCb->pafPrivateMetadata[i].size   = 0; 
394             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
395             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
396         }
397     }
398     
399     // reset read/write flags
400     if (resetRwFlags)
401     {
402         pCb->writerActiveFlag = 0;
403         pCb->readerActiveFlag = 0;
404         pCb->emptyFlag = 0;
405     }
406     
407     // reset error counts
408     pCb->errUndCnt = 0;
409     pCb->errOvrCnt = 0;
410     
411     // (***) FL: revisit
412     // Write back circular buffer configuration
413     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
414     // Write back AF circular buffer
415     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
416     // Write back PCM data
417     for (n=0; n<pCb->maxNumAfCb; n++)
418     {
419         pAfCb = &pCb->afCb[n];
420         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
421         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
422         for (i=0; i<pCb->maxAFChanNum; i++)
423         {
424             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
425         }
426     }
427     Cache_wait();
429     // Leave the gate
430     GateMP_leave(gateHandle, key);
431     
432     return ASP_DECOP_CB_SOK;
435 // Start reads from circular buffer
436 Int cbReadStart(
437     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
438     Int8 cbIdx                          // decoder output circular buffer index
441     IArg key;
442     GateMP_Handle gateHandle;
443     PAF_AST_DecOpCircBuf *pCb;
445     // Get gate handle
446     gateHandle = pCbCtl->gateHandle;
447     // Enter gate
448     key = GateMP_enter(gateHandle);
450     // Get circular buffer base pointer
451     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
452     
453     // Invalidate circular buffer configuration
454     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
455     Cache_wait();
456     
457     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
459     // update flags
460     pCb->readerActiveFlag = 1;
461     
462     // (***) FL: revisit
463     // Write back circular buffer configuration
464     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
465     Cache_wait();
467     // Leave the gate
468     GateMP_leave(gateHandle, key);
470     return ASP_DECOP_CB_SOK;
473 // Stop reads from circular buffer
474 Int cbReadStop(
475     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
476     Int8 cbIdx                          // decoder output circular buffer index
479     IArg key;
480     GateMP_Handle gateHandle;
481     PAF_AST_DecOpCircBuf *pCb;
483     // Get gate handle
484     gateHandle = pCbCtl->gateHandle;
485     // Enter gate
486     key = GateMP_enter(gateHandle);
488     // Get circular buffer base pointer
489     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
491     // Invalidate circular buffer configuration
492     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
493     Cache_wait();
494     
495     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
497     // update flags
498     pCb->readerActiveFlag = 0;
499     
500     // (***) FL: revisit
501     // Write back circular buffer configuration
502     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
503     Cache_wait();
505     // Leave the gate
506     GateMP_leave(gateHandle, key);
508     return ASP_DECOP_CB_SOK;
511 // Read audio frame from circular buffer
512 Int cbReadAf(
513     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
514     Int8 cbIdx,                         // decoder output circular buffer index
515     PAF_AudioFrame *pAfRd               // audio frame into which to read
518     IArg key;
519     GateMP_Handle gateHandle;
520     PAF_AST_DecOpCircBuf *pCb;
521     PAF_AudioFrame *pAfCb;
522     PAF_ChannelMask_HD streamMask;
523     Int8 i;
524     Int16 j;
525     Int8 numMetadata = 0;
527     // Get gate handle
528     gateHandle = pCbCtl->gateHandle;
529     // Enter gate
530     key = GateMP_enter(gateHandle);
532     // Get circular buffer base pointer
533     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
535     // (***) FL: revisit
536     // Invalidate circular buffer configuration.
537     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
538     Cache_wait();
540     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
542     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
543     {
544         // This shouldn't occur:
545         //  writer is active AND draining circular buffer
546         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
547         SW_BREAKPOINT; // FL: debug
548         
549         // Leave the gate
550         GateMP_leave(gateHandle, key);
551         
552         return ASP_DECOP_CB_READ_INVSTATE;
553     }
555     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
556     {
557         //
558         // No active writer, not draining circular buffer.
559         // Skip UNDerflow check, mute output.
560         //
561         //cbReadAfMute(pAfRd, pCb->strFrameLen);
562         cbReadMuteWithLastAfInfo(pCb, pAfRd);
563         
564         // Leave the gate
565         GateMP_leave(gateHandle, key);
567         return ASP_DECOP_CB_SOK;
568     }
569     
570     // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
571     // Here we are checking (1,0) state here
572     if (pCb->writerActiveFlag == 1)
573     {
574         // check underflow
575         if (pCb->numAfCb <= 0)
576         {
577             // 
578             // Increment underflow count.
579             // Mute output on underflow.
580             //
581             pCb->errUndCnt++;
582             //cbReadAfMute(pAfRd, pCb->strFrameLen);
583             cbReadMuteWithLastAfInfo(pCb, pAfRd);
584             //SW_BREAKPOINT; // FL: debug
585             
586             // Write back circular buffer configuration.
587             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
588             Cache_wait();    
589             
590             // Leave the gate
591             GateMP_leave(gateHandle, key);
592             
593             return ASP_DECOP_CB_READ_UNDERFLOW;
594         }
595     }
596     
597     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
598     {
599         //
600         // Writer active or draining remaining frames in circular buffer.
601         // Get next output audio frame.
602         //
603         
604         // get pointer to current audio frame in circular buffer
605         pAfCb = &pCb->afCb[pCb->afRdIdx];
607         // (***) FL: revisit
608         // Invalidate audio frame
609         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
610         Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
611         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
612         {
613             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
614         }
615         Cache_wait();
617         // compute stream mask
618         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
620         // Invalidate PCM data
621         for (i = 0; i < pCb->maxAFChanNum; i++)
622         {
623             if ((streamMask >> i) & 0x1)
624             {
625                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
626             }
627         }
628         Cache_wait();        
629         
630         // read audio frame information updated by decoder
631         pAfRd->sampleDecode = pAfCb->sampleDecode;
632         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
633         pAfRd->sampleRate = pAfCb->sampleRate;
634         pAfRd->sampleCount = pCb->strFrameLen;
635         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
636         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
637         
638         // read metadata information updated by decoder //QIN
639         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
640         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
641         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
642         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
643         
644         // update Last Cb info as per actual stream
645         pCb->lastAf.sampleCount = pCb->strFrameLen;
646         pCb->lastAf.sampleRate = pAfCb->sampleRate;
648         // read PCM samples
649         for (i = 0; i < pCb->maxAFChanNum; i++)
650         {
651             if ((streamMask >> i) & 0x1)
652             {
653                 for (j = 0; j < pCb->strFrameLen; j++)
654                 {
655                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
656                 }
658                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
659             }
660         }
661         
662         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
663         {
664             pAfRd->pafPrivateMetadata[i].offset = 0;
665             pAfRd->pafPrivateMetadata[i].size   = 0;
666         }
667         
668         // read metadata //QIN
669         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
670         {
671             // FL: this is done above
672             ////Invalidate metadata data
673             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
674             //Cache_wait();        
675             
676             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
677                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
678                  &&(pAfCb->pafPrivateMetadata[i].size))
679             {
680                 // FL: this is done above
681                 ////Invalidate metadata data
682                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
683                 //Cache_wait();        
684         
685                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
686                 pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
687                 pAfRd->pafPrivateMetadata[numMetadata].size   = pAfCb->pafPrivateMetadata[i].size;
688                 memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
689                 numMetadata++; //number of metadata associated with current 256 segment of audio samples
690             }
691             else //reset un-used buf
692             {
693                 pAfRd->pafPrivateMetadata[i].offset = 0;
694                 pAfRd->pafPrivateMetadata[i].size   = 0;
695             }
697         }
698         pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
699         
700         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
701         if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
702         {
703             // update audio frame read index
704             pCb->afRdIdx++;
705             if (pCb->afRdIdx >= pCb->maxNumAfCb)
706             {
707                 pCb->afRdIdx = 0;
708             }
709             
710             // update PCM read index
711             pCb->pcmRdIdx = 0;
712             
713             // update number of audio frames in circular buffer
714             pCb->numAfCb--;
715         }
716         memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
717     }
718     
719     if (pCb->emptyFlag == 1)
720     {
721         //
722         // Writer inactive, but remaining frames in circular buffer.
723         // Update empty flag.
724         //
725         if (pCb->numAfCb <= 0)
726         {
727             pCb->emptyFlag = 0;
728         }
729     }
730     
731     // (***) FL: revisit
732     // Write back circular buffer configuration.
733     // NOTE: Probably only a subset of this information needs to be updated.
734     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
735     Cache_wait();    
736         
737     // Leave the gate
738     GateMP_leave(gateHandle, key);
740     return ASP_DECOP_CB_SOK;
743 // Generate mute AF on circular buffer read
744 static Void cbReadAfMute(
745     PAF_AudioFrame *pAfRd,      // audio frame into which to read
746     Int16 strFrameLen           // stream frame length (output transaction size)
749     PAF_ChannelMask_HD streamMask;
750     Int8 i;
751     
752     pAfRd->sampleDecode = PAF_SOURCE_PCM;
753     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
754     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
755     pAfRd->sampleCount = strFrameLen;
756     pAfRd->channelConfigurationRequest.full = 0;
757     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
758     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
759     pAfRd->channelConfigurationStream.full = 0;
760     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
761     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
762     
763     // compute stream mask
764     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
765     // Clear PCM data
766     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
767     {
768         if ((streamMask >> i) & 0x1)
769         {
770             memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
771         }
772         pAfRd->data.samsiz[i] = 0;
773     }
774     // write metadata information updated by decoder
775     pAfRd->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
776     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
777     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
778     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
780 // Init last audio frame configuration info 
781 static Void cbInitLastAfInfo(
782     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
785     pAfRd->sampleDecode = PAF_SOURCE_PCM;
786     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
787     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
788     pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
789     pAfRd->channelConfigurationRequest.full = 0;
790     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
791     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
792     pAfRd->channelConfigurationStream.full = 0;
793     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
794     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
796     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
797     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
798     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
799     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
802 // Generate mute AF on circular buffer read using the last AF configuration info 
803 static Void cbReadMuteWithLastAfInfo (
804     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
805     PAF_AudioFrame *pAfRd         // audio frame into which to read
808     PAF_ChannelMask_HD streamMask;
809     Int8 i;
811     pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
812     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
813     pAfRd->sampleRate  = pCb->lastAf.sampleRate;
814     pAfRd->sampleCount = pCb->strFrameLen;
815     pAfRd->channelConfigurationRequest.full     = pCb->lastAf.channelConfigurationRequest.full;
816     pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat;
817     pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
818     pAfRd->channelConfigurationStream.full      = pCb->lastAf.channelConfigurationStream.full;
819     pAfRd->channelConfigurationStream.part.sat  = pCb->lastAf.channelConfigurationStream.part.sat;
820     pAfRd->channelConfigurationStream.part.sub  = pCb->lastAf.channelConfigurationStream.part.sub;
821     
822     // compute stream mask
823     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
824     // Clear PCM data
825     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
826     {
827         if ((streamMask >> i) & 0x1)
828         {
829             memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
830         }
831         pAfRd->data.samsiz[i] = 0;
832     }
833     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
834     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
835     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
836     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */