7a80156fa85a29a7dac4066619ee2ccfbe28d8c5
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 if (sourceSelect == PAF_SOURCE_PCM)
145 {
146 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
148 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
149 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
151 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
152 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
153 pCb->pcmRdIdx = 0;
154 pCb->prvMdRdIdx = 0;
156 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
157 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
158 }
159 else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
160 {
161 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
163 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
164 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_DDP;
166 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
167 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
168 pCb->pcmRdIdx = 0;
169 pCb->prvMdRdIdx = 0;
171 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
172 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
173 }
174 else if (sourceSelect == PAF_SOURCE_THD)
175 {
176 //gCbInitSourceSelThdCnt++; //debug
178 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
180 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
181 // FL: (***) set nominal delay per sampling rate -- need to review these settings
182 switch (pDecInitAf->sampleRate)
183 {
184 case PAF_SAMPLERATE_44100HZ:
185 case PAF_SAMPLERATE_48000HZ:
186 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
187 break;
188 case PAF_SAMPLERATE_88200HZ:
189 case PAF_SAMPLERATE_96000HZ:
190 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_96kTHD;
191 break;
192 case PAF_SAMPLERATE_176400HZ:
193 case PAF_SAMPLERATE_192000HZ:
194 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_192kTHD;
195 break;
196 default:
197 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
198 break;
199 }
201 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
202 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
203 pCb->pcmRdIdx = 0;
204 pCb->prvMdRdIdx = 0;
206 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
207 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
208 }
209 else
210 {
211 //
212 // Currently unsupported source select
213 //
215 SW_BREAKPOINT; // debug
217 // Leave the gate
218 GateMP_leave(gateHandle, key);
220 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
221 }
223 // Initialize audio frames
224 for (n = 0; n < pCb->maxNumAfCb; n++)
225 {
226 pAfCb = &pCb->afCb[n]; // get pointer to CB AF
228 // Dec init AF sample count not correct for CB AFs.
229 // Dec Op frame length is computed in framework based on selected source.
230 pAfCb->sampleCount = decOpFrameLen;
232 // initialize CB AF using Dec init AF
233 pAfCb->sampleDecode = pDecInitAf->sampleDecode;
234 PAF_PROCESS_COPY(pAfCb->sampleProcess, pDecInitAf->sampleProcess);
235 pAfCb->sampleRate = pDecInitAf->sampleRate;
236 pAfCb->channelConfigurationRequest.full = pDecInitAf->channelConfigurationRequest.full;
237 pAfCb->channelConfigurationStream.full = pDecInitAf->channelConfigurationStream.full;
239 // initialize metadata information updated by decoder
240 pAfCb->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
241 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
242 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
243 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
244 }
246 // Initialize circular buffer current number of frames
247 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
249 // Initialize audio frame PCM buffers
250 pPcmBuf = pCb->pcmBuf;
251 pMetaBuf = pCb->metaBuf;
252 for (n=0; n<pCb->maxNumAfCb; n++)
253 {
254 pAfCb = &pCb->afCb[n]; // get pointer to CB AF
256 pAfCb->data.nChannels = pCb->maxAFChanNum;
257 pAfCb->data.nSamples = decOpFrameLen;
258 for (i=0; i<pCb->maxAFChanNum; i++)
259 {
260 pAfCb->data.sample[i] = pPcmBuf;
261 memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
262 pPcmBuf += pCb->maxAFSampCount;
264 pAfCb->data.samsiz[i] = 0;
265 }
267 // Initialize metadata buffers
268 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
269 {
270 pAfCb->pafPrivateMetadata[i].offset = 0;
271 pAfCb->pafPrivateMetadata[i].size = 0;
272 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
273 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
274 }
275 }
277 // Initialize last audio frame configuration info
278 cbInitLastAfInfo(pCb, pDecInitAf);
280 // Reset read/write flags
281 if (resetRwFlags != 0)
282 {
283 pCb->writerActiveFlag = 0;
284 pCb->readerActiveFlag = 0;
285 pCb->drainFlag = 0;
286 }
288 // Reset stats
289 pCb->readAfWriterInactiveCnt = 0;
290 pCb->readAfNdCnt = 0;
291 pCb->wrtAfReaderInactiveCnt = 0;
292 pCb->wrtAfZeroSampsCnt = 0;
293 pCb->errUndCnt = 0;
294 pCb->errOvrCnt = 0;
296 // Write back circular buffer configuration
297 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
298 // Write back AF circular buffer
299 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
300 // Write back PCM data
301 for (n=0; n<pCb->maxNumAfCb; n++)
302 {
303 pAfCb = &pCb->afCb[n];
304 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
305 Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
306 for (i=0; i<pCb->maxAFChanNum; i++)
307 {
308 Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
309 }
310 }
311 Cache_wait();
313 // Leave the gate
314 GateMP_leave(gateHandle, key);
316 return ASP_DECOP_CB_SOK;
317 }
319 //Int8 gCbWriteStartCnt=0; // debug
321 // Start writes to circular buffer
322 Int cbWriteStart(
323 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
324 Int8 cbIdx // decoder output circular buffer index
325 )
326 {
327 IArg key;
328 GateMP_Handle gateHandle;
329 PAF_AST_DecOpCircBuf *pCb;
330 PAF_AudioFrame *pAfCb;
331 Int8 n;
332 //Int8 i;
334 //gCbWriteStartCnt++; // debug
336 // Get gate handle
337 gateHandle = pCbCtl->gateHandle;
338 // Enter gate
339 key = GateMP_enter(gateHandle);
341 // Get circular buffer base pointer
342 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
344 // Invalidate circular buffer configuration.
345 // NOTE: Probably only a subset of this information needs to be updated.
346 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
347 Cache_wait();
349 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
351 // Invalidate AF circular buffer
352 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
353 for (n=0; n<pCb->maxNumAfCb; n++)
354 {
355 pAfCb = &pCb->afCb[n];
356 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
357 }
358 Cache_wait();
360 // update flags
361 pCb->writerActiveFlag = 1;
362 pCb->drainFlag = 0;
363 //pCb->afLagIdx = 0;
365 // Write back circular buffer configuration
366 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
367 Cache_wait();
369 // Leave the gate
370 GateMP_leave(gateHandle, key);
372 return ASP_DECOP_CB_SOK;
373 };
375 // Stop writes to circular buffer
376 Int cbWriteStop(
377 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
378 Int8 cbIdx // decoder output circular buffer index
379 )
380 {
381 IArg key;
382 GateMP_Handle gateHandle;
383 PAF_AST_DecOpCircBuf *pCb;
385 // Get gate handle
386 gateHandle = pCbCtl->gateHandle;
387 // Enter gate
388 key = GateMP_enter(gateHandle);
390 // Get circular buffer base pointer
391 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
393 // Invalidate circular buffer configuration
394 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
395 Cache_wait();
397 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
399 // update flags
400 pCb->writerActiveFlag = 0;
401 pCb->drainFlag = 1;
403 // Write back circular buffer configuration
404 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
405 Cache_wait();
407 // Leave the gate
408 GateMP_leave(gateHandle, key);
410 return ASP_DECOP_CB_SOK;
411 }
413 // debug
414 //Int16 gSampleCountBuf[10];
415 //Int16 gCalcDeltaSampsBuf[10];
416 //Int8 gPrimedFlagCnt=0;
418 // (***) FL: revisit
419 // Write audio frame to circular buffer
420 Int cbWriteAf(
421 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
422 Int8 cbIdx, // decoder output circular buffer index
423 PAF_AudioFrame *pAfWrt // audio frame from which to write
424 )
425 {
426 IArg key;
427 GateMP_Handle gateHandle;
428 PAF_AST_DecOpCircBuf *pCb;
429 PAF_AudioFrame *pAfCb;
430 PAF_ChannelMask_HD streamMask;
431 Int8 i;
432 Int16 j;
433 PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
435 // Get gate handle
436 gateHandle = pCbCtl->gateHandle;
437 // Enter gate
438 key = GateMP_enter(gateHandle);
440 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
442 // Get circular buffer base pointer
443 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
444 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
446 // Invalidate circular buffer configuration.
447 // NOTE: Probably only a subset of this information needs to be updated.
448 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
449 Cache_wait();
451 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
452 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
454 //if (pCb->readerActiveFlag == 1)
455 //{
456 // //
457 // // Normal case, reader active.
458 // //
460 if (pAfWrt->sampleCount != 0)
461 {
462 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
464 // check overflow
465 //while (pCb->numAfCb >= pCb->maxNumAfCb); // debug
466 if (pCb->numAfCb >= pCb->maxNumAfCb)
467 {
468 pCb->errOvrCnt++;
470 //SW_BREAKPOINT;
471 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
473 // Write back circular buffer configuration
474 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
475 Cache_wait();
477 // Leave the gate
478 GateMP_leave(gateHandle, key);
480 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
482 return ASP_DECOP_CB_WRITE_OVERFLOW;
483 }
485 pAfCb = &pCb->afCb[pCb->afWrtIdx];
486 pPcmBuf = pAfCb->data.sample[0];
487 pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
488 if ((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum)) >= (pCb->pcmBufEnd))
489 {
490 pPcmBuf = pCb->pcmBuf;
491 }
493 for (i=0; i<pCb->maxAFChanNum; i++)
494 {
495 pAfCb->data.sample[i] = pPcmBuf;
496 pPcmBuf += pAfWrt->sampleCount;
497 pAfCb->data.samsiz[i] = 0;
498 }
499 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
500 Cache_wait();
502 //for (i=0; i<pCb->maxAFChanNum; i++){
503 //}
504 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
505 {
506 pAfCb->pafPrivateMetadata[i].offset = 0;
507 pAfCb->pafPrivateMetadata[i].size = 0;
508 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
509 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
510 }
512 nextWrtIdx = 0;
513 if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
514 {
515 //Log_info0("cbWriteAf: AF Wrap around **** ");
516 // next audio frame will be audio frame 0
517 nextWrtIdx = 0;
518 }
519 else
520 {
521 // next audio frame will be current audio frame + 1
522 nextWrtIdx = pCb->afWrtIdx + 1;
523 }
525 pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
526 pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
528 // write audio frame information updated by decoder
529 pAfCb->sampleDecode = pAfWrt->sampleDecode;
530 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
531 pAfCb->sampleRate = pAfWrt->sampleRate;
532 pAfCb->sampleCount = pAfWrt->sampleCount;
533 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
534 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
535 // write metadata information updated by decoder
536 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
537 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
538 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
539 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
540 // write PCM samples
541 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
542 for (i = 0; i < pCb->maxAFChanNum; i++)
543 {
544 if ((streamMask >> i) & 0x1)
545 {
546 for (j = 0; j < pAfWrt->sampleCount; j++)
547 {
548 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
549 }
551 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
552 }
553 }
555 #ifdef CB_RW_OP_CAP_PP // debug
556 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
557 {
558 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
559 {
560 // log sample count
561 pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
562 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
563 // log idxs
564 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
565 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
566 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
567 pCb->cb_opCnt++;
568 }
569 }
570 #endif
572 // prepare metadata buffer pointers according to the metadata and buffer sizes
573 for (i=0; i < pAfWrt->numPrivateMetadata; i++)
574 {
575 UInt8 *nextMdBuf;
576 if(i == 0)
577 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
578 else
579 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
580 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
581 {
582 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
583 }
584 else if(i != 0)
585 {
586 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
587 }
588 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
589 }
591 // Write metadata to circular buffer
592 for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
593 {
594 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
595 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
596 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
597 }
599 Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
600 Cache_wait();
601 for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
602 {
603 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
604 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
605 }
606 // update audio frame write index
607 pCb->afWrtIdx++;
608 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
609 {
610 pCb->afWrtIdx = 0;
611 }
613 pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
614 if(pAfWrt->numPrivateMetadata > 0)
615 {
616 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
617 }
618 else
619 {
620 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
621 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
622 Cache_wait();
623 }
624 Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
625 Cache_wait();
626 // update number of audio frames in circular buffer
627 pCb->numAfCb++;
629 // Update CB Lag index
630 //if (pCb->afLagIdx < pCb->afInitialLag)
631 //{
632 // pCb->afLagIdx += 1;
633 //}
635 // Update CB primed flag
636 // calculate number of delta samples before allowing CB read
637 if (pCb->primedFlag == 0)
638 {
639 pCb->primedFlag = 1;
641 // Calculate number of output frames to block reader.
642 // This is sample count reader waits before allowed to actually read samples from the CB.
643 //pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
644 // FL: CB read decrements by strFrameLen and tests for >0, so rounding to strFrameLen is unnecessary
645 pCb->deltaSamps = pCb->targetNDSamps - pAfWrt->sampleCount;
647 // debug
648 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
649 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
650 //if (gPrimedFlagCnt < 10)
651 // gPrimedFlagCnt++;
652 }
654 // Write back circular buffer configuration
655 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
656 // write back audio frame
657 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
658 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
659 Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
660 Cache_wait();
661 // write back PCM data
662 for (i = 0; i < pCb->maxAFChanNum; i++)
663 {
664 if ((streamMask >> i) & 0x1)
665 {
666 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
667 }
668 }
669 Cache_wait();
671 #if 0 // (***) FL: shows timing of CB write
672 // debug
673 {
674 static Uint8 toggleState = 0;
675 if (toggleState == 0)
676 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
677 else
678 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
679 toggleState = ~(toggleState);
680 }
681 #endif
683 Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
684 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);
685 }
686 else
687 {
688 //
689 // Skip write in case of 0 sample count
690 //
692 // writing audio frame w/ zero samples
693 // update stat
694 pCb->wrtAfZeroSampsCnt++;
696 // Write back circular buffer configuration
697 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
698 Cache_wait();
699 }
700 //}
701 //else if (pCb->readerActiveFlag == 0)
702 if (pCb->readerActiveFlag == 0)
703 {
704 //
705 // Reader inactive, don't write to circular buffer or check OVRflow.
706 //
708 // writing AF w/ inactive reader
709 // update stat
710 pCb->wrtAfReaderInactiveCnt++;
712 // Write back circular buffer configuration
713 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
714 Cache_wait();
715 }
717 // Leave the gate
718 GateMP_leave(gateHandle, key);
720 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
722 return ASP_DECOP_CB_SOK;
723 }
725 #if 0
726 // Get next audio frame to write in circular buffer
727 Int cbGetNextWriteAf(
728 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
729 Int8 cbIdx, // decoder output circular buffer index
730 PAF_AudioFrame **ppAfWrt // audio frame next to be written
731 )
732 {
733 IArg key;
734 GateMP_Handle gateHandle;
735 PAF_AST_DecOpCircBuf *pCb;
737 // Get gate handle
738 gateHandle = pCbCtl->gateHandle;
739 // Enter gate
740 key = GateMP_enter(gateHandle);
742 // Get circular buffer base pointer
743 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
745 // get pointer to current audio frame in circular buffer
746 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
748 // update audio frame write index
749 pCb->afWrtIdx++;
750 if (pCb->afWrtIdx > pCb->maxNumAfCb)
751 {
752 pCb->afWrtIdx = 0;
753 }
755 // Leave the gate
756 GateMP_leave(gateHandle, key);
758 return ASP_DECOP_CB_SOK;
759 }
760 #endif
762 // Init last audio frame configuration info
763 static Void cbInitLastAfInfo(
764 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
765 PAF_AudioFrame *pAfInit // audio frame used for init
766 )
767 {
768 memset(&pCb->lastAf, 0, sizeof(PAF_AudioFrame));
770 pCb->lastAf.sampleDecode = pAfInit->sampleDecode;
771 pCb->lastAf.sampleRate = pAfInit->sampleRate;
772 pCb->lastAf.channelConfigurationRequest.full = pAfInit->channelConfigurationRequest.full;
773 pCb->lastAf.channelConfigurationStream.full = pAfInit->channelConfigurationStream.full;
774 }