0b9dda9bcead6eaccd3233f334148f6cb8cc015a
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / common / paf_decOpCircBuf.c
2 /*
3 Copyright (c) 2016, 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 <ti/sysbios/hal/Cache.h>
39 #include <xdc/runtime/Log.h>
41 #include "pafdec.h"
42 #include "pafsp.h"
43 #include "paf_decOpCircBuf.h"
45 #define MAX_NUM_AF_PCM ( 4 )
46 #define MAX_NUM_AF_DDP ( 2 )
48 #define CB_INIT_RD_LAG ( 2 )
50 // Initialize circular buffer
51 Int cbInit(
52 Int8 sourceSelect, // source select (PCM, DDP, etc.)
53 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
54 Int16 strFrameLen, // stream frame length (PCM samples)
55 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
56 )
57 {
58 PAF_AudioFrame *pAfCb;
59 PAF_AudioData *pPcmBuf;
60 Int8 *pMetaBuf; //QIN
61 Int8 n;
62 Int8 i;
64 // set input frame length
65 pCb->decOpFrameLen = decOpFrameLen;
67 // set output frame length
68 pCb->strFrameLen = strFrameLen;
70 // initialize circular buffer maximum number of audio frames
71 if (sourceSelect == PAF_SOURCE_PCM)
72 {
73 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
74 pCb->afWrtIdx = CB_INIT_RD_LAG;
75 pCb->afRdIdx = 0;
76 pCb->pcmRdIdx = 0; // 2*256 in behind
78 // initialize audio frames
79 for (n=0; n<pCb->maxNumAfCb; n++)
80 {
81 pAfCb = &pCb->afCb[n];
82 pAfCb->sampleDecode = PAF_SOURCE_PCM;
83 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
84 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
85 pAfCb->sampleCount = decOpFrameLen;
86 pAfCb->channelConfigurationRequest.full = 0;
87 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
88 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
89 pAfCb->channelConfigurationStream.full = 0;
90 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
91 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
92 }
93 }
94 else if (sourceSelect == PAF_SOURCE_DDP)
95 {
96 pCb->maxNumAfCb = MAX_NUM_AF_DDP;
97 pCb->afRdIdx = 0;
98 pCb->afWrtIdx = 0;//1;//QIN - Reduce delay to prevent cb overflow. Need further investigation.
99 pCb->pcmRdIdx = 0;//decOpFrameLen - CB_INIT_RD_LAG*strFrameLen; //QIN - Reduce delay to prevent cb overflow. Need further investigation.
101 // initialize audio frames
102 for (n=0; n<pCb->maxNumAfCb; n++)
103 {
104 pAfCb = &pCb->afCb[n];
105 pAfCb->sampleDecode = PAF_SOURCE_DDP;
106 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
107 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
108 pAfCb->sampleCount = decOpFrameLen;
109 pAfCb->channelConfigurationRequest.full = 0;
110 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
111 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
112 pAfCb->channelConfigurationStream.full = 0;
113 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
114 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
115 }
116 }
117 else
118 {
119 return PAF_DECOP_CB_INIT_INV_SOURCE_SEL;
120 }
122 // initialize circular buffer current number of frames
123 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
125 // initialize audio frame PCM buffers
126 pPcmBuf = pCb->pcmBuf;
127 pMetaBuf = pCb->metaBuf; //QIN
128 for (n=0; n<pCb->maxNumAfCb; n++)
129 {
130 pAfCb = &pCb->afCb[n];
131 pAfCb->data.nChannels = PAF_DECOP_CB_MAX_NUM_PCM_CH;
132 pAfCb->data.nSamples = decOpFrameLen;
133 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
134 {
135 pAfCb->data.sample[i] = pPcmBuf;
136 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
137 pPcmBuf += decOpFrameLen;
139 pAfCb->data.samsiz[i] = 0;
140 }
141 //Initialize metadata buffers //QIN
142 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
143 {
144 pAfCb->pafPrivateMetadata[i].offset = 0;
145 pAfCb->pafPrivateMetadata[i].size = 0;
146 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
147 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
148 }
149 }
150 // update flags
151 pCb->writerActiveFlag = 0;
152 pCb->readerActiveFlag = 0;
153 pCb->emptyFlag = 0;
154 //pCb->cbWriteAfInit = 0;
156 // (***) FL: revisit
157 // Write back circular buffer configuration
158 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
159 // Write back AF circular buffer
160 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
161 // Write back PCM data
162 for (n=0; n<pCb->maxNumAfCb; n++)
163 {
164 pAfCb = &pCb->afCb[n];
165 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
166 Cache_wb(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
167 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
168 {
169 Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
170 }
171 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
172 {
173 Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
174 }
175 }
176 Cache_wait();
178 return PAF_DECOP_CB_SOK;
179 }
181 // Start writes to circular buffer
182 Int cbWriteStart(
183 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
184 )
185 {
186 PAF_AudioFrame *pAfCb;
187 Int8 n;
188 Int8 i;
190 // (***) FL: revisit
191 // Invalidate circular buffer configuration.
192 // NOTE: Probably only a subset of this information needs to be updated.
193 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
194 Cache_wait();
196 // Invalidate AF circular buffer
197 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
198 for (n=0; n<pCb->maxNumAfCb; n++)
199 {
200 pAfCb = &pCb->afCb[n];
201 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
202 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
203 {
204 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
205 }
206 }
207 Cache_wait();
209 // update flags
210 pCb->writerActiveFlag = 1;
211 pCb->emptyFlag = 0;
213 // (***) FL: revisit
214 // Write back circular buffer configuration
215 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
217 return PAF_DECOP_CB_SOK;
218 };
220 // Stop writes to circular buffer
221 Int cbWriteStop(
222 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
223 )
224 {
225 // update flags
226 pCb->writerActiveFlag = 0;
227 pCb->emptyFlag = 1;
229 // (***) FL: revisit
230 // Write back circular buffer configuration
231 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
233 return PAF_DECOP_CB_SOK;
234 }
236 // Start reads from circular buffer
237 Int cbReadStart(
238 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
239 )
240 {
241 // update flags
242 pCb->readerActiveFlag = 1;
244 // (***) FL: revisit
245 // Write back circular buffer configuration
246 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
248 return PAF_DECOP_CB_SOK;
249 }
251 // Stop reads from circular buffer
252 Int cbReadStop(
253 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
254 )
255 {
256 // update flags
257 pCb->readerActiveFlag = 0;
259 // (***) FL: revisit
260 // Write back circular buffer configuration
261 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
263 return PAF_DECOP_CB_SOK;
264 }
265 // restore read/write flags of the circular buffer. - QIN
266 Int cbReadWriteRestore(
267 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
268 )
269 {
270 // Invalidate circular buffer configuration.
271 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
272 Cache_wait();
274 // update flags
275 pCb->readerActiveFlag = 1;
276 pCb->writerActiveFlag = 1;
278 // (***) FL: revisit
279 // Write back circular buffer configuration
280 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
282 return PAF_DECOP_CB_SOK;
283 }
285 // Read audio frame from circular buffer
286 Int cbReadAf(
287 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
288 PAF_AudioFrame *pAfRd // audio frame into which to read
289 )
290 {
291 PAF_AudioFrame *pAfCb;
292 PAF_ChannelMask_HD streamMask;
293 Int8 i;
294 Int16 j;
296 // (***) FL: revisit
297 // Invalidate circular buffer configuration.
298 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
299 Cache_wait();
301 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
302 {
303 // This shouldn't occur:
304 // writer is active AND draining circular buffer
305 Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
306 return PAF_DECOP_CB_READ_INVSTATE;
307 }
309 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
310 {
311 //
312 // No active writer, not draining circular buffer.
313 // Skip UNDerflow check, mute output.
314 //
316 pAfRd->sampleDecode = PAF_SOURCE_PCM;
317 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
318 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
319 pAfRd->sampleCount = pCb->strFrameLen;
320 pAfRd->channelConfigurationRequest.full = 0;
321 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
322 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
323 pAfRd->channelConfigurationStream.full = 0;
324 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
325 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
327 // compute stream mask
328 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
329 // Clear PCM data
330 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
331 {
332 if ((streamMask >> i) & 0x1)
333 {
334 memset(pAfRd->data.sample[i], pCb->strFrameLen, 0);
335 }
336 pAfRd->data.samsiz[i] = 0;
337 }
339 return PAF_DECOP_CB_SOK;
340 }
342 if ((pCb->writerActiveFlag == 1))
343 {
344 // check underflow
345 if (pCb->numAfCb <= 0)
346 {
347 return PAF_DECOP_CB_READ_UNDERFLOW;
348 }
349 }
351 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
352 {
353 //
354 // Writer active or draining remaining frames in circular buffer.
355 // Get next output audio frame.
356 //
358 // get pointer to current audio frame in circular buffer
359 pAfCb = &pCb->afCb[pCb->afRdIdx];
361 // (***) FL: revisit
362 // Invalidate audio frame
363 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
364 Cache_inv(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
365 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
366 {
367 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
368 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, PAF_MAX_PRIVATE_MD_SZ*sizeof(Int8), Cache_Type_ALLD, 0);
369 }
370 Cache_wait();
372 // compute stream mask
373 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
375 // Invalidate PCM data
376 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
377 {
378 if ((streamMask >> i) & 0x1)
379 {
380 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
381 }
382 }
383 Cache_wait();
385 // read audio frame information updated by decoder
386 pAfRd->sampleDecode = pAfCb->sampleDecode;
387 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
388 pAfRd->sampleRate = pAfCb->sampleRate;
389 pAfRd->sampleCount = pCb->strFrameLen;
390 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
391 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
393 // read metadata information updated by decoder //QIN
394 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
395 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
396 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
397 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
399 // read PCM samples
400 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
401 {
402 if ((streamMask >> i) & 0x1)
403 {
404 for (j = 0; j < pCb->strFrameLen; j++)
405 {
406 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
407 }
409 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
410 }
411 }
412 // read metadata //QIN
413 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
414 {
415 //Invalidate metadata data
416 Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
417 Cache_wait();
418 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
419 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
420 &&(pAfCb->pafPrivateMetadata[i].size))
421 {
422 //Invalidate metadata data
423 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
424 Cache_wait();
426 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
427 pAfRd->pafPrivateMetadata[i].offset = 0;//pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
428 pAfRd->pafPrivateMetadata[i].size = pAfCb->pafPrivateMetadata[i].size;
429 memcpy (pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
430 }
431 else //reset un-used buf
432 {
433 pAfRd->pafPrivateMetadata[i].offset = 0;
434 pAfRd->pafPrivateMetadata[i].size = 0;
435 }
436 }
437 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
438 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
439 {
440 // update audio frame read index
441 pCb->afRdIdx++;
442 if (pCb->afRdIdx >= pCb->maxNumAfCb)
443 {
444 pCb->afRdIdx = 0;
445 }
447 // update PCM read index
448 pCb->pcmRdIdx = 0;
450 // update number of audio frames in circular buffer
451 pCb->numAfCb--;
452 }
453 }
455 if (pCb->emptyFlag == 1)
456 {
457 //
458 // Writer inactive, but remaining frames in circular buffer.
459 // Update empty flag.
460 //
461 if (pCb->numAfCb <= 0)
462 {
463 pCb->emptyFlag = 0;
464 }
465 }
467 // (***) FL: revisit
468 // Write back circular buffer configuration.
469 // NOTE: Probably only a subset of this information needs to be updated.
470 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
471 Cache_wait();
473 return PAF_DECOP_CB_SOK;
474 }
476 // Write audio frame to circular buffer
477 Int cbWriteAf(
478 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
479 PAF_AudioFrame *pAfWrt // audio frame from which to write
480 )
481 {
482 PAF_AudioFrame *pAfCb;
483 PAF_ChannelMask_HD streamMask;
484 Int8 i;
485 Int16 j;
487 // (***) FL: revisit
488 // Invalidate circular buffer configuration.
489 // NOTE: Probably only a subset of this information needs to be updated.
490 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
491 Cache_wait();
493 if (pCb->readerActiveFlag == 1)
494 {
495 //
496 // Normal case, reader active.
497 // If reader not active, don't write to circular buffer or check OVRflow.
499 #if 0
500 if (pCb->cbWriteAfInit == 0)
501 {
502 // Invalidate AF circular buffer
503 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
504 for (n=0; n<pCb->maxNumAfCb; n++)
505 {
506 pAfCb = &pCb->afCb[n];
507 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
508 }
509 Cache_wait();
511 pCb->cbWriteAfInit = 1;
512 }
513 #endif
516 // check overflow
517 //if (pCb->numAfCb >= pCb->maxNumAfCb)
518 //{
519 // return PAF_DECOP_CB_WRITE_OVERFLOW;
520 //}
521 while (pCb->numAfCb >= pCb->maxNumAfCb); //Qin replace with while loop for debugging
522 // get pointer to current audio frame in circular buffer
523 pAfCb = &pCb->afCb[pCb->afWrtIdx];
525 // write audio frame information updated by decoder
526 pAfCb->sampleDecode = pAfWrt->sampleDecode;
527 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
528 pAfCb->sampleRate = pAfWrt->sampleRate;
529 pAfCb->sampleCount = pAfWrt->sampleCount;
530 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
531 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
532 // write metadata information updated by decoder//QIN
533 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
534 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
535 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
536 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
537 // write PCM samples
538 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
539 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
540 {
541 if ((streamMask >> i) & 0x1)
542 {
543 for (j = 0; j < pCb->decOpFrameLen; j++)
544 {
545 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
546 }
548 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
549 }
550 }
552 //Write metadata to circular buffer //QIN
553 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
554 {
555 if (pAfWrt->pafPrivateMetadata[i].size )
556 {
557 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
558 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
559 memcpy (pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
560 }
561 else
562 {
563 pAfCb->pafPrivateMetadata[i].offset = 0;
564 pAfCb->pafPrivateMetadata[i].size = 0;
565 }
566 }
567 // update audio frame write index
568 pCb->afWrtIdx++;
569 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
570 {
571 pCb->afWrtIdx = 0;
572 }
574 // update number of audio frames in circular buffer
575 pCb->numAfCb++;
577 // (***) FL: revisit
578 // Write back circular buffer configuration
579 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
580 // write back audio frame
581 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
582 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
583 // write back PCM data
584 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
585 {
586 if ((streamMask >> i) & 0x1)
587 {
588 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
589 }
590 }
592 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
593 {
594 Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
595 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, PAF_MAX_PRIVATE_MD_SZ*sizeof(Int8), Cache_Type_ALLD, 0);
596 }
597 Cache_wait();
598 }
600 return PAF_DECOP_CB_SOK;
601 }
603 // Get next audio frame to write in circular buffer
604 Int cbGetNextWriteAf(
605 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
606 PAF_AudioFrame **ppAfWrt // audio frame next to be written
607 )
608 {
609 // get pointer to current audio frame in circular buffer
610 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
612 // update audio frame write index
613 pCb->afWrtIdx++;
614 if (pCb->afWrtIdx > pCb->maxNumAfCb)
615 {
616 pCb->afWrtIdx = 0;
617 }
619 return PAF_DECOP_CB_SOK;
620 }
622 // Output log of circular buffer control variables (debug)
623 Int cbLog(
624 PAF_DecodeOpCircBuf *pCb,
625 Int8 fullLog
626 )
627 {
628 Log_info4("afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx,
629 pCb->afWrtIdx,
630 pCb->numAfCb);
631 if (fullLog)
632 {
633 Log_info1("maxNumAfCb=%d", pCb->maxNumAfCb);
634 Log_info2("decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
635 //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
636 }
638 return 0;
639 }