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 #include "evmc66x_gpio_dbg.h" // Debug
52 #ifdef CB_RW_OP_CAP_PP // debug
53 // Global variables
54 Uint32 *gCB_samples_op = NULL;
55 Uint8 *gCB_op_owner = NULL;
56 Uint32 *gCB_opCnt = 0;
57 Uint8 *gCB_afRdIdx = NULL;
58 Uint8 *gCB_afWrtIdx = NULL;
59 Uint8 *gCB_numAfCb = NULL;
60 #endif
62 #define DEF_SOURCE_SEL ( PAF_SOURCE_PCM ) // default source select
63 #define DEF_DEC_OP_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // ( 256 ) // default decoder output frame length
64 #define DEF_STR_FRAME_LEN ( PAF_SYS_FRAMELENGTH ) // default stream frame length
66 #if 0
67 // Generate mute AF on circular buffer read
68 static Void cbReadAfMute(
69 PAF_AudioFrame *pAfRd, // audio frame into which to read
70 Int16 strFrameLen // stream frame length (output transaction size)
71 );
72 #endif
74 // Init last audio frame configuration info
75 static Void cbInitLastAfInfo(
76 PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
77 );
79 // Generate mute AF on circular buffer read using the last AF configuration info
80 static Void cbReadMuteWithLastAfInfo (
81 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
82 PAF_AudioFrame *pAfRd // audio frame into which to read
83 );
85 // Initialize circular buffer control
86 Int cbCtlInit(
87 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
88 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
89 )
90 {
91 GateMP_Params gateParams;
92 GateMP_Handle gateHandle;
94 GateMP_Params_init(&gateParams);
95 gateParams.localProtect = GateMP_LocalProtect_THREAD;
96 gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
97 gateParams.name = ASP_DECODE_CB_GATE_NAME;
98 gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
99 gateHandle = GateMP_create(&gateParams);
100 if (gateHandle != NULL)
101 {
102 pCbCtl->gateHandle = gateHandle;
103 }
104 else
105 {
106 pCbCtl->gateHandle = NULL;
107 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
108 }
110 pCbCtl->pXDecOpCb = pXDecOpCb;
112 return ASP_DECOP_CB_SOK;
114 }
116 // Initialize circular buffer
117 Int cbInit(
118 PAF_AST_DecOpCircBuf *pCb
119 )
120 {
121 PAF_AudioFrame *pAfCb;
122 PAF_AudioData *pPcmBuf;
123 UInt8 *pMetaBuf;
124 Int8 n;
125 Int8 i;
127 // set source select
128 pCb->sourceSel = DEF_SOURCE_SEL;
130 // set input frame length
131 pCb->decOpFrameLen = DEF_DEC_OP_FRAME_LEN;
133 // set output frame length
134 pCb->strFrameLen = DEF_STR_FRAME_LEN;
136 // initialize circular buffer maximum number of audio frames
137 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;//ASP_DECOP_CB_MAX_NUM_AF_PCM;
138 pCb->afWrtIdx = ASP_DECOP_CB_INIT_LAG_PCM;
139 pCb->afRdIdx = 0;
140 pCb->pcmRdIdx = 0;
142 // Initialize CB primed flag
143 pCb->primedFlag = 0;
144 // Initialize delta samples
145 pCb->deltaSamps = 0;
147 // set default value to PCM configuration
148 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
149 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
150 // initialize audio frames
151 for (n=0; n<pCb->maxNumAfCb; n++)
152 {
153 pAfCb = &pCb->afCb[n];
154 pAfCb->sampleDecode = PAF_SOURCE_PCM;
155 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
156 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
157 pAfCb->sampleCount = DEF_DEC_OP_FRAME_LEN;
158 pAfCb->channelConfigurationRequest.full = 0;
159 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
160 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
161 pAfCb->channelConfigurationStream.full = 0;
162 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
163 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
164 }
166 // initialize circular buffer current number of frames
167 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
169 // initialize audio frame PCM buffers
170 pPcmBuf = pCb->pcmBuf;
171 pMetaBuf = pCb->metaBuf;
172 for (n=0; n<pCb->maxNumAfCb; n++)
173 {
174 pAfCb = &pCb->afCb[n];
175 pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
176 pAfCb->data.nSamples = DEF_DEC_OP_FRAME_LEN;
177 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
178 {
179 pAfCb->data.sample[i] = pPcmBuf;
180 memset(pAfCb->data.sample[i], 0, DEF_DEC_OP_FRAME_LEN);
181 pPcmBuf += DEF_DEC_OP_FRAME_LEN;
183 pAfCb->data.samsiz[i] = 0;
184 }
186 // write metadata information updated by decoder
187 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
188 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
189 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
190 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
192 // Initialize metadata buffers
193 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
194 {
195 pAfCb->pafPrivateMetadata[i].offset = 0;
196 pAfCb->pafPrivateMetadata[i].size = 0;
197 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
198 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
199 }
200 }
202 // reset read/write flags
203 pCb->writerActiveFlag = 0;
204 pCb->readerActiveFlag = 0;
205 pCb->emptyFlag = 0;
207 // reset error counts
208 pCb->errUndCnt = 0;
209 pCb->errOvrCnt = 0;
211 #ifdef CB_RW_OP_CAP_PP // debug
212 // Get address in global variables
213 gCB_samples_op = pCb->cb_samples_op;
214 gCB_op_owner = pCb->cb_op_owner;
215 gCB_opCnt = &pCb->cb_opCnt;
216 gCB_afRdIdx = pCb->cb_afRdIdx;
217 gCB_afWrtIdx = pCb->cb_afWrtIdx;
218 gCB_numAfCb = pCb->cb_numAfCb;
219 #endif
221 cbInitLastAfInfo(&pCb->lastAf);
223 // Write back circular buffer configuration
224 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
225 // Write back AF circular buffer
226 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
227 // Write back PCM data
228 for (n=0; n<pCb->maxNumAfCb; n++)
229 {
230 pAfCb = &pCb->afCb[n];
231 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
232 Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
233 for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
234 {
235 Cache_wb(pAfCb->data.sample[i], DEF_DEC_OP_FRAME_LEN*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
236 }
237 }
238 Cache_wait();
240 return ASP_DECOP_CB_SOK;
241 }
243 // Initialize circular buffer based on selected source
244 Int cbInitSourceSel(
245 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
246 Int8 cbIdx, // decoder output circular buffer index
247 Int8 sourceSelect, // source select (PCM, DDP, etc.)
248 Int16 decOpFrameLen, // decoder output frame length (PCM samples)
249 Int16 strFrameLen, // stream frame length (PCM samples)
250 Int8 resetRwFlags // whether to reset reader, writer, and empty flags
251 )
252 {
253 IArg key;
254 GateMP_Handle gateHandle;
255 PAF_AST_DecOpCircBuf *pCb;
256 PAF_AudioFrame *pAfCb;
257 PAF_AudioData *pPcmBuf;
258 UInt8 *pMetaBuf;
259 Int8 n;
260 Int8 i;
262 // Get gate handle
263 gateHandle = pCbCtl->gateHandle;
264 // Enter gate
265 key = GateMP_enter(gateHandle);
267 // Get circular buffer base pointer
268 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
270 // Invalidate circular buffer configuration
271 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
272 Cache_wait();
274 //Log_info1("cbInitSourceSel:afCb=0x%04x", (IArg)pCb->afCb); // debug
276 // set source select
277 pCb->sourceSel = sourceSelect;
279 // set input frame length
280 pCb->decOpFrameLen = decOpFrameLen;
282 // set output frame length
283 pCb->strFrameLen = strFrameLen;
285 //pCb->afInitialLag = 0; // default No lag
286 //pCb->afLagIdx = 0;
287 // Initialize CB primed flag
288 pCb->primedFlag = 0;
289 // Initialize delta samples
290 pCb->deltaSamps = 0;
292 // initialize circular buffer maximum number of audio frames
293 if (sourceSelect == PAF_SOURCE_PCM)
294 {
295 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_PCM;
297 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_PCM;
298 // Initialize target nominal delay
299 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kPCM;
301 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
302 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
303 pCb->pcmRdIdx = 0;
305 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH;
306 pCb->maxAFSampCount = DEF_DEC_OP_FRAME_LEN;
308 // initialize audio frames
309 for (n=0; n<pCb->maxNumAfCb; n++)
310 {
311 pAfCb = &pCb->afCb[n];
312 pAfCb->sampleDecode = sourceSelect;
313 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
314 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
315 pAfCb->sampleCount = decOpFrameLen;
316 pAfCb->channelConfigurationRequest.full = 0;
317 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
318 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
319 pAfCb->channelConfigurationStream.full = 0;
320 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
321 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
323 // write metadata information updated by decoder
324 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
325 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
326 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
327 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
328 }
329 }
330 else if ((sourceSelect == PAF_SOURCE_DDP) || (sourceSelect == PAF_SOURCE_AC3))
331 {
332 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_DDP;
334 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_DDP;
335 // Initialize target nominal delay
336 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kDDP;
338 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
339 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
340 pCb->pcmRdIdx = 0;
342 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_DDP;
343 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kDDP;
345 // initialize audio frames
346 for (n=0; n<pCb->maxNumAfCb; n++)
347 {
348 pAfCb = &pCb->afCb[n];
349 pAfCb->sampleDecode = sourceSelect;
350 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
351 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
352 pAfCb->sampleCount = decOpFrameLen;
353 pAfCb->channelConfigurationRequest.full = 0;
354 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
355 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
356 pAfCb->channelConfigurationStream.full = 0;
357 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
358 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
360 // write metadata information updated by decoder
361 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
362 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
363 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
364 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
365 }
366 }
367 else if (sourceSelect == PAF_SOURCE_THD)
368 {
369 pCb->maxNumAfCb = ASP_DECOP_CB_MAX_NUM_AF_THD;
371 //pCb->afInitialLag = ASP_DECOP_CB_INIT_LAG_THD;
372 // Initialize target nominal delay
373 pCb->targetNDSamps = ASP_DECOP_CB_TARGET_ND_SAMPS_48kTHD;
375 pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
376 pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
377 pCb->pcmRdIdx = 0;
379 pCb->maxAFChanNum = ASP_DECOP_CB_MAX_NUM_PCM_CH_MAT;
380 pCb->maxAFSampCount = ASP_DECOP_CB_MAX_PCM_FRAME_LEN_48kMAT;
382 // initialize audio frames
383 for (n=0; n<pCb->maxNumAfCb; n++)
384 {
385 pAfCb = &pCb->afCb[n];
386 pAfCb->sampleDecode = sourceSelect;
387 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
388 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
389 pAfCb->sampleCount = decOpFrameLen;
390 pAfCb->channelConfigurationRequest.full = 0;
391 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
392 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
393 pAfCb->channelConfigurationStream.full = 0;
394 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
395 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
397 // write metadata information updated by decoder
398 pAfCb->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
399 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
400 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
401 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
402 }
403 }
404 else
405 {
406 SW_BREAKPOINT;
408 // Leave the gate
409 GateMP_leave(gateHandle, key);
411 return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
412 }
414 // initialize circular buffer current number of frames
415 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
417 // initialize audio frame PCM buffers
418 pPcmBuf = pCb->pcmBuf;
419 pMetaBuf = pCb->metaBuf;
420 for (n=0; n<pCb->maxNumAfCb; n++)
421 {
422 pAfCb = &pCb->afCb[n];
423 pAfCb->data.nChannels = pCb->maxAFChanNum;
424 pAfCb->data.nSamples = decOpFrameLen;
425 for (i=0; i<pCb->maxAFChanNum; i++)
426 {
427 pAfCb->data.sample[i] = pPcmBuf;
428 memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
429 pPcmBuf += pCb->maxAFSampCount;
431 pAfCb->data.samsiz[i] = 0;
432 }
434 // Initialize metadata buffers
435 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
436 {
437 pAfCb->pafPrivateMetadata[i].offset = 0;
438 pAfCb->pafPrivateMetadata[i].size = 0;
439 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
440 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
441 }
442 }
444 // reset read/write flags
445 if (resetRwFlags)
446 {
447 pCb->writerActiveFlag = 0;
448 pCb->readerActiveFlag = 0;
449 pCb->emptyFlag = 0;
450 }
452 // reset error counts
453 pCb->errUndCnt = 0;
454 pCb->errOvrCnt = 0;
456 // Write back circular buffer configuration
457 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
458 // Write back AF circular buffer
459 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
460 // Write back PCM data
461 for (n=0; n<pCb->maxNumAfCb; n++)
462 {
463 pAfCb = &pCb->afCb[n];
464 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
465 Cache_wb(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
466 for (i=0; i<pCb->maxAFChanNum; i++)
467 {
468 Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
469 }
470 }
471 Cache_wait();
473 // Leave the gate
474 GateMP_leave(gateHandle, key);
476 return ASP_DECOP_CB_SOK;
477 }
479 // Start reads from circular buffer
480 Int cbReadStart(
481 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
482 Int8 cbIdx // decoder output circular buffer index
483 )
484 {
485 IArg key;
486 GateMP_Handle gateHandle;
487 PAF_AST_DecOpCircBuf *pCb;
489 // Get gate handle
490 gateHandle = pCbCtl->gateHandle;
491 // Enter gate
492 key = GateMP_enter(gateHandle);
494 // Get circular buffer base pointer
495 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
497 // Invalidate circular buffer configuration
498 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
499 Cache_wait();
501 //Log_info1("cbReadStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
503 // update flags
504 pCb->readerActiveFlag = 1;
506 // Write back circular buffer configuration
507 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
508 Cache_wait();
510 // Leave the gate
511 GateMP_leave(gateHandle, key);
513 return ASP_DECOP_CB_SOK;
514 }
516 // Stop reads from circular buffer
517 Int cbReadStop(
518 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
519 Int8 cbIdx // decoder output circular buffer index
520 )
521 {
522 IArg key;
523 GateMP_Handle gateHandle;
524 PAF_AST_DecOpCircBuf *pCb;
526 // Get gate handle
527 gateHandle = pCbCtl->gateHandle;
528 // Enter gate
529 key = GateMP_enter(gateHandle);
531 // Get circular buffer base pointer
532 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
534 // Invalidate circular buffer configuration
535 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
536 Cache_wait();
538 //Log_info1("cbReadStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
540 // update flags
541 pCb->readerActiveFlag = 0;
543 // Write back circular buffer configuration
544 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
545 Cache_wait();
547 // Leave the gate
548 GateMP_leave(gateHandle, key);
550 return ASP_DECOP_CB_SOK;
551 }
553 // Read audio frame from circular buffer
554 Int cbReadAf(
555 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
556 Int8 cbIdx, // decoder output circular buffer index
557 PAF_AudioFrame *pAfRd // audio frame into which to read
558 )
559 {
560 IArg key;
561 GateMP_Handle gateHandle;
562 PAF_AST_DecOpCircBuf *pCb;
563 PAF_AudioFrame *pAfCb;
564 PAF_ChannelMask_HD streamMask;
565 Int8 i;
566 Int16 j;
567 Int8 numMetadata = 0;
569 // Get gate handle
570 gateHandle = pCbCtl->gateHandle;
571 // Enter gate
572 key = GateMP_enter(gateHandle);
574 // Get circular buffer base pointer
575 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
577 // Invalidate circular buffer configuration.
578 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
579 Cache_wait();
581 //Log_info1("cbReadAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
583 if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
584 {
585 // This shouldn't occur:
586 // writer is active AND draining circular buffer
587 //Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag); // FL: debug
588 SW_BREAKPOINT; // FL: debug
590 // Leave the gate
591 GateMP_leave(gateHandle, key);
593 return ASP_DECOP_CB_READ_INVSTATE;
594 }
596 //if (((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0)) || (pCb->afLagIdx < pCb->afInitialLag))
597 if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
598 {
599 //
600 // No active writer, not draining circular buffer.
601 // Skip UNDerflow check, mute output.
602 //
603 //cbReadAfMute(pAfRd, pCb->strFrameLen);
604 cbReadMuteWithLastAfInfo(pCb, pAfRd);
606 // Leave the gate
607 GateMP_leave(gateHandle, key);
609 return ASP_DECOP_CB_SOK;
610 }
612 //if ((pCb->primedFlag == 0) || ((pCb->primedFlag==1) && (pCb->deltaSamps > 0))
613 if ((pCb->primedFlag == 0) || (pCb->deltaSamps > 0))
614 {
615 if (pCb->primedFlag == 1)
616 {
617 pCb->deltaSamps = pCb->deltaSamps - pCb->strFrameLen;
618 }
620 cbReadMuteWithLastAfInfo(pCb, pAfRd);
622 // Write back circular buffer configuration.
623 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
624 Cache_wait();
626 // Leave the gate
627 GateMP_leave(gateHandle, key);
629 return ASP_DECOP_CB_SOK;
630 }
633 // (writerActiveFlag,emptyFlag)=(1,0) and (0,1) are left
634 // Here we are checking (1,0) state here
635 if (pCb->writerActiveFlag == 1)
636 {
637 // check underflow
638 if (pCb->numAfCb <= 0)
639 {
640 //
641 // Increment underflow count.
642 // Mute output on underflow.
643 //
644 pCb->errUndCnt++;
645 //cbReadAfMute(pAfRd, pCb->strFrameLen);
646 cbReadMuteWithLastAfInfo(pCb, pAfRd);
647 //SW_BREAKPOINT; // FL: debug
649 {
650 static Uint8 toggleState = 0;
651 if (toggleState == 0)
652 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_107);
653 else
654 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_107);
655 toggleState = ~(toggleState);
656 }
658 #ifdef CB_RW_OP_CAP_PP // debug
659 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
660 {
661 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
662 {
663 // log sample count
664 pCb->cb_samples_op[pCb->cb_opCnt] = 0; // due to underflow
665 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
666 // log idxs
667 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
668 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
669 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
670 pCb->cb_opCnt++;
671 }
672 }
673 #endif
675 // Write back circular buffer configuration.
676 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
677 Cache_wait();
679 // Leave the gate
680 GateMP_leave(gateHandle, key);
682 return ASP_DECOP_CB_READ_UNDERFLOW;
683 }
684 }
686 if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
687 {
688 //
689 // Writer active or draining remaining frames in circular buffer.
690 // Get next output audio frame.
691 //
693 // get pointer to current audio frame in circular buffer
694 pAfCb = &pCb->afCb[pCb->afRdIdx];
696 // Invalidate audio frame
697 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
698 Cache_inv(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
699 for (i=0; i<pAfCb->numPrivateMetadata; i++) // only invalidate numPrivateMetadata
700 {
701 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // only update metadata package size
702 }
703 Cache_wait();
705 // compute stream mask
706 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
708 // Invalidate channel pointers
709 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
710 Cache_wait();
712 // Invalidate PCM data
713 for (i = 0; i < pCb->maxAFChanNum; i++)
714 {
715 if ((streamMask >> i) & 0x1)
716 {
717 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
718 }
719 }
720 Cache_wait();
722 // read audio frame information updated by decoder
723 pAfRd->sampleDecode = pAfCb->sampleDecode;
724 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
725 pAfRd->sampleRate = pAfCb->sampleRate;
726 pAfRd->sampleCount = pCb->strFrameLen;
727 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
728 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
730 // read metadata information updated by decoder
731 pAfRd->bsMetadata_type = pAfCb->bsMetadata_type; /* non zero if metadata is attached. */
732 pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
733 pAfRd->numPrivateMetadata = pAfCb->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
734 pAfRd->bsMetadata_offset = pAfCb->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
736 #ifdef CB_RW_OP_CAP_PP // debug
737 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
738 {
739 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
740 {
741 // log sample count
742 pCb->cb_samples_op[pCb->cb_opCnt] = pAfRd->sampleCount;
743 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_R;
744 // log idxs
745 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
746 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
747 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
748 pCb->cb_opCnt++;
749 }
750 }
751 #endif
753 // update Last Cb info as per actual stream
754 pCb->lastAf.sampleCount = pCb->strFrameLen;
755 pCb->lastAf.sampleRate = pAfCb->sampleRate;
757 // read PCM samples
758 for (i = 0; i < pCb->maxAFChanNum; i++)
759 {
760 if ((streamMask >> i) & 0x1)
761 {
762 for (j = 0; j < pCb->strFrameLen; j++)
763 {
764 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
765 }
767 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
768 }
769 }
771 for (i = 0; i < PAF_MAX_NUM_PRIVATE_MD; i++)
772 {
773 pAfRd->pafPrivateMetadata[i].offset = 0;
774 pAfRd->pafPrivateMetadata[i].size = 0;
775 }
777 // read metadata
778 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // only read numPrivateMetadata
779 {
780 if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx)
781 &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
782 &&(pAfCb->pafPrivateMetadata[i].size))
783 {
784 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
785 pAfRd->pafPrivateMetadata[numMetadata].offset = pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
786 pAfRd->pafPrivateMetadata[numMetadata].size = pAfCb->pafPrivateMetadata[i].size;
787 memcpy(pAfRd->pafPrivateMetadata[numMetadata].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
788 numMetadata++; //number of metadata associated with current 256 segment of audio samples
789 }
790 else //reset un-used buf
791 {
792 pAfRd->pafPrivateMetadata[i].offset = 0;
793 pAfRd->pafPrivateMetadata[i].size = 0;
794 }
796 }
797 pAfRd->numPrivateMetadata = numMetadata; //number of metadata associated with current 256 segment of audio samples
799 pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
800 if (pCb->pcmRdIdx >= pAfCb->sampleCount)
801 {
802 // update audio frame read index
803 pCb->afRdIdx++;
804 if (pCb->afRdIdx >= pCb->maxNumAfCb)
805 {
806 pCb->afRdIdx = 0;
807 }
809 // update PCM read index
810 pCb->pcmRdIdx = 0;
812 // update number of audio frames in circular buffer
813 pCb->numAfCb--;
814 }
815 memcpy (&pCb->lastAf, pAfRd, sizeof(PAF_AudioFrame));
817 {
818 static Uint8 toggleState = 0;
819 if (toggleState == 0)
820 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_106);
821 else
822 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_106);
823 toggleState = ~(toggleState);
824 }
825 }
827 if (pCb->emptyFlag == 1)
828 {
829 //
830 // Writer inactive, but remaining frames in circular buffer.
831 // Update empty flag.
832 //
833 if (pCb->numAfCb <= 0)
834 {
835 pCb->emptyFlag = 0;
836 }
837 }
839 // Write back circular buffer configuration.
840 // NOTE: Probably only a subset of this information needs to be updated.
841 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
842 Cache_wait();
844 // Leave the gate
845 GateMP_leave(gateHandle, key);
847 return ASP_DECOP_CB_SOK;
848 }
850 #if 0
851 // Generate mute AF on circular buffer read
852 static Void cbReadAfMute(
853 PAF_AudioFrame *pAfRd, // audio frame into which to read
854 Int16 strFrameLen // stream frame length (output transaction size)
855 )
856 {
857 PAF_ChannelMask_HD streamMask;
858 Int8 i;
860 pAfRd->sampleDecode = PAF_SOURCE_PCM;
861 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
862 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
863 pAfRd->sampleCount = strFrameLen;
864 pAfRd->channelConfigurationRequest.full = 0;
865 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
866 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
867 pAfRd->channelConfigurationStream.full = 0;
868 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
869 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
871 // compute stream mask
872 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
873 // Clear PCM data
874 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
875 {
876 if ((streamMask >> i) & 0x1)
877 {
878 memset(pAfRd->data.sample[i], 0, strFrameLen*sizeof(PAF_AudioData));
879 }
880 pAfRd->data.samsiz[i] = 0;
881 }
882 // write metadata information updated by decoder
883 pAfRd->bsMetadata_type = PAF_bsMetadata_channelData; /* non zero if metadata is attached. */
884 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
885 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
886 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
887 }
888 #endif
890 // Init last audio frame configuration info
891 static Void cbInitLastAfInfo(
892 PAF_AudioFrame *pAfRd // last audio frame stored in CB instance
893 )
894 {
895 pAfRd->sampleDecode = PAF_SOURCE_PCM;
896 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
897 pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
898 pAfRd->sampleCount = DEF_DEC_OP_FRAME_LEN;
899 pAfRd->channelConfigurationRequest.full = 0;
900 pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
901 pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
902 pAfRd->channelConfigurationStream.full = 0;
903 pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
904 pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
906 pAfRd->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
907 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
908 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
909 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
910 }
912 // Generate mute AF on circular buffer read using the last AF configuration info
913 static Void cbReadMuteWithLastAfInfo (
914 PAF_AST_DecOpCircBuf *pCb, // decoder output circular buffer control
915 PAF_AudioFrame *pAfRd // audio frame into which to read
916 )
917 {
918 PAF_ChannelMask_HD streamMask;
919 Int8 i;
921 pAfRd->sampleDecode = pCb->lastAf.sampleDecode;
922 PAF_PROCESS_ZERO(pAfRd->sampleProcess);
923 pAfRd->sampleRate = pCb->lastAf.sampleRate;
924 pAfRd->sampleCount = pCb->strFrameLen;
925 pAfRd->channelConfigurationRequest.full = pCb->lastAf.channelConfigurationRequest.full;
926 pAfRd->channelConfigurationRequest.part.sat = pCb->lastAf.channelConfigurationRequest.part.sat;
927 pAfRd->channelConfigurationRequest.part.sub = pCb->lastAf.channelConfigurationRequest.part.sub;
928 pAfRd->channelConfigurationStream.full = pCb->lastAf.channelConfigurationStream.full;
929 pAfRd->channelConfigurationStream.part.sat = pCb->lastAf.channelConfigurationStream.part.sat;
930 pAfRd->channelConfigurationStream.part.sub = pCb->lastAf.channelConfigurationStream.part.sub;
932 // compute stream mask
933 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
934 // Clear PCM data
935 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
936 {
937 if ((streamMask >> i) & 0x1)
938 {
939 memset(pAfRd->data.sample[i], 0, pAfRd->sampleCount*sizeof(PAF_AudioData));
940 }
941 pAfRd->data.samsiz[i] = 0;
942 }
943 pAfRd->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
944 pAfRd->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
945 pAfRd->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
946 pAfRd->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
947 }