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>
42 #include "common.h"
43 #include "paftyp.h"
44 //#include "pafdec.h"
45 //#include "pafsp.h"
46 #include "aspDecOpCircBuf_slave.h"
48 #include "evmc66x_gpio_dbg.h" // Debug
50 #if 0
51 // Initialize circular buffer control
52 Int cbCtlInit(
53 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
54 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
55 )
56 {
57 GateMP_Handle gateHandle;
58 Int status;
60 do {
61 status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
62 } while (status == GateMP_E_NOTFOUND);
63 if (status == GateMP_S_SUCCESS)
64 {
65 pCbCtl->gateHandle = gateHandle;
66 }
67 else
68 {
69 pCbCtl->gateHandle = NULL;
70 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
71 }
73 pCbCtl->numCb = numCb; // init number of circular buffers
74 pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
76 return ASP_DECOP_CB_SOK;
77 }
78 #endif
80 //Int8 gCbWriteStartCnt=0; // debug
82 // Start writes to circular buffer
83 Int cbWriteStart(
84 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
85 Int8 cbIdx // decoder output circular buffer index
86 )
87 {
88 IArg key;
89 GateMP_Handle gateHandle;
90 PAF_AST_DecOpCircBuf *pCb;
91 PAF_AudioFrame *pAfCb;
92 Int8 n;
93 //Int8 i;
95 //gCbWriteStartCnt++; // debug
97 // Get gate handle
98 gateHandle = pCbCtl->gateHandle;
99 // Enter gate
100 key = GateMP_enter(gateHandle);
102 // Get circular buffer base pointer
103 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
105 // Invalidate circular buffer configuration.
106 // NOTE: Probably only a subset of this information needs to be updated.
107 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
108 Cache_wait();
110 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
112 // Invalidate AF circular buffer
113 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
114 for (n=0; n<pCb->maxNumAfCb; n++)
115 {
116 pAfCb = &pCb->afCb[n];
117 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
118 }
119 Cache_wait();
121 // update flags
122 pCb->writerActiveFlag = 1;
123 pCb->drainFlag = 0;
124 //pCb->afLagIdx = 0;
126 // Write back circular buffer configuration
127 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
128 Cache_wait();
130 // Leave the gate
131 GateMP_leave(gateHandle, key);
133 return ASP_DECOP_CB_SOK;
134 };
136 // Stop writes to circular buffer
137 Int cbWriteStop(
138 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
139 Int8 cbIdx // decoder output circular buffer index
140 )
141 {
142 IArg key;
143 GateMP_Handle gateHandle;
144 PAF_AST_DecOpCircBuf *pCb;
146 // Get gate handle
147 gateHandle = pCbCtl->gateHandle;
148 // Enter gate
149 key = GateMP_enter(gateHandle);
151 // Get circular buffer base pointer
152 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
154 // Invalidate circular buffer configuration
155 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
156 Cache_wait();
158 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
160 // update flags
161 pCb->writerActiveFlag = 0;
162 pCb->drainFlag = 1;
164 // Write back circular buffer configuration
165 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
166 Cache_wait();
168 // Leave the gate
169 GateMP_leave(gateHandle, key);
171 return ASP_DECOP_CB_SOK;
172 }
174 // debug
175 //Int16 gSampleCountBuf[10];
176 //Int16 gCalcDeltaSampsBuf[10];
177 //Int8 gPrimedFlagCnt=0;
179 // (***) FL: revisit
180 // Write audio frame to circular buffer
181 Int cbWriteAf(
182 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
183 Int8 cbIdx, // decoder output circular buffer index
184 PAF_AudioFrame *pAfWrt // audio frame from which to write
185 )
186 {
187 IArg key;
188 GateMP_Handle gateHandle;
189 PAF_AST_DecOpCircBuf *pCb;
190 PAF_AudioFrame *pAfCb;
191 PAF_ChannelMask_HD streamMask;
192 Int8 i;
193 Int16 j;
194 PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
196 // Get gate handle
197 gateHandle = pCbCtl->gateHandle;
198 // Enter gate
199 key = GateMP_enter(gateHandle);
201 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
203 // Get circular buffer base pointer
204 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
205 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
207 // Invalidate circular buffer configuration.
208 // NOTE: Probably only a subset of this information needs to be updated.
209 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
210 Cache_wait();
212 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
213 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
215 //if (pCb->readerActiveFlag == 1)
216 //{
217 // //
218 // // Normal case, reader active.
219 // //
221 if (pAfWrt->sampleCount != 0)
222 {
223 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // debug
225 // check overflow
226 //while (pCb->numAfCb >= pCb->maxNumAfCb); // debug
227 if (pCb->numAfCb >= pCb->maxNumAfCb)
228 {
229 pCb->errOvrCnt++;
231 //SW_BREAKPOINT;
232 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
234 // Write back circular buffer configuration
235 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
236 Cache_wait();
238 // Leave the gate
239 GateMP_leave(gateHandle, key);
241 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
243 return ASP_DECOP_CB_WRITE_OVERFLOW;
244 }
246 pAfCb = &pCb->afCb[pCb->afWrtIdx];
247 pPcmBuf = pAfCb->data.sample[0];
248 pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
249 if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
250 {
251 pPcmBuf = pCb->pcmBuf;
252 }
254 for (i=0; i<pCb->maxAFChanNum; i++)
255 {
256 pAfCb->data.sample[i] = pPcmBuf;
257 pPcmBuf += pAfWrt->sampleCount;
258 pAfCb->data.samsiz[i] = 0;
259 }
260 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
261 Cache_wait();
263 //for (i=0; i<pCb->maxAFChanNum; i++){
264 //}
265 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
266 {
267 pAfCb->pafPrivateMetadata[i].offset = 0;
268 pAfCb->pafPrivateMetadata[i].size = 0;
269 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
270 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
271 }
273 nextWrtIdx = 0;
274 if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
275 {
276 //Log_info0("cbWriteAf: AF Wrap around **** ");
277 // next audio frame will be audio frame 0
278 nextWrtIdx = 0;
279 }
280 else
281 {
282 // next audio frame will be current audio frame + 1
283 nextWrtIdx = pCb->afWrtIdx + 1;
284 }
286 pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
287 pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
289 // write audio frame information updated by decoder
290 pAfCb->sampleDecode = pAfWrt->sampleDecode;
291 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
292 pAfCb->sampleRate = pAfWrt->sampleRate;
293 pAfCb->sampleCount = pAfWrt->sampleCount;
294 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
295 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
296 // write metadata information updated by decoder
297 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
298 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
299 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
300 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
301 // write PCM samples
302 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
303 for (i = 0; i < pCb->maxAFChanNum; i++)
304 {
305 if ((streamMask >> i) & 0x1)
306 {
307 for (j = 0; j < pAfWrt->sampleCount; j++)
308 {
309 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
310 }
312 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
313 }
314 }
316 #ifdef CB_RW_OP_CAP_PP // debug
317 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
318 {
319 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
320 {
321 // log sample count
322 pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
323 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
324 // log idxs
325 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
326 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
327 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
328 pCb->cb_opCnt++;
329 }
330 }
331 #endif
333 // prepare metadata buffer pointers according to the metadata and buffer sizes
334 for (i=0; i < pAfWrt->numPrivateMetadata; i++)
335 {
336 UInt8 *nextMdBuf;
337 if(i == 0)
338 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
339 else
340 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
341 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
342 {
343 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
344 }
345 else if(i != 0)
346 {
347 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
348 }
349 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
350 }
352 // Write metadata to circular buffer
353 for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
354 {
355 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
356 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
357 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
358 }
360 Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
361 Cache_wait();
362 for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
363 {
364 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
365 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
366 }
367 // update audio frame write index
368 pCb->afWrtIdx++;
369 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
370 {
371 pCb->afWrtIdx = 0;
372 }
374 pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
375 if(pAfWrt->numPrivateMetadata > 0)
376 {
377 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
378 }
379 else
380 {
381 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
382 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
383 Cache_wait();
384 }
385 Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
386 Cache_wait();
387 // update number of audio frames in circular buffer
388 pCb->numAfCb++;
390 // Update CB Lag index
391 //if (pCb->afLagIdx < pCb->afInitialLag)
392 //{
393 // pCb->afLagIdx += 1;
394 //}
396 // Update CB primed flag
397 // calculate number of delta samples before
398 if (pCb->primedFlag == 0)
399 {
400 pCb->primedFlag = 1;
402 // Calculate number of output frames to block reader.
403 // This is sample count reader waits before allowed to actually read samples from the CB.
404 pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
406 // debug
407 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
408 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
409 //if (gPrimedFlagCnt < 10)
410 // gPrimedFlagCnt++;
411 }
413 // Write back circular buffer configuration
414 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
415 // write back audio frame
416 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
417 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
418 Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
419 Cache_wait();
420 // write back PCM data
421 for (i = 0; i < pCb->maxAFChanNum; i++)
422 {
423 if ((streamMask >> i) & 0x1)
424 {
425 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
426 }
427 }
428 Cache_wait();
430 {
431 static Uint8 toggleState = 0;
432 if (toggleState == 0)
433 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
434 else
435 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
436 toggleState = ~(toggleState);
437 }
438 Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
439 Log_info4("CBWMETA num=%d size=%d offset=%d chrequest=0x%04x", pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[0].size, pAfCb->pafPrivateMetadata[0].offset, pAfCb->channelConfigurationRequest.full);
440 }
441 else
442 {
443 //
444 // Skip write in case of 0 sample count
445 //
447 // writing audio frame w/ zero samples
448 // update stat
449 pCb->wrtAfZeroSampsCnt++;
451 // Write back circular buffer configuration
452 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
453 Cache_wait();
454 }
455 //}
456 //else if (pCb->readerActiveFlag == 0)
457 if (pCb->readerActiveFlag == 0)
458 {
459 //
460 // Reader inactive, don't write to circular buffer or check OVRflow.
461 //
463 // writing AF w/ inactive reader
464 // update stat
465 pCb->wrtAfReaderInactiveCnt++;
467 // Write back circular buffer configuration
468 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
469 Cache_wait();
470 }
472 // Leave the gate
473 GateMP_leave(gateHandle, key);
475 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
477 return ASP_DECOP_CB_SOK;
478 }
480 #if 0
481 // Get next audio frame to write in circular buffer
482 Int cbGetNextWriteAf(
483 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
484 Int8 cbIdx, // decoder output circular buffer index
485 PAF_AudioFrame **ppAfWrt // audio frame next to be written
486 )
487 {
488 IArg key;
489 GateMP_Handle gateHandle;
490 PAF_AST_DecOpCircBuf *pCb;
492 // Get gate handle
493 gateHandle = pCbCtl->gateHandle;
494 // Enter gate
495 key = GateMP_enter(gateHandle);
497 // Get circular buffer base pointer
498 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
500 // get pointer to current audio frame in circular buffer
501 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
503 // update audio frame write index
504 pCb->afWrtIdx++;
505 if (pCb->afWrtIdx > pCb->maxNumAfCb)
506 {
507 pCb->afWrtIdx = 0;
508 }
510 // Leave the gate
511 GateMP_leave(gateHandle, key);
513 return ASP_DECOP_CB_SOK;
514 }
515 #endif