Add metadata initialization to cbInit routines
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / framework / aspDecOpCircBuf_master.c
2 /*
3 Copyright (c) 2016, Texas Instruments Incorporated - http://www.ti.com/
4 All rights reserved.
6 * Redistribution and use in source and binary forms, with or without 
7 * modification, are permitted provided that the following conditions
8 * are met:
9 *
10 * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 *
13 * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the
16 * distribution.
17 *
18 * Neither the name of Texas Instruments Incorporated nor the names of
19 * its contributors may be used to endorse or promote products derived
20 * from this software without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
25 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
26 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
28 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
30 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
31 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
32 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 *
34 */
36 #include <string.h> // for memset()
37 #include <xdc/std.h>
38 #include <xdc/runtime/Log.h>
39 #include <ti/sysbios/hal/Cache.h>
40 #include <ti/uia/events/UIAEvt.h>
41 #include <ti/ipc/GateMP.h>
43 #include "common.h"
44 #include "paftyp.h"
45 #include "pafdec.h"
46 #include "aspDecOpCircBuf_master.h"
48 #define DEF_SOURCE_SEL          ( PAF_SOURCE_PCM ) // default source select
49 #define DEF_DEC_OP_FRAME_LEN    ( 256 )     // default decoder output frame length
50 #define DEF_STR_FRAME_LEN       ( 256 )     // default stream frame length
52 // Generate mute AF on circular buffer read
53 static Void cbReadAfMute(
54     PAF_AudioFrame *pAfRd,      // audio frame into which to read
55     Int16 strFrameLen           // stream frame length (output transaction size)
56 );
59 // Initialize circular buffer control
60 Int cbCtlInit(
61     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
62     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
63 )
64 {
65     GateMP_Params gateParams;
66     GateMP_Handle gateHandle;
67     
68     GateMP_Params_init(&gateParams);
69     gateParams.localProtect = GateMP_LocalProtect_THREAD;
70     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
71     gateParams.name = ASP_DECODE_CB_GATE_NAME;
72     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
73     gateHandle = GateMP_create(&gateParams);
74     if (gateHandle != NULL)
75     {
76         pCbCtl->gateHandle = gateHandle;
77     }
78     else
79     {
80         pCbCtl->gateHandle = NULL;
81         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
82     }
83     
84     pCbCtl->pXDecOpCb = pXDecOpCb;
85     
86     return ASP_DECOP_CB_SOK;
87     
88 }
90 // Initialize circular buffer
91 Int cbInit(
92     PAF_AST_DecOpCircBuf *pCb
93 )
94 {
95     PAF_AudioFrame *pAfCb;
96     PAF_AudioData *pPcmBuf;
97     UInt8 *pMetaBuf;
98     Int8 n;
99     Int8 i;
101     // set source select
102     pCb->sourceSel = DEF_SOURCE_SEL;
104     // set input frame length
105     pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
106     
107     // set output frame length
108     pCb->strFrameLen = DEF_STR_FRAME_LEN;
109     
110     // initialize circular buffer maximum number of audio frames
111     pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
112     pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
113     pCb->afRdIdx = 0;
114     pCb->pcmRdIdx = 0; // 2*256 in behind
115     
116     // initialize audio frames
117     for (n=0; n<pCb->maxNumAfCb; n++)
118     {
119         pAfCb = &pCb->afCb[n];
120         pAfCb->sampleDecode = PAF_SOURCE_PCM;
121         PAF_PROCESS_ZERO(pAfCb->sampleProcess);
122         pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
123         pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
124         pAfCb->channelConfigurationRequest.full = 0;
125         pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
126         pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
127         pAfCb->channelConfigurationStream.full = 0;
128         pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
129         pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
130     }
132     // initialize circular buffer current number of frames
133     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
134     
135     // initialize audio frame PCM buffers
136     pPcmBuf = pCb->pcmBuf;
137     pMetaBuf = pCb->metaBuf; //QIN
138     for (n=0; n<pCb->maxNumAfCb; n++)
139     {
140         pAfCb = &pCb->afCb[n];
141         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
142         pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
143         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
144         {
145             pAfCb->data.sample[i] = pPcmBuf;
146             memset(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN, 0);
147             pPcmBuf += DEF_DEC_OP_FRAME_LEN;
148             
149             pAfCb->data.samsiz[i] = 0;
150         }
151         
152         // write metadata information updated by decoder
153         pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
154         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
155         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
156         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
157         
158         // Initialize metadata buffers //QIN
159         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
160         {
161             pAfCb->pafPrivateMetadata[i].offset = 0; 
162             pAfCb->pafPrivateMetadata[i].size   = 0; 
163             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
164             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
165         }
166     }
167     
168     // reset read/write flags
169     pCb->writerActiveFlag = 0;
170     pCb->readerActiveFlag = 0;
171     pCb->emptyFlag = 0;
172     
173     // reset error counts
174     pCb->errUndCnt = 0;
175     pCb->errOvrCnt = 0;
176     
177     // (***) FL: revisit
178     // Write back circular buffer configuration
179     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
180     // Write back AF circular buffer
181     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
182     // Write back PCM data
183     for (n=0; n<pCb->maxNumAfCb; n++)
184     {
185         pAfCb = &pCb->afCb[n];
186         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
187         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
188         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
189         {
190             Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
191         }
192         // FL: unnecessary since part of AF
193         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
194         //{
195         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
196         //}
197     }
198     Cache_wait();
200     return ASP_DECOP_CB_SOK;
203 // Initialize circular buffer based on selected source
204 Int cbInitSourceSel(
205     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
206     Int8 cbIdx,                         // decoder output circular buffer index
207     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
208     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
209     Int16 strFrameLen,                  // stream frame length (PCM samples)
210     Int8 resetRwFlags                   // whether to reset reader, writer, and empty flags
213     IArg key;
214     GateMP_Handle gateHandle;
215     PAF_AST_DecOpCircBuf *pCb;
216     PAF_AudioFrame *pAfCb;
217     PAF_AudioData *pPcmBuf;
218     UInt8 *pMetaBuf; //QIN
219     Int8 n;
220     Int8 i;
222     // Get gate handle
223     gateHandle = pCbCtl->gateHandle;
224     // Enter gate
225     key = GateMP_enter(gateHandle);
227     // Get circular buffer base pointer
228     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
229     
230     // Invalidate circular buffer configuration
231     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
232     Cache_wait();
234     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
236     // set source select
237     pCb->sourceSel = sourceSelect;
239     // set input frame length
240     pCb->decOpFrameLen = decOpFrameLen;
241     
242     // set output frame length
243     pCb->strFrameLen = strFrameLen;
244     
245     // initialize circular buffer maximum number of audio frames
246     if (sourceSelect == PAF_SOURCE_PCM)
247     {
248         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
249         // 2*256 in behind
250         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
251         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
252         pCb->pcmRdIdx = 0;
253         
254         // initialize audio frames
255         for (n=0; n<pCb->maxNumAfCb; n++)
256         {
257             pAfCb = &pCb->afCb[n];
258             pAfCb->sampleDecode = sourceSelect;
259             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
260             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
261             pAfCb->sampleCount = decOpFrameLen;
262             pAfCb->channelConfigurationRequest.full = 0;
263             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
264             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
265             pAfCb->channelConfigurationStream.full = 0;
266             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
267             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
268             
269             // write metadata information updated by decoder
270             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
271             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
272             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
273             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
274         }
275     }
276     else if (sourceSelect == PAF_SOURCE_DDP)
277     {
278         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
279         // 4*256 in behind
280         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
281         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
282         pCb->pcmRdIdx = decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
283         
284         // initialize audio frames
285         for (n=0; n<pCb->maxNumAfCb; n++)
286         {
287             pAfCb = &pCb->afCb[n];
288             pAfCb->sampleDecode = sourceSelect;
289             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
290             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
291             pAfCb->sampleCount = decOpFrameLen;
292             pAfCb->channelConfigurationRequest.full = 0;
293             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
294             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
295             pAfCb->channelConfigurationStream.full = 0;
296             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
297             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
298             
299             // write metadata information updated by decoder
300             pAfCb->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
301             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
302             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
303             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
304         }
305     }
306     else
307     {
308         SW_BREAKPOINT;
309         
310         // Leave the gate
311         GateMP_leave(gateHandle, key);
313         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
314     }
316     // initialize circular buffer current number of frames
317     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
318     
319     // initialize audio frame PCM buffers
320     pPcmBuf = pCb->pcmBuf;
321     pMetaBuf = pCb->metaBuf; //QIN
322     for (n=0; n<pCb->maxNumAfCb; n++)
323     {
324         pAfCb = &pCb->afCb[n];
325         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
326         pAfCb->data.nSamples = decOpFrameLen;
327         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
328         {
329             pAfCb->data.sample[i] = pPcmBuf;
330             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
331             pPcmBuf += decOpFrameLen;
332             
333             pAfCb->data.samsiz[i] = 0;
334         }
335         
336         // Initialize metadata buffers //QIN
337         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
338         {
339             pAfCb->pafPrivateMetadata[i].offset = 0; 
340             pAfCb->pafPrivateMetadata[i].size   = 0; 
341             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
342             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
343         }
344     }
345     
346     // reset read/write flags
347     if (resetRwFlags)
348     {
349         pCb->writerActiveFlag = 0;
350         pCb->readerActiveFlag = 0;
351         pCb->emptyFlag = 0;
352     }
353     
354     // reset error counts
355     pCb->errUndCnt = 0;
356     pCb->errOvrCnt = 0;
357     
358     // (***) FL: revisit
359     // Write back circular buffer configuration
360     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
361     // Write back AF circular buffer
362     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
363     // Write back PCM data
364     for (n=0; n<pCb->maxNumAfCb; n++)
365     {
366         pAfCb = &pCb->afCb[n];
367         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
368         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
369         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
370         {
371             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
372         }
373         // FL: unnecessary since part of AF
374         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
375         //{
376         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
377         //}
378     }
379     Cache_wait();
381     // Leave the gate
382     GateMP_leave(gateHandle, key);
383     
384     return ASP_DECOP_CB_SOK;
387 // Start reads from circular buffer
388 Int cbReadStart(
389     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
390     Int8 cbIdx                          // decoder output circular buffer index
393     IArg key;
394     GateMP_Handle gateHandle;
395     PAF_AST_DecOpCircBuf *pCb;
397     // Get gate handle
398     gateHandle = pCbCtl->gateHandle;
399     // Enter gate
400     key = GateMP_enter(gateHandle);
402     // Get circular buffer base pointer
403     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
404     
405     // Invalidate circular buffer configuration
406     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
407     Cache_wait();
408     
409     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
411     // update flags
412     pCb->readerActiveFlag = 1;
413     
414     // (***) FL: revisit
415     // Write back circular buffer configuration
416     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
417     Cache_wait();
419     // Leave the gate
420     GateMP_leave(gateHandle, key);
422     return ASP_DECOP_CB_SOK;
425 // Stop reads from circular buffer
426 Int cbReadStop(
427     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
428     Int8 cbIdx                          // decoder output circular buffer index
431     IArg key;
432     GateMP_Handle gateHandle;
433     PAF_AST_DecOpCircBuf *pCb;
435     // Get gate handle
436     gateHandle = pCbCtl->gateHandle;
437     // Enter gate
438     key = GateMP_enter(gateHandle);
440     // Get circular buffer base pointer
441     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
443     // Invalidate circular buffer configuration
444     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
445     Cache_wait();
446     
447     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
449     // update flags
450     pCb->readerActiveFlag = 0;
451     
452     // (***) FL: revisit
453     // Write back circular buffer configuration
454     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
455     Cache_wait();
457     // Leave the gate
458     GateMP_leave(gateHandle, key);
460     return ASP_DECOP_CB_SOK;
463 // Read audio frame from circular buffer
464 Int cbReadAf(
465     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
466     Int8 cbIdx,                         // decoder output circular buffer index
467     PAF_AudioFrame *pAfRd               // audio frame into which to read
470     IArg key;
471     GateMP_Handle gateHandle;
472     PAF_AST_DecOpCircBuf *pCb;
473     PAF_AudioFrame *pAfCb;
474     PAF_ChannelMask_HD streamMask;
475     Int8 i;
476     Int16 j;
478     // Get gate handle
479     gateHandle = pCbCtl->gateHandle;
480     // Enter gate
481     key = GateMP_enter(gateHandle);
483     // Get circular buffer base pointer
484     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
486     // (***) FL: revisit
487     // Invalidate circular buffer configuration.
488     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
489     Cache_wait();
491     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
493     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
494     {
495         // This shouldn't occur:
496         //  writer is active AND draining circular buffer
497         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
498         SW_BREAKPOINT; // FL: debug
499         
500         // Leave the gate
501         GateMP_leave(gateHandle, key);
502         
503         return ASP_DECOP_CB_READ_INVSTATE;
504     }
506     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
507     {
508         //
509         // No active writer, not draining circular buffer.
510         // Skip UNDerflow check, mute output.
511         //
512         cbReadAfMute(pAfRd, pCb->strFrameLen);
513         
514         // Leave the gate
515         GateMP_leave(gateHandle, key);
517         return ASP_DECOP_CB_SOK;
518     }
519     
520     // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
521     // Here we are checking (1,0) state here
522     if ((pCb->writerActiveFlag == 1))
523     {
524         // check underflow
525         if (pCb->numAfCb <= 0)
526         {
527             // 
528             // Increment underflow count.
529             // Mute output on underflow.
530             //
531             pCb->errUndCnt++;
532             cbReadAfMute(pAfRd, pCb->strFrameLen);
533             //SW_BREAKPOINT; // FL: debug
534             
535             // Write back circular buffer configuration.
536             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
537             Cache_wait();    
538             
539             // Leave the gate
540             GateMP_leave(gateHandle, key);
541             
542             return ASP_DECOP_CB_READ_UNDERFLOW;
543         }
544     }
545     
546     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
547     {
548         //
549         // Writer active or draining remaining frames in circular buffer.
550         // Get next output audio frame.
551         //
552         
553         // get pointer to current audio frame in circular buffer
554         pAfCb = &pCb->afCb[pCb->afRdIdx];
556         // (***) FL: revisit
557         // Invalidate audio frame
558         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
559         Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
560         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
561         {
562             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
563             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
564         }
565         Cache_wait();
567         // compute stream mask
568         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
570         // Invalidate PCM data
571         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
572         {
573             if ((streamMask >> i) & 0x1)
574             {
575                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
576             }
577         }
578         Cache_wait();        
579         
580         // read audio frame information updated by decoder
581         pAfRd->sampleDecode = pAfCb->sampleDecode;
582         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
583         pAfRd->sampleRate = pAfCb->sampleRate;
584         pAfRd->sampleCount = pCb->strFrameLen;
585         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
586         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
587         
588         // read metadata information updated by decoder //QIN
589         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
590         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
591         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
592         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
593         
594         // read PCM samples
595         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
596         {
597             if ((streamMask >> i) & 0x1)
598             {
599                 for (j = 0; j < pCb->strFrameLen; j++)
600                 {
601                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
602                 }
604                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
605             }
606         }
607         // read metadata //QIN
608         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
609         {
610             // FL: this is done above
611             ////Invalidate metadata data
612             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
613             //Cache_wait();        
614             
615             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
616                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
617                  &&(pAfCb->pafPrivateMetadata[i].size))
618             {
619                 // FL: this is done above
620                 ////Invalidate metadata data
621                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
622                 //Cache_wait();        
623         
624                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
625                 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
626                 pAfRd->pafPrivateMetadata[i].size   = pAfCb->pafPrivateMetadata[i].size;
627                 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
628             }
629             else //reset un-used buf
630             {
631                 pAfRd->pafPrivateMetadata[i].offset = 0;
632                 pAfRd->pafPrivateMetadata[i].size   = 0;
633             }
634         }
635         
636         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
637         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
638         {
639             // update audio frame read index
640             pCb->afRdIdx++;
641             if (pCb->afRdIdx >= pCb->maxNumAfCb)
642             {
643                 pCb->afRdIdx = 0;
644             }
645             
646             // update PCM read index
647             pCb->pcmRdIdx = 0;
648             
649             // update number of audio frames in circular buffer
650             pCb->numAfCb--;
651         }
652     }
653     
654     if (pCb->emptyFlag == 1)
655     {
656         //
657         // Writer inactive, but remaining frames in circular buffer.
658         // Update empty flag.
659         //
660         if (pCb->numAfCb <= 0)
661         {
662             pCb->emptyFlag = 0;
663         }
664     }
665     
666     // (***) FL: revisit
667     // Write back circular buffer configuration.
668     // NOTE: Probably only a subset of this information needs to be updated.
669     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
670     Cache_wait();    
671         
672     // Leave the gate
673     GateMP_leave(gateHandle, key);
675     return ASP_DECOP_CB_SOK;
678 // Generate mute AF on circular buffer read
679 static Void cbReadAfMute(
680     PAF_AudioFrame *pAfRd,      // audio frame into which to read
681     Int16 strFrameLen           // stream frame length (output transaction size)
684     PAF_ChannelMask_HD streamMask;
685     Int8 i;
686     
687     pAfRd->sampleDecode = PAF_SOURCE_PCM;
688     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
689     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
690     pAfRd->sampleCount = strFrameLen;
691     pAfRd->channelConfigurationRequest.full = 0;
692     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
693     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
694     pAfRd->channelConfigurationStream.full = 0;
695     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
696     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
697     
698     // compute stream mask
699     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
700     // Clear PCM data
701     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
702     {
703         if ((streamMask >> i) & 0x1)
704         {
705             memset(pAfRd->data.sample[i], strFrameLen, 0);
706         }
707         pAfRd->data.samsiz[i] = 0;
708     }
709     // write metadata information updated by decoder
710     pAfRd->bsMetadata_type     = PAF_bsMetadata_channelData;    /* non zero if metadata is attached. */
711     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
712     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
713     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */