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 ( 2 )
13 #define CB_INIT_RD_LAG ( 2 )
15 // PCM audio frame data
17 // DDP audio frame data
19 // Initialize circular buffer
20 Int cbInit(
21 Int8 sourceSelect, // source select (PCM, DDP, etc.)
22 Int decOpFrameLen, // decoder output frame length
23 Int pafFrameLen, // PAF frame length
24 PAF_DecodeOpCircBuf *pCb // decoder output circular buffer
25 )
26 {
27 PAF_AudioFrame *pAfCb;
28 PAF_AudioData *pPcmBuf;
29 Int n;
30 Int i;
32 // set input frame length
33 pCb->decOpFrameLen = decOpFrameLen;
35 // set output frame length
36 pCb->pafFrameLen = pafFrameLen;
38 // initialize circular buffer maximum number of audio frames
39 if (sourceSelect == PAF_SOURCE_PCM)
40 {
41 pCb->maxNumAfCb = MAX_NUM_AF_PCM;
42 pCb->afWrtIdx = CB_INIT_RD_LAG;
43 pCb->afRdIdx = 0;
44 pCb->pcmRdIdx = 0; // 2*256 in behind
46 // initialize audio frames
47 for (n=0; n<pCb->maxNumAfCb; n++)
48 {
49 pAfCb = &pCb->afCb[n];
50 pAfCb->sampleDecode = PAF_SOURCE_PCM;
51 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
52 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
53 pAfCb->sampleCount = decOpFrameLen;
54 pAfCb->channelConfigurationRequest.full = 0;
55 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
56 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
57 pAfCb->channelConfigurationStream.full = 0;
58 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
59 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
60 }
61 }
62 else if (sourceSelect == PAF_SOURCE_DDP)
63 {
64 pCb->maxNumAfCb = MAX_NUM_AF_DDP;
65 pCb->afRdIdx = 0;
66 pCb->afWrtIdx = 1;
67 pCb->pcmRdIdx = decOpFrameLen - CB_INIT_RD_LAG*pafFrameLen; // 2*256 behind
69 // initialize audio frames
70 for (n=0; n<pCb->maxNumAfCb; n++)
71 {
72 pAfCb = &pCb->afCb[n];
73 pAfCb->sampleDecode = PAF_SOURCE_DDP;
74 PAF_PROCESS_ZERO(pAfCb->sampleProcess);
75 pAfCb->sampleRate = PAF_SAMPLERATE_48000HZ;
76 pAfCb->sampleCount = decOpFrameLen;
77 pAfCb->channelConfigurationRequest.full = 0;
78 pAfCb->channelConfigurationRequest.part.sat = PAF_CC_SAT_SURROUND4;
79 pAfCb->channelConfigurationRequest.part.sub = PAF_CC_SUB_ONE;
80 pAfCb->channelConfigurationStream.full = 0;
81 pAfCb->channelConfigurationStream.part.sat = PAF_CC_SAT_SURROUND4;
82 pAfCb->channelConfigurationStream.part.sub = PAF_CC_SUB_ONE;
83 }
84 }
85 else
86 {
87 return PAF_DECOP_CB_INIT_INV_SOURCE_SEL;
88 }
90 // initialize circular buffer current number of frames
91 pCb->numAfCb = pCb->afWrtIdx - pCb->afRdIdx;
93 // initialize audio frame PCM buffers
94 pPcmBuf = pCb->pcmBuf;
95 for (n=0; n<pCb->maxNumAfCb; n++)
96 {
97 pAfCb = &pCb->afCb[n];
98 pAfCb->data.nChannels = PAF_DECOP_CB_MAX_NUM_PCM_CH;
99 pAfCb->data.nSamples = decOpFrameLen;
100 for (i=0; i<PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
101 {
102 pAfCb->data.sample[i] = pPcmBuf;
103 memset(pAfCb->data.sample[i], decOpFrameLen, 0);
104 pPcmBuf += decOpFrameLen;
106 pAfCb->data.samsiz[i] = 0;
107 }
108 }
110 pCb->cbWriteInit = FALSE;
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;
131 }
133 // Read audio frame from circular buffer
134 Int cbReadAf(
135 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
136 PAF_AudioFrame *pAfRd // audio frame into which to read
137 )
138 {
139 PAF_AudioFrame *pAfCb;
140 PAF_ChannelMask_HD streamMask;
141 Int i, j;
143 // (***) FL: hackin'
144 // Invalidate circular buffer configuration.
145 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
146 Cache_wait();
148 // check underflow
149 if (pCb->numAfCb <= 0)
150 {
151 return PAF_DECOP_CB_READ_UNDERFLOW;
152 }
154 // get pointer to current audio frame in circular buffer
155 pAfCb = &pCb->afCb[pCb->afRdIdx];
157 // (***) FL: hackin'
158 // Invalidate audio frame
159 Cache_inv(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
160 Cache_inv(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
161 Cache_wait();
163 // compute stream mask
164 streamMask = pAfRd->fxns->channelMask(pAfRd, pAfCb->channelConfigurationStream);
166 // Invalidate PCM data
167 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
168 {
169 if ((streamMask >> i) & 0x1)
170 {
171 Cache_inv(&pAfCb->data.sample[i][pCb->pcmRdIdx], pCb->pafFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
172 }
173 }
174 Cache_wait();
176 // read audio frame information updated by decoder
177 pAfRd->sampleDecode = pAfCb->sampleDecode;
178 PAF_PROCESS_COPY(pAfRd->sampleProcess, pAfCb->sampleProcess);
179 pAfRd->sampleRate = pAfCb->sampleRate;
180 pAfRd->sampleCount = pCb->pafFrameLen;
181 pAfRd->channelConfigurationRequest = pAfCb->channelConfigurationRequest;
182 pAfRd->channelConfigurationStream = pAfCb->channelConfigurationStream;
184 // read PCM samples
185 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
186 {
187 if ((streamMask >> i) & 0x1)
188 {
189 for (j = 0; j < pCb->pafFrameLen; j++)
190 {
191 pAfRd->data.sample[i][j] = pAfCb->data.sample[i][pCb->pcmRdIdx+j];
192 }
194 pAfRd->data.samsiz[i] = pAfCb->data.samsiz[i];
195 }
196 }
198 pCb->pcmRdIdx += pCb->pafFrameLen; // update PCM read index
199 if (pCb->pcmRdIdx == pCb->decOpFrameLen)
200 {
201 // update audio frame read index
202 pCb->afRdIdx++;
203 if (pCb->afRdIdx >= pCb->maxNumAfCb)
204 {
205 pCb->afRdIdx = 0;
206 }
208 // update PCM read index
209 pCb->pcmRdIdx = 0;
211 // update number of audio frames in circular buffer
212 pCb->numAfCb--;
213 }
215 // (***) FL: hackin'
216 // Write back circular buffer configuration.
217 // NOTE: Probably only a subset of this information needs to be updated.
218 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
219 Cache_wait();
221 return PAF_DECOP_CB_SOK;
222 }
224 // Write audio frame to circular buffer
225 Int cbWriteAf(
226 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
227 PAF_AudioFrame *pAfWrt // audio frame from which to write
228 )
229 {
230 PAF_AudioFrame *pAfCb;
231 PAF_ChannelMask_HD streamMask;
232 Int n;
233 Int i, j;
235 // (***) FL: hackin'
236 // Invalidate circular buffer configuration.
237 // NOTE: Probably only a subset of this information needs to be updated.
238 Cache_inv(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
239 Cache_wait();
241 if (pCb->cbWriteInit == FALSE)
242 {
243 // Invalidate AF circular buffer
244 Cache_inv(pCb->afCb, pCb->maxNumAfCb*sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
245 for (n=0; n<pCb->maxNumAfCb; n++)
246 {
247 pAfCb = &pCb->afCb[n];
248 Cache_inv(pAfCb->data.sample, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioData *), Cache_Type_ALLD, 0);
249 }
250 Cache_wait();
252 pCb->cbWriteInit = TRUE;
253 }
255 // check overflow
256 if (pCb->numAfCb >= pCb->maxNumAfCb)
257 {
258 return PAF_DECOP_CB_WRITE_OVERFLOW;
259 }
261 // get pointer to current audio frame in circular buffer
262 pAfCb = &pCb->afCb[pCb->afWrtIdx];
264 // write audio frame information updated by decoder
265 pAfCb->sampleDecode = pAfWrt->sampleDecode;
266 PAF_PROCESS_COPY(pAfCb->sampleProcess, pAfWrt->sampleProcess);
267 pAfCb->sampleRate = pAfWrt->sampleRate;
268 pAfCb->sampleCount = pAfWrt->sampleCount;
269 pAfCb->channelConfigurationRequest = pAfWrt->channelConfigurationRequest;
270 pAfCb->channelConfigurationStream = pAfWrt->channelConfigurationStream;
272 // write PCM samples
273 streamMask = pAfWrt->fxns->channelMask(pAfWrt, pAfCb->channelConfigurationStream);
274 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
275 {
276 if ((streamMask >> i) & 0x1)
277 {
278 for (j = 0; j < pCb->decOpFrameLen; j++)
279 {
280 pAfCb->data.sample[i][j] = pAfWrt->data.sample[i][j];
281 }
283 pAfCb->data.samsiz[i] = pAfWrt->data.samsiz[i];
284 }
285 }
287 // update audio frame write index
288 pCb->afWrtIdx++;
289 if (pCb->afWrtIdx >= pCb->maxNumAfCb)
290 {
291 pCb->afWrtIdx = 0;
292 }
294 // update number of audio frames in circular buffer
295 pCb->numAfCb++;
297 // (***) FL: hackin'
298 // Write back circular buffer configuration
299 Cache_wb(pCb, sizeof(PAF_DecodeOpCircBuf), Cache_Type_ALLD, 0);
300 // write back audio frame
301 Cache_wb(pAfCb, sizeof(PAF_AudioFrame), Cache_Type_ALLD, 0);
302 Cache_wb(pAfCb->data.samsiz, PAF_DECOP_CB_MAX_NUM_PCM_CH*sizeof(PAF_AudioSize), Cache_Type_ALLD, 0);
303 // write back PCM data
304 for (i = 0; i < PAF_DECOP_CB_MAX_NUM_PCM_CH; i++)
305 {
306 if ((streamMask >> i) & 0x1)
307 {
308 Cache_wb(pAfCb->data.sample[i], pCb->decOpFrameLen*sizeof(PAF_AudioData), Cache_Type_ALLD, 0);
309 }
310 }
311 Cache_wait();
313 return PAF_DECOP_CB_SOK;
314 }
316 // Get next audio frame to write in circular buffer
317 Int cbGetNextWriteAf(
318 PAF_DecodeOpCircBuf *pCb, // decoder output circular buffer
319 PAF_AudioFrame **ppAfWrt // audio frame next to be written
320 )
321 {
322 // get pointer to current audio frame in circular buffer
323 *ppAfWrt = &pCb->afCb[pCb->afWrtIdx];
325 // update audio frame write index
326 pCb->afWrtIdx++;
327 if (pCb->afWrtIdx > pCb->maxNumAfCb)
328 {
329 pCb->afWrtIdx = 0;
330 }
332 return PAF_DECOP_CB_SOK;
333 }
335 Int cbLog(
336 PAF_DecodeOpCircBuf *pCb,
337 Int fullLog
338 )
339 {
340 Log_info4("afRdIdx=%d, pcmRdIdx=%d, afWrtIdx=%d, numAfCb=%d", pCb->afRdIdx, pCb->pcmRdIdx,
341 pCb->afWrtIdx,
342 pCb->numAfCb);
343 if (fullLog)
344 {
345 Log_info1("maxNumAfCb=%d", pCb->maxNumAfCb);
346 Log_info2("decOpFrameLen=%d, pafFrameLen=%d", pCb->decOpFrameLen, pCb->pafFrameLen);
347 Log_info1("cbWriteInit=%d", pCb->cbWriteInit);
348 }
350 return 0;
351 }