PASDK-400:AAC integration
[processor-sdk/performance-audio-sr.git] / pasdk / common / aspDecOpCircBuf_common.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/ipc/GateMP.h>
42 #include "aspDecOpCircBuf_common.h"
44 // Initialize circular buffer control
45 Int cbCtlInit(
46     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
47     Int8 numDecOpCb,                    // number of circular buffers
48     PAF_AST_DecOpCircBuf **pXDecOpCb    // address of decoder output circular buffer base pointer
49 )
50 {
51 #ifdef _TMS320C6X
52     GateMP_Params gateParams;
53     GateMP_Handle gateHandle;
54     
55     GateMP_Params_init(&gateParams);
56     gateParams.localProtect = GateMP_LocalProtect_THREAD;
57     gateParams.remoteProtect = GateMP_RemoteProtect_SYSTEM;
58     gateParams.name = ASP_DECODE_CB_GATE_NAME;
59     gateParams.regionId = ASP_DECODE_CB_GATE_REGION_ID;
60     gateHandle = GateMP_create(&gateParams);
61     if (gateHandle != NULL)
62     {
63         pCbCtl->gateHandle = gateHandle;
64     }
65     else
66     {
67         pCbCtl->gateHandle = NULL;
68         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
69     }
70     
71     pCbCtl->numDecOpCb = numDecOpCb;    // init number of circular buffers
72     pCbCtl->pXDecOpCb = pXDecOpCb;      // init base address of circular buffers
73     
74     return ASP_DECOP_CB_SOK;    
76 #elif defined(ARMCOMPILE)
77     GateMP_Handle gateHandle;
78     Int status;
79     
80     do {
81         status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
82     } while (status == GateMP_E_NOTFOUND);
83     if (status == GateMP_S_SUCCESS)
84     {
85         pCbCtl->gateHandle = gateHandle;
86     }
87     else
88     {
89         pCbCtl->gateHandle = NULL;
90         return ASP_DECOP_CB_CTL_INIT_INV_GATE;
91     }
92     
93     pCbCtl->numDecOpCb = numDecOpCb;    // init number of circular buffers
94     pCbCtl->pXDecOpCb = pXDecOpCb;      // init base address of circular buffers
95     
96     return ASP_DECOP_CB_SOK;
98 #else
99     #error "Unsupported platform"
101 #endif
104 // Reset circular buffer
105 Int cbReset(
106     PAF_AST_DecOpCircBufCtl *pCbCtl,
107     Int8 cbIdx
110     IArg key;
111     GateMP_Handle gateHandle;
112     PAF_AST_DecOpCircBuf *pCb;
113     PAF_AudioFrame *pAfCb;
114     Int8 n;
115     Int8 i;
117     // Get gate handle
118     gateHandle = pCbCtl->gateHandle;
119     // Enter gate
120     key = GateMP_enter(gateHandle);
122     // Get circular buffer base pointer
123     pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
124     
125     // Invalidate circular buffer configuration
126     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
127     Cache_wait();
129     // Initialize CB primed flag
130     pCb->primedFlag = 0;
131     // Initialize delta samples
132     pCb->deltaSamps = 0;
133     
134     // Reset circular buffer:
135     //  - AF write, read indices
136     if (pCb->sourceSel == PAF_SOURCE_PCM)
137     {
138         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_PCM;
139         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_PCM;
140     }
141     else if (pCb->sourceSel == PAF_SOURCE_AAC)
142     {
143         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_AAC;
144         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_AAC;
145     }
146     else if (pCb->sourceSel == PAF_SOURCE_DDP)
147     {
148         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DDP;
149         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DDP;
150     }
151     else if (pCb->sourceSel == PAF_SOURCE_THD)
152     {
153         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_THD;
154         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_THD;
155     }
156     else if ((pCb->sourceSel == PAF_SOURCE_DTS)   ||
157              (pCb->sourceSel == PAF_SOURCE_DTSHD) ||
158              (pCb->sourceSel == PAF_SOURCE_DTS12) ||
159              (pCb->sourceSel == PAF_SOURCE_DTS13) ||
160              (pCb->sourceSel == PAF_SOURCE_DTS14) ||
161              (pCb->sourceSel == PAF_SOURCE_DTS16) ||
162              (pCb->sourceSel == PAF_SOURCE_DTSALL)
163             )
164     {
166         pCb->afWrtIdx = ASP_DECOP_CB_INIT_WRTIDX_DTS;
167         pCb->afRdIdx = ASP_DECOP_CB_INIT_RDIDX_DTS;
168         pCb->pcmRdIdx = pCb->decOpFrameLen - ASP_DECOP_CB_INIT_LAG_DTS*pCb->strFrameLen;
169     }
170     else
171     {
172         //
173         // Currently unsupported source select
174         //
175         return ASP_DECOP_CB_RESET_INV_SOURCE_SEL;
176     }
177         
178     // Reset circular buffer:
179     //  - PCM read index
180     //  - Private metadata read index
181     //  - number of PCM samples in CB
182     pCb->pcmRdIdx = 0;
183     pCb->prvMdRdIdx = 0;
184     pCb->numPcmSampsPerCh = 0;
186     // initialize circular buffer current number of frames
187     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
189     for (n=0; n<pCb->maxNumAfCb; n++)
190     {
191         pAfCb = &pCb->afCb[n];
192         
193         // Clear PCM data
194         for (i=0; i<pCb->maxAFChanNum; i++)
195         {
196             memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
197             pAfCb->data.samsiz[i] = 0;
198         }
199         
200         // Clear metadata
201         pAfCb->bsMetadata_type     = PAF_bsMetadata_none;           /* non zero if metadata is attached. */
202         pAfCb->pafBsMetadataUpdate = 0;                             /* indicates whether bit-stream metadata update */
203         pAfCb->numPrivateMetadata  = 0;                             /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
204         pAfCb->bsMetadata_offset   = 0;                             /* offset into audio frame for change in bsMetadata_type field */
205         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
206         {
207             pAfCb->pafPrivateMetadata[i].offset = 0; 
208             pAfCb->pafPrivateMetadata[i].size   = 0;
209         }
210     }
211     
212     // reset stats
213     pCb->readAfWriterInactiveCnt = 0;
214     pCb->readAfNdCnt = 0;
215     pCb->wrtAfReaderInactiveCnt = 0;
216     pCb->wrtAfZeroSampsCnt = 0;
217     pCb->errAfUndCnt = 0;
218     pCb->errAfOvrCnt = 0;
219     pCb->errPcmUndCnt = 0;
220     pCb->errPcmOvrCnt = 0;
222     // Write back circular buffer configuration
223     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     for (n=0; n<pCb->maxNumAfCb; n++)
228     {
229         pAfCb = &pCb->afCb[n];
230         for (i=0; i<pCb->maxAFChanNum; i++)
231         {
232             Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
233         }
234     }
235     Cache_wait();
237     // Leave the gate
238     GateMP_leave(gateHandle, key);
240     return ASP_DECOP_CB_SOK;
243 // Get circular buffer statistics
244 Int cbGetStats(
245     PAF_AST_DecOpCircBufCtl *pCbCtl,    // decoder output circular buffer control
246     Int8 cbIdx,                         // decoder output circular buffer index
247     PAF_AST_DecOpCircBufStats *pCbStats // decoder output circular buffer statistics
248     
251     IArg key;
252     GateMP_Handle gateHandle;
253     PAF_AST_DecOpCircBuf *pCb;
254     
255     // Get gate handle
256     gateHandle = pCbCtl->gateHandle;
257     // Enter gate
258     key = GateMP_enter(gateHandle);
259     
260     // Get circular buffer base pointer
261     pCb = &(*pCbCtl->pXDecOpCb)[cbIdx];
263     // Invalidate circular buffer configuration.
264     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
265     Cache_wait();
267     // Populate statistics
268     pCbStats->readAfWriterInactiveCnt = pCb->readAfWriterInactiveCnt;
269     pCbStats->readAfNdCnt = pCb->readAfNdCnt;
270     pCbStats->wrtAfReaderInactiveCnt = pCb->wrtAfReaderInactiveCnt;
271     pCbStats->wrtAfZeroSampsCnt = pCb->wrtAfZeroSampsCnt;
272     pCbStats->errAfUndCnt = pCb->errAfUndCnt;
273     pCbStats->errAfOvrCnt = pCb->errAfOvrCnt;
274     pCbStats->errPcmUndCnt = pCb->errPcmUndCnt;
275     pCbStats->errPcmOvrCnt = pCb->errPcmOvrCnt;
276     
277     // Leave the gate
278     GateMP_leave(gateHandle, key);
279     
280     return ASP_DECOP_CB_SOK;
284 // Output log of circular buffer control variables (debug)
285 Int cbLog(
286     PAF_AST_DecOpCircBufCtl *pCbCtl,
287     Int8 cbIdx, 
288     Int8 fullLog, 
289     char *locInfo
292     IArg key;
293     GateMP_Handle gateHandle;
294     PAF_AST_DecOpCircBuf *pCb;
295     
296     // Get gate handle
297     gateHandle = pCbCtl->gateHandle;
298     // Enter gate
299     key = GateMP_enter(gateHandle);
300     
301     // Get circular buffer base pointer
302     pCb = &(*pCbCtl->pXDecOpCb)[cbIdx];
303     
304     // Invalidate circular buffer configuration.
305     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
306     Cache_wait();
308     Log_info1("CB: %s", (IArg)locInfo);
309     Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, drainFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->drainFlag);
310     Log_info5("CB: afRdIdx=%d, pcmRdIdx=%d, prvMdRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, pCb->prvMdRdIdx, pCb->afWrtIdx, pCb->numAfCb);
311     if (fullLog)
312     {
313         Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb);  
314         Log_info2("CB: decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
315         //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
316     }
318     // Leave the gate
319     GateMP_leave(gateHandle, key);
320     
321     return ASP_DECOP_CB_SOK;