]> 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
PASDK-477:Merge remote-tracking branch 'origin/dev_pasdk_qin_dtsx' into pasdk_frank_p...
[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;
240         switch (pDecInitAf->sampleRate)
241         {
242             case PAF_SAMPLERATE_44100HZ:
243             case PAF_SAMPLERATE_48000HZ:
244                 decOpFrameLen = 256;
245                 break;
246             case PAF_SAMPLERATE_88200HZ:
247             case PAF_SAMPLERATE_96000HZ:
248                 decOpFrameLen = (256*2);
249                 break;
250             case PAF_SAMPLERATE_176400HZ:
251             case PAF_SAMPLERATE_192000HZ:
252                 decOpFrameLen = (256*4);
253                 break;
254             default:
255                 decOpFrameLen = 256;
256                 break;
257         }
259 #if 0           
260         // initialize audio frames
261         for (n=0; n<pCb->maxNumAfCb; n++)
262         {
263             pAfCb = &pCb->afCb[n];
264             pAfCb->sampleDecode = sourceSelect;
265             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
266             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
267             pAfCb->sampleCount = decOpFrameLen;
268             pAfCb->channelConfigurationRequest.full = 0;
269             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
270             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
271             pAfCb->channelConfigurationStream.full = 0;
272             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
273             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
275             // write metadata information updated by decoder
276             pAfCb->bsMetadata_type     = PAF_bsMetadata_DTS_X;          /* Audio data from DTSX decoder. */
277             pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
278             pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
279             pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
280         }
281 #endif
282     }
283     else
284     {
285         //
286         // Currently unsupported source select
287         //
288         
289         SW_BREAKPOINT; // debug
290         
291         // Leave the gate
292         GateMP_leave(gateHandle, key);
294         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
295     }
297     // Initialize circular buffer:
298     //  - PCM read index
299     //  - Private metadata read index
300     //  - number of PCM samples in CB
301     pCb->pcmRdIdx = 0;
302     pCb->prvMdRdIdx = 0;
303     pCb->numPcmSampsPerCh = 0;
305     // Initialize audio frames
306     for (n = 0; n < pCb->maxNumAfCb; n++)
307     {
308         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
309         
310         // Dec init AF sample count not correct for CB AFs.
311         // Dec Op frame length is computed in framework based on selected source.
312         pAfCb->sampleCount = decOpFrameLen;
314         // initialize CB AF using Dec init AF
315         pAfCb->sampleDecode = pDecInitAf->sampleDecode;
316         PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
317         pAfCb->sampleRate = pDecInitAf->sampleRate;
318         pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
319         pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
320         
321         // initialize metadata information updated by decoder
322         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
323         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
324         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
325         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
326     }
327     
328     // Initialize circular buffer current number of frames
329     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
330     
331     // Initialize audio frame PCM buffers
332     pPcmBuf = pCb->pcmBuf;
333     pMetaBuf = pCb->metaBuf;
334     for (n=0; n<pCb->maxNumAfCb; n++)
335     {
336         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
337         
338         pAfCb->data.nChannels = pCb->maxAFChanNum;
339         pAfCb->data.nSamples = decOpFrameLen;
340         for (i=0; i<pCb->maxAFChanNum; i++)
341         {
342             pAfCb->data.sample[i] = pPcmBuf;
343             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
344             pPcmBuf += pCb->maxAFSampCount;
345             
346             pAfCb->data.samsiz[i] = 0;
347         }
348         
349         // Initialize metadata buffers
350         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
351         {
352             pAfCb->pafPrivateMetadata[i].offset = 0; 
353             pAfCb->pafPrivateMetadata[i].size   = 0; 
354             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
355             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
356         }
357     }
358     
359     // Initialize last audio frame configuration info
360     cbInitLastAfInfo(pCb, pDecInitAf);
361     
362     // Reset read/write flags
363     if (resetRwFlags != 0)
364     {
365         pCb->writerActiveFlag = 0;
366         pCb->readerActiveFlag = 0;
367         pCb->drainFlag = 0;
368     }
369     
370     // Reset stats
371     pCb->readAfWriterInactiveCnt = 0;
372     pCb->readAfNdCnt = 0;
373     pCb->wrtAfReaderInactiveCnt = 0;
374     pCb->wrtAfZeroSampsCnt = 0;
375     pCb->errAfUndCnt = 0;
376     pCb->errAfOvrCnt = 0;
377     pCb->errPcmUndCnt = 0;
378     pCb->errPcmOvrCnt = 0;
379     
380     // Write back circular buffer configuration
381     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
382     // Write back AF circular buffer
383     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
384     // Write back PCM data
385     for (n=0; n<pCb->maxNumAfCb; n++)
386     {
387         pAfCb = &pCb->afCb[n];
388         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
389         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
390         for (i=0; i<pCb->maxAFChanNum; i++)
391         {
392             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
393         }
394     }
395     Cache_wait();
397     // Leave the gate
398     GateMP_leave(gateHandle, key);
399     
400     return ASP_DECOP_CB_SOK;
403 //Int8 gCbWriteStartCnt=0; // debug
405 // Start writes to circular buffer
406 Int cbWriteStart(
407     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
408     Int8 cbIdx                          // decoder output circular buffer index
411     IArg key;
412     GateMP_Handle gateHandle;
413     PAF_AST_DecOpCircBuf *pCb;
414     PAF_AudioFrame *pAfCb;
415     Int8 n;
416     //Int8 i;
418     //gCbWriteStartCnt++; // debug
419     
420     // Get gate handle
421     gateHandle = pCbCtl->gateHandle;
422     // Enter gate
423     key = GateMP_enter(gateHandle);
425     // Get circular buffer base pointer
426     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
428     // Invalidate circular buffer configuration.
429     // NOTE: Probably only a subset of this information needs to be updated.
430     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
431     Cache_wait();
432     
433     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
434     
435     // Invalidate AF circular buffer
436     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
437     for (n=0; n<pCb->maxNumAfCb; n++)
438     {
439         pAfCb = &pCb->afCb[n];
440         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
441     }
442     Cache_wait();
443             
444     // update flags
445     pCb->writerActiveFlag = 1;
446     pCb->drainFlag = 0;
447     //pCb->afLagIdx = 0;
448     
449     // Write back circular buffer configuration
450     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
451     Cache_wait();
453     // Leave the gate
454     GateMP_leave(gateHandle, key);
456     return ASP_DECOP_CB_SOK;
457 };
459 // Stop writes to circular buffer
460 Int cbWriteStop(
461     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
462     Int8 cbIdx                          // decoder output circular buffer index
465     IArg key;
466     GateMP_Handle gateHandle;
467     PAF_AST_DecOpCircBuf *pCb;
469     // Get gate handle
470     gateHandle = pCbCtl->gateHandle;
471     // Enter gate
472     key = GateMP_enter(gateHandle);
474     // Get circular buffer base pointer
475     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
477     // Invalidate circular buffer configuration
478     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
479     Cache_wait();
481     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // debug
482     
483     // update flags
484     pCb->writerActiveFlag = 0;
485     pCb->drainFlag = 1;
487     // Write back circular buffer configuration
488     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
489     Cache_wait();
490     
491     // Leave the gate
492     GateMP_leave(gateHandle, key);
494     return ASP_DECOP_CB_SOK;
497 // debug
498 //Int16 gSampleCountBuf[10];
499 //Int16 gCalcDeltaSampsBuf[10];
500 //Int8 gPrimedFlagCnt=0;
501 // debug
502 //Int32 gPcmOvershootWrap1=0;
503 //Int32 gPcmOvershootWrap2=0;
504 //Int32 gPcmOvershootNoWrap=0;
506 // (***) FL: revisit
507 // Write audio frame to circular buffer
508 Int cbWriteAf(
509     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
510     Int8 cbIdx,                         // decoder output circular buffer index
511     PAF_AudioFrame *pAfWrt              // audio frame from which to write
514     IArg key;
515     GateMP_Handle gateHandle;
516     PAF_AST_DecOpCircBuf *pCb;
517     PAF_AudioFrame *pAfCb;
518     PAF_ChannelMask_HD streamMask;
519     Int8 i;
520     Int16 j;
521     PAF_AudioData *pPcmBuf; 
522     UInt8 *pMetaBuf; 
523     //int nextWrtIdx;
524     //PAF_AudioFrame *pAfCbNextAf; 
525     PAF_AudioFrame *pAfCbRd;
526     PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
527     Int8 pcmOvr;
528     
529     // Get gate handle
530     gateHandle = pCbCtl->gateHandle;
531     // Enter gate
532     key = GateMP_enter(gateHandle);
534     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
536     // Get circular buffer base pointer
537     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
538     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
540     // Invalidate circular buffer configuration.
541     // NOTE: Probably only a subset of this information needs to be updated.
542     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
543     Cache_wait();
545     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
546     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
548     //if (pCb->readerActiveFlag == 1)
549     //{
550     //    //
551     //    // Normal case, reader active.
552     //    //
553         
554         if (pAfWrt->sampleCount != 0)
555         {
556             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
558             // check AF overflow
559             if (pCb->numAfCb >= pCb->maxNumAfCb)
560             {
561                 pCb->errAfOvrCnt++;
563                 //SW_BREAKPOINT;
564                 Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
566                 // Write back circular buffer configuration
567                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
568                 Cache_wait();
570                 // Leave the gate
571                 GateMP_leave(gateHandle, key);
573                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
575                 return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
576             }
577             
578             // FL: this won't reliably detect overflow because of PCM buffer write address wrap
579             // check PCM overflow
580             //if ((pCb->numPcmSampsPerCh + pAfWrt->sampleCount) > pCb->maxNumPcmSampsPerCh)
581             //{
582             //    pCb->errPcmOvrCnt++;
583             //
584             //    Log_info3("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d, maxNumPcmSampsPerCh=%d",
585             //        pCb->numPcmSampsPerCh, pAfWrt->sampleCount, pCb->maxNumPcmSampsPerCh);
586             //
587             //    // Write back circular buffer configuration
588             //    Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
589             //    Cache_wait();
590             //
591             //    // Leave the gate
592             //    GateMP_leave(gateHandle, key);
593             //
594             //    return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
595             //}
597             // get CB AF write info
598             pAfCb = &pCb->afCb[pCb->afWrtIdx];                      // get CB AF to be written
599             pPcmBufWrt = pAfCb->data.sample[0];                     // get current location in PCM buffer to be written
600             // (***) FL: currently no metadata buffer overflow detection
601             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;         // get current location in MD buffer to be written
602             
603             // get CB AF read info
604             pAfCbRd = &pCb->afCb[pCb->afRdIdx];                     // get CB AF being read
605             //pPcmBufRd = pAfCbRd->data.sample[0];                    // FL: starting location of PCM samples for AF being read
606             pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx;    // FL: current location of PCM samples for AF being read
607             
608             // Check PCM buffer overflow
609             pPcmBuf = pPcmBufWrt;
610             pcmOvr = 0;
611             for (i = 0; i < pCb->maxAFChanNum; i++)
612             {
613                 //
614                 // Writes of PCM to PCM CB use CC stream, but this isn't considered here.
615                 // For each channel which *can* be written, check the current reader location won't be overwritten.
616                 // The current reader location is the earliest channel which *could have been* written for that CB AF.
617                 //
618                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
619                 {
620                     // this write will wrap
621                     
622                     // check OVR before wrap
623                     if ((pPcmBuf < pPcmBufRd) && 
624                         ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
625                     {
626                         pCb->errPcmOvrCnt++;
627                         //gPcmOvershootWrap1 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
628                         pcmOvr = 1;
629                     }
630                     
631                     if (pcmOvr == 0)
632                     {
633                         // wrap pointer
634                         pPcmBuf = pCb->pcmBuf;   
635                         // check OVR after wrap
636                         if ((pPcmBuf < pPcmBufRd) && 
637                             ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
638                         {
639                             pCb->errPcmOvrCnt++;
640                             //gPcmOvershootWrap2 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
641                             pcmOvr = 1;
642                         }                                                                
643                     }
644                 }
645                 else if ((pPcmBuf < pPcmBufRd) && 
646                     ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
647                 {
648                     // this write won't wrap
649                     
650                     //gPcmOvershootNoWrap = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
651                     pCb->errPcmOvrCnt++;
652                     pcmOvr = 1;
653                 }
654                 else
655                 {
656                     // update pointer
657                     pPcmBuf += pAfWrt->sampleCount;                                        
658                 }
659                 
660                 if (pcmOvr == 1)
661                 {
662                     Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d", 
663                          pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
664             
665                     //SW_BREAKPOINT; // debug
666                     
667                     // Write back circular buffer configuration
668                     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
669                     Cache_wait();
670             
671                     // Leave the gate
672                     GateMP_leave(gateHandle, key);
673             
674                     return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
675                 }
676             }
677             
678             // (***) FL: !!! REVISIT!!! 
679             //           Allocating memory for max # channels (e.g. 32 for THD).
680             //           GROSS over allocation for THD 192 kHz, 6ch max.
681             // configure AF sample pointers
682             pPcmBuf = pPcmBufWrt;
683             for (i = 0; i < pCb->maxAFChanNum; i++)
684             {
685                 // check PCM buffer wrap
686                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
687                 {
688                     pPcmBuf = pCb->pcmBuf;
689                 }
690                 
691                 pAfCb->data.sample[i] = pPcmBuf;                
692                 pPcmBuf += pAfWrt->sampleCount;
693                 pAfCb->data.samsiz[i] = 0;
694             }
695             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
696             Cache_wait();
698             // FL: brute force reset of all metadata in CB AF?
699             for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
700             {
701                 pAfCb->pafPrivateMetadata[i].offset = 0;
702                 pAfCb->pafPrivateMetadata[i].size   = 0;
703                 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
704                 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
705             }
707 #if 0 // FL: unused
708             nextWrtIdx = 0;
709             if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
710             {
711                 //Log_info0("cbWriteAf: AF Wrap around **** ");
712                 // next audio frame will be audio frame 0
713                 nextWrtIdx = 0;
714             }
715             else
716             {
717                 // next audio frame will be current audio frame + 1
718                 nextWrtIdx = pCb->afWrtIdx + 1;
719             }
720             
721             pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
722             pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount]; // pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
723 #endif
724             
725             // write audio frame information updated by decoder
726             pAfCb->sampleDecode = pAfWrt->sampleDecode;
727             PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
728             pAfCb->sampleRate = pAfWrt->sampleRate;
729             pAfCb->sampleCount = pAfWrt->sampleCount;
730             pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
731             pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
732             // write metadata information updated by decoder
733             pAfCb->bsMetadata_type     = pAfWrt->bsMetadata_type;        /* non zero if metadata is attached. */
734             pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
735             pAfCb->numPrivateMetadata  = pAfWrt->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
736             pAfCb->bsMetadata_offset   = pAfWrt->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
737             
738                         pAfCb->mode = pAfWrt->mode;                                       /* mode is used in DTSX to pass info to PARMA */
739                         pAfCb->numChansUsedForMetadata = pAfWrt->numChansUsedForMetadata; /* if metadata is used in DTSX*/
740                         pAfCb->pafBsFixedData = pAfWrt->pafBsFixedData;                   /* if true, do not convert float to fixed in DTSX metadata transfer */
741                         pAfCb->root = pAfWrt->root;                                       /* used for channel MASK in DTSX . BAD IDEA, need fix */
742                         pAfCb->resetCount = pAfWrt->resetCount;                           /* used for communication between DTSX and PARMA */
743                         pAfCb->data.nChannels = pAfWrt->data.nChannels;                   /* number of channels used */
744             // write PCM samples
746                         if (pAfCb->bsMetadata_type == PAF_bsMetadata_DTS_X)
747                         {
748                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
749                                 for (i = 0; i < pAfWrt->data.nChannels; i++)
750                                 { 
751                                         for (j = 0; j < pAfWrt->sampleCount; j++)
752                                         {
753                                                 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
754                                         }
756                                         pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
757                                 }
758                         }
759                         else
760                         {
761                                 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
762                                 for (i = 0; i < pCb->maxAFChanNum; i++)
763                                 {
765                                         if ((streamMask >> i) & 0x1)
766                                         { //DTSX needs up to 16 channels to transfer metadata.
767                                                 for (j = 0; j < pAfWrt->sampleCount; j++)
768                                                 {
769                                                         pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
770                                                 }
772                                                 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
773                                         }
774                                 }
775                         }
776             // Update PCM samples per channel
777             pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
778             
779             #ifdef CB_RW_OP_CAP_PP // debug
780             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
781             {
782                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
783                 {
784                     // log sample count
785                     pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
786                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
787                     // log idxs
788                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
789                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
790                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
791                     pCb->cb_opCnt++;
792                 }
793             }
794             #endif
796             // prepare metadata buffer pointers according to the metadata and buffer sizes
797             for (i = 0; i < pAfWrt->numPrivateMetadata; i++)
798             {
799                 UInt8 *nextMdBuf;
800                 if (i == 0)
801                 {
802                     nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);                    
803                 }
804                 else
805                 {
806                     nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);                    
807                 }
808                 if (nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
809                 {
810                     pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
811                 }
812                 else if (i != 0)
813                 {
814                     pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
815                 }
816                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
817             }
819             // Write metadata to circular buffer
820             for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
821             {
822                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
823                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
824                 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
825             }
827             Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
828             Cache_wait();
829             for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
830             {
831                 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
832                 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
833             }
834             // update audio frame write index
835             pCb->afWrtIdx++;
836             if (pCb->afWrtIdx >= pCb->maxNumAfCb)
837             {
838                 pCb->afWrtIdx = 0;
839             }
841             pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
842             if (pAfWrt->numPrivateMetadata > 0)
843             {
844                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
845             }
846             else
847             {
848                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
849                 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
850                 Cache_wait();
851             }
852             Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
853             Cache_wait();
854             // update number of audio frames in circular buffer
855             pCb->numAfCb++;
856             
857             // Update CB Lag index 
858             //if (pCb->afLagIdx < pCb->afInitialLag)
859             //{
860             //    pCb->afLagIdx += 1;
861             //}
862             
863             // Update CB primed flag.
864             // Calculate number of delta samples before allowing CB read.
865             if (pCb->primedFlag == 0)
866             {
867                 pCb->primedFlag = 1;
868                 
869                 // THD has variable number of AUs per frame. 
870                 // Some frames can be quite large (e.g. 96 AUs), and delta samples calculation small or even negative.
871                 // In this case, there won't be any reader hold off, and no nominal delay in the CB.
872                 pCb->deltaSamps = pCb->targetNDSamps;
873                 
874                 // debug
875                 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
876                 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
877                 //if (gPrimedFlagCnt < 10)
878                 //    gPrimedFlagCnt++;
879             }
881             // Update delta samples using number of write audio frame samples.
882             if (pCb->deltaSamps > 0)
883             {
884                 pCb->deltaSamps = pCb->deltaSamps - pAfWrt->sampleCount;
885             }
886             
887             // Write back circular buffer configuration
888             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
889             // write back audio frame
890             Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
891             Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
892             Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
893             Cache_wait();
894             // write back PCM data
895                         if (pAfCb->bsMetadata_type == PAF_bsMetadata_DTS_X)
896                         {       
897                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
898                                 for (i = 0; i < pAfWrt->data.nChannels; i++)
899                                 { 
900                                         Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
901                                 }
902                         }
903                         else 
904                         {
905                                 for (i = 0; i < pCb->maxAFChanNum; i++)
906                                 {
907                                         if ((streamMask >> i) & 0x1)
908                                         {
909                                                 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
910                                         }
911                                 }
912                         }
913             Cache_wait();
915 #if 0 // also for CB_RW_OP_CAP_PP (***) FL: shows timing of CB write
916             // debug
917             {
918                 static Uint8 toggleState = 0;
919                if (toggleState == 0)
920                    GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
921                else
922                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
923                toggleState = ~(toggleState);
924             }
925 #endif
927             Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
928             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);
929         }
930         else
931         {
932             //
933             // Skip write in case of 0 sample count
934             //
935             
936             // writing audio frame w/ zero samples
937             // update stat
938             pCb->wrtAfZeroSampsCnt++;
940             // Write back circular buffer configuration
941             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
942             Cache_wait();
943         }
944     //}
945     //else if (pCb->readerActiveFlag == 0)
946     if (pCb->readerActiveFlag == 0)
947     {
948         //
949         // Reader inactive, don't write to circular buffer or check OVRflow.
950         //
951         
952         // writing AF w/ inactive reader
953         // update stat
954         pCb->wrtAfReaderInactiveCnt++;
956         // Write back circular buffer configuration
957         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
958         Cache_wait();
959     }
961     // Leave the gate
962     GateMP_leave(gateHandle, key);
964     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
966     return ASP_DECOP_CB_SOK;
969 #if 0
970 // Get next audio frame to write in circular buffer
971 Int cbGetNextWriteAf(
972     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
973     Int8 cbIdx,                         // decoder output circular buffer index
974     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
977     IArg key;
978     GateMP_Handle gateHandle;
979     PAF_AST_DecOpCircBuf *pCb;
981     // Get gate handle
982     gateHandle = pCbCtl->gateHandle;
983     // Enter gate
984     key = GateMP_enter(gateHandle);
986     // Get circular buffer base pointer
987     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
989     // get pointer to current audio frame in circular buffer
990     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
991     
992     // update audio frame write index
993     pCb->afWrtIdx++;
994     if (pCb->afWrtIdx > pCb->maxNumAfCb)
995     {
996         pCb->afWrtIdx = 0;
997     }    
998     
999     // Leave the gate
1000     GateMP_leave(gateHandle, key);
1002     return ASP_DECOP_CB_SOK;
1004 #endif
1006 // Init last audio frame configuration info 
1007 static Void cbInitLastAfInfo(
1008     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
1009     PAF_AudioFrame *pAfInit     // audio frame used for init
1012     memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
1013     
1014     pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
1015     pCb->lastAf.sampleRate = pAfInit->sampleRate;
1016     pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
1017     pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;