2 /*
3 Copyright (c) 2017, 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 //
37 //
38 // Stacking Input Buffer Driver implementations
39 //
40 //
41 // Derived from /c/ti/c6000/src/drivers/dgs.c
43 #include <xdc/std.h>
44 #include <xdc/cfg/global.h>
45 #include <xdc/runtime/Memory.h>
46 #include <xdc/runtime/System.h>
47 #include <xdc/runtime/Error.h>
48 #include <xdc/runtime/IHeap.h>
49 #include <ti/sysbios/knl/Queue.h>
50 #include <ti/sysbios/knl/Semaphore.h>
51 #include <ti/sysbios/heaps/HeapMem.h>
53 #include <dev2.h>
54 #include "mib.h"
55 #include "miberr.h"
56 #include <inpbuf.h>
57 #include <pafdec.h>
58 #include <pafsio.h>
59 #include <pafsio_ialg.h>
61 #include <limits.h> //INT_MAX
62 #include <string.h>
64 typedef xdc_Short MdInt;
65 typedef xdc_UShort MdUns;
66 typedef xdc_Char SmInt;
67 typedef xdc_UChar SmUns;
70 extern const ti_sysbios_heaps_HeapMem_Handle heapMemDdr3;
71 #define HEAPMALLOC (IHeap_Handle)heapMemDdr3
72 extern HeapMem_Handle DEV2_memSpaceToHeap (IALG_MemSpace space);
74 #include "pafhjt.h"
76 #include <ti/sysbios/knl/Clock.h>
77 #include <xdc/runtime/Log.h>
79 //grab from samrat.c
80 #include <paftyp.h>
81 #include <stdasp.h>
83 #include <logp.h>
84 #include <stdio.h> // printf in case of programming error
86 // allows you to set a different trace module in pa.cfg
87 #define TR_MOD trace
89 //#define TRACE_ENABLE
90 #ifdef TRACE_ENABLE
91 #include "dp.h"
92 #define TRACE(a) dp a // LOG_printf a
93 #else
94 #define TRACE(a)
95 #endif
97 extern const PAF_SampleRateHz
98 PAF_ASP_sampleRateHzTable[PAF_SAMPLERATE_N][PAF_SAMPLERATEHZ_N];
100 #define SCANATSAMPLERATELIMIT ((float) 48000.)
102 // Likely needs to be 7 when/if AC3 handling is changed to
103 // throw away fill.
104 #define NUM_CHILD_BUFFERS 6
106 Int DIB_ctrl (DEV2_Handle device, Uns code, Arg Arg);
107 Int DIB_idle (DEV2_Handle device, Bool Flush);
108 Int DIB_issue (DEV2_Handle device);
109 Int DIB_open (DEV2_Handle device, String Name);
110 Int DIB_reclaim (DEV2_Handle device);
111 Int DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
112 Int DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
113 Int DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
114 Int DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, Int size, Int forTotal);
115 Int DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
116 Int DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
117 Int DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout);
118 Int DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count);
119 Int DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd);
121 // Driver function table.
122 DIB_Fxns DIB_FXNS = {
123 NULL, // close not used in PA/F systems
124 DIB_ctrl,
125 DIB_idle,
126 DIB_issue,
127 DIB_open,
128 NULL, // ready not used in PA/F systems
129 DIB_reclaim,
130 DIB_getSync,
131 DIB_initFrame,
132 DIB_requestFrame,
133 DIB_issueChild,
134 DIB_reclaimChild,
135 DIB_reset,
136 DIB_syncScan,
137 DIB_waitForData,
138 DIB_syncScanDTS
139 };
141 // macros assume pDevExt is available and pDevExt->pFxns is valid
142 #define DIB_FTABLE_getSync(_a,_b) (*pDevExt->pFxns->getSync)(_a,_b)
143 #define DIB_FTABLE_initFrame(_a,_b) (*pDevExt->pFxns->initFrame)(_a,_b)
144 #define DIB_FTABLE_requestFrame(_a,_b) (*pDevExt->pFxns->requestFrame)(_a,_b)
145 #define DIB_FTABLE_issueChild(_a,_b,_c,_d) (*pDevExt->pFxns->issueChild)(_a,_b,_c,_d)
146 #define DIB_FTABLE_reclaimChild(_a,_b) (*pDevExt->pFxns->reclaimChild)(_a,_b)
147 #define DIB_FTABLE_reset(_a,_b) (*pDevExt->pFxns->reset)(_a,_b)
148 #define DIB_FTABLE_syncScan(_a,_b,_c) (*pDevExt->pFxns->syncScan)(_a,_b,_c)
149 #define DIB_FTABLE_waitForData(_a,_b,_c) (*pDevExt->pFxns->waitForData)(_a,_b,_c)
150 #define DIB_FTABLE_syncScanDTS(_a,_b,_c,_d) (*pDevExt->pFxns->syncScanDTS)(_a,_b,_c,_d)
152 // .............................................................................
154 //IBMODE
155 enum
156 {
157 MODE_DEFAULT = 0,
158 MODE_NO_ZERORUNRESTART = 1,
159 MODE_NO_ZERORUN = 2
160 };
162 // syncState
163 enum
164 {
165 SYNC_NONE,
166 SYNC_ONE,
167 SYNC_ONGOING,
168 SYNC_PCM,
169 SYNC_PCM_FORCED,
170 SYNC_AUTO
171 };
173 // scanState
174 enum
175 {
176 SCANNED_NONE,
177 SCANNED_IEC_PA,
178 SCANNED_IEC_PB,
179 SCANNED_IEC_PC,
180 SCANNED_DTS14_SYNC_A,
181 SCANNED_DTS14_SYNC_B,
182 SCANNED_DTS14_SYNC_C,
183 SCANNED_DTS14_SYNC_D,
184 SCANNED_DTS16_SYNC_A,
185 SCANNED_DTS16_SYNC_B,
186 SCANNED_DTS16_SYNC_C
187 };
189 // all sizes in number of 16bit words words
190 #define IEC_HEADER_SIZE 4 //PA PB PC PD
191 #define DTS14_HEADER_SIZE 6
192 #define DTS16_HEADER_SIZE 4
194 //table needed until PAF_SOURCE is reordered to match IEC numbering
195 const SmUns iecPafSource[23] =
196 {
197 PAF_SOURCE_UNKNOWN, // 0: IEC NULL Type
198 PAF_SOURCE_AC3, // 1: Comments on 1-15 match IEC 61937 part 2.
199 PAF_SOURCE_UNKNOWN, // 2: IEC reserved
200 PAF_SOURCE_UNKNOWN, // 3: IEC pause
201 PAF_SOURCE_UNKNOWN, // 4: MPEG 1 layer 1
202 PAF_SOURCE_MP3, // 5: MPEG layer 2 or 3
203 PAF_SOURCE_UNKNOWN, // 6: MPEG 2 data with extension
204 PAF_SOURCE_AAC, // 7: MPEG-2 AAC ADTS
205 PAF_SOURCE_UNKNOWN, // 8: MPEG 2 layer 1 low sampling frequency
206 PAF_SOURCE_UNKNOWN, // 9: MPEG 2 layer 2 or 3 low sampling frequency
207 PAF_SOURCE_UNKNOWN, // 10: reserved
208 PAF_SOURCE_DTS, // 11: DTS type 1 (11 bit: 512 sample repeat period)
209 PAF_SOURCE_DTS12, // 12: DTS type 2 (12 bit: 1024 sample repeat period)
210 PAF_SOURCE_DTS13, // 13: DTS type 3 (13 bit: 2048 sample repeat period)
211 PAF_SOURCE_DTS14, // 14: ATRAC
212 PAF_SOURCE_UNKNOWN, // 15: ATRAC 2/3
213 PAF_SOURCE_THD, // 16
214 PAF_SOURCE_DTSHD, // 17
215 PAF_SOURCE_WMA9PRO, // 18
216 PAF_SOURCE_UNKNOWN, // 19
217 PAF_SOURCE_UNKNOWN, // 20
218 PAF_SOURCE_DDP, // 21
219 PAF_SOURCE_THD, // 22
220 };
222 // IEC framelengths (in 16bit words)
223 const MdUns iecFrameLength[23] =
224 {
225 0,
226 1536*2,
227 0, 0, 0,
228 1152*2,
229 0,
230 1024*2,
231 0, 0, 0,
232 512*2,
233 1024*2,
234 2048*2,
235 0, 0,
236 15*1024*2, //THD
237 1*1024, // DTSHD, actual framelength is adjusted by DTSsubType
238 4096*2,
239 0,0,
240 1536*2*4,
241 15*1024*2 //THD
242 };
244 #define IEC_PA ((short) 0xF872)
245 #define IEC_PB ((short) 0x4E1F)
246 #define DTS16_SYNC_A ((short) 0x7FFE)
247 #define DTS16_SYNC_B ((short) 0x8001)
248 #define DTS16_SYNC_C ((short) 0xFC00)
249 #define DTS14_SYNC_A ((short) 0x1FFF)
250 #define DTS14_SYNC_B ((short) 0xE800)
251 #define DTS14_SYNC_C ((short) 0x07F0)
253 #define DTS_BURST_TYPE_I 0x008B
254 #define DTS_BURST_TYPE_II 0x018C
255 #define DTS_BURST_TYPE_III 0x028D
256 #define DTS_BURST_TYPE_IV 0x0491
258 #define DTS_BURST_TYPE_IV_CBR 0x02
259 #define DTS_BURST_TYPE_IV_LBR 0x03
260 #define DTS_BURST_TYPE_IV_HBR 0x04
262 #define DEFAULT_AUTOREQUESTSIZE 128
263 //#define DEFAULT_AUTOREQUESTSIZE 256
265 // This is used at a couple of locations to ensure the transfer
266 // size is sufficiently long to be useful.
267 #define NOMINAL_XFERSIZE 128 //GJ Debug
269 #define min(a, b) (((a) < (b)) ? (a) : (b))
270 #define max(a, b) (((a) > (b)) ? (a) : (b))
272 // FL: (***) debug
273 #include "evmc66x_gpio_dbg.h"
275 // -----------------------------------------------------------------------------
277 inline void IncrementPtr (PAF_InpBufConfig *pBufConfig, Ptr *pPtr, int numWords)
278 {
279 int addr;
282 addr = (int) *pPtr + numWords*pBufConfig->sizeofElement;
283 if (addr > ((int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer - 1))
284 addr -= pBufConfig->sizeofBuffer;
286 *pPtr = (Ptr) addr;
287 return;
288 } // IncrementPtr
290 // -----------------------------------------------------------------------------
292 inline int GetNumAvail (PAF_InpBufConfig *pBufConfig)
293 {
294 int numBytes;
297 if ( (Uns) pBufConfig->head.pVoid >= (Uns) pBufConfig->pntr.pVoid)
298 numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid);
299 else
300 numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
302 // return in words
303 return (numBytes / pBufConfig->sizeofElement);
304 } // GetNumAvail
306 // -----------------------------------------------------------------------------
307 // compute how much data we have including outstanding requests
309 inline int GetFutureAvail (PAF_InpBufConfig *pBufConfig)
310 {
311 int numBytes;
314 if ( (Uns) pBufConfig->futureHead.pVoid >= (Uns) pBufConfig->pntr.pVoid)
315 numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid);
316 else
317 numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
319 // return in words
320 return (numBytes / pBufConfig->sizeofElement);
321 } // GetFutureAvail
323 // -----------------------------------------------------------------------------
325 Int DIB_issue (DEV2_Handle device)
326 {
327 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
328 DEV2_Frame *srcFrame;
329 Int status;
330 PAF_InpBufConfig *pBufConfig;
333 srcFrame = Queue_get (device->todevice);
334 pBufConfig = (PAF_InpBufConfig *) srcFrame->addr;
335 if (!pBufConfig || !pBufConfig->pBufStatus)
336 return SIO2_EINVAL;
338 Queue_put (device->fromdevice, (Queue_Elem *)srcFrame);
340 if (srcFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
342 // do nothing if not synced since syncing done in reclaim
343 // This is executed in force modes from the first call to PAF_AST_decodeInit
344 // which calls SIO2_issue for NEWFRAME before all other calls.
345 if (pDevExt->syncState == SYNC_NONE)
346 return 0;
348 status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
349 if (status)
350 return status;
351 }
353 return 0;
354 } // DIB_issue
356 // -----------------------------------------------------------------------------
357 // Although interface allows for arbitrary BufConfigs we only support 1 -- so
358 // we can assume the one on the fromdevice is the one we want
360 extern int gIsrInputCnt;
361 extern int gIsrOutputCnt;
363 Int DIB_reclaim (DEV2_Handle device)
364 {
365 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
366 DEV2_Frame *dstFrame;
367 Int status = 0;
368 PAF_InpBufConfig *pBufConfig;
370 dstFrame = (DEV2_Frame *) Queue_head (device->fromdevice);
372 if (dstFrame == (DEV2_Frame *) device->fromdevice)
373 return DIBERR_UNSPECIFIED;
374 if (!dstFrame->addr)
375 return DIBERR_UNSPECIFIED;
377 // if deferred error from last request frame then return now
378 status = pDevExt->deferredError;
379 if (status) {
380 pDevExt->deferredError = 0;
381 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
382 return status;
383 }
385 pBufConfig = (Ptr) dstFrame->addr;
386 dstFrame->size = sizeof (PAF_InpBufConfig);
388 // .........................................................................
390 if ((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC)) {
392 Log_info0("DIB: At case: syncState == SYNC_NONE (or PAF_SIO_REQUEST_SYNC)");
394 // pass in external buffer config which used to initialize the internal view
395 status = DIB_FTABLE_reset (device, pBufConfig);
396 if (status)
397 return status;
399 status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
400 if (status)
401 return status;
403 // since getSync resets sourceProgram to unknown at entry
404 // sourceProgram will remain unknown if no sync is returned
405 // (i.e. no need to reset it here)
406 if (pDevExt->syncState == SYNC_NONE)
407 {
408 Log_info0("Returning DIBERR_SYNC after DIB_FTABLE_getSync");
409 return DIBERR_SYNC;
410 }
412 // get input info (frameLength/etc)
413 status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
415 if (status)
416 {
417 Log_info1("Returning %d after DIB_FTABLE_initFrame", status);
418 return status;
419 }
421 // request timing frame
422 status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
423 if (status)
424 {
425 Log_info1("Returning %d after DIB_FTABLE_requestFrame", status);
426 return status;
427 }
428 // update external view of bufConfig. In particular for slave force PCM
429 // this insures that the first decode will be processed with deliverZeros = 1
430 // which is necessary since the first decode of slave input occurs before the
431 // first slave input frame is actually captured.
432 *pBufConfig = pDevExt->bufConfig;
434 } //((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC))
436 // .........................................................................
438 if (dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
440 Log_info0("DIB: At case = PAF_SIO_REQUEST_NEWFRAME");
442 // wait for enough data to check for sync at expected location
443 status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->bufConfig.frameLength);
444 if (status)
445 {
446 Log_info2("DIB_reclaim.%d DIB_FTABLE_waitForData returned %d", __LINE__, status);
447 //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_waitForData returned %d\n", __LINE__, status));
448 return status;
449 }
451 // if PCM, but not forced PCM, then scan for bitstream sync
452 // note that we we using the local view of bufConfig here and we update the
453 // public view afterwards.
454 if (pDevExt->syncState == SYNC_PCM) {
455 float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
456 PAF_InpBufConfig *pBufConfig = &pDevExt->bufConfig;
457 Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
459 // normally no scanning done if sampleRate > 48kHz since bitstream input is highly unlikley.
460 if ((sampleRate <= SCANATSAMPLERATELIMIT) || pBufConfig->pBufStatus->scanAtHighSampleRateMode) {
461 if (!pBufConfig->deliverZeros) {
462 pDevExt->pcmTimeout = pBufConfig->lengthofData;
464 // check zeroRunTrigger if needed
465 if (ibMode != MODE_NO_ZERORUN) {
466 if(pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) {
467 // set this flag one block late to allow for
468 // transmission of all data in frame which contained zeroRunTrigger
469 pBufConfig->deliverZeros = 1;
470 pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
471 } // > zeroRunTrigger
472 } // !MODE_NO_ZERORUN
473 } // !pBufConfig->deliverZeros
475 // scan PCM data
476 status = DIB_FTABLE_syncScan (device, pBufConfig, &pDevExt->pcmTimeout);
477 if (status) {
478 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
479 Log_info2("DIB_reclaim.%d DIB_FTABLE_syncScan returned %d", __LINE__, status);
480 //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_syncScan returned %d\n", __LINE__, status));
481 return status;
482 }
484 // if scan found something other than PCM, then exit with error
485 if (pDevExt->syncState != SYNC_PCM)
486 {
487 Log_info1("DIB_reclaim.%d error: syncState != SYNC_PCM", __LINE__);
488 //TRACE((&TR_MOD, "DIB_reclaim.%d error: syncState != SYNC_PCM\n", __LINE__));
489 return DIBERR_SYNC;
490 }
492 // if heeding zeroRunRestart control then return to unknown if necessary
493 if ((ibMode == MODE_DEFAULT) &&
494 (pDevExt->zeroCount >= 2*pBufConfig->pBufStatus->zeroRunRestart)) {
495 // if zeroRunRestart me then reset input to unknown
496 Log_info1("DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN", __LINE__);
497 //TRACE((&TR_MOD, "DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN\n", __LINE__));
498 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
499 return DIBERR_SYNC;
500 }
502 // since in skeptical state we disallow returning to PCM when end of timeout contains zeros
503 // note that we need not check the mode here since above logic prevents deliverZeros state.
504 if (pBufConfig->deliverZeros && (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger))
505 {
506 //TRACE((&TR_MOD, "DIB_reclaim.%d set pcmTimeout = unknown timeout\n", __LINE__));
507 pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
508 }
509 } //scanAtHighSampleRate
510 } //SYNC_PCM
512 // clear this flag immediately to play new audio ASAP
513 // this check is OK for forced PCM since pcmTimeout and zeroCount are not
514 // updated
515 if (pDevExt->bufConfig.deliverZeros && !pDevExt->pcmTimeout &&
516 (pDevExt->zeroCount < 2 * pDevExt->bufConfig.pBufStatus->zeroRunTrigger))
517 {
518 pDevExt->bufConfig.deliverZeros = 0;
519 }
521 // update external view of buffer with local view we do this with current
522 // frame info before the following update to the local view for the next
523 // frame to be captured. Need to subtract headerSize from lengthofData
524 // since, at least for THD, it is needed by decoders.
525 *pBufConfig = pDevExt->bufConfig;
526 pBufConfig->lengthofData -= pDevExt->headerSize;
527 Log_info4("DIB_reclaim.%d lengthofData = %d; InISRCNT=%d; OutISRCNT=%d", __LINE__, pBufConfig->lengthofData, gIsrInputCnt, gIsrInputCnt);
528 //TRACE((&TR_MOD, "DIB_reclaim.%d lengthofData = %d\n", __LINE__, pBufConfig->lengthofData));
530 // HACK: for DSD the frameLength needs to be the number of samples to generate.
531 if ((pDevExt->sourceSelect >= PAF_SOURCE_DSD1) &&
532 (pDevExt->sourceSelect <= PAF_SOURCE_DSD3))
533 pBufConfig->frameLength /= pBufConfig->stride;
534 Log_info2("DIB_reclaim.%d frameLength = %d", __LINE__, pBufConfig->frameLength);
535 //TRACE((&TR_MOD, "DIB_reclaim.%d frameLength = %d\n", __LINE__, pBufConfig->frameLength));
537 // set external view to point at synch position of the frame guaranteed
538 // to be captured by above waitForData. Need to condition this against PCM since
539 // in that case pSync could point anywhere in the buffer to to syncScan. E.g.
540 // if there was a partial sync then pSync would point at that rather than
541 // at the beginning of the buffer.
542 // TODO: change syncScan to only update pDevExt->pSync when there is an actual sync
543 // so that we can use this for both PCM and bitstream
544 if (pDevExt->syncState == SYNC_ONGOING) {
545 pBufConfig->pntr = pDevExt->pSync;
546 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
547 } //SYNC_ONGOING
549 // if a bitstream then need to update tail to bitstream sync location
550 // and check for next sync at expected location
551 // quick scan for sync. if decoding IEC but sync is missing then
552 // defer error until the next frame so that we decode all frames
553 // TODO: does this assume decoders have copied the entire input frame
554 // i.e. it is ok to adjust the input buffer pointers.
555 // if successful then this sets
556 // pSync = address of PA (for IEC)
557 status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
558 if (status) {
559 if (pBufConfig->pBufStatus->lastFrameMask & (1 << pDevExt->sourceProgram)) {
560 pDevExt->deferredError = status;
561 Log_info1("DIB_reclaim.%d last frame\n", __LINE__);
562 //TRACE((&TR_MOD, "DIB_reclaim.%d last frame\n", __LINE__));
563 pBufConfig->pBufStatus->lastFrameFlag = 1;
564 return 0;
565 }
566 else {
567 Log_info1("DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN", __LINE__);
568 //TRACE((&TR_MOD, "DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN\n", __LINE__));
569 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
570 return status;
571 }
572 }
574 } //(dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME)
576 // .........................................................................
578 Log_info4("DIB_reclaim.%d exit status = %d, InISRCNT = %d OutISRCNT = %d", __LINE__, status, gIsrInputCnt, gIsrOutputCnt);
579 //TRACE((&TR_MOD, "DIB_reclaim.%d exit status = %d\n", __LINE__, status));
581 return status;
582 } // DIB_reclaim
584 // -----------------------------------------------------------------------------
586 Int DIB_ctrl (DEV2_Handle device, Uns code, Arg arg)
587 {
588 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
589 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
590 Int status = 0;
593 switch (code) {
595 case PAF_SIO_CONTROL_GET_CHILD_DEVICE:
596 *((Arg *)arg) = (Arg) pChild;
597 break;
599 //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
601 case PAF_SIO_CONTROL_SET_DECSTATUSADDR:
602 pDevExt->pDecodeStatus = (PAF_DecodeStatus *) arg;
603 break;
605 case PAF_SIO_CONTROL_SET_PCMFRAMELENGTH:
606 pDevExt->pcmFrameLength = (XDAS_Int32) arg;
607 break;
609 case PAF_SIO_CONTROL_SET_SOURCESELECT:
610 pDevExt->sourceSelect = (XDAS_Int8) arg;
611 break;
613 case PAF_SIO_CONTROL_SET_AUTOREQUESTSIZE:
614 pDevExt->autoRequestSize = (XDAS_Int16) arg;
615 break;
617 case PAF_SIO_CONTROL_GET_SOURCEPROGRAM:
618 if (!arg)
619 return DIBERR_UNSPECIFIED;
620 *((XDAS_Int8 *) arg) = pDevExt->sourceProgram;
621 break;
623 case PAF_SIO_CONTROL_SET_IALGADDR:
624 pDevExt->pSioIalg = (PAF_SIO_IALG_Obj *) arg;
625 break;
627 //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
629 case PAF_SIO_CONTROL_OPEN:
630 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
631 pDevExt->zeroCount = 0;
632 if (pDevExt->pInpBufStatus)
633 pDevExt->pInpBufStatus->zeroRun = 0;
634 status = DEV2_ctrl (pChild, code, arg);
635 break;
637 case PAF_SIO_CONTROL_CLOSE:
638 if (pDevExt->pInpBufStatus)
639 pDevExt->pInpBufStatus->zeroRun = 0;
640 status = DEV2_ctrl (pChild, code, arg);
641 break;
643 // return number of DMA events vs. request size
644 // only update if not in error state (i.e. status = 0)
645 case PAF_SIO_CONTROL_GET_NUM_EVENTS:
646 if (!arg)
647 return DIBERR_UNSPECIFIED;
648 status = DEV2_ctrl (pChild, code, arg);
649 if (!status)
650 *((Int *)arg) -= pDevExt->pcmFrameLength;
651 break;
653 // return net samples until next DIB_waitForData() should succeed w/o blocking
654 case PAF_SIO_CONTROL_GET_NUM_REMAINING:
655 if (!arg)
656 return DIBERR_UNSPECIFIED;
657 status = DEV2_ctrl (pChild, code, arg);
658 *((Int *)arg) -= pDevExt->numSamplesExtra;
659 break;
661 default:
662 status = DEV2_ctrl (pChild, code, arg);
663 break;
664 }
666 return status;
667 } // DIB_ctrl
669 // -----------------------------------------------------------------------------
671 Int DIB_idle (DEV2_Handle device, Bool flush)
672 {
673 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
674 Int status;
677 while (!Queue_empty (device->todevice))
678 Queue_enqueue (device->fromdevice, Queue_dequeue (device->todevice));
680 while (!Queue_empty (device->fromdevice))
681 Queue_enqueue (Queue_handle(&((SIO2_Handle) device)->framelist), Queue_dequeue (device->fromdevice));
683 status = DIB_FTABLE_reset (device, NULL);
684 if (status)
685 return status;
687 return 0;
688 } // DIB_idle
690 // -----------------------------------------------------------------------------
692 Int DIB_open (DEV2_Handle device, String name)
693 {
694 DIB_DeviceExtension *pDevExt;
695 DEV2_Handle pChild;
696 DEV2_Device *entry;
697 DEV2_Frame *frame;
698 Int status, i;
699 Error_Block eb;
701 Error_init(&eb);
703 name = DEV2_match (name, &entry);
704 if (entry == NULL) {
705 Log_info1("DEV2_match failed in DIB_open:", SIO2_ENODEV);
706 return SIO2_ENODEV;
707 }
709 // only one frame interface supported
710 if (device->nbufs != 1)
711 return SYS_EALLOC;
713 if (!(pDevExt = Memory_alloc (device->bufSeg, sizeof(DIB_DeviceExtension), 0, &eb)))
714 {
715 Log_info1("DIB Memory alloc failed in DIB_open:", SYS_EALLOC);
716 return SYS_EALLOC;
717 }
718 pDevExt->pcmFrameLength = 0;
719 pDevExt->sourceSelect = PAF_SOURCE_NONE;
720 pDevExt->autoRequestSize = DEFAULT_AUTOREQUESTSIZE;
721 pDevExt->pInpBufStatus = NULL;
722 pDevExt->pDecodeStatus = NULL;
723 device->object = (Ptr)pDevExt;
725 pChild = (DEV2_Handle)&pDevExt->child;
726 pChild->fromdevice = Queue_create (NULL, &eb);
727 pChild->todevice = Queue_create (NULL, &eb);
728 if (pChild->fromdevice == NULL || pChild->todevice == NULL) {
729 Log_info1 ("DIB Queue_create failed in DIB_open:", SYS_EALLOC);
730 return SYS_EALLOC;
731 }
733 pChild->bufsize = 0;
734 pChild->nbufs = NUM_CHILD_BUFFERS;
735 pChild->bufSeg = device->bufSeg;
736 pChild->mode = device->mode;
737 pChild->timeout = device->timeout;
738 pChild->align = device->align;
739 pChild->devid = entry->devid;
740 pChild->params = entry->params;
741 pChild->fxns = *(DEV2_Fxns *)(entry->fxns);
742 ((SIO2_Handle)pChild)->model = ((SIO2_Handle)device)->model;
744 //Create frames and put them on the correct device queue.
745 // We only support ISSUERECLAIM mode so size = 0
746 Queue_construct(&((SIO2_Handle)pChild)->framelist, NULL); //Queue_new (&((SIO2_Handle)pChild)->framelist);
747 for (i=0; i < pChild->nbufs; i++) {
748 frame = DEV2_mkframe (0, 0, 0);
749 if (!frame)
750 return SYS_EALLOC;
751 Queue_put (Queue_handle(&((SIO2_Handle)pChild)->framelist), (Queue_Elem *) frame);
752 }
754 // open underlying device
755 status = DEV2_open (pChild, name);
756 if (status)
757 return status;
759 // use dev match to fetch function table pointer for DIB
760 name = DEV2_match ("/DIB", &entry);
761 if (entry == NULL) {
762 Log_info1 ("DEV2_match for DIB in DIB_open:", SIO2_ENODEV);
763 return SIO2_ENODEV;
764 }
765 pDevExt->pFxns = (DIB_Fxns *) entry->fxns;
767 // set IEC frame length table pointer -- change in
768 // subsequent control call (not defined) to add new IEC type
769 pDevExt->pIECFrameLength = (XDAS_UInt16 *) iecFrameLength;
771 status = DIB_FTABLE_reset (device,NULL);
772 if (status)
773 return status;
775 return status;
776 } // DIB_open
778 // -----------------------------------------------------------------------------
779 // Although this is void it is still needed since BIOS calls all DEV inits on
780 // startup.
782 Void DIB_init (Void)
783 {
784 } // DIB_init
786 // -----------------------------------------------------------------------------
787 // Notes:
788 // 1. DIB_reset is called prior to this function being called.(see DIB_reclaim)
789 // 2. (1) ==> sizeofBuffer is an integral # of 2byte samples.
790 // 3. (2) ==> if we use a request size which is divisor of sizeofBuffer there
791 // will be no wrap-around when requesting data for scanning.
792 // 4. (3) ==> we meet the interface requirement for syncScan which has no
793 // circular arithmetic.
795 Int DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
796 {
797 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
798 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
799 int status;
800 Uns timeout, syncBufSize, syncRequestSize;
801 Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
802 Int deliverZeros;
804 //..........................................................................
806 // implement local timeout so that we don't get 'stuck' here when input
807 // is all zeros + lock
808 if (pDevExt->syncState == SYNC_NONE) {
809 Uns localTimeout;
810 // latch value before resetting to PAF_SOURCE_UNKNOWN
811 Int sourceProgram = pDevExt->sourceProgram;
813 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
815 // if here then guaranteed to have fresh reset
817 if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
818 pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
819 timeout = 0;
821 // no zero run counting in force modes since no scanning
822 pBufConfig->pBufStatus->zeroRun = 0;
823 pDevExt->zeroCount = 0;
824 }
825 else if ((pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO) &&
826 ((sourceProgram == PAF_SOURCE_UNKNOWN) || (sourceProgram == PAF_SOURCE_PCM))) {
827 // if sourceselect is PCMAUTO then
828 // if current input is a bistream then scan for normal timeout period
829 // if current input is unknown or PCM then transition immediately to PCM
830 // this provides for *no* lossed PCM, detection of bitstreams, but some noise
831 // is possible.
832 timeout = 0;
833 pDevExt->zeroCount = 0;
834 }
835 else
836 timeout = 2*pBufConfig->pBufStatus->unknownTimeout;
838 // force request size to be a divisor of sizeofBuffer
839 syncRequestSize = NOMINAL_XFERSIZE;
840 if (pBufConfig->stride > 2)
841 syncRequestSize *= pBufConfig->stride;
842 syncBufSize = pBufConfig->sizeofBuffer / ((int) (pBufConfig->sizeofBuffer/syncRequestSize));
844 if (timeout) {
845 status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
846 if (status)
847 return status;
848 }
850 localTimeout = timeout;
851 while ((timeout) && (pDevExt->syncState != SYNC_ONE)) {
853 status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
854 if (status)
855 return status;
857 #if 0 // (***) FL: shows timing of Input Rx SIO reclaim during autodet
858 // (***) debug // B5
859 {
860 static Uint8 toggleState = 0;
861 if (toggleState == 0)
862 GPIOSetOutput(GPIO_PORT_0, GPIO_PIN_99);
863 else
864 GPIOClearOutput(GPIO_PORT_0, GPIO_PIN_99);
865 toggleState = ~(toggleState);
866 }
867 #endif
869 // get next block of data to scan
870 status = DIB_FTABLE_waitForData (device, pBufConfig, syncBufSize);
871 if (status)
872 return status;
874 // this function updates the tail pointer
875 status = DIB_FTABLE_syncScan (device, pBufConfig, &timeout);
876 if (status)
877 return status;
879 // if input is zero, i.e. haven't decremented at all,
880 // then break out and use more logic and
881 if (localTimeout < syncBufSize) {
882 // Should this be 2 *? MAW
883 if (timeout == 2*pBufConfig->pBufStatus->unknownTimeout)
884 break;
885 }
886 else
887 {
888 Log_info3("DIB: Inside DIB_getSync with syncState != SYNC_ONE. localTimeout = %d, syncBufSize = %d, timeout = %d", localTimeout,syncBufSize, timeout);
889 localTimeout -= syncBufSize;
890 }
891 }
893 // if found sync then return to caller who will call
894 // initFrame to get bitstream info and requestFrame for data
895 if (pDevExt->syncState != SYNC_NONE)
896 return 0;
898 } //pDevExt->syncState == SYNC_NONE
900 //..........................................................................
902 // set default to zero -- we assume decode calls will not be made
903 // before data is available since this must be master input. Will be changed below
904 // as needed
905 deliverZeros = 0;
907 if (pDevExt->syncState == SYNC_AUTO) {
908 timeout = pDevExt->pcmTimeout;
909 deliverZeros = 1;
910 }
912 // if in zero run, and heeding full zeroRun control, then return to unknown if # zeros > trigger/Restart
913 if (ibMode == MODE_DEFAULT) {
914 if ((pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) ||
915 (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunRestart))
916 return DIBERR_SYNC;
917 // since we may have exited prematurely above we check timeout
918 if (timeout)
919 return DIBERR_SYNC;
920 }
921 // if heeding trigger but not restart then enter deliverZeros state of PCM
922 else if (ibMode == MODE_NO_ZERORUNRESTART) {
923 if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
924 deliverZeros = 1;
925 }
927 // here if timeout to PCM (includes force PCM)
928 status = DIB_FTABLE_reset (device, pBufConfig);
929 if (status)
930 return status;
932 // hack -- try 32bit then 16bit if necessary
933 pBufConfig->sizeofElement = 4;
934 status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
935 if(status) {
936 pBufConfig->sizeofElement = 2;
937 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
938 if(status)
939 return status;
940 }
942 // Force sizeofBuffer to be integral number of frame sizes. This ensures that the
943 // pcm buffers will not need a circular wrap-around. We prevent this because
944 // syncScan makes this assumption in order to perform an efficient scan.
945 {
946 int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride*pDevExt->pcmFrameLength;
947 pBufConfig->sizeofBuffer = (pBufConfig->allocation)/sizeofStride*sizeofStride;
948 }
950 if (pDevExt->sourceSelect == PAF_SOURCE_DSD1 || pDevExt->sourceSelect == PAF_SOURCE_DSD2 ||
951 pDevExt->sourceSelect == PAF_SOURCE_DSD3)
952 pDevExt->sourceProgram = pDevExt->sourceSelect;
953 else
954 pDevExt->sourceProgram = PAF_SOURCE_PCM;
956 if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
957 pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
958 pDevExt->syncState = SYNC_PCM_FORCED;
959 // set to one -- ensures that PCM decode calls made before data is
960 // available will result in zero output.
961 // (mostly needed for PA15 since, currently, all other frameworks
962 // require a frame of data before the first decode call.
963 deliverZeros = 1;
964 }
965 else
966 pDevExt->syncState = SYNC_PCM;
968 // update config struct
969 pBufConfig->deliverZeros = deliverZeros;
971 //..........................................................................
973 return 0;
974 } // DIB_getSync
976 // -----------------------------------------------------------------------------
978 int gWrapCtr=0;
979 Int DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, int size, int forTotal)
980 {
981 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
982 DEV2_Handle pChild = (DEV2_Handle) &pDevExt->child;
983 int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
984 DEV2_Frame *dstFrame;
985 int futureHead, status;
986 int i, sizes[2];
987 Ptr endAddr[2];
991 // if seeking for total amount then adjust for difference
992 if (forTotal)
993 size -= GetFutureAvail (pBufConfig);
995 // return success if we needn't make any requests
996 if (size <= 0)
997 return 0;
999 // assume if eight channel then using optimized dMAX routine which requires
1000 // requests which are a mulitple of 8 to operate correctly. If not a proper
1001 // multiple then we increase the requested size as needed. This information
1002 // is communicated to other portions of DIB indirectly through the update
1003 // of the futureHead pointer (here) and head pointer (in reclaim). To these
1004 // other portions it is a don't care as we ensure enough data requested will
1005 // be available at, the now slightly deferred, reclaim point. We assume that
1006 // the buffer is a multiple of 8 and so, by using this single statement, we
1007 // ensure all requests are a mulitple 8 even if they need to be split across
1008 // the buffer wrap point.
1009 if (pBufConfig->stride == 8)
1010 size = (size + 7) & ~0x7;
1012 // convert to bytes
1013 size *= pBufConfig->sizeofElement;
1014 //size *= 4;
1016 // if request crosses circular buffer boundary then split into two requests
1017 futureHead = (int) pBufConfig->futureHead.pVoid + size;
1018 if (futureHead <= bufEnd) {
1019 sizes[0] = size;
1020 sizes[1] = 0;
1022 // If this request happens to be the rest of the buffer, then
1023 // futureHead must be set to the beginning of the buffer.
1024 if (futureHead != bufEnd)
1025 endAddr[0] = (Ptr) futureHead;
1026 else
1027 endAddr[0] = pBufConfig->base.pVoid;
1028 }
1029 else {
1030 sizes[0] = bufEnd - (int) pBufConfig->futureHead.pVoid;
1031 sizes[1] = futureHead - bufEnd;
1032 endAddr[0] = pBufConfig->base.pVoid;
1033 endAddr[1] = (Ptr) ((int)pBufConfig->base.pVoid + sizes[1]);
1034 }
1036 for (i=0; i < 2; i++) {
1037 if (sizes[i]) {
1038 dstFrame = Queue_get (Queue_handle(&((SIO2_Handle) pChild)->framelist));
1039 if (dstFrame == (DEV2_Frame *)&((SIO2_Handle) pChild)->framelist)
1040 return DIBERR_UNSPECIFIED;
1041 dstFrame->arg = (Arg) pBufConfig;
1043 dstFrame->addr = pBufConfig->futureHead.pVoid;
1044 dstFrame->size = sizes[i];
1045 Queue_put (pChild->todevice, (Queue_Elem *)dstFrame);
1046 status = DEV2_issue (pChild);
1047 if (status)
1048 return DIBERR_UNSPECIFIED;
1050 pBufConfig->futureHead.pVoid = endAddr[i];
1052 if (i==1)
1053 {
1054 gWrapCtr++;
1055 Log_info4("DIB: Inside DIB_issueChild Wrap Around Point #%d, with Future Head: 0x%x, current addr: 0x%x, current size: %d", gWrapCtr, (xdc_IArg)pBufConfig->futureHead.pVoid, (xdc_IArg)dstFrame->addr, dstFrame->size );
1057 }
1058 }
1059 }
1061 return 0;
1062 } // DIB_issueChild
1064 // -----------------------------------------------------------------------------
1066 Int DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1067 {
1068 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1069 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
1070 DEV2_Frame *srcFrame;
1071 int status, bufEnd;
1073 //Log_info3("DIB_reclaimChild.%d: Inside DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim);
1074 //TRACE((&TR_MOD, "DIB_reclaimChild.%d: calling DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim));
1075 status = DEV2_reclaim (pChild);
1076 if (status)
1077 {
1078 Log_info2("DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED", __LINE__, status);
1079 //TRACE((&TR_MOD, "DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED \n", __LINE__, status));
1080 return DIBERR_UNSPECIFIED;
1081 }
1083 //Log_info1("DIB_reclaimChild.%d calling Queue_get()", __LINE__);
1084 //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_get()\n", __LINE__));
1085 srcFrame = Queue_get (pChild->fromdevice);
1086 //Log_info2("DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x", __LINE__, srcFrame);
1087 //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x\n", __LINE__, srcFrame));
1088 Queue_put (Queue_handle(&((SIO2_Handle) pChild)->framelist), (Queue_Elem *)srcFrame);
1090 // Only for non-fill requests do we update ptrs
1091 if (srcFrame->addr != NULL) {
1092 //Log_info2("DIB_reclaimChild.%d update pointers with srcFrame->size = %d", __LINE__, srcFrame->size);
1093 //TRACE((&TR_MOD, "DIB_reclaimChild.%d update pointers\n", __LINE__));
1094 pBufConfig->head.pVoid = (Ptr) ((int)srcFrame->addr + srcFrame->size);
1096 // wrap, if necessary
1097 bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1098 if( (int) pBufConfig->head.pVoid >= bufEnd )
1099 {
1100 Log_info1("DIB_reclaimChild.%d wrap pointer", __LINE__);
1101 //TRACE((&TR_MOD, "DIB_reclaimChild.%d wrap pointer\n", __LINE__));
1102 pBufConfig->head.pVoid = (Ptr) ((int) pBufConfig->base.pVoid + (int) pBufConfig->head.pVoid - bufEnd);
1103 }
1104 }
1106 Log_info2("DIB_reclaimChild.%d exit with status = %d", __LINE__, status);
1107 //TRACE((&TR_MOD, "DIB_reclaimChild.%d exit with status = %d\n", __LINE__, status));
1109 return status;
1110 } // DIB_reclaimChild
1112 // -----------------------------------------------------------------------------
1113 // This function uses the local definition of frameLength and lengthofData in
1114 // pDevExt to request the next frame of data.
1116 Int DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1117 {
1118 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1119 int status = 0;
1122 // if in steady state then update tail pointer to indicate we are done, i.e. no
1123 // longer own, the last frame of data.
1124 if (pDevExt->running > 1)
1125 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
1127 switch (pDevExt->syncState) {
1128 case SYNC_PCM:
1129 case SYNC_PCM_FORCED:
1131 if (pDevExt->sourceSelect == PAF_SOURCE_DSD1)
1132 pDevExt->frameLength = 256;
1133 else if (pDevExt->sourceSelect == PAF_SOURCE_DSD2)
1134 pDevExt->frameLength = 128;
1135 else if (pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1136 pDevExt->frameLength = 64;
1137 else
1138 pDevExt->frameLength = pDevExt->pcmFrameLength;
1140 pDevExt->lengthofData = pBufConfig->stride*pDevExt->frameLength;
1141 pDevExt->frameLength = pDevExt->lengthofData;
1143 // note that the following issueChild
1144 // doesn't *fetch* the data which will next be consumed,
1145 // but rather *replenishes* what's about to be consumed
1146 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1147 break;
1149 case SYNC_ONE:
1150 // for the first issue we need to set the tail pointer to the bitstream sync
1151 pBufConfig->pntr = pDevExt->pSync;
1152 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
1153 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->frameLength, 1);
1155 // HD codecs need extra time due to several factors
1156 // time between first info call and starting output is non-negligible
1157 // peak decoder MIPs
1158 // reset time for decoders/ASPs
1159 if ((pDevExt->sourceProgram == PAF_SOURCE_DDP) ||
1160 (pDevExt->sourceProgram == PAF_SOURCE_DTSHD) ||
1161 (pDevExt->sourceProgram == PAF_SOURCE_THD) ||
1162 (pDevExt->sourceProgram == PAF_SOURCE_DXP))
1163 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1165 pDevExt->syncState = SYNC_ONGOING;
1166 break;
1168 case SYNC_ONGOING:
1169 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1170 break;
1172 } //switch
1174 // update bufConfig with info for use in next reclaim call
1175 // the interface to DIB is based on a single frame. So the amount
1176 // of data requested in this issue is assumed to be what is wanted in the next
1177 // reclaim.
1178 pBufConfig->frameLength = pDevExt->frameLength;
1179 pBufConfig->lengthofData = pDevExt->lengthofData;
1180 // enable to inspect input buffer.
1181 // if (pDevExt->lengthofData > 512)
1182 // asm( " SWBP 0" ); // breakpoint
1185 if (pDevExt->running < 3)
1186 pDevExt->running++;
1188 // Goal is to align timing so synchronized with forthcoming
1189 // "DIB_waitForData (... pDevExt->lengthofData);"
1190 // in DIB_reclaim(), servicing PAF_SIO_REQUEST_NEWFRAME, for PAF_SOURCE_PCM/DSD?.
1191 // ** need to revise above DSD handling so it works w/ this calc. **
1192 {
1193 int futureAvail = GetFutureAvail (pBufConfig);
1194 // GetFutureAvail() returns 0 if full buffer requested or if no requests outstanding
1195 // -- 0 (empty) can't be right interpretation here, on account of foregoing issueChild()
1196 if( ! futureAvail)
1197 futureAvail = pBufConfig->sizeofBuffer / pBufConfig->sizeofElement; // total words in buffer
1198 pDevExt->numSamplesExtra = (XDAS_Int16) (futureAvail - pDevExt->frameLength);
1199 }
1201 return status;
1202 } // DIB_requestFrame
1204 // -----------------------------------------------------------------------------
1206 Int DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1207 {
1208 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1209 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
1210 int status, numChan;
1213 //?? Do we need a shutdown to handle queue problems?
1214 // or are there no problems since we use one frame
1215 status = DEV2_idle (pChild, 1);
1216 if(status)
1217 return status;
1219 if (pBufConfig) {
1220 int sizeofStride;
1221 pBufConfig->pntr = pBufConfig->base;
1222 pBufConfig->head = pBufConfig->base;
1223 pBufConfig->futureHead = pBufConfig->base;
1225 pBufConfig->lengthofData = 0;
1227 //devices must? support 2byte words
1228 pBufConfig->sizeofElement = 2;
1229 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1230 if(status)
1231 return status;
1233 status = DEV2_ctrl (pChild, PAF_SIO_CONTROL_GET_NUMCHANNELS, (Arg) &numChan);
1234 if(status)
1235 return status;
1236 pBufConfig->stride = numChan;
1238 // compute and use *effective buffer size*
1239 sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
1240 pBufConfig->sizeofBuffer = (pBufConfig->allocation)/sizeofStride*sizeofStride; //GJ: Debug - Account for EDMA padding
1242 //hack -- save status context for use in close
1243 pDevExt->pInpBufStatus = pBufConfig->pBufStatus;
1244 pBufConfig->pBufStatus->lastFrameFlag = 0;
1246 pDevExt->bufConfig = *pBufConfig;
1247 pDevExt->pSync = pBufConfig->base;
1248 }
1250 pDevExt->syncState = SYNC_NONE;
1251 pDevExt->scanState = SCANNED_NONE;
1252 pDevExt->pcmTimeout = 0;
1253 pDevExt->deferredError = 0;
1255 pDevExt->numSamplesSinceDTS = 0;
1256 pDevExt->numSamplesExtra = 0;
1258 pDevExt->headerSize = 0;
1259 pDevExt->running = 0;
1261 return 0;
1262 } // DIB_reset
1264 // -----------------------------------------------------------------------------
1265 // Notes:
1266 // 1. The amount of data to be scanned will not result in a buffer wrap-around
1267 // 2. (1) is currently met from the two locations that call this function
1268 // a. DIB_getSync
1269 // b. DIB_reclaim (for PCM)
1270 // 3. We require that pTimeout != NULL since we dereference to make a const
1272 Int DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout)
1273 {
1274 DIB_DeviceExtension * restrict pDevExt = (DIB_DeviceExtension *)device->object;
1275 MdInt * restrict pTail, * restrict pShadowTail, * restrict pSync;
1276 MdInt *pLocalTail, pc;
1277 XDAS_Int8 scanState;
1278 XDAS_UInt32 zeroCount;
1279 int stride, numLeft, i, datId;
1280 int status, foundDTS = 0;
1281 Uns scanCount, pageSize;
1282 PAF_SIO_IALG_Obj *pObj = pDevExt->pSioIalg;
1283 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1284 const int timeoutChanged = (*pTimeout != 2 * pBufConfig->pBufStatus->unknownTimeout);
1285 MdInt DTSHDSubType;
1287 // .........................................................................
1289 // works for both SYNC_NONE and SYNC_PCM
1290 numLeft = min (*pTimeout, GetNumAvail(pBufConfig));
1292 pTail = pBufConfig->pntr.pMdInt;
1293 pShadowTail = pBufConfig->pntr.pMdInt;
1295 // if scratch buffer present then assume it is needed for paging
1296 pageSize = numLeft*pBufConfig->sizeofElement;
1298 Log_info3("DIB: Entered DIB_syncScan with pTail = 0x%x & numLeft = %d, timeout = %d", (xdc_IArg)pTail, numLeft, *pTimeout);
1301 if ((pAlgConfig->numRec > 1) && pAlgConfig->pMemRec[1].base && (pAlgConfig->pMemRec[1].size >= pageSize)) {
1302 pTail = pAlgConfig->pMemRec[1].base;
1303 datId = DAT_copy ((void *) pShadowTail, (void *) pTail, pageSize);
1304 DAT_wait (datId);
1305 }
1307 if (pBufConfig->sizeofElement == 4) {
1308 Log_info0("DIB: SyncScan - Inside pBufConfig->sizeofElement == 4");
1309 stride = 2;
1310 pTail += 1; // point at MSB
1311 pShadowTail += 1;
1312 }
1313 else
1314 stride = 1;
1316 // .........................................................................
1318 // scan until out of available data or a sync found
1319 scanCount = 0;
1320 zeroCount = pDevExt->zeroCount;
1321 scanState = pDevExt->scanState;
1322 pSync = pDevExt->pSync.pMdInt;
1324 Log_info4("DIB: Entered DIB_syncScan with zeroCount = %d & scanState = %d, stride = %d, pSync = 0x%x", zeroCount, scanState, stride, (xdc_IArg)pSync);
1326 // scan until out of available data or a sync found
1327 for (i=0; i < numLeft; i++) {
1328 MdInt tail = pTail[i*stride];
1330 // assumes SCANNED_NONE = 0
1331 if (!scanState) {
1332 if (tail == IEC_PA) {
1333 // since above code handles ongoing sync we are
1334 // safe to check for extended sync here. i.e.
1335 // two zeros before PA.
1336 if (zeroCount >= 2) {
1337 scanState = SCANNED_IEC_PA;
1338 pSync = &pShadowTail[i*stride];
1339 }
1340 }
1341 else if (tail == DTS14_SYNC_A) {
1342 scanState = SCANNED_DTS14_SYNC_A;
1343 pSync = &pShadowTail[i*stride];
1344 }
1345 else if (tail == DTS16_SYNC_A) {
1346 scanState = SCANNED_DTS16_SYNC_A;
1347 pSync = &pShadowTail[i*stride];
1348 }
1350 // limit count to prevent wrap around
1351 zeroCount = min (zeroCount+1,INT_MAX - 1);
1352 if (tail != 0x0000)
1353 zeroCount = 0;
1355 // don't start counting until we get the first non-zero
1356 // sample while UNKNOWN. Note we don't have to worry
1357 // about the other scanCount increments since these
1358 // only occur after the first non-zero sample.
1359 //
1360 // so don't count unless
1361 // . we are already started counting (in this call) ||
1362 // . we started counting in an earlier scanForSync (timeout has changed) ||
1363 // . the last sample was non-zero
1364 if (scanCount || (tail != 0x0000) || timeoutChanged)
1365 {
1366 //Log_info3("DIB: DIB_syncScan scanCount = %d tail = %d timeoutChanged = %d", scanCount, tail, timeoutChanged);
1367 scanCount += 1;
1368 }
1371 continue;
1372 }
1374 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1376 switch (scanState) {
1378 case SCANNED_DTS16_SYNC_A:
1379 if (tail == DTS16_SYNC_B) {
1380 scanState = SCANNED_DTS16_SYNC_B;
1381 scanCount += 1;
1382 }
1383 else
1384 scanState = SCANNED_NONE;
1385 break;
1387 // wait for header data to get payload size via
1388 // nblks/fsize
1389 case SCANNED_DTS16_SYNC_B:
1390 // use extended sync
1392 if ((short)(tail & 0xFC00) == DTS16_SYNC_C) {
1393 scanState = SCANNED_DTS16_SYNC_C;
1394 scanCount += 1;
1395 }
1396 else
1397 scanState = SCANNED_NONE;
1398 break;
1400 // `````````````````````````````````````````````````````````````````````````
1401 // check for 2nd word of DTS-14 sync
1402 case SCANNED_DTS14_SYNC_A:
1403 if (tail == DTS14_SYNC_B) {
1404 scanState = SCANNED_DTS14_SYNC_B;
1405 scanCount += 1;
1406 }
1407 else
1408 scanState = SCANNED_NONE;
1409 break;
1411 // check for 3rd word of DTS-14 sync
1412 case SCANNED_DTS14_SYNC_B:
1413 // if here then looking for extended 38 bit sync
1414 if ((short)(tail & 0xFFF0) == DTS14_SYNC_C) {
1415 scanState = SCANNED_DTS14_SYNC_C;
1416 scanCount += 1;
1417 }
1418 else
1419 scanState = SCANNED_NONE;
1420 break;
1422 // wait for header data to get payload size via
1423 // nblks/fsize
1424 case SCANNED_DTS14_SYNC_C:
1425 scanState = SCANNED_DTS14_SYNC_D;
1426 scanCount += 1;
1427 break;
1429 // `````````````````````````````````````````````````````````````````````````
1430 // if here then all of header is buffered
1431 case SCANNED_DTS16_SYNC_C:
1432 case SCANNED_DTS14_SYNC_D:
1433 // update sync to point at beginning of DTS header as syncScanDTS uses this info
1434 pDevExt->scanState = scanState;
1435 pDevExt->pSync.pMdInt = pSync;
1436 status = DIB_FTABLE_syncScanDTS (device, pBufConfig, pTimeout, (XDAS_UInt16 *) &pShadowTail[i*stride]);
1437 scanState = pDevExt->scanState;
1438 if (status)
1439 return status;
1440 foundDTS = 1;
1441 if (pDevExt->syncState == SYNC_ONE)
1442 goto syncScanExit;
1443 break;
1445 // `````````````````````````````````````````````````````````````````````````
1447 // note that the round about detection of IEC only
1448 // happens for the first sync so the extra states are OK.
1449 case SCANNED_IEC_PA:
1450 if (tail == IEC_PB) {
1451 scanState = SCANNED_IEC_PB;
1452 scanCount += 1;
1453 Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - if path");
1454 }
1455 else
1456 {
1457 Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - else path");
1458 scanState = SCANNED_NONE;
1459 }
1460 break;
1462 case SCANNED_IEC_PB:
1463 // Update scanCount here since, at this point, we are confident that
1464 // this is a proper IEC stream. Regardless if we ignore it our not.
1465 // Therefore we want to properly signal that this data has been scanned.
1466 scanCount += 1;
1468 // check for IEC pause packets at this time and if required ignore them.
1469 // By construction we are guaranteed to have tail=PC at this time.
1470 if ((pBufConfig->pBufStatus->mode == MODE_NO_ZERORUNRESTART) ||
1471 (pBufConfig->pBufStatus->mode == MODE_NO_ZERORUN)) {
1472 MdInt pc = tail & 0x1F;
1474 if ((pc == 0) || (pc == 3)) {
1475 scanState = SCANNED_NONE;
1476 break;
1477 }
1478 }
1480 scanState = SCANNED_IEC_PC;
1481 break;
1483 case SCANNED_IEC_PC:
1484 pLocalTail = pSync;
1485 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1486 pc = *pLocalTail & 0x1F;
1487 pDevExt->headerSize = IEC_HEADER_SIZE;
1489 Log_info0("DIB: Sync Scan - Inside case: SCANNED_IEC_PC");
1490 // Handle DTSHD subtype (LBR)
1491 if (pc == 0x11) {
1492 pDevExt->headerSize +=6;
1493 DTSHDSubType = (*pLocalTail & 0x700)>>8;
1494 }
1495 // DDP or THD
1496 if (pc == 21 || pc ==22) {
1497 TRACE((&TR_MOD, "Dolby: useIECSubType is 0x%x.\n", pBufConfig->pBufStatus->useIECSubType));
1498 if (pBufConfig->pBufStatus->useIECSubType == 1) {
1499 unsigned char IECSubType = *pLocalTail & 0x60;
1500 TRACE((&TR_MOD, "Dolby: IECSubType is 0x%x.\n", IECSubType));
1501 if (IECSubType != 0) {
1502 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
1503 pDevExt->frameLength = 0;
1504 }
1505 }
1506 }
1507 // don't know how to support other types
1508 if (pc > 22)
1509 {
1510 Log_info1("DIB: Unknown IEC type 0x%x encountered.\n", pc);
1511 return DIBERR_SYNC;
1512 }
1514 pDevExt->syncState = SYNC_ONE;
1515 pBufConfig->pntr.pMdInt = pSync;
1516 pDevExt->sourceProgram = iecPafSource[pc];
1518 Log_info2("source is %d. pc is %d.", iecPafSource[pc], pc);
1519 //TRACE((&TR_MOD, "source is %d. pc is %d.\n", iecPafSource[pc], pc));
1520 #if 0 //No need to differentiate LBR subtype from DTSHD as DXP source program as LBR is handled inside DTSX decoder like other subtypes.
1521 if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
1522 pDevExt->sourceProgram = PAF_SOURCE_DXP; // LBR is 23
1523 #endif
1524 pDevExt->frameLength = pDevExt->pIECFrameLength[pc];
1525 pDevExt->lengthofData = pDevExt->frameLength;
1526 if (pc == 1)
1527 pDevExt->frameLength = 4288;
1528 else if (pc == 0x11) {
1529 pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
1530 pDevExt->lengthofData = pDevExt->frameLength;
1531 }
1533 goto syncScanExit;
1535 } // switch
1536 } // for
1538 // .............................................................................
1540 syncScanExit:
1541 Log_info4("DIB inside syncScanExit. pTimeout = %d, scanCount = %d, zeroCount = %d, numLeft = %d", *pTimeout,scanCount, zeroCount, numLeft );
1542 pDevExt->zeroCount = zeroCount;
1543 pDevExt->scanState = scanState;
1544 pDevExt->pSync.pMdInt = pSync;
1546 if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1547 pBufConfig->pBufStatus->zeroRun = 1;
1548 else
1549 pBufConfig->pBufStatus->zeroRun = 0;
1551 // If detected an initial DTS sync in a previous buffer then add the
1552 // number of samples in this buffer to the tally.
1553 // TODO: should we add numLeft instead of lengthofData?
1554 if (!foundDTS && pDevExt->numSamplesSinceDTS)
1555 pDevExt->numSamplesSinceDTS += pBufConfig->lengthofData;
1557 if (*pTimeout > scanCount)
1558 *pTimeout -= scanCount;
1559 else {
1560 *pTimeout = 0;
1561 return 0;
1562 }
1564 // This flushes the current scanned buffer if a sync is not found
1565 // Note that this code is not executed when *pTimeout = 0.
1566 // TODO: should this be moved elsewhere. Like in requestFrame?
1567 // seems like this should be done in request frame for continuous modes
1568 // and in getSync for traditional modes.
1569 // What does it mean that this is not executed when we have timed out to PCM
1570 if (pDevExt->syncState == SYNC_NONE || pDevExt->syncState == SYNC_AUTO) {
1571 IncrementPtr (pBufConfig, (Ptr *) &pBufConfig->pntr.pMdInt, numLeft);
1572 return 0;
1573 }
1575 return 0;
1576 } // DIB_syncScan
1578 // -----------------------------------------------------------------------------
1579 // Assumes scanState is SCANNED_DTS16_SYNC_C or SCANNED_DTS14_SYNC_D
1581 Int DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd)
1582 {
1583 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1584 Int sourceProgram = (pDevExt->scanState == SCANNED_DTS14_SYNC_D) ? PAF_SOURCE_DTS14 : PAF_SOURCE_DTS16;
1585 float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
1586 MdInt *pLocalTail, pc, pd;
1587 int nblks;
1590 // compute repetition rate as predicted by DTS header
1591 pLocalTail = pDevExt->pSync.pMdInt;
1592 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1593 pc = *pLocalTail;
1594 if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1595 nblks = (pc & 0x01FC) >> 2;
1596 else {
1597 IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 1);
1598 pd = *pLocalTail;
1599 nblks = (pc & 0x7) << 4;
1600 nblks |= (pd & 0x3C00) >> 10;
1601 }
1603 // if samplerate > 44.1k and DTS16 bit CD then report as DTS-DVD
1604 // this is a work around to the possibility that DTS-DVD is being
1605 // sent but, due to the variance in input recording, we may have
1606 // missed the IEC header. This is predicated on the enable register
1607 if (pBufConfig->pBufStatus->reportDTS16AsDTSForLargeSampleRate &&
1608 (sampleRate > 44100) && (sourceProgram == PAF_SOURCE_DTS16))
1609 sourceProgram = PAF_SOURCE_DTS;
1611 // point at LSB, if neceesary, so that space calculation is correct
1612 if (pBufConfig->sizeofElement == 4)
1613 pHeaderEnd -= 1;
1615 // If in PCM mode then require double sync, at an appropriate spacing,
1616 // in order to determine DTS validity.
1617 if (pDevExt->syncState == SYNC_PCM) {
1618 int diff;
1620 // If we have started counting, i.e. found a previous sync,
1621 // then compute sync spacing.
1622 if (pDevExt->numSamplesSinceDTS) {
1623 // determine distance since last sync
1624 // pHeaderEnd, which points at the end of the DTS header, is guaranteed
1625 // to be in the active buffer. Whereas the pointer to the beginning of the header (pSync)
1626 // may have occured in the previous buffer.
1627 diff = ((int) pHeaderEnd - (int) pBufConfig->pntr.pVoid);
1628 if (diff < 0)
1629 diff += pBufConfig->sizeofBuffer;
1630 diff /= pBufConfig->sizeofElement;
1631 diff += pDevExt->numSamplesSinceDTS;
1633 // if spacing incorrect then reset sample count to
1634 // force next conditional to be true.
1635 if (diff != (nblks+1)*32*2)
1636 pDevExt->numSamplesSinceDTS = 0;
1637 }
1639 // If this is the 1st sync detected or if this is the second sync
1640 // but the spacing between DTS syncs did not match that predicted by
1641 // NBLKS, then this is not DTS data. Therefore the previous DTS sync
1642 // word was not valid and so it is safe to reset the count based on
1643 // this secondary sync word. This latter sync may or may not be valid;
1644 // we don't know yet. In both cases init sync spacing count, reset
1645 // scan state, and continue. Note that there is a positive, albeit
1646 // quite small, probability of falsing in a pathological case where
1647 // the PCM data, interpreted as a DTS header and used to compute NBLKS,
1648 // actually matches the fake DTS syncs in the PCM file.
1649 if (!pDevExt->numSamplesSinceDTS) {
1650 diff = (int) pBufConfig->head.pVoid - (int) pHeaderEnd;
1651 if (diff <= 0)
1652 diff += pBufConfig->sizeofBuffer;
1653 diff /= pBufConfig->sizeofElement;
1654 pDevExt->numSamplesSinceDTS = diff;
1655 pDevExt->scanState = SCANNED_NONE;
1656 return 0;
1657 }
1658 } //SYNC_PCM
1660 pDevExt->lengthofData = (nblks+1)*32*2;
1661 if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1662 pDevExt->frameLength = pDevExt->lengthofData + 4;
1663 else
1664 pDevExt->frameLength = pDevExt->lengthofData + 6;
1666 pDevExt->syncState = SYNC_ONE;
1667 pBufConfig->pntr = pDevExt->pSync;
1668 pDevExt->sourceProgram = sourceProgram;
1670 return 0;
1671 } //DIB_syncScanDTS
1673 // -----------------------------------------------------------------------------
1674 // This function is responsible for verifying bitstream sync (if applicable) and
1675 // configuring the sizes of the next frame of data.
1677 Int DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1678 {
1679 DIB_DeviceExtension * restrict pDevExt = (DIB_DeviceExtension *) device->object;
1680 MdInt * restrict pTail;
1681 MdInt pa, pb, pc;
1682 unsigned char DTSHDSubType;
1683 PAF_UnionPointer ac3SearchPtr;
1686 // MID 810
1687 // TODO: is this needed anymore? can we combine above and this?
1688 // I don't think this is needed since pSync is guaranteed to be
1689 // valid under all cases where this function is called.
1690 if (!(pDevExt->scanState == SCANNED_DTS14_SYNC_D ||
1691 pDevExt->scanState == SCANNED_DTS16_SYNC_C ||
1692 pDevExt->scanState == SCANNED_IEC_PC ))
1693 return 0;
1695 // minimum possible distance from current IEC sync to next is 1856 words
1696 // capture this here before we update pSync following
1697 ac3SearchPtr = pDevExt->pSync;
1699 // for steady state compute expected sync location
1700 if (pDevExt->syncState == SYNC_ONGOING)
1701 IncrementPtr (pBufConfig, &pDevExt->pSync.pVoid, pBufConfig->lengthofData);
1703 pTail = pDevExt->pSync.pMdInt;
1704 pa = *pTail;
1705 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1706 pb = *pTail;
1707 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1708 pc = *pTail;
1709 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1711 switch (pDevExt->scanState) {
1712 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1714 case SCANNED_DTS14_SYNC_D:
1715 // check sync (extended sync checked above for 1st sync)
1716 if ((pa != DTS14_SYNC_A) || (pb != DTS14_SYNC_B) || ((pc & 0xFC00) != (DTS14_SYNC_C & 0xFC00)))
1717 return DIBERR_SYNC;
1718 break;
1720 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1722 case SCANNED_DTS16_SYNC_C:
1723 // check sync (extended sync checked above for 1st sync)
1724 if ((pa != DTS16_SYNC_A) || (pb != DTS16_SYNC_B))
1725 return DIBERR_SYNC;
1726 break;
1728 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1730 case SCANNED_IEC_PC:
1731 // check for sync
1732 // special handling for AC3 variable bit rate (VBR)
1733 // start looking for sync at max payload sync location and
1734 // scan forward. Note that getSync() has waited for
1735 // sufficient data to arrive so that we can determine reliably
1736 // the presence or absence of a correct sync.
1738 if ((pa != IEC_PA) || (pb != IEC_PB)) {
1739 PAF_SIO_IALG_Obj *pObj = pDevExt->pSioIalg;
1740 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1741 int scan1, scan2, searchIdx, datId;
1742 const int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1745 // only extend IEC search in the case of AC3
1746 if (pDevExt->sourceProgram != PAF_SOURCE_AC3)
1747 return DIBERR_SYNC;
1749 // move search ptr to earliest possible location of next sync
1750 IncrementPtr (pBufConfig, &ac3SearchPtr.pVoid, 1856);
1752 // compute number of samples between earliest possible sync location
1753 // (ac3SearchPtr) and latest possible sync location (head)
1754 scan1 = (int) pBufConfig->head.pVoid - (int) ac3SearchPtr.pVoid;
1755 if (scan1 < 0) {
1756 // here if search will wrap around so split search into two
1757 // halves to accomodate circular buffer
1758 scan1 = bufEnd - (int) ac3SearchPtr.pVoid;
1759 scan2 = (int) pBufConfig->head.pVoid - (int) pBufConfig->base.pVoid;
1760 }
1761 else
1762 scan2 = 0;
1764 // page if necessary (assume so if second memRec present)
1765 if (pAlgConfig->numRec > 1) {
1766 // if invalid buffer or if page buffer not big enough for either split then error
1767 if (!pAlgConfig->pMemRec[1].base ||
1768 (pAlgConfig->pMemRec[1].size < max(scan1,scan2)))
1769 return DIBERR_UNSPECIFIED;
1771 pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1772 datId = DAT_copy (ac3SearchPtr.pVoid, (void *) pTail, scan1);
1773 DAT_wait (datId);
1774 }
1775 else
1776 pTail = ac3SearchPtr.pMdInt;
1778 // convert to number of words
1779 scan1 /= pBufConfig->sizeofElement;
1781 // if non-zero must be IEC header, otherwise sync error
1782 // update pointer after check so that it remains
1783 // pointed at first non-zero word when breaking
1784 searchIdx = 0;
1785 while (scan1--) {
1786 if (*pTail != 0) {
1787 // force skip of any possible split scan since we found non-zero word
1788 scan2 = 0;
1789 break;
1790 }
1791 *pTail++;
1792 searchIdx++;
1793 }
1795 // perform second half of circular buffer search if necessary
1796 if (scan2) {
1797 // page if necessary, note no need to check valid buffer
1798 // or space since this is ensured in first scan
1799 if (pAlgConfig->numRec > 1) {
1800 pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1801 datId = DAT_copy (pBufConfig->base.pVoid, (void *) pTail, scan2);
1802 DAT_wait (datId);
1803 }
1804 else
1805 pTail = pBufConfig->base.pMdInt;
1807 // convert to number of words
1808 scan2 /= pBufConfig->sizeofElement;
1810 while (scan2--) {
1811 if (*pTail != 0)
1812 break;
1813 *pTail++;
1814 searchIdx++;
1815 }
1816 }
1818 // if using paging buffer then translate search pointer back into circular buffer
1819 if (pAlgConfig->numRec > 1) {
1820 pTail = ac3SearchPtr.pMdInt;
1821 IncrementPtr (pBufConfig, (Ptr *) &pTail, searchIdx);
1822 }
1824 // update sync in expection of success, if it is not a sync then no
1825 // harm since it will be ignored then reset
1826 pDevExt->pSync.pMdInt = pTail;
1828 // above search only scans for the first non-zero word.
1829 // here is common check to make sure that non-zero data is an IEC sync.
1830 pa = *pTail;
1831 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1832 pb = *pTail;
1833 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1834 pc = *pTail;
1835 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1836 if ((pa != IEC_PA) || (pb != IEC_PB))
1837 return DIBERR_SYNC;
1838 }
1840 // compute possible DTSHD sub type before masking pc
1841 DTSHDSubType = (pc & 0x700) >> 8;
1843 // mask pc to get data type only
1844 pc = pc & 0x1F;
1846 // don't know how to support other types
1847 // this also ensures that the below array access is bounded
1848 if (pc > 22)
1849 return DIBERR_SYNC;
1851 // continuing frame must be same as current type otherwise
1852 // we return error to force reset of decode and input
1853 // classification state machines
1854 if (pDevExt->sourceProgram != iecPafSource[pc]) {
1855 if (DTSHDSubType == 3 &&
1856 (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <= 48000.0)) {
1857 if (pDevExt->sourceProgram != PAF_SOURCE_DXP)
1858 return DIBERR_SYNC;
1859 }
1860 else
1861 return DIBERR_SYNC;
1862 }
1863 break;
1865 // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1866 } //switch
1868 return 0;
1869 } // DIB_initFrame
1871 // -----------------------------------------------------------------------------
1873 Int DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count )
1874 {
1875 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
1876 DEV2_Handle pChild = (DEV2_Handle) &pDevExt->child;
1877 Int status, lock;
1879 Log_info2("DIB_waitForData.%d count = %d", __LINE__, count);
1880 //TRACE((&TR_MOD, "DIB_waitForData.%d count = %d\n", __LINE__, count));
1882 while (GetNumAvail(pBufConfig) < count) {
1883 PAF_SIO_InputStatus inputStatus;
1885 // query underlying device for lock status & check lock override register
1886 // dont wait without lock
1887 status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS, (Arg) &inputStatus);
1888 if (status)
1889 {
1890 Log_info2("DIB_waitForData.%d SIO2_ctrl() returned %d", __LINE__, status);
1891 //TRACE((&TR_MOD, "DIB_waitForData.%d SIO2_ctrl() returned %d\n", __LINE__, status));
1892 return status;
1893 }
1894 lock = inputStatus.lock;
1895 #ifndef IGNORE_LOCK_OVERRIDE
1896 if ((pBufConfig->pBufStatus->lockOverride & (XDAS_Int8)0x80) == 0)
1897 {
1898 Log_info1("DIB_waitForData.%d lock = lockOverride\n", __LINE__);
1899 //TRACE((&TR_MOD, "DIB_waitForData.%d lock = lockOverride\n", __LINE__));
1900 lock = pBufConfig->pBufStatus->lockOverride;
1901 }
1902 #endif
1903 if (!lock)
1904 {
1905 Log_info1("DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__);
1906 //TRACE((&TR_MOD, "DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__));
1907 return DIBERR_SYNC;
1908 }
1909 // check that decoding still requested -- allows for status
1910 // register to be updated via IOS to cancel autoProcessing
1911 if (pDevExt->pDecodeStatus) {
1912 if (pDevExt->pDecodeStatus->sourceSelect == PAF_SOURCE_NONE)
1913 {
1914 Log_info1("DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC", __LINE__);
1915 //TRACE((&TR_MOD, "DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC\n", __LINE__));
1916 return DIBERR_SYNC;
1917 }
1918 }
1920 Log_info1("DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()", __LINE__);
1921 //TRACE((&TR_MOD, "DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()\n", __LINE__));
1922 status = DIB_FTABLE_reclaimChild (device, pBufConfig);
1923 if(status)
1924 {
1925 Log_info2("DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d", __LINE__, status);
1926 //TRACE((&TR_MOD, "DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d\n", __LINE__, status));
1927 return status;
1928 }
1929 }
1931 return 0;
1932 } // DIB_waitForData
1934 // -----------------------------------------------------------------------------
1935 #ifdef IEC_ENCODE
1937 // FS9 only supports PCM input so return error if not PCM.
1939 Int DIB_requestFrame_957 (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1940 {
1941 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *) device->object;
1942 int i, head, tail, avail, status;
1945 if (pDevExt->sourceProgram != PAF_SOURCE_PCM)
1946 return DIBERR_SYNC;
1948 // if in steady state then update tail pointer to indicate we are done, i.e. no
1949 // longer own, the last frame of data.
1950 if (pDevExt->running > 1)
1951 IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
1953 pDevExt->lengthofData = pBufConfig->stride*pDevExt->pcmFrameLength;
1954 pDevExt->frameLength = pDevExt->lengthofData;
1956 // note that due to MID 1037 it is required to check the return status after this call
1957 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1958 if (status)
1959 return status;
1961 // add extra input delay to account for peak encoder mips
1962 for (i=0; i < 4; i++) {
1963 head = (int) pBufConfig->futureHead.pVoid;
1964 tail = (int) pBufConfig->pntr.pVoid;
1965 // compute how much data we have including outstanding requests
1966 if (head >= tail)
1967 avail = head - tail;
1968 else
1969 avail = head - tail + pBufConfig->sizeofBuffer;
1971 // convert to words
1972 avail /= pBufConfig->sizeofElement;
1973 if (avail < 4*pBufConfig->lengthofData) {
1974 status = DIB_FTABLE_issueChild (device, pBufConfig, pBufConfig->lengthofData, 0);
1975 if (status)
1976 return status;
1977 }
1978 }
1980 pBufConfig->frameLength = pDevExt->frameLength;
1981 pBufConfig->lengthofData = pDevExt->lengthofData;
1983 if (pDevExt->running < 3)
1984 pDevExt->running++;
1986 return 0;
1987 } // DIB_requestFrame_957
1989 #endif /* IEC_ENCODE */
1991 // -----------------------------------------------------------------------------
1993 #ifdef DSD_OVER_SPDIF
1995 Int DIB_requestFrame_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
1996 {
1997 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
1998 int status;
2000 status = DIB_requestFrame (device, pBufConfig);
2001 // For testing DSD over SPDIF i.e. 1 pin vs actual over 6 pin
2002 pDevExt->numSamplesExtra += pDevExt->lengthofData;
2003 pDevExt->lengthofData *=6;
2004 pDevExt->numSamplesExtra -= pDevExt->lengthofData;
2006 return status;
2007 } // DIB_requestFrame
2009 Int DIB_getSync_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2010 {
2011 DIB_DeviceExtension *pDevExt = (DIB_DeviceExtension *)device->object;
2012 DEV2_Handle pChild = (DEV2_Handle)&pDevExt->child;
2013 int status;
2015 status=DIB_getSync (device, pBufConfig );
2016 if(status)
2017 return status;
2019 pBufConfig->sizeofElement = 2;
2020 status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
2021 if (status)
2022 return status;
2024 // compute and use *effective buffer size*
2025 {
2026 int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
2027 pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
2028 }
2029 //..........................................................................
2031 return 0;
2032 } // DIB_getSync_patch
2034 #endif /* DSD_OVER_SPDIF */
2036 // -----------------------------------------------------------------------------