[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 // 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, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
111 // FL: unnecessary since part of AF
112 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
113 //{
114 // Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
115 //}
116 }
117 Cache_wait();
119 // update flags
120 pCb->writerActiveFlag = 1;
121 pCb->emptyFlag = 0;
123 // (***) FL: revisit
124 // Write back circular buffer configuration
125 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
126 Cache_wait();
128 // Leave the gate
129 GateMP_leave(gateHandle, key);
131 return ASP_DECOP_CB_SOK;
132 };
134 // Stop writes to circular buffer
135 Int cbWriteStop(
136 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
137 Int8 cbIdx // decoder output circular buffer index
138 )
139 {
140 IArg key;
141 GateMP_Handle gateHandle;
142 PAF_AST_DecOpCircBuf *pCb;
144 // Get gate handle
145 gateHandle = pCbCtl->gateHandle;
146 // Enter gate
147 key = GateMP_enter(gateHandle);
149 // Get circular buffer base pointer
150 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
152 // Invalidate circular buffer configuration
153 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
154 Cache_wait();
156 //Log_info1("cbWriteStop:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
158 // update flags
159 pCb->writerActiveFlag = 0;
160 pCb->emptyFlag = 1;
162 // (***) FL: revisit
163 // Write back circular buffer configuration
164 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
165 Cache_wait();
167 // Leave the gate
168 GateMP_leave(gateHandle, key);
170 return ASP_DECOP_CB_SOK;
171 }
173 // Write audio frame to circular buffer
174 Int cbWriteAf(
175 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
176 Int8 cbIdx, // decoder output circular buffer index
177 PAF_AudioFrame *pAfWrt // audio frame from which to write
178 )
179 {
180 IArg key;
181 GateMP_Handle gateHandle;
182 PAF_AST_DecOpCircBuf *pCb;
183 PAF_AudioFrame *pAfCb;
184 PAF_ChannelMask_HD streamMask;
185 Int8 i;
186 Int16 j;
188 // Get gate handle
189 gateHandle = pCbCtl->gateHandle;
190 // Enter gate
191 key = GateMP_enter(gateHandle);
193 //Log_info2("cbWriteAf:gate enter, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
195 // Get circular buffer base pointer
196 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
197 //Log_info1("cbWriteAf:pCb=0x%04x", (IArg)pCb); // FL: debug
199 // (***) FL: revisit
200 // Invalidate circular buffer configuration.
201 // NOTE: Probably only a subset of this information nexeds to be updated.
202 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
203 Cache_wait();
205 //Log_info1("cbWriteAf:afCb=0x%04x", (IArg)pCb->afCb); // FL: debug
206 //Log_info2("cbWriteAf:pCb->readerActiveFlag=%d, pCb->writerActiveFlag=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->writerActiveFlag); // FL: debug
208 if (pCb->readerActiveFlag == 1)
209 {
210 //
211 // Normal case, reader active.
212 // If reader not active, don't write to circular buffer or check OVRflow.
214 #if 0
215 if (pCb->cbWriteAfInit == 0)
216 {
217 // Invalidate AF circular buffer
218 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
219 for (n=0; n<pCb->maxNumAfCb; n++)
220 {
221 pAfCb = &pCb->afCb[n];
222 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
223 }
224 Cache_wait();
226 pCb->cbWriteAfInit = 1;
227 }
228 #endif
230 //Log_info2("cbWriteAf:pCb->numAfCb=%d, pCb->maxNumAfCb=%d", (IArg)pCb->readerActiveFlag, (IArg)pCb->maxNumAfCb); // FL: debug
232 // check overflow
233 //while (pCb->numAfCb >= pCb->maxNumAfCb); // FL: debug
234 if (pCb->numAfCb >= pCb->maxNumAfCb)
235 {
236 pCb->errOvrCnt++;
238 //SW_BREAKPOINT;
239 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
241 // Write back circular buffer configuration
242 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
244 // Leave the gate
245 GateMP_leave(gateHandle, key);
247 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
249 return ASP_DECOP_CB_WRITE_OVERFLOW;
250 }
252 // get pointer to current audio frame in circular buffer
253 //Log_info2("cbWriteAf:afCb=0x%04x, pCb->afWrtIdx=%d", (IArg)pCb->afCb, (IArg)pCb->afWrtIdx); // FL: debug
254 pAfCb = &pCb->afCb[pCb->afWrtIdx];
255 //Log_info1("cbWriteAf:pAfCb=0x%04x", (IArg)pAfCb); // FL: debug
257 // write audio frame information updated by decoder
258 pAfCb->sampleDecode = pAfWrt->sampleDecode;
259 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
260 pAfCb->sampleRate = pAfWrt->sampleRate;
261 pAfCb->sampleCount = pAfWrt->sampleCount;
262 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
263 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
264 // write metadata information updated by decoder //QIN
265 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
266 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
267 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
268 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
269 // write PCM samples
270 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
271 //Log_info1("cbWriteAf:streamMask=0x%04x", (IArg)streamMask); // FL: debug
272 //Log_info1("cbWriteAf:pCb->decOpFrameLen=%d", (IArg)pCb->decOpFrameLen); // FL: debug
273 //Log_info2("cbWriteAf:pAfCb->data.sample=0x%04x, pAfWrt->data.sample=0x%04x", (IArg)pAfCb->data.sample, (IArg)pAfWrt->data.sample); // FL: debug
274 //Log_info2("cbWriteAf:pAfCb->data.samsiz=0x%04x, pAfWrt->data.samsiz=0x%04x", (IArg)pAfCb->data.samsiz, (IArg)pAfWrt->data.samsiz); // FL: debug
275 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
276 {
277 if ((streamMask >> i) & 0x1)
278 {
279 for (j = 0; j < pCb->decOpFrameLen; j++)
280 {
281 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
282 }
284 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
285 }
286 }
288 //Log_info1("cbWriteAf:pAfCb->numPrivateMetadata=%d", (IArg)pAfCb->numPrivateMetadata); // FL: debug
289 // Write metadata to circular buffer
290 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
291 {
292 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
293 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
294 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
295 }
297 // update audio frame write index
298 //Log_info2("cbWriteAf:pCb->afWrtIdx=%d, pCb->maxNumAfCb", (IArg)pCb->afWrtIdx, (IArg)pCb->maxNumAfCb); // FL: debug
299 pCb->afWrtIdx++;
300 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
301 {
302 pCb->afWrtIdx = 0;
303 }
304 //Log_info2("cbWriteAf:pCb->afWrtIdx=%d, pCb->maxNumAfCb", (IArg)pCb->afWrtIdx, (IArg)pCb->maxNumAfCb); // FL: debug
306 // update number of audio frames in circular buffer
307 //Log_info1("cbWriteAf:pCb->numAfCb=%d", (IArg)pCb->numAfCb); // FL: debug
308 pCb->numAfCb++;
309 //Log_info1("cbWriteAf:pCb->numAfCb=%d", (IArg)pCb->numAfCb); // FL: debug
311 // (***) FL: revisit
312 // Write back circular buffer configuration
313 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
314 // write back audio frame
315 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
316 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
317 // write back PCM data
318 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
319 {
320 if ((streamMask >> i) & 0x1)
321 {
322 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
323 }
324 }
326 // write back private metadata // QIN
327 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
328 {
329 //Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
330 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
331 }
332 Cache_wait();
333 }
335 // Leave the gate
336 GateMP_leave(gateHandle, key);
338 //Log_info2("cbWriteAf:gate leave, gateHandle=0x%04x, key=%d", (IArg)gateHandle, (IArg)key); // FL: debug
340 return ASP_DECOP_CB_SOK;
341 }
343 // Get next audio frame to write in circular buffer
344 Int cbGetNextWriteAf(
345 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
346 Int8 cbIdx, // decoder output circular buffer index
347 PAF_AudioFrame **ppAfWrt // audio frame next to be written
348 )
349 {
350 IArg key;
351 GateMP_Handle gateHandle;
352 PAF_AST_DecOpCircBuf *pCb;
354 // Get gate handle
355 gateHandle = pCbCtl->gateHandle;
356 // Enter gate
357 key = GateMP_enter(gateHandle);
359 // Get circular buffer base pointer
360 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
362 // get pointer to current audio frame in circular buffer
363 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
365 // update audio frame write index
366 pCb->afWrtIdx++;
367 if (pCb->afWrtIdx > pCb->maxNumAfCb)
368 {
369 pCb->afWrtIdx = 0;
370 }
372 // Leave the gate
373 GateMP_leave(gateHandle, key);
375 return ASP_DECOP_CB_SOK;
376 }