13189f94c415211fdd0cc7861d4a595f98f442f1
[processor-sdk/performance-audio-sr.git] / pasdk / test_arm / framework / aspDecOpCircBuf_slave.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>
42 #include "common.h"
43 #include "paftyp.h"
44 //#include "pafdec.h"
45 //#include "pafsp.h"
46 #include "aspDecOpCircBuf_slave.h"
48 #include "evmc66x_gpio_dbg.h" // Debug
50 #if 0 // FL: moved to common
51 // Initialize circular buffer control
52 Int cbCtlInit(
53     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
54     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
55 )
56 {
57     GateMP_Handle gateHandle;
58     Int status;
59     
60     do {
61         status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
62     } while (status == GateMP_E_NOTFOUND);
63     if (status == GateMP_S_SUCCESS)
64     {
65         pCbCtl->gateHandle = gateHandle;
66     }
67     else
68     {
69         pCbCtl->gateHandle = NULL;
70         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
71     }
72     
73     pCbCtl->numCb = numCb;          // init number of circular buffers
74     pCbCtl->pXDecOpCb = pXDecOpCb;  // init base address of circular buffers
75     
76     return ASP_DECOP_CB_SOK;
77 }
78 #endif
80 // debug
81 //Int8 gCbInitSourceSelCnt=0;
82 //Int8 gCbInitSourceSelThdCnt=0;
84 // Initialize circular buffer based on selected source
85 Int cbInitSourceSel(
86     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
87     Int8 cbIdx,                         // decoder output circular buffer index
88     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
89     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
90     Int16 strFrameLen,                  // stream frame length (PCM samples)
91     Int8 resetRwFlags,                  // whether to reset reader, writer, and drain flags
92     PAF_AudioFrame *pDecInfo1Af         // pointer to Dec Info1 audio frame
93 )
94 {
95     IArg key;
96     GateMP_Handle gateHandle;
97     PAF_AST_DecOpCircBuf *pCb;
98     PAF_AudioFrame *pAfCb;
99     PAF_AudioData *pPcmBuf;
100     UInt8 *pMetaBuf;
101     Int8 n;
102     Int8 i;
104     //gCbInitSourceSelCnt++; // debug
105     
106     // Get gate handle
107     gateHandle = pCbCtl->gateHandle;
108     // Enter gate
109     key = GateMP_enter(gateHandle);
111     // Get circular buffer base pointer
112     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
113     
114     // Invalidate circular buffer configuration
115     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
116     Cache_wait();
118     //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
120     // Set source select
121     pCb->sourceSel = sourceSelect;
123     // Set input frame length
124     pCb->decOpFrameLen = decOpFrameLen;
125     
126     // Set output frame length
127     pCb->strFrameLen = strFrameLen;
129     //pCb->afInitialLag = 0;  // default No lag
130     //pCb->afLagIdx = 0;
131     // Initialize CB primed flag
132     pCb->primedFlag = 0;
133     // Initialize delta samples
134     pCb->deltaSamps = 0;
135     
136     // Initialize circular buffer:
137     //  - maximum number of AFs
138     //  - target nominal delay
139     //  - AF write, read indices
140     //  - maximum AF channel and sample counts
141     if (sourceSelect == PAF_SOURCE_PCM)
142     {
143         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
144         
145         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
146         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
147         
148         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
149         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
150         pCb->pcmRdIdx = 0;
151         
152         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
153         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;        
154     }
155     else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
156     {
157         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
158         
159         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
160         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
161         
162         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
163         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
164         pCb->pcmRdIdx = 0;
165         
166         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
167         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
168     }
169     else if (sourceSelect == PAF_SOURCE_THD)
170     {
171         //gCbInitSourceSelThdCnt++; //debug
172         
173         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
174         
175         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
176         // FL: (***) set nominal delay per sampling rate -- need to review these settings
177         switch (pDecInfo1Af->sampleRate)
178         {
179             case PAF_SAMPLERATE_44100HZ:
180             case PAF_SAMPLERATE_48000HZ:
181                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
182                 break;
183             case PAF_SAMPLERATE_88200HZ:
184             case PAF_SAMPLERATE_96000HZ:
185                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
186                 break;
187             case PAF_SAMPLERATE_176400HZ:
188             case PAF_SAMPLERATE_192000HZ:
189                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
190                 break;
191         }
192         
193         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
194         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
195         pCb->pcmRdIdx = 0;
196         
197         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
198         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;        
199     }
200     else
201     {
202         //
203         // Currently unsupported source select
204         //
205         
206         SW_BREAKPOINT; // debug
207         
208         // Leave the gate
209         GateMP_leave(gateHandle, key);
211         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
212     }
213     
214     // Initialize audio frames
215     for (n = 0; n < pCb->maxNumAfCb; n++)
216     {
217         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
218         
219         // Dec Info1 AF sample count not correct for CB AFs
220         pAfCb->sampleCount = decOpFrameLen;
222         // initialize CB AF using Dec Info1 AF
223         pAfCb->sampleDecode = pDecInfo1Af->sampleDecode;
224         PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInfo1Af->sampleProcess);
225         pAfCb->sampleRate = pDecInfo1Af->sampleRate;
226         pAfCb->channelConfigurationRequest.full = pDecInfo1Af->channelConfigurationRequest.full;
227         pAfCb->channelConfigurationStream.full = pDecInfo1Af->channelConfigurationStream.full;
228         
229         // initialize metadata information updated by decoder
230         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
231         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
232         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
233         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
234     }
235     
236     // Initialize circular buffer current number of frames
237     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
238     
239     // Initialize audio frame PCM buffers
240     pPcmBuf = pCb->pcmBuf;
241     pMetaBuf = pCb->metaBuf;
242     for (n=0; n<pCb->maxNumAfCb; n++)
243     {
244         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
245         
246         pAfCb->data.nChannels = pCb->maxAFChanNum;
247         pAfCb->data.nSamples = decOpFrameLen;
248         for (i=0; i<pCb->maxAFChanNum; i++)
249         {
250             pAfCb->data.sample[i] = pPcmBuf;
251             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
252             pPcmBuf += pCb->maxAFSampCount;
253             
254             pAfCb->data.samsiz[i] = 0;
255         }
256         
257         // Initialize metadata buffers
258         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
259         {
260             pAfCb->pafPrivateMetadata[i].offset = 0; 
261             pAfCb->pafPrivateMetadata[i].size   = 0; 
262             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
263             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
264         }
265     }
266     
267     // Reset read/write flags
268     if (resetRwFlags != 0)
269     {
270         pCb->writerActiveFlag = 0;
271         pCb->readerActiveFlag = 0;
272         pCb->drainFlag = 0;
273     }
274     
275     // Reset stats
276     pCb->readAfWriterInactiveCnt = 0;
277     pCb->wrtAfReaderInactiveCnt = 0;
278     pCb->wrtAfZeroSampsCnt = 0;
279     pCb->errUndCnt = 0;
280     pCb->errOvrCnt = 0;
281     
282     // Write back circular buffer configuration
283     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
284     // Write back AF circular buffer
285     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
286     // Write back PCM data
287     for (n=0; n<pCb->maxNumAfCb; n++)
288     {
289         pAfCb = &pCb->afCb[n];
290         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
291         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
292         for (i=0; i<pCb->maxAFChanNum; i++)
293         {
294             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
295         }
296     }
297     Cache_wait();
299     // Leave the gate
300     GateMP_leave(gateHandle, key);
301     
302     return ASP_DECOP_CB_SOK;
305 //Int8 gCbWriteStartCnt=0; // debug
307 // Start writes to circular buffer
308 Int cbWriteStart(
309     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
310     Int8 cbIdx                          // decoder output circular buffer index
313     IArg key;
314     GateMP_Handle gateHandle;
315     PAF_AST_DecOpCircBuf *pCb;
316     PAF_AudioFrame *pAfCb;
317     Int8 n;
318     //Int8 i;
320     //gCbWriteStartCnt++; // debug
321     
322     // Get gate handle
323     gateHandle = pCbCtl->gateHandle;
324     // Enter gate
325     key = GateMP_enter(gateHandle);
327     // Get circular buffer base pointer
328     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
330     // Invalidate circular buffer configuration.
331     // NOTE: Probably only a subset of this information needs to be updated.
332     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
333     Cache_wait();
334     
335     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
336     
337     // Invalidate AF circular buffer
338     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
339     for (n=0; n<pCb->maxNumAfCb; n++)
340     {
341         pAfCb = &pCb->afCb[n];
342         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
343     }
344     Cache_wait();
345             
346     // update flags
347     pCb->writerActiveFlag = 1;
348     pCb->drainFlag = 0;
349     //pCb->afLagIdx = 0;
350     
351     // Write back circular buffer configuration
352     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
353     Cache_wait();
355     // Leave the gate
356     GateMP_leave(gateHandle, key);
358     return ASP_DECOP_CB_SOK;
359 };
361 // Stop writes to circular buffer
362 Int cbWriteStop(
363     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
364     Int8 cbIdx                          // decoder output circular buffer index
367     IArg key;
368     GateMP_Handle gateHandle;
369     PAF_AST_DecOpCircBuf *pCb;
371     // Get gate handle
372     gateHandle = pCbCtl->gateHandle;
373     // Enter gate
374     key = GateMP_enter(gateHandle);
376     // Get circular buffer base pointer
377     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
379     // Invalidate circular buffer configuration
380     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
381     Cache_wait();
383     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // debug
384     
385     // update flags
386     pCb->writerActiveFlag = 0;
387     pCb->drainFlag = 1;
389     // Write back circular buffer configuration
390     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
391     Cache_wait();
392     
393     // Leave the gate
394     GateMP_leave(gateHandle, key);
396     return ASP_DECOP_CB_SOK;
399 // debug
400 //Int16 gSampleCountBuf[10];
401 //Int16 gCalcDeltaSampsBuf[10];
402 //Int8 gPrimedFlagCnt=0;
404 // (***) FL: revisit
405 // Write audio frame to circular buffer
406 Int cbWriteAf(
407     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
408     Int8 cbIdx,                         // decoder output circular buffer index
409     PAF_AudioFrame *pAfWrt              // audio frame from which to write
412     IArg key;
413     GateMP_Handle gateHandle;
414     PAF_AST_DecOpCircBuf *pCb;
415     PAF_AudioFrame *pAfCb;
416     PAF_ChannelMask_HD streamMask;
417     Int8 i;
418     Int16 j;
419     PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf; 
421     // Get gate handle
422     gateHandle = pCbCtl->gateHandle;
423     // Enter gate
424     key = GateMP_enter(gateHandle);
426     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
428     // Get circular buffer base pointer
429     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
430     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
432     // Invalidate circular buffer configuration.
433     // NOTE: Probably only a subset of this information needs to be updated.
434     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
435     Cache_wait();
437     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
438     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
440     //if (pCb->readerActiveFlag == 1)
441     //{
442     //    //
443     //    // Normal case, reader active.
444     //    //
445         
446         if (pAfWrt->sampleCount != 0)
447         {
448             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
450             // check overflow
451             //while (pCb->numAfCb >= pCb->maxNumAfCb); // debug
452             if (pCb->numAfCb >= pCb->maxNumAfCb)
453             {
454                 pCb->errOvrCnt++;
456                 //SW_BREAKPOINT;
457                 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
459                 // Write back circular buffer configuration
460                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
461                 Cache_wait();
463                 // Leave the gate
464                 GateMP_leave(gateHandle, key);
466                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
468                 return ASP_DECOP_CB_WRITE_OVERFLOW;
469             }
471             pAfCb = &pCb->afCb[pCb->afWrtIdx];
472             pPcmBuf = pAfCb->data.sample[0];
473             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
474             if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
475             {
476                 pPcmBuf = pCb->pcmBuf;
477             }
479             for (i=0; i<pCb->maxAFChanNum; i++)
480             {
481                 pAfCb->data.sample[i] = pPcmBuf;
482                 pPcmBuf += pAfWrt->sampleCount;
483                 pAfCb->data.samsiz[i] = 0;
484             }
485             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
486             Cache_wait();
488             //for (i=0; i<pCb->maxAFChanNum; i++){
489             //}
490             for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
491             {
492                 pAfCb->pafPrivateMetadata[i].offset = 0;
493                 pAfCb->pafPrivateMetadata[i].size   = 0;
494                 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
495                 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
496             }
498             nextWrtIdx = 0;
499             if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
500             {
501                 //Log_info0("cbWriteAf: AF Wrap around **** ");
502                 // next audio frame will be audio frame 0
503                 nextWrtIdx = 0;
504             }
505             else
506             {
507                 // next audio frame will be current audio frame + 1
508                 nextWrtIdx = pCb->afWrtIdx + 1;
509             }
511             pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
512             pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
514             // write audio frame information updated by decoder
515             pAfCb->sampleDecode = pAfWrt->sampleDecode;
516             PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
517             pAfCb->sampleRate = pAfWrt->sampleRate;
518             pAfCb->sampleCount = pAfWrt->sampleCount;
519             pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
520             pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
521             // write metadata information updated by decoder
522             pAfCb->bsMetadata_type     = pAfWrt->bsMetadata_type;        /* non zero if metadata is attached. */
523             pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
524             pAfCb->numPrivateMetadata  = pAfWrt->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
525             pAfCb->bsMetadata_offset   = pAfWrt->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
526             // write PCM samples
527             streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
528             for (i = 0; i < pCb->maxAFChanNum; i++)
529             {
530                 if ((streamMask >> i) & 0x1)
531                 {
532                     for (j = 0; j < pAfWrt->sampleCount; j++)
533                     {
534                         pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
535                     }
537                     pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
538                 }
539             }
541             #ifdef CB_RW_OP_CAP_PP // debug
542             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
543             {
544                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
545                 {
546                     // log sample count
547                     pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
548                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
549                     // log idxs
550                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
551                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
552                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
553                     pCb->cb_opCnt++;
554                 }
555             }
556             #endif
558             // prepare metadata buffer pointers according to the metadata and buffer sizes
559             for (i=0; i < pAfWrt->numPrivateMetadata; i++)
560             {
561                 UInt8 *nextMdBuf;
562                 if(i == 0)
563                     nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
564                 else
565                     nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
566                 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
567                 {
568                     pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
569                 }
570                 else if(i != 0)
571                 {
572                     pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
573                 }
574                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
575             }
577             // Write metadata to circular buffer
578             for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
579             {
580                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
581                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
582                 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
583             }
585             Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
586             Cache_wait();
587             for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
588             {
589                 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
590                 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
591             }
592             // update audio frame write index
593             pCb->afWrtIdx++;
594             if (pCb->afWrtIdx >= pCb->maxNumAfCb)
595             {
596                 pCb->afWrtIdx = 0;
597             }
599             pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
600             if(pAfWrt->numPrivateMetadata > 0)
601             {
602                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
603             }
604             else
605             {
606                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
607                 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
608                 Cache_wait();
609             }
610             Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
611             Cache_wait();
612             // update number of audio frames in circular buffer
613             pCb->numAfCb++;
614             
615             // Update CB Lag index 
616             //if (pCb->afLagIdx < pCb->afInitialLag)
617             //{
618             //    pCb->afLagIdx += 1;
619             //}
620             
621             // Update CB primed flag
622             // calculate number of delta samples before 
623             if (pCb->primedFlag == 0)
624             {
625                 pCb->primedFlag = 1;
626                 
627                 // Calculate number of output frames to block reader.
628                 // This is sample count reader waits before allowed to actually read samples from the CB.
629                 pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
630                 
631                 // debug
632                 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
633                 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
634                 //if (gPrimedFlagCnt < 10)
635                 //    gPrimedFlagCnt++;
636             }
638             // Write back circular buffer configuration
639             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
640             // write back audio frame
641             Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
642             Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
643             Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
644             Cache_wait();
645             // write back PCM data
646             for (i = 0; i < pCb->maxAFChanNum; i++)
647             {
648                 if ((streamMask >> i) & 0x1)
649                 {
650                     Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
651                 }
652             }
653             Cache_wait();
655             {
656                 static Uint8 toggleState = 0;
657                if (toggleState == 0)
658                    GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
659                else
660                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
661                toggleState = ~(toggleState);
662             }
663             Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
664             Log_info4("CBWMETA num=%d  size=%d  offset=%d chrequest=0x%04x", pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[0].size, pAfCb->pafPrivateMetadata[0].offset, pAfCb->channelConfigurationRequest.full);
665         }
666         else
667         {
668             //
669             // Skip write in case of 0 sample count
670             //
671             
672             // writing audio frame w/ zero samples
673             // update stat
674             pCb->wrtAfZeroSampsCnt++;
676             // Write back circular buffer configuration
677             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
678             Cache_wait();
679         }
680     //}
681     //else if (pCb->readerActiveFlag == 0)
682     if (pCb->readerActiveFlag == 0)
683     {
684         //
685         // Reader inactive, don't write to circular buffer or check OVRflow.
686         //
687         
688         // writing AF w/ inactive reader
689         // update stat
690         pCb->wrtAfReaderInactiveCnt++;
692         // Write back circular buffer configuration
693         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
694         Cache_wait();
695     }
697     // Leave the gate
698     GateMP_leave(gateHandle, key);
700     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
702     return ASP_DECOP_CB_SOK;
705 #if 0
706 // Get next audio frame to write in circular buffer
707 Int cbGetNextWriteAf(
708     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
709     Int8 cbIdx,                         // decoder output circular buffer index
710     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
713     IArg key;
714     GateMP_Handle gateHandle;
715     PAF_AST_DecOpCircBuf *pCb;
717     // Get gate handle
718     gateHandle = pCbCtl->gateHandle;
719     // Enter gate
720     key = GateMP_enter(gateHandle);
722     // Get circular buffer base pointer
723     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
725     // get pointer to current audio frame in circular buffer
726     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
727     
728     // update audio frame write index
729     pCb->afWrtIdx++;
730     if (pCb->afWrtIdx > pCb->maxNumAfCb)
731     {
732         pCb->afWrtIdx = 0;
733     }    
734     
735     // Leave the gate
736     GateMP_leave(gateHandle, key);
738     return ASP_DECOP_CB_SOK;
740 #endif