Add GateMP for Decoder Output Circular Buffer
[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;
55     
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     }
61     
62     pCbCtl->xDecOpCb = xDecOpCb;
63     
64     return ASP_DECOP_CB_SOK;
65     
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();
94     
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();
108             
109     // update flags
110     pCb->writerActiveFlag = 1;
111     pCb->emptyFlag = 0;
112     
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
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();
145     
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();
154     
155     // Leave the gate
156     GateMP_leave(gateHandle, key);
158     return ASP_DECOP_CB_SOK;
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
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();
189     
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         }
225         
226         // get pointer to current audio frame in circular buffer
227         pAfCb = &pCb->afCb[pCb->afWrtIdx];
228            
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                 }            
251                 
252                 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
253             }
254         }
255         
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         }
263         
264         // update audio frame write index
265         pCb->afWrtIdx++;
266         if (pCb->afWrtIdx >= pCb->maxNumAfCb)
267         {
268             pCb->afWrtIdx = 0;
269         }
270         
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         }
288         
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     }  
297     
298     // Leave the gate
299     GateMP_leave(gateHandle, key);
301     return ASP_DECOP_CB_SOK;
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
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];
325     
326     // update audio frame write index
327     pCb->afWrtIdx++;
328     if (pCb->afWrtIdx > pCb->maxNumAfCb)
329     {
330         pCb->afWrtIdx = 0;
331     }    
332     
333     // Leave the gate
334     GateMP_leave(gateHandle, key);
336     return ASP_DECOP_CB_SOK;