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;
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 }
71 pCbCtl->numDecOpCb = numDecOpCb; // init number of circular buffers
72 pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
74 return ASP_DECOP_CB_SOK;
76 #elif defined(ARMCOMPILE)
77 GateMP_Handle gateHandle;
78 Int status;
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 }
93 pCbCtl->numDecOpCb = numDecOpCb; // init number of circular buffers
94 pCbCtl->pXDecOpCb = pXDecOpCb; // init base address of circular buffers
96 return ASP_DECOP_CB_SOK;
98 #else
99 #error "Unsupported platform"
101 #endif
102 }
104 // Reset circular buffer
105 Int cbReset(
106 PAF_AST_DecOpCircBufCtl *pCbCtl,
107 Int8 cbIdx
108 )
109 {
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]);
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;
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 }
169 else
170 {
171 //
172 // Currently unsupported source select
173 //
174 return ASP_DECOP_CB_RESET_INV_SOURCE_SEL;
175 }
177 // Reset circular buffer:
178 // - PCM read index
179 // - Private metadata read index
180 // - number of PCM samples in CB
181 pCb->pcmRdIdx = 0;
182 pCb->prvMdRdIdx = 0;
183 pCb->numPcmSampsPerCh = 0;
185 // initialize circular buffer current number of frames
186 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
188 for (n=0; n<pCb->maxNumAfCb; n++)
189 {
190 pAfCb = &pCb->afCb[n];
192 // Clear PCM data
193 for (i=0; i<pCb->maxAFChanNum; i++)
194 {
195 memset(pAfCb->data.sample[i], 0, pCb->maxAFSampCount);
196 pAfCb->data.samsiz[i] = 0;
197 }
199 // Clear metadata
200 pAfCb->bsMetadata_type = PAF_bsMetadata_none; /* non zero if metadata is attached. */
201 pAfCb->pafBsMetadataUpdate = 0; /* indicates whether bit-stream metadata update */
202 pAfCb->numPrivateMetadata = 0; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
203 pAfCb->bsMetadata_offset = 0; /* offset into audio frame for change in bsMetadata_type field */
204 for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
205 {
206 pAfCb->pafPrivateMetadata[i].offset = 0;
207 pAfCb->pafPrivateMetadata[i].size = 0;
208 }
209 }
211 // reset stats
212 pCb->readAfWriterInactiveCnt = 0;
213 pCb->readAfNdCnt = 0;
214 pCb->wrtAfReaderInactiveCnt = 0;
215 pCb->wrtAfZeroSampsCnt = 0;
216 pCb->errAfUndCnt = 0;
217 pCb->errAfOvrCnt = 0;
218 pCb->errPcmUndCnt = 0;
219 pCb->errPcmOvrCnt = 0;
221 // Write back circular buffer configuration
222 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
224 // Write back AF circular buffer
225 Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
226 for (n=0; n<pCb->maxNumAfCb; n++)
227 {
228 pAfCb = &pCb->afCb[n];
229 for (i=0; i<pCb->maxAFChanNum; i++)
230 {
231 Cache_wb(pAfCb->data.sample[i], pCb->maxAFSampCount*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
232 }
233 }
234 Cache_wait();
236 // Leave the gate
237 GateMP_leave(gateHandle, key);
239 return ASP_DECOP_CB_SOK;
240 }
242 // Get circular buffer statistics
243 Int cbGetStats(
244 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
245 Int8 cbIdx, // decoder output circular buffer index
246 PAF_AST_DecOpCircBufStats *pCbStats // decoder output circular buffer statistics
248 )
249 {
250 IArg key;
251 GateMP_Handle gateHandle;
252 PAF_AST_DecOpCircBuf *pCb;
254 // Get gate handle
255 gateHandle = pCbCtl->gateHandle;
256 // Enter gate
257 key = GateMP_enter(gateHandle);
259 // Get circular buffer base pointer
260 pCb = &(*pCbCtl->pXDecOpCb)[cbIdx];
262 // Invalidate circular buffer configuration.
263 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
264 Cache_wait();
266 // Populate statistics
267 pCbStats->readAfWriterInactiveCnt = pCb->readAfWriterInactiveCnt;
268 pCbStats->readAfNdCnt = pCb->readAfNdCnt;
269 pCbStats->wrtAfReaderInactiveCnt = pCb->wrtAfReaderInactiveCnt;
270 pCbStats->wrtAfZeroSampsCnt = pCb->wrtAfZeroSampsCnt;
271 pCbStats->errAfUndCnt = pCb->errAfUndCnt;
272 pCbStats->errAfOvrCnt = pCb->errAfOvrCnt;
273 pCbStats->errPcmUndCnt = pCb->errPcmUndCnt;
274 pCbStats->errPcmOvrCnt = pCb->errPcmOvrCnt;
276 // Leave the gate
277 GateMP_leave(gateHandle, key);
279 return ASP_DECOP_CB_SOK;
280 }
283 // Output log of circular buffer control variables (debug)
284 Int cbLog(
285 PAF_AST_DecOpCircBufCtl *pCbCtl,
286 Int8 cbIdx,
287 Int8 fullLog,
288 char *locInfo
289 )
290 {
291 IArg key;
292 GateMP_Handle gateHandle;
293 PAF_AST_DecOpCircBuf *pCb;
295 // Get gate handle
296 gateHandle = pCbCtl->gateHandle;
297 // Enter gate
298 key = GateMP_enter(gateHandle);
300 // Get circular buffer base pointer
301 pCb = &(*pCbCtl->pXDecOpCb)[cbIdx];
303 // Invalidate circular buffer configuration.
304 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
305 Cache_wait();
307 Log_info1("CB: %s", (IArg)locInfo);
308 Log_info3("CB: readerActiveFlag=%d, writerActiveFlag=%d, drainFlag=%d", pCb->readerActiveFlag, pCb->writerActiveFlag, pCb->drainFlag);
309 Log_info5("CB: afRdIdx=%d, pcmRdIdx=%d, prvMdRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, pCb->prvMdRdIdx, pCb->afWrtIdx, pCb->numAfCb);
310 if (fullLog)
311 {
312 Log_info1("CB: maxNumAfCb=%d", pCb->maxNumAfCb);
313 Log_info2("CB: decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
314 //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
315 }
317 // Leave the gate
318 GateMP_leave(gateHandle, key);
320 return ASP_DECOP_CB_SOK;
321 }