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 // Initialize circular buffer control
51 Int cbCtlInit(
52 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
53 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
54 )
55 {
56 GateMP_Handle gateHandle;
57 Int status;
59 do {
60 status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
61 } while (status == GateMP_E_NOTFOUND);
62 if (status == GateMP_S_SUCCESS)
63 {
64 pCbCtl->gateHandle = gateHandle;
65 }
66 else
67 {
68 pCbCtl->gateHandle = NULL;
69 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
70 }
72 pCbCtl->pXDecOpCb = pXDecOpCb;
74 return ASP_DECOP_CB_SOK;
76 }
78 //Int8 gCbWriteStartCnt=0; // debug
80 // Start writes to circular buffer
81 Int cbWriteStart(
82 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
83 Int8 cbIdx // decoder output circular buffer index
84 )
85 {
86 IArg key;
87 GateMP_Handle gateHandle;
88 PAF_AST_DecOpCircBuf *pCb;
89 PAF_AudioFrame *pAfCb;
90 Int8 n;
91 //Int8 i;
93 //gCbWriteStartCnt++; // debug
95 // Get gate handle
96 gateHandle = pCbCtl->gateHandle;
97 // Enter gate
98 key = GateMP_enter(gateHandle);
100 // Get circular buffer base pointer
101 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
103 // Invalidate circular buffer configuration.
104 // NOTE: Probably only a subset of this information needs to be updated.
105 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
106 Cache_wait();
108 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // debug
110 // Invalidate AF circular buffer
111 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
112 for (n=0; n<pCb->maxNumAfCb; n++)
113 {
114 pAfCb = &pCb->afCb[n];
115 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
116 }
117 Cache_wait();
119 // update flags
120 pCb->writerActiveFlag = 1;
121 pCb->emptyFlag = 0;
122 //pCb->afLagIdx = 0;
124 // Write back circular buffer configuration
125 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
126 Cache_wait();
128 // Leave the gate
129 GateMP_leave(gateHandle, key);
131 return ASP_DECOP_CB_SOK;
132 };
134 // Stop writes to circular buffer
135 Int cbWriteStop(
136 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
137 Int8 cbIdx // decoder output circular buffer index
138 )
139 {
140 IArg key;
141 GateMP_Handle gateHandle;
142 PAF_AST_DecOpCircBuf *pCb;
144 // Get gate handle
145 gateHandle = pCbCtl->gateHandle;
146 // Enter gate
147 key = GateMP_enter(gateHandle);
149 // Get circular buffer base pointer
150 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
152 // Invalidate circular buffer configuration
153 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
154 Cache_wait();
156 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // debug
158 // update flags
159 pCb->writerActiveFlag = 0;
160 pCb->emptyFlag = 1;
162 // Write back circular buffer configuration
163 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
164 Cache_wait();
166 // Leave the gate
167 GateMP_leave(gateHandle, key);
169 return ASP_DECOP_CB_SOK;
170 }
172 // debug
173 //Int16 gSampleCountBuf[10];
174 //Int16 gCalcDeltaSampsBuf[10];
175 //Int8 gPrimedFlagCnt=0;
177 // Write audio frame to circular buffer
178 Int cbWriteAf(
179 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
180 Int8 cbIdx, // decoder output circular buffer index
181 PAF_AudioFrame *pAfWrt // audio frame from which to write
182 )
183 {
184 IArg key;
185 GateMP_Handle gateHandle;
186 PAF_AST_DecOpCircBuf *pCb;
187 PAF_AudioFrame *pAfCb;
188 PAF_ChannelMask_HD streamMask;
189 Int8 i;
190 Int16 j;
191 PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
193 // Get gate handle
194 gateHandle = pCbCtl->gateHandle;
195 // Enter gate
196 key = GateMP_enter(gateHandle);
198 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // debug
200 // Get circular buffer base pointer
201 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
202 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // debug
204 // Invalidate circular buffer configuration.
205 // NOTE: Probably only a subset of this information needs to be updated.
206 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
207 Cache_wait();
209 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // debug
210 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // debug
212 if ((pCb->readerActiveFlag == 1) && (pAfWrt->sampleCount)) //QIN ?
213 {
214 //
215 // Normal case, reader active.
216 // If reader not active, don't write to circular buffer or check OVRflow.
218 #if 0
219 if (pCb->cbWriteAfInit == 0)
220 {
221 // Invalidate AF circular buffer
222 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
223 for (n=0; n<pCb->maxNumAfCb; n++)
224 {
225 pAfCb = &pCb->afCb[n];
226 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
227 }
228 Cache_wait();
230 pCb->cbWriteAfInit = 1;
231 }
232 #endif
234 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // FL: debug
236 // check overflow
237 //while (pCb->numAfCb >= pCb->maxNumAfCb); // debug
238 if (pCb->numAfCb >= pCb->maxNumAfCb)
239 {
240 pCb->errOvrCnt++;
242 //SW_BREAKPOINT;
243 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
245 // Write back circular buffer configuration
246 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
248 // Leave the gate
249 GateMP_leave(gateHandle, key);
251 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
253 return ASP_DECOP_CB_WRITE_OVERFLOW;
254 }
256 pAfCb = &pCb->afCb[pCb->afWrtIdx];
257 pPcmBuf = pAfCb->data.sample[0];
258 pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
259 if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
260 {
261 pPcmBuf = pCb->pcmBuf;
262 }
264 for (i=0; i<pCb->maxAFChanNum; i++)
265 {
266 pAfCb->data.sample[i] = pPcmBuf;
267 pPcmBuf += pAfWrt->sampleCount;
268 pAfCb->data.samsiz[i] = 0;
269 }
270 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
271 Cache_wait();
273 for (i=0; i<pCb->maxAFChanNum; i++){
274 }
275 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
276 {
277 pAfCb->pafPrivateMetadata[i].offset = 0;
278 pAfCb->pafPrivateMetadata[i].size = 0;
279 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
280 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
281 }
283 nextWrtIdx = 0;
284 if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
285 {
286 //Log_info0("cbWriteAf: AF Wrap around **** ");
287 // next audio frame will be audio frame 0
288 nextWrtIdx = 0;
289 }else{
290 // next audio frame will be current audio frame + 1
291 nextWrtIdx = pCb->afWrtIdx + 1;
292 }
294 pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
295 pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
297 // write audio frame information updated by decoder
298 pAfCb->sampleDecode = pAfWrt->sampleDecode;
299 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
300 pAfCb->sampleRate = pAfWrt->sampleRate;
301 pAfCb->sampleCount = pAfWrt->sampleCount;
302 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
303 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
304 // write metadata information updated by decoder
305 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
306 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
307 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
308 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
309 // write PCM samples
310 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
311 for (i = 0; i < pCb->maxAFChanNum; i++)
312 {
313 if ((streamMask >> i) & 0x1)
314 {
315 for (j = 0; j < pAfWrt->sampleCount; j++)
316 {
317 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
318 }
320 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
321 }
322 }
324 #ifdef CB_RW_OP_CAP_PP // debug
325 if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
326 {
327 if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
328 {
329 // log sample count
330 pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
331 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
332 // log idxs
333 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
334 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
335 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
336 pCb->cb_opCnt++;
337 }
338 }
339 #endif
341 // prepare metadata buffer pointers according to the metadata and buffer sizes
342 for (i=0; i < pAfWrt->numPrivateMetadata; i++)
343 {
344 UInt8 *nextMdBuf;
345 if(i == 0)
346 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
347 else
348 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
349 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
350 {
351 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
352 }
353 else if(i != 0)
354 {
355 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
356 }
357 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
358 }
360 // Write metadata to circular buffer
361 for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // only copy numPrivateMetadata
362 {
363 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
364 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
365 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
366 }
368 Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0); // FL: this is write back and invalidate??
369 Cache_wait();
370 for (i=0; i<pAfCb->numPrivateMetadata; i++) // only write back numPrivateMetadata
371 {
372 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
373 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
374 }
375 // update audio frame write index
376 pCb->afWrtIdx++;
377 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
378 {
379 pCb->afWrtIdx = 0;
380 }
382 pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
383 if(pAfWrt->numPrivateMetadata > 0)
384 {
385 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
386 }
387 else
388 {
389 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
390 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
391 Cache_wait();
392 }
393 Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
394 Cache_wait();
395 // update number of audio frames in circular buffer
396 pCb->numAfCb++;
398 // Update CB Lag index
399 //if (pCb->afLagIdx < pCb->afInitialLag)
400 //{
401 // pCb->afLagIdx += 1;
402 //}
404 // Update CB primed flag
405 // calculate number of delta samples before
406 if (pCb->primedFlag == 0)
407 {
408 pCb->primedFlag = 1;
410 // Calculate number of output frames to block reader.
411 // This is sample count reader waits before allowed to actually read samples from the CB.
412 pCb->deltaSamps = (pCb->targetNDSamps - pAfWrt->sampleCount + (pCb->strFrameLen-1)) / pCb->strFrameLen * pCb->strFrameLen;
414 // debug
415 //gSampleCountBuf[gPrimedFlagCnt] = pAfWrt->sampleCount;
416 //gCalcDeltaSampsBuf[gPrimedFlagCnt] = pCb->deltaSamps;
417 //if (gPrimedFlagCnt < 10)
418 // gPrimedFlagCnt++;
419 }
421 // (***) FL: revisit
422 // Write back circular buffer configuration
423 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
424 // write back audio frame
425 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
426 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
427 Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
428 Cache_wait();
429 // write back PCM data
430 for (i = 0; i < pCb->maxAFChanNum; i++)
431 {
432 if ((streamMask >> i) & 0x1)
433 {
434 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
435 }
436 }
437 Cache_wait();
439 {
440 static Uint8 toggleState = 0;
441 if (toggleState == 0)
442 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
443 else
444 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
445 toggleState = ~(toggleState);
446 }
447 Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
448 // write back private metadata // QIN
449 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);
450 }
452 // Leave the gate
453 GateMP_leave(gateHandle, key);
455 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
457 return ASP_DECOP_CB_SOK;
458 }
460 // Get next audio frame to write in circular buffer
461 Int cbGetNextWriteAf(
462 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
463 Int8 cbIdx, // decoder output circular buffer index
464 PAF_AudioFrame **ppAfWrt // audio frame next to be written
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 // get pointer to current audio frame in circular buffer
480 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
482 // update audio frame write index
483 pCb->afWrtIdx++;
484 if (pCb->afWrtIdx > pCb->maxNumAfCb)
485 {
486 pCb->afWrtIdx = 0;
487 }
489 // Leave the gate
490 GateMP_leave(gateHandle, key);
492 return ASP_DECOP_CB_SOK;
493 }