[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / framework / aspDecOpCircBuf_master.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 <xdc/runtime/Log.h>
39 #include <ti/sysbios/hal/Cache.h>
40 #include <ti/uia/events/UIAEvt.h>
41 #include <ti/ipc/GateMP.h>
43 #include "common.h"
44 #include "paftyp.h"
45 #include "pafdec.h"
46 #include "aspDecOpCircBuf_master.h"
48 #define DEF_SOURCE_SEL ( PAF_SOURCE_PCM ) // default source select
49 #define DEF_DEC_OP_FRAME_LEN ( 256 ) // default decoder output frame length
50 #define DEF_STR_FRAME_LEN ( 256 ) // default stream frame length
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 // Generate mute AF on circular buffer read
59 static Void cbReadAfMute(
60 PAF_AudioFrame *pAfRd, // audio frame into which to read
61 Int16 strFrameLen // stream frame length (output transaction size)
62 );
65 // Initialize circular buffer control
66 Int cbCtlInit(
67 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
68 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
69 )
70 {
71 GateMP_Params gateParams;
72 GateMP_Handle gateHandle;
74 GateMP_Params_init(&gateParams);
75 gateParams.localProtect = GateMP_LocalProtect_THREAD;
76 gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
77 gateParams.name = ASP_DECODE_CB_GATE_NAME;
78 gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
79 gateHandle = GateMP_create(&gateParams);
80 if (gateHandle != NULL)
81 {
82 pCbCtl->gateHandle = gateHandle;
83 }
84 else
85 {
86 pCbCtl->gateHandle = NULL;
87 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
88 }
90 pCbCtl->pXDecOpCb = pXDecOpCb;
92 return ASP_DECOP_CB_SOK;
94 }
96 // Initialize circular buffer
97 Int cbInit(
98 PAF_AST_DecOpCircBuf *pCb
99 )
100 {
101 PAF_AudioFrame *pAfCb;
102 PAF_AudioData *pPcmBuf;
103 UInt8 *pMetaBuf;
104 Int8 n;
105 Int8 i;
107 // set source select
108 pCb->sourceSel = DEF_SOURCE_SEL;
110 // set input frame length
111 pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
113 // set output frame length
114 pCb->strFrameLen = DEF_STR_FRAME_LEN;
116 // initialize circular buffer maximum number of audio frames
117 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
118 pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
119 pCb->afRdIdx = 0;
120 pCb->pcmRdIdx = 0; // 2*256 in behind
122 // initialize audio frames
123 for (n=0; n<pCb->maxNumAfCb; n++)
124 {
125 pAfCb = &pCb->afCb[n];
126 pAfCb->sampleDecode = PAF_SOURCE_PCM;
127 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
128 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
129 pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
130 pAfCb->channelConfigurationRequest.full = 0;
131 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
132 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
133 pAfCb->channelConfigurationStream.full = 0;
134 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
135 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
136 }
138 // initialize circular buffer current number of frames
139 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
141 // initialize audio frame PCM buffers
142 pPcmBuf = pCb->pcmBuf;
143 pMetaBuf = pCb->metaBuf; //QIN
144 for (n=0; n<pCb->maxNumAfCb; n++)
145 {
146 pAfCb = &pCb->afCb[n];
147 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
148 pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
149 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
150 {
151 pAfCb->data.sample[i] = pPcmBuf;
152 memset(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN, 0);
153 pPcmBuf += DEF_DEC_OP_FRAME_LEN;
155 pAfCb->data.samsiz[i] = 0;
156 }
158 // Initialize metadata buffers //QIN
159 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
160 {
161 pAfCb->pafPrivateMetadata[i].offset = 0;
162 pAfCb->pafPrivateMetadata[i].size = 0;
163 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
164 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
165 }
166 }
168 // reset read/write flags
169 pCb->writerActiveFlag = 0;
170 pCb->readerActiveFlag = 0;
171 pCb->emptyFlag = 0;
173 // reset error counts
174 pCb->errUndCnt = 0;
175 pCb->errOvrCnt = 0;
177 // (***) FL: revisit
178 // Write back circular buffer configuration
179 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
180 // Write back AF circular buffer
181 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
182 // Write back PCM data
183 for (n=0; n<pCb->maxNumAfCb; n++)
184 {
185 pAfCb = &pCb->afCb[n];
186 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
187 Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
188 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
189 {
190 Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
191 }
192 // FL: unnecessary since part of AF
193 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
194 //{
195 // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
196 //}
197 }
198 Cache_wait();
200 return ASP_DECOP_CB_SOK;
201 }
203 // Initialize circular buffer based on selected source
204 Int cbInitSourceSel(
205 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
206 Int8 cbIdx, // decoder output circular buffer index
207 Int8 sourceSelect, // source select (PCM, DDP, etc.)
208 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
209 Int16 strFrameLen, // stream frame length (PCM samples)
210 Int8 resetRwFlags // whether to reset reader, writer, and empty flags
211 )
212 {
213 IArg key;
214 GateMP_Handle gateHandle;
215 PAF_AST_DecOpCircBuf *pCb;
216 PAF_AudioFrame *pAfCb;
217 PAF_AudioData *pPcmBuf;
218 UInt8 *pMetaBuf; //QIN
219 Int8 n;
220 Int8 i;
222 // Get gate handle
223 gateHandle = pCbCtl->gateHandle;
224 // Enter gate
225 key = GateMP_enter(gateHandle);
227 // Get circular buffer base pointer
228 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
230 // Invalidate circular buffer configuration
231 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
232 Cache_wait();
234 //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
236 // set source select
237 pCb->sourceSel = sourceSelect;
239 // set input frame length
240 pCb->decOpFrameLen = decOpFrameLen;
242 // set output frame length
243 pCb->strFrameLen = strFrameLen;
245 // initialize circular buffer maximum number of audio frames
246 if (sourceSelect == PAF_SOURCE_PCM)
247 {
248 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
249 pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
250 pCb->afRdIdx = 0;
251 pCb->pcmRdIdx = 0; // 2*256 in behind
253 // initialize audio frames
254 for (n=0; n<pCb->maxNumAfCb; n++)
255 {
256 pAfCb = &pCb->afCb[n];
257 pAfCb->sampleDecode = PAF_SOURCE_PCM;
258 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
259 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
260 pAfCb->sampleCount = decOpFrameLen;
261 pAfCb->channelConfigurationRequest.full = 0;
262 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
263 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
264 pAfCb->channelConfigurationStream.full = 0;
265 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
266 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
267 }
268 }
269 else if (sourceSelect == PAF_SOURCE_DDP)
270 {
271 pCb->maxNumAfCb = MAX_NUM_AF_DDP;
272 pCb->afWrtIdx = 1;
273 pCb->afRdIdx = 0;
274 pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG_DDP*strFrameLen; // 4*256 behind
276 // initialize audio frames
277 for (n=0; n<pCb->maxNumAfCb; n++)
278 {
279 pAfCb = &pCb->afCb[n];
280 pAfCb->sampleDecode = PAF_SOURCE_DDP;
281 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
282 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
283 pAfCb->sampleCount = decOpFrameLen;
284 pAfCb->channelConfigurationRequest.full = 0;
285 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
286 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
287 pAfCb->channelConfigurationStream.full = 0;
288 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
289 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
290 }
291 }
292 else
293 {
294 // Leave the gate
295 GateMP_leave(gateHandle, key);
297 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
298 }
300 // initialize circular buffer current number of frames
301 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
303 // initialize audio frame PCM buffers
304 pPcmBuf = pCb->pcmBuf;
305 pMetaBuf = pCb->metaBuf; //QIN
306 for (n=0; n<pCb->maxNumAfCb; n++)
307 {
308 pAfCb = &pCb->afCb[n];
309 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
310 pAfCb->data.nSamples = decOpFrameLen;
311 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
312 {
313 pAfCb->data.sample[i] = pPcmBuf;
314 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
315 pPcmBuf += decOpFrameLen;
317 pAfCb->data.samsiz[i] = 0;
318 }
320 // Initialize metadata buffers //QIN
321 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
322 {
323 pAfCb->pafPrivateMetadata[i].offset = 0;
324 pAfCb->pafPrivateMetadata[i].size = 0;
325 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
326 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
327 }
328 }
330 // reset read/write flags
331 if (resetRwFlags)
332 {
333 pCb->writerActiveFlag = 0;
334 pCb->readerActiveFlag = 0;
335 pCb->emptyFlag = 0;
336 }
338 // reset error counts
339 pCb->errUndCnt = 0;
340 pCb->errOvrCnt = 0;
342 // (***) FL: revisit
343 // Write back circular buffer configuration
344 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
345 // Write back AF circular buffer
346 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
347 // Write back PCM data
348 for (n=0; n<pCb->maxNumAfCb; n++)
349 {
350 pAfCb = &pCb->afCb[n];
351 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
352 Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
353 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
354 {
355 Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
356 }
357 // FL: unnecessary since part of AF
358 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
359 //{
360 // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
361 //}
362 }
363 Cache_wait();
365 // Leave the gate
366 GateMP_leave(gateHandle, key);
368 return ASP_DECOP_CB_SOK;
369 }
371 // Start reads from circular buffer
372 Int cbReadStart(
373 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
374 Int8 cbIdx // decoder output circular buffer index
375 )
376 {
377 IArg key;
378 GateMP_Handle gateHandle;
379 PAF_AST_DecOpCircBuf *pCb;
381 // Get gate handle
382 gateHandle = pCbCtl->gateHandle;
383 // Enter gate
384 key = GateMP_enter(gateHandle);
386 // Get circular buffer base pointer
387 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
389 // Invalidate circular buffer configuration
390 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
391 Cache_wait();
393 //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
395 // update flags
396 pCb->readerActiveFlag = 1;
398 // (***) FL: revisit
399 // Write back circular buffer configuration
400 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
401 Cache_wait();
403 // Leave the gate
404 GateMP_leave(gateHandle, key);
406 return ASP_DECOP_CB_SOK;
407 }
409 // Stop reads from circular buffer
410 Int cbReadStop(
411 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
412 Int8 cbIdx // decoder output circular buffer index
413 )
414 {
415 IArg key;
416 GateMP_Handle gateHandle;
417 PAF_AST_DecOpCircBuf *pCb;
419 // Get gate handle
420 gateHandle = pCbCtl->gateHandle;
421 // Enter gate
422 key = GateMP_enter(gateHandle);
424 // Get circular buffer base pointer
425 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
427 // Invalidate circular buffer configuration
428 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
429 Cache_wait();
431 //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
433 // update flags
434 pCb->readerActiveFlag = 0;
436 // (***) FL: revisit
437 // Write back circular buffer configuration
438 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
439 Cache_wait();
441 // Leave the gate
442 GateMP_leave(gateHandle, key);
444 return ASP_DECOP_CB_SOK;
445 }
447 // Read audio frame from circular buffer
448 Int cbReadAf(
449 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
450 Int8 cbIdx, // decoder output circular buffer index
451 PAF_AudioFrame *pAfRd // audio frame into which to read
452 )
453 {
454 IArg key;
455 GateMP_Handle gateHandle;
456 PAF_AST_DecOpCircBuf *pCb;
457 PAF_AudioFrame *pAfCb;
458 PAF_ChannelMask_HD streamMask;
459 Int8 i;
460 Int16 j;
462 // Get gate handle
463 gateHandle = pCbCtl->gateHandle;
464 // Enter gate
465 key = GateMP_enter(gateHandle);
467 // Get circular buffer base pointer
468 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
470 // (***) FL: revisit
471 // Invalidate circular buffer configuration.
472 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
473 Cache_wait();
475 //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
477 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
478 {
479 // This shouldn't occur:
480 // writer is active AND draining circular buffer
481 //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
482 SW_BREAKPOINT; // FL: debug
484 // Leave the gate
485 GateMP_leave(gateHandle, key);
487 return ASP_DECOP_CB_READ_INVSTATE;
488 }
490 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
491 {
492 //
493 // No active writer, not draining circular buffer.
494 // Skip UNDerflow check, mute output.
495 //
496 cbReadAfMute(pAfRd, pCb->strFrameLen);
498 // Leave the gate
499 GateMP_leave(gateHandle, key);
501 return ASP_DECOP_CB_SOK;
502 }
504 // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
505 // Here we are checking (1,0) state here
506 if ((pCb->writerActiveFlag == 1))
507 {
508 // check underflow
509 if (pCb->numAfCb <= 0)
510 {
511 //
512 // Increment underflow count.
513 // Mute output on underflow.
514 //
515 pCb->errUndCnt++;
516 cbReadAfMute(pAfRd, pCb->strFrameLen);
517 //SW_BREAKPOINT; // FL: debug
519 // Write back circular buffer configuration.
520 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
521 Cache_wait();
523 // Leave the gate
524 GateMP_leave(gateHandle, key);
526 return ASP_DECOP_CB_READ_UNDERFLOW;
527 }
528 }
530 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
531 {
532 //
533 // Writer active or draining remaining frames in circular buffer.
534 // Get next output audio frame.
535 //
537 // get pointer to current audio frame in circular buffer
538 pAfCb = &pCb->afCb[pCb->afRdIdx];
540 // (***) FL: revisit
541 // Invalidate audio frame
542 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
543 Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
544 for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
545 {
546 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
547 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
548 }
549 Cache_wait();
551 // compute stream mask
552 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
554 // Invalidate PCM data
555 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
556 {
557 if ((streamMask >> i) & 0x1)
558 {
559 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
560 }
561 }
562 Cache_wait();
564 // read audio frame information updated by decoder
565 pAfRd->sampleDecode = pAfCb->sampleDecode;
566 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
567 pAfRd->sampleRate = pAfCb->sampleRate;
568 pAfRd->sampleCount = pCb->strFrameLen;
569 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
570 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
572 // read metadata information updated by decoder //QIN
573 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
574 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
575 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
576 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
578 // read PCM samples
579 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
580 {
581 if ((streamMask >> i) & 0x1)
582 {
583 for (j = 0; j < pCb->strFrameLen; j++)
584 {
585 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
586 }
588 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
589 }
590 }
591 // read metadata //QIN
592 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
593 {
594 // FL: this is done above
595 ////Invalidate metadata data
596 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
597 //Cache_wait();
599 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
600 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
601 &&(pAfCb->pafPrivateMetadata[i].size))
602 {
603 // FL: this is done above
604 ////Invalidate metadata data
605 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
606 //Cache_wait();
608 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
609 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
610 pAfRd->pafPrivateMetadata[i].size = pAfCb->pafPrivateMetadata[i].size;
611 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
612 }
613 else //reset un-used buf
614 {
615 pAfRd->pafPrivateMetadata[i].offset = 0;
616 pAfRd->pafPrivateMetadata[i].size = 0;
617 }
618 }
620 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
621 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
622 {
623 // update audio frame read index
624 pCb->afRdIdx++;
625 if (pCb->afRdIdx >= pCb->maxNumAfCb)
626 {
627 pCb->afRdIdx = 0;
628 }
630 // update PCM read index
631 pCb->pcmRdIdx = 0;
633 // update number of audio frames in circular buffer
634 pCb->numAfCb--;
635 }
636 }
638 if (pCb->emptyFlag == 1)
639 {
640 //
641 // Writer inactive, but remaining frames in circular buffer.
642 // Update empty flag.
643 //
644 if (pCb->numAfCb <= 0)
645 {
646 pCb->emptyFlag = 0;
647 }
648 }
650 // (***) FL: revisit
651 // Write back circular buffer configuration.
652 // NOTE: Probably only a subset of this information needs to be updated.
653 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
654 Cache_wait();
656 // Leave the gate
657 GateMP_leave(gateHandle, key);
659 return ASP_DECOP_CB_SOK;
660 }
662 // Generate mute AF on circular buffer read
663 static Void cbReadAfMute(
664 PAF_AudioFrame *pAfRd, // audio frame into which to read
665 Int16 strFrameLen // stream frame length (output transaction size)
666 )
667 {
668 PAF_ChannelMask_HD streamMask;
669 Int8 i;
671 pAfRd->sampleDecode = PAF_SOURCE_PCM;
672 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
673 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
674 pAfRd->sampleCount = strFrameLen;
675 pAfRd->channelConfigurationRequest.full = 0;
676 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
677 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
678 pAfRd->channelConfigurationStream.full = 0;
679 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
680 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
682 // compute stream mask
683 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
684 // Clear PCM data
685 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
686 {
687 if ((streamMask >> i) & 0x1)
688 {
689 memset(pAfRd->data.sample[i], strFrameLen, 0);
690 }
691 pAfRd->data.samsiz[i] = 0;
692 }
693 }