]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_dsp/framework/aspDecOpCircBuf_master.c
Fixed bugs in Circular buffer.
[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 channel pointers
621         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
622         Cache_wait();
624         // Invalidate PCM data
625         for (i = 0; i < pCb->maxAFChanNum; i++)
626         {
627             if ((streamMask >> i) & 0x1)
628             {
629                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
630             }
631         }
632         Cache_wait();        
633         
634         // read audio frame information updated by decoder
635         pAfRd->sampleDecode = pAfCb->sampleDecode;
636         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
637         pAfRd->sampleRate = pAfCb->sampleRate;
638         pAfRd->sampleCount = pCb->strFrameLen;
639         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
640         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
641         
642         // read metadata information updated by decoder //QIN
643         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
644         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
645         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
646         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
647         
648         // update Last Cb info as per actual stream
649         pCb->lastAf.sampleCount = pCb->strFrameLen;
650         pCb->lastAf.sampleRate = pAfCb->sampleRate;
652         // read PCM samples
653         for (i = 0; i < pCb->maxAFChanNum; i++)
654         {
655             if ((streamMask >> i) & 0x1)
656             {
657                 for (j = 0; j < pCb->strFrameLen; j++)
658                 {
659                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
660                 }
662                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
663             }
664         }
665         
666         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
667         {
668             pAfRd->pafPrivateMetadata[i].offset = 0;
669             pAfRd->pafPrivateMetadata[i].size   = 0;
670         }
671         
672         // read metadata //QIN
673         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
674         {
675             // FL: this is done above
676             ////Invalidate metadata data
677             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
678             //Cache_wait();        
679             
680             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
681                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
682                  &&(pAfCb->pafPrivateMetadata[i].size))
683             {
684                 // FL: this is done above
685                 ////Invalidate metadata data
686                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
687                 //Cache_wait();        
688         
689                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
690                 pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
691                 pAfRd->pafPrivateMetadata[numMetadata].size   = pAfCb->pafPrivateMetadata[i].size;
692                 memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
693                 numMetadata++; //number of metadata associated with current 256 segment of audio samples
694             }
695             else //reset un-used buf
696             {
697                 pAfRd->pafPrivateMetadata[i].offset = 0;
698                 pAfRd->pafPrivateMetadata[i].size   = 0;
699             }
701         }
702         pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
703         
704         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
705         if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
706         {
707             // update audio frame read index
708             pCb->afRdIdx++;
709             if (pCb->afRdIdx >= pCb->maxNumAfCb)
710             {
711                 pCb->afRdIdx = 0;
712             }
713             
714             // update PCM read index
715             pCb->pcmRdIdx = 0;
716             
717             // update number of audio frames in circular buffer
718             pCb->numAfCb--;
719         }
720         memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
721     }
722     
723     if (pCb->emptyFlag == 1)
724     {
725         //
726         // Writer inactive, but remaining frames in circular buffer.
727         // Update empty flag.
728         //
729         if (pCb->numAfCb <= 0)
730         {
731             pCb->emptyFlag = 0;
732         }
733     }
734     
735     // (***) FL: revisit
736     // Write back circular buffer configuration.
737     // NOTE: Probably only a subset of this information needs to be updated.
738     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
739     Cache_wait();    
740         
741     // Leave the gate
742     GateMP_leave(gateHandle, key);
744     return ASP_DECOP_CB_SOK;
747 // Generate mute AF on circular buffer read
748 static Void cbReadAfMute(
749     PAF_AudioFrame *pAfRd,      // audio frame into which to read
750     Int16 strFrameLen           // stream frame length (output transaction size)
753     PAF_ChannelMask_HD streamMask;
754     Int8 i;
755     
756     pAfRd->sampleDecode = PAF_SOURCE_PCM;
757     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
758     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
759     pAfRd->sampleCount = strFrameLen;
760     pAfRd->channelConfigurationRequest.full = 0;
761     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
762     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
763     pAfRd->channelConfigurationStream.full = 0;
764     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
765     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
766     
767     // compute stream mask
768     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
769     // Clear PCM data
770     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
771     {
772         if ((streamMask >> i) & 0x1)
773         {
774             memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
775         }
776         pAfRd->data.samsiz[i] = 0;
777     }
778     // write metadata information updated by decoder
779     pAfRd->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
780     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
781     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
782     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
784 // Init last audio frame configuration info 
785 static Void cbInitLastAfInfo(
786     PAF_AudioFrame *pAfRd      // last audio frame stored in CB instance
789     pAfRd->sampleDecode = PAF_SOURCE_PCM;
790     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
791     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
792     pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
793     pAfRd->channelConfigurationRequest.full = 0;
794     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
795     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
796     pAfRd->channelConfigurationStream.full = 0;
797     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
798     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
800     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
801     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
802     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
803     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
806 // Generate mute AF on circular buffer read using the last AF configuration info 
807 static Void cbReadMuteWithLastAfInfo (
808     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
809     PAF_AudioFrame *pAfRd         // audio frame into which to read
812     PAF_ChannelMask_HD streamMask;
813     Int8 i;
815     pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
816     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
817     pAfRd->sampleRate  = pCb->lastAf.sampleRate;
818     pAfRd->sampleCount = pCb->strFrameLen;
819     pAfRd->channelConfigurationRequest.full     = pCb->lastAf.channelConfigurationRequest.full;
820     pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat;
821     pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
822     pAfRd->channelConfigurationStream.full      = pCb->lastAf.channelConfigurationStream.full;
823     pAfRd->channelConfigurationStream.part.sat  = pCb->lastAf.channelConfigurationStream.part.sat;
824     pAfRd->channelConfigurationStream.part.sub  = pCb->lastAf.channelConfigurationStream.part.sub;
825     
826     // compute stream mask
827     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
828     // Clear PCM data
829     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
830     {
831         if ((streamMask >> i) & 0x1)
832         {
833             memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
834         }
835         pAfRd->data.samsiz[i] = 0;
836     }
837     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
838     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
839     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
840     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */