[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 <ti/sysbios/hal/Cache.h>
39 #include <xdc/runtime/Log.h>
41 #include "common.h"
42 #include "paftyp.h"
43 //#include "pafdec.h"
44 //#include "pafsp.h"
45 #include "aspDecOpCircBuf_slave.h"
47 // Initialize circular buffer control
48 Int cbCtlInit(
49 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
50 PAF_AST_DecOpCircBuf *xDecOpCb // decoder output circular buffer base pointer
51 )
52 {
53 GateMP_Handle gateHandle;
54 Int status;
56 status = GateMP_open(ASP_DECODE_CB_GATE_NAME, &gateHandle);
57 if (status < 0)
58 {
59 return ASP_DECOP_CB_CTL_INIT_INV_GATE;
60 }
62 pCbCtl->xDecOpCb = xDecOpCb;
64 return ASP_DECOP_CB_SOK;
66 }
68 // Start writes to circular buffer
69 Int cbWriteStart(
70 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
71 Int8 cbIdx // decoder output circular buffer index
72 )
73 {
74 IArg key;
75 GateMP_Handle gateHandle;
76 PAF_AST_DecOpCircBuf *pCb;
77 PAF_AudioFrame *pAfCb;
78 Int8 n;
79 //Int8 i;
81 // Get gate handle
82 gateHandle = pCbCtl->gateHandle;
83 // Enter gate
84 key = GateMP_enter(gateHandle);
86 // Get circular buffer base pointer
87 pCb = &pCbCtl->xDecOpCb[cbIdx];
89 // (***) FL: revisit
90 // Invalidate circular buffer configuration.
91 // NOTE: Probably only a subset of this information needs to be updated.
92 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
93 Cache_wait();
95 // Invalidate AF circular buffer
96 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
97 for (n=0; n<pCb->maxNumAfCb; n++)
98 {
99 pAfCb = &pCb->afCb[n];
100 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
101 // FL: unnecessary since part of AF
102 //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++) //QIN
103 //{
104 // Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
105 //}
106 }
107 Cache_wait();
109 // update flags
110 pCb->writerActiveFlag = 1;
111 pCb->emptyFlag = 0;
113 // (***) FL: revisit
114 // Write back circular buffer configuration
115 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
116 Cache_wait();
118 // Leave the gate
119 GateMP_leave(gateHandle, key);
121 return ASP_DECOP_CB_SOK;
122 };
124 // Stop writes to circular buffer
125 Int cbWriteStop(
126 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
127 Int8 cbIdx // decoder output circular buffer index
128 )
129 {
130 IArg key;
131 GateMP_Handle gateHandle;
132 PAF_AST_DecOpCircBuf *pCb;
134 // Get gate handle
135 gateHandle = pCbCtl->gateHandle;
136 // Enter gate
137 key = GateMP_enter(gateHandle);
139 // Get circular buffer base pointer
140 pCb = &pCbCtl->xDecOpCb[cbIdx];
142 // Invalidate circular buffer configuration
143 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
144 Cache_wait();
146 // update flags
147 pCb->writerActiveFlag = 0;
148 pCb->emptyFlag = 1;
150 // (***) FL: revisit
151 // Write back circular buffer configuration
152 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
153 Cache_wait();
155 // Leave the gate
156 GateMP_leave(gateHandle, key);
158 return ASP_DECOP_CB_SOK;
159 }
161 // Write audio frame to circular buffer
162 Int cbWriteAf(
163 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
164 Int8 cbIdx, // decoder output circular buffer index
165 PAF_AudioFrame *pAfWrt // audio frame from which to write
166 )
167 {
168 IArg key;
169 GateMP_Handle gateHandle;
170 PAF_AST_DecOpCircBuf *pCb;
171 PAF_AudioFrame *pAfCb;
172 PAF_ChannelMask_HD streamMask;
173 Int8 i;
174 Int16 j;
176 // Get gate handle
177 gateHandle = pCbCtl->gateHandle;
178 // Enter gate
179 key = GateMP_enter(gateHandle);
181 // Get circular buffer base pointer
182 pCb = &pCbCtl->xDecOpCb[cbIdx];
184 // (***) FL: revisit
185 // Invalidate circular buffer configuration.
186 // NOTE: Probably only a subset of this information nexeds to be updated.
187 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
188 Cache_wait();
190 if (pCb->readerActiveFlag == 1)
191 {
192 //
193 // Normal case, reader active.
194 // If reader not active, don't write to circular buffer or check OVRflow.
196 #if 0
197 if (pCb->cbWriteAfInit == 0)
198 {
199 // Invalidate AF circular buffer
200 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
201 for (n=0; n<pCb->maxNumAfCb; n++)
202 {
203 pAfCb = &pCb->afCb[n];
204 Cache_inv(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
205 }
206 Cache_wait();
208 pCb->cbWriteAfInit = 1;
209 }
210 #endif
212 // check overflow
213 if (pCb->numAfCb >= pCb->maxNumAfCb)
214 {
215 pCb->errOvrCnt++;
217 //SW_BREAKPOINT;
218 Log_info1("cbWriteAf: ERROR: overflow, numAfCb=%d", pCb->numAfCb);
220 // Leave the gate
221 GateMP_leave(gateHandle, key);
223 return ASP_DECOP_CB_WRITE_OVERFLOW;
224 }
226 // get pointer to current audio frame in circular buffer
227 pAfCb = &pCb->afCb[pCb->afWrtIdx];
229 // write audio frame information updated by decoder
230 pAfCb->sampleDecode = pAfWrt->sampleDecode;
231 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
232 pAfCb->sampleRate = pAfWrt->sampleRate;
233 pAfCb->sampleCount = pAfWrt->sampleCount;
234 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
235 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
236 // write metadata information updated by decoder //QIN
237 pAfCb->bsMetadata_type = pAfWrt->bsMetadata_type; /* non zero if metadata is attached. */
238 pAfCb->pafBsMetadataUpdate = pAfWrt->pafBsMetadataUpdate; /* indicates whether bit-stream metadata update */
239 pAfCb->numPrivateMetadata = pAfWrt->numPrivateMetadata; /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
240 pAfCb->bsMetadata_offset = pAfWrt->bsMetadata_offset; /* offset into audio frame for change in bsMetadata_type field */
241 // write PCM samples
242 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
243 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
244 {
245 if ((streamMask >> i) & 0x1)
246 {
247 for (j = 0; j < pCb->decOpFrameLen; j++)
248 {
249 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
250 }
252 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
253 }
254 }
256 // Write metadata to circular buffer
257 for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only copy numPrivateMetadata
258 {
259 pAfCb->pafPrivateMetadata[i].offset = pAfWrt->pafPrivateMetadata[i].offset;
260 pAfCb->pafPrivateMetadata[i].size = pAfWrt->pafPrivateMetadata[i].size;
261 memcpy(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].pMdBuf, pAfWrt->pafPrivateMetadata[i].size);
262 }
264 // update audio frame write index
265 pCb->afWrtIdx++;
266 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
267 {
268 pCb->afWrtIdx = 0;
269 }
271 // update number of audio frames in circular buffer
272 pCb->numAfCb++;
274 // (***) FL: revisit
275 // Write back circular buffer configuration
276 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
277 // write back audio frame
278 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
279 Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
280 // write back PCM data
281 for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
282 {
283 if ((streamMask >> i) & 0x1)
284 {
285 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
286 }
287 }
289 // write back private metadata // QIN
290 for (i=0; i<pAfCb->numPrivateMetadata; i++) // FL: only write back numPrivateMetadata
291 {
292 //Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
293 Cache_wb(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
294 }
295 Cache_wait();
296 }
298 // Leave the gate
299 GateMP_leave(gateHandle, key);
301 return ASP_DECOP_CB_SOK;
302 }
304 // Get next audio frame to write in circular buffer
305 Int cbGetNextWriteAf(
306 PAF_AST_DecOpCircBufCtl *pCbCtl, // decoder output circular buffer control
307 Int8 cbIdx, // decoder output circular buffer index
308 PAF_AudioFrame **ppAfWrt // audio frame next to be written
309 )
310 {
311 IArg key;
312 GateMP_Handle gateHandle;
313 PAF_AST_DecOpCircBuf *pCb;
315 // Get gate handle
316 gateHandle = pCbCtl->gateHandle;
317 // Enter gate
318 key = GateMP_enter(gateHandle);
320 // Get circular buffer base pointer
321 pCb = &pCbCtl->xDecOpCb[cbIdx];
323 // get pointer to current audio frame in circular buffer
324 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
326 // update audio frame write index
327 pCb->afWrtIdx++;
328 if (pCb->afWrtIdx > pCb->maxNumAfCb)
329 {
330 pCb->afWrtIdx = 0;
331 }
333 // Leave the gate
334 GateMP_leave(gateHandle, key);
336 return ASP_DECOP_CB_SOK;
337 }