[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 "common.h"
42 #include "pafdec.h"
43 #include "pafsp.h"
44 #include "paf_decOpCircBuf.h"
46 // Generate mute AF on circular buffer read
47 static Void cbReadAfMute(
48 PAF_AudioFrame *pAfRd, // audio frame into which to read
49 Int16 strFrameLen // stream frame length (output transaction size)
50 );
52 #define MAX_NUM_AF_PCM ( 4 )
53 #define CB_INIT_RD_LAG_PCM ( 2 ) // 0...3
55 #define MAX_NUM_AF_DDP ( 2 )
56 #define CB_INIT_RD_LAG_DDP ( 4 ) // 0...5
58 // Initialize circular buffer
59 Int cbInit(
60 Int8 sourceSelect, // source select (PCM, DDP, etc.)
61 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
62 Int16 strFrameLen, // stream frame length (PCM samples)
63 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer
64 Int8 resetRwFlags // whether to reset reader, writer, and empty flags
65 )
66 {
67 PAF_AudioFrame *pAfCb;
68 PAF_AudioData *pPcmBuf;
69 UInt8 *pMetaBuf; //QIN
70 Int8 n;
71 Int8 i;
73 // set input frame length
74 pCb->decOpFrameLen = decOpFrameLen;
76 // set output frame length
77 pCb->strFrameLen = strFrameLen;
79 // initialize circular buffer maximum number of audio frames
80 if (sourceSelect == PAF_SOURCE_PCM)
81 {
82 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
83 pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
84 pCb->afRdIdx = 0;
85 pCb->pcmRdIdx = 0; // 2*256 in behind
87 // initialize audio frames
88 for (n=0; n<pCb->maxNumAfCb; n++)
89 {
90 pAfCb = &pCb->afCb[n];
91 pAfCb->sampleDecode = PAF_SOURCE_PCM;
92 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
93 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
94 pAfCb->sampleCount = decOpFrameLen;
95 pAfCb->channelConfigurationRequest.full = 0;
96 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
97 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
98 pAfCb->channelConfigurationStream.full = 0;
99 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
100 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
101 }
102 }
103 else if (sourceSelect == PAF_SOURCE_DDP)
104 {
105 pCb->maxNumAfCb = MAX_NUM_AF_DDP;
106 pCb->afWrtIdx = 1;
107 pCb->afRdIdx = 0;
108 pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG_DDP*strFrameLen; // 4*256 behind
110 // initialize audio frames
111 for (n=0; n<pCb->maxNumAfCb; n++)
112 {
113 pAfCb = &pCb->afCb[n];
114 pAfCb->sampleDecode = PAF_SOURCE_DDP;
115 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
116 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
117 pAfCb->sampleCount = decOpFrameLen;
118 pAfCb->channelConfigurationRequest.full = 0;
119 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
120 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
121 pAfCb->channelConfigurationStream.full = 0;
122 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
123 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
124 }
125 }
126 else
127 {
128 return PAF_DECOP_CB_INIT_INV_SOURCE_SEL;
129 }
131 // initialize circular buffer current number of frames
132 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
134 // initialize audio frame PCM buffers
135 pPcmBuf = pCb->pcmBuf;
136 pMetaBuf = pCb->metaBuf; //QIN
137 for (n=0; n<pCb->maxNumAfCb; n++)
138 {
139 pAfCb = &pCb->afCb[n];
140 pAfCb->data.nChannels = PAF_DECOP_CB_MAX_NUM_PCM_CH;
141 pAfCb->data.nSamples = decOpFrameLen;
142 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
143 {
144 pAfCb->data.sample[i] = pPcmBuf;
145 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
146 pPcmBuf += decOpFrameLen;
148 pAfCb->data.samsiz[i] = 0;
149 }
151 // Initialize metadata buffers //QIN
152 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
153 {
154 pAfCb->pafPrivateMetadata[i].offset = 0;
155 pAfCb->pafPrivateMetadata[i].size = 0;
156 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
157 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
158 }
159 }
161 // reset read/write flags
162 if (resetRwFlags)
163 {
164 pCb->writerActiveFlag = 0;
165 pCb->readerActiveFlag = 0;
166 pCb->emptyFlag = 0;
167 }
168 // reset error counts
169 pCb->errUndCnt = 0;
170 pCb->errOvrCnt = 0;
172 // (***) FL: revisit
173 // Write back circular buffer configuration
174 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
175 // Write back AF circular buffer
176 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
177 // Write back PCM data
178 for (n=0; n<pCb->maxNumAfCb; n++)
179 {
180 pAfCb = &pCb->afCb[n];
181 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
182 Cache_wb(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
183 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
184 {
185 Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
186 }
187 // FL: unnecessary since part of AF
188 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
189 //{
190 // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
191 //}
192 }
193 Cache_wait();
195 return PAF_DECOP_CB_SOK;
196 }
198 // Start writes to circular buffer
199 Int cbWriteStart(
200 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
201 )
202 {
203 PAF_AudioFrame *pAfCb;
204 Int8 n;
205 //Int8 i;
207 // (***) FL: revisit
208 // Invalidate circular buffer configuration.
209 // NOTE: Probably only a subset of this information needs to be updated.
210 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
211 Cache_wait();
213 // Invalidate AF circular buffer
214 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
215 for (n=0; n<pCb->maxNumAfCb; n++)
216 {
217 pAfCb = &pCb->afCb[n];
218 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
219 // FL: unnecessary since part of AF
220 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
221 //{
222 // Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
223 //}
224 }
225 Cache_wait();
227 // update flags
228 pCb->writerActiveFlag = 1;
229 pCb->emptyFlag = 0;
231 // (***) FL: revisit
232 // Write back circular buffer configuration
233 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
234 Cache_wait();
236 return PAF_DECOP_CB_SOK;
237 };
239 // Stop writes to circular buffer
240 Int cbWriteStop(
241 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
242 )
243 {
244 // Invalidate circular buffer configuration
245 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
246 Cache_wait();
248 // update flags
249 pCb->writerActiveFlag = 0;
250 pCb->emptyFlag = 1;
252 // (***) FL: revisit
253 // Write back circular buffer configuration
254 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
255 Cache_wait();
257 return PAF_DECOP_CB_SOK;
258 }
260 // Start reads from circular buffer
261 Int cbReadStart(
262 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
263 )
264 {
265 // Invalidate circular buffer configuration
266 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
267 Cache_wait();
269 // update flags
270 pCb->readerActiveFlag = 1;
272 // (***) FL: revisit
273 // Write back circular buffer configuration
274 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
275 Cache_wait();
277 return PAF_DECOP_CB_SOK;
278 }
280 // Stop reads from circular buffer
281 Int cbReadStop(
282 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
283 )
284 {
285 // Invalidate circular buffer configuration
286 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
287 Cache_wait();
289 // update flags
290 pCb->readerActiveFlag = 0;
292 // (***) FL: revisit
293 // Write back circular buffer configuration
294 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
295 Cache_wait();
297 return PAF_DECOP_CB_SOK;
298 }
300 // Read audio frame from circular buffer
301 Int cbReadAf(
302 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer
303 PAF_AudioFrame *pAfRd // audio frame into which to read
304 )
305 {
306 PAF_AudioFrame *pAfCb;
307 PAF_ChannelMask_HD streamMask;
308 Int8 i;
309 Int16 j;
311 // (***) FL: revisit
312 // Invalidate circular buffer configuration.
313 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
314 Cache_wait();
316 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
317 {
318 // This shouldn't occur:
319 // writer is active AND draining circular buffer
320 Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
321 SW_BREAKPOINT; // FL: debug
322 return PAF_DECOP_CB_READ_INVSTATE;
323 }
325 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
326 {
327 //
328 // No active writer, not draining circular buffer.
329 // Skip UNDerflow check, mute output.
330 //
331 cbReadAfMute(pAfRd, pCb->strFrameLen);
333 return PAF_DECOP_CB_SOK;
334 }
336 if ((pCb->writerActiveFlag == 1))
337 {
338 // check underflow
339 if (pCb->numAfCb <= 0)
340 {
341 //
342 // Increment underflow count.
343 // Mute output on underflow.
344 //
345 pCb->errUndCnt++;
346 cbReadAfMute(pAfRd, pCb->strFrameLen);
347 //SW_BREAKPOINT; // FL: debug
349 // Write back circular buffer configuration.
350 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
351 Cache_wait();
353 return PAF_DECOP_CB_READ_UNDERFLOW;
354 }
355 }
357 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
358 {
359 //
360 // Writer active or draining remaining frames in circular buffer.
361 // Get next output audio frame.
362 //
364 // get pointer to current audio frame in circular buffer
365 pAfCb = &pCb->afCb[pCb->afRdIdx];
367 // (***) FL: revisit
368 // Invalidate audio frame
369 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
370 Cache_inv(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
371 for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
372 {
373 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
374 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
375 }
376 Cache_wait();
378 // compute stream mask
379 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
381 // Invalidate PCM data
382 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
383 {
384 if ((streamMask >> i) & 0x1)
385 {
386 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
387 }
388 }
389 Cache_wait();
391 // read audio frame information updated by decoder
392 pAfRd->sampleDecode = pAfCb->sampleDecode;
393 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
394 pAfRd->sampleRate = pAfCb->sampleRate;
395 pAfRd->sampleCount = pCb->strFrameLen;
396 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
397 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
399 // read metadata information updated by decoder //QIN
400 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
401 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
402 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
403 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
405 // read PCM samples
406 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
407 {
408 if ((streamMask >> i) & 0x1)
409 {
410 for (j = 0; j < pCb->strFrameLen; j++)
411 {
412 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
413 }
415 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
416 }
417 }
418 // read metadata //QIN
419 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
420 {
421 // FL: this is done above
422 ////Invalidate metadata data
423 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
424 //Cache_wait();
426 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
427 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
428 &&(pAfCb->pafPrivateMetadata[i].size))
429 {
430 // FL: this is done above
431 ////Invalidate metadata data
432 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
433 //Cache_wait();
435 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
436 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
437 pAfRd->pafPrivateMetadata[i].size = pAfCb->pafPrivateMetadata[i].size;
438 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
439 }
440 else //reset un-used buf
441 {
442 pAfRd->pafPrivateMetadata[i].offset = 0;
443 pAfRd->pafPrivateMetadata[i].size = 0;
444 }
445 }
447 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
448 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
449 {
450 // update audio frame read index
451 pCb->afRdIdx++;
452 if (pCb->afRdIdx >= pCb->maxNumAfCb)
453 {
454 pCb->afRdIdx = 0;
455 }
457 // update PCM read index
458 pCb->pcmRdIdx = 0;
460 // update number of audio frames in circular buffer
461 pCb->numAfCb--;
462 }
463 }
465 if (pCb->emptyFlag == 1)
466 {
467 //
468 // Writer inactive, but remaining frames in circular buffer.
469 // Update empty flag.
470 //
471 if (pCb->numAfCb <= 0)
472 {
473 pCb->emptyFlag = 0;
474 }
475 }
477 // (***) FL: revisit
478 // Write back circular buffer configuration.
479 // NOTE: Probably only a subset of this information needs to be updated.
480 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
481 Cache_wait();
483 return PAF_DECOP_CB_SOK;
484 }
486 // Write audio frame to circular buffer
487 Int cbWriteAf(
488 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer
489 PAF_AudioFrame *pAfWrt // audio frame from which to write
490 )
491 {
492 PAF_AudioFrame *pAfCb;
493 PAF_ChannelMask_HD streamMask;
494 Int8 i;
495 Int16 j;
497 // (***) FL: revisit
498 // Invalidate circular buffer configuration.
499 // NOTE: Probably only a subset of this information nexeds to be updated.
500 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
501 Cache_wait();
503 if (pCb->readerActiveFlag == 1)
504 {
505 //
506 // Normal case, reader active.
507 // If reader not active, don't write to circular buffer or check OVRflow.
509 #if 0
510 if (pCb->cbWriteAfInit == 0)
511 {
512 // Invalidate AF circular buffer
513 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
514 for (n=0; n<pCb->maxNumAfCb; n++)
515 {
516 pAfCb = &pCb->afCb[n];
517 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
518 }
519 Cache_wait();
521 pCb->cbWriteAfInit = 1;
522 }
523 #endif
525 // check overflow
526 if (pCb->numAfCb >= pCb->maxNumAfCb)
527 {
528 pCb->errOvrCnt++;
529 //SW_BREAKPOINT;
530 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
531 return PAF_DECOP_CB_WRITE_OVERFLOW;
532 }
534 // get pointer to current audio frame in circular buffer
535 pAfCb = &pCb->afCb[pCb->afWrtIdx];
537 // write audio frame information updated by decoder
538 pAfCb->sampleDecode = pAfWrt->sampleDecode;
539 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
540 pAfCb->sampleRate = pAfWrt->sampleRate;
541 pAfCb->sampleCount = pAfWrt->sampleCount;
542 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
543 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
544 // write metadata information updated by decoder //QIN
545 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
546 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
547 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
548 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
549 // write PCM samples
550 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
551 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
552 {
553 if ((streamMask >> i) & 0x1)
554 {
555 for (j = 0; j < pCb->decOpFrameLen; j++)
556 {
557 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
558 }
560 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
561 }
562 }
564 // Write metadata to circular buffer
565 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
566 {
567 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
568 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
569 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
570 }
572 // update audio frame write index
573 pCb->afWrtIdx++;
574 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
575 {
576 pCb->afWrtIdx = 0;
577 }
579 // update number of audio frames in circular buffer
580 pCb->numAfCb++;
582 // (***) FL: revisit
583 // Write back circular buffer configuration
584 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
585 // write back audio frame
586 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
587 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
588 // write back PCM data
589 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
590 {
591 if ((streamMask >> i) & 0x1)
592 {
593 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
594 }
595 }
597 // write back private metadata // QIN
598 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
599 {
600 //Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
601 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
602 }
603 Cache_wait();
604 }
606 return PAF_DECOP_CB_SOK;
607 }
609 // Get next audio frame to write in circular buffer
610 Int cbGetNextWriteAf(
611 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer
612 PAF_AudioFrame **ppAfWrt // audio frame next to be written
613 )
614 {
615 // get pointer to current audio frame in circular buffer
616 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
618 // update audio frame write index
619 pCb->afWrtIdx++;
620 if (pCb->afWrtIdx > pCb->maxNumAfCb)
621 {
622 pCb->afWrtIdx = 0;
623 }
625 return PAF_DECOP_CB_SOK;
626 }
628 // Output log of circular buffer control variables (debug)
629 Int cbLog(
630 PAF_AST_DecOpCircBuf *pCb,
631 Int8 fullLog,
632 char *locInfo
633 )
634 {
635 Log_info1("CB: %s", (IArg)locInfo);
636 Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, emptyFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->emptyFlag);
637 Log_info4("CB: afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx,
638 pCb->afWrtIdx,
639 pCb->numAfCb);
640 if (fullLog)
641 {
642 Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb);
643 Log_info2("CB: decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
644 //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
645 }
647 return 0;
648 }
650 // Generate mute AF on circular buffer read
651 static Void cbReadAfMute(
652 PAF_AudioFrame *pAfRd, // audio frame into which to read
653 Int16 strFrameLen // stream frame length (output transaction size)
654 )
655 {
656 PAF_ChannelMask_HD streamMask;
657 Int8 i;
659 pAfRd->sampleDecode = PAF_SOURCE_PCM;
660 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
661 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
662 pAfRd->sampleCount = strFrameLen;
663 pAfRd->channelConfigurationRequest.full = 0;
664 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
665 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
666 pAfRd->channelConfigurationStream.full = 0;
667 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
668 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
670 // compute stream mask
671 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
672 // Clear PCM data
673 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
674 {
675 if ((streamMask >> i) & 0x1)
676 {
677 memset(pAfRd->data.sample[i], strFrameLen, 0);
678 }
679 pAfRd->data.samsiz[i] = 0;
680 }
681 }