PASDK-218:CB updates for THD 192 kHz
[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
211     {
212         //
213         // Currently unsupported source select
214         //
215         
216         SW_BREAKPOINT; // debug
217         
218         // Leave the gate
219         GateMP_leave(gateHandle, key);
221         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
222     }
224     // Initialize circular buffer:
225     //  - PCM read index
226     //  - Private metadata read index
227     //  - number of PCM samples in CB
228     pCb->pcmRdIdx = 0;
229     pCb->prvMdRdIdx = 0;
230     pCb->numPcmSampsPerCh = 0;
232     // Initialize audio frames
233     for (n = 0; n < pCb->maxNumAfCb; n++)
234     {
235         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
236         
237         // Dec init AF sample count not correct for CB AFs.
238         // Dec Op frame length is computed in framework based on selected source.
239         pAfCb->sampleCount = decOpFrameLen;
241         // initialize CB AF using Dec init AF
242         pAfCb->sampleDecode = pDecInitAf->sampleDecode;
243         PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
244         pAfCb->sampleRate = pDecInitAf->sampleRate;
245         pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
246         pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
247         
248         // initialize metadata information updated by decoder
249         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
250         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
251         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
252         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
253     }
254     
255     // Initialize circular buffer current number of frames
256     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
257     
258     // Initialize audio frame PCM buffers
259     pPcmBuf = pCb->pcmBuf;
260     pMetaBuf = pCb->metaBuf;
261     for (n=0; n<pCb->maxNumAfCb; n++)
262     {
263         pAfCb = &pCb->afCb[n]; // get pointer to CB AF
264         
265         pAfCb->data.nChannels = pCb->maxAFChanNum;
266         pAfCb->data.nSamples = decOpFrameLen;
267         for (i=0; i<pCb->maxAFChanNum; i++)
268         {
269             pAfCb->data.sample[i] = pPcmBuf;
270             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
271             pPcmBuf += pCb->maxAFSampCount;
272             
273             pAfCb->data.samsiz[i] = 0;
274         }
275         
276         // Initialize metadata buffers
277         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
278         {
279             pAfCb->pafPrivateMetadata[i].offset = 0; 
280             pAfCb->pafPrivateMetadata[i].size   = 0; 
281             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
282             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
283         }
284     }
285     
286     // Initialize last audio frame configuration info
287     cbInitLastAfInfo(pCb, pDecInitAf);
288     
289     // Reset read/write flags
290     if (resetRwFlags != 0)
291     {
292         pCb->writerActiveFlag = 0;
293         pCb->readerActiveFlag = 0;
294         pCb->drainFlag = 0;
295     }
296     
297     // Reset stats
298     pCb->readAfWriterInactiveCnt = 0;
299     pCb->readAfNdCnt = 0;
300     pCb->wrtAfReaderInactiveCnt = 0;
301     pCb->wrtAfZeroSampsCnt = 0;
302     pCb->errAfUndCnt = 0;
303     pCb->errAfOvrCnt = 0;
304     pCb->errPcmUndCnt = 0;
305     pCb->errPcmOvrCnt = 0;
306     
307     // Write back circular buffer configuration
308     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
309     // Write back AF circular buffer
310     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
311     // Write back PCM data
312     for (n=0; n<pCb->maxNumAfCb; n++)
313     {
314         pAfCb = &pCb->afCb[n];
315         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
316         Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
317         for (i=0; i<pCb->maxAFChanNum; i++)
318         {
319             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
320         }
321     }
322     Cache_wait();
324     // Leave the gate
325     GateMP_leave(gateHandle, key);
326     
327     return ASP_DECOP_CB_SOK;
330 //Int8 gCbWriteStartCnt=0; // debug
332 // Start writes to circular buffer
333 Int cbWriteStart(
334     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
335     Int8 cbIdx                          // decoder output circular buffer index
338     IArg key;
339     GateMP_Handle gateHandle;
340     PAF_AST_DecOpCircBuf *pCb;
341     PAF_AudioFrame *pAfCb;
342     Int8 n;
343     //Int8 i;
345     //gCbWriteStartCnt++; // debug
346     
347     // Get gate handle
348     gateHandle = pCbCtl->gateHandle;
349     // Enter gate
350     key = GateMP_enter(gateHandle);
352     // Get circular buffer base pointer
353     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
355     // Invalidate circular buffer configuration.
356     // NOTE: Probably only a subset of this information needs to be updated.
357     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
358     Cache_wait();
359     
360     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
361     
362     // Invalidate AF circular buffer
363     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
364     for (n=0; n<pCb->maxNumAfCb; n++)
365     {
366         pAfCb = &pCb->afCb[n];
367         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
368     }
369     Cache_wait();
370             
371     // update flags
372     pCb->writerActiveFlag = 1;
373     pCb->drainFlag = 0;
374     //pCb->afLagIdx = 0;
375     
376     // Write back circular buffer configuration
377     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
378     Cache_wait();
380     // Leave the gate
381     GateMP_leave(gateHandle, key);
383     return ASP_DECOP_CB_SOK;
384 };
386 // Stop writes to circular buffer
387 Int cbWriteStop(
388     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
389     Int8 cbIdx                          // decoder output circular buffer index
392     IArg key;
393     GateMP_Handle gateHandle;
394     PAF_AST_DecOpCircBuf *pCb;
396     // Get gate handle
397     gateHandle = pCbCtl->gateHandle;
398     // Enter gate
399     key = GateMP_enter(gateHandle);
401     // Get circular buffer base pointer
402     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
404     // Invalidate circular buffer configuration
405     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
406     Cache_wait();
408     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // debug
409     
410     // update flags
411     pCb->writerActiveFlag = 0;
412     pCb->drainFlag = 1;
414     // Write back circular buffer configuration
415     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
416     Cache_wait();
417     
418     // Leave the gate
419     GateMP_leave(gateHandle, key);
421     return ASP_DECOP_CB_SOK;
424 // debug
425 //Int16 gSampleCountBuf[10];
426 //Int16 gCalcDeltaSampsBuf[10];
427 //Int8 gPrimedFlagCnt=0;
429 // (***) FL: revisit
430 // Write audio frame to circular buffer
431 Int cbWriteAf(
432     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
433     Int8 cbIdx,                         // decoder output circular buffer index
434     PAF_AudioFrame *pAfWrt              // audio frame from which to write
437     IArg key;
438     GateMP_Handle gateHandle;
439     PAF_AST_DecOpCircBuf *pCb;
440     PAF_AudioFrame *pAfCb;
441     PAF_ChannelMask_HD streamMask;
442     Int8 i;
443     Int16 j;
444     PAF_AudioData *pPcmBuf; UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf; 
445     PAF_AudioFrame *pAfCbRd;
446     PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
447     
448     // Get gate handle
449     gateHandle = pCbCtl->gateHandle;
450     // Enter gate
451     key = GateMP_enter(gateHandle);
453     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
455     // Get circular buffer base pointer
456     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
457     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
459     // Invalidate circular buffer configuration.
460     // NOTE: Probably only a subset of this information needs to be updated.
461     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
462     Cache_wait();
464     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
465     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
467     //if (pCb->readerActiveFlag == 1)
468     //{
469     //    //
470     //    // Normal case, reader active.
471     //    //
472         
473         if (pAfWrt->sampleCount != 0)
474         {
475             //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
477             // check AF overflow
478             if (pCb->numAfCb >= pCb->maxNumAfCb)
479             {
480                 pCb->errAfOvrCnt++;
482                 //SW_BREAKPOINT;
483                 Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
485                 // Write back circular buffer configuration
486                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
487                 Cache_wait();
489                 // Leave the gate
490                 GateMP_leave(gateHandle, key);
492                 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
494                 return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
495             }
496             
497             // FL: this won't reliably detect overflow because of PCM buffer write address wrap
498             // check PCM overflow
499             //if ((pCb->numPcmSampsPerCh + pAfWrt->sampleCount) > pCb->maxNumPcmSampsPerCh)
500             //{
501             //    pCb->errPcmOvrCnt++;
502             //
503             //    Log_info3("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d, maxNumPcmSampsPerCh=%d",
504             //        pCb->numPcmSampsPerCh, pAfWrt->sampleCount, pCb->maxNumPcmSampsPerCh);
505             //
506             //    // Write back circular buffer configuration
507             //    Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
508             //    Cache_wait();
509             //
510             //    // Leave the gate
511             //    GateMP_leave(gateHandle, key);
512             //
513             //    return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
514             //}
516             pAfCb = &pCb->afCb[pCb->afWrtIdx]; // get CB AF to be written
517             
518             // Get reader current PCM buffer location for PCM buffer overflow check
519             pAfCbRd = &pCb->afCb[pCb->afRdIdx];
520             //pPcmBufRd = pAfCbRd->data.sample[0];                    // FL: starting location of PCM samples for AF being read
521             pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx;    // FL: current location of PCM samples for AF being read
522             
523             pPcmBufWrt = pAfCb->data.sample[0];             // get current location in PCM buffer to be written
524             // (***) FL: currently no metadata buffer overflow detection
525             pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf; // get current location in MD buffer to be written
526             
527             // check PCM buffer overflow
528             pPcmBuf = pPcmBufWrt;
529             for (i = 0; i < pCb->maxAFChanNum; i++)
530             {
531                 // check PCM buffer wrap
532                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
533                 {
534                     pPcmBuf = pCb->pcmBuf;
535                 }
536                 
537                 // check PCM buffer overflow
538                 if ((pPcmBuf < pPcmBufRd) && 
539                     ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
540                 {
541                     pCb->errPcmOvrCnt++;;
542                     
543                     Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d", 
544                          pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
545             
546                     //SW_BREAKPOINT; // debug
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                 }
557                 
558                 pPcmBuf += pAfWrt->sampleCount;
559             }
560             
561             // configure AF sample pointers
562             pPcmBuf = pPcmBufWrt;
563             for (i = 0; i < pCb->maxAFChanNum; i++)
564             {
565                 // check PCM buffer wrap
566                 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
567                 {
568                     pPcmBuf = pCb->pcmBuf;
569                 }
570                 
571                 pAfCb->data.sample[i] = pPcmBuf;                
572                 pPcmBuf += pAfWrt->sampleCount;
573                 pAfCb->data.samsiz[i] = 0;
574             }
575             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
576             Cache_wait();
578             // FL: brute force reset of all metadata in CB AF?
579             for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
580             {
581                 pAfCb->pafPrivateMetadata[i].offset = 0;
582                 pAfCb->pafPrivateMetadata[i].size   = 0;
583                 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
584                 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
585             }
587             nextWrtIdx = 0;
588             if ((pCb->afWrtIdx + 1) >= pCb->maxNumAfCb)
589             {
590                 //Log_info0("cbWriteAf: AF Wrap around **** ");
591                 // next audio frame will be audio frame 0
592                 nextWrtIdx = 0;
593             }
594             else
595             {
596                 // next audio frame will be current audio frame + 1
597                 nextWrtIdx = pCb->afWrtIdx + 1;
598             }
600             pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
601             pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
603             // write audio frame information updated by decoder
604             pAfCb->sampleDecode = pAfWrt->sampleDecode;
605             PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
606             pAfCb->sampleRate = pAfWrt->sampleRate;
607             pAfCb->sampleCount = pAfWrt->sampleCount;
608             pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
609             pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
610             // write metadata information updated by decoder
611             pAfCb->bsMetadata_type     = pAfWrt->bsMetadata_type;        /* non zero if metadata is attached. */
612             pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
613             pAfCb->numPrivateMetadata  = pAfWrt->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
614             pAfCb->bsMetadata_offset   = pAfWrt->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
615             // write PCM samples
616             streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
617             for (i = 0; i < pCb->maxAFChanNum; i++)
618             {
619                 if ((streamMask >> i) & 0x1)
620                 {
621                     for (j = 0; j < pAfWrt->sampleCount; j++)
622                     {
623                         pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
624                     }
626                     pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
627                 }
628             }
629             
630             // Update PCM samples per channel
631             pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
632             
633             #ifdef CB_RW_OP_CAP_PP // debug
634             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
635             {
636                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
637                 {
638                     // log sample count
639                     pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
640                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
641                     // log idxs
642                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
643                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
644                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
645                     pCb->cb_opCnt++;
646                 }
647             }
648             #endif
650             // prepare metadata buffer pointers according to the metadata and buffer sizes
651             for (i=0; i < pAfWrt->numPrivateMetadata; i++)
652             {
653                 UInt8 *nextMdBuf;
654                 if(i == 0)
655                     nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
656                 else
657                     nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
658                 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
659                 {
660                     pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
661                 }
662                 else if(i != 0)
663                 {
664                     pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
665                 }
666                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
667             }
669             // Write metadata to circular buffer
670             for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
671             {
672                 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
673                 pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
674                 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
675             }
677             Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
678             Cache_wait();
679             for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
680             {
681                 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
682                 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
683             }
684             // update audio frame write index
685             pCb->afWrtIdx++;
686             if (pCb->afWrtIdx >= pCb->maxNumAfCb)
687             {
688                 pCb->afWrtIdx = 0;
689             }
691             pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
692             if(pAfWrt->numPrivateMetadata > 0)
693             {
694                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
695             }
696             else
697             {
698                 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
699                 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
700                 Cache_wait();
701             }
702             Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
703             Cache_wait();
704             // update number of audio frames in circular buffer
705             pCb->numAfCb++;
706             
707             // Update CB Lag index 
708             //if (pCb->afLagIdx < pCb->afInitialLag)
709             //{
710             //    pCb->afLagIdx += 1;
711             //}
712             
713             // Update CB primed flag
714             // calculate number of delta samples before allowing CB read
715             if (pCb->primedFlag == 0)
716             {
717                 pCb->primedFlag = 1;
718                 
719                 // Calculate number of output frames to block reader.
720                 // This is sample count reader waits before allowed to actually read samples from the CB.
721                 //pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
722                 // FL: CB read decrements by strFrameLen and tests for >0, so rounding to strFrameLen is unnecessary
723                 pCb->deltaSamps = pCb->targetNDSamps - pAfWrt->sampleCount;
724                 
725                 // debug
726                 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
727                 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
728                 //if (gPrimedFlagCnt < 10)
729                 //    gPrimedFlagCnt++;
730             }
732             // Write back circular buffer configuration
733             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
734             // write back audio frame
735             Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
736             Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
737             Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
738             Cache_wait();
739             // write back PCM data
740             for (i = 0; i < pCb->maxAFChanNum; i++)
741             {
742                 if ((streamMask >> i) & 0x1)
743                 {
744                     Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
745                 }
746             }
747             Cache_wait();
749 #if 0 // (***) FL: shows timing of CB write
750             // debug
751             {
752                 static Uint8 toggleState = 0;
753                if (toggleState == 0)
754                    GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
755                else
756                    GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
757                toggleState = ~(toggleState);
758             }
759 #endif
761             Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
762             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);
763         }
764         else
765         {
766             //
767             // Skip write in case of 0 sample count
768             //
769             
770             // writing audio frame w/ zero samples
771             // update stat
772             pCb->wrtAfZeroSampsCnt++;
774             // Write back circular buffer configuration
775             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
776             Cache_wait();
777         }
778     //}
779     //else if (pCb->readerActiveFlag == 0)
780     if (pCb->readerActiveFlag == 0)
781     {
782         //
783         // Reader inactive, don't write to circular buffer or check OVRflow.
784         //
785         
786         // writing AF w/ inactive reader
787         // update stat
788         pCb->wrtAfReaderInactiveCnt++;
790         // Write back circular buffer configuration
791         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
792         Cache_wait();
793     }
795     // Leave the gate
796     GateMP_leave(gateHandle, key);
798     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
800     return ASP_DECOP_CB_SOK;
803 #if 0
804 // Get next audio frame to write in circular buffer
805 Int cbGetNextWriteAf(
806     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
807     Int8 cbIdx,                         // decoder output circular buffer index
808     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
811     IArg key;
812     GateMP_Handle gateHandle;
813     PAF_AST_DecOpCircBuf *pCb;
815     // Get gate handle
816     gateHandle = pCbCtl->gateHandle;
817     // Enter gate
818     key = GateMP_enter(gateHandle);
820     // Get circular buffer base pointer
821     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
823     // get pointer to current audio frame in circular buffer
824     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
825     
826     // update audio frame write index
827     pCb->afWrtIdx++;
828     if (pCb->afWrtIdx > pCb->maxNumAfCb)
829     {
830         pCb->afWrtIdx = 0;
831     }    
832     
833     // Leave the gate
834     GateMP_leave(gateHandle, key);
836     return ASP_DECOP_CB_SOK;
838 #endif
840 // Init last audio frame configuration info 
841 static Void cbInitLastAfInfo(
842     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
843     PAF_AudioFrame *pAfInit     // audio frame used for init
846     memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
847     
848     pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
849     pCb->lastAf.sampleRate = pAfInit->sampleRate;
850     pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
851     pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;