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;
76 // set output frame length
77 pCb->strFrameLen = strFrameLen;
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
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
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;
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;
148 pAfCb->data.samsiz[i] = 0;
149 }
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 }
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;
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;
196 }
198 // Start reads from circular buffer
199 Int cbReadStart(
200 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
201 )
202 {
203 // Invalidate circular buffer configuration
204 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
205 Cache_wait();
207 // update flags
208 pCb->readerActiveFlag = 1;
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;
216 }
218 // Stop reads from circular buffer
219 Int cbReadStop(
220 PAF_AST_DecOpCircBuf *pCb // decoder output circular buffer
221 )
222 {
223 // Invalidate circular buffer configuration
224 Cache_inv(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
225 Cache_wait();
227 // update flags
228 pCb->readerActiveFlag = 0;
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;
236 }
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
242 )
243 {
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);
271 return ASP_DECOP_CB_SOK;
272 }
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
287 // Write back circular buffer configuration.
288 Cache_wb(pCb, sizeof(PAF_AST_DecOpCircBuf), Cache_Type_ALLD, 0);
289 Cache_wait();
291 return ASP_DECOP_CB_READ_UNDERFLOW;
292 }
293 }
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 //
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();
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;
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 */
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();
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();
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 }
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 }
395 // update PCM read index
396 pCb->pcmRdIdx = 0;
398 // update number of audio frames in circular buffer
399 pCb->numAfCb--;
400 }
401 }
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 }
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();
421 return ASP_DECOP_CB_SOK;
422 }
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)
428 )
429 {
430 PAF_ChannelMask_HD streamMask;
431 Int8 i;
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;
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 }
455 }