]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - procsdk_audio_x_xx_xx_xx/common/paf_decOpCircBuf.c
Changed pingpong buffering of DDP in circular buffer to triple buffering to prevent...
[processor-sdk/performance-audio-sr.git] / procsdk_audio_x_xx_xx_xx / common / paf_decOpCircBuf.c
1 #include <string.h> // for memset()
2 #include <xdc/std.h>
3 #include <ti/sysbios/hal/Cache.h>
4 #include <xdc/runtime/Log.h>
6 #include "pafdec.h"
7 #include "pafsp.h"
8 #include "paf_decOpCircBuf.h"
10 #define MAX_NUM_AF_PCM      ( 4 )
11 #define MAX_NUM_AF_DDP      ( 3 ) //Qin - Increased to prevent cb overflow.
13 #define CB_INIT_RD_LAG      ( 2 )
15 // Initialize circular buffer
16 Int cbInit(
17     Int8 sourceSelect,          // source select (PCM, DDP, etc.)
18     Int16 decOpFrameLen,        // decoder output frame length (PCM samples)
19     Int16 strFrameLen,          // stream frame length (PCM samples)
20     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
21 )
22 {
23     PAF_AudioFrame *pAfCb;
24     PAF_AudioData *pPcmBuf;
25     Int8 n;
26     Int8 i;
28     // set input frame length
29     pCb->decOpFrameLen = decOpFrameLen;
30     
31     // set output frame length
32     pCb->strFrameLen = strFrameLen;
33     
34     // initialize circular buffer maximum number of audio frames
35     if (sourceSelect == PAF_SOURCE_PCM)
36     {
37         pCb->maxNumAfCb = MAX_NUM_AF_PCM;
38         pCb->afWrtIdx = CB_INIT_RD_LAG;
39         pCb->afRdIdx = 0;
40         pCb->pcmRdIdx = 0; // 2*256 in behind
41         
42         // initialize audio frames
43         for (n=0; n<pCb->maxNumAfCb; n++)
44         {
45             pAfCb = &pCb->afCb[n];
46             pAfCb->sampleDecode = PAF_SOURCE_PCM;
47             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
48             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
49             pAfCb->sampleCount = decOpFrameLen;
50             pAfCb->channelConfigurationRequest.full = 0;
51             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
52             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
53             pAfCb->channelConfigurationStream.full = 0;
54             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
55             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
56         }
57     }
58     else if (sourceSelect == PAF_SOURCE_DDP)
59     {
60         pCb->maxNumAfCb = MAX_NUM_AF_DDP;
61         pCb->afRdIdx = 0;
62         pCb->afWrtIdx = 0;//1;//QIN - Reduce delay to prevent cb overflow. Need further investigation.
63         pCb->pcmRdIdx = 0;//decOpFrameLen - CB_INIT_RD_LAG*strFrameLen; //QIN - Reduce delay to prevent cb overflow. Need further investigation.
64         
65         // initialize audio frames
66         for (n=0; n<pCb->maxNumAfCb; n++)
67         {
68             pAfCb = &pCb->afCb[n];
69             pAfCb->sampleDecode = PAF_SOURCE_DDP;
70             PAF_PROCESS_ZERO(pAfCb->sampleProcess);
71             pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
72             pAfCb->sampleCount = decOpFrameLen;
73             pAfCb->channelConfigurationRequest.full = 0;
74             pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
75             pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
76             pAfCb->channelConfigurationStream.full = 0;
77             pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
78             pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
79         }
80     }
81     else
82     {
83         return PAF_DECOP_CB_INIT_INV_SOURCE_SEL;
84     }
86     // initialize circular buffer current number of frames
87     pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
88     
89     // initialize audio frame PCM buffers
90     pPcmBuf = pCb->pcmBuf;
91     for (n=0; n<pCb->maxNumAfCb; n++)
92     {
93         pAfCb = &pCb->afCb[n];
94         pAfCb->data.nChannels = PAF_DECOP_CB_MAX_NUM_PCM_CH;
95         pAfCb->data.nSamples = decOpFrameLen;
96         for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
97         {
98             pAfCb->data.sample[i] = pPcmBuf;
99             memset(pAfCb->data.sample[i], decOpFrameLen, 0);
100             pPcmBuf += decOpFrameLen;
101             
102             pAfCb->data.samsiz[i] = 0;
103         }
104     }
105     
106     // update flags
107     pCb->writerActiveFlag = 0;
108     pCb->readerActiveFlag = 0;
109     pCb->emptyFlag = 0;
110     //pCb->cbWriteAfInit = 0;
111     
112     // (***) FL: hackin'
113     // Write back circular buffer configuration
114     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
115     // Write back AF circular buffer
116     Cache_wb(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
117     // Write back PCM data
118     for (n=0; n<pCb->maxNumAfCb; n++)
119     {
120         pAfCb = &pCb->afCb[n];
121         Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
122         Cache_wb(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
123         for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
124         {
125             Cache_wb(pAfCb->data.sample[i], decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
126         }
127     }
128     Cache_wait();
130     return PAF_DECOP_CB_SOK;
133 // Start writes to circular buffer
134 Int cbWriteStart(
135     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
138     PAF_AudioFrame *pAfCb;
139     Int8 n;
141     // (***) FL: hackin'
142     // Invalidate circular buffer configuration.
143     // NOTE: Probably only a subset of this information needs to be updated.
144     Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
145     Cache_wait();
146     
147     // Invalidate AF circular buffer
148     Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
149     for (n=0; n<pCb->maxNumAfCb; n++)
150     {
151         pAfCb = &pCb->afCb[n];
152         Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
153     }
154     Cache_wait();
155             
156     // update flags
157     pCb->writerActiveFlag = 1;
158     pCb->emptyFlag = 0;
159     
160     // (***) FL: hackin'
161     // Write back circular buffer configuration
162     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
164     return PAF_DECOP_CB_SOK;
165 };
167 // Stop writes to circular buffer
168 Int cbWriteStop(
169     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
172     // update flags
173     pCb->writerActiveFlag = 0;
174     pCb->emptyFlag = 1;
176     // (***) FL: hackin'
177     // Write back circular buffer configuration
178     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
179     
180     return PAF_DECOP_CB_SOK;
183 // Start reads from circular buffer
184 Int cbReadStart(
185     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
188     // update flags
189     pCb->readerActiveFlag = 1;
190     
191     // (***) FL: hackin'
192     // Write back circular buffer configuration
193     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
195     return PAF_DECOP_CB_SOK;
198 // Stop reads from circular buffer
199 Int cbReadStop(
200     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
203     // update flags
204     pCb->readerActiveFlag = 0;
205     
206     // (***) FL: hackin'
207     // Write back circular buffer configuration
208     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
210     return PAF_DECOP_CB_SOK;
212 // restore read/write flags of the circular buffer. - QIN
213 Int cbReadWriteRestore(
214     PAF_DecodeOpCircBuf *pCb    // decoder output circular buffer
217     // Invalidate circular buffer configuration.
218     Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
219     Cache_wait();
221     // update flags
222     pCb->readerActiveFlag = 1;
223     pCb->writerActiveFlag = 1;
224     
225     // (***) FL: hackin'
226     // Write back circular buffer configuration
227     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
229     return PAF_DECOP_CB_SOK;
232 // Read audio frame from circular buffer
233 Int cbReadAf(
234     PAF_DecodeOpCircBuf *pCb,   // decoder output circular buffer
235     PAF_AudioFrame *pAfRd       // audio frame into which to read
238     PAF_AudioFrame *pAfCb;
239     PAF_ChannelMask_HD streamMask;
240     Int8 i;
241     Int16 j;
243     // (***) FL: hackin'
244     // Invalidate circular buffer configuration.
245     Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
246     Cache_wait();
248     if ((pCb->writerActiveFlag == 1) && (pCb->emptyFlag == 1))
249     {
250         // This shouldn't occur:
251         //  writer is active AND draining circular buffer
252         Log_info2("cbReadAf: ERROR: writerActiveFlag=%d, emptyFlag=%d", pCb->writerActiveFlag, pCb->emptyFlag);
253         return PAF_DECOP_CB_READ_INVSTATE;
254     }
256     if ((pCb->writerActiveFlag == 0) && (pCb->emptyFlag == 0))
257     {
258         //
259         // No active writer, not draining circular buffer.
260         // Skip UNDerflow check, mute output.
261         //
262         
263         pAfRd->sampleDecode = PAF_SOURCE_PCM;
264         PAF_PROCESS_ZERO(pAfRd->sampleProcess);
265         pAfRd->sampleRate = PAF_SAMPLERATE_48000HZ;
266         pAfRd->sampleCount = pCb->strFrameLen;
267         pAfRd->channelConfigurationRequest.full = 0;
268         pAfRd->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
269         pAfRd->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
270         pAfRd->channelConfigurationStream.full = 0;
271         pAfRd->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
272         pAfRd->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
273         
274         // compute stream mask
275         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfRd->channelConfigurationStream);
276         // Clear PCM data
277         for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
278         {
279             if ((streamMask >> i) & 0x1)
280             {
281                 memset(pAfRd->data.sample[i], pCb->strFrameLen, 0);
282             }
283             pAfRd->data.samsiz[i] = 0;
284         }
285         
286         return PAF_DECOP_CB_SOK;
287     }
288         
289     if ((pCb->writerActiveFlag == 1))
290     {
291         // check underflow
292         if (pCb->numAfCb <= 0)
293         {
294             return PAF_DECOP_CB_READ_UNDERFLOW;
295         }
296     }
297     
298     if ((pCb->writerActiveFlag == 1) || (pCb->emptyFlag == 1))
299     {
300         //
301         // Writer active or draining remaining frames in circular buffer.
302         // Get next output audio frame.
303         //
304         
305         // get pointer to current audio frame in circular buffer
306         pAfCb = &pCb->afCb[pCb->afRdIdx];
308         // (***) FL: hackin'
309         // Invalidate audio frame
310         Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
311         Cache_inv(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
312         Cache_wait();
314         // compute stream mask
315         streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
317         // Invalidate PCM data
318         for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
319         {
320             if ((streamMask >> i) & 0x1)
321             {
322                 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->strFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
323             }
324         }
325         Cache_wait();        
326         
327         // read audio frame information updated by decoder
328         pAfRd->sampleDecode = pAfCb->sampleDecode;
329         PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
330         pAfRd->sampleRate = pAfCb->sampleRate;
331         pAfRd->sampleCount = pCb->strFrameLen;
332         pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
333         pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
335         // read PCM samples
336         for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
337         {
338             if ((streamMask >> i) & 0x1)
339             {
340                 for (j = 0; j < pCb->strFrameLen; j++)
341                 {
342                     pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
343                 }
345                 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
346             }
347         }
348         
349         pCb->pcmRdIdx += pCb->strFrameLen; // update PCM read index
350         if (pCb->pcmRdIdx == pCb->decOpFrameLen)
351         {
352             // update audio frame read index
353             pCb->afRdIdx++;
354             if (pCb->afRdIdx >= pCb->maxNumAfCb)
355             {
356                 pCb->afRdIdx = 0;
357             }
358             
359             // update PCM read index
360             pCb->pcmRdIdx = 0;
361             
362             // update number of audio frames in circular buffer
363             pCb->numAfCb--;
364         }
365     }
366     
367     if (pCb->emptyFlag == 1)
368     {
369         //
370         // Writer inactive, but remaining frames in circular buffer.
371         // Update empty flag.
372         //
373         if (pCb->numAfCb <= 0)
374         {
375             pCb->emptyFlag = 0;
376         }
377     }
378     
379     // (***) FL: hackin'
380     // Write back circular buffer configuration.
381     // NOTE: Probably only a subset of this information needs to be updated.
382     Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
383     Cache_wait();    
384         
385     return PAF_DECOP_CB_SOK;
388 // Write audio frame to circular buffer
389 Int cbWriteAf(
390     PAF_DecodeOpCircBuf *pCb,   // decoder output circular buffer
391     PAF_AudioFrame *pAfWrt      // audio frame from which to write
394     PAF_AudioFrame *pAfCb;
395     PAF_ChannelMask_HD streamMask;
396     Int8 i;
397     Int16 j;
399     // (***) FL: hackin'
400     // Invalidate circular buffer configuration.
401     // NOTE: Probably only a subset of this information needs to be updated.
402     Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
403     Cache_wait();
404     
405     if (pCb->readerActiveFlag == 1)
406     {
407         //
408         // Normal case, reader active.
409         // If reader not active, don't write to circular buffer or check OVRflow.
411 #if 0        
412         if (pCb->cbWriteAfInit == 0)
413         {
414             // Invalidate AF circular buffer
415             Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
416             for (n=0; n<pCb->maxNumAfCb; n++)
417             {
418                 pAfCb = &pCb->afCb[n];
419                 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
420             }
421             Cache_wait();
423             pCb->cbWriteAfInit = 1;
424         }
425 #endif        
427         // check overflow
428         if (pCb->numAfCb >= pCb->maxNumAfCb)
429         {
430             return PAF_DECOP_CB_WRITE_OVERFLOW;
431         }
433         // get pointer to current audio frame in circular buffer
434         pAfCb = &pCb->afCb[pCb->afWrtIdx];
435            
436         // write audio frame information updated by decoder
437         pAfCb->sampleDecode = pAfWrt->sampleDecode;
438         PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
439         pAfCb->sampleRate = pAfWrt->sampleRate;
440         pAfCb->sampleCount = pAfWrt->sampleCount;
441         pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
442         pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
443         
444         // write PCM samples
445         streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
446         for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
447         {
448             if ((streamMask >> i) & 0x1)
449             {
450                 for (j = 0; j < pCb->decOpFrameLen; j++)
451                 {
452                     pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
453                 }            
454                 
455                 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
456             }
457         }
458         
459         // update audio frame write index
460         pCb->afWrtIdx++;
461         if (pCb->afWrtIdx >= pCb->maxNumAfCb)
462         {
463             pCb->afWrtIdx = 0;
464         }
465         
466         // update number of audio frames in circular buffer
467         pCb->numAfCb++;
469         // (***) FL: hackin'
470         // Write back circular buffer configuration
471         Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
472         // write back audio frame
473         Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
474         Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
475         // write back PCM data
476         for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
477         {
478             if ((streamMask >> i) & 0x1)
479             {
480                 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
481             }
482         }
483         Cache_wait();
484     }  
485     
486     return PAF_DECOP_CB_SOK;
489 // Get next audio frame to write in circular buffer
490 Int cbGetNextWriteAf(
491     PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
492     PAF_AudioFrame **ppAfWrt  // audio frame next to be written
495     // get pointer to current audio frame in circular buffer
496     *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
497     
498     // update audio frame write index
499     pCb->afWrtIdx++;
500     if (pCb->afWrtIdx > pCb->maxNumAfCb)
501     {
502         pCb->afWrtIdx = 0;
503     }    
504     
505     return PAF_DECOP_CB_SOK;
508 // Output log of circular buffer control variables (debug)
509 Int cbLog(
510     PAF_DecodeOpCircBuf *pCb,
511     Int8 fullLog
514     Log_info4("afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx, 
515         pCb->afWrtIdx, 
516         pCb->numAfCb);
517     if (fullLog)
518     {
519         Log_info1("maxNumAfCb=%d", pCb->maxNumAfCb);  
520         Log_info2("decOpFrameLen=%d, strFrameLen=%d", pCb->decOpFrameLen, pCb->strFrameLen);
521         //Log_info1("cbWriteInit=%d", pCb->cbWriteAfInit);
522     }
523     
524     return 0;