Adding back this code causes mat-thd (input only) to work
[processor-sdk/performance-audio-sr.git] / pasdk / test_dsp / mib / mib.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 //
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 #if 0
75 #if ((PAF_DEVICE&0xFF000000) == 0xD8000000)
76 #ifndef dMAX_CFG
77 #include <dap_dmax.h>
78 #else
79 #include <dmax_struct.h>
80 #include <dmax_params.h>
81 #endif /* dMAX_CFG */
82 #include "psdkaf_hjt.h"
83 extern Uint32 DAT_cacheop_and_copy (void *src, void *dst, Uint16 byteCnt);
84 #undef DAT_copy
85 #define DAT_copy DAT_cacheop_and_copy
86 #else
87 #include "pafhjt.h"
88 #include "dmax_dat.h" // this has to come after pafhjt
89 #endif
91 #else
92 #include "pafhjt.h"
93 #endif
95 #include <ti/sysbios/knl/Clock.h>
96 #include <xdc/runtime/Log.h>
98 //grab from samrat.c
99 #include <paftyp.h>
100 #include <stdasp.h>
102 #include <logp.h>
103 #include <stdio.h>  // printf in case of programming error
105 // allows you to set a different trace module in pa.cfg
106 #define TR_MOD  trace
108 //#define TRACE_ENABLE
109 #ifdef TRACE_ENABLE
110   #include "dp.h"
111   #define TRACE(a)  dp a    // LOG_printf a
112 #else
113   #define TRACE(a)
114 #endif
116 extern const PAF_SampleRateHz
117 PAF_ASP_sampleRateHzTable[PAF_SAMPLERATE_N][PAF_SAMPLERATEHZ_N];
119 #define SCANATSAMPLERATELIMIT ((float) 48000.)
121 // Likely needs to be 7 when/if AC3 handling is changed to
122 // throw away fill.
123 #define NUM_CHILD_BUFFERS 6
125 Int   DIB_ctrl (DEV2_Handle device, Uns code, Arg Arg);
126 Int   DIB_idle (DEV2_Handle device, Bool Flush);
127 Int   DIB_issue (DEV2_Handle device);
128 Int   DIB_open (DEV2_Handle device, String Name);
129 Int   DIB_reclaim (DEV2_Handle device);
130 Int   DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
131 Int   DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
132 Int   DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
133 Int   DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, Int size, Int forTotal);
134 Int   DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
135 Int   DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig);
136 Int   DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout);
137 Int   DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count);
138 Int   DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd);
140 // Driver function table.
141 DIB_Fxns DIB_FXNS  = {
142     NULL,                // close not used in PA/F systems
143     DIB_ctrl,
144     DIB_idle,
145     DIB_issue,
146     DIB_open,
147     NULL,                // ready not used in PA/F systems
148     DIB_reclaim,
149     DIB_getSync,
150     DIB_initFrame,
151     DIB_requestFrame,
152     DIB_issueChild,
153     DIB_reclaimChild,
154     DIB_reset,
155     DIB_syncScan,
156     DIB_waitForData,
157     DIB_syncScanDTS
158 };
160 // macros assume pDevExt is available and pDevExt->pFxns is valid
161 #define DIB_FTABLE_getSync(_a,_b)             (*pDevExt->pFxns->getSync)(_a,_b)
162 #define DIB_FTABLE_initFrame(_a,_b)           (*pDevExt->pFxns->initFrame)(_a,_b)
163 #define DIB_FTABLE_requestFrame(_a,_b)        (*pDevExt->pFxns->requestFrame)(_a,_b)
164 #define DIB_FTABLE_issueChild(_a,_b,_c,_d)    (*pDevExt->pFxns->issueChild)(_a,_b,_c,_d)
165 #define DIB_FTABLE_reclaimChild(_a,_b)        (*pDevExt->pFxns->reclaimChild)(_a,_b)
166 #define DIB_FTABLE_reset(_a,_b)               (*pDevExt->pFxns->reset)(_a,_b)
167 #define DIB_FTABLE_syncScan(_a,_b,_c)         (*pDevExt->pFxns->syncScan)(_a,_b,_c)
168 #define DIB_FTABLE_waitForData(_a,_b,_c)      (*pDevExt->pFxns->waitForData)(_a,_b,_c)
169 #define DIB_FTABLE_syncScanDTS(_a,_b,_c,_d)   (*pDevExt->pFxns->syncScanDTS)(_a,_b,_c,_d)
171 // .............................................................................
173 //IBMODE
174 enum
176     MODE_DEFAULT = 0,
177     MODE_NO_ZERORUNRESTART = 1,
178     MODE_NO_ZERORUN = 2
179 };
181 // syncState
182 enum
184     SYNC_NONE,
185     SYNC_ONE,
186     SYNC_ONGOING,
187     SYNC_PCM,
188     SYNC_PCM_FORCED,
189     SYNC_AUTO
190 };
192 // scanState
193 enum
195     SCANNED_NONE,
196     SCANNED_IEC_PA,
197     SCANNED_IEC_PB,
198     SCANNED_IEC_PC,
199     SCANNED_DTS14_SYNC_A,
200     SCANNED_DTS14_SYNC_B,
201     SCANNED_DTS14_SYNC_C,
202     SCANNED_DTS14_SYNC_D,
203     SCANNED_DTS16_SYNC_A,
204     SCANNED_DTS16_SYNC_B,
205     SCANNED_DTS16_SYNC_C
206 };
208 // all sizes in number of 16bit words words
209 #define IEC_HEADER_SIZE   4 //PA PB PC PD
210 #define DTS14_HEADER_SIZE 6
211 #define DTS16_HEADER_SIZE 4
213 //table needed until PAF_SOURCE is reordered to match IEC numbering
214 const SmUns iecPafSource[23] =
216     PAF_SOURCE_UNKNOWN,  // 0: IEC NULL Type
217     PAF_SOURCE_AC3,      // 1: Comments on 1-15 match IEC 61937 part 2.
218     PAF_SOURCE_UNKNOWN,  // 2: IEC reserved
219     PAF_SOURCE_UNKNOWN,  // 3: IEC pause
220     PAF_SOURCE_UNKNOWN,  // 4: MPEG 1 layer 1
221     PAF_SOURCE_MP3,      // 5: MPEG layer 2 or 3
222     PAF_SOURCE_UNKNOWN,  // 6: MPEG 2 data with extension
223     PAF_SOURCE_AAC,      // 7: MPEG-2 AAC ADTS
224     PAF_SOURCE_UNKNOWN,  // 8: MPEG 2 layer 1 low sampling frequency
225     PAF_SOURCE_UNKNOWN,  // 9: MPEG 2 layer 2 or 3 low sampling frequency
226     PAF_SOURCE_UNKNOWN,  // 10: reserved
227     PAF_SOURCE_DTS,      // 11: DTS type 1 (11 bit: 512 sample repeat period)
228     PAF_SOURCE_DTS12,    // 12: DTS type 2 (12 bit: 1024 sample repeat period)
229     PAF_SOURCE_DTS13,    // 13: DTS type 3 (13 bit: 2048 sample repeat period)
230     PAF_SOURCE_DTS14,    // 14: ATRAC
231     PAF_SOURCE_UNKNOWN,  // 15: ATRAC 2/3
232     PAF_SOURCE_THD,      // 16
233     PAF_SOURCE_DTSHD,    // 17
234     PAF_SOURCE_WMA9PRO,  // 18
235     PAF_SOURCE_UNKNOWN,  // 19
236     PAF_SOURCE_UNKNOWN,  // 20
237     PAF_SOURCE_DDP,      // 21
238     PAF_SOURCE_THD,      // 22
239 };
241 // IEC framelengths (in 16bit words)
242 static const MdUns iecFrameLength[23] =
244     0,
245     1536*2,
246     0, 0, 0,
247     1152*2,
248     0,
249     1024*2,
250     0, 0, 0,
251     512*2,
252     1024*2,
253     2048*2,
254     0, 0,
255     15*1024*2, //THD
256     1*1024, // DTSHD, actual framelength is adjusted by DTSsubType
257     4096*2,
258     0,0,
259     1536*2*4,
260     15*1024*2 //THD
261 };
263 #define IEC_PA       ((short) 0xF872)
264 #define IEC_PB       ((short) 0x4E1F)
265 #define DTS16_SYNC_A ((short) 0x7FFE)
266 #define DTS16_SYNC_B ((short) 0x8001)
267 #define DTS16_SYNC_C ((short) 0xFC00)
268 #define DTS14_SYNC_A ((short) 0x1FFF)
269 #define DTS14_SYNC_B ((short) 0xE800)
270 #define DTS14_SYNC_C ((short) 0x07F0)
272 #define  DTS_BURST_TYPE_I  0x008B
273 #define  DTS_BURST_TYPE_II 0x018C
274 #define  DTS_BURST_TYPE_III 0x028D
275 #define  DTS_BURST_TYPE_IV  0x0491
277 #define  DTS_BURST_TYPE_IV_CBR  0x02
278 #define  DTS_BURST_TYPE_IV_LBR  0x03
279 #define  DTS_BURST_TYPE_IV_HBR  0x04
281 #define DEFAULT_AUTOREQUESTSIZE  128
282 //#define DEFAULT_AUTOREQUESTSIZE  256
284 // This is used at a couple of locations to ensure the transfer
285 // size is sufficiently long to be useful.
286 //#define NOMINAL_XFERSIZE         128
287 #define NOMINAL_XFERSIZE         128 //GJ Debug
288 //#define NOMINAL_XFERSIZE         512 //GJ Debug
290 #define min(a, b)  (((a) < (b)) ? (a) : (b))
291 #define max(a, b)  (((a) > (b)) ? (a) : (b))
293 // -----------------------------------------------------------------------------
295 inline void IncrementPtr (PAF_InpBufConfig *pBufConfig, Ptr *pPtr, int numWords)
297     int addr;
300     addr = (int) *pPtr + numWords*pBufConfig->sizeofElement;
301     if (addr > ((int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer - 1))
302         addr -= pBufConfig->sizeofBuffer;
304     *pPtr = (Ptr) addr;
305     return;
306 } // IncrementPtr
308 // -----------------------------------------------------------------------------
310 inline int GetNumAvail (PAF_InpBufConfig *pBufConfig)
312     int numBytes;
315     if ( (Uns) pBufConfig->head.pVoid >= (Uns) pBufConfig->pntr.pVoid)
316         numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid);
317     else
318         numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
320     // return in words
321     return (numBytes / pBufConfig->sizeofElement);
322 } // GetNumAvail
324 // -----------------------------------------------------------------------------
325 // compute how much data we have including outstanding requests
327 inline int GetFutureAvail (PAF_InpBufConfig *pBufConfig)
329     int numBytes;
332     if ( (Uns) pBufConfig->futureHead.pVoid >= (Uns) pBufConfig->pntr.pVoid)
333         numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid);
334     else
335         numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
337     // return in words
338     return (numBytes / pBufConfig->sizeofElement);
339 } // GetFutureAvail
341 // -----------------------------------------------------------------------------
343 Int DIB_issue (DEV2_Handle device)
345     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
346     DEV2_Frame             *srcFrame;
347     Int                    status;
348     PAF_InpBufConfig      *pBufConfig;
351     srcFrame = Queue_get (device->todevice);
352     pBufConfig = (PAF_InpBufConfig *) srcFrame->addr;
353     if (!pBufConfig || !pBufConfig->pBufStatus)
354         return SIO2_EINVAL;
356     Queue_put (device->fromdevice, (Queue_Elem *)srcFrame);
358 //GJ: PAF_SIO_REQUEST_AUTO, Not Supported, yet.
359     if (srcFrame->arg == PAF_SIO_REQUEST_AUTO) {
360 #if 0
361         // if not yet running, prime input buffer
362         if (pDevExt->syncState == SYNC_NONE) {
364             status = DIB_FTABLE_reset (device, pBufConfig);
365             if (status)
366                 return status;
368             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
370             status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
371             if (status)
372                 return status;
374             // * also reset pDevExt->zeroCount, as in DIB_getSync()?
375             // just for PAF_SOURCE_PCMAUTO? *
376             pDevExt->pcmTimeout =
377                 pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO ? 0 :
378                 2 * pBufConfig->pBufStatus->unknownTimeout;
379             pDevExt->syncState = SYNC_AUTO;
381             // allows PCM decoder to be used to generate zero-valued audio frames while scanning
382             pBufConfig->deliverZeros = 1;
383         }
384         // no action if already sync'ed
385         else if (pDevExt->syncState != SYNC_AUTO)
386             return 0;
388         status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
389         if (status)
390             return status;
391 #endif
392     }
393     else if (srcFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
395         // do nothing if not synced since syncing done in reclaim
396         // This is executed in force modes from the first call to PAF_AST_decodeInit
397         // which calls SIO2_issue for NEWFRAME before all other calls.
398         if (pDevExt->syncState == SYNC_NONE)
399             return 0;
401         status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
402         if (status)
403             return status;
404     }
406     return 0;
407 } // DIB_issue
409 // -----------------------------------------------------------------------------
410 // Although interface allows for arbitrary BufConfigs we only support 1 -- so
411 // we can assume the one on the fromdevice is the one we want
413 extern int gIsrInputCnt; // GJ Debug
414 extern int gIsrOutputCnt; // GJ Debug
416 Int DIB_reclaim (DEV2_Handle device)
418     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *) device->object;
419     DEV2_Frame             *dstFrame;
420     Int                    status = 0;
421     PAF_InpBufConfig      *pBufConfig;
423     dstFrame = (DEV2_Frame *) Queue_head (device->fromdevice);
425     if (dstFrame == (DEV2_Frame *) device->fromdevice)
426         return DIBERR_UNSPECIFIED;
427     if (!dstFrame->addr)
428         return DIBERR_UNSPECIFIED;
430     // if deferred error from last request frame then return now
431     status = pDevExt->deferredError;
432     if (status) {
433         pDevExt->deferredError = 0;
434         pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
435         return status;
436     }
438     pBufConfig = (Ptr) dstFrame->addr;
439     dstFrame->size = sizeof (PAF_InpBufConfig);
441     // .........................................................................
443     if (dstFrame->arg == PAF_SIO_REQUEST_AUTO) {
444 //GJ: PAF_SIO_REQUEST_AUTO - not supported, yet.
445 #if 0
446         Log_info0("DIB: At case = PAF_SIO_REQUEST_AUTO"); // GJ Debug
448         // verify set up by prior DIB_issue()
449         // no action if already sync'ed
450         if (pDevExt->syncState == SYNC_NONE)
451             return DIBERR_AUTO;
452         else if (pDevExt->syncState != SYNC_AUTO)
453             return 0;
455         // get next block of data to scan
456         status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->autoRequestSize);
457         if (status)
458             return status;
460         if (pDevExt->sourceSelect == PAF_SOURCE_NONE) {
461             IncrementPtr (pBufConfig, &pDevExt->bufConfig.pntr.pVoid, pDevExt->autoRequestSize);
462             return 0;
463         }
465         // this function updates the tail pointer; it WON'T reset to SYNC_NONE
466         status = DIB_FTABLE_syncScan (device, &pDevExt->bufConfig, &pDevExt->pcmTimeout);
467         if (status)
468             return status;
470         // if not yet sync'ed ...
471         if (pDevExt->syncState == SYNC_AUTO) {
472             // if timeout, harness tail of DIB_getSync()
473             if (!pDevExt->pcmTimeout) {
475                 // checks pDevExt->zeroCount, runs DIB_reset(),
476                 // updates pBufConfig->deliverZeros/sizeofElement/sizeofBuffer,
477                 // sets pDevExt->sourceProgram = PAF_SOURCE_PCM/DSD?
478                 //  and pDevExt->syncState = SYNC_PCM[_FORCED]
479                 status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
480                 if (status)
481                     return status;
482             }
483         }
485         // if sync'ed to bitstream, this requests add'l input;
486         // if PCM, this "kickstarts" the input,
487         // using settings per above call to DIB_getSync()
488         if (pDevExt->syncState != SYNC_AUTO) {
490             status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
491             if (status)
492                 return status;
494             // this situation may occur for various IEC types,
495             // w/ no matching PAF_SOURCE_ type is defined
496             // (see iecPafSource[] table for the latter mapping)
497             // most like cases are null & pause packets
498             if (pDevExt->sourceProgram == PAF_SOURCE_UNKNOWN)
499                 return DIBERR_SYNC;
501             // request timing frame
502             status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
503             if (status)
504                 return status;
505         }
507 #endif
508     } //dstFrame->arg == PAF_SIO_REQUEST_AUTO
510     // .........................................................................
512     if ((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC)) {
514         Log_info0("DIB: At case: syncState == SYNC_NONE (or PAF_SIO_REQUEST_SYNC)");  // GJ Debug
516         // pass in external buffer config which used to initialize the internal view
517         status = DIB_FTABLE_reset (device, pBufConfig);
518         if (status)
519             return status;
521         status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
522         if (status)
523             return status;
525         // since getSync resets sourceProgram to unknown at entry
526         // sourceProgram will remain unknown if no sync is returned
527         // (i.e. no need to reset it here)
528         if (pDevExt->syncState == SYNC_NONE)
529         {
530             Log_info0("Returning DIBERR_SYNC after DIB_FTABLE_getSync"); // GJ Debug
531             return DIBERR_SYNC;
532         }
534         // get input info (frameLength/etc)
535         status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
537         if (status)
538         {
539             Log_info1("Returning %d after DIB_FTABLE_initFrame", status); // GJ Debug
540             return status;
541         }
543         // request timing frame
544         status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
545         if (status)
546         {
547             Log_info1("Returning %d after DIB_FTABLE_requestFrame", status); // GJ Debug
548             return status;
549         }
550         // update external view of bufConfig. In particular for slave force PCM
551         // this insures that the first decode will be processed with deliverZeros = 1
552         // which is necessary since the first decode of slave input occurs before the
553         // first slave input frame is actually captured.
554         *pBufConfig = pDevExt->bufConfig;
556     } //((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC))
558     // .........................................................................
560     if (dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
562         Log_info0("DIB: At case = PAF_SIO_REQUEST_NEWFRAME"); // GJ Debug
564         // wait for enough data to check for sync at expected location
565         status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->bufConfig.frameLength);
566         if (status)
567         {
568             Log_info2("DIB_reclaim.%d DIB_FTABLE_waitForData returned %d", __LINE__, status); // GJ Debug
569             //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_waitForData returned %d\n", __LINE__, status));
570             return status;
571         }
573         // if PCM, but not forced PCM, then scan for bitstream sync
574         // note that we we using the local view of bufConfig here and we update the
575         // public view afterwards.
576         if (pDevExt->syncState == SYNC_PCM) {
577             float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
578             PAF_InpBufConfig *pBufConfig = &pDevExt->bufConfig;
579             Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
581             // normally no scanning done if sampleRate > 48kHz since bitstream input is highly unlikley.
582             if ((sampleRate <= SCANATSAMPLERATELIMIT) || pBufConfig->pBufStatus->scanAtHighSampleRateMode) {
583                 if (!pBufConfig->deliverZeros) {
584                     pDevExt->pcmTimeout = pBufConfig->lengthofData;
586                     // check zeroRunTrigger if needed
587                     if (ibMode != MODE_NO_ZERORUN) {
588                         if(pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) {
589                             // set this flag one block late to allow for
590                             // transmission of all data in frame which contained zeroRunTrigger
591                             pBufConfig->deliverZeros = 1;
592                             pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
593                         } // > zeroRunTrigger
594                     } // !MODE_NO_ZERORUN
595                 } // !pBufConfig->deliverZeros
597                 // scan PCM data
598                 status = DIB_FTABLE_syncScan (device, pBufConfig, &pDevExt->pcmTimeout);
599                 if (status) {
600                     pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
601                     Log_info2("DIB_reclaim.%d DIB_FTABLE_syncScan returned %d", __LINE__, status); // GJ Debug
602                     //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_syncScan returned %d\n", __LINE__, status));
603                     return status;
604                 }
606                 // if scan found something other than PCM, then exit with error
607                 if (pDevExt->syncState != SYNC_PCM)
608                 {
609                     Log_info1("DIB_reclaim.%d error: syncState != SYNC_PCM", __LINE__); // GJ Debug
610                     //TRACE((&TR_MOD, "DIB_reclaim.%d error: syncState != SYNC_PCM\n", __LINE__));
611                     return DIBERR_SYNC;
612                 }
614                 // if heeding zeroRunRestart control then return to unknown if necessary
615                 if ((ibMode == MODE_DEFAULT) &&
616                     (pDevExt->zeroCount >= 2*pBufConfig->pBufStatus->zeroRunRestart)) {
617                     // if zeroRunRestart me then reset input to unknown
618                     Log_info1("DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
619                     //TRACE((&TR_MOD, "DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN\n", __LINE__));
620                     pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
621                     return DIBERR_SYNC;
622                 }
624                 // since in skeptical state we disallow returning to PCM when end of timeout contains zeros
625                 // note that we need not check the mode here since above logic prevents deliverZeros state.
626                 if (pBufConfig->deliverZeros && (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger))
627                 {
628                     //TRACE((&TR_MOD, "DIB_reclaim.%d set pcmTimeout = unknown timeout\n", __LINE__));
629                     pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
630                 }
631             } //scanAtHighSampleRate
632         } //SYNC_PCM
634         // clear this flag immediately to play new audio ASAP
635         // this check is OK for forced PCM since pcmTimeout and zeroCount are not
636         // updated
637         if (pDevExt->bufConfig.deliverZeros && !pDevExt->pcmTimeout &&
638             (pDevExt->zeroCount < 2 * pDevExt->bufConfig.pBufStatus->zeroRunTrigger))
639         {
640             pDevExt->bufConfig.deliverZeros = 0;
641         }
643         // update external view of buffer with local view we do this with current 
644         // frame info before the following update to the local view for the next 
645         // frame to be captured. Need to subtract headerSize from lengthofData
646         // since, at least for THD, it is needed by decoders.
647         *pBufConfig = pDevExt->bufConfig;
648         pBufConfig->lengthofData -= pDevExt->headerSize;
649         Log_info4("DIB_reclaim.%d lengthofData = %d; InISRCNT=%d; OutISRCNT=%d", __LINE__, pBufConfig->lengthofData, gIsrInputCnt, gIsrInputCnt); // GJ Debug
650         //TRACE((&TR_MOD, "DIB_reclaim.%d lengthofData = %d\n", __LINE__, pBufConfig->lengthofData));
652         // HACK: for DSD the frameLength needs to be the number of samples to generate.
653         if ((pDevExt->sourceSelect >= PAF_SOURCE_DSD1) &&
654             (pDevExt->sourceSelect <= PAF_SOURCE_DSD3))
655             pBufConfig->frameLength /= pBufConfig->stride;
656         Log_info2("DIB_reclaim.%d frameLength = %d", __LINE__, pBufConfig->frameLength); // GJ Debug
657         //TRACE((&TR_MOD, "DIB_reclaim.%d frameLength = %d\n", __LINE__, pBufConfig->frameLength));
659         // set external view to point at synch position of the frame guaranteed
660         // to be captured by above waitForData. Need to condition this against PCM since
661         // in that case pSync could point anywhere in the buffer to to syncScan. E.g.
662         // if there was a partial sync then pSync would point at that rather than
663         // at the beginning of the buffer.
664         // TODO: change syncScan to only update pDevExt->pSync when there is an actual sync
665         //       so that we can use this for both PCM and bitstream
666         if (pDevExt->syncState == SYNC_ONGOING) {
667             pBufConfig->pntr = pDevExt->pSync;
668             IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
669         } //SYNC_ONGOING
671         // if a bitstream then need to update tail to bitstream sync location
672         // and check for next sync at expected location
673         // quick scan for sync. if decoding IEC but sync is missing then
674         // defer error until the next frame so that we decode all frames
675         // TODO: does this assume decoders have copied the entire input frame
676         //       i.e. it is ok to adjust the input buffer pointers.
677         // if successful then this sets
678         //      pSync = address of PA (for IEC)
679         status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
680         if (status) {
681             if (pBufConfig->pBufStatus->lastFrameMask & (1 << pDevExt->sourceProgram)) {
682                 pDevExt->deferredError = status;
683                 Log_info1("DIB_reclaim.%d last frame\n", __LINE__); // GJ Debug
684                 //TRACE((&TR_MOD, "DIB_reclaim.%d last frame\n", __LINE__));
685                 pBufConfig->pBufStatus->lastFrameFlag = 1;
686                 return 0;
687             }
688             else {
689                 Log_info1("DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
690                 //TRACE((&TR_MOD, "DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN\n", __LINE__));
691                 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
692                 return status;
693             }
694         }
696     } //(dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME)
698     // .........................................................................
700     Log_info4("DIB_reclaim.%d exit status = %d, InISRCNT = %d OutISRCNT = %d", __LINE__, status, gIsrInputCnt, gIsrOutputCnt); // GJ Debug
701     //TRACE((&TR_MOD, "DIB_reclaim.%d exit status = %d\n", __LINE__, status));
703     return status;
704 } // DIB_reclaim
706 // -----------------------------------------------------------------------------
708 Int DIB_ctrl (DEV2_Handle  device, Uns code, Arg arg)
710     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
711     DEV2_Handle            pChild = (DEV2_Handle)&pDevExt->child;
712     Int status = 0;
715     switch (code) {
717         case PAF_SIO_CONTROL_GET_CHILD_DEVICE:
718             *((Arg *)arg) = (Arg) pChild;
719             break;
721             //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
723         case PAF_SIO_CONTROL_SET_DECSTATUSADDR:
724             pDevExt->pDecodeStatus = (PAF_DecodeStatus *) arg;
725             break;
727         case PAF_SIO_CONTROL_SET_PCMFRAMELENGTH:
728             pDevExt->pcmFrameLength = (XDAS_Int32) arg;
729             break;
731         case PAF_SIO_CONTROL_SET_SOURCESELECT:
732             pDevExt->sourceSelect = (XDAS_Int8) arg;
733             break;
735         case PAF_SIO_CONTROL_SET_AUTOREQUESTSIZE:
736             pDevExt->autoRequestSize = (XDAS_Int16) arg;
737             break;
739         case PAF_SIO_CONTROL_GET_SOURCEPROGRAM:
740             if (!arg)
741                 return DIBERR_UNSPECIFIED;
742             *((XDAS_Int8 *) arg) = pDevExt->sourceProgram;
743             break;
745         case PAF_SIO_CONTROL_SET_IALGADDR:
746             pDevExt->pSioIalg = (PAF_SIO_IALG_Obj *) arg;
747             break;
749             //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
751         case PAF_SIO_CONTROL_OPEN:
752             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
753             pDevExt->zeroCount = 0;
754             if (pDevExt->pInpBufStatus)
755                 pDevExt->pInpBufStatus->zeroRun = 0;
756             status = DEV2_ctrl (pChild, code, arg);
757             break;
759         case PAF_SIO_CONTROL_CLOSE:
760             if (pDevExt->pInpBufStatus)
761                 pDevExt->pInpBufStatus->zeroRun = 0;
762             status = DEV2_ctrl (pChild, code, arg);
763             break;
765         // return number of DMA events vs. request size
766         // only update if not in error state (i.e. status = 0)
767         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
768             if (!arg)
769                 return DIBERR_UNSPECIFIED;
770             status = DEV2_ctrl (pChild, code, arg);
771             if (!status)
772                 *((Int *)arg) -= pDevExt->pcmFrameLength;
773             break;
775         // return net samples until next DIB_waitForData() should succeed w/o blocking
776         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
777             if (!arg)
778                 return DIBERR_UNSPECIFIED;
779             status = DEV2_ctrl (pChild, code, arg);
780             *((Int *)arg) -= pDevExt->numSamplesExtra;
781             break;
783         default:
784             status = DEV2_ctrl (pChild, code, arg);
785             break;
786     }
788     return status;
789 } // DIB_ctrl
791 // -----------------------------------------------------------------------------
793 Int DIB_idle (DEV2_Handle device, Bool flush)
795     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
796     Int                    status;
799     while (!Queue_empty (device->todevice))
800         Queue_enqueue (device->fromdevice, Queue_dequeue (device->todevice));
802     while (!Queue_empty (device->fromdevice))
803         Queue_enqueue (Queue_handle(&((SIO2_Handle) device)->framelist), Queue_dequeue (device->fromdevice));
805     status = DIB_FTABLE_reset (device, NULL);
806     if (status)
807         return status;
809     return 0;
810 } // DIB_idle
812 // -----------------------------------------------------------------------------
814 Int DIB_open (DEV2_Handle device, String name)
816     DIB_DeviceExtension   *pDevExt;
817     DEV2_Handle             pChild;
818     DEV2_Device            *entry;
819     DEV2_Frame             *frame;
820     Int                    status, i;
821         Error_Block eb;
823         Error_init(&eb);
825     name = DEV2_match (name, &entry);
826     if (entry == NULL) {
827         Log_info1("DEV2_match failed in DIB_open:", SIO2_ENODEV);
828         return SIO2_ENODEV;
829     }
831     // only one frame interface supported
832     if (device->nbufs != 1)
833         return SYS_EALLOC;
835     if (!(pDevExt = Memory_alloc (device->bufSeg, sizeof(DIB_DeviceExtension), 0, &eb)))
836     {
837         Log_info1("DIB Memory alloc failed in DIB_open:", SYS_EALLOC);
838         return SYS_EALLOC;
839     }
840     pDevExt->pcmFrameLength = 0;
841     pDevExt->sourceSelect  = PAF_SOURCE_NONE;
842     pDevExt->autoRequestSize = DEFAULT_AUTOREQUESTSIZE;
843     pDevExt->pInpBufStatus = NULL;
844     pDevExt->pDecodeStatus = NULL;
845     device->object = (Ptr)pDevExt;
847     pChild = (DEV2_Handle)&pDevExt->child;
848     pChild->fromdevice = Queue_create (NULL, &eb);
849     pChild->todevice = Queue_create (NULL, &eb);
850     if (pChild->fromdevice == NULL || pChild->todevice == NULL) {
851         Log_info1 ("DIB Queue_create failed in DIB_open:", SYS_EALLOC);
852         return SYS_EALLOC;
853     }
855     pChild->bufsize = 0;
856     pChild->nbufs = NUM_CHILD_BUFFERS;
857     pChild->bufSeg = device->bufSeg;
858     pChild->mode = device->mode;
859     pChild->timeout = device->timeout;
860     pChild->align = device->align;
861     pChild->devid = entry->devid;
862     pChild->params = entry->params;
863     pChild->fxns = *(DEV2_Fxns *)(entry->fxns);
864     ((SIO2_Handle)pChild)->model = ((SIO2_Handle)device)->model;
866     //Create frames and put them on the correct device queue.
867     // We only support ISSUERECLAIM mode so size = 0
868     Queue_construct(&((SIO2_Handle)pChild)->framelist, NULL); //Queue_new (&((SIO2_Handle)pChild)->framelist);
869     for (i=0; i < pChild->nbufs; i++) {
870         frame = DEV2_mkframe (0, 0, 0);
871         if (!frame)
872             return SYS_EALLOC;
873         Queue_put (Queue_handle(&((SIO2_Handle)pChild)->framelist), (Queue_Elem *) frame);
874     }
876     // open underlying device
877     status = DEV2_open (pChild, name);
878     if (status)
879         return status;
881     // use dev match to fetch function table pointer for DIB
882     name = DEV2_match ("/DIB", &entry);
883     if (entry == NULL) {
884         Log_info1 ("DEV2_match for DIB in DIB_open:", SIO2_ENODEV);
885         return SIO2_ENODEV;
886     }
887     pDevExt->pFxns = (DIB_Fxns *) entry->fxns;
889     // set IEC frame length table pointer -- change in
890     // subsequent control call (not defined) to add new IEC type
891     pDevExt->pIECFrameLength = (XDAS_UInt16 *) iecFrameLength;
893     status = DIB_FTABLE_reset (device,NULL);
894     if (status)
895         return status;
897     return status;
898 } // DIB_open
900 // -----------------------------------------------------------------------------
901 // Although this is void it is still needed since BIOS calls all DEV inits on
902 // startup.
904 Void DIB_init (Void)
906 } // DIB_init
908 // -----------------------------------------------------------------------------
909 // Notes:
910 //   1. DIB_reset is called prior to this function being called.(see DIB_reclaim)
911 //   2. (1) ==> sizeofBuffer is an integral # of 2byte samples.
912 //   3. (2) ==> if we use a request size which is divisor of sizeofBuffer there
913 //              will be no wrap-around when requesting data for scanning.
914 //   4. (3) ==> we meet the interface requirement for syncScan which has no
915 //              circular arithmetic.
917 Int DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
919     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
920     DEV2_Handle             pChild = (DEV2_Handle)&pDevExt->child;
921     int status;
922     Uns timeout,  syncBufSize, syncRequestSize;
923     Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
924     Int deliverZeros;
926     //..........................................................................
928     // implement local timeout so that we don't get 'stuck' here when input
929     // is all zeros + lock
930     if (pDevExt->syncState == SYNC_NONE) {
931         Uns localTimeout;
932         // latch value before resetting to PAF_SOURCE_UNKNOWN
933         Int sourceProgram = pDevExt->sourceProgram;
935         pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
937         // if here then guaranteed to have fresh reset
939         if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
940             pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
941             timeout = 0;
943             // no zero run counting in force modes since no scanning
944             pBufConfig->pBufStatus->zeroRun = 0;
945             pDevExt->zeroCount = 0;
946         }
947         else if ((pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO) &&
948                  ((sourceProgram == PAF_SOURCE_UNKNOWN) || (sourceProgram == PAF_SOURCE_PCM))) {
949             // if sourceselect is PCMAUTO then
950             //    if current input is a bistream then scan for normal timeout period
951             //    if current input is unknown or PCM then transition immediately to PCM
952             // this provides for *no* lossed PCM, detection of bitstreams, but some noise
953             // is possible.
954             timeout = 0;
955             pDevExt->zeroCount = 0;
956         }
957         else
958             timeout = 2*pBufConfig->pBufStatus->unknownTimeout;
960         // force request size to be a divisor of sizeofBuffer
961         syncRequestSize = NOMINAL_XFERSIZE;
962         if (pBufConfig->stride > 2)
963             syncRequestSize *= pBufConfig->stride;
964         syncBufSize = pBufConfig->sizeofBuffer / ((int) (pBufConfig->sizeofBuffer/syncRequestSize));
966         if (timeout) {
967             status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
968             if (status)
969                 return status;
970         }
972         localTimeout = timeout;
973         while ((timeout) && (pDevExt->syncState != SYNC_ONE)) {
975             status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
976             if (status)
977                 return status;
979             // get next block of data to scan
980             status = DIB_FTABLE_waitForData (device, pBufConfig, syncBufSize);
981             if (status)
982                 return status;
984             // this function updates the tail pointer
985             status = DIB_FTABLE_syncScan (device, pBufConfig, &timeout);
986             if (status)
987                 return status;
989             // if input is zero, i.e. haven't decremented at all,
990             // then break out and use more logic and
991             if (localTimeout < syncBufSize) {
992                 // Should this be 2 *? MAW
993                 if (timeout == 2*pBufConfig->pBufStatus->unknownTimeout)
994                     break;
995             }
996             else
997             {
998                 Log_info3("DIB: Inside DIB_getSync with syncState != SYNC_ONE. localTimeout = %d, syncBufSize  = %d, timeout = %d", localTimeout,syncBufSize, timeout); // GJ Debug
999                 localTimeout -= syncBufSize;
1000             }
1001         }
1003         // if found sync then return to caller who will call 
1004         // initFrame to get bitstream info and requestFrame for data
1005         if (pDevExt->syncState != SYNC_NONE)
1006             return 0;
1008     } //pDevExt->syncState == SYNC_NONE
1010     //..........................................................................
1012     // set default to zero -- we assume decode calls will not be made
1013     // before data is available since this must be master input. Will be changed below
1014     // as needed
1015     deliverZeros = 0;
1017     if (pDevExt->syncState == SYNC_AUTO) {
1018         timeout = pDevExt->pcmTimeout;
1019         deliverZeros = 1;
1020     }
1022     // if in zero run, and heeding full zeroRun control, then return to unknown if # zeros > trigger/Restart
1023     if (ibMode == MODE_DEFAULT) {
1024         if ((pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) ||
1025             (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunRestart))
1026             return DIBERR_SYNC;
1027         // since we may have exited prematurely above we check timeout
1028         if (timeout)
1029             return DIBERR_SYNC;
1030     }
1031     // if heeding trigger but not restart then enter deliverZeros state of PCM
1032     else if (ibMode == MODE_NO_ZERORUNRESTART) {
1033         if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1034             deliverZeros = 1;
1035     }
1037     // here if timeout to PCM (includes force PCM)
1038     status = DIB_FTABLE_reset (device, pBufConfig);
1039     if (status)
1040         return status;
1042     // hack -- try 32bit then 16bit if necessary
1043     pBufConfig->sizeofElement = 4;
1044     status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1045     if(status) {
1046         pBufConfig->sizeofElement = 2;
1047         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1048         if(status)
1049             return status;
1050     }
1052     // Force sizeofBuffer to be integral number of frame sizes. This ensures that the
1053     // pcm buffers will not need a circular wrap-around. We prevent this because
1054     // syncScan makes this assumption in order to perform an efficient scan.
1055     {
1056         int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride*pDevExt->pcmFrameLength;
1057         pBufConfig->sizeofBuffer = (pBufConfig->allocation)/sizeofStride*sizeofStride;
1058     }
1060     if (pDevExt->sourceSelect == PAF_SOURCE_DSD1 || pDevExt->sourceSelect == PAF_SOURCE_DSD2 ||
1061         pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1062         pDevExt->sourceProgram = pDevExt->sourceSelect;
1063     else
1064         pDevExt->sourceProgram = PAF_SOURCE_PCM;
1066     if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
1067         pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
1068         pDevExt->syncState = SYNC_PCM_FORCED;
1069         // set to one -- ensures that PCM decode calls made before data is
1070         // available will result in zero output.
1071         // (mostly needed for PA15 since, currently, all other frameworks
1072         // require a frame of data before the first decode call.
1073         deliverZeros = 1;
1074     }
1075     else
1076         pDevExt->syncState = SYNC_PCM;
1078     // update config struct
1079     pBufConfig->deliverZeros = deliverZeros;
1081     //..........................................................................
1083     return 0;
1084 } // DIB_getSync
1086 // -----------------------------------------------------------------------------
1088 int gWrapCtr=0;
1089 Int DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig  *pBufConfig, int size, int forTotal)
1091     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *) device->object;
1092     DEV2_Handle             pChild  = (DEV2_Handle) &pDevExt->child;
1093     int                    bufEnd  = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1094     DEV2_Frame             *dstFrame;
1095     int                    futureHead, status;
1096     int                    i, sizes[2];
1097     Ptr                    endAddr[2];
1098    
1101     // if seeking for total amount then adjust for difference
1102     if (forTotal) 
1103         size -= GetFutureAvail (pBufConfig);
1105     // return success if we needn't make any requests
1106     if (size <= 0)
1107         return 0;
1109     // assume if eight channel then using optimized dMAX routine which requires
1110     // requests which are a mulitple of 8 to operate correctly. If not a proper
1111     // multiple then we increase the requested size as needed. This information
1112     // is communicated to other portions of DIB indirectly through the update
1113     // of the futureHead pointer (here) and head pointer (in reclaim). To these
1114     // other portions it is a don't care as we ensure enough data requested will
1115     // be available at, the now slightly deferred, reclaim point. We assume that
1116     // the buffer is a multiple of 8 and so, by using this single statement, we
1117     // ensure all requests are a mulitple 8 even if they need to be split across
1118     // the buffer wrap point.
1119     if (pBufConfig->stride == 8)
1120         size = (size + 7) & ~0x7;
1122     // convert to bytes
1123     size *= pBufConfig->sizeofElement;
1124     //size *= 4;
1126     // if request crosses circular buffer boundary then split into two requests
1127     futureHead = (int) pBufConfig->futureHead.pVoid + size;
1128     if (futureHead <= bufEnd) {
1129         sizes[0] = size;
1130         sizes[1] = 0;
1132         // If this request happens to be the rest of the buffer, then 
1133         // futureHead must be set to the beginning of the buffer.
1134         if (futureHead != bufEnd)
1135             endAddr[0] = (Ptr) futureHead;
1136         else
1137             endAddr[0] = pBufConfig->base.pVoid;
1138     }
1139     else {
1140         sizes[0] = bufEnd - (int) pBufConfig->futureHead.pVoid;
1141         sizes[1] = futureHead - bufEnd;
1142         endAddr[0] = pBufConfig->base.pVoid;
1143         endAddr[1] = (Ptr) ((int)pBufConfig->base.pVoid + sizes[1]);
1144     }
1146     for (i=0; i < 2; i++) {
1147         if (sizes[i]) {
1148             dstFrame = Queue_get (Queue_handle(&((SIO2_Handle) pChild)->framelist));
1149             if (dstFrame == (DEV2_Frame *)&((SIO2_Handle) pChild)->framelist)
1150                 return DIBERR_UNSPECIFIED;
1151             dstFrame->arg = (Arg) pBufConfig;
1153             dstFrame->addr = pBufConfig->futureHead.pVoid;
1154             dstFrame->size = sizes[i];
1155             Queue_put (pChild->todevice, (Queue_Elem *)dstFrame);
1156             status = DEV2_issue (pChild);
1157             if (status)
1158                 return DIBERR_UNSPECIFIED;
1160             pBufConfig->futureHead.pVoid = endAddr[i];
1161             // GJ Debug
1162             if (i==1)
1163             {
1164                 gWrapCtr++;
1165                 Log_info4("DIB: Inside DIB_issueChild Wrap Around Point #%d, with Future Head: 0x%x, current addr: 0x%x, current size: %d", gWrapCtr, pBufConfig->futureHead.pVoid, dstFrame->addr, dstFrame->size ); // GJ Debug
1167             }
1168         }
1169     }
1171     return 0;
1172 } // DIB_issueChild
1174 // -----------------------------------------------------------------------------
1176 Int DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1178     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1179     DEV2_Handle              pChild = (DEV2_Handle)&pDevExt->child;
1180     DEV2_Frame              *srcFrame;
1181     int                     status, bufEnd;
1183     //Log_info3("DIB_reclaimChild.%d: Inside DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim); // GJ Debug
1184     //TRACE((&TR_MOD, "DIB_reclaimChild.%d: calling DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim));
1185     status = DEV2_reclaim (pChild);
1186     if (status)
1187     {
1188         Log_info2("DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED", __LINE__, status); // GJ Debug
1189         //TRACE((&TR_MOD, "DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED \n", __LINE__, status));
1190         return DIBERR_UNSPECIFIED;
1191     }
1193     //Log_info1("DIB_reclaimChild.%d calling Queue_get()", __LINE__); // GJ Debug
1194     //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_get()\n", __LINE__));
1195     srcFrame = Queue_get (pChild->fromdevice);
1196     //Log_info2("DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x", __LINE__, srcFrame); // GJ Debug
1197     //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x\n", __LINE__, srcFrame));
1198     Queue_put (Queue_handle(&((SIO2_Handle) pChild)->framelist), (Queue_Elem *)srcFrame);
1200     // Only for non-fill requests do we update ptrs
1201     if (srcFrame->addr != NULL) {
1202         //Log_info2("DIB_reclaimChild.%d update pointers with srcFrame->size = %d", __LINE__, srcFrame->size); // GJ Debug
1203         //TRACE((&TR_MOD, "DIB_reclaimChild.%d update pointers\n", __LINE__));
1204         pBufConfig->head.pVoid = (Ptr) ((int)srcFrame->addr + srcFrame->size);
1206         // wrap, if necessary
1207         bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1208         if( (int) pBufConfig->head.pVoid >= bufEnd )
1209         {
1210             Log_info1("DIB_reclaimChild.%d wrap pointer", __LINE__); // GJ Debug
1211             //TRACE((&TR_MOD, "DIB_reclaimChild.%d wrap pointer\n", __LINE__));
1212             pBufConfig->head.pVoid = (Ptr) ((int) pBufConfig->base.pVoid + (int) pBufConfig->head.pVoid - bufEnd);
1213         }
1214     }
1216     Log_info2("DIB_reclaimChild.%d exit with status = %d", __LINE__, status); // GJ Debug
1217     //TRACE((&TR_MOD, "DIB_reclaimChild.%d exit with status = %d\n", __LINE__, status));
1219     return status;
1220 } // DIB_reclaimChild
1222 // -----------------------------------------------------------------------------
1223 // This function uses the local definition of frameLength and lengthofData in
1224 // pDevExt to request the next frame of data.
1226 Int DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1228     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1229     int status = 0;
1232     // if in steady state then update tail pointer to indicate we are done, i.e. no
1233     // longer own, the last frame of data.
1234     if (pDevExt->running > 1)
1235         IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
1237     switch (pDevExt->syncState) {
1238         case SYNC_PCM:
1239         case SYNC_PCM_FORCED:
1240                     
1241             if (pDevExt->sourceSelect == PAF_SOURCE_DSD1)
1242                 pDevExt->frameLength = 256;
1243             else if (pDevExt->sourceSelect == PAF_SOURCE_DSD2)
1244                 pDevExt->frameLength = 128;
1245             else if (pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1246                 pDevExt->frameLength = 64;
1247             else
1248                 pDevExt->frameLength = pDevExt->pcmFrameLength;
1250             pDevExt->lengthofData = pBufConfig->stride*pDevExt->frameLength;
1251             pDevExt->frameLength  = pDevExt->lengthofData;        
1253             // note that the following issueChild
1254             // doesn't *fetch* the data which will next be consumed,
1255             // but rather *replenishes* what's about to be consumed
1256             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1257             break;
1259         case SYNC_ONE:
1260             // for the first issue we need to set the tail pointer to the bitstream sync
1261             pBufConfig->pntr = pDevExt->pSync;
1262             IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
1263             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->frameLength, 1);
1265             // HD codecs need extra time due to several factors
1266             //   time between first info call and starting output is non-negligible
1267             //   peak decoder MIPs
1268             //   reset time for decoders/ASPs
1269             if ((pDevExt->sourceProgram == PAF_SOURCE_DDP)   ||
1270                 (pDevExt->sourceProgram == PAF_SOURCE_DTSHD) ||
1271                 (pDevExt->sourceProgram == PAF_SOURCE_THD)   ||
1272                 (pDevExt->sourceProgram == PAF_SOURCE_DXP))
1273                 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1275             pDevExt->syncState = SYNC_ONGOING;
1276             break;
1278         case SYNC_ONGOING:
1279             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1280             break;
1282     } //switch
1284     // update bufConfig with info for use in next reclaim call
1285     // the interface to DIB is based on a single frame. So the amount
1286     // of data requested in this issue is assumed to be what is wanted in the next
1287     // reclaim.
1288     pBufConfig->frameLength  = pDevExt->frameLength;
1289     pBufConfig->lengthofData = pDevExt->lengthofData;
1290     // enable to inspect input buffer.
1291     // if (pDevExt->lengthofData > 512)
1292     //     asm( " SWBP 0" );  // breakpoint
1295     if (pDevExt->running < 3)
1296         pDevExt->running++;
1298     // Goal is to align timing so synchronized with forthcoming
1299     // "DIB_waitForData (... pDevExt->lengthofData);"
1300     // in DIB_reclaim(), servicing PAF_SIO_REQUEST_NEWFRAME, for PAF_SOURCE_PCM/DSD?.
1301     // ** need to revise above DSD handling so it works w/ this calc. **
1302     {
1303         int futureAvail = GetFutureAvail (pBufConfig);
1304         // GetFutureAvail() returns 0 if full buffer requested or if no requests outstanding
1305         // -- 0 (empty) can't be right interpretation here, on account of foregoing issueChild()
1306         if( ! futureAvail)
1307             futureAvail = pBufConfig->sizeofBuffer / pBufConfig->sizeofElement; // total words in buffer
1308         pDevExt->numSamplesExtra = (XDAS_Int16) (futureAvail - pDevExt->frameLength);
1309     }
1311     return status;
1312 } // DIB_requestFrame
1314 // -----------------------------------------------------------------------------
1316 Int DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1318     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1319     DEV2_Handle              pChild = (DEV2_Handle)&pDevExt->child;
1320     int status, numChan;
1323     //?? Do we need a shutdown to handle queue problems?
1324     // or are there no problems since we use one frame
1325     status = DEV2_idle (pChild, 1);
1326     if(status)
1327         return status;
1329     if (pBufConfig) {
1330         int sizeofStride;
1331         pBufConfig->pntr       = pBufConfig->base;
1332         pBufConfig->head       = pBufConfig->base;
1333         pBufConfig->futureHead = pBufConfig->base;
1335         pBufConfig->lengthofData = 0;
1337         //devices must? support 2byte words
1338         pBufConfig->sizeofElement = 2;
1339         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1340         if(status)
1341             return status;
1343         status = DEV2_ctrl (pChild, PAF_SIO_CONTROL_GET_NUMCHANNELS, (Arg) &numChan);
1344         if(status)
1345             return status;
1346         pBufConfig->stride = numChan;
1348         // compute and use *effective buffer size*
1349         sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
1350         pBufConfig->sizeofBuffer = (pBufConfig->allocation)/sizeofStride*sizeofStride;  //GJ: Debug - Account for EDMA padding
1352         //hack -- save status context for use in close
1353         pDevExt->pInpBufStatus = pBufConfig->pBufStatus;
1354         pBufConfig->pBufStatus->lastFrameFlag = 0;
1356         pDevExt->bufConfig = *pBufConfig;
1357         pDevExt->pSync = pBufConfig->base;
1358     }
1360     pDevExt->syncState = SYNC_NONE;
1361     pDevExt->scanState = SCANNED_NONE;
1362     pDevExt->pcmTimeout = 0;
1363     pDevExt->deferredError = 0;
1365     pDevExt->numSamplesSinceDTS = 0;
1366     pDevExt->numSamplesExtra = 0;
1368     pDevExt->headerSize = 0;
1369     pDevExt->running = 0;
1371     return 0;
1372 } // DIB_reset
1374 // -----------------------------------------------------------------------------
1375 // Notes:
1376 //   1. The amount of data to be scanned will not result in a buffer wrap-around
1377 //   2. (1) is currently met from the two locations that call this function
1378 //          a. DIB_getSync
1379 //          b. DIB_reclaim (for PCM)
1380 //   3. We require that pTimeout != NULL since we dereference to make a const
1382 Int DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout)
1384     DIB_DeviceExtension   * restrict pDevExt = (DIB_DeviceExtension *)device->object;
1385     MdInt * restrict pTail, * restrict pShadowTail, * restrict pSync;
1386     MdInt *pLocalTail, pc;
1387     XDAS_Int8   scanState;
1388     XDAS_UInt32 zeroCount;
1389     int stride, numLeft, i, datId;
1390     int status, foundDTS = 0;
1391     Uns scanCount, pageSize;
1392     PAF_SIO_IALG_Obj    *pObj = pDevExt->pSioIalg;
1393     PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1394     const int timeoutChanged = (*pTimeout != 2 * pBufConfig->pBufStatus->unknownTimeout);
1395     MdInt DTSHDSubType;
1397     // .........................................................................
1399     // works for both SYNC_NONE and SYNC_PCM
1400     numLeft = min (*pTimeout, GetNumAvail(pBufConfig));
1402     pTail = pBufConfig->pntr.pMdInt;
1403     pShadowTail = pBufConfig->pntr.pMdInt;
1405     // if scratch buffer present then assume it is needed for paging
1406     pageSize = numLeft*pBufConfig->sizeofElement;
1408     Log_info3("DIB: Entered DIB_syncScan with pTail = 0x%x & numLeft = %d, timeout = %d", pTail, numLeft, *pTimeout); // GJ Debug
1411     if ((pAlgConfig->numRec > 1) && pAlgConfig->pMemRec[1].base && (pAlgConfig->pMemRec[1].size >= pageSize)) {
1412         pTail = pAlgConfig->pMemRec[1].base;
1413         datId = DAT_copy ((void *) pShadowTail, (void *) pTail, pageSize);
1414         DAT_wait (datId);
1415     }
1417     if (pBufConfig->sizeofElement == 4) {
1418         Log_info0("DIB: SyncScan - Inside pBufConfig->sizeofElement == 4"); // GJ Debug
1419         stride = 2;
1420         pTail += 1; // point at MSB
1421         pShadowTail += 1;
1422     }
1423     else
1424         stride = 1;
1426     // .........................................................................
1428     // scan until out of available data or a sync found
1429     scanCount = 0;
1430     zeroCount = pDevExt->zeroCount;
1431     scanState = pDevExt->scanState;
1432     pSync     = pDevExt->pSync.pMdInt;
1434     Log_info4("DIB: Entered DIB_syncScan with zeroCount = %d & scanState = %d, stride = %d, pSync = 0x%x", zeroCount, scanState, stride, pSync); // GJ Debug
1436     // scan until out of available data or a sync found
1437     for (i=0; i < numLeft; i++) {
1438         MdInt tail = pTail[i*stride];
1440         // assumes SCANNED_NONE = 0
1441         if (!scanState) {
1442             if (tail == IEC_PA) {
1443                 // since above code handles ongoing sync we are
1444                 //  safe to check for extended sync here. i.e.
1445                 //  two zeros before PA.
1446                 if (zeroCount >= 2) {
1447                     scanState = SCANNED_IEC_PA;
1448                     pSync = &pShadowTail[i*stride];
1449                 }
1450             }
1451             else if (tail == DTS14_SYNC_A) {
1452                 scanState = SCANNED_DTS14_SYNC_A;
1453                 pSync = &pShadowTail[i*stride];
1454             }
1455             else if (tail == DTS16_SYNC_A) {
1456                 scanState = SCANNED_DTS16_SYNC_A;
1457                 pSync = &pShadowTail[i*stride];
1458             }
1460             // limit count to prevent wrap around
1461             zeroCount = min (zeroCount+1,INT_MAX - 1);
1462             if (tail != 0x0000)
1463                 zeroCount = 0;
1465             // don't start counting until we get the first non-zero
1466             // sample while UNKNOWN. Note we don't have to worry
1467             // about the other scanCount increments since these
1468             // only occur after the first non-zero sample.
1469             //
1470             // so don't count unless
1471             //    . we are already started counting (in this call) ||
1472             //    . we started counting in an earlier scanForSync (timeout has changed) ||
1473             //    . the last sample was non-zero
1474             if (scanCount || (tail != 0x0000) || timeoutChanged)
1475             {
1476                 //Log_info3("DIB: DIB_syncScan scanCount = %d tail = %d timeoutChanged = %d", scanCount, tail, timeoutChanged); // GJ Debug
1477                 scanCount += 1;
1478             }
1481             continue;
1482         }
1484         // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1486         switch (scanState) {
1488             case SCANNED_DTS16_SYNC_A:
1489                 if (tail == DTS16_SYNC_B) {
1490                     scanState = SCANNED_DTS16_SYNC_B;
1491                     scanCount += 1;
1492                 }
1493                 else
1494                     scanState = SCANNED_NONE;
1495                 break;
1497                 // wait for header data to get payload size via
1498                 // nblks/fsize
1499             case SCANNED_DTS16_SYNC_B:
1500                 // use extended sync
1502                 if ((short)(tail & 0xFC00) == DTS16_SYNC_C) {
1503                     scanState = SCANNED_DTS16_SYNC_C;
1504                     scanCount += 1;
1505                 }
1506                 else
1507                     scanState = SCANNED_NONE;
1508                 break;
1510                 // `````````````````````````````````````````````````````````````````````````
1511                 // check for 2nd word of DTS-14 sync
1512             case SCANNED_DTS14_SYNC_A:
1513                 if (tail == DTS14_SYNC_B) {
1514                     scanState = SCANNED_DTS14_SYNC_B;
1515                     scanCount += 1;
1516                 }
1517                 else
1518                     scanState = SCANNED_NONE;
1519                 break;
1521                 // check for 3rd word of DTS-14 sync
1522             case SCANNED_DTS14_SYNC_B:
1523                 // if here then looking for extended 38 bit sync
1524                 if ((short)(tail & 0xFFF0) == DTS14_SYNC_C) {
1525                     scanState = SCANNED_DTS14_SYNC_C;
1526                     scanCount += 1;
1527                 }
1528                 else
1529                     scanState = SCANNED_NONE;
1530                 break;
1532                 // wait for header data to get payload size via
1533                 //   nblks/fsize
1534             case SCANNED_DTS14_SYNC_C:
1535                 scanState = SCANNED_DTS14_SYNC_D;
1536                 scanCount += 1;
1537                 break;
1539                 // `````````````````````````````````````````````````````````````````````````
1540                 // if here then all of header is buffered
1541             case SCANNED_DTS16_SYNC_C:
1542             case SCANNED_DTS14_SYNC_D:
1543                 // update sync to point at beginning of DTS header as syncScanDTS uses this info
1544                 pDevExt->scanState    = scanState;
1545                 pDevExt->pSync.pMdInt = pSync;
1546                 status = DIB_FTABLE_syncScanDTS (device, pBufConfig, pTimeout, (XDAS_UInt16 *) &pShadowTail[i*stride]);
1547                 scanState = pDevExt->scanState;
1548                 if (status)
1549                     return status;
1550                 foundDTS = 1;
1551                 if (pDevExt->syncState == SYNC_ONE)
1552                     goto syncScanExit;
1553                 break;
1555                 // `````````````````````````````````````````````````````````````````````````
1557                 // note that the round about detection of IEC only
1558                 // happens for the first sync so the extra states are OK.
1559             case SCANNED_IEC_PA:
1560                 if (tail == IEC_PB) {
1561                     scanState = SCANNED_IEC_PB;
1562                     scanCount += 1;
1563                     Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - if path"); // GJ Debug
1564                 }
1565                 else
1566                 {
1567                     Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - else path"); // GJ Debug
1568                     scanState = SCANNED_NONE;
1569                 }
1570                 break;
1572             case SCANNED_IEC_PB:
1573                 // Update scanCount here since, at this point, we are confident that
1574                 // this is a proper IEC stream. Regardless if we ignore it our not.
1575                 // Therefore we want to properly signal that this data has been scanned.
1576                 scanCount += 1;
1578                 // check for IEC pause packets at this time and if required ignore them.
1579                 // By construction we are guaranteed to have tail=PC at this time.
1580                 if ((pBufConfig->pBufStatus->mode == MODE_NO_ZERORUNRESTART) ||
1581                     (pBufConfig->pBufStatus->mode == MODE_NO_ZERORUN)) {
1582                     MdInt pc = tail & 0x1F;
1584                     if ((pc == 0) || (pc == 3)) {
1585                         scanState = SCANNED_NONE;
1586                         break;
1587                     }
1588                 }
1590                 scanState = SCANNED_IEC_PC;
1591                 break;
1593             case SCANNED_IEC_PC:
1594                 pLocalTail = pSync;
1595                 IncrementPtr (pBufConfig, (Ptr *)  &pLocalTail, 2);
1596                 pc = *pLocalTail & 0x1F;
1597                 pDevExt->headerSize = IEC_HEADER_SIZE;
1599                 Log_info0("DIB: Sync Scan - Inside case: SCANNED_IEC_PC"); // GJ Debug
1600                 // Handle DTSHD subtype (LBR)
1601                 if (pc == 0x11) {
1602                     pDevExt->headerSize +=6;
1603                     DTSHDSubType = (*pLocalTail & 0x700)>>8;
1604                 }
1605                 // DDP or THD
1606                 if (pc == 21 || pc ==22) {
1607                     TRACE((&TR_MOD, "Dolby: useIECSubType is 0x%x.\n", pBufConfig->pBufStatus->useIECSubType));
1608                     if (pBufConfig->pBufStatus->useIECSubType == 1) {
1609                         unsigned char IECSubType = *pLocalTail & 0x60;
1610                         TRACE((&TR_MOD, "Dolby: IECSubType is 0x%x.\n", IECSubType));
1611                         if (IECSubType != 0) {
1612                             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
1613                             pDevExt->frameLength = 0;
1614                         }
1615                     }
1616                 }
1617                 // don't know how to support other types
1618                 if (pc > 22)
1619                 {
1620                     Log_info1("DIB:  Unknown IEC type 0x%x encountered.\n", pc); // GJ Debug
1621                     return DIBERR_SYNC;
1622                 }
1624                 pDevExt->syncState = SYNC_ONE;
1625                 pBufConfig->pntr.pMdInt = pSync;
1626                 pDevExt->sourceProgram = iecPafSource[pc];
1628                 Log_info2("source is %d.  pc is %d.", iecPafSource[pc], pc); // GJ Debug 
1629                 //TRACE((&TR_MOD, "source is %d.  pc is %d.\n", iecPafSource[pc], pc));
1631                 if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
1632                     pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
1633              
1634                 pDevExt->frameLength = pDevExt->pIECFrameLength[pc];
1635                 pDevExt->lengthofData = pDevExt->frameLength;
1636                 if (pc == 1)
1637                     pDevExt->frameLength = 4288;
1638                 else if (pc == 0x11) {
1639                     pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
1640                     pDevExt->lengthofData = pDevExt->frameLength;
1641                 }
1643                 goto syncScanExit;
1645         } // switch
1646     } // for
1648     // .............................................................................
1650 syncScanExit:
1651     Log_info4("DIB inside syncScanExit.  pTimeout = %d, scanCount = %d, zeroCount = %d, numLeft = %d", *pTimeout,scanCount, zeroCount, numLeft ); // GJ Debug
1652     pDevExt->zeroCount    = zeroCount;
1653     pDevExt->scanState    = scanState;
1654     pDevExt->pSync.pMdInt = pSync;
1656     if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1657         pBufConfig->pBufStatus->zeroRun = 1;
1658     else
1659         pBufConfig->pBufStatus->zeroRun = 0;
1661     // If detected an initial DTS sync in a previous buffer then add the
1662     // number of samples in this buffer to the tally.
1663     // TODO: should we add numLeft instead of lengthofData?
1664     if (!foundDTS && pDevExt->numSamplesSinceDTS)
1665         pDevExt->numSamplesSinceDTS += pBufConfig->lengthofData;
1667     if (*pTimeout > scanCount)
1668         *pTimeout -= scanCount;
1669     else {
1670         *pTimeout = 0;
1671         return 0;
1672     }
1674     // This flushes the current scanned buffer if a sync is not found
1675     // Note that this code is not executed when *pTimeout = 0. 
1676     // TODO: should this be moved elsewhere. Like in requestFrame?
1677     //       seems like this should be done in request frame for continuous modes
1678     //       and in getSync for traditional modes.
1679     //       What does it mean that this is not executed when we have timed out to PCM
1680     if (pDevExt->syncState == SYNC_NONE || pDevExt->syncState == SYNC_AUTO) {
1681         IncrementPtr (pBufConfig, (Ptr *) &pBufConfig->pntr.pMdInt, numLeft);
1682         return 0;
1683     }
1685     return 0;
1686 } // DIB_syncScan
1688 // -----------------------------------------------------------------------------
1689 // Assumes scanState is SCANNED_DTS16_SYNC_C or SCANNED_DTS14_SYNC_D
1691 Int DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd)
1693     DIB_DeviceExtension  *pDevExt = (DIB_DeviceExtension *)device->object;
1694     Int sourceProgram = (pDevExt->scanState == SCANNED_DTS14_SYNC_D) ? PAF_SOURCE_DTS14  : PAF_SOURCE_DTS16;
1695     float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
1696     MdInt *pLocalTail, pc, pd;
1697     int nblks;
1700     // compute repetition rate as predicted by DTS header
1701     pLocalTail = pDevExt->pSync.pMdInt;
1702     IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1703     pc = *pLocalTail;
1704     if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1705         nblks = (pc & 0x01FC) >> 2;
1706     else {
1707         IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 1);
1708         pd = *pLocalTail;
1709         nblks = (pc & 0x7) << 4;
1710         nblks |= (pd & 0x3C00) >> 10;
1711     }
1713     // if samplerate > 44.1k and DTS16 bit CD then report as DTS-DVD
1714     // this is a work around to the possibility that DTS-DVD is being
1715     // sent but, due to the variance in input recording, we may have
1716     // missed the IEC header. This is predicated on the enable register
1717     if (pBufConfig->pBufStatus->reportDTS16AsDTSForLargeSampleRate &&
1718         (sampleRate > 44100) && (sourceProgram == PAF_SOURCE_DTS16))
1719         sourceProgram = PAF_SOURCE_DTS;
1721     // point at LSB, if neceesary, so that space calculation is correct
1722     if (pBufConfig->sizeofElement == 4)
1723         pHeaderEnd -= 1;
1725     // If in PCM mode then require double sync, at an appropriate spacing,
1726     // in order to determine DTS validity.
1727     if (pDevExt->syncState == SYNC_PCM) {
1728         int diff;
1730         // If we have started counting, i.e. found a previous sync,
1731         // then compute sync spacing.
1732         if (pDevExt->numSamplesSinceDTS) {
1733             // determine distance since last sync
1734             //    pHeaderEnd, which points at the end of the DTS header, is guaranteed
1735             //    to be in the active buffer. Whereas the pointer to the beginning of the header (pSync)
1736             //    may have occured in the previous buffer.
1737             diff = ((int) pHeaderEnd - (int) pBufConfig->pntr.pVoid);
1738             if (diff < 0)
1739                 diff += pBufConfig->sizeofBuffer;
1740             diff /= pBufConfig->sizeofElement;
1741             diff += pDevExt->numSamplesSinceDTS;
1743             // if spacing incorrect then reset sample count to
1744             // force next conditional to be true.
1745             if (diff != (nblks+1)*32*2)
1746                 pDevExt->numSamplesSinceDTS = 0;
1747         }
1749         // If this is the 1st sync detected or if this is the second sync
1750         // but the spacing between DTS syncs did not match that predicted by
1751         // NBLKS, then this is not DTS data. Therefore the previous DTS sync
1752         // word was not valid and so it is safe to reset the count based on
1753         // this secondary sync word. This latter sync may or may not be valid;
1754         // we don't know yet. In both cases init sync spacing count, reset
1755         // scan state, and continue. Note that there is a positive, albeit
1756         // quite small, probability of falsing in a pathological case where
1757         // the PCM data, interpreted as a DTS header and used to compute NBLKS,
1758         // actually matches the fake DTS syncs in the PCM file.
1759         if (!pDevExt->numSamplesSinceDTS) {
1760             diff = (int) pBufConfig->head.pVoid - (int) pHeaderEnd;
1761             if (diff <= 0)
1762                 diff += pBufConfig->sizeofBuffer;
1763             diff /= pBufConfig->sizeofElement;
1764             pDevExt->numSamplesSinceDTS = diff;
1765             pDevExt->scanState = SCANNED_NONE;
1766             return 0;
1767         }
1768     } //SYNC_PCM
1770     pDevExt->lengthofData = (nblks+1)*32*2;
1771     if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1772         pDevExt->frameLength = pDevExt->lengthofData + 4;
1773     else
1774         pDevExt->frameLength = pDevExt->lengthofData + 6;
1776     pDevExt->syncState = SYNC_ONE;
1777     pBufConfig->pntr = pDevExt->pSync;
1778     pDevExt->sourceProgram = sourceProgram;
1780     return 0;
1781 } //DIB_syncScanDTS
1783 // -----------------------------------------------------------------------------
1784 // This function is responsible for verifying bitstream sync (if applicable) and
1785 // configuring the sizes of the next frame of data.
1787 Int DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1789     DIB_DeviceExtension  * restrict pDevExt = (DIB_DeviceExtension *) device->object;
1790     MdInt * restrict pTail;
1791     MdInt pa, pb, pc;
1792     unsigned char DTSHDSubType;
1793     PAF_UnionPointer     ac3SearchPtr;
1796     // MID 810
1797     // TODO: is this needed anymore? can we combine above and this?
1798     // I don't think this is needed since pSync is guaranteed to be
1799     // valid under all cases where this function is called.
1800     if (!(pDevExt->scanState == SCANNED_DTS14_SYNC_D ||
1801           pDevExt->scanState == SCANNED_DTS16_SYNC_C ||
1802           pDevExt->scanState == SCANNED_IEC_PC ))
1803         return 0;
1805     // minimum possible distance from current IEC sync to next is 1856 words
1806     // capture this here before we update pSync following
1807     ac3SearchPtr = pDevExt->pSync; 
1809     // for steady state compute expected sync location
1810     if (pDevExt->syncState == SYNC_ONGOING) 
1811         IncrementPtr (pBufConfig, &pDevExt->pSync.pVoid, pBufConfig->lengthofData);
1813     pTail = pDevExt->pSync.pMdInt;
1814     pa = *pTail;
1815     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1816     pb = *pTail;
1817     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1818     pc = *pTail;
1819     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1821     switch (pDevExt->scanState) {
1822         // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1824         case SCANNED_DTS14_SYNC_D:
1825             // check sync (extended sync checked above for 1st sync)
1826             if ((pa != DTS14_SYNC_A) || (pb != DTS14_SYNC_B) || ((pc & 0xFC00) != (DTS14_SYNC_C & 0xFC00)))
1827                 return DIBERR_SYNC;
1828             break;
1830             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1832         case SCANNED_DTS16_SYNC_C:
1833             // check sync (extended sync checked above for 1st sync)
1834             if ((pa != DTS16_SYNC_A) || (pb != DTS16_SYNC_B))
1835                 return DIBERR_SYNC;
1836             break;
1838             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1840         case SCANNED_IEC_PC:
1841             // check for sync
1842             //    special handling for AC3 variable bit rate (VBR)
1843             //       start looking for sync at max payload sync location and
1844             //       scan forward. Note that getSync() has waited for
1845             //       sufficient data to arrive so that we can determine reliably
1846             //       the presence or absence of a correct sync.
1848             if ((pa != IEC_PA) || (pb != IEC_PB)) {
1849                 PAF_SIO_IALG_Obj    *pObj = pDevExt->pSioIalg;
1850                 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1851                 int scan1, scan2, searchIdx, datId;
1852                 const int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1855                 // only extend IEC search in the case of AC3
1856                 if (pDevExt->sourceProgram != PAF_SOURCE_AC3)
1857                     return DIBERR_SYNC;
1859                 // move search ptr to earliest possible location of next sync
1860                 IncrementPtr (pBufConfig, &ac3SearchPtr.pVoid, 1856);
1862                 // compute number of samples between earliest possible sync location
1863                 // (ac3SearchPtr) and latest possible sync location (head)
1864                 scan1 = (int) pBufConfig->head.pVoid - (int) ac3SearchPtr.pVoid;
1865                 if (scan1 < 0) {
1866                     // here if search will wrap around so split search into two
1867                     // halves to accomodate circular buffer
1868                     scan1 = bufEnd - (int) ac3SearchPtr.pVoid;
1869                     scan2 = (int) pBufConfig->head.pVoid - (int) pBufConfig->base.pVoid;
1870                 }
1871                 else
1872                     scan2 = 0;
1874                 // page if necessary (assume so if second memRec present)
1875                 if (pAlgConfig->numRec > 1) {
1876                     // if invalid buffer or if page buffer not big enough for either split then error
1877                     if (!pAlgConfig->pMemRec[1].base ||
1878                         (pAlgConfig->pMemRec[1].size < max(scan1,scan2)))
1879                         return DIBERR_UNSPECIFIED;
1881                     pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1882                     datId = DAT_copy (ac3SearchPtr.pVoid, (void *) pTail, scan1);
1883                     DAT_wait (datId);
1884                 }
1885                 else
1886                     pTail = ac3SearchPtr.pMdInt;
1888                 // convert to number of words
1889                 scan1 /= pBufConfig->sizeofElement;
1891                 // if non-zero must be IEC header, otherwise sync error
1892                 // update pointer after check so that it remains
1893                 // pointed at first non-zero word when breaking
1894                 searchIdx = 0;
1895                 while (scan1--) {
1896                     if (*pTail != 0) {
1897                         // force skip of any possible split scan since we found non-zero word
1898                         scan2 = 0;
1899                         break;
1900                     }
1901                     *pTail++;
1902                     searchIdx++;
1903                 }
1905                 // perform second half of circular buffer search if necessary
1906                 if (scan2) {
1907                     // page if necessary, note no need to check valid buffer
1908                     // or space since this is ensured in first scan
1909                     if (pAlgConfig->numRec > 1) {
1910                         pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1911                         datId = DAT_copy (pBufConfig->base.pVoid, (void *) pTail, scan2);
1912                         DAT_wait (datId);
1913                     }
1914                     else
1915                         pTail = pBufConfig->base.pMdInt;
1917                     // convert to number of words
1918                     scan2 /= pBufConfig->sizeofElement;
1920                     while (scan2--) {
1921                         if (*pTail != 0)
1922                             break;
1923                         *pTail++;
1924                         searchIdx++;
1925                     }
1926                 }
1928                 // if using paging buffer then translate search pointer back into circular buffer
1929                 if (pAlgConfig->numRec > 1) {
1930                     pTail = ac3SearchPtr.pMdInt;
1931                     IncrementPtr (pBufConfig, (Ptr *) &pTail, searchIdx);
1932                 }
1934                 // update sync in expection of success, if it is not a sync then no
1935                 // harm since it will be ignored then reset
1936                 pDevExt->pSync.pMdInt = pTail;
1938                 // above search only scans for the first non-zero word.
1939                 // here is common check to make sure that non-zero data is an IEC sync.
1940                 pa = *pTail;
1941                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1942                 pb = *pTail;
1943                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1944                 pc = *pTail;
1945                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1946                 if ((pa != IEC_PA) || (pb != IEC_PB))
1947                     return DIBERR_SYNC;
1948             }
1950             // compute possible DTSHD sub type before masking pc
1951             DTSHDSubType = (pc & 0x700) >> 8;
1953             // mask pc to get data type only
1954             pc = pc & 0x1F;
1956             // don't know how to support other types
1957             // this also ensures that the below array access is bounded
1958             if (pc > 22)
1959                 return DIBERR_SYNC;
1961             // continuing frame must be same as current type otherwise
1962             // we return error to force reset of decode and input
1963             // classification state machines
1964             if (pDevExt->sourceProgram != iecPafSource[pc]) {
1965                 if (DTSHDSubType == 3 &&
1966                     (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <= 48000.0))  {
1967                     if (pDevExt->sourceProgram != PAF_SOURCE_DXP)
1968                         return DIBERR_SYNC;
1969                 }
1970                 else
1971                     return DIBERR_SYNC;
1972             }
1973             break;
1975             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1976     } //switch
1978     return 0;
1979 } // DIB_initFrame
1981 // -----------------------------------------------------------------------------
1983 Int DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count )
1985     DIB_DeviceExtension  *pDevExt = (DIB_DeviceExtension *) device->object;
1986     DEV2_Handle            pChild = (DEV2_Handle) &pDevExt->child;
1987     Int status, lock;
1989     Log_info2("DIB_waitForData.%d count = %d", __LINE__, count); // GJ Debug
1990     //TRACE((&TR_MOD, "DIB_waitForData.%d count = %d\n", __LINE__, count));
1992     while (GetNumAvail(pBufConfig) < count) {
1993         PAF_SIO_InputStatus inputStatus;
1995         // query underlying device for lock status & check lock override register
1996         // dont wait without lock
1997         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS, (Arg) &inputStatus);
1998         if (status)
1999         {
2000             Log_info2("DIB_waitForData.%d SIO2_ctrl() returned %d", __LINE__, status); // GJ Debug
2001             //TRACE((&TR_MOD, "DIB_waitForData.%d SIO2_ctrl() returned %d\n", __LINE__, status));
2002             return status;
2003         }
2004         lock = inputStatus.lock;
2005 #ifndef IGNORE_LOCK_OVERRIDE
2006         if ((pBufConfig->pBufStatus->lockOverride & (XDAS_Int8)0x80) == 0)
2007         {
2008             Log_info1("DIB_waitForData.%d lock = lockOverride\n", __LINE__); // GJ Debug
2009             //TRACE((&TR_MOD, "DIB_waitForData.%d lock = lockOverride\n", __LINE__));
2010             lock = pBufConfig->pBufStatus->lockOverride;
2011         }
2012 #endif
2013         if (!lock)
2014         {
2015             Log_info1("DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__); // GJ Debug
2016             //TRACE((&TR_MOD, "DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__));
2017             return DIBERR_SYNC;
2018         }
2019         // check that decoding still requested -- allows for status
2020         // register to be updated via IOS to cancel autoProcessing
2021         if (pDevExt->pDecodeStatus) {
2022             if (pDevExt->pDecodeStatus->sourceSelect == PAF_SOURCE_NONE)
2023             {
2024                 Log_info1("DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC", __LINE__); // GJ Debug
2025                 //TRACE((&TR_MOD, "DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC\n", __LINE__));
2026                 return DIBERR_SYNC;
2027             }
2028         }
2030         Log_info1("DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()", __LINE__); // GJ Debug
2031         //TRACE((&TR_MOD, "DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()\n", __LINE__));
2032         status = DIB_FTABLE_reclaimChild (device, pBufConfig);
2033         if(status)
2034         {
2035             Log_info2("DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d", __LINE__, status); // GJ Debug
2036             //TRACE((&TR_MOD, "DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d\n", __LINE__, status));
2037             return status;
2038         }
2039     }
2041     return 0;
2042 } // DIB_waitForData
2044 // -----------------------------------------------------------------------------
2045 #ifdef IEC_ENCODE
2047 // FS9 only supports PCM input so return error if not PCM.
2049 Int DIB_requestFrame_957 (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
2051     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *) device->object;
2052     int i, head, tail, avail, status;
2055     if (pDevExt->sourceProgram != PAF_SOURCE_PCM)
2056         return DIBERR_SYNC;
2058     // if in steady state then update tail pointer to indicate we are done, i.e. no
2059     // longer own, the last frame of data. 
2060     if (pDevExt->running > 1)
2061         IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
2063     pDevExt->lengthofData = pBufConfig->stride*pDevExt->pcmFrameLength;
2064     pDevExt->frameLength  = pDevExt->lengthofData;        
2066     // note that due to MID 1037 it is required to check the return status after this call
2067     status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
2068     if (status)
2069         return status;
2071     // add extra input delay to account for peak encoder mips
2072     for (i=0; i < 4; i++) {
2073         head = (int) pBufConfig->futureHead.pVoid;
2074         tail = (int) pBufConfig->pntr.pVoid;
2075         // compute how much data we have including outstanding requests
2076         if (head >= tail)
2077             avail = head - tail;
2078         else
2079             avail = head - tail + pBufConfig->sizeofBuffer;
2081         // convert to words
2082         avail /= pBufConfig->sizeofElement;
2083         if (avail < 4*pBufConfig->lengthofData) {
2084             status = DIB_FTABLE_issueChild (device, pBufConfig, pBufConfig->lengthofData, 0);
2085             if (status)
2086                 return status;
2087         }
2088     }
2090     pBufConfig->frameLength  = pDevExt->frameLength;
2091     pBufConfig->lengthofData = pDevExt->lengthofData;
2093     if (pDevExt->running < 3)
2094         pDevExt->running++;
2096     return 0;
2097 } // DIB_requestFrame_957
2099 #endif /* IEC_ENCODE */
2101 // -----------------------------------------------------------------------------
2103 #ifdef DSD_OVER_SPDIF
2105 Int DIB_requestFrame_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2107     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
2108     int status;
2110     status = DIB_requestFrame (device, pBufConfig);
2111     // For testing DSD over SPDIF i.e. 1 pin vs actual over 6 pin
2112     pDevExt->numSamplesExtra += pDevExt->lengthofData;
2113     pDevExt->lengthofData *=6;
2114     pDevExt->numSamplesExtra -= pDevExt->lengthofData;
2116     return status;
2117 } // DIB_requestFrame
2119 Int DIB_getSync_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2121     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
2122     DEV2_Handle             pChild = (DEV2_Handle)&pDevExt->child;
2123     int status;
2125     status=DIB_getSync (device, pBufConfig );
2126     if(status)
2127         return status;
2129     pBufConfig->sizeofElement = 2;
2130     status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
2131     if (status)
2132         return status;
2134     // compute and use *effective buffer size*
2135     {
2136         int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
2137         pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
2138     }
2139     //..........................................................................
2141     return 0;
2142 } // DIB_getSync_patch
2144 #endif /* DSD_OVER_SPDIF */
2146 // -----------------------------------------------------------------------------