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;
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 }
80 pCbCtl->numCb = numCb; // init number of circular buffers
81 pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
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 )
100 {
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
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]);
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;
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;
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;
149 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
150 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
152 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
153 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
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;
179 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
180 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
182 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
183 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
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
194 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
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 }
217 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
218 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
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 //
289 SW_BREAKPOINT; // debug
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
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;
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 }
328 // Initialize circular buffer current number of frames
329 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
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
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;
346 pAfCb->data.samsiz[i] = 0;
347 }
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 }
359 // Initialize last audio frame configuration info
360 cbInitLastAfInfo(pCb, pDecInitAf);
362 // Reset read/write flags
363 if (resetRwFlags != 0)
364 {
365 pCb->writerActiveFlag = 0;
366 pCb->readerActiveFlag = 0;
367 pCb->drainFlag = 0;
368 }
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;
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);
400 return ASP_DECOP_CB_SOK;
401 }
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
409 )
410 {
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
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();
433 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
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();
444 // update flags
445 pCb->writerActiveFlag = 1;
446 pCb->drainFlag = 0;
447 //pCb->afLagIdx = 0;
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
463 )
464 {
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
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();
491 // Leave the gate
492 GateMP_leave(gateHandle, key);
494 return ASP_DECOP_CB_SOK;
495 }
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
512 )
513 {
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;
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 // //
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 }
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
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
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
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 }
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
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 }
660 if (pcmOvr == 1)
661 {
662 Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d",
663 pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
665 //SW_BREAKPOINT; // debug
667 // Write back circular buffer configuration
668 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
669 Cache_wait();
671 // Leave the gate
672 GateMP_leave(gateHandle, key);
674 return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
675 }
676 }
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 }
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 }
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
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 */
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;
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++;
857 // Update CB Lag index
858 //if (pCb->afLagIdx < pCb->afInitialLag)
859 //{
860 // pCb->afLagIdx += 1;
861 //}
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;
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;
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 }
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 //
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 //
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;
967 }
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
975 )
976 {
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];
992 // update audio frame write index
993 pCb->afWrtIdx++;
994 if (pCb->afWrtIdx > pCb->maxNumAfCb)
995 {
996 pCb->afWrtIdx = 0;
997 }
999 // Leave the gate
1000 GateMP_leave(gateHandle, key);
1002 return ASP_DECOP_CB_SOK;
1003 }
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
1010 )
1011 {
1012 memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
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;
1018 }