]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - pasdk/test_arm/framework/aspDecOpCircBuf_slave.c
PASDK-277: Added GPIO for timestamping CB operation.
[processor-sdk/performance-audio-sr.git] / pasdk / test_arm / framework / aspDecOpCircBuf_slave.c
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;
56     
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     }
69     
70     pCbCtl->pXDecOpCb = pXDecOpCb;
71     
72     return ASP_DECOP_CB_SOK;
73     
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();
102     
103     //Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
104     
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();
113             
114     // update flags
115     pCb->writerActiveFlag = 1;
116     pCb->emptyFlag = 0;
117     pCb->afLagIdx = 0;
118     
119     // (***) FL: revisit
120     // Write back circular buffer configuration
121     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
122     Cache_wait();
124     // Leave the gate
125     GateMP_leave(gateHandle, key);
127     return ASP_DECOP_CB_SOK;
128 };
130 // Stop writes to circular buffer
131 Int cbWriteStop(
132     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
133     Int8 cbIdx                          // decoder output circular buffer index
136     IArg key;
137     GateMP_Handle gateHandle;
138     PAF_AST_DecOpCircBuf *pCb;
140     // Get gate handle
141     gateHandle = pCbCtl->gateHandle;
142     // Enter gate
143     key = GateMP_enter(gateHandle);
145     // Get circular buffer base pointer
146     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
148     // Invalidate circular buffer configuration
149     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
150     Cache_wait();
152     //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);  // FL: debug
153     
154     // update flags
155     pCb->writerActiveFlag = 0;
156     pCb->emptyFlag = 1;
158     // (***) FL: revisit
159     // Write back circular buffer configuration
160     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
161     Cache_wait();
162     
163     // Leave the gate
164     GateMP_leave(gateHandle, key);
166     return ASP_DECOP_CB_SOK;
169 // Write audio frame to circular buffer
170 Int cbWriteAf(
171     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
172     Int8 cbIdx,                         // decoder output circular buffer index
173     PAF_AudioFrame *pAfWrt              // audio frame from which to write
176     IArg key;
177     GateMP_Handle gateHandle;
178     PAF_AST_DecOpCircBuf *pCb;
179     PAF_AudioFrame *pAfCb;
180     PAF_ChannelMask_HD streamMask;
181     Int8 i;
182     Int16 j;
183     PAF_AudioData *pPcmBuf;UInt8 *pMetaBuf; int nextWrtIdx;PAF_AudioFrame *pAfCbNextAf; 
185     // Get gate handle
186     gateHandle = pCbCtl->gateHandle;
187     // Enter gate
188     key = GateMP_enter(gateHandle);
190     //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
192     // Get circular buffer base pointer
193     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
194     //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // FL: debug
196     // (***) FL: revisit
197     // Invalidate circular buffer configuration.
198     // NOTE: Probably only a subset of this information nexeds to be updated.
199     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
200     Cache_wait();
202     //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
203     //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // FL: debug
205     if ((pCb->readerActiveFlag == 1) && (pAfWrt->sampleCount)) //QIN ?
206     {
207         //
208         // Normal case, reader active.
209         // If reader not active, don't write to circular buffer or check OVRflow.
211 #if 0        
212         if (pCb->cbWriteAfInit == 0)
213         {
214             // Invalidate AF circular buffer
215             Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
216             for (n=0; n<pCb->maxNumAfCb; n++)
217             {
218                 pAfCb = &pCb->afCb[n];
219                 Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
220             }
221             Cache_wait();
223             pCb->cbWriteAfInit = 1;
224         }
225 #endif        
227         //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // FL: debug
229         // check overflow
230         //while (pCb->numAfCb >= pCb->maxNumAfCb); // FL: debug
231         if (pCb->numAfCb >= pCb->maxNumAfCb)
232         {
233             pCb->errOvrCnt++;
235             //SW_BREAKPOINT;
236             Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
238             // Write back circular buffer configuration
239             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
241             // Leave the gate
242             GateMP_leave(gateHandle, key);
244             //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
246             return ASP_DECOP_CB_WRITE_OVERFLOW;
247         }
249         pAfCb = &pCb->afCb[pCb->afWrtIdx];
250         pPcmBuf = pAfCb->data.sample[0];
251         pMetaBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
252         if((pPcmBuf + (pAfWrt->sampleCount * pCb->maxAFChanNum )) > (pCb->pcmBufEnd))
253         {
254             pPcmBuf = pCb->pcmBuf;
255         }
257         for (i=0; i<pCb->maxAFChanNum; i++)
258         {
260             pAfCb->data.sample[i] = pPcmBuf;
261             pPcmBuf += pAfWrt->sampleCount;
262             pAfCb->data.samsiz[i] = 0;
263         }
264         Cache_inv(pAfCb->data.sample, pCb->maxAFChanNum*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
265         Cache_wait();
267         for (i=0; i<pCb->maxAFChanNum; i++){
268         }
269         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
270         {
271             pAfCb->pafPrivateMetadata[i].offset = 0;
272             pAfCb->pafPrivateMetadata[i].size   = 0;
273             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
274             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
275         }
277         nextWrtIdx = 0;
278         if ((pCb->afWrtIdx +1) >= pCb->maxNumAfCb)
279         {
280             //Log_info0("cbWriteAf: AF Wrap around **** ");
281             nextWrtIdx = 0;
282         }else{
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 //QIN
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);
304         for (i = 0; i < pCb->maxAFChanNum; i++)
305         {
306             if ((streamMask >> i) & 0x1)
307             {
308                 for (j = 0; j < pAfWrt->sampleCount; j++)
309                 {
310                     pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
311                 }
313                 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
314             }
315         }
317         #ifdef CB_RW_OP_CAP_PP
318         if (pCb->cb_opCnt < CB_OP_COUNT_MAX)
319         {
320             if ((pCb->cb_samples_op != NULL) && (pCb->cb_op_owner != NULL))
321             {
322                 // log sample count
323                 pCb->cb_samples_op[pCb->cb_opCnt] = pAfWrt->sampleCount;
324                 pCb->cb_op_owner[pCb->cb_opCnt] = CB_OP_W;
325                 // log idxs
326                 pCb->cb_afRdIdx[pCb->cb_opCnt] = pCb->afRdIdx;
327                 pCb->cb_afWrtIdx[pCb->cb_opCnt] = pCb->afWrtIdx;
328                 pCb->cb_numAfCb[pCb->cb_opCnt] = pCb->numAfCb; // numAfCb might not be pointing to this instance
329                 pCb->cb_opCnt++;
330             }
331         }
332         #endif
334         // prepare metadata buffer pointers according to the metadata and buffer sizes
335         for (i=0; i < pAfWrt->numPrivateMetadata; i++)
336         {
337             UInt8 *nextMdBuf;
338             if(i == 0)
339                 nextMdBuf = (pAfCb->pafPrivateMetadata[0].pMdBuf + pAfWrt->pafPrivateMetadata[0].size);
340             else
341                 nextMdBuf = (pAfCb->pafPrivateMetadata[i-1].pMdBuf + pAfWrt->pafPrivateMetadata[i-1].size);
342             if(nextMdBuf >= pCb->metaBufEnd) // metadata buffer overflow
343             {
344                 pAfCb->pafPrivateMetadata[i].pMdBuf = pCb->metaBuf;
345             }
346             else if(i != 0)
347             {
348                 pAfCb->pafPrivateMetadata[i].pMdBuf = nextMdBuf;
349             }
350             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
351         }
353         // Write metadata to circular buffer
354         for (i = 0; i < pAfWrt->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
355         {
356             pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
357             pAfCb->pafPrivateMetadata[i].size   = pAfWrt->pafPrivateMetadata[i].size;
358             memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
359         }
361         Cache_inv(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
362         Cache_wait();
363         for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
364         {
365             //Log_info4("cbWriteAf: AF: %d nummd: %d offset: %d size: %d ", pCb->afWrtIdx, pAfCb->numPrivateMetadata, pAfCb->pafPrivateMetadata[i].offset,  pAfCb->pafPrivateMetadata[i].size);
366             Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
367         }
368         // update audio frame write index
369         pCb->afWrtIdx++;
370         if (pCb->afWrtIdx >= pCb->maxNumAfCb)
371         {
372             pCb->afWrtIdx = 0;
373         }
375         pCb->afCb[pCb->afWrtIdx].data.sample[0] = &pAfCb->data.sample[pCb->maxAFChanNum - 1][pAfWrt->sampleCount];
376         if(pAfWrt->numPrivateMetadata > 0)
377         {
378             pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].pMdBuf + pAfWrt->pafPrivateMetadata[pAfWrt->numPrivateMetadata - 1].size;
379         }
380         else
381         {
382             pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf = pAfCb->pafPrivateMetadata[0].pMdBuf;
383             Cache_wb(pCb->afCb , ASP_DECOP_CB_MAX_NUM_PCM_FRAMES*sizeof(PAF_AudioFrame *), Cache_Type_ALLD, 0);
384             Cache_wait();
385         }
386         Cache_inv(pCb->afCb[pCb->afWrtIdx].pafPrivateMetadata[0].pMdBuf, sizeof(UInt8 *), Cache_Type_ALLD, 0);
387         Cache_wait();
388         // update number of audio frames in circular buffer
389         pCb->numAfCb++;
390         // Update CB Lag index 
391         if (pCb->afLagIdx < pCb->afInitialLag)
392         {
393             pCb->afLagIdx += 1;
394         }
397         // (***) FL: revisit
398         // Write back circular buffer configuration
399         Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
400         // write back audio frame
401         Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
402         Cache_wb(pAfCb->data.samsiz, pCb->maxAFChanNum*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
403         Cache_wb(pAfCb->pafPrivateMetadata, pAfWrt->numPrivateMetadata*sizeof(PAF_PrivateMetadata *), Cache_Type_ALLD, 0);
404         Cache_wait();
405         // write back PCM data
406         for (i = 0; i < pCb->maxAFChanNum; i++)
407         {
408             if ((streamMask >> i) & 0x1)
409             {
410                 Cache_wb(pAfCb->data.sample[i], pAfWrt->sampleCount * sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
411             }
412         }
413         Cache_wait();
415         {
416             static Uint8 toggleState = 0;
417            if (toggleState == 0)
418                GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
419            else
420                GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
421            toggleState = ~(toggleState);
422         }
423         Log_info3("wrote %d samples into AF %d sourceSel: %d", pAfCb->sampleCount, pCb->afWrtIdx, pCb->sourceSel);
424         // write back private metadata // QIN
425         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);
426     }
428     // Leave the gate
429     GateMP_leave(gateHandle, key);
431     //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
433     return ASP_DECOP_CB_SOK;
436 // Get next audio frame to write in circular buffer
437 Int cbGetNextWriteAf(
438     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
439     Int8 cbIdx,                         // decoder output circular buffer index
440     PAF_AudioFrame **ppAfWrt            // audio frame next to be written
443     IArg key;
444     GateMP_Handle gateHandle;
445     PAF_AST_DecOpCircBuf *pCb;
447     // Get gate handle
448     gateHandle = pCbCtl->gateHandle;
449     // Enter gate
450     key = GateMP_enter(gateHandle);
452     // Get circular buffer base pointer
453     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
455     // get pointer to current audio frame in circular buffer
456     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
457     
458     // update audio frame write index
459     pCb->afWrtIdx++;
460     if (pCb->afWrtIdx > pCb->maxNumAfCb)
461     {
462         pCb->afWrtIdx = 0;
463     }    
464     
465     // Leave the gate
466     GateMP_leave(gateHandle, key);
468     return ASP_DECOP_CB_SOK;