[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_arm / framework / aspDecOpCircBuf_slave.c
2 /*
3 Copyright (c) 2016, 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 extern UInt32 gSlaveDecDecodeCnt;
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 // Start writes to circular buffer
79 Int cbWriteStart(
80 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
81 Int8 cbIdx // decoder output circular buffer index
82 )
83 {
84 IArg key;
85 GateMP_Handle gateHandle;
86 PAF_AST_DecOpCircBuf *pCb;
87 PAF_AudioFrame *pAfCb;
88 Int8 n;
89 //Int8 i;
91 // Get gate handle
92 gateHandle = pCbCtl->gateHandle;
93 // Enter gate
94 key = GateMP_enter(gateHandle);
96 // Get circular buffer base pointer
97 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
99 // (***) FL: revisit
100 // Invalidate circular buffer configuration.
101 // NOTE: Probably only a subset of this information needs to be updated.
102 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
103 Cache_wait();
105 Log_info1("cbWriteStart:afCb=0x%04x", (IArg)pCb->afCb);
107 // Invalidate AF circular buffer
108 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
109 for (n=0; n<pCb->maxNumAfCb; n++)
110 {
111 pAfCb = &pCb->afCb[n];
112 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
113 // FL: unnecessary since part of AF
114 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
115 //{
116 // Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
117 //}
118 }
119 Cache_wait();
121 // update flags
122 pCb->writerActiveFlag = 1;
123 pCb->emptyFlag = 0;
125 // (***) FL: revisit
126 // Write back circular buffer configuration
127 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
128 Cache_wait();
130 // Leave the gate
131 GateMP_leave(gateHandle, key);
133 return ASP_DECOP_CB_SOK;
134 };
136 // Stop writes to circular buffer
137 Int cbWriteStop(
138 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
139 Int8 cbIdx // decoder output circular buffer index
140 )
141 {
142 IArg key;
143 GateMP_Handle gateHandle;
144 PAF_AST_DecOpCircBuf *pCb;
146 // Get gate handle
147 gateHandle = pCbCtl->gateHandle;
148 // Enter gate
149 key = GateMP_enter(gateHandle);
151 // Get circular buffer base pointer
152 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
154 // Invalidate circular buffer configuration
155 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
156 Cache_wait();
158 Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb);
160 // update flags
161 pCb->writerActiveFlag = 0;
162 pCb->emptyFlag = 1;
164 // (***) FL: revisit
165 // Write back circular buffer configuration
166 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
167 Cache_wait();
169 // Leave the gate
170 GateMP_leave(gateHandle, key);
172 return ASP_DECOP_CB_SOK;
173 }
175 // Write audio frame to circular buffer
176 Int cbWriteAf(
177 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
178 Int8 cbIdx, // decoder output circular buffer index
179 PAF_AudioFrame *pAfWrt // audio frame from which to write
180 )
181 {
182 IArg key;
183 GateMP_Handle gateHandle;
184 PAF_AST_DecOpCircBuf *pCb;
185 PAF_AudioFrame *pAfCb;
186 PAF_ChannelMask_HD streamMask;
187 Int8 i;
188 Int16 j;
190 // Get gate handle
191 gateHandle = pCbCtl->gateHandle;
192 // Enter gate
193 key = GateMP_enter(gateHandle);
195 Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key);
197 // Get circular buffer base pointer
198 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
199 Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb);
201 // (***) FL: revisit
202 // Invalidate circular buffer configuration.
203 // NOTE: Probably only a subset of this information nexeds to be updated.
204 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
205 Cache_wait();
207 Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb);
209 Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag);
211 if (pCb->readerActiveFlag == 1)
212 {
213 //
214 // Normal case, reader active.
215 // If reader not active, don't write to circular buffer or check OVRflow.
217 #if 0
218 if (pCb->cbWriteAfInit == 0)
219 {
220 // Invalidate AF circular buffer
221 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
222 for (n=0; n<pCb->maxNumAfCb; n++)
223 {
224 pAfCb = &pCb->afCb[n];
225 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
226 }
227 Cache_wait();
229 pCb->cbWriteAfInit = 1;
230 }
231 #endif
233 Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb);
235 // check overflow
236 if (pCb->numAfCb >= pCb->maxNumAfCb)
237 {
238 pCb->errOvrCnt++;
240 //SW_BREAKPOINT;
241 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
243 // Write back circular buffer configuration
244 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
246 // Leave the gate
247 GateMP_leave(gateHandle, key);
249 Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key);
251 return ASP_DECOP_CB_WRITE_OVERFLOW;
252 }
254 // get pointer to current audio frame in circular buffer
255 Log_info2("cbWriteAf:afCb=0x%04x, pCb->afWrtIdx=%d", (IArg)pCb->afCb, (IArg)pCb->afWrtIdx);
256 pAfCb = &pCb->afCb[pCb->afWrtIdx];
257 Log_info1("cbWriteAf:pAfCb=0x%04x", (IArg)pAfCb);
259 // write audio frame information updated by decoder
260 pAfCb->sampleDecode = pAfWrt->sampleDecode;
261 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
262 pAfCb->sampleRate = pAfWrt->sampleRate;
263 pAfCb->sampleCount = pAfWrt->sampleCount;
264 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
265 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
266 // write metadata information updated by decoder //QIN
267 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
268 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
269 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
270 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
271 // write PCM samples
272 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
273 Log_info1("cbWriteAf:streamMask=0x%04x", (IArg)streamMask);
274 Log_info1("cbWriteAf:pCb->decOpFrameLen=%d", (IArg)pCb->decOpFrameLen);
275 Log_info2("cbWriteAf:pAfCb->data.sample=0x%04x, pAfWrt->data.sample=0x%04x", (IArg)pAfCb->data.sample, (IArg)pAfWrt->data.sample);
276 Log_info2("cbWriteAf:pAfCb->data.samsiz=0x%04x, pAfWrt->data.samsiz=0x%04x", (IArg)pAfCb->data.samsiz, (IArg)pAfWrt->data.samsiz);
277 //if (gSlaveDecDecodeCnt == 7)
278 //{
279 // Log_info1("gSlaveDecDecodeCnt=%d", (IArg)gSlaveDecDecodeCnt);
280 //}
281 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
282 {
283 if ((streamMask >> i) & 0x1)
284 {
285 for (j = 0; j < pCb->decOpFrameLen; j++)
286 {
287 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
288 }
290 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
291 }
292 }
294 Log_info1("cbWriteAf:pAfCb->numPrivateMetadata=%d", (IArg)pAfCb->numPrivateMetadata);
295 // Write metadata to circular buffer
296 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
297 {
298 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
299 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
300 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
301 }
303 // update audio frame write index
304 Log_info2("cbWriteAf:pCb->afWrtIdx=%d, pCb->maxNumAfCb", (IArg)pCb->afWrtIdx, (IArg)pCb->maxNumAfCb);
305 pCb->afWrtIdx++;
306 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
307 {
308 pCb->afWrtIdx = 0;
309 }
310 Log_info2("cbWriteAf:pCb->afWrtIdx=%d, pCb->maxNumAfCb", (IArg)pCb->afWrtIdx, (IArg)pCb->maxNumAfCb);
312 // update number of audio frames in circular buffer
313 Log_info1("cbWriteAf:pCb->numAfCb=%d", (IArg)pCb->numAfCb);
314 pCb->numAfCb++;
315 Log_info1("cbWriteAf:pCb->numAfCb=%d", (IArg)pCb->numAfCb);
317 // (***) FL: revisit
318 // Write back circular buffer configuration
319 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
320 // write back audio frame
321 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
322 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
323 // write back PCM data
324 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
325 {
326 if ((streamMask >> i) & 0x1)
327 {
328 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
329 }
330 }
332 // write back private metadata // QIN
333 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
334 {
335 //Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
336 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
337 }
338 Cache_wait();
339 }
341 // Leave the gate
342 GateMP_leave(gateHandle, key);
344 Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key);
346 return ASP_DECOP_CB_SOK;
347 }
349 // Get next audio frame to write in circular buffer
350 Int cbGetNextWriteAf(
351 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
352 Int8 cbIdx, // decoder output circular buffer index
353 PAF_AudioFrame **ppAfWrt // audio frame next to be written
354 )
355 {
356 IArg key;
357 GateMP_Handle gateHandle;
358 PAF_AST_DecOpCircBuf *pCb;
360 // Get gate handle
361 gateHandle = pCbCtl->gateHandle;
362 // Enter gate
363 key = GateMP_enter(gateHandle);
365 // Get circular buffer base pointer
366 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
368 // get pointer to current audio frame in circular buffer
369 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
371 // update audio frame write index
372 pCb->afWrtIdx++;
373 if (pCb->afWrtIdx > pCb->maxNumAfCb)
374 {
375 pCb->afWrtIdx = 0;
376 }
378 // Leave the gate
379 GateMP_leave(gateHandle, key);
381 return ASP_DECOP_CB_SOK;
382 }