8cb8467ba6fd3e2fe2616bd41b24df875d4c0e30
2 /*
3 Copyright (c) 2018, 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 // debug
58 //Int8 gCbInitDecWriteCnt=0;
60 /// Initialize circular buffer for Decoder writes
61 Int cbInitDecWrite(
62 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
63 Int8 cbIdx, // decoder output circular buffer index
64 Int8 sourceSelect, // source select (PCM, DDP, etc.)
65 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
66 Int8 resetRwFlags, // whether to reset reader, writer, and drain flags
67 PAF_AudioFrame *pDecInitAf // pointer to Dec output audio frame used for CB initialization
68 )
69 {
70 IArg key;
71 GateMP_Handle gateHandle;
72 PAF_AST_DecOpCircBuf *pCb;
73 PAF_AudioFrame *pAfCb;
74 PAF_AudioData *pPcmBuf;
75 UInt8 *pMetaBuf;
76 Int8 n;
77 Int8 i;
79 //gCbInitDecWriteCnt++; // debug
81 // Get gate handle
82 gateHandle = pCbCtl->gateHandle;
83 // Enter gate
84 key = GateMP_enter(gateHandle);
86 // Get circular buffer base pointer
87 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
89 // Invalidate circular buffer configuration
90 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
91 Cache_wait();
93 //Log_info1("cbInitDecWrite:afCb=0x%04x", (IArg)pCb->afCb); // debug
95 // Set source select
96 pCb->sourceSel = sourceSelect;
98 // Set input frame length
99 pCb->decOpFrameLen = decOpFrameLen;
101 // Initialize CB primed flag
102 pCb->primedFlag = 0;
103 // Initialize delta samples
104 pCb->deltaSamps = 0;
106 // Initialize circular buffer:
107 // - maximum number of AFs
108 // - target nominal delay
109 // - AF write, read indices
110 // - maximum AF channel and sample counts
111 // - maximum number of PCM samples per channel
112 if (sourceSelect == PAF_SOURCE_PCM)
113 {
114 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
116 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
118 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
119 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
121 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
122 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
124 pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
125 }
126 else if (sourceSelect == PAF_SOURCE_AAC)
127 {
128 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_AAC;
130 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_AAC;
132 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_AAC;
133 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_AAC;
135 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_AAC;
136 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kAAC;
138 pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
139 }
140 else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
141 {
142 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
144 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
146 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
147 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
149 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
150 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
152 pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
153 }
154 else if (sourceSelect == PAF_SOURCE_THD)
155 {
156 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
158 // FL: set nominal delay per sampling rate -- these settings need to be reviewed
159 switch (pDecInitAf->sampleRate)
160 {
161 case PAF_SAMPLERATE_44100HZ:
162 case PAF_SAMPLERATE_48000HZ:
163 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
164 break;
165 case PAF_SAMPLERATE_88200HZ:
166 case PAF_SAMPLERATE_96000HZ:
167 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
168 break;
169 case PAF_SAMPLERATE_176400HZ:
170 case PAF_SAMPLERATE_192000HZ:
171 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
172 break;
173 default:
174 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
175 break;
176 }
178 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
179 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
181 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
182 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
184 pCb->maxNumPcmSampsPerCh = (Int32)(pCb->pcmBufEnd - pCb->pcmBuf)/pCb->maxAFChanNum;
185 }
186 else if ((sourceSelect == PAF_SOURCE_DTS) ||
187 (sourceSelect == PAF_SOURCE_DTSHD) ||
188 (sourceSelect == PAF_SOURCE_DTS12) ||
189 (sourceSelect == PAF_SOURCE_DTS13) ||
190 (sourceSelect == PAF_SOURCE_DTS14) ||
191 (sourceSelect == PAF_SOURCE_DTS16) ||
192 (sourceSelect == PAF_SOURCE_DTSALL)
193 )
194 {
195 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DTS;
196 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DTS;
197 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DTS;
198 pCb->pcmRdIdx = 0;
199 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DTS;
200 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDTS;
201 switch (pDecInitAf->sampleRate)
202 {
203 case PAF_SAMPLERATE_44100HZ:
204 case PAF_SAMPLERATE_48000HZ:
205 decOpFrameLen = 256;
206 break;
207 case PAF_SAMPLERATE_88200HZ:
208 case PAF_SAMPLERATE_96000HZ:
209 decOpFrameLen = (256*2);
210 break;
211 case PAF_SAMPLERATE_176400HZ:
212 case PAF_SAMPLERATE_192000HZ:
213 decOpFrameLen = (256*4);
214 break;
215 default:
216 decOpFrameLen = 256;
217 break;
218 }
220 #if 0
221 // initialize audio frames
222 for (n=0; n<pCb->maxNumAfCb; n++)
223 {
224 pAfCb = &pCb->afCb[n];
225 pAfCb->sampleDecode = sourceSelect;
226 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
227 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
228 pAfCb->sampleCount = decOpFrameLen;
229 pAfCb->channelConfigurationRequest.full = 0;
230 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
231 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
232 pAfCb->channelConfigurationStream.full = 0;
233 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
234 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
236 // write metadata information updated by decoder
237 pAfCb->bsMetadata_type = PAF_bsMetadata_DTS_X; /* Audio data from DTSX decoder. */
238 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
239 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
240 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
241 }
242 #endif
243 }
244 else
245 {
246 //
247 // Currently unsupported source select
248 //
250 SW_BREAKPOINT; // debug
252 // Leave the gate
253 GateMP_leave(gateHandle, key);
255 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
256 }
258 // Initialize circular buffer:
259 // - PCM read index
260 // - Private metadata read index
261 // - number of PCM samples in CB
262 pCb->pcmRdIdx = 0;
263 pCb->prvMdRdIdx = 0;
264 pCb->numPcmSampsPerCh = 0;
266 // Initialize audio frames
267 for (n = 0; n < pCb->maxNumAfCb; n++)
268 {
269 pAfCb = &pCb->afCb[n]; // get pointer to CB AF
271 // Dec init AF sample count not correct for CB AFs.
272 // Dec Op frame length is computed in framework based on selected source.
273 pAfCb->sampleCount = decOpFrameLen;
275 // initialize CB AF using Dec init AF
276 pAfCb->sampleDecode = pDecInitAf->sampleDecode;
277 PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
278 pAfCb->sampleRate = pDecInitAf->sampleRate;
279 pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
280 pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
282 // initialize metadata information updated by decoder
283 pAfCb->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
284 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
285 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
286 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
287 }
289 // Initialize circular buffer current number of frames
290 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
292 // Initialize audio frame PCM buffers
293 pPcmBuf = pCb->pcmBuf;
294 pMetaBuf = pCb->metaBuf;
295 for (n=0; n<pCb->maxNumAfCb; n++)
296 {
297 pAfCb = &pCb->afCb[n]; // get pointer to CB AF
299 pAfCb->data.nChannels = pCb->maxAFChanNum;
300 pAfCb->data.nSamples = decOpFrameLen;
301 for (i=0; i<pCb->maxAFChanNum; i++)
302 {
303 pAfCb->data.sample[i] = pPcmBuf;
304 memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
305 pPcmBuf += pCb->maxAFSampCount;
307 pAfCb->data.samsiz[i] = 0;
308 }
310 // Initialize metadata buffers
311 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
312 {
313 pAfCb->pafPrivateMetadata[i].offset = 0;
314 pAfCb->pafPrivateMetadata[i].size = 0;
315 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
316 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
317 }
318 }
320 // Initialize last audio frame configuration info
321 cbInitLastAfInfo(pCb, pDecInitAf);
323 // Reset read/write flags
324 if (resetRwFlags != 0)
325 {
326 pCb->writerActiveFlag = 0;
327 pCb->readerActiveFlag = 0;
328 pCb->drainFlag = 0;
329 }
331 // Reset stats
332 pCb->readAfWriterInactiveCnt = 0;
333 pCb->readAfNdCnt = 0;
334 pCb->wrtAfReaderInactiveCnt = 0;
335 pCb->wrtAfZeroSampsCnt = 0;
336 pCb->errAfUndCnt = 0;
337 pCb->errAfOvrCnt = 0;
338 pCb->errPcmUndCnt = 0;
339 pCb->errPcmOvrCnt = 0;
341 // Write back circular buffer configuration
342 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
343 // Write back AF circular buffer
344 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
345 // Write back PCM data
346 for (n=0; n<pCb->maxNumAfCb; n++)
347 {
348 pAfCb = &pCb->afCb[n];
349 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
350 Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
351 for (i=0; i<pCb->maxAFChanNum; i++)
352 {
353 Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
354 }
355 }
356 Cache_wait();
358 // Leave the gate
359 GateMP_leave(gateHandle, key);
361 return ASP_DECOP_CB_SOK;
362 }
364 //Int8 gCbWriteStartCnt=0; // debug
366 // Start writes to circular buffer
367 Int cbWriteStart(
368 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
369 Int8 cbIdx // decoder output circular buffer index
370 )
371 {
372 IArg key;
373 GateMP_Handle gateHandle;
374 PAF_AST_DecOpCircBuf *pCb;
375 PAF_AudioFrame *pAfCb;
376 Int8 n;
377 //Int8 i;
379 //gCbWriteStartCnt++; // debug
381 // Get gate handle
382 gateHandle = pCbCtl->gateHandle;
383 // Enter gate
384 key = GateMP_enter(gateHandle);
386 // Get circular buffer base pointer
387 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
389 // Invalidate circular buffer configuration.
390 // NOTE: Probably only a subset of this information needs to be updated.
391 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
392 Cache_wait();
394 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
396 // Invalidate AF circular buffer
397 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
398 for (n=0; n<pCb->maxNumAfCb; n++)
399 {
400 pAfCb = &pCb->afCb[n];
401 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
402 }
403 Cache_wait();
405 // update flags
406 pCb->writerActiveFlag = 1;
407 pCb->drainFlag = 0;
408 //pCb->afLagIdx = 0;
410 // Write back circular buffer configuration
411 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
412 Cache_wait();
414 // Leave the gate
415 GateMP_leave(gateHandle, key);
417 return ASP_DECOP_CB_SOK;
418 };
420 // Stop writes to circular buffer
421 Int cbWriteStop(
422 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
423 Int8 cbIdx // decoder output circular buffer index
424 )
425 {
426 IArg key;
427 GateMP_Handle gateHandle;
428 PAF_AST_DecOpCircBuf *pCb;
430 // Get gate handle
431 gateHandle = pCbCtl->gateHandle;
432 // Enter gate
433 key = GateMP_enter(gateHandle);
435 // Get circular buffer base pointer
436 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
438 // Invalidate circular buffer configuration
439 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
440 Cache_wait();
442 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
444 // update flags
445 pCb->writerActiveFlag = 0;
446 pCb->drainFlag = 1;
448 // Write back circular buffer configuration
449 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
450 Cache_wait();
452 // Leave the gate
453 GateMP_leave(gateHandle, key);
455 return ASP_DECOP_CB_SOK;
456 }
458 // debug
459 //Int16 gSampleCountBuf[10];
460 //Int16 gCalcDeltaSampsBuf[10];
461 //Int8 gPrimedFlagCnt=0;
462 // debug
463 //Int32 gPcmOvershootWrap1=0;
464 //Int32 gPcmOvershootWrap2=0;
465 //Int32 gPcmOvershootNoWrap=0;
467 // Write audio frame to circular buffer
468 Int cbWriteAf(
469 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
470 Int8 cbIdx, // decoder output circular buffer index
471 PAF_AudioFrame *pAfWrt // audio frame from which to write
472 )
473 {
474 IArg key;
475 GateMP_Handle gateHandle;
476 PAF_AST_DecOpCircBuf *pCb;
477 PAF_AudioFrame *pAfCb;
478 PAF_ChannelMask_HD streamMask;
479 Int8 i;
480 Int16 j;
481 PAF_AudioData *pPcmBuf;
482 UInt8 *pMetaBuf;
483 //int nextWrtIdx;
484 //PAF_AudioFrame *pAfCbNextAf;
485 PAF_AudioFrame *pAfCbRd;
486 PAF_AudioData *pPcmBufRd, *pPcmBufWrt;
487 Int8 pcmOvr;
489 // Get gate handle
490 gateHandle = pCbCtl->gateHandle;
491 // Enter gate
492 key = GateMP_enter(gateHandle);
494 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
496 // Get circular buffer base pointer
497 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
498 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
500 // Invalidate circular buffer configuration.
501 // NOTE: Probably only a subset of this information needs to be updated.
502 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
503 Cache_wait();
505 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
506 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
508 if (pAfWrt->sampleCount != 0)
509 {
510 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
512 // check AF overflow
513 if (pCb->numAfCb >= pCb->maxNumAfCb)
514 {
515 pCb->errAfOvrCnt++;
517 //SW_BREAKPOINT;
518 Log_info1("cbWriteAf: ERROR: AF CB overflow, numAfCb=%d", pCb->numAfCb);
520 // Write back circular buffer configuration
521 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
522 Cache_wait();
524 // Leave the gate
525 GateMP_leave(gateHandle, key);
527 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
529 return ASP_DECOP_CB_AF_WRITE_OVERFLOW;
530 }
532 // get CB AF write info
533 pAfCb = &pCb->afCb[pCb->afWrtIdx]; // get CB AF to be written
534 pPcmBufWrt = pAfCb->data.sample[0]; // get current location in PCM buffer to be written
535 // currently no metadata buffer overflow detection
536 pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf; // get current location in MD buffer to be written
538 // get CB AF read info
539 pAfCbRd = &pCb->afCb[pCb->afRdIdx]; // get CB AF being read
540 pPcmBufRd = pAfCbRd->data.sample[0] + pCb->pcmRdIdx; // current location of PCM samples for AF being read
542 // Check PCM buffer overflow
543 pPcmBuf = pPcmBufWrt;
544 pcmOvr = 0;
545 for (i = 0; i < pCb->maxAFChanNum; i++)
546 {
547 //
548 // Writes of PCM to PCM CB use CC stream, but this isn't considered here.
549 // For each channel which *can* be written, check the current reader location won't be overwritten.
550 // The current reader location is the earliest channel which *could have been* written for that CB AF.
551 //
552 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
553 {
554 // this write will wrap
556 // check OVR before wrap
557 if ((pPcmBuf < pPcmBufRd) &&
558 ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
559 {
560 pCb->errPcmOvrCnt++;
561 //gPcmOvershootWrap1 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
562 pcmOvr = 1;
563 }
565 if (pcmOvr == 0)
566 {
567 // wrap pointer
568 pPcmBuf = pCb->pcmBuf;
569 // check OVR after wrap
570 if ((pPcmBuf < pPcmBufRd) &&
571 ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
572 {
573 pCb->errPcmOvrCnt++;
574 //gPcmOvershootWrap2 = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
575 pcmOvr = 1;
576 }
577 }
578 }
579 else if ((pPcmBuf < pPcmBufRd) &&
580 ((pPcmBuf + pAfWrt->sampleCount) >= pPcmBufRd))
581 {
582 // this write won't wrap
584 //gPcmOvershootNoWrap = pPcmBuf + pAfWrt->sampleCount - pPcmBufRd; // debug
585 pCb->errPcmOvrCnt++;
586 pcmOvr = 1;
587 }
588 else
589 {
590 // update pointer
591 pPcmBuf += pAfWrt->sampleCount;
592 }
594 if (pcmOvr == 1)
595 {
596 Log_info2("cbWriteAf: ERROR: PCM CB overflow, sampleCount=%d, numPcmSampsPerCh=%d",
597 pAfWrt->sampleCount, pCb->numPcmSampsPerCh);
599 //SW_BREAKPOINT; // debug
601 // Write back circular buffer configuration
602 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
603 Cache_wait();
605 // Leave the gate
606 GateMP_leave(gateHandle, key);
608 return ASP_DECOP_CB_PCM_WRITE_OVERFLOW;
609 }
610 }
612 //
613 // FL: over allocating memory for PCM CB
614 // Allocating memory for max # channels (e.g. 32 for THD).
615 // Over allocation for THD 192 kHz, 6ch max.
616 //
618 // configure AF sample pointers
619 pPcmBuf = pPcmBufWrt;
620 for (i = 0; i < pCb->maxAFChanNum; i++)
621 {
622 // check PCM buffer wrap
623 if ((pPcmBuf + pAfWrt->sampleCount) >= pCb->pcmBufEnd)
624 {
625 pPcmBuf = pCb->pcmBuf;
626 }
628 pAfCb->data.sample[i] = pPcmBuf;
629 pPcmBuf += pAfWrt->sampleCount;
630 pAfCb->data.samsiz[i] = 0;
631 }
632 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
633 Cache_wait();
635 // FL: brute force reset of all metadata in CB AF
636 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
637 {
638 pAfCb->pafPrivateMetadata[i].offset = 0;
639 pAfCb->pafPrivateMetadata[i].size = 0;
640 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
641 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
642 }
644 // write audio frame information updated by decoder
645 pAfCb->sampleDecode = pAfWrt->sampleDecode;
646 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
647 pAfCb->sampleRate = pAfWrt->sampleRate;
648 pAfCb->sampleCount = pAfWrt->sampleCount;
649 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
650 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
651 // write metadata information updated by decoder
652 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
653 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
654 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
655 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
657 pAfCb->mode = pAfWrt->mode; /* mode is used in DTSX to pass info to PARMA */
658 pAfCb->numChansUsedForMetadata = pAfWrt->numChansUsedForMetadata; /* if metadata is used in DTSX*/
659 pAfCb->pafBsFixedData = pAfWrt->pafBsFixedData; /* if true, do not convert float to fixed in DTSX metadata transfer */
660 pAfCb->root = pAfWrt->root; /* used for channel MASK in DTSX . BAD IDEA, need fix */
661 pAfCb->resetCount = pAfWrt->resetCount; /* used for communication between DTSX and PARMA */
662 pAfCb->data.nChannels = pAfWrt->data.nChannels; /* number of channels used */
663 // write PCM samples
665 if (pAfCb->bsMetadata_type == PAF_bsMetadata_DTS_X)
666 {
667 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
668 for (i = 0; i < pAfWrt->data.nChannels; i++)
669 {
670 for (j = 0; j < pAfWrt->sampleCount; j++)
671 {
672 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
673 }
675 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
676 }
677 }
678 else
679 {
680 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
681 for (i = 0; i < pCb->maxAFChanNum; i++)
682 {
684 if ((streamMask >> i) & 0x1)
685 { //DTSX needs up to 16 channels to transfer metadata.
686 for (j = 0; j < pAfWrt->sampleCount; j++)
687 {
688 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
689 }
691 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
692 }
693 }
694 }
695 // Update PCM samples per channel
696 pCb->numPcmSampsPerCh += pAfWrt->sampleCount;
698 #ifdef CB_RW_OP_CAP_PP // debug
699 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
700 {
701 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
702 {
703 // log sample count
704 pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
705 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
706 // log idxs
707 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
708 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
709 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
710 pCb->cb_opCnt++;
711 }
712 }
713 #endif
715 // prepare metadata buffer pointers according to the metadata and buffer sizes
716 for (i = 0; i < pAfWrt->numPrivateMetadata; i++)
717 {
718 UInt8 *nextMdBuf;
719 if (i == 0)
720 {
721 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
722 }
723 else
724 {
725 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
726 }
727 if (nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
728 {
729 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
730 }
731 else if (i != 0)
732 {
733 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
734 }
735 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
736 }
738 // Write metadata to circular buffer
739 for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
740 {
741 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
742 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
743 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
744 }
746 Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
747 Cache_wait();
748 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
749 {
750 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
751 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
752 }
753 // update audio frame write index
754 pCb->afWrtIdx++;
755 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
756 {
757 pCb->afWrtIdx = 0;
758 }
760 pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
761 if (pAfWrt->numPrivateMetadata > 0)
762 {
763 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
764 }
765 else
766 {
767 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
768 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
769 Cache_wait();
770 }
771 Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
772 Cache_wait();
773 // update number of audio frames in circular buffer
774 pCb->numAfCb++;
776 // Update CB primed flag.
777 // Calculate number of delta samples before allowing CB read.
778 if (pCb->primedFlag == 0)
779 {
780 pCb->primedFlag = 1;
782 // THD has variable number of AUs per frame.
783 // Some frames can be quite large (e.g. 96 AUs), and delta samples calculation small or even negative.
784 // In this case, there won't be any reader hold off, and no nominal delay in the CB.
785 pCb->deltaSamps = pCb->targetNDSamps;
787 // debug
788 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
789 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
790 //if (gPrimedFlagCnt < 10)
791 // gPrimedFlagCnt++;
792 }
794 // Update delta samples using number of write audio frame samples.
795 if (pCb->deltaSamps > 0)
796 {
797 pCb->deltaSamps = pCb->deltaSamps - pAfWrt->sampleCount;
798 }
800 // Write back circular buffer configuration
801 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
802 // write back audio frame
803 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
804 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
805 Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
806 Cache_wait();
807 // write back PCM data
808 if (pAfCb->bsMetadata_type == PAF_bsMetadata_DTS_X)
809 {
810 //DTSX needs up to 8 to 16 channels to transfer metadata depends on sampling rate.
811 for (i = 0; i < pAfWrt->data.nChannels; i++)
812 {
813 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
814 }
815 }
816 else
817 {
818 for (i = 0; i < pCb->maxAFChanNum; i++)
819 {
820 if ((streamMask >> i) & 0x1)
821 {
822 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
823 }
824 }
825 }
826 Cache_wait();
828 #if 0 // debug // also for CB_RW_OP_CAP_PP
829 // shows timing of CB write
830 // ADC B5
831 {
832 static Uint8 toggleState = 0;
833 if (toggleState == 0)
834 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
835 else
836 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
837 toggleState = ~(toggleState);
838 }
839 #endif
841 Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
842 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);
843 }
844 else
845 {
846 //
847 // Skip write in case of 0 sample count
848 //
850 // writing audio frame w/ zero samples
851 // update stat
852 pCb->wrtAfZeroSampsCnt++;
854 // Write back circular buffer configuration
855 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
856 Cache_wait();
857 }
859 if (pCb->readerActiveFlag == 0)
860 {
861 //
862 // Reader inactive, don't write to circular buffer or check OVRflow.
863 //
865 // writing AF w/ inactive reader
866 // update stat
867 pCb->wrtAfReaderInactiveCnt++;
869 // Write back circular buffer configuration
870 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
871 Cache_wait();
872 }
874 // Leave the gate
875 GateMP_leave(gateHandle, key);
877 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
879 return ASP_DECOP_CB_SOK;
880 }
882 #if 0
883 // Get next audio frame to write in circular buffer
884 Int cbGetNextWriteAf(
885 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
886 Int8 cbIdx, // decoder output circular buffer index
887 PAF_AudioFrame **ppAfWrt // audio frame next to be written
888 )
889 {
890 IArg key;
891 GateMP_Handle gateHandle;
892 PAF_AST_DecOpCircBuf *pCb;
894 // Get gate handle
895 gateHandle = pCbCtl->gateHandle;
896 // Enter gate
897 key = GateMP_enter(gateHandle);
899 // Get circular buffer base pointer
900 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
902 // get pointer to current audio frame in circular buffer
903 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
905 // update audio frame write index
906 pCb->afWrtIdx++;
907 if (pCb->afWrtIdx > pCb->maxNumAfCb)
908 {
909 pCb->afWrtIdx = 0;
910 }
912 // Leave the gate
913 GateMP_leave(gateHandle, key);
915 return ASP_DECOP_CB_SOK;
916 }
917 #endif
919 // Init last audio frame configuration info
920 static Void cbInitLastAfInfo(
921 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
922 PAF_AudioFrame *pAfInit // audio frame used for init
923 )
924 {
925 memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
927 pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
928 pCb->lastAf.sampleRate = pAfInit->sampleRate;
929 pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
930 pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;
931 }