[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 // Invalidate AF circular buffer
104 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
105 for (n=0; n<pCb->maxNumAfCb; n++)
106 {
107 pAfCb = &pCb->afCb[n];
108 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
109 // FL: unnecessary since part of AF
110 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
111 //{
112 // Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
113 //}
114 }
115 Cache_wait();
117 // update flags
118 pCb->writerActiveFlag = 1;
119 pCb->emptyFlag = 0;
121 // (***) FL: revisit
122 // Write back circular buffer configuration
123 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
124 Cache_wait();
126 // Leave the gate
127 GateMP_leave(gateHandle, key);
129 return ASP_DECOP_CB_SOK;
130 };
132 // Stop writes to circular buffer
133 Int cbWriteStop(
134 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
135 Int8 cbIdx // decoder output circular buffer index
136 )
137 {
138 IArg key;
139 GateMP_Handle gateHandle;
140 PAF_AST_DecOpCircBuf *pCb;
142 // Get gate handle
143 gateHandle = pCbCtl->gateHandle;
144 // Enter gate
145 key = GateMP_enter(gateHandle);
147 // Get circular buffer base pointer
148 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
150 // Invalidate circular buffer configuration
151 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
152 Cache_wait();
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();
163 // Leave the gate
164 GateMP_leave(gateHandle, key);
166 return ASP_DECOP_CB_SOK;
167 }
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
174 )
175 {
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;
184 // Get gate handle
185 gateHandle = pCbCtl->gateHandle;
186 // Enter gate
187 key = GateMP_enter(gateHandle);
189 // Get circular buffer base pointer
190 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
192 // (***) FL: revisit
193 // Invalidate circular buffer configuration.
194 // NOTE: Probably only a subset of this information nexeds to be updated.
195 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
196 Cache_wait();
198 if (pCb->readerActiveFlag == 1)
199 {
200 //
201 // Normal case, reader active.
202 // If reader not active, don't write to circular buffer or check OVRflow.
204 #if 0
205 if (pCb->cbWriteAfInit == 0)
206 {
207 // Invalidate AF circular buffer
208 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
209 for (n=0; n<pCb->maxNumAfCb; n++)
210 {
211 pAfCb = &pCb->afCb[n];
212 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
213 }
214 Cache_wait();
216 pCb->cbWriteAfInit = 1;
217 }
218 #endif
220 // check overflow
221 if (pCb->numAfCb >= pCb->maxNumAfCb)
222 {
223 pCb->errOvrCnt++;
225 //SW_BREAKPOINT;
226 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
228 // Leave the gate
229 GateMP_leave(gateHandle, key);
231 return ASP_DECOP_CB_WRITE_OVERFLOW;
232 }
234 // get pointer to current audio frame in circular buffer
235 pAfCb = &pCb->afCb[pCb->afWrtIdx];
237 // write audio frame information updated by decoder
238 pAfCb->sampleDecode = pAfWrt->sampleDecode;
239 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
240 pAfCb->sampleRate = pAfWrt->sampleRate;
241 pAfCb->sampleCount = pAfWrt->sampleCount;
242 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
243 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
244 // write metadata information updated by decoder //QIN
245 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
246 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
247 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
248 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
249 // write PCM samples
250 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
251 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
252 {
253 if ((streamMask >> i) & 0x1)
254 {
255 for (j = 0; j < pCb->decOpFrameLen; j++)
256 {
257 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
258 }
260 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
261 }
262 }
264 // Write metadata to circular buffer
265 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
266 {
267 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
268 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
269 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
270 }
272 // update audio frame write index
273 pCb->afWrtIdx++;
274 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
275 {
276 pCb->afWrtIdx = 0;
277 }
279 // update number of audio frames in circular buffer
280 pCb->numAfCb++;
282 // (***) FL: revisit
283 // Write back circular buffer configuration
284 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
285 // write back audio frame
286 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
287 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
288 // write back PCM data
289 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
290 {
291 if ((streamMask >> i) & 0x1)
292 {
293 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
294 }
295 }
297 // write back private metadata // QIN
298 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
299 {
300 //Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
301 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
302 }
303 Cache_wait();
304 }
306 // Leave the gate
307 GateMP_leave(gateHandle, key);
309 return ASP_DECOP_CB_SOK;
310 }
312 // Get next audio frame to write in circular buffer
313 Int cbGetNextWriteAf(
314 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
315 Int8 cbIdx, // decoder output circular buffer index
316 PAF_AudioFrame **ppAfWrt // audio frame next to be written
317 )
318 {
319 IArg key;
320 GateMP_Handle gateHandle;
321 PAF_AST_DecOpCircBuf *pCb;
323 // Get gate handle
324 gateHandle = pCbCtl->gateHandle;
325 // Enter gate
326 key = GateMP_enter(gateHandle);
328 // Get circular buffer base pointer
329 pCb = &((*pCbCtl->pXDecOpCb)[cbIdx]);
331 // get pointer to current audio frame in circular buffer
332 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
334 // update audio frame write index
335 pCb->afWrtIdx++;
336 if (pCb->afWrtIdx > pCb->maxNumAfCb)
337 {
338 pCb->afWrtIdx = 0;
339 }
341 // Leave the gate
342 GateMP_leave(gateHandle, key);
344 return ASP_DECOP_CB_SOK;
345 }