2 /*
3 Copyright (c) 2017, 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 #include "dbgBenchmark.h" // PCM high-sampling rate + SRC + CAR benchmarking
50 #ifdef CB_RW_OP_CAP_PP
51 // Global variables
52 Uint32 *gCB_samples_op = NULL;
53 Uint8 *gCB_op_owner = NULL;
54 Uint32 *gCB_opCnt = 0;
55 Uint8 *gCB_afRdIdx = NULL;
56 Uint8 *gCB_afWrtIdx = NULL;
57 Uint8 *gCB_numAfCb = NULL;
58 #endif
60 #define DEF_SOURCE_SEL ( PAF_SOURCE_PCM ) // default source select
61 #define DEF_DEC_OP_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // ( 256 ) // default decoder output frame length
62 #define DEF_STR_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // default stream frame length
64 // Generate mute AF on circular buffer read
65 static Void cbReadAfMute(
66 PAF_AudioFrame *pAfRd, // audio frame into which to read
67 Int16 strFrameLen // stream frame length (output transaction size)
68 );
70 // Init last audio frame configuration info
71 static Void cbInitLastAfInfo(
72 PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
73 );
75 // Generate mute AF on circular buffer read using the last AF configuration info
76 static Void cbReadMuteWithLastAfInfo (
77 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
78 PAF_AudioFrame *pAfRd // audio frame into which to read
79 );
81 // Initialize circular buffer control
82 Int cbCtlInit(
83 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
84 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
85 )
86 {
87 GateMP_Params gateParams;
88 GateMP_Handle gateHandle;
90 GateMP_Params_init(&gateParams);
91 gateParams.localProtect = GateMP_LocalProtect_THREAD;
92 gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
93 gateParams.name = ASP_DECODE_CB_GATE_NAME;
94 gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
95 gateHandle = GateMP_create(&gateParams);
96 if (gateHandle != NULL)
97 {
98 pCbCtl->gateHandle = gateHandle;
99 }
100 else
101 {
102 pCbCtl->gateHandle = NULL;
103 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
104 }
106 pCbCtl->pXDecOpCb = pXDecOpCb;
108 return ASP_DECOP_CB_SOK;
110 }
112 // Initialize circular buffer
113 Int cbInit(
114 PAF_AST_DecOpCircBuf *pCb
115 )
116 {
117 PAF_AudioFrame *pAfCb;
118 PAF_AudioData *pPcmBuf;
119 UInt8 *pMetaBuf;
120 Int8 n;
121 Int8 i;
123 // set source select
124 pCb->sourceSel = DEF_SOURCE_SEL;
126 // set input frame length
127 pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
129 // set output frame length
130 pCb->strFrameLen = DEF_STR_FRAME_LEN;
132 // initialize circular buffer maximum number of audio frames
133 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;//ASP_DECOP_CB_MAX_NUM_AF_PCM;
134 pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
135 pCb->afRdIdx = 0;
136 pCb->pcmRdIdx = 0; // 2*256 in behind
138 // set default value to PCM configuration
139 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
140 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
141 // initialize audio frames
142 for (n=0; n<pCb->maxNumAfCb; n++)
143 {
144 pAfCb = &pCb->afCb[n];
145 pAfCb->sampleDecode = PAF_SOURCE_PCM;
146 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
147 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
148 pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
149 pAfCb->channelConfigurationRequest.full = 0;
150 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
151 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
152 pAfCb->channelConfigurationStream.full = 0;
153 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
154 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
155 }
157 // initialize circular buffer current number of frames
158 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
160 // initialize audio frame PCM buffers
161 pPcmBuf = pCb->pcmBuf;
162 pMetaBuf = pCb->metaBuf; //QIN
163 for (n=0; n<pCb->maxNumAfCb; n++)
164 {
165 pAfCb = &pCb->afCb[n];
166 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
167 pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
168 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
169 {
170 pAfCb->data.sample[i] = pPcmBuf;
171 memset(pAfCb->data.sample[i], 0, DEF_DEC_OP_FRAME_LEN);
172 pPcmBuf += DEF_DEC_OP_FRAME_LEN;
174 pAfCb->data.samsiz[i] = 0;
175 }
177 // write metadata information updated by decoder
178 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
179 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
180 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
181 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
183 // Initialize metadata buffers //QIN
184 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
185 {
186 pAfCb->pafPrivateMetadata[i].offset = 0;
187 pAfCb->pafPrivateMetadata[i].size = 0;
188 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
189 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
190 }
191 }
193 // reset read/write flags
194 pCb->writerActiveFlag = 0;
195 pCb->readerActiveFlag = 0;
196 pCb->emptyFlag = 0;
198 // reset error counts
199 pCb->errUndCnt = 0;
200 pCb->errOvrCnt = 0;
202 #ifdef CB_RW_OP_CAP_PP
203 // Get address in global variables
204 gCB_samples_op = pCb->cb_samples_op;
205 gCB_op_owner = pCb->cb_op_owner;
206 gCB_opCnt = &pCb->cb_opCnt;
207 gCB_afRdIdx = pCb->cb_afRdIdx;
208 gCB_afWrtIdx = pCb->cb_afWrtIdx;
209 gCB_numAfCb = pCb->cb_numAfCb;
210 #endif
212 cbInitLastAfInfo(&pCb->lastAf);
214 // (***) FL: revisit
215 // Write back circular buffer configuration
216 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
217 // Write back AF circular buffer
218 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
219 // Write back PCM data
220 for (n=0; n<pCb->maxNumAfCb; n++)
221 {
222 pAfCb = &pCb->afCb[n];
223 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
224 Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
225 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
226 {
227 Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
228 }
229 // FL: unnecessary since part of AF
230 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) // Write back metadata //QIN
231 //{
232 // Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
233 //}
234 }
235 Cache_wait();
237 return ASP_DECOP_CB_SOK;
238 }
240 // Initialize circular buffer based on selected source
241 Int cbInitSourceSel(
242 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
243 Int8 cbIdx, // decoder output circular buffer index
244 Int8 sourceSelect, // source select (PCM, DDP, etc.)
245 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
246 Int16 strFrameLen, // stream frame length (PCM samples)
247 Int8 resetRwFlags // whether to reset reader, writer, and empty flags
248 )
249 {
250 IArg key;
251 GateMP_Handle gateHandle;
252 PAF_AST_DecOpCircBuf *pCb;
253 PAF_AudioFrame *pAfCb;
254 PAF_AudioData *pPcmBuf;
255 UInt8 *pMetaBuf; //QIN
256 Int8 n;
257 Int8 i;
259 // Get gate handle
260 gateHandle = pCbCtl->gateHandle;
261 // Enter gate
262 key = GateMP_enter(gateHandle);
264 // Get circular buffer base pointer
265 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
267 // Invalidate circular buffer configuration
268 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
269 Cache_wait();
271 //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
273 // set source select
274 pCb->sourceSel = sourceSelect;
276 // set input frame length
277 pCb->decOpFrameLen = decOpFrameLen;
279 // set output frame length
280 pCb->strFrameLen = strFrameLen;
282 pCb->afInitialLag = 0; // default No lag
283 pCb->afLagIdx = 0;
286 // initialize circular buffer maximum number of audio frames
287 if (sourceSelect == PAF_SOURCE_PCM)
288 {
289 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
290 // 2*256 in behind
291 pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
292 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
293 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
294 pCb->pcmRdIdx = 0;
295 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
296 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
298 // initialize audio frames
299 for (n=0; n<pCb->maxNumAfCb; n++)
300 {
301 pAfCb = &pCb->afCb[n];
302 pAfCb->sampleDecode = sourceSelect;
303 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
304 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
305 pAfCb->sampleCount = decOpFrameLen;
306 pAfCb->channelConfigurationRequest.full = 0;
307 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
308 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
309 pAfCb->channelConfigurationStream.full = 0;
310 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
311 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
313 // write metadata information updated by decoder
314 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
315 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
316 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
317 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
318 }
319 }
320 else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
321 {
322 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
323 // 4*256 in behind
324 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
325 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
326 pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
327 pCb->pcmRdIdx = 0; //decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DDP*strFrameLen; // 4*256 behind
328 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
329 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
331 // initialize audio frames
332 for (n=0; n<pCb->maxNumAfCb; n++)
333 {
334 pAfCb = &pCb->afCb[n];
335 pAfCb->sampleDecode = sourceSelect;
336 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
337 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
338 pAfCb->sampleCount = decOpFrameLen;
339 pAfCb->channelConfigurationRequest.full = 0;
340 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
341 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
342 pAfCb->channelConfigurationStream.full = 0;
343 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
344 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
346 // write metadata information updated by decoder
347 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
348 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
349 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
350 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
351 }
352 }
353 else if (sourceSelect == PAF_SOURCE_THD)
354 {
355 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
356 pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
357 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
358 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
359 pCb->pcmRdIdx = 0;
360 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
361 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
363 // initialize audio frames
364 for (n=0; n<pCb->maxNumAfCb; n++)
365 {
366 pAfCb = &pCb->afCb[n];
367 pAfCb->sampleDecode = sourceSelect;
368 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
369 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
370 pAfCb->sampleCount = decOpFrameLen;
371 pAfCb->channelConfigurationRequest.full = 0;
372 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
373 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
374 pAfCb->channelConfigurationStream.full = 0;
375 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
376 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
378 // write metadata information updated by decoder
379 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
380 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
381 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
382 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
383 }
384 }
385 else
386 {
387 SW_BREAKPOINT;
389 // Leave the gate
390 GateMP_leave(gateHandle, key);
392 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
393 }
395 // initialize circular buffer current number of frames
396 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
398 // initialize audio frame PCM buffers
399 pPcmBuf = pCb->pcmBuf;
400 pMetaBuf = pCb->metaBuf; //QIN
401 for (n=0; n<pCb->maxNumAfCb; n++)
402 {
403 pAfCb = &pCb->afCb[n];
404 pAfCb->data.nChannels = pCb->maxAFChanNum;
405 pAfCb->data.nSamples = decOpFrameLen;
406 for (i=0; i<pCb->maxAFChanNum; i++)
407 {
408 pAfCb->data.sample[i] = pPcmBuf;
409 memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
410 pPcmBuf += pCb->maxAFSampCount;
412 pAfCb->data.samsiz[i] = 0;
413 }
415 // Initialize metadata buffers //QIN
416 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
417 {
418 pAfCb->pafPrivateMetadata[i].offset = 0;
419 pAfCb->pafPrivateMetadata[i].size = 0;
420 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
421 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
422 }
423 }
425 // reset read/write flags
426 if (resetRwFlags)
427 {
428 pCb->writerActiveFlag = 0;
429 pCb->readerActiveFlag = 0;
430 pCb->emptyFlag = 0;
431 }
433 // reset error counts
434 pCb->errUndCnt = 0;
435 pCb->errOvrCnt = 0;
437 // (***) FL: revisit
438 // Write back circular buffer configuration
439 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
440 // Write back AF circular buffer
441 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
442 // Write back PCM data
443 for (n=0; n<pCb->maxNumAfCb; n++)
444 {
445 pAfCb = &pCb->afCb[n];
446 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
447 Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
448 for (i=0; i<pCb->maxAFChanNum; i++)
449 {
450 Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
451 }
452 }
453 Cache_wait();
455 // Leave the gate
456 GateMP_leave(gateHandle, key);
458 return ASP_DECOP_CB_SOK;
459 }
461 // Start reads from circular buffer
462 Int cbReadStart(
463 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
464 Int8 cbIdx // decoder output circular buffer index
465 )
466 {
467 IArg key;
468 GateMP_Handle gateHandle;
469 PAF_AST_DecOpCircBuf *pCb;
471 // Get gate handle
472 gateHandle = pCbCtl->gateHandle;
473 // Enter gate
474 key = GateMP_enter(gateHandle);
476 // Get circular buffer base pointer
477 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
479 // Invalidate circular buffer configuration
480 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
481 Cache_wait();
483 //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
485 // update flags
486 pCb->readerActiveFlag = 1;
488 // (***) FL: revisit
489 // Write back circular buffer configuration
490 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
491 Cache_wait();
493 // Leave the gate
494 GateMP_leave(gateHandle, key);
496 return ASP_DECOP_CB_SOK;
497 }
499 // Stop reads from circular buffer
500 Int cbReadStop(
501 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
502 Int8 cbIdx // decoder output circular buffer index
503 )
504 {
505 IArg key;
506 GateMP_Handle gateHandle;
507 PAF_AST_DecOpCircBuf *pCb;
509 // Get gate handle
510 gateHandle = pCbCtl->gateHandle;
511 // Enter gate
512 key = GateMP_enter(gateHandle);
514 // Get circular buffer base pointer
515 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
517 // Invalidate circular buffer configuration
518 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
519 Cache_wait();
521 //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
523 // update flags
524 pCb->readerActiveFlag = 0;
526 // (***) FL: revisit
527 // Write back circular buffer configuration
528 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
529 Cache_wait();
531 // Leave the gate
532 GateMP_leave(gateHandle, key);
534 return ASP_DECOP_CB_SOK;
535 }
537 // Read audio frame from circular buffer
538 Int cbReadAf(
539 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
540 Int8 cbIdx, // decoder output circular buffer index
541 PAF_AudioFrame *pAfRd // audio frame into which to read
542 )
543 {
544 IArg key;
545 GateMP_Handle gateHandle;
546 PAF_AST_DecOpCircBuf *pCb;
547 PAF_AudioFrame *pAfCb;
548 PAF_ChannelMask_HD streamMask;
549 Int8 i;
550 Int16 j;
551 Int8 numMetadata = 0;
553 // Get gate handle
554 gateHandle = pCbCtl->gateHandle;
555 // Enter gate
556 key = GateMP_enter(gateHandle);
558 // Get circular buffer base pointer
559 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
561 // (***) FL: revisit
562 // Invalidate circular buffer configuration.
563 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
564 Cache_wait();
566 //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
568 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
569 {
570 // This shouldn't occur:
571 // writer is active AND draining circular buffer
572 //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
573 SW_BREAKPOINT; // FL: debug
575 // Leave the gate
576 GateMP_leave(gateHandle, key);
578 return ASP_DECOP_CB_READ_INVSTATE;
579 }
581 if (((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
582 {
583 //
584 // No active writer, not draining circular buffer.
585 // Skip UNDerflow check, mute output.
586 //
587 //cbReadAfMute(pAfRd, pCb->strFrameLen);
588 cbReadMuteWithLastAfInfo(pCb, pAfRd);
590 // Leave the gate
591 GateMP_leave(gateHandle, key);
593 return ASP_DECOP_CB_SOK;
594 }
596 // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
597 // Here we are checking (1,0) state here
598 if (pCb->writerActiveFlag == 1)
599 {
600 // check underflow
601 if (pCb->numAfCb <= 0)
602 {
603 //
604 // Increment underflow count.
605 // Mute output on underflow.
606 //
607 pCb->errUndCnt++;
608 //cbReadAfMute(pAfRd, pCb->strFrameLen);
609 cbReadMuteWithLastAfInfo(pCb, pAfRd);
610 //SW_BREAKPOINT; // FL: debug
612 {
613 static Uint8 toggleState = 0;
614 if (toggleState == 0)
615 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
616 else
617 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
618 toggleState = ~(toggleState);
619 }
621 #ifdef CB_RW_OP_CAP_PP
622 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
623 {
624 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
625 {
626 // log sample count
627 pCb->cb_samples_op[pCb->cb_opCnt] = 0; // due to underflow
628 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
629 // log idxs
630 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
631 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
632 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
633 pCb->cb_opCnt++;
634 }
635 }
636 #endif
638 // Write back circular buffer configuration.
639 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
640 Cache_wait();
642 // Leave the gate
643 GateMP_leave(gateHandle, key);
645 return ASP_DECOP_CB_READ_UNDERFLOW;
646 }
647 }
649 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
650 {
651 //
652 // Writer active or draining remaining frames in circular buffer.
653 // Get next output audio frame.
654 //
656 // get pointer to current audio frame in circular buffer
657 pAfCb = &pCb->afCb[pCb->afRdIdx];
659 // (***) FL: revisit
660 // Invalidate audio frame
661 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
662 Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
663 for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
664 {
665 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
666 }
667 Cache_wait();
669 // compute stream mask
670 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
672 // Invalidate channel pointers
673 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
674 Cache_wait();
676 // Invalidate PCM data
677 for (i = 0; i < pCb->maxAFChanNum; i++)
678 {
679 if ((streamMask >> i) & 0x1)
680 {
681 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
682 }
683 }
684 Cache_wait();
686 // read audio frame information updated by decoder
687 pAfRd->sampleDecode = pAfCb->sampleDecode;
688 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
689 pAfRd->sampleRate = pAfCb->sampleRate;
690 pAfRd->sampleCount = pCb->strFrameLen;
691 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
692 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
694 // read metadata information updated by decoder //QIN
695 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
696 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
697 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
698 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
700 #ifdef CB_RW_OP_CAP_PP
701 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
702 {
703 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
704 {
705 // log sample count
706 pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
707 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
708 // log idxs
709 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
710 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
711 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
712 pCb->cb_opCnt++;
713 }
714 }
715 #endif
717 // update Last Cb info as per actual stream
718 pCb->lastAf.sampleCount = pCb->strFrameLen;
719 pCb->lastAf.sampleRate = pAfCb->sampleRate;
721 // read PCM samples
722 for (i = 0; i < pCb->maxAFChanNum; i++)
723 {
724 if ((streamMask >> i) & 0x1)
725 {
726 for (j = 0; j < pCb->strFrameLen; j++)
727 {
728 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
729 }
731 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
732 }
733 }
735 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
736 {
737 pAfRd->pafPrivateMetadata[i].offset = 0;
738 pAfRd->pafPrivateMetadata[i].size = 0;
739 }
741 // read metadata //QIN
742 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
743 {
744 // FL: this is done above
745 ////Invalidate metadata data
746 //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
747 //Cache_wait();
749 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
750 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
751 &&(pAfCb->pafPrivateMetadata[i].size))
752 {
753 // FL: this is done above
754 ////Invalidate metadata data
755 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
756 //Cache_wait();
758 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
759 pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
760 pAfRd->pafPrivateMetadata[numMetadata].size = pAfCb->pafPrivateMetadata[i].size;
761 memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
762 numMetadata++; //number of metadata associated with current 256 segment of audio samples
763 }
764 else //reset un-used buf
765 {
766 pAfRd->pafPrivateMetadata[i].offset = 0;
767 pAfRd->pafPrivateMetadata[i].size = 0;
768 }
770 }
771 pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
773 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
774 if (pCb->pcmRdIdx >= pAfCb->sampleCount)
775 {
776 // update audio frame read index
777 pCb->afRdIdx++;
778 if (pCb->afRdIdx >= pCb->maxNumAfCb)
779 {
780 pCb->afRdIdx = 0;
781 }
783 // update PCM read index
784 pCb->pcmRdIdx = 0;
786 // update number of audio frames in circular buffer
787 pCb->numAfCb--;
788 }
789 memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
791 {
792 static Uint8 toggleState = 0;
793 if (toggleState == 0)
794 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
795 else
796 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
797 toggleState = ~(toggleState);
798 }
799 }
801 if (pCb->emptyFlag == 1)
802 {
803 //
804 // Writer inactive, but remaining frames in circular buffer.
805 // Update empty flag.
806 //
807 if (pCb->numAfCb <= 0)
808 {
809 pCb->emptyFlag = 0;
810 }
811 }
813 // (***) FL: revisit
814 // Write back circular buffer configuration.
815 // NOTE: Probably only a subset of this information needs to be updated.
816 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
817 Cache_wait();
819 // Leave the gate
820 GateMP_leave(gateHandle, key);
822 return ASP_DECOP_CB_SOK;
823 }
825 // Generate mute AF on circular buffer read
826 static Void cbReadAfMute(
827 PAF_AudioFrame *pAfRd, // audio frame into which to read
828 Int16 strFrameLen // stream frame length (output transaction size)
829 )
830 {
831 PAF_ChannelMask_HD streamMask;
832 Int8 i;
834 pAfRd->sampleDecode = PAF_SOURCE_PCM;
835 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
836 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
837 pAfRd->sampleCount = strFrameLen;
838 pAfRd->channelConfigurationRequest.full = 0;
839 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
840 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
841 pAfRd->channelConfigurationStream.full = 0;
842 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
843 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
845 // compute stream mask
846 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
847 // Clear PCM data
848 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
849 {
850 if ((streamMask >> i) & 0x1)
851 {
852 memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
853 }
854 pAfRd->data.samsiz[i] = 0;
855 }
856 // write metadata information updated by decoder
857 pAfRd->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
858 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
859 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
860 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
861 }
862 // Init last audio frame configuration info
863 static Void cbInitLastAfInfo(
864 PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
865 )
866 {
867 pAfRd->sampleDecode = PAF_SOURCE_PCM;
868 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
869 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
870 pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
871 pAfRd->channelConfigurationRequest.full = 0;
872 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
873 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
874 pAfRd->channelConfigurationStream.full = 0;
875 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
876 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
878 pAfRd->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
879 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
880 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
881 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
882 }
884 // Generate mute AF on circular buffer read using the last AF configuration info
885 static Void cbReadMuteWithLastAfInfo (
886 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
887 PAF_AudioFrame *pAfRd // audio frame into which to read
888 )
889 {
890 PAF_ChannelMask_HD streamMask;
891 Int8 i;
893 pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
894 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
895 pAfRd->sampleRate = pCb->lastAf.sampleRate;
896 pAfRd->sampleCount = pCb->strFrameLen;
897 pAfRd->channelConfigurationRequest.full = pCb->lastAf.channelConfigurationRequest.full;
898 pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat;
899 pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
900 pAfRd->channelConfigurationStream.full = pCb->lastAf.channelConfigurationStream.full;
901 pAfRd->channelConfigurationStream.part.sat = pCb->lastAf.channelConfigurationStream.part.sat;
902 pAfRd->channelConfigurationStream.part.sub = pCb->lastAf.channelConfigurationStream.part.sub;
904 // compute stream mask
905 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
906 // Clear PCM data
907 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
908 {
909 if ((streamMask >> i) & 0x1)
910 {
911 memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
912 }
913 pAfRd->data.samsiz[i] = 0;
914 }
915 pAfRd->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
916 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
917 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
918 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
919 }