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 // Initialize circular buffer control
49 Int cbCtlInit(
50 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
51 PAF_AST_DecOpCircBuf **pXDecOpCb // address of decoder output circular buffer base pointer
52 )
53 {
54 GateMP_Handle gateHandle;
55 Int status;
57 do {
58 status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
59 } while (status == GateMP_E_NOTFOUND);
60 if (status == GateMP_S_SUCCESS)
61 {
62 pCbCtl->gateHandle = gateHandle;
63 }
64 else
65 {
66 pCbCtl->gateHandle = NULL;
67 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
68 }
70 pCbCtl->pXDecOpCb = pXDecOpCb;
72 return ASP_DECOP_CB_SOK;
74 }
76 // Start writes to circular buffer
77 Int cbWriteStart(
78 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
79 Int8 cbIdx // decoder output circular buffer index
80 )
81 {
82 IArg key;
83 GateMP_Handle gateHandle;
84 PAF_AST_DecOpCircBuf *pCb;
85 PAF_AudioFrame *pAfCb;
86 Int8 n;
87 //Int8 i;
89 // Get gate handle
90 gateHandle = pCbCtl->gateHandle;
91 // Enter gate
92 key = GateMP_enter(gateHandle);
94 // Get circular buffer base pointer
95 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
97 // (***) FL: revisit
98 // Invalidate circular buffer configuration.
99 // NOTE: Probably only a subset of this information needs to be updated.
100 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
101 Cache_wait();
103 //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
105 // Invalidate AF circular buffer
106 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
107 for (n=0; n<pCb->maxNumAfCb; n++)
108 {
109 pAfCb = &pCb->afCb[n];
110 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
111 }
112 Cache_wait();
114 // update flags
115 pCb->writerActiveFlag = 1;
116 pCb->emptyFlag = 0;
118 // (***) FL: revisit
119 // Write back circular buffer configuration
120 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
121 Cache_wait();
123 // Leave the gate
124 GateMP_leave(gateHandle, key);
126 return ASP_DECOP_CB_SOK;
127 };
129 // Stop writes to circular buffer
130 Int cbWriteStop(
131 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
132 Int8 cbIdx // decoder output circular buffer index
133 )
134 {
135 IArg key;
136 GateMP_Handle gateHandle;
137 PAF_AST_DecOpCircBuf *pCb;
139 // Get gate handle
140 gateHandle = pCbCtl->gateHandle;
141 // Enter gate
142 key = GateMP_enter(gateHandle);
144 // Get circular buffer base pointer
145 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
147 // Invalidate circular buffer configuration
148 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
149 Cache_wait();
151 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
153 // update flags
154 pCb->writerActiveFlag = 0;
155 pCb->emptyFlag = 1;
157 // (***) FL: revisit
158 // Write back circular buffer configuration
159 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
160 Cache_wait();
162 // Leave the gate
163 GateMP_leave(gateHandle, key);
165 return ASP_DECOP_CB_SOK;
166 }
168 // Write audio frame to circular buffer
169 Int cbWriteAf(
170 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
171 Int8 cbIdx, // decoder output circular buffer index
172 PAF_AudioFrame *pAfWrt // audio frame from which to write
173 )
174 {
175 IArg key;
176 GateMP_Handle gateHandle;
177 PAF_AST_DecOpCircBuf *pCb;
178 PAF_AudioFrame *pAfCb;
179 PAF_ChannelMask_HD streamMask;
180 Int8 i;
181 Int16 j;
182 PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf;
184 // Get gate handle
185 gateHandle = pCbCtl->gateHandle;
186 // Enter gate
187 key = GateMP_enter(gateHandle);
189 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
191 // Get circular buffer base pointer
192 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
193 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // FL: debug
195 // (***) FL: revisit
196 // Invalidate circular buffer configuration.
197 // NOTE: Probably only a subset of this information nexeds to be updated.
198 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
199 Cache_wait();
201 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
202 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // FL: debug
204 if ((pCb->readerActiveFlag == 1) && (pAfWrt->sampleCount)) //QIN ?
205 {
206 //
207 // Normal case, reader active.
208 // If reader not active, don't write to circular buffer or check OVRflow.
210 #if 0
211 if (pCb->cbWriteAfInit == 0)
212 {
213 // Invalidate AF circular buffer
214 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
215 for (n=0; n<pCb->maxNumAfCb; n++)
216 {
217 pAfCb = &pCb->afCb[n];
218 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
219 }
220 Cache_wait();
222 pCb->cbWriteAfInit = 1;
223 }
224 #endif
226 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // FL: debug
228 // check overflow
229 //while (pCb->numAfCb >= pCb->maxNumAfCb); // FL: debug
230 if (pCb->numAfCb >= pCb->maxNumAfCb)
231 {
232 pCb->errOvrCnt++;
234 //SW_BREAKPOINT;
235 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
237 // Write back circular buffer configuration
238 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
240 // Leave the gate
241 GateMP_leave(gateHandle, key);
243 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
245 return ASP_DECOP_CB_WRITE_OVERFLOW;
246 }
248 pAfCb = &pCb->afCb[pCb->afWrtIdx];
249 pPcmBuf = pAfCb->data.sample[0];
250 pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
251 if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
252 {
253 pPcmBuf = pCb->pcmBuf;
254 }
256 for (i=0; i<pCb->maxAFChanNum; i++)
257 {
259 pAfCb->data.sample[i] = pPcmBuf;
260 pPcmBuf += pAfWrt->sampleCount;
261 pAfCb->data.samsiz[i] = 0;
262 }
263 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
264 Cache_wait();
266 for (i=0; i<pCb->maxAFChanNum; i++){
267 }
268 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
269 {
270 pAfCb->pafPrivateMetadata[i].offset = 0;
271 pAfCb->pafPrivateMetadata[i].size = 0;
272 pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
273 pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
274 }
276 nextWrtIdx = 0;
277 if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
278 {
279 //Log_info0("cbWriteAf: AF Wrap around **** ");
280 nextWrtIdx = 0;
281 }else{
282 nextWrtIdx = pCb->afWrtIdx + 1;
283 }
285 pAfCbNextAf = &pCb->afCb[nextWrtIdx]; // +1 or last AF if overflow
286 pAfCbNextAf->data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];// pAfCb->data.sample[15] + (pAfCb->sampleCount * sizeof(PAF_AudioData));
288 // write audio frame information updated by decoder
289 pAfCb->sampleDecode = pAfWrt->sampleDecode;
290 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
291 pAfCb->sampleRate = pAfWrt->sampleRate;
292 pAfCb->sampleCount = pAfWrt->sampleCount;
293 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
294 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
295 // write metadata information updated by decoder //QIN
296 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
297 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
298 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
299 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
300 // write PCM samples
301 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 }
317 // prepare metadata buffer pointers according to the metadata and buffer sizes
318 for (i=0; i < pAfWrt->numPrivateMetadata; i++)
319 {
320 UInt8 *nextMdBuf;
321 if(i == 0)
322 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
323 else
324 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
325 if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
326 {
327 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
328 }
329 else if(i != 0)
330 {
331 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
332 }
333 Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
334 }
336 // Write metadata to circular buffer
337 for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
338 {
339 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
340 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
341 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
342 }
344 Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
345 Cache_wait();
346 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
347 {
348 //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset, pAfCb->pafPrivateMetadata[i].size);
349 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
350 }
351 // update audio frame write index
352 pCb->afWrtIdx++;
353 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
354 {
355 pCb->afWrtIdx = 0;
356 }
358 pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
359 if(pAfWrt->numPrivateMetadata > 0)
360 {
361 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
362 }
363 else
364 {
365 pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
366 Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
367 Cache_wait();
368 }
369 Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
370 Cache_wait();
371 // update number of audio frames in circular buffer
372 pCb->numAfCb++;
374 // (***) FL: revisit
375 // Write back circular buffer configuration
376 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
377 // write back audio frame
378 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
379 Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
380 Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
381 Cache_wait();
382 // write back PCM data
383 for (i = 0; i < pCb->maxAFChanNum; i++)
384 {
385 if ((streamMask >> i) & 0x1)
386 {
387 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
388 }
389 }
390 Cache_wait();
391 Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
392 // write back private metadata // QIN
393 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);
394 }
396 // Leave the gate
397 GateMP_leave(gateHandle, key);
399 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
401 return ASP_DECOP_CB_SOK;
402 }
404 // Get next audio frame to write in circular buffer
405 Int cbGetNextWriteAf(
406 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
407 Int8 cbIdx, // decoder output circular buffer index
408 PAF_AudioFrame **ppAfWrt // audio frame next to be written
409 )
410 {
411 IArg key;
412 GateMP_Handle gateHandle;
413 PAF_AST_DecOpCircBuf *pCb;
415 // Get gate handle
416 gateHandle = pCbCtl->gateHandle;
417 // Enter gate
418 key = GateMP_enter(gateHandle);
420 // Get circular buffer base pointer
421 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
423 // get pointer to current audio frame in circular buffer
424 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
426 // update audio frame write index
427 pCb->afWrtIdx++;
428 if (pCb->afWrtIdx > pCb->maxNumAfCb)
429 {
430 pCb->afWrtIdx = 0;
431 }
433 // Leave the gate
434 GateMP_leave(gateHandle, key);
436 return ASP_DECOP_CB_SOK;
437 }