948c1fb9b4716d0092a1f8f27a07b1421a1dff51
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / pasdk / test_dsp / framework / aspDecOpCircBuf_master.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 "aspDecOpCircBuf_master.h"
46 #define MAX_NUM_AF_PCM      ( 4 )
47 #define CB_INIT_RD_LAG_PCM  ( 2 ) // 0...3
49 #define MAX_NUM_AF_DDP      ( 2 )
50 #define CB_INIT_RD_LAG_DDP  ( 4 ) // 0...5
52 // Generate mute AF on circular buffer read
53 static Void cbReadAfMute(
54     PAF_AudioFrame *pAfRd,      // audio frame into which to read
55     Int16 strFrameLen           // stream frame length (output transaction size)
56 );
58 // Initialize circular buffer
59 Int cbInit(
60     Int8 sourceSelect,          // source select (PCM, DDP, etc.)
61     Int16 decOpFrameLen,        // decoder output frame length (PCM samples)
62     Int16 strFrameLen,          // stream frame length (PCM samples)
63     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer
64     Int8 resetRwFlags           // whether to reset reader, writer, and empty flags
65 )
66 {
67     PAF_AudioFrame *pAfCb;
68     PAF_AudioData *pPcmBuf;
69     UInt8 *pMetaBuf; //QIN
70     Int8 n;
71     Int8 i;
73     // set input frame length
74     pCb->decOpFrameLen = decOpFrameLen;
75     
76     // set output frame length
77     pCb->strFrameLen = strFrameLen;
78     
79     // initialize circular buffer maximum number of audio frames
80     if (sourceSelect == PAF_SOURCE_PCM)
81     {
82         pCb->maxNumAfCb = MAX_NUM_AF_PCM;
83         pCb->afWrtIdx = CB_INIT_RD_LAG_PCM;
84         pCb->afRdIdx = 0;
85         pCb->pcmRdIdx = 0; // 2*256 in behind
86         
87         // initialize audio frames
88         for (n=0; n<pCb->maxNumAfCb; n++)
89         {
90             pAfCb = &pCb->afCb[n];
91             pAfCb->sampleDecode = PAF_SOURCE_PCM;
92             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
93             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
94             pAfCb->sampleCount = decOpFrameLen;
95             pAfCb->channelConfigurationRequest.full = 0;
96             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
97             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
98             pAfCb->channelConfigurationStream.full = 0;
99             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
100             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
101         }
102     }
103     else if (sourceSelect == PAF_SOURCE_DDP)
104     {
105         pCb->maxNumAfCb = MAX_NUM_AF_DDP;
106         pCb->afWrtIdx = 1;
107         pCb->afRdIdx = 0;
108         pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG_DDP*strFrameLen; // 4*256 behind
109         
110         // initialize audio frames
111         for (n=0; n<pCb->maxNumAfCb; n++)
112         {
113             pAfCb = &pCb->afCb[n];
114             pAfCb->sampleDecode = PAF_SOURCE_DDP;
115             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
116             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
117             pAfCb->sampleCount = decOpFrameLen;
118             pAfCb->channelConfigurationRequest.full = 0;
119             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
120             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
121             pAfCb->channelConfigurationStream.full = 0;
122             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
123             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
124         }
125     }
126     else
127     {
128         return ASP_DECOP_CB_INIT_INV_SOURCE_SEL;
129     }
131     // initialize circular buffer current number of frames
132     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
133     
134     // initialize audio frame PCM buffers
135     pPcmBuf = pCb->pcmBuf;
136     pMetaBuf = pCb->metaBuf; //QIN
137     for (n=0; n<pCb->maxNumAfCb; n++)
138     {
139         pAfCb = &pCb->afCb[n];
140         pAfCb->data.nChannels = ASP_DECOP_CB_MAX_NUM_PCM_CH;
141         pAfCb->data.nSamples = decOpFrameLen;
142         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
143         {
144             pAfCb->data.sample[i] = pPcmBuf;
145             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
146             pPcmBuf += decOpFrameLen;
147             
148             pAfCb->data.samsiz[i] = 0;
149         }
150         
151         // Initialize metadata buffers //QIN
152         for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)
153         {
154             pAfCb->pafPrivateMetadata[i].offset = 0; 
155             pAfCb->pafPrivateMetadata[i].size   = 0; 
156             pAfCb->pafPrivateMetadata[i].pMdBuf = pMetaBuf;
157             pMetaBuf += PAF_MAX_PRIVATE_MD_SZ;
158         }
159     }
160     
161     // reset read/write flags
162     if (resetRwFlags)
163     {
164         pCb->writerActiveFlag = 0;
165         pCb->readerActiveFlag = 0;
166         pCb->emptyFlag = 0;
167     }
168     // reset error counts
169     pCb->errUndCnt = 0;
170     pCb->errOvrCnt = 0;
171     
172     // (***) FL: revisit
173     // Write back circular buffer configuration
174     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
175     // Write back AF circular buffer
176     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
177     // Write back PCM data
178     for (n=0; n<pCb->maxNumAfCb; n++)
179     {
180         pAfCb = &pCb->afCb[n];
181         Cache_wb(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
182         Cache_wb(pAfCb->data.sample, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
183         for (i=0; i<ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
184         {
185             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
186         }
187         // FL: unnecessary since part of AF
188         //for (i=0; i<PAF_MAX_NUM_PRIVATE_MD; i++)     // Write back metadata //QIN
189         //{
190         //    Cache_wb(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
191         //}
192     }
193     Cache_wait();
195     return ASP_DECOP_CB_SOK;
198 // Start reads from circular buffer
199 Int cbReadStart(
200     PAF_AST_DecOpCircBuf *pCb   // decoder output circular buffer
203     // Invalidate circular buffer configuration
204     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
205     Cache_wait();
206     
207     // update flags
208     pCb->readerActiveFlag = 1;
209     
210     // (***) FL: revisit
211     // Write back circular buffer configuration
212     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
213     Cache_wait();
215     return ASP_DECOP_CB_SOK;
218 // Stop reads from circular buffer
219 Int cbReadStop(
220     PAF_AST_DecOpCircBuf *pCb   // decoder output circular buffer
223     // Invalidate circular buffer configuration
224     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
225     Cache_wait();
226     
227     // update flags
228     pCb->readerActiveFlag = 0;
229     
230     // (***) FL: revisit
231     // Write back circular buffer configuration
232     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
233     Cache_wait();
235     return ASP_DECOP_CB_SOK;
238 // Read audio frame from circular buffer
239 Int cbReadAf(
240     PAF_AST_DecOpCircBuf *pCb,  // decoder output circular buffer
241     PAF_AudioFrame *pAfRd       // audio frame into which to read
244     PAF_AudioFrame *pAfCb;
245     PAF_ChannelMask_HD streamMask;
246     Int8 i;
247     Int16 j;
249     // (***) FL: revisit
250     // Invalidate circular buffer configuration.
251     Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
252     Cache_wait();
254     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
255     {
256         // This shouldn't occur:
257         //  writer is active AND draining circular buffer
258         Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
259         SW_BREAKPOINT; // FL: debug
260         return ASP_DECOP_CB_READ_INVSTATE;
261     }
263     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
264     {
265         //
266         // No active writer, not draining circular buffer.
267         // Skip UNDerflow check, mute output.
268         //
269         cbReadAfMute(pAfRd, pCb->strFrameLen);
270         
271         return ASP_DECOP_CB_SOK;
272     }
273         
274     if ((pCb->writerActiveFlag == 1))
275     {
276         // check underflow
277         if (pCb->numAfCb <= 0)
278         {
279             // 
280             // Increment underflow count.
281             // Mute output on underflow.
282             //
283             pCb->errUndCnt++;
284             cbReadAfMute(pAfRd, pCb->strFrameLen);
285             //SW_BREAKPOINT; // FL: debug
286             
287             // Write back circular buffer configuration.
288             Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
289             Cache_wait();    
290             
291             return ASP_DECOP_CB_READ_UNDERFLOW;
292         }
293     }
294     
295     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
296     {
297         //
298         // Writer active or draining remaining frames in circular buffer.
299         // Get next output audio frame.
300         //
301         
302         // get pointer to current audio frame in circular buffer
303         pAfCb = &pCb->afCb[pCb->afRdIdx];
305         // (***) FL: revisit
306         // Invalidate audio frame
307         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
308         Cache_inv(pAfCb->data.samsiz, ASP_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
309         for (i=0; i<pAfCb->numPrivateMetadata; i++) //QIN // FL: only invalidate numPrivateMetadata
310         {
311             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0); // FL: unnecessary since part of AF
312             Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0); // FL: only update metadata package size
313         }
314         Cache_wait();
316         // compute stream mask
317         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
319         // Invalidate PCM data
320         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
321         {
322             if ((streamMask >> i) & 0x1)
323             {
324                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
325             }
326         }
327         Cache_wait();        
328         
329         // read audio frame information updated by decoder
330         pAfRd->sampleDecode = pAfCb->sampleDecode;
331         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
332         pAfRd->sampleRate = pAfCb->sampleRate;
333         pAfRd->sampleCount = pCb->strFrameLen;
334         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
335         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
336         
337         // read metadata information updated by decoder //QIN
338         pAfRd->bsMetadata_type     = pAfCb->bsMetadata_type;        /* non zero if metadata is attached. */
339         pAfRd->pafBsMetadataUpdate = pAfCb->pafBsMetadataUpdate;    /* indicates whether bit-stream metadata update */
340         pAfRd->numPrivateMetadata  = pAfCb->numPrivateMetadata;     /* number of valid private metadata (0 or 1 if metadata filtering enabled) */
341         pAfRd->bsMetadata_offset   = pAfCb->bsMetadata_offset;      /* offset into audio frame for change in bsMetadata_type field */
342         
343         // read PCM samples
344         for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
345         {
346             if ((streamMask >> i) & 0x1)
347             {
348                 for (j = 0; j < pCb->strFrameLen; j++)
349                 {
350                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
351                 }
353                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
354             }
355         }
356         // read metadata //QIN
357         for (i = 0; i < pAfCb->numPrivateMetadata; i++) // FL: only read numPrivateMetadata
358         {
359             // FL: this is done above
360             ////Invalidate metadata data
361             //Cache_inv(&pAfCb->pafPrivateMetadata[i], sizeof(PAF_PrivateMetadata), Cache_Type_ALLD, 0);
362             //Cache_wait();        
363             
364             if ((pAfCb->pafPrivateMetadata[i].offset >= pCb->pcmRdIdx) 
365                  &&(pAfCb->pafPrivateMetadata[i].offset < (pCb->pcmRdIdx + pCb->strFrameLen))
366                  &&(pAfCb->pafPrivateMetadata[i].size))
367             {
368                 // FL: this is done above
369                 ////Invalidate metadata data
370                 //Cache_inv(pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size, Cache_Type_ALLD, 0);
371                 //Cache_wait();        
372         
373                 // the offset is adjusted for segment [pCb->pcmRdIdx, (pCb->pcmRdIdx + pCb->pafFrameLen)]
374                 pAfRd->pafPrivateMetadata[i].offset = 0; //pAfCb->pafPrivateMetadata[i].offset - pCb->pcmRdIdx;
375                 pAfRd->pafPrivateMetadata[i].size   = pAfCb->pafPrivateMetadata[i].size;
376                 memcpy(pAfRd->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].pMdBuf, pAfCb->pafPrivateMetadata[i].size);
377             }
378             else //reset un-used buf
379             {
380                 pAfRd->pafPrivateMetadata[i].offset = 0;
381                 pAfRd->pafPrivateMetadata[i].size   = 0;
382             }
383         }
384         
385         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
386         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
387         {
388             // update audio frame read index
389             pCb->afRdIdx++;
390             if (pCb->afRdIdx >= pCb->maxNumAfCb)
391             {
392                 pCb->afRdIdx = 0;
393             }
394             
395             // update PCM read index
396             pCb->pcmRdIdx = 0;
397             
398             // update number of audio frames in circular buffer
399             pCb->numAfCb--;
400         }
401     }
402     
403     if (pCb->emptyFlag == 1)
404     {
405         //
406         // Writer inactive, but remaining frames in circular buffer.
407         // Update empty flag.
408         //
409         if (pCb->numAfCb <= 0)
410         {
411             pCb->emptyFlag = 0;
412         }
413     }
414     
415     // (***) FL: revisit
416     // Write back circular buffer configuration.
417     // NOTE: Probably only a subset of this information needs to be updated.
418     Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
419     Cache_wait();    
420         
421     return ASP_DECOP_CB_SOK;
424 // Generate mute AF on circular buffer read
425 static Void cbReadAfMute(
426     PAF_AudioFrame *pAfRd,      // audio frame into which to read
427     Int16 strFrameLen           // stream frame length (output transaction size)
430     PAF_ChannelMask_HD streamMask;
431     Int8 i;
432     
433     pAfRd->sampleDecode = PAF_SOURCE_PCM;
434     PAF_PROCESS_ZERO(pAfRd->sampleProcess);
435     pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
436     pAfRd->sampleCount = strFrameLen;
437     pAfRd->channelConfigurationRequest.full = 0;
438     pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
439     pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
440     pAfRd->channelConfigurationStream.full = 0;
441     pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
442     pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
443     
444     // compute stream mask
445     streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
446     // Clear PCM data
447     for (i = 0; i < ASP_DECOP_CB_MAX_NUM_PCM_CH; i++)
448     {
449         if ((streamMask >> i) & 0x1)
450         {
451             memset(pAfRd->data.sample[i], strFrameLen, 0);
452         }
453         pAfRd->data.samsiz[i] = 0;
454     }