1 #include <string.h> // for memset()
2 #include <xdc/std.h>
3 #include <ti/sysbios/hal/Cache.h>
4 #include <xdc/runtime/Log.h>
6 #include "pafdec.h"
7 #include "pafsp.h"
8 #include "paf_decOpCircBuf.h"
10 #define MAX_NUM_AF_PCM ( 4 )
11 #define MAX_NUM_AF_DDP ( 2 )
13 #define CB_INIT_RD_LAG ( 2 )
15 // Initialize circular buffer
16 Int cbInit(
17 Int8 sourceSelect, // source select (PCM, DDP, etc.)
18 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
19 Int16 strFrameLen, // stream frame length (PCM samples)
20 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
21 )
22 {
23 PAF_AudioFrame *pAfCb;
24 PAF_AudioData *pPcmBuf;
25 Int8 *pMetaBuf; //QIN
26 Int8 n;
27 Int8 i;
29 // set input frame length
30 pCb->decOpFrameLen = decOpFrameLen;
32 // set output frame length
33 pCb->strFrameLen = strFrameLen;
35 // initialize circular buffer maximum number of audio frames
36 if (sourceSelect == PAF_SOURCE_PCM)
37 {
38 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
39 pCb->afWrtIdx = CB_INIT_RD_LAG;
40 pCb->afRdIdx = 0;
41 pCb->pcmRdIdx = 0; // 2*256 in behind
43 // initialize audio frames
44 for (n=0; n<pCb->maxNumAfCb; n++)
45 {
46 pAfCb = &pCb->afCb[n];
47 pAfCb->sampleDecode = PAF_SOURCE_PCM;
48 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
49 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
50 pAfCb->sampleCount = decOpFrameLen;
51 pAfCb->channelConfigurationRequest.full = 0;
52 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
53 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
54 pAfCb->channelConfigurationStream.full = 0;
55 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
56 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
57 }
58 }
59 else if (sourceSelect == PAF_SOURCE_DDP)
60 {
61 pCb->maxNumAfCb = MAX_NUM_AF_DDP;
62 pCb->afRdIdx = 0;
63 pCb->afWrtIdx = 0;//1;//QIN - Reduce delay to prevent cb overflow. Need further investigation.
64 pCb->pcmRdIdx = 0;//decOpFrameLen - CB_INIT_RD_LAG*strFrameLen; //QIN - Reduce delay to prevent cb overflow. Need further investigation.
66 // initialize audio frames
67 for (n=0; n<pCb->maxNumAfCb; n++)
68 {
69 pAfCb = &pCb->afCb[n];
70 pAfCb->sampleDecode = PAF_SOURCE_DDP;
71 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
72 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
73 pAfCb->sampleCount = decOpFrameLen;
74 pAfCb->channelConfigurationRequest.full = 0;
75 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
76 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
77 pAfCb->channelConfigurationStream.full = 0;
78 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
79 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
80 }
81 }
82 else
83 {
84 return PAF_DECOP_CB_INIT_INV_SOURCE_SEL;
85 }
87 // initialize circular buffer current number of frames
88 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
90 // initialize audio frame PCM buffers
91 pPcmBuf = pCb->pcmBuf;
92 pMetaBuf = pCb->metaBuf; //QIN
93 for (n=0; n<pCb->maxNumAfCb; n++)
94 {
95 pAfCb = &pCb->afCb[n];
96 pAfCb->data.nChannels = PAF_DECOP_CB_MAX_NUM_PCM_CH;
97 pAfCb->data.nSamples = decOpFrameLen;
98 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
99 {
100 pAfCb->data.sample[i] = pPcmBuf;
101 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
102 pPcmBuf += decOpFrameLen;
104 pAfCb->data.samsiz[i] = 0;
105 }
106 //Initialize metadata buffers //QIN
107 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
108 {
109 pAfCb->pafPrivateMetadata[i].offset = 0;
110 pAfCb->pafPrivateMetadata[i].size = 0;
111 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
112 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
113 }
114 }
115 // update flags
116 pCb->writerActiveFlag = 0;
117 pCb->readerActiveFlag = 0;
118 pCb->emptyFlag = 0;
119 //pCb->cbWriteAfInit = 0;
121 // (***) FL: revisit
122 // Write back circular buffer configuration
123 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
124 // Write back AF circular buffer
125 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
126 // Write back PCM data
127 for (n=0; n<pCb->maxNumAfCb; n++)
128 {
129 pAfCb = &pCb->afCb[n];
130 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
131 Cache_wb(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
132 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
133 {
134 Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
135 }
136 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
137 {
138 Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
139 }
140 }
141 Cache_wait();
143 return PAF_DECOP_CB_SOK;
144 }
146 // Start writes to circular buffer
147 Int cbWriteStart(
148 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
149 )
150 {
151 PAF_AudioFrame *pAfCb;
152 Int8 n;
153 Int8 i;
155 // (***) FL: revisit
156 // Invalidate circular buffer configuration.
157 // NOTE: Probably only a subset of this information needs to be updated.
158 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
159 Cache_wait();
161 // Invalidate AF circular buffer
162 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
163 for (n=0; n<pCb->maxNumAfCb; n++)
164 {
165 pAfCb = &pCb->afCb[n];
166 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
167 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
168 {
169 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
170 }
171 }
172 Cache_wait();
174 // update flags
175 pCb->writerActiveFlag = 1;
176 pCb->emptyFlag = 0;
178 // (***) FL: revisit
179 // Write back circular buffer configuration
180 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
182 return PAF_DECOP_CB_SOK;
183 };
185 // Stop writes to circular buffer
186 Int cbWriteStop(
187 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
188 )
189 {
190 // update flags
191 pCb->writerActiveFlag = 0;
192 pCb->emptyFlag = 1;
194 // (***) FL: revisit
195 // Write back circular buffer configuration
196 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
198 return PAF_DECOP_CB_SOK;
199 }
201 // Start reads from circular buffer
202 Int cbReadStart(
203 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
204 )
205 {
206 // update flags
207 pCb->readerActiveFlag = 1;
209 // (***) FL: revisit
210 // Write back circular buffer configuration
211 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
213 return PAF_DECOP_CB_SOK;
214 }
216 // Stop reads from circular buffer
217 Int cbReadStop(
218 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
219 )
220 {
221 // update flags
222 pCb->readerActiveFlag = 0;
224 // (***) FL: revisit
225 // Write back circular buffer configuration
226 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
228 return PAF_DECOP_CB_SOK;
229 }
230 // restore read/write flags of the circular buffer. - QIN
231 Int cbReadWriteRestore(
232 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
233 )
234 {
235 // Invalidate circular buffer configuration.
236 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
237 Cache_wait();
239 // update flags
240 pCb->readerActiveFlag = 1;
241 pCb->writerActiveFlag = 1;
243 // (***) FL: revisit
244 // Write back circular buffer configuration
245 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
247 return PAF_DECOP_CB_SOK;
248 }
250 // Read audio frame from circular buffer
251 Int cbReadAf(
252 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
253 PAF_AudioFrame *pAfRd // audio frame into which to read
254 )
255 {
256 PAF_AudioFrame *pAfCb;
257 PAF_ChannelMask_HD streamMask;
258 Int8 i;
259 Int16 j;
261 // (***) FL: revisit
262 // Invalidate circular buffer configuration.
263 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
264 Cache_wait();
266 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
267 {
268 // This shouldn't occur:
269 // writer is active AND draining circular buffer
270 Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
271 return PAF_DECOP_CB_READ_INVSTATE;
272 }
274 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
275 {
276 //
277 // No active writer, not draining circular buffer.
278 // Skip UNDerflow check, mute output.
279 //
281 pAfRd->sampleDecode = PAF_SOURCE_PCM;
282 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
283 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
284 pAfRd->sampleCount = pCb->strFrameLen;
285 pAfRd->channelConfigurationRequest.full = 0;
286 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
287 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
288 pAfRd->channelConfigurationStream.full = 0;
289 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
290 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
292 // compute stream mask
293 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
294 // Clear PCM data
295 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
296 {
297 if ((streamMask >> i) & 0x1)
298 {
299 memset(pAfRd->data.sample[i], pCb->strFrameLen, 0);
300 }
301 pAfRd->data.samsiz[i] = 0;
302 }
304 return PAF_DECOP_CB_SOK;
305 }
307 if ((pCb->writerActiveFlag == 1))
308 {
309 // check underflow
310 if (pCb->numAfCb <= 0)
311 {
312 return PAF_DECOP_CB_READ_UNDERFLOW;
313 }
314 }
316 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
317 {
318 //
319 // Writer active or draining remaining frames in circular buffer.
320 // Get next output audio frame.
321 //
323 // get pointer to current audio frame in circular buffer
324 pAfCb = &pCb->afCb[pCb->afRdIdx];
326 // (***) FL: revisit
327 // Invalidate audio frame
328 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
329 Cache_inv(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
330 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
331 {
332 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
333 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, PAF_MAX_PRIVATE_MD_SZ*sizeof(Int8), Cache_Type_ALLD, 0);
334 }
335 Cache_wait();
337 // compute stream mask
338 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
340 // Invalidate PCM data
341 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
342 {
343 if ((streamMask >> i) & 0x1)
344 {
345 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
346 }
347 }
348 Cache_wait();
350 // read audio frame information updated by decoder
351 pAfRd->sampleDecode = pAfCb->sampleDecode;
352 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
353 pAfRd->sampleRate = pAfCb->sampleRate;
354 pAfRd->sampleCount = pCb->strFrameLen;
355 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
356 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
358 // read metadata information updated by decoder //QIN
359 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
360 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
361 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
362 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
364 // read PCM samples
365 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
366 {
367 if ((streamMask >> i) & 0x1)
368 {
369 for (j = 0; j < pCb->strFrameLen; j++)
370 {
371 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
372 }
374 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
375 }
376 }
377 // read metadata //QIN
378 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
379 {
380 //Invalidate metadata data
381 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
382 Cache_wait();
383 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
384 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
385 &&(pAfCb->pafPrivateMetadata[i].size))
386 {
387 //Invalidate metadata data
388 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
389 Cache_wait();
391 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
392 pAfRd->pafPrivateMetadata[i].offset = 0;//pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
393 pAfRd->pafPrivateMetadata[i].size = pAfCb->pafPrivateMetadata[i].size;
394 memcpy (pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
395 }
396 else //reset un-used buf
397 {
398 pAfRd->pafPrivateMetadata[i].offset = 0;
399 pAfRd->pafPrivateMetadata[i].size = 0;
400 }
401 }
402 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
403 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
404 {
405 // update audio frame read index
406 pCb->afRdIdx++;
407 if (pCb->afRdIdx >= pCb->maxNumAfCb)
408 {
409 pCb->afRdIdx = 0;
410 }
412 // update PCM read index
413 pCb->pcmRdIdx = 0;
415 // update number of audio frames in circular buffer
416 pCb->numAfCb--;
417 }
418 }
420 if (pCb->emptyFlag == 1)
421 {
422 //
423 // Writer inactive, but remaining frames in circular buffer.
424 // Update empty flag.
425 //
426 if (pCb->numAfCb <= 0)
427 {
428 pCb->emptyFlag = 0;
429 }
430 }
432 // (***) FL: revisit
433 // Write back circular buffer configuration.
434 // NOTE: Probably only a subset of this information needs to be updated.
435 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
436 Cache_wait();
438 return PAF_DECOP_CB_SOK;
439 }
441 // Write audio frame to circular buffer
442 Int cbWriteAf(
443 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
444 PAF_AudioFrame *pAfWrt // audio frame from which to write
445 )
446 {
447 PAF_AudioFrame *pAfCb;
448 PAF_ChannelMask_HD streamMask;
449 Int8 i;
450 Int16 j;
452 // (***) FL: revisit
453 // Invalidate circular buffer configuration.
454 // NOTE: Probably only a subset of this information needs to be updated.
455 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
456 Cache_wait();
458 if (pCb->readerActiveFlag == 1)
459 {
460 //
461 // Normal case, reader active.
462 // If reader not active, don't write to circular buffer or check OVRflow.
464 #if 0
465 if (pCb->cbWriteAfInit == 0)
466 {
467 // Invalidate AF circular buffer
468 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
469 for (n=0; n<pCb->maxNumAfCb; n++)
470 {
471 pAfCb = &pCb->afCb[n];
472 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
473 }
474 Cache_wait();
476 pCb->cbWriteAfInit = 1;
477 }
478 #endif
481 // check overflow
482 //if (pCb->numAfCb >= pCb->maxNumAfCb)
483 //{
484 // return PAF_DECOP_CB_WRITE_OVERFLOW;
485 //}
486 while (pCb->numAfCb >= pCb->maxNumAfCb); //Qin replace with while loop for debugging
487 // get pointer to current audio frame in circular buffer
488 pAfCb = &pCb->afCb[pCb->afWrtIdx];
490 // write audio frame information updated by decoder
491 pAfCb->sampleDecode = pAfWrt->sampleDecode;
492 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
493 pAfCb->sampleRate = pAfWrt->sampleRate;
494 pAfCb->sampleCount = pAfWrt->sampleCount;
495 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
496 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
497 // write metadata information updated by decoder//QIN
498 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
499 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
500 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
501 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
502 // write PCM samples
503 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
504 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
505 {
506 if ((streamMask >> i) & 0x1)
507 {
508 for (j = 0; j < pCb->decOpFrameLen; j++)
509 {
510 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
511 }
513 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
514 }
515 }
517 //Write metadata to circular buffer //QIN
518 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
519 {
520 if (pAfWrt->pafPrivateMetadata[i].size )
521 {
522 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
523 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
524 memcpy (pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
525 }
526 else
527 {
528 pAfCb->pafPrivateMetadata[i].offset = 0;
529 pAfCb->pafPrivateMetadata[i].size = 0;
530 }
531 }
532 // update audio frame write index
533 pCb->afWrtIdx++;
534 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
535 {
536 pCb->afWrtIdx = 0;
537 }
539 // update number of audio frames in circular buffer
540 pCb->numAfCb++;
542 // (***) FL: revisit
543 // Write back circular buffer configuration
544 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
545 // write back audio frame
546 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
547 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
548 // write back PCM data
549 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
550 {
551 if ((streamMask >> i) & 0x1)
552 {
553 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
554 }
555 }
557 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
558 {
559 Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
560 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, PAF_MAX_PRIVATE_MD_SZ*sizeof(Int8), Cache_Type_ALLD, 0);
561 }
562 Cache_wait();
563 }
565 return PAF_DECOP_CB_SOK;
566 }
568 // Get next audio frame to write in circular buffer
569 Int cbGetNextWriteAf(
570 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
571 PAF_AudioFrame **ppAfWrt // audio frame next to be written
572 )
573 {
574 // get pointer to current audio frame in circular buffer
575 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
577 // update audio frame write index
578 pCb->afWrtIdx++;
579 if (pCb->afWrtIdx > pCb->maxNumAfCb)
580 {
581 pCb->afWrtIdx = 0;
582 }
584 return PAF_DECOP_CB_SOK;
585 }
587 // Output log of circular buffer control variables (debug)
588 Int cbLog(
589 PAF_DecodeOpCircBuf *pCb,
590 Int8 fullLog
591 )
592 {
593 Log_info4("afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx,
594 pCb->afWrtIdx,
595 pCb->numAfCb);
596 if (fullLog)
597 {
598 Log_info1("maxNumAfCb=%d", pCb->maxNumAfCb);
599 Log_info2("decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
600 //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
601 }
603 return 0;
604 }