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