06360effd3eeccc2399351bca617fa4a8ffd7e38
[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_DDP) || (sourceSelect == PAF_SOURCE_AC3))
161     {
162         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
163         
164         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
165         pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
166         
167         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
168         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
169         
170         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
171         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
173         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
174     }
175     else if (sourceSelect == PAF_SOURCE_THD)
176     {
177         //gCbInitSourceSelThdCnt++; //debug
178         
179         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
180         
181         //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
182         // FL: (***) set nominal delay per sampling rate -- need to review these settings
183         switch (pDecInitAf->sampleRate)
184         {
185             case PAF_SAMPLERATE_44100HZ:
186             case PAF_SAMPLERATE_48000HZ:
187                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
188                 break;
189             case PAF_SAMPLERATE_88200HZ:
190             case PAF_SAMPLERATE_96000HZ:
191                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
192                 break;
193             case PAF_SAMPLERATE_176400HZ:
194             case PAF_SAMPLERATE_192000HZ:
195                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
196                 break;
197             default:
198                 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
199                 break;
200         }
201         
202         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
203         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
204         
205         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
206         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;        
208         pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
209     }
210         else if ((sourceSelect == PAF_SOURCE_DTS)   ||
211                  (sourceSelect == PAF_SOURCE_DTSHD) ||
212                  (sourceSelect == PAF_SOURCE_DTS12) ||
213                  (sourceSelect == PAF_SOURCE_DTS13) ||
214                  (sourceSelect == PAF_SOURCE_DTS14) ||
215                  (sourceSelect == PAF_SOURCE_DTS16) ||
216                  (sourceSelect == PAF_SOURCE_DTSALL)
217                 )
218     {
219         pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DTS;
220         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DTS;
221         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DTS;
222         pCb->pcmRdIdx = 0;
223         pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DTS;
224         pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDTS;
226         // initialize audio frames
227         for (n=0; n<pCb->maxNumAfCb; n++)
228         {
229             pAfCb = &pCb->afCb[n];
230             pAfCb->sampleDecode = sourceSelect;
231             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
232             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
233             pAfCb->sampleCount = decOpFrameLen;
234             pAfCb->channelConfigurationRequest.full = 0;
235             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
236             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
237             pAfCb->channelConfigurationStream.full = 0;
238             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
239             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
241             // write metadata information updated by decoder
242             pAfCb->bsMetadata_type     = PAF_bsMetadata_DTS_X;          /* Audio data from DTSX decoder. */
243             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
244             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
245             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
246         }
247     }
248     else
249     {
250         //
251         // Currently unsupported source select
252         //
253         
254         SW_BREAKPOINT; // debug
255         
256         // Leave the gate
257         GateMP_leave(gateHandle, key);
259         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
260     }
262     // Initialize circular buffer:
263     //  - PCM read index
264     //  - Private metadata read index
265     //  - number of PCM samples in CB
266     pCb->pcmRdIdx = 0;
267     pCb->prvMdRdIdx = 0;
268     pCb->numPcmSampsPerCh = 0;
270     // Initialize audio frames
271     for (n = 0; n < pCb->maxNumAfCb; n++)
272     {
273         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
274         
275         // Dec init AF sample count not correct for CB AFs.
276         // Dec Op frame length is computed in framework based on selected source.
277         pAfCb->sampleCount = decOpFrameLen;
279         // initialize CB AF using Dec init AF
280         pAfCb->sampleDecode = pDecInitAf->sampleDecode;
281         PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
282         pAfCb->sampleRate = pDecInitAf->sampleRate;
283         pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
284         pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
285         
286         // initialize metadata information updated by decoder
287         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
288         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
289         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
290         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
291     }
292     
293     // Initialize circular buffer current number of frames
294     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
295     
296     // Initialize audio frame PCM buffers
297     pPcmBuf = pCb->pcmBuf;
298     pMetaBuf = pCb->metaBuf;
299     for (n=0; n<pCb->maxNumAfCb; n++)
300     {
301         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
302         
303         pAfCb->data.nChannels = pCb->maxAFChanNum;
304         pAfCb->data.nSamples = decOpFrameLen;
305         for (i=0; i<pCb->maxAFChanNum; i++)
306         {
307             pAfCb->data.sample[i] = pPcmBuf;
308             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
309             pPcmBuf += pCb->maxAFSampCount;
310             
311             pAfCb->data.samsiz[i] = 0;
312         }
313         
314         // Initialize metadata buffers
315         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
316         {
317             pAfCb->pafPrivateMetadata[i].offset = 0; 
318             pAfCb->pafPrivateMetadata[i].size   = 0; 
319             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
320             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
321         }
322     }
323     
324     // Initialize last audio frame configuration info
325     cbInitLastAfInfo(pCb, pDecInitAf);
326     
327     // Reset read/write flags
328     if (resetRwFlags != 0)
329     {
330         pCb->writerActiveFlag = 0;
331         pCb->readerActiveFlag = 0;
332         pCb->drainFlag = 0;
333     }
334     
335     // Reset stats
336     pCb->readAfWriterInactiveCnt = 0;
337     pCb->readAfNdCnt = 0;
338     pCb->wrtAfReaderInactiveCnt = 0;
339     pCb->wrtAfZeroSampsCnt = 0;
340     pCb->errAfUndCnt = 0;
341     pCb->errAfOvrCnt = 0;
342     pCb->errPcmUndCnt = 0;
343     pCb->errPcmOvrCnt = 0;
344     
345     // Write back circular buffer configuration
346     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
347     // Write back AF circular buffer
348     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
349     // Write back PCM data
350     for (n=0; n<pCb->maxNumAfCb; n++)
351     {
352         pAfCb = &pCb->afCb[n];
353         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
354         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
355         for (i=0; i<pCb->maxAFChanNum; i++)
356         {
357             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
358         }
359     }
360     Cache_wait();
362     // Leave the gate
363     GateMP_leave(gateHandle, key);
364     
365     return ASP_DECOP_CB_SOK;
368 //Int8 gCbWriteStartCnt=0; // debug
370 // Start writes to circular buffer
371 Int cbWriteStart(
372     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
373     Int8 cbIdx                          // decoder output circular buffer index
376     IArg key;
377     GateMP_Handle gateHandle;
378     PAF_AST_DecOpCircBuf *pCb;
379     PAF_AudioFrame *pAfCb;
380     Int8 n;
381     //Int8 i;
383     //gCbWriteStartCnt++; // debug
384     
385     // Get gate handle
386     gateHandle = pCbCtl->gateHandle;
387     // Enter gate
388     key = GateMP_enter(gateHandle);
390     // Get circular buffer base pointer
391     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
393     // Invalidate circular buffer configuration.
394     // NOTE: Probably only a subset of this information needs to be updated.
395     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
396     Cache_wait();
397     
398     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
399     
400     // Invalidate AF circular buffer
401     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
402     for (n=0; n<pCb->maxNumAfCb; n++)
403     {
404         pAfCb = &pCb->afCb[n];
405         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
406     }
407     Cache_wait();
408             
409     // update flags
410     pCb->writerActiveFlag = 1;
411     pCb->drainFlag = 0;
412     //pCb->afLagIdx = 0;
413     
414     // Write back circular buffer configuration
415     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
416     Cache_wait();
418     // Leave the gate
419     GateMP_leave(gateHandle, key);
421     return ASP_DECOP_CB_SOK;
422 };
424 // Stop writes to circular buffer
425 Int cbWriteStop(
426     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
427     Int8 cbIdx                          // decoder output circular buffer index
430     IArg key;
431     GateMP_Handle gateHandle;
432     PAF_AST_DecOpCircBuf *pCb;
434     // Get gate handle
435     gateHandle = pCbCtl->gateHandle;
436     // Enter gate
437     key = GateMP_enter(gateHandle);
439     // Get circular buffer base pointer
440     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
442     // Invalidate circular buffer configuration
443     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
444     Cache_wait();
446     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // debug
447     
448     // update flags
449     pCb->writerActiveFlag = 0;
450     pCb->drainFlag = 1;
452     // Write back circular buffer configuration
453     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
454     Cache_wait();
455     
456     // Leave the gate
457     GateMP_leave(gateHandle, key);
459     return ASP_DECOP_CB_SOK;
462 // debug
463 //Int16 gSampleCountBuf[10];
464 //Int16 gCalcDeltaSampsBuf[10];
465 //Int8 gPrimedFlagCnt=0;
467 // (***) FL: revisit
468 // Write audio frame to circular buffer
469 Int cbWriteAf(
470     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
471     Int8 cbIdx,                         // decoder output circular buffer index
472     PAF_AudioFrame *pAfWrt              // audio frame from which to write
475     IArg key;
476     GateMP_Handle gateHandle;
477     PAF_AST_DecOpCircBuf *pCb;
478     PAF_AudioFrame *pAfCb;
479     PAF_ChannelMask_HD streamMask;
480     Int8 i;
481     Int16 j;
482     PAF_AudioData *pPcmBuf; 
483     UInt8 *pMetaBuf; 
484     //int nextWrtIdx;
485     //PAF_AudioFrame *pAfCbNextAf; 
486     PAF_AudioFrame *pAfCbRd;
487     PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
488     Int8 pcmOvr;
489     
490     // Get gate handle
491     gateHandle = pCbCtl->gateHandle;
492     // Enter gate
493     key = GateMP_enter(gateHandle);
495     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
497     // Get circular buffer base pointer
498     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
499     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
501     // Invalidate circular buffer configuration.
502     // NOTE: Probably only a subset of this information needs to be updated.
503     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
504     Cache_wait();
506     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
507     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
509     //if (pCb->readerActiveFlag == 1)
510     //{
511     //    //
512     //    // Normal case, reader active.
513     //    //
514         
515         if (pAfWrt->sampleCount != 0)
516         {
517             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
519             // check AF overflow
520             if (pCb->numAfCb >= pCb->maxNumAfCb)
521             {
522                 pCb->errAfOvrCnt++;
524                 //SW_BREAKPOINT;
525                 Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
527                 // Write back circular buffer configuration
528                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
529                 Cache_wait();
531                 // Leave the gate
532                 GateMP_leave(gateHandle, key);
534                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
536                 return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
537             }
538             
539             // FL: this won't reliably detect overflow because of PCM buffer write address wrap
540             // check PCM overflow
541             //if ((pCb->numPcmSampsPerCh + pAfWrt->sampleCount) > pCb->maxNumPcmSampsPerCh)
542             //{
543             //    pCb->errPcmOvrCnt++;
544             //
545             //    Log_info3("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d, maxNumPcmSampsPerCh=%d",
546             //        pCb->numPcmSampsPerCh, pAfWrt->sampleCount, pCb->maxNumPcmSampsPerCh);
547             //
548             //    // Write back circular buffer configuration
549             //    Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
550             //    Cache_wait();
551             //
552             //    // Leave the gate
553             //    GateMP_leave(gateHandle, key);
554             //
555             //    return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
556             //}
558             // get CB AF write info
559             pAfCb = &pCb->afCb[pCb->afWrtIdx];                      // get CB AF to be written
560             pPcmBufWrt = pAfCb->data.sample[0];                     // get current location in PCM buffer to be written
561             // (***) FL: currently no metadata buffer overflow detection
562             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;         // get current location in MD buffer to be written
563             
564             // get CB AF read info
565             pAfCbRd = &pCb->afCb[pCb->afRdIdx];                     // get CB AF being read
566             //pPcmBufRd = pAfCbRd->data.sample[0];                    // FL: starting location of PCM samples for AF being read
567             pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx;    // FL: current location of PCM samples for AF being read
568             
569             // Check PCM buffer overflow
570             pPcmBuf = pPcmBufWrt;
571             pcmOvr = 0;
572             for (i = 0; i < pCb->maxAFChanNum; i++)
573             {
574                 //
575                 // Writes of PCM to PCM CB use CC stream, but this isn't considered here.
576                 // For each channel which *can* be written, check the current reader location won't be overwritten.
577                 // The current reader location is the earliest channel which *could have been* written for that CB AF.
578                 //
579                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
580                 {
581                     // this write will wrap
582                     
583                     // check OVR before wrap
584                     if ((pPcmBuf < pPcmBufRd) && 
585                         ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
586                     {
587                         pCb->errPcmOvrCnt++;
588                         pcmOvr = 1;
589                     }
590                     
591                     if (pcmOvr == 0)
592                     {
593                         // wrap pointer
594                         pPcmBuf = pCb->pcmBuf;   
595                         // check OVR after wrap
596                         if ((pPcmBuf < pPcmBufRd) && 
597                             ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
598                         {
599                             pCb->errPcmOvrCnt++;
600                             pcmOvr = 1;
601                         }                                                                
602                     }
603                 }
604                 else if ((pPcmBuf < pPcmBufRd) && 
605                     ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
606                 {
607                     // this write won't wrap
608                     
609                     pCb->errPcmOvrCnt++;
610                     pcmOvr = 1;
611                 }
612                 else
613                 {
614                     // update pointer
615                     pPcmBuf += pAfWrt->sampleCount;                                        
616                 }
617                 
618                 if (pcmOvr == 1)
619                 {
620                     Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d", 
621                          pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
622             
623                     //SW_BREAKPOINT; // debug
624                     
625                     // Write back circular buffer configuration
626                     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
627                     Cache_wait();
628             
629                     // Leave the gate
630                     GateMP_leave(gateHandle, key);
631             
632                     return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
633                 }
634             }
635             
636             // (***) FL: !!! REVISIT!!! 
637             //           Allocating memory for max # channels (e.g. 32 for THD).
638             //           GROSS over allocation for THD 192 kHz, 6ch max.
639             // configure AF sample pointers
640             pPcmBuf = pPcmBufWrt;
641             for (i = 0; i < pCb->maxAFChanNum; i++)
642             {
643                 // check PCM buffer wrap
644                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
645                 {
646                     pPcmBuf = pCb->pcmBuf;
647                 }
648                 
649                 pAfCb->data.sample[i] = pPcmBuf;                
650                 pPcmBuf += pAfWrt->sampleCount;
651                 pAfCb->data.samsiz[i] = 0;
652             }
653             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
654             Cache_wait();
656             // FL: brute force reset of all metadata in CB AF?
657             for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
658             {
659                 pAfCb->pafPrivateMetadata[i].offset = 0;
660                 pAfCb->pafPrivateMetadata[i].size   = 0;
661                 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
662                 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
663             }
665 #if 0 // FL: unused
666             nextWrtIdx = 0;
667             if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
668             {
669                 //Log_info0("cbWriteAf: AF Wrap around **** ");
670                 // next audio frame will be audio frame 0
671                 nextWrtIdx = 0;
672             }
673             else
674             {
675                 // next audio frame will be current audio frame + 1
676                 nextWrtIdx = pCb->afWrtIdx + 1;
677             }
678             
679             pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
680             pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount]; // pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
681 #endif
682             
683             // write audio frame information updated by decoder
684             pAfCb->sampleDecode = pAfWrt->sampleDecode;
685             PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
686             pAfCb->sampleRate = pAfWrt->sampleRate;
687             pAfCb->sampleCount = pAfWrt->sampleCount;
688             pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
689             pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
690             // write metadata information updated by decoder
691             pAfCb->bsMetadata_type     = pAfWrt->bsMetadata_type;        /* non zero if metadata is attached. */
692             pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
693             pAfCb->numPrivateMetadata  = pAfWrt->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
694             pAfCb->bsMetadata_offset   = pAfWrt->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
695             
696 #ifdef DTS_BUILD
697         pAfCb->mode = pAfWrt->mode;                                       /* mode is used in DTSX to pass info to PARMA */
698         pAfCb->numChansUsedForMetadata = pAfWrt->numChansUsedForMetadata; /* if metadata is used in DTSX*/
699         pAfCb->pafBsFixedData = pAfWrt->pafBsFixedData;                   /* if true, do not convert float to fixed in DTSX metadata transfer */
700         pAfCb->root = pAfWrt->root;                                       /* used for channel MASK in DTSX . BAD IDEA, need fix */
701         pAfCb->resetCount = pAfWrt->resetCount;                           /* used for communication between DTSX and PARMA */
702 #endif          
703             // write PCM samples
704             streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
705             for (i = 0; i < pCb->maxAFChanNum; i++)
706             {
707 #ifndef DTS_BUILD
708             if ((streamMask >> i) & 0x1)
709 #endif
710             { //DTSX needs up to 16 channels to transfer metadata.
711                     for (j = 0; j < pAfWrt->sampleCount; j++)
712                     {
713                         pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
714                     }
716                     pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
717                 }
718             }
719             
720             // Update PCM samples per channel
721             pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
722             
723             #ifdef CB_RW_OP_CAP_PP // debug
724             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
725             {
726                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
727                 {
728                     // log sample count
729                     pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
730                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
731                     // log idxs
732                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
733                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
734                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
735                     pCb->cb_opCnt++;
736                 }
737             }
738             #endif
740             // prepare metadata buffer pointers according to the metadata and buffer sizes
741             for (i = 0; i < pAfWrt->numPrivateMetadata; i++)
742             {
743                 UInt8 *nextMdBuf;
744                 if (i == 0)
745                 {
746                     nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);                    
747                 }
748                 else
749                 {
750                     nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);                    
751                 }
752                 if (nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
753                 {
754                     pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
755                 }
756                 else if (i != 0)
757                 {
758                     pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
759                 }
760                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
761             }
763             // Write metadata to circular buffer
764             for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
765             {
766                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
767                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
768                 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
769             }
771             Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
772             Cache_wait();
773             for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
774             {
775                 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
776                 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
777             }
778             // update audio frame write index
779             pCb->afWrtIdx++;
780             if (pCb->afWrtIdx >= pCb->maxNumAfCb)
781             {
782                 pCb->afWrtIdx = 0;
783             }
785             pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
786             if (pAfWrt->numPrivateMetadata > 0)
787             {
788                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
789             }
790             else
791             {
792                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
793                 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
794                 Cache_wait();
795             }
796             Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
797             Cache_wait();
798             // update number of audio frames in circular buffer
799             pCb->numAfCb++;
800             
801             // Update CB Lag index 
802             //if (pCb->afLagIdx < pCb->afInitialLag)
803             //{
804             //    pCb->afLagIdx += 1;
805             //}
806             
807             // Update CB primed flag
808             // calculate number of delta samples before allowing CB read
809             if (pCb->primedFlag == 0)
810             {
811                 pCb->primedFlag = 1;
812                 
813                 // Calculate number of output frames to block reader.
814                 // This is sample count reader waits before allowed to actually read samples from the CB.
815                 //pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
816                 // FL: CB read decrements by strFrameLen and tests for >0, so rounding to strFrameLen is unnecessary
817                 pCb->deltaSamps = pCb->targetNDSamps - pAfWrt->sampleCount;
818                 
819                 // debug
820                 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
821                 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
822                 //if (gPrimedFlagCnt < 10)
823                 //    gPrimedFlagCnt++;
824             }
826             // Write back circular buffer configuration
827             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
828             // write back audio frame
829             Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
830             Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
831             Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
832             Cache_wait();
833             // write back PCM data
834             for (i = 0; i < pCb->maxAFChanNum; i++)
835             {
836 #ifndef DTS_BUILD
837             if ((streamMask >> i) & 0x1)
838 #endif
839             {//DTSX needs up to 16 channels to transfer metadata.
840                     Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
841                 }
842             }
843             Cache_wait();
845 #if 0 // (***) FL: shows timing of CB write
846             // debug
847             {
848                 static Uint8 toggleState = 0;
849                if (toggleState == 0)
850                    GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
851                else
852                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
853                toggleState = ~(toggleState);
854             }
855 #endif
857             Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
858             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);
859         }
860         else
861         {
862             //
863             // Skip write in case of 0 sample count
864             //
865             
866             // writing audio frame w/ zero samples
867             // update stat
868             pCb->wrtAfZeroSampsCnt++;
870             // Write back circular buffer configuration
871             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
872             Cache_wait();
873         }
874     //}
875     //else if (pCb->readerActiveFlag == 0)
876     if (pCb->readerActiveFlag == 0)
877     {
878         //
879         // Reader inactive, don't write to circular buffer or check OVRflow.
880         //
881         
882         // writing AF w/ inactive reader
883         // update stat
884         pCb->wrtAfReaderInactiveCnt++;
886         // Write back circular buffer configuration
887         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
888         Cache_wait();
889     }
891     // Leave the gate
892     GateMP_leave(gateHandle, key);
894     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
896     return ASP_DECOP_CB_SOK;
899 #if 0
900 // Get next audio frame to write in circular buffer
901 Int cbGetNextWriteAf(
902     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
903     Int8 cbIdx,                         // decoder output circular buffer index
904     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
907     IArg key;
908     GateMP_Handle gateHandle;
909     PAF_AST_DecOpCircBuf *pCb;
911     // Get gate handle
912     gateHandle = pCbCtl->gateHandle;
913     // Enter gate
914     key = GateMP_enter(gateHandle);
916     // Get circular buffer base pointer
917     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
919     // get pointer to current audio frame in circular buffer
920     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
921     
922     // update audio frame write index
923     pCb->afWrtIdx++;
924     if (pCb->afWrtIdx > pCb->maxNumAfCb)
925     {
926         pCb->afWrtIdx = 0;
927     }    
928     
929     // Leave the gate
930     GateMP_leave(gateHandle, key);
932     return ASP_DECOP_CB_SOK;
934 #endif
936 // Init last audio frame configuration info 
937 static Void cbInitLastAfInfo(
938     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
939     PAF_AudioFrame *pAfInit     // audio frame used for init
942     memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
943     
944     pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
945     pCb->lastAf.sampleRate = pAfInit->sampleRate;
946     pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
947     pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;