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