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