750fe4df3eaaca4c0cc6072002462c4c04843483
[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;
56     
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     }
69     
70     pCbCtl->pXDecOpCb = pXDecOpCb;
71     
72     return ASP_DECOP_CB_SOK;
73     
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();
102     
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();
116             
117     // update flags
118     pCb->writerActiveFlag = 1;
119     pCb->emptyFlag = 0;
120     
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
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();
153     
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();
162     
163     // Leave the gate
164     GateMP_leave(gateHandle, key);
166     return ASP_DECOP_CB_SOK;
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
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();
197     
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         }
233         
234         // get pointer to current audio frame in circular buffer
235         pAfCb = &pCb->afCb[pCb->afWrtIdx];
236            
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                 }            
259                 
260                 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
261             }
262         }
263         
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         }
271         
272         // update audio frame write index
273         pCb->afWrtIdx++;
274         if (pCb->afWrtIdx >= pCb->maxNumAfCb)
275         {
276             pCb->afWrtIdx = 0;
277         }
278         
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         }
296         
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     }  
305     
306     // Leave the gate
307     GateMP_leave(gateHandle, key);
309     return ASP_DECOP_CB_SOK;
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
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];
333     
334     // update audio frame write index
335     pCb->afWrtIdx++;
336     if (pCb->afWrtIdx > pCb->maxNumAfCb)
337     {
338         pCb->afWrtIdx = 0;
339     }    
340     
341     // Leave the gate
342     GateMP_leave(gateHandle, key);
344     return ASP_DECOP_CB_SOK;