Merge branch 'dev_pasdk_frank_pasdk516AsotRefactoring' into dev_pasdk_pasdk29Integration
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / framework / aspDecOpCircBuf_master.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>
41 #include <ti/ipc/GateMP.h>
43 #include "common.h"
44 #include "paftyp.h"
45 #include "pafdec.h"
46 #include "aspDecOpCircBuf_master.h"
48 #include "evmc66x_gpio_dbg.h" // Debug
50 #ifdef CB_RW_OP_CAP_PP // debug
51 // Global variables
52 Uint32 *gCB_samples_op = NULL;
53 Uint8 *gCB_op_owner = NULL;
54 Uint32 *gCB_opCnt = 0;
55 Uint8 *gCB_afRdIdx = NULL;
56 Uint8 *gCB_afWrtIdx = NULL;
57 Uint8 *gCB_numAfCb = NULL;
58 #endif
60 // Update last audio frame configuration info 
61 static Void cbUpdateLastAfInfo(
62     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
63     PAF_AudioFrame *pAfUpd      // audio frame used for update
64 );
66 // Generate mute AF on circular buffer read using the last AF configuration info 
67 static Void cbReadMuteWithLastAfInfo(
68     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
69     PAF_AudioFrame *pAfRd         // audio frame into which to read
70 );
72 // Initialize circular buffer
73 Int cbInit(
74     PAF_AST_DecOpCircBuf *pCb
75 )
76 {
77     // set source select
78     pCb->sourceSel = PAF_SOURCE_UNKNOWN;
80     #ifdef CB_RW_OP_CAP_PP // debug
81     // Get address in global variables
82     gCB_samples_op = pCb->cb_samples_op;
83     gCB_op_owner = pCb->cb_op_owner;
84     gCB_opCnt = &pCb->cb_opCnt;
85     gCB_afRdIdx = pCb->cb_afRdIdx;
86     gCB_afWrtIdx = pCb->cb_afWrtIdx;
87     gCB_numAfCb = pCb->cb_numAfCb;
88     #endif
89     
90     // Write back circular buffer configuration
91     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
92     Cache_wait();
94     return ASP_DECOP_CB_SOK;
95 }
97 // Initialize circular buffer for Stream reads
98 Int cbInitStreamRead(
99     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
100     Int8 cbIdx                          // decoder output circular buffer index
103     IArg key;
104     GateMP_Handle gateHandle;
105     PAF_AST_DecOpCircBuf *pCb;
106     
107     // Get gate handle
108     gateHandle = pCbCtl->gateHandle;
109     // Enter gate
110     key = GateMP_enter(gateHandle);
112     // Get circular buffer base pointer
113     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
114     
115     // Invalidate circular buffer configuration
116     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
117     Cache_wait();
119     // Set output frame length
120     pCb->strFrameLen = pCb->cbStatus.strFrameLen;
122     // Write back circular buffer configuration
123     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
124     Cache_wait();
126     // Leave the gate
127     GateMP_leave(gateHandle, key);
128     
129     //return ret;
130     return ASP_DECOP_CB_SOK;
133 // Start reads from circular buffer
134 Int cbReadStart(
135     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
136     Int8 cbIdx                          // decoder output circular buffer index
139     IArg key;
140     GateMP_Handle gateHandle;
141     PAF_AST_DecOpCircBuf *pCb;
143     // Get gate handle
144     gateHandle = pCbCtl->gateHandle;
145     // Enter gate
146     key = GateMP_enter(gateHandle);
148     // Get circular buffer base pointer
149     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
150     
151     // Invalidate circular buffer configuration
152     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
153     Cache_wait();
154     
155     //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
157     // update flags
158     pCb->readerActiveFlag = 1;
159     
160     // Write back circular buffer configuration
161     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
162     Cache_wait();
164     // Leave the gate
165     GateMP_leave(gateHandle, key);
167     return ASP_DECOP_CB_SOK;
170 // Stop reads from circular buffer
171 Int cbReadStop(
172     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
173     Int8 cbIdx                          // decoder output circular buffer index
176     IArg key;
177     GateMP_Handle gateHandle;
178     PAF_AST_DecOpCircBuf *pCb;
180     // Get gate handle
181     gateHandle = pCbCtl->gateHandle;
182     // Enter gate
183     key = GateMP_enter(gateHandle);
185     // Get circular buffer base pointer
186     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
188     // Invalidate circular buffer configuration
189     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
190     Cache_wait();
191     
192     //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
194     // update flags
195     pCb->readerActiveFlag = 0;
196     
197     // Write back circular buffer configuration
198     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
199     Cache_wait();
201     // Leave the gate
202     GateMP_leave(gateHandle, key);
204     return ASP_DECOP_CB_SOK;
207 // debug
208 //Int16 gDeltaSampsBuf[20];
209 //Int8 gDeltaSampsBufIdx=0;
211 // Read audio frame from circular buffer
212 Int cbReadAf(
213     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
214     Int8 cbIdx,                         // decoder output circular buffer index
215     PAF_AudioFrame *pAfRd               // audio frame into which to read
218     IArg key;
219     GateMP_Handle gateHandle;           // CB gate handle to arbitrate CB r/w access
220     PAF_AST_DecOpCircBuf *pCb;          // pointer to CB
221     PAF_AudioFrame *pAfCb;              // pointer to current CB AF
222     PAF_ChannelMask_HD streamMask;      // CB AF stream mask
223     Int16 numSampsRd;                   // number of samples to read from current CB AF
224     Int16 totNumSampsRd;                // total number of samples read from CB
225     Int16 pcmWrtIdx;                    // read audio frame PCM write index
226     Int8 prvMdWrtIdx;                   // read audio frame metadata write index
227     Int8 i;
228     Int16 j;
229     
230     // Get gate handle
231     gateHandle = pCbCtl->gateHandle;
232     // Enter gate
233     key = GateMP_enter(gateHandle);
235     // Get circular buffer base pointer
236     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
238     // Invalidate circular buffer configuration.
239     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
240     Cache_wait();
242     //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
244     //
245     // Check (writerActiveFlag,drainFlag)=(1,1)
246     //
247     if ((pCb->writerActiveFlag == 1) && (pCb->drainFlag == 1))
248     {
249         //
250         // This shouldn't occur:
251         // writer is active AND draining circular buffer
252         //
253         
254         //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, drainFlag=%d", pCb->writerActiveFlag, pCb->drainFlag); // debug
255         SW_BREAKPOINT; // debug
256         
257         // Leave the gate
258         GateMP_leave(gateHandle, key);
259         
260         return ASP_DECOP_CB_READ_INVSTATE;
261     }
263     //
264     // Check (writerActiveFlag,drainFlag)=(0,0)
265     //
266     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 0))
267     {
268         //
269         // Writer inactive, not draining circular buffer.
270         // Skip UNDerflow check, mute output.
271         //
272         
273         pCb->readAfWriterInactiveCnt++;
274         
275         // Mute output if write inactive and not draining CB
276         //cbReadAfMute(pAfRd, pCb->strFrameLen);
277         cbReadMuteWithLastAfInfo(pCb, pAfRd);
278         
279         // Write back circular buffer configuration.
280         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
281         Cache_wait();
283         // Leave the gate
284         GateMP_leave(gateHandle, key);
286         return ASP_DECOP_CB_SOK;
287     }
289     if ((pCb->writerActiveFlag == 0) && (pCb->drainFlag == 1))
290     {
291         //
292         // Writer inactive, but remaining frames in circular buffer.
293         // Update drain flag.
294         //
295         
296         if (pCb->numAfCb <= 0)
297         {
298             pCb->drainFlag = 0;
300             // Mute output if CB drained
301             cbReadMuteWithLastAfInfo(pCb, pAfRd);
303             // Write back circular buffer configuration.
304             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
305             Cache_wait();    
307             // Leave the gate
308             GateMP_leave(gateHandle, key);
310             return ASP_DECOP_CB_SOK;
311         }
312     }
313     
314     //
315     // Hold off read of PCM samples from CB until Nominal Delay satisfied
316     //
317     if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
318     {
319         pCb->readAfNdCnt++;
320         
321         cbReadMuteWithLastAfInfo(pCb, pAfRd);
322         
323         // Write back circular buffer configuration.
324         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
325         Cache_wait();
326         
327         // Leave the gate
328         GateMP_leave(gateHandle, key);
330         return ASP_DECOP_CB_SOK;
331     }
332     
333     //
334     // (writerActiveFlag,drainFlag)= (0,0) and (1,1) states checked above
335     // (writerActiveFlag,drainFlag)=(1,0) and (0,1) states are left
336     // Checking (writerActiveFlag,drainFlag)=(1,0) state here
337     //
338     if (pCb->writerActiveFlag == 1)
339     {
340         // check underflow
341         if (pCb->numAfCb <= 0)
342         {
343             // 
344             // Increment underflow count
345             //
346             pCb->errAfUndCnt++;
347             // Mute output on underflow
348             //cbReadAfMute(pAfRd, pCb->strFrameLen);
349             cbReadMuteWithLastAfInfo(pCb, pAfRd);
350             //SW_BREAKPOINT; // debug
351             
352 #if 0 // debug // also for CB_RW_OP_CAP_PP 
353             // Shows timing of CB underflow
354             // ADC B9
355             {
356                 static Uint8 toggleState = 0;
357                 if (toggleState == 0)
358                     GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
359                 else
360                     GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
361                 toggleState = ~(toggleState);
362             }
363 #endif
365             #ifdef CB_RW_OP_CAP_PP // debug
366             if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
367             {
368                 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
369                 {
370                     // log sample count
371                     pCb->cb_samples_op[pCb->cb_opCnt] = 0;  // due to underflow
372                     pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
373                     // log idxs
374                     pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
375                     pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
376                     pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
377                     pCb->cb_opCnt++;
378                 }
379             }
380             #endif
382             // Write back circular buffer configuration.
383             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
384             Cache_wait();    
385             
386             // Leave the gate
387             GateMP_leave(gateHandle, key);
388             
389             return ASP_DECOP_CB_AF_READ_UNDERFLOW;
390         }
391     }
392     
393     //
394     // Checking (writerActiveFlag,drainFlag)=(1,0) state above and here
395     // Checking (writerActiveFlag,drainFlag)=(0,1) state here
396     //
397     if ((pCb->writerActiveFlag == 1) || (pCb->drainFlag == 1))
398     {
399         //
400         // Writer active or draining remaining frames in circular buffer.
401         // Read next audio frame.
402         //
404         //
405         // Read Audio Frame from CB Audio Frames.
406         // Read PCM & associated metadata from CB AFs until Read AF is filled.
407         //
408         // If multiple CB AFs are read in creating Read AF, CB AF parameters 
409         // can *change* between read CB AFs. Since only one Read AF is produced 
410         // per CB read, this is a "data collision", i.e. can't have more than 
411         // one set of CB AF parameters in Read AF.
412         //
413         // Currently applying parameters from earliest read CB AF to Read Af.
414         // This can result in delay (or skip) w.r.t. application of additional 
415         // CB AF parameters not used for creating Read AF. This is reasonable 
416         // given there's no way to "interpolate" AF parameters, e.g. how to 
417         // interpolation change in in bit-stream metadata type, or CC stream?
418         //
419         
420         // Get pointer to current CB Audio Frame
421         pAfCb = &pCb->afCb[pCb->afRdIdx];
423         // Cache invalidate CB AF
424         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
425         Cache_wait();
426         
427         // Read CB AF information updated by decoder
428         pAfRd->sampleDecode = pAfCb->sampleDecode;
429         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
430         pAfRd->sampleRate = pAfCb->sampleRate;
431         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
432         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
433         // Read CB AF bit-stream metadata information updated by decoder
434         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if private metadata is attached. */
435         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
436         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
437         //Following parameters are used in DTSX
438         pAfRd->mode = pAfCb->mode;                                       /* mode is used in DTSX to pass info to PARMA */
439         pAfRd->numChansUsedForMetadata = pAfCb->numChansUsedForMetadata; /* if metadata is used in DTSX */
440         pAfRd->pafBsFixedData = pAfCb->pafBsFixedData;                   /* if true, do not convert float to fixed in DTSX metadata transfer */
441         pAfRd->root = pAfCb->root;                                       /* used for channel MASK in DTSX. BAD IDEA, need fix */
442         pAfRd->resetCount = pAfCb->resetCount;                           /* used for communication between DTSX and PARMA */
444         // Compute stream mask for current CB AF.
445         // Mask indicates which channels are present in AF.
446         // Mask needed for cache invalidate and read of PCM samples in AF.
447         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
449         // Cache invalidate CB AF samsiz (volume scaling exponent) array
450         Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
451         Cache_wait();
452         
453                 if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
454                 {
455                         //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
456                         for (i = 0; i < pAfCb->data.nChannels; i++)
457                         { 
458                            pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
459                         }
460                 }
461                 else
462                 {
463                         // Read CB AF samsiz array
464                         for (i = 0; i < pCb->maxAFChanNum; i++)
465                         {
466                                 if ((streamMask >> i) & 0x1)
467                                 {
468                                         pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
469                                 }
470                         }
471                 }
472         
473         // FL: This brute force approach to clearing metadata isn't 
474         //     necessary if decoders properly set, and downstream 
475         //     components properly use, number of private metadata
476         //     in audio frame
477         // Reset Read AF metadata
478         for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
479         {
480             pAfRd->pafPrivateMetadata[i].offset = 0;
481             pAfRd->pafPrivateMetadata[i].size   = 0;
482         }
483         
484         totNumSampsRd = 0;  // init total number of samples read from CB
485         pcmWrtIdx = 0;      // init Read AF PCM write index
486         prvMdWrtIdx = 0;    // init Read AF metadata write index
487         while ((totNumSampsRd < pCb->strFrameLen) && (pCb->numAfCb > 0))
488         {
489             // Compute how many PCM samples can be read from CB AF
490             //  Number of samples left in current CB AF: pAfCb->sampleCount - pCb->pcmRdIdx
491             //  Number of samples left to write to Read AF: pCb->strFrameLen - totNumSampsRd
492             numSampsRd = (pAfCb->sampleCount - pCb->pcmRdIdx) < (pCb->strFrameLen - totNumSampsRd) ? 
493                 (pAfCb->sampleCount - pCb->pcmRdIdx) : (pCb->strFrameLen - totNumSampsRd);
495             // Cache invalidate CB AF PCM sample channel pointers
496             Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
497             Cache_wait();
499             // Cache invalidate CB AF PCM samples
500                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
501                         {
502                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
503                                 for (i = 0; i < pAfCb->data.nChannels; i++)
504                                 { 
505                                         Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], numSampsRd*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
506                                 }
507                         }
508                         else
509                         {
510                                 for (i = 0; i < pCb->maxAFChanNum; i++)
511                                 {
512                                         if ((streamMask >> i) & 0x1)
513                                         {
514                                                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], numSampsRd*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
515                                         }
516                                 }
517                         }
518             Cache_wait();
520             // Read PCM samples from CB AF
521                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
522                         {
523                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
524                                 for (i = 0; i < pAfCb->data.nChannels; i++)
525                                 { 
526                                         for (j = 0; j < numSampsRd; j++)
527                                         {
528                                                 pAfRd->data.sample[i][pcmWrtIdx+j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
529                                         }
530                                 }
531                         }
532                         else
533                         {
534                                 for (i = 0; i < pCb->maxAFChanNum; i++)
535                                 {
536                                         if ((streamMask >> i) & 0x1)
537                                         {
538                                                 for (j = 0; j < numSampsRd; j++)
539                                                 {
540                                                         pAfRd->data.sample[i][pcmWrtIdx+j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
541                                                 }
542                                         }
543                                 }
544                         }
545             // Cache invalidate CB AF unused metadata
546             for (i = pCb->prvMdRdIdx; i < pAfCb->numPrivateMetadata; i++)
547             {
548                 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
549             }
550             Cache_wait();
552             // Read CB AF metadata
553             while (((pCb->prvMdRdIdx < pAfCb->numPrivateMetadata) && 
554                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset >= pCb->pcmRdIdx) &&
555                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset < (pCb->pcmRdIdx + numSampsRd)) &&
556                 (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size)) &&
557                 (prvMdWrtIdx < PAF_MAX_NUM_PRIVATE_MD))
558             {
559                 // Write Read AF metadata offset.
560                 //  Compute relative offset of PCM samples being read from CB AF.
561                 //  Compute absolute offset of PCM samples written to Read AF by 
562                 //  adding relative offset to Read AF PCM write index.
563                 pAfRd->pafPrivateMetadata[prvMdWrtIdx].offset = 
564                     (pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].offset - pCb->pcmRdIdx) +   // offset relative to samples being read from CB AF
565                     pcmWrtIdx;                                                              // absolute offset into samples being written to read AF
566                 // Write Read AF metadata size    
567                 pAfRd->pafPrivateMetadata[prvMdWrtIdx].size = pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size;
568                 // Write Read AF metadata payload
569                 memcpy(pAfRd->pafPrivateMetadata[prvMdWrtIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].pMdBuf, pAfCb->pafPrivateMetadata[pCb->prvMdRdIdx].size);
570                 
571                 pCb->prvMdRdIdx++;  // update CB metadata read index
572                 prvMdWrtIdx++;      // update CB metadata write index
573             }
574             
575             // Update CB control
576             pCb->pcmRdIdx += numSampsRd; // update PCM read index
577             if (pCb->pcmRdIdx >= pAfCb->sampleCount) 
578             {
579                 // Finished reading PCM samples from current CB AF.
580                 // Move to next AF in CB.
581                 
582                 // Update audio frame read index.
583                 // Wrap index if required.
584                 pCb->afRdIdx++;
585                 if (pCb->afRdIdx >= pCb->maxNumAfCb)
586                 {
587                     pCb->afRdIdx = 0;
588                 }
589                 
590                 // Reset PCM read index
591                 pCb->pcmRdIdx = 0;
592                 // Reset metadata read index
593                 pCb->prvMdRdIdx = 0;
594                 
595                 // Update number of audio frames in circular buffer
596                 pCb->numAfCb--;
597             }
598             
599             // Update PCM write index
600             pcmWrtIdx += numSampsRd;
602             // Update total number of samples read
603             totNumSampsRd += numSampsRd;
604             
605             if (totNumSampsRd < pCb->strFrameLen)
606             {
607                 //
608                 // Need to read another AF from CB to obtain all PCM/metadata for Read AF
609                 //
610                 
611                 // Get pointer to current CB Audio Frame
612                 pAfCb = &pCb->afCb[pCb->afRdIdx];
613                 
614                 // Cache invalidate CB AF
615                 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
616                 Cache_wait();
617             }
618         }
619        
620         pAfRd->sampleCount = totNumSampsRd;         // write Read AF sample count
621         pAfRd->numPrivateMetadata = prvMdWrtIdx;    // write Read AF number of metadata
622         
623         pCb->numPcmSampsPerCh -= totNumSampsRd;     // update PCM samples per channel
624        
625         if (totNumSampsRd < pCb->strFrameLen)
626         {
627             // Clear remaining Read AF PCM samples
628                         if (pAfRd->bsMetadata_type == PAF_bsMetadata_DTS_X)
629                         {
630                                 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
631                                 for (i = 0; i < pAfCb->data.nChannels; i++)
632                                 { 
633                                         memset(&pAfRd->data.sample[i][pcmWrtIdx], 0, (pCb->strFrameLen-totNumSampsRd));
634                                 }
635                         }
636                         else{
637                                 for (i = 0; i < pCb->maxAFChanNum; i++)
638                                 {
639                                         if ((streamMask >> i) & 0x1)
640                                         {
641                                                 memset(&pAfRd->data.sample[i][pcmWrtIdx], 0, (pCb->strFrameLen-totNumSampsRd));
642                                         }
643                                 }
644                         }        
645             if (pCb->writerActiveFlag == 1)
646             {
647                 //
648                 // UNDerflow, 
649                 // read stopped due to insufficient PCM samples in CB to fill Read AF
650                 //
651             
652                 // 
653                 // Increment underflow count
654                 //
655                 pCb->errPcmUndCnt++;
657                 // Mute output on underflow
658                 cbReadMuteWithLastAfInfo(pCb, pAfRd);
659                 
660 #if 0 // debug // also for CB_RW_OP_CAP_PP 
661                 // Shows timing of CB underflow
662                 // ADC B9
663                 {
664                     static Uint8 toggleState = 0;
665                     if (toggleState == 0)
666                         GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
667                     else
668                         GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
669                     toggleState = ~(toggleState);
670                 }
671 #endif
673                 #ifdef CB_RW_OP_CAP_PP // debug
674                 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
675                 {
676                     if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
677                     {
678                         // log sample count
679                         pCb->cb_samples_op[pCb->cb_opCnt] = 0;  // due to underflow
680                         pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
681                         // log idxs
682                         pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
683                         pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
684                         pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
685                         pCb->cb_opCnt++;
686                     }
687                 }
688                 #endif
690                 // Write back circular buffer configuration.
691                 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
692                 Cache_wait();    
693                 
694                 // Leave the gate
695                 GateMP_leave(gateHandle, key);
696                 
697                 return ASP_DECOP_CB_PCM_READ_UNDERFLOW;
698             }
699         }
700         
701         // Read AF complete, update Last CB AF Info
702         cbUpdateLastAfInfo(pCb, pAfRd);
704 #if 0 // debug // also for CB_RW_OP_CAP_PP 
705         // Shows timing of successful CB read
706         // ADC B8
707         {
708             static Uint8 toggleState = 0;
709             if (toggleState == 0)
710                 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
711             else
712                 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
713             toggleState = ~(toggleState);
714         }
715 #endif
717 #ifdef CB_RW_OP_CAP_PP // debug
718         if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
719         {
720             if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
721             {
722                 // log sample count
723                 pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
724                 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
725                 // log idxs
726                 pCb->cb_afRdIdx[pCb->cb_opCnt] = (pCb->pcmRdIdx == 0) ? (pCb->afRdIdx-1) : (pCb->afRdIdx);
727                 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
728                 pCb->cb_numAfCb[pCb->cb_opCnt] = (pCb->pcmRdIdx == 0) ? (pCb->numAfCb+1) : (pCb->numAfCb); // numAfCb might not be pointing to this instance
729                 pCb->cb_opCnt++;
730             }
731         }
732 #endif
733     }
734     
735     // Write back circular buffer configuration.
736     // NOTE: Probably only a subset of this information needs to be updated.
737     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
738     Cache_wait();    
739         
740     // Leave the gate
741     GateMP_leave(gateHandle, key);
743     return ASP_DECOP_CB_SOK;
746 // Update last audio frame configuration info 
747 static Void cbUpdateLastAfInfo(
748     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer control
749     PAF_AudioFrame *pAfUpd      // audio frame used for update
752     // These are parameters used in cbReadMuteWithLastAfInfo()
753     pCb->lastAf.sampleDecode = pAfUpd->sampleDecode;
754     pCb->lastAf.sampleRate = pAfUpd->sampleRate;
755     pCb->lastAf.channelConfigurationRequest.full = pAfUpd->channelConfigurationRequest.full;
756     pCb->lastAf.channelConfigurationStream.full = pAfUpd->channelConfigurationStream.full;
759 // Generate mute AF on circular buffer read using the last AF configuration info 
760 static Void cbReadMuteWithLastAfInfo(
761     PAF_AST_DecOpCircBuf *pCb,    // decoder output circular buffer control
762     PAF_AudioFrame *pAfRd         // audio frame into which to read
765     PAF_ChannelMask_HD streamMask;
766     Int8 i;
768     pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
769     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
770     pAfRd->sampleRate  = pCb->lastAf.sampleRate;
771     pAfRd->sampleCount = pCb->strFrameLen;
772     pAfRd->channelConfigurationRequest.full     = pCb->lastAf.channelConfigurationRequest.full;
773     pAfRd->channelConfigurationStream.full      = pCb->lastAf.channelConfigurationStream.full;
774     
775     // compute stream mask
776     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
777     // Clear PCM data
778     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
779     {
780         if ((streamMask >> i) & 0x1)
781                 {
782             memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
783         }
784         pAfRd->data.samsiz[i] = 0;
785     }
786     pAfRd->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
787     pAfRd->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
788     pAfRd->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
789     pAfRd->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
790     //Following parameters are used in DTSX
791         pAfRd->mode = 0;                                            /* mode used by PARMA */
792         pAfRd->numChansUsedForMetadata = 15;                        /* constant of 15 */
793         pAfRd->pafBsFixedData = TRUE;                               /* if true, do not convert float to fixed in DTSX metadata transfer */
794         pAfRd->root = 0x1BF;                                        /* used for channel MASK in DTSX. 0x1BF = 7.1 as defined in dtshd_dec_api_common.h */
795     pAfRd->resetCount = 0;                                      /* used for communication between DTSX and PARMA */
798 // Check circular buffer drain state
799 Int cbCheckDrainState(
800     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
801     Int8 cbIdx,                         // decoder output circular buffer index, or indicator combined drain state desired
802     Int8 *pDrainedFlag                  // output drain state indicator (combined or for selected circular buffer)
805     IArg key;
806     GateMP_Handle gateHandle;
807     PAF_AST_DecOpCircBuf *pCb;
808     Int8 drainedFlag;
809     Int8 i;
810     
811     // Get gate handle
812     gateHandle = pCbCtl->gateHandle;
813     // Enter gate
814     key = GateMP_enter(gateHandle);
816     if (cbIdx != ASP_DECOP_CHECK_DRAINSTATE_ALL)
817     {
818         //
819         // Check drain state for selected circular buffer
820         //
821         
822         // Get circular buffer base pointer
823         pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
825         // Invalidate circular buffer configuration
826         Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
827         Cache_wait();
829         drainedFlag = !pCb->writerActiveFlag && !pCb->drainFlag;
830     }
831     else
832     {
833         //
834         // Check combined drain state for all circular buffers.
835         // Combined drain state is logical AND of drain state for all circular buffers.
836         //
838         drainedFlag = 1; // init combined drained flag to TRUE
839         for (i = 0; i < pCbCtl->numDecOpCb; i++)
840         {
841             // Get circular buffer base pointer
842             pCb = &((*pCbCtl->pXDecOpCb)[i]);
844             // Invalidate circular buffer configuration
845             Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
846             Cache_wait();
847             
848             // Update combined drain state
849             drainedFlag = drainedFlag && (!pCb->writerActiveFlag && !pCb->drainFlag);
850         }
851     }
852     
853     *pDrainedFlag = drainedFlag;
854     
855     // Leave the gate
856     GateMP_leave(gateHandle, key);
858     return ASP_DECOP_CB_SOK;