[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 // Generate mute AF on circular buffer read
53 static Void cbReadAfMute(
54 PAF_AudioFrame *pAfRd, // audio frame into which to read
55 Int16 strFrameLen // stream frame length (output transaction size)
56 );
59 // Initialize circular buffer control
60 Int cbCtlInit(
61 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
62 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
63 )
64 {
65 GateMP_Params gateParams;
66 GateMP_Handle gateHandle;
68 GateMP_Params_init(&gateParams);
69 gateParams.localProtect = GateMP_LocalProtect_THREAD;
70 gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
71 gateParams.name = ASP_DECODE_CB_GATE_NAME;
72 gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
73 gateHandle = GateMP_create(&gateParams);
74 if (gateHandle != NULL)
75 {
76 pCbCtl->gateHandle = gateHandle;
77 }
78 else
79 {
80 pCbCtl->gateHandle = NULL;
81 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
82 }
84 pCbCtl->pXDecOpCb = pXDecOpCb;
86 return ASP_DECOP_CB_SOK;
88 }
90 // Initialize circular buffer
91 Int cbInit(
92 PAF_AST_DecOpCircBuf *pCb
93 )
94 {
95 PAF_AudioFrame *pAfCb;
96 PAF_AudioData *pPcmBuf;
97 UInt8 *pMetaBuf;
98 Int8 n;
99 Int8 i;
101 // set source select
102 pCb->sourceSel = DEF_SOURCE_SEL;
104 // set input frame length
105 pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
107 // set output frame length
108 pCb->strFrameLen = DEF_STR_FRAME_LEN;
110 // initialize circular buffer maximum number of audio frames
111 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
112 pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
113 pCb->afRdIdx = 0;
114 pCb->pcmRdIdx = 0; // 2*256 in behind
116 // initialize audio frames
117 for (n=0; n<pCb->maxNumAfCb; n++)
118 {
119 pAfCb = &pCb->afCb[n];
120 pAfCb->sampleDecode = PAF_SOURCE_PCM;
121 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
122 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
123 pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
124 pAfCb->channelConfigurationRequest.full = 0;
125 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
126 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
127 pAfCb->channelConfigurationStream.full = 0;
128 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
129 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
130 }
132 // initialize circular buffer current number of frames
133 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
135 // initialize audio frame PCM buffers
136 pPcmBuf = pCb->pcmBuf;
137 pMetaBuf = pCb->metaBuf; //QIN
138 for (n=0; n<pCb->maxNumAfCb; n++)
139 {
140 pAfCb = &pCb->afCb[n];
141 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
142 pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
143 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
144 {
145 pAfCb->data.sample[i] = pPcmBuf;
146 memset(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN, 0);
147 pPcmBuf += DEF_DEC_OP_FRAME_LEN;
149 pAfCb->data.samsiz[i] = 0;
150 }
152 // write metadata information updated by decoder
153 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
154 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
155 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
156 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
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 = ASP_DECOP_CB_MAX_NUM_AF_PCM;
249 // 2*256 in behind
250 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
251 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
252 pCb->pcmRdIdx = 0;
254 // initialize audio frames
255 for (n=0; n<pCb->maxNumAfCb; n++)
256 {
257 pAfCb = &pCb->afCb[n];
258 pAfCb->sampleDecode = sourceSelect;
259 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
260 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
261 pAfCb->sampleCount = decOpFrameLen;
262 pAfCb->channelConfigurationRequest.full = 0;
263 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
264 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
265 pAfCb->channelConfigurationStream.full = 0;
266 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
267 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
269 // write metadata information updated by decoder
270 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
271 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
272 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
273 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
274 }
275 }
276 else if (sourceSelect == PAF_SOURCE_DDP)
277 {
278 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
279 // 4*256 in behind
280 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
281 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
282 pCb->pcmRdIdx = decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
284 // initialize audio frames
285 for (n=0; n<pCb->maxNumAfCb; n++)
286 {
287 pAfCb = &pCb->afCb[n];
288 pAfCb->sampleDecode = sourceSelect;
289 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
290 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
291 pAfCb->sampleCount = decOpFrameLen;
292 pAfCb->channelConfigurationRequest.full = 0;
293 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
294 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
295 pAfCb->channelConfigurationStream.full = 0;
296 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
297 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
299 // write metadata information updated by decoder
300 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
301 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
302 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
303 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
304 }
305 }
306 else
307 {
308 SW_BREAKPOINT;
310 // Leave the gate
311 GateMP_leave(gateHandle, key);
313 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
314 }
316 // initialize circular buffer current number of frames
317 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
319 // initialize audio frame PCM buffers
320 pPcmBuf = pCb->pcmBuf;
321 pMetaBuf = pCb->metaBuf; //QIN
322 for (n=0; n<pCb->maxNumAfCb; n++)
323 {
324 pAfCb = &pCb->afCb[n];
325 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
326 pAfCb->data.nSamples = decOpFrameLen;
327 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
328 {
329 pAfCb->data.sample[i] = pPcmBuf;
330 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
331 pPcmBuf += decOpFrameLen;
333 pAfCb->data.samsiz[i] = 0;
334 }
336 // Initialize metadata buffers //QIN
337 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
338 {
339 pAfCb->pafPrivateMetadata[i].offset = 0;
340 pAfCb->pafPrivateMetadata[i].size = 0;
341 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
342 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
343 }
344 }
346 // reset read/write flags
347 if (resetRwFlags)
348 {
349 pCb->writerActiveFlag = 0;
350 pCb->readerActiveFlag = 0;
351 pCb->emptyFlag = 0;
352 }
354 // reset error counts
355 pCb->errUndCnt = 0;
356 pCb->errOvrCnt = 0;
358 // (***) FL: revisit
359 // Write back circular buffer configuration
360 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
361 // Write back AF circular buffer
362 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
363 // Write back PCM data
364 for (n=0; n<pCb->maxNumAfCb; n++)
365 {
366 pAfCb = &pCb->afCb[n];
367 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
368 Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
369 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
370 {
371 Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
372 }
373 // FL: unnecessary since part of AF
374 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
375 //{
376 // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
377 //}
378 }
379 Cache_wait();
381 // Leave the gate
382 GateMP_leave(gateHandle, key);
384 return ASP_DECOP_CB_SOK;
385 }
387 // Start reads from circular buffer
388 Int cbReadStart(
389 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
390 Int8 cbIdx // decoder output circular buffer index
391 )
392 {
393 IArg key;
394 GateMP_Handle gateHandle;
395 PAF_AST_DecOpCircBuf *pCb;
397 // Get gate handle
398 gateHandle = pCbCtl->gateHandle;
399 // Enter gate
400 key = GateMP_enter(gateHandle);
402 // Get circular buffer base pointer
403 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
405 // Invalidate circular buffer configuration
406 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
407 Cache_wait();
409 //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
411 // update flags
412 pCb->readerActiveFlag = 1;
414 // (***) FL: revisit
415 // Write back circular buffer configuration
416 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
417 Cache_wait();
419 // Leave the gate
420 GateMP_leave(gateHandle, key);
422 return ASP_DECOP_CB_SOK;
423 }
425 // Stop reads from circular buffer
426 Int cbReadStop(
427 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
428 Int8 cbIdx // decoder output circular buffer index
429 )
430 {
431 IArg key;
432 GateMP_Handle gateHandle;
433 PAF_AST_DecOpCircBuf *pCb;
435 // Get gate handle
436 gateHandle = pCbCtl->gateHandle;
437 // Enter gate
438 key = GateMP_enter(gateHandle);
440 // Get circular buffer base pointer
441 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
443 // Invalidate circular buffer configuration
444 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
445 Cache_wait();
447 //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
449 // update flags
450 pCb->readerActiveFlag = 0;
452 // (***) FL: revisit
453 // Write back circular buffer configuration
454 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
455 Cache_wait();
457 // Leave the gate
458 GateMP_leave(gateHandle, key);
460 return ASP_DECOP_CB_SOK;
461 }
463 // Read audio frame from circular buffer
464 Int cbReadAf(
465 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
466 Int8 cbIdx, // decoder output circular buffer index
467 PAF_AudioFrame *pAfRd // audio frame into which to read
468 )
469 {
470 IArg key;
471 GateMP_Handle gateHandle;
472 PAF_AST_DecOpCircBuf *pCb;
473 PAF_AudioFrame *pAfCb;
474 PAF_ChannelMask_HD streamMask;
475 Int8 i;
476 Int16 j;
478 // Get gate handle
479 gateHandle = pCbCtl->gateHandle;
480 // Enter gate
481 key = GateMP_enter(gateHandle);
483 // Get circular buffer base pointer
484 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
486 // (***) FL: revisit
487 // Invalidate circular buffer configuration.
488 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
489 Cache_wait();
491 //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
493 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
494 {
495 // This shouldn't occur:
496 // writer is active AND draining circular buffer
497 //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
498 SW_BREAKPOINT; // FL: debug
500 // Leave the gate
501 GateMP_leave(gateHandle, key);
503 return ASP_DECOP_CB_READ_INVSTATE;
504 }
506 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
507 {
508 //
509 // No active writer, not draining circular buffer.
510 // Skip UNDerflow check, mute output.
511 //
512 cbReadAfMute(pAfRd, pCb->strFrameLen);
514 // Leave the gate
515 GateMP_leave(gateHandle, key);
517 return ASP_DECOP_CB_SOK;
518 }
520 // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
521 // Here we are checking (1,0) state here
522 if ((pCb->writerActiveFlag == 1))
523 {
524 // check underflow
525 if (pCb->numAfCb <= 0)
526 {
527 //
528 // Increment underflow count.
529 // Mute output on underflow.
530 //
531 pCb->errUndCnt++;
532 cbReadAfMute(pAfRd, pCb->strFrameLen);
533 //SW_BREAKPOINT; // FL: debug
535 // Write back circular buffer configuration.
536 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
537 Cache_wait();
539 // Leave the gate
540 GateMP_leave(gateHandle, key);
542 return ASP_DECOP_CB_READ_UNDERFLOW;
543 }
544 }
546 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
547 {
548 //
549 // Writer active or draining remaining frames in circular buffer.
550 // Get next output audio frame.
551 //
553 // get pointer to current audio frame in circular buffer
554 pAfCb = &pCb->afCb[pCb->afRdIdx];
556 // (***) FL: revisit
557 // Invalidate audio frame
558 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
559 Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
560 for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
561 {
562 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
563 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
564 }
565 Cache_wait();
567 // compute stream mask
568 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
570 // Invalidate PCM data
571 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
572 {
573 if ((streamMask >> i) & 0x1)
574 {
575 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
576 }
577 }
578 Cache_wait();
580 // read audio frame information updated by decoder
581 pAfRd->sampleDecode = pAfCb->sampleDecode;
582 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
583 pAfRd->sampleRate = pAfCb->sampleRate;
584 pAfRd->sampleCount = pCb->strFrameLen;
585 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
586 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
588 // read metadata information updated by decoder //QIN
589 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
590 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
591 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
592 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
594 // read PCM samples
595 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
596 {
597 if ((streamMask >> i) & 0x1)
598 {
599 for (j = 0; j < pCb->strFrameLen; j++)
600 {
601 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
602 }
604 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
605 }
606 }
607 // read metadata //QIN
608 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
609 {
610 // FL: this is done above
611 ////Invalidate metadata data
612 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
613 //Cache_wait();
615 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
616 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
617 &&(pAfCb->pafPrivateMetadata[i].size))
618 {
619 // FL: this is done above
620 ////Invalidate metadata data
621 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
622 //Cache_wait();
624 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
625 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
626 pAfRd->pafPrivateMetadata[i].size = pAfCb->pafPrivateMetadata[i].size;
627 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
628 }
629 else //reset un-used buf
630 {
631 pAfRd->pafPrivateMetadata[i].offset = 0;
632 pAfRd->pafPrivateMetadata[i].size = 0;
633 }
634 }
636 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
637 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
638 {
639 // update audio frame read index
640 pCb->afRdIdx++;
641 if (pCb->afRdIdx >= pCb->maxNumAfCb)
642 {
643 pCb->afRdIdx = 0;
644 }
646 // update PCM read index
647 pCb->pcmRdIdx = 0;
649 // update number of audio frames in circular buffer
650 pCb->numAfCb--;
651 }
652 }
654 if (pCb->emptyFlag == 1)
655 {
656 //
657 // Writer inactive, but remaining frames in circular buffer.
658 // Update empty flag.
659 //
660 if (pCb->numAfCb <= 0)
661 {
662 pCb->emptyFlag = 0;
663 }
664 }
666 // (***) FL: revisit
667 // Write back circular buffer configuration.
668 // NOTE: Probably only a subset of this information needs to be updated.
669 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
670 Cache_wait();
672 // Leave the gate
673 GateMP_leave(gateHandle, key);
675 return ASP_DECOP_CB_SOK;
676 }
678 // Generate mute AF on circular buffer read
679 static Void cbReadAfMute(
680 PAF_AudioFrame *pAfRd, // audio frame into which to read
681 Int16 strFrameLen // stream frame length (output transaction size)
682 )
683 {
684 PAF_ChannelMask_HD streamMask;
685 Int8 i;
687 pAfRd->sampleDecode = PAF_SOURCE_PCM;
688 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
689 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
690 pAfRd->sampleCount = strFrameLen;
691 pAfRd->channelConfigurationRequest.full = 0;
692 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
693 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
694 pAfRd->channelConfigurationStream.full = 0;
695 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
696 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
698 // compute stream mask
699 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
700 // Clear PCM data
701 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
702 {
703 if ((streamMask >> i) & 0x1)
704 {
705 memset(pAfRd->data.sample[i], strFrameLen, 0);
706 }
707 pAfRd->data.samsiz[i] = 0;
708 }
709 // write metadata information updated by decoder
710 pAfRd->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
711 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
712 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
713 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
714 }