]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_arm/framework/aspDecOpCircBuf_slave.c
a5025e0e5005e32d7b130ad19292c72957375925
[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 // Init last audio frame configuration info 
51 static Void cbInitLastAfInfo(
52     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
53     PAF_AudioFrame *pAfInit     // audio frame used for init
54 );
57 #if 0 // FL: moved to common
58 // Initialize circular buffer control
59 Int cbCtlInit(
60     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
61     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
62 )
63 {
64     GateMP_Handle gateHandle;
65     Int status;
66     
67     do {
68         status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
69     } while (status == GateMP_E_NOTFOUND);
70     if (status == GateMP_S_SUCCESS)
71     {
72         pCbCtl->gateHandle = gateHandle;
73     }
74     else
75     {
76         pCbCtl->gateHandle = NULL;
77         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
78     }
79     
80     pCbCtl->numCb = numCb;          // init number of circular buffers
81     pCbCtl->pXDecOpCb = pXDecOpCb;  // init base address of circular buffers
82     
83     return ASP_DECOP_CB_SOK;
84 }
85 #endif
87 // debug
88 //Int8 gCbInitDecWriteCnt=0;
89 //Int8 gCbInitDecWriteThdCnt=0;
91 /// Initialize circular buffer for Decoder writes
92 Int cbInitDecWrite(
93     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
94     Int8 cbIdx,                         // decoder output circular buffer index
95     Int8 sourceSelect,                  // source select (PCM, DDP, etc.)
96     Int16 decOpFrameLen,                // decoder output frame length (PCM samples)
97     Int8 resetRwFlags,                  // whether to reset reader, writer, and drain flags
98     PAF_AudioFrame *pDecInitAf          // pointer to Dec output audio frame used for CB initialization
99 )
101     IArg key;
102     GateMP_Handle gateHandle;
103     PAF_AST_DecOpCircBuf *pCb;
104     PAF_AudioFrame *pAfCb;
105     PAF_AudioData *pPcmBuf;
106     UInt8 *pMetaBuf;
107     Int8 n;
108     Int8 i;
110     //gCbInitDecWriteCnt++; // debug
111     
112     // Get gate handle
113     gateHandle = pCbCtl->gateHandle;
114     // Enter gate
115     key = GateMP_enter(gateHandle);
117     // Get circular buffer base pointer
118     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
119     
120     // Invalidate circular buffer configuration
121     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
122     Cache_wait();
124     //Log_info1("cbInitDecWrite:afCb=0x%04x", (IArg)pCb->afCb); // debug
126     // Set source select
127     pCb->sourceSel = sourceSelect;
129     // Set input frame length
130     pCb->decOpFrameLen = decOpFrameLen;
131     
132     //pCb->afInitialLag = 0;  // default No lag
133     //pCb->afLagIdx = 0;
134     // Initialize CB primed flag
135     pCb->primedFlag = 0;
136     // Initialize delta samples
137     pCb->deltaSamps = 0;
138     
139     // Initialize circular buffer:
140     //  - maximum number of AFs
141     //  - target nominal delay
142     //  - AF write, read indices
143     //  - maximum AF channel and sample counts
144     //  - maximum number of PCM samples per channel
145     if (sourceSelect == PAF_SOURCE_PCM)
146     {
147         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
148         
149         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
150         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
151         
152         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
153         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
154         
155         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
156         pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN; 
158         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
159     }
160     else if (sourceSelect == PAF_SOURCE_AAC)
161     {
162         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_AAC;
164         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
165         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_AAC;
167         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_AAC;
168         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_AAC;
170         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_AAC;
171         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kAAC;
173         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
174     }
175     else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
176     {
177         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
178         
179         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
180         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
181         
182         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
183         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
184         
185         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
186         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
188         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
189     }
190     else if (sourceSelect == PAF_SOURCE_THD)
191     {
192         //gCbInitSourceSelThdCnt++; //debug
193         
194         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
195         
196         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
197         // FL: (***) set nominal delay per sampling rate -- need to review these settings
198         switch (pDecInitAf->sampleRate)
199         {
200             case PAF_SAMPLERATE_44100HZ:
201             case PAF_SAMPLERATE_48000HZ:
202                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
203                 break;
204             case PAF_SAMPLERATE_88200HZ:
205             case PAF_SAMPLERATE_96000HZ:
206                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
207                 break;
208             case PAF_SAMPLERATE_176400HZ:
209             case PAF_SAMPLERATE_192000HZ:
210                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
211                 break;
212             default:
213                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
214                 break;
215         }
216         
217         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
218         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
219         
220         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
221         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;        
223         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
224     }
225         else if ((sourceSelect == PAF_SOURCE_DTS)   ||
226                  (sourceSelect == PAF_SOURCE_DTSHD) ||
227                  (sourceSelect == PAF_SOURCE_DTS12) ||
228                  (sourceSelect == PAF_SOURCE_DTS13) ||
229                  (sourceSelect == PAF_SOURCE_DTS14) ||
230                  (sourceSelect == PAF_SOURCE_DTS16) ||
231                  (sourceSelect == PAF_SOURCE_DTSALL)
232                 )
233     {
234         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DTS;
235         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DTS;
236         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DTS;
237         pCb->pcmRdIdx = 0;
238         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DTS;
239         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDTS;
241         // initialize audio frames
242         for (n=0; n<pCb->maxNumAfCb; n++)
243         {
244             pAfCb = &pCb->afCb[n];
245             pAfCb->sampleDecode = sourceSelect;
246             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
247             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
248             pAfCb->sampleCount = decOpFrameLen;
249             pAfCb->channelConfigurationRequest.full = 0;
250             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
251             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
252             pAfCb->channelConfigurationStream.full = 0;
253             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
254             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
256             // write metadata information updated by decoder
257             pAfCb->bsMetadata_type     = PAF_bsMetadata_DTS_X;          /* Audio data from DTSX decoder. */
258             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
259             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
260             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
261         }
262     }
263     else
264     {
265         //
266         // Currently unsupported source select
267         //
268         
269         SW_BREAKPOINT; // debug
270         
271         // Leave the gate
272         GateMP_leave(gateHandle, key);
274         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
275     }
277     // Initialize circular buffer:
278     //  - PCM read index
279     //  - Private metadata read index
280     //  - number of PCM samples in CB
281     pCb->pcmRdIdx = 0;
282     pCb->prvMdRdIdx = 0;
283     pCb->numPcmSampsPerCh = 0;
285     // Initialize audio frames
286     for (n = 0; n < pCb->maxNumAfCb; n++)
287     {
288         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
289         
290         // Dec init AF sample count not correct for CB AFs.
291         // Dec Op frame length is computed in framework based on selected source.
292         pAfCb->sampleCount = decOpFrameLen;
294         // initialize CB AF using Dec init AF
295         pAfCb->sampleDecode = pDecInitAf->sampleDecode;
296         PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
297         pAfCb->sampleRate = pDecInitAf->sampleRate;
298         pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
299         pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
300         
301         // initialize metadata information updated by decoder
302         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
303         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
304         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
305         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
306     }
307     
308     // Initialize circular buffer current number of frames
309     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
310     
311     // Initialize audio frame PCM buffers
312     pPcmBuf = pCb->pcmBuf;
313     pMetaBuf = pCb->metaBuf;
314     for (n=0; n<pCb->maxNumAfCb; n++)
315     {
316         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
317         
318         pAfCb->data.nChannels = pCb->maxAFChanNum;
319         pAfCb->data.nSamples = decOpFrameLen;
320         for (i=0; i<pCb->maxAFChanNum; i++)
321         {
322             pAfCb->data.sample[i] = pPcmBuf;
323             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
324             pPcmBuf += pCb->maxAFSampCount;
325             
326             pAfCb->data.samsiz[i] = 0;
327         }
328         
329         // Initialize metadata buffers
330         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
331         {
332             pAfCb->pafPrivateMetadata[i].offset = 0; 
333             pAfCb->pafPrivateMetadata[i].size   = 0; 
334             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
335             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
336         }
337     }
338     
339     // Initialize last audio frame configuration info
340     cbInitLastAfInfo(pCb, pDecInitAf);
341     
342     // Reset read/write flags
343     if (resetRwFlags != 0)
344     {
345         pCb->writerActiveFlag = 0;
346         pCb->readerActiveFlag = 0;
347         pCb->drainFlag = 0;
348     }
349     
350     // Reset stats
351     pCb->readAfWriterInactiveCnt = 0;
352     pCb->readAfNdCnt = 0;
353     pCb->wrtAfReaderInactiveCnt = 0;
354     pCb->wrtAfZeroSampsCnt = 0;
355     pCb->errAfUndCnt = 0;
356     pCb->errAfOvrCnt = 0;
357     pCb->errPcmUndCnt = 0;
358     pCb->errPcmOvrCnt = 0;
359     
360     // Write back circular buffer configuration
361     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
362     // Write back AF circular buffer
363     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
364     // Write back PCM data
365     for (n=0; n<pCb->maxNumAfCb; n++)
366     {
367         pAfCb = &pCb->afCb[n];
368         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
369         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
370         for (i=0; i<pCb->maxAFChanNum; i++)
371         {
372             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
373         }
374     }
375     Cache_wait();
377     // Leave the gate
378     GateMP_leave(gateHandle, key);
379     
380     return ASP_DECOP_CB_SOK;
383 //Int8 gCbWriteStartCnt=0; // debug
385 // Start writes to circular buffer
386 Int cbWriteStart(
387     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
388     Int8 cbIdx                          // decoder output circular buffer index
391     IArg key;
392     GateMP_Handle gateHandle;
393     PAF_AST_DecOpCircBuf *pCb;
394     PAF_AudioFrame *pAfCb;
395     Int8 n;
396     //Int8 i;
398     //gCbWriteStartCnt++; // debug
399     
400     // Get gate handle
401     gateHandle = pCbCtl->gateHandle;
402     // Enter gate
403     key = GateMP_enter(gateHandle);
405     // Get circular buffer base pointer
406     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
408     // Invalidate circular buffer configuration.
409     // NOTE: Probably only a subset of this information needs to be updated.
410     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
411     Cache_wait();
412     
413     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
414     
415     // Invalidate AF circular buffer
416     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
417     for (n=0; n<pCb->maxNumAfCb; n++)
418     {
419         pAfCb = &pCb->afCb[n];
420         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
421     }
422     Cache_wait();
423             
424     // update flags
425     pCb->writerActiveFlag = 1;
426     pCb->drainFlag = 0;
427     //pCb->afLagIdx = 0;
428     
429     // Write back circular buffer configuration
430     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
431     Cache_wait();
433     // Leave the gate
434     GateMP_leave(gateHandle, key);
436     return ASP_DECOP_CB_SOK;
437 };
439 // Stop writes to circular buffer
440 Int cbWriteStop(
441     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
442     Int8 cbIdx                          // decoder output circular buffer index
445     IArg key;
446     GateMP_Handle gateHandle;
447     PAF_AST_DecOpCircBuf *pCb;
449     // Get gate handle
450     gateHandle = pCbCtl->gateHandle;
451     // Enter gate
452     key = GateMP_enter(gateHandle);
454     // Get circular buffer base pointer
455     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
457     // Invalidate circular buffer configuration
458     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
459     Cache_wait();
461     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // debug
462     
463     // update flags
464     pCb->writerActiveFlag = 0;
465     pCb->drainFlag = 1;
467     // Write back circular buffer configuration
468     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
469     Cache_wait();
470     
471     // Leave the gate
472     GateMP_leave(gateHandle, key);
474     return ASP_DECOP_CB_SOK;
477 // debug
478 //Int16 gSampleCountBuf[10];
479 //Int16 gCalcDeltaSampsBuf[10];
480 //Int8 gPrimedFlagCnt=0;
482 Int32 gPcmOvershootWrap1=0;
483 Int32 gPcmOvershootWrap2=0;
484 Int32 gPcmOvershootNoWrap=0;
486 // (***) FL: revisit
487 // Write audio frame to circular buffer
488 Int cbWriteAf(
489     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
490     Int8 cbIdx,                         // decoder output circular buffer index
491     PAF_AudioFrame *pAfWrt              // audio frame from which to write
494     IArg key;
495     GateMP_Handle gateHandle;
496     PAF_AST_DecOpCircBuf *pCb;
497     PAF_AudioFrame *pAfCb;
498     PAF_ChannelMask_HD streamMask;
499     Int8 i;
500     Int16 j;
501     PAF_AudioData *pPcmBuf; 
502     UInt8 *pMetaBuf; 
503     //int nextWrtIdx;
504     //PAF_AudioFrame *pAfCbNextAf; 
505     PAF_AudioFrame *pAfCbRd;
506     PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
507     Int8 pcmOvr;
508     
509     // Get gate handle
510     gateHandle = pCbCtl->gateHandle;
511     // Enter gate
512     key = GateMP_enter(gateHandle);
514     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
516     // Get circular buffer base pointer
517     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
518     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
520     // Invalidate circular buffer configuration.
521     // NOTE: Probably only a subset of this information needs to be updated.
522     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
523     Cache_wait();
525     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
526     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
528     //if (pCb->readerActiveFlag == 1)
529     //{
530     //    //
531     //    // Normal case, reader active.
532     //    //
533         
534         if (pAfWrt->sampleCount != 0)
535         {
536             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
538             // check AF overflow
539             if (pCb->numAfCb >= pCb->maxNumAfCb)
540             {
541                 pCb->errAfOvrCnt++;
543                 //SW_BREAKPOINT;
544                 Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
546                 // Write back circular buffer configuration
547                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
548                 Cache_wait();
550                 // Leave the gate
551                 GateMP_leave(gateHandle, key);
553                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
555                 return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
556             }
557             
558             // FL: this won't reliably detect overflow because of PCM buffer write address wrap
559             // check PCM overflow
560             //if ((pCb->numPcmSampsPerCh + pAfWrt->sampleCount) > pCb->maxNumPcmSampsPerCh)
561             //{
562             //    pCb->errPcmOvrCnt++;
563             //
564             //    Log_info3("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d, maxNumPcmSampsPerCh=%d",
565             //        pCb->numPcmSampsPerCh, pAfWrt->sampleCount, pCb->maxNumPcmSampsPerCh);
566             //
567             //    // Write back circular buffer configuration
568             //    Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
569             //    Cache_wait();
570             //
571             //    // Leave the gate
572             //    GateMP_leave(gateHandle, key);
573             //
574             //    return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
575             //}
577             // get CB AF write info
578             pAfCb = &pCb->afCb[pCb->afWrtIdx];                      // get CB AF to be written
579             pPcmBufWrt = pAfCb->data.sample[0];                     // get current location in PCM buffer to be written
580             // (***) FL: currently no metadata buffer overflow detection
581             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;         // get current location in MD buffer to be written
582             
583             // get CB AF read info
584             pAfCbRd = &pCb->afCb[pCb->afRdIdx];                     // get CB AF being read
585             //pPcmBufRd = pAfCbRd->data.sample[0];                    // FL: starting location of PCM samples for AF being read
586             pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx;    // FL: current location of PCM samples for AF being read
587             
588             // Check PCM buffer overflow
589             pPcmBuf = pPcmBufWrt;
590             pcmOvr = 0;
591             for (i = 0; i < pCb->maxAFChanNum; i++)
592             {
593                 //
594                 // Writes of PCM to PCM CB use CC stream, but this isn't considered here.
595                 // For each channel which *can* be written, check the current reader location won't be overwritten.
596                 // The current reader location is the earliest channel which *could have been* written for that CB AF.
597                 //
598                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
599                 {
600                     // this write will wrap
601                     
602                     // check OVR before wrap
603                     if ((pPcmBuf < pPcmBufRd) && 
604                         ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
605                     {
606                         pCb->errPcmOvrCnt++;
607                         gPcmOvershootWrap1 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd;
608                         pcmOvr = 1;
609                     }
610                     
611                     if (pcmOvr == 0)
612                     {
613                         // wrap pointer
614                         pPcmBuf = pCb->pcmBuf;   
615                         // check OVR after wrap
616                         if ((pPcmBuf < pPcmBufRd) && 
617                             ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
618                         {
619                             pCb->errPcmOvrCnt++;
620                             gPcmOvershootWrap2 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd;
621                             pcmOvr = 1;
622                         }                                                                
623                     }
624                 }
625                 else if ((pPcmBuf < pPcmBufRd) && 
626                     ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
627                 {
628                     // this write won't wrap
629                     
630                     gPcmOvershootNoWrap = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd;
631                     pCb->errPcmOvrCnt++;
632                     pcmOvr = 1;
633                 }
634                 else
635                 {
636                     // update pointer
637                     pPcmBuf += pAfWrt->sampleCount;                                        
638                 }
639                 
640                 if (pcmOvr == 1)
641                 {
642                     Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d", 
643                          pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
644             
645                     //SW_BREAKPOINT; // debug
646                     
647                     // Write back circular buffer configuration
648                     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
649                     Cache_wait();
650             
651                     // Leave the gate
652                     GateMP_leave(gateHandle, key);
653             
654                     return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
655                 }
656             }
657             
658             // (***) FL: !!! REVISIT!!! 
659             //           Allocating memory for max # channels (e.g. 32 for THD).
660             //           GROSS over allocation for THD 192 kHz, 6ch max.
661             // configure AF sample pointers
662             pPcmBuf = pPcmBufWrt;
663             for (i = 0; i < pCb->maxAFChanNum; i++)
664             {
665                 // check PCM buffer wrap
666                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
667                 {
668                     pPcmBuf = pCb->pcmBuf;
669                 }
670                 
671                 pAfCb->data.sample[i] = pPcmBuf;                
672                 pPcmBuf += pAfWrt->sampleCount;
673                 pAfCb->data.samsiz[i] = 0;
674             }
675             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
676             Cache_wait();
678             // FL: brute force reset of all metadata in CB AF?
679             for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
680             {
681                 pAfCb->pafPrivateMetadata[i].offset = 0;
682                 pAfCb->pafPrivateMetadata[i].size   = 0;
683                 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
684                 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
685             }
687 #if 0 // FL: unused
688             nextWrtIdx = 0;
689             if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
690             {
691                 //Log_info0("cbWriteAf: AF Wrap around **** ");
692                 // next audio frame will be audio frame 0
693                 nextWrtIdx = 0;
694             }
695             else
696             {
697                 // next audio frame will be current audio frame + 1
698                 nextWrtIdx = pCb->afWrtIdx + 1;
699             }
700             
701             pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
702             pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount]; // pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
703 #endif
704             
705             // write audio frame information updated by decoder
706             pAfCb->sampleDecode = pAfWrt->sampleDecode;
707             PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
708             pAfCb->sampleRate = pAfWrt->sampleRate;
709             pAfCb->sampleCount = pAfWrt->sampleCount;
710             pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
711             pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
712             // write metadata information updated by decoder
713             pAfCb->bsMetadata_type     = pAfWrt->bsMetadata_type;        /* non zero if metadata is attached. */
714             pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
715             pAfCb->numPrivateMetadata  = pAfWrt->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
716             pAfCb->bsMetadata_offset   = pAfWrt->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
717             
718 #ifdef DTS_BUILD
719         pAfCb->mode = pAfWrt->mode;                                       /* mode is used in DTSX to pass info to PARMA */
720         pAfCb->numChansUsedForMetadata = pAfWrt->numChansUsedForMetadata; /* if metadata is used in DTSX*/
721         pAfCb->pafBsFixedData = pAfWrt->pafBsFixedData;                   /* if true, do not convert float to fixed in DTSX metadata transfer */
722         pAfCb->root = pAfWrt->root;                                       /* used for channel MASK in DTSX . BAD IDEA, need fix */
723         pAfCb->resetCount = pAfWrt->resetCount;                           /* used for communication between DTSX and PARMA */
724 #endif          
725             // write PCM samples
726             streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
727             for (i = 0; i < pCb->maxAFChanNum; i++)
728             {
729 #ifndef DTS_BUILD
730             if ((streamMask >> i) & 0x1)
731 #endif
732             { //DTSX needs up to 16 channels to transfer metadata.
733                     for (j = 0; j < pAfWrt->sampleCount; j++)
734                     {
735                         pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
736                     }
738                     pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
739                 }
740             }
741             
742             // Update PCM samples per channel
743             pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
744             
745             #ifdef CB_RW_OP_CAP_PP // debug
746             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
747             {
748                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
749                 {
750                     // log sample count
751                     pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
752                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
753                     // log idxs
754                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
755                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
756                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
757                     pCb->cb_opCnt++;
758                 }
759             }
760             #endif
762             // prepare metadata buffer pointers according to the metadata and buffer sizes
763             for (i = 0; i < pAfWrt->numPrivateMetadata; i++)
764             {
765                 UInt8 *nextMdBuf;
766                 if (i == 0)
767                 {
768                     nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);                    
769                 }
770                 else
771                 {
772                     nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);                    
773                 }
774                 if (nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
775                 {
776                     pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
777                 }
778                 else if (i != 0)
779                 {
780                     pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
781                 }
782                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
783             }
785             // Write metadata to circular buffer
786             for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
787             {
788                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
789                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
790                 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
791             }
793             Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
794             Cache_wait();
795             for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
796             {
797                 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
798                 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
799             }
800             // update audio frame write index
801             pCb->afWrtIdx++;
802             if (pCb->afWrtIdx >= pCb->maxNumAfCb)
803             {
804                 pCb->afWrtIdx = 0;
805             }
807             pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
808             if (pAfWrt->numPrivateMetadata > 0)
809             {
810                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
811             }
812             else
813             {
814                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
815                 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
816                 Cache_wait();
817             }
818             Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
819             Cache_wait();
820             // update number of audio frames in circular buffer
821             pCb->numAfCb++;
822             
823             // Update CB Lag index 
824             //if (pCb->afLagIdx < pCb->afInitialLag)
825             //{
826             //    pCb->afLagIdx += 1;
827             //}
828             
829             // Update CB primed flag.
830             // Calculate number of delta samples before allowing CB read.
831             if (pCb->primedFlag == 0)
832             {
833                 pCb->primedFlag = 1;
834                 
835                 // THD has variable number of AUs per frame. 
836                 // Some frames can be quite large (e.g. 96 AUs), and delta samples calculation small or even negative.
837                 // In this case, there won't be any reader hold off, and no nominal delay in the CB.
838                 pCb->deltaSamps = pCb->targetNDSamps;
839                 
840                 // debug
841                 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
842                 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
843                 //if (gPrimedFlagCnt < 10)
844                 //    gPrimedFlagCnt++;
845             }
847             // Update delta samples using number of write audio frame samples.
848             if (pCb->deltaSamps > 0)
849             {
850                 pCb->deltaSamps = pCb->deltaSamps - pAfWrt->sampleCount;
851             }
852             
853             // Write back circular buffer configuration
854             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
855             // write back audio frame
856             Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
857             Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
858             Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
859             Cache_wait();
860             // write back PCM data
861             for (i = 0; i < pCb->maxAFChanNum; i++)
862             {
863 #ifndef DTS_BUILD
864             if ((streamMask >> i) & 0x1)
865 #endif
866             {//DTSX needs up to 16 channels to transfer metadata.
867                     Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
868                 }
869             }
870             Cache_wait();
872 #if 0 // also for CB_RW_OP_CAP_PP (***) FL: shows timing of CB write
873             // debug
874             {
875                 static Uint8 toggleState = 0;
876                if (toggleState == 0)
877                    GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
878                else
879                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
880                toggleState = ~(toggleState);
881             }
882 #endif
884             Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
885             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);
886         }
887         else
888         {
889             //
890             // Skip write in case of 0 sample count
891             //
892             
893             // writing audio frame w/ zero samples
894             // update stat
895             pCb->wrtAfZeroSampsCnt++;
897             // Write back circular buffer configuration
898             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
899             Cache_wait();
900         }
901     //}
902     //else if (pCb->readerActiveFlag == 0)
903     if (pCb->readerActiveFlag == 0)
904     {
905         //
906         // Reader inactive, don't write to circular buffer or check OVRflow.
907         //
908         
909         // writing AF w/ inactive reader
910         // update stat
911         pCb->wrtAfReaderInactiveCnt++;
913         // Write back circular buffer configuration
914         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
915         Cache_wait();
916     }
918     // Leave the gate
919     GateMP_leave(gateHandle, key);
921     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
923     return ASP_DECOP_CB_SOK;
926 #if 0
927 // Get next audio frame to write in circular buffer
928 Int cbGetNextWriteAf(
929     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
930     Int8 cbIdx,                         // decoder output circular buffer index
931     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
934     IArg key;
935     GateMP_Handle gateHandle;
936     PAF_AST_DecOpCircBuf *pCb;
938     // Get gate handle
939     gateHandle = pCbCtl->gateHandle;
940     // Enter gate
941     key = GateMP_enter(gateHandle);
943     // Get circular buffer base pointer
944     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
946     // get pointer to current audio frame in circular buffer
947     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
948     
949     // update audio frame write index
950     pCb->afWrtIdx++;
951     if (pCb->afWrtIdx > pCb->maxNumAfCb)
952     {
953         pCb->afWrtIdx = 0;
954     }    
955     
956     // Leave the gate
957     GateMP_leave(gateHandle, key);
959     return ASP_DECOP_CB_SOK;
961 #endif
963 // Init last audio frame configuration info 
964 static Void cbInitLastAfInfo(
965     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
966     PAF_AudioFrame *pAfInit     // audio frame used for init
969     memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
970     
971     pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
972     pCb->lastAf.sampleRate = pAfInit->sampleRate;
973     pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
974     pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;