]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - processor-sdk/performance-audio-sr.git/blob - processor_audio_sdk_1_00_00_00/pasdk/test_dsp/mib/mib.c
Fix headers
[processor-sdk/performance-audio-sr.git] / processor_audio_sdk_1_00_00_00 / 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         512 //GJ Debug
289 #define min(a, b)  (((a) < (b)) ? (a) : (b))
290 #define max(a, b)  (((a) > (b)) ? (a) : (b))
292 // -----------------------------------------------------------------------------
294 inline void IncrementPtr (PAF_InpBufConfig *pBufConfig, Ptr *pPtr, int numWords)
296     int addr;
299     addr = (int) *pPtr + numWords*pBufConfig->sizeofElement;
300     if (addr > ((int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer - 1))
301         addr -= pBufConfig->sizeofBuffer;
303     *pPtr = (Ptr) addr;
304     return;
305 } // IncrementPtr
307 // -----------------------------------------------------------------------------
309 inline int GetNumAvail (PAF_InpBufConfig *pBufConfig)
311     int numBytes;
314     if ( (Uns) pBufConfig->head.pVoid >= (Uns) pBufConfig->pntr.pVoid)
315         numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid);
316     else
317         numBytes = ((int)pBufConfig->head.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
319     // return in words
320     return (numBytes / pBufConfig->sizeofElement);
321 } // GetNumAvail
323 // -----------------------------------------------------------------------------
324 // compute how much data we have including outstanding requests
326 inline int GetFutureAvail (PAF_InpBufConfig *pBufConfig)
328     int numBytes;
331     if ( (Uns) pBufConfig->futureHead.pVoid >= (Uns) pBufConfig->pntr.pVoid)
332         numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid);
333     else
334         numBytes = ((int)pBufConfig->futureHead.pVoid - (int)pBufConfig->pntr.pVoid + pBufConfig->sizeofBuffer);
336     // return in words
337     return (numBytes / pBufConfig->sizeofElement);
338 } // GetFutureAvail
340 // -----------------------------------------------------------------------------
342 Int DIB_issue (DEV2_Handle device)
344     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
345     DEV2_Frame             *srcFrame;
346     Int                    status;
347     PAF_InpBufConfig      *pBufConfig;
350     srcFrame = Queue_get (device->todevice);
351     pBufConfig = (PAF_InpBufConfig *) srcFrame->addr;
352     if (!pBufConfig || !pBufConfig->pBufStatus)
353         return SIO2_EINVAL;
355     Queue_put (device->fromdevice, srcFrame);
357     if (srcFrame->arg == PAF_SIO_REQUEST_AUTO) {
359         // if not yet running, prime input buffer
360         if (pDevExt->syncState == SYNC_NONE) {
362             status = DIB_FTABLE_reset (device, pBufConfig);
363             if (status)
364                 return status;
366             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
368             status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
369             if (status)
370                 return status;
372             // * also reset pDevExt->zeroCount, as in DIB_getSync()?
373             // just for PAF_SOURCE_PCMAUTO? *
374             pDevExt->pcmTimeout =
375                 pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO ? 0 :
376                 2 * pBufConfig->pBufStatus->unknownTimeout;
377             pDevExt->syncState = SYNC_AUTO;
379             // allows PCM decoder to be used to generate zero-valued audio frames while scanning
380             pBufConfig->deliverZeros = 1;
381         }
382         // no action if already sync'ed
383         else if (pDevExt->syncState != SYNC_AUTO)
384             return 0;
386         status = DIB_FTABLE_issueChild (device, &pDevExt->bufConfig, pDevExt->autoRequestSize, 0);
387         if (status)
388             return status;
389     }
390     else if (srcFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
392         // do nothing if not synced since syncing done in reclaim
393         // This is executed in force modes from the first call to PAF_AST_decodeInit
394         // which calls SIO2_issue for NEWFRAME before all other calls.
395         if (pDevExt->syncState == SYNC_NONE)
396             return 0;
398         status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
399         if (status)
400             return status;
401     }
403     return 0;
404 } // DIB_issue
406 // -----------------------------------------------------------------------------
407 // Although interface allows for arbitrary BufConfigs we only support 1 -- so
408 // we can assume the one on the fromdevice is the one we want
410 extern int gIsrCnt; // GJ Debug
412 Int DIB_reclaim (DEV2_Handle device)
414     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *) device->object;
415     DEV2_Frame             *dstFrame;
416     Int                    status = 0;
417     PAF_InpBufConfig      *pBufConfig;
419     dstFrame = (DEV2_Frame *) Queue_head (device->fromdevice);
421     if (dstFrame == (DEV2_Frame *) device->fromdevice)
422         return DIBERR_UNSPECIFIED;
423     if (!dstFrame->addr)
424         return DIBERR_UNSPECIFIED;
426     // if deferred error from last request frame then return now
427     status = pDevExt->deferredError;
428     if (status) {
429         pDevExt->deferredError = 0;
430         pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
431         return status;
432     }
434     pBufConfig = (Ptr) dstFrame->addr;
435     dstFrame->size = sizeof (PAF_InpBufConfig);
437     // .........................................................................
439     if (dstFrame->arg == PAF_SIO_REQUEST_AUTO) {
441         Log_info0("DIB: At case = PAF_SIO_REQUEST_AUTO"); // GJ Debug
443         // verify set up by prior DIB_issue()
444         // no action if already sync'ed
445         if (pDevExt->syncState == SYNC_NONE)
446             return DIBERR_AUTO;
447         else if (pDevExt->syncState != SYNC_AUTO)
448             return 0;
450         // get next block of data to scan
451         status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->autoRequestSize);
452         if (status)
453             return status;
455         if (pDevExt->sourceSelect == PAF_SOURCE_NONE) {
456             IncrementPtr (pBufConfig, &pDevExt->bufConfig.pntr.pVoid, pDevExt->autoRequestSize);
457             return 0;
458         }
460         // this function updates the tail pointer; it WON'T reset to SYNC_NONE
461         status = DIB_FTABLE_syncScan (device, &pDevExt->bufConfig, &pDevExt->pcmTimeout);
462         if (status)
463             return status;
465         // if not yet sync'ed ...
466         if (pDevExt->syncState == SYNC_AUTO) {
467             // if timeout, harness tail of DIB_getSync()
468             if (!pDevExt->pcmTimeout) {
470                 // checks pDevExt->zeroCount, runs DIB_reset(),
471                 // updates pBufConfig->deliverZeros/sizeofElement/sizeofBuffer,
472                 // sets pDevExt->sourceProgram = PAF_SOURCE_PCM/DSD?
473                 //  and pDevExt->syncState = SYNC_PCM[_FORCED]
474                 status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
475                 if (status)
476                     return status;
477             }
478         }
480         // if sync'ed to bitstream, this requests add'l input;
481         // if PCM, this "kickstarts" the input,
482         // using settings per above call to DIB_getSync()
483         if (pDevExt->syncState != SYNC_AUTO) {
485             status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
486             if (status)
487                 return status;
489             // this situation may occur for various IEC types,
490             // w/ no matching PAF_SOURCE_ type is defined
491             // (see iecPafSource[] table for the latter mapping)
492             // most like cases are null & pause packets
493             if (pDevExt->sourceProgram == PAF_SOURCE_UNKNOWN)
494                 return DIBERR_SYNC;
496             // request timing frame
497             status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
498             if (status)
499                 return status;
500         }
501     } //dstFrame->arg == PAF_SIO_REQUEST_AUTO
503     // .........................................................................
505     if ((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC)) {
507         Log_info0("DIB: At case: syncState == SYNC_NONE (or PAF_SIO_REQUEST_SYNC)");  // GJ Debug
509         // pass in external buffer config which used to initialize the internal view
510         status = DIB_FTABLE_reset (device, pBufConfig);
511         if (status)
512             return status;
514         status = DIB_FTABLE_getSync (device, &pDevExt->bufConfig);
515         if (status)
516             return status;
518         // since getSync resets sourceProgram to unknown at entry
519         // sourceProgram will remain unknown if no sync is returned
520         // (i.e. no need to reset it here)
521         if (pDevExt->syncState == SYNC_NONE)
522         {
523             Log_info0("Returning DIBERR_SYNC after DIB_FTABLE_getSync"); // GJ Debug
524             return DIBERR_SYNC;
525         }
527         // get input info (frameLength/etc)
528         status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
530         if (status)
531         {
532             Log_info1("Returning %d after DIB_FTABLE_initFrame", status); // GJ Debug
533             return status;
534         }
536         // request timing frame
537         status = DIB_FTABLE_requestFrame (device, &pDevExt->bufConfig);
538         if (status)
539         {
540             Log_info1("Returning %d after DIB_FTABLE_requestFrame", status); // GJ Debug
541             return status;
542         }
543         // update external view of bufConfig. In particular for slave force PCM
544         // this insures that the first decode will be processed with deliverZeros = 1
545         // which is necessary since the first decode of slave input occurs before the
546         // first slave input frame is actually captured.
547         *pBufConfig = pDevExt->bufConfig;
549     } //((pDevExt->syncState == SYNC_NONE) || (dstFrame->arg == PAF_SIO_REQUEST_SYNC))
551     // .........................................................................
553     if (dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME) {
555         Log_info0("DIB: At case = PAF_SIO_REQUEST_NEWFRAME"); // GJ Debug
557         // wait for enough data to check for sync at expected location
558         status = DIB_FTABLE_waitForData (device, &pDevExt->bufConfig, pDevExt->bufConfig.frameLength);
559         if (status)
560         {
561             Log_info2("DIB_reclaim.%d DIB_FTABLE_waitForData returned %d", __LINE__, status); // GJ Debug
562             //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_waitForData returned %d\n", __LINE__, status));
563             return status;
564         }
566         // if PCM, but not forced PCM, then scan for bitstream sync
567         // note that we we using the local view of bufConfig here and we update the
568         // public view afterwards.
569         if (pDevExt->syncState == SYNC_PCM) {
570             float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
571             PAF_InpBufConfig *pBufConfig = &pDevExt->bufConfig;
572             Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
574             // normally no scanning done if sampleRate > 48kHz since bitstream input is highly unlikley.
575             if ((sampleRate <= SCANATSAMPLERATELIMIT) || pBufConfig->pBufStatus->scanAtHighSampleRateMode) {
576                 if (!pBufConfig->deliverZeros) {
577                     pDevExt->pcmTimeout = pBufConfig->lengthofData;
579                     // check zeroRunTrigger if needed
580                     if (ibMode != MODE_NO_ZERORUN) {
581                         if(pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) {
582                             // set this flag one block late to allow for
583                             // transmission of all data in frame which contained zeroRunTrigger
584                             pBufConfig->deliverZeros = 1;
585                             pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
586                         } // > zeroRunTrigger
587                     } // !MODE_NO_ZERORUN
588                 } // !pBufConfig->deliverZeros
590                 // scan PCM data
591                 status = DIB_FTABLE_syncScan (device, pBufConfig, &pDevExt->pcmTimeout);
592                 if (status) {
593                     pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
594                     Log_info2("DIB_reclaim.%d DIB_FTABLE_syncScan returned %d", __LINE__, status); // GJ Debug
595                     //TRACE((&TR_MOD, "DIB_reclaim.%d DIB_FTABLE_syncScan returned %d\n", __LINE__, status));
596                     return status;
597                 }
599                 // if scan found something other than PCM, then exit with error
600                 if (pDevExt->syncState != SYNC_PCM)
601                 {
602                     Log_info1("DIB_reclaim.%d error: syncState != SYNC_PCM", __LINE__); // GJ Debug
603                     //TRACE((&TR_MOD, "DIB_reclaim.%d error: syncState != SYNC_PCM\n", __LINE__));
604                     return DIBERR_SYNC;
605                 }
607                 // if heeding zeroRunRestart control then return to unknown if necessary
608                 if ((ibMode == MODE_DEFAULT) &&
609                     (pDevExt->zeroCount >= 2*pBufConfig->pBufStatus->zeroRunRestart)) {
610                     // if zeroRunRestart me then reset input to unknown
611                     Log_info1("DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
612                     //TRACE((&TR_MOD, "DIB_reclaim.%d error: zeroRunRestart, setting PAF_SOURCE_UNKNOWN\n", __LINE__));
613                     pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
614                     return DIBERR_SYNC;
615                 }
617                 // since in skeptical state we disallow returning to PCM when end of timeout contains zeros
618                 // note that we need not check the mode here since above logic prevents deliverZeros state.
619                 if (pBufConfig->deliverZeros && (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger))
620                 {
621                     //TRACE((&TR_MOD, "DIB_reclaim.%d set pcmTimeout = unknown timeout\n", __LINE__));
622                     pDevExt->pcmTimeout = 2 * pBufConfig->pBufStatus->unknownTimeout;
623                 }
624             } //scanAtHighSampleRate
625         } //SYNC_PCM
627         // clear this flag immediately to play new audio ASAP
628         // this check is OK for forced PCM since pcmTimeout and zeroCount are not
629         // updated
630         if (pDevExt->bufConfig.deliverZeros && !pDevExt->pcmTimeout &&
631             (pDevExt->zeroCount < 2 * pDevExt->bufConfig.pBufStatus->zeroRunTrigger))
632         {
633             pDevExt->bufConfig.deliverZeros = 0;
634         }
636         // update external view of buffer with local view we do this with current 
637         // frame info before the following update to the local view for the next 
638         // frame to be captured. Need to subtract headerSize from lengthofData
639         // since, at least for THD, it is needed by decoders.
640         *pBufConfig = pDevExt->bufConfig;
641         pBufConfig->lengthofData -= pDevExt->headerSize;
642         Log_info3("DIB_reclaim.%d lengthofData = %d; ISRCNT=%d", __LINE__, pBufConfig->lengthofData, gIsrCnt); // GJ Debug
643         //TRACE((&TR_MOD, "DIB_reclaim.%d lengthofData = %d\n", __LINE__, pBufConfig->lengthofData));
645         // HACK: for DSD the frameLength needs to be the number of samples to generate.
646         if ((pDevExt->sourceSelect >= PAF_SOURCE_DSD1) &&
647             (pDevExt->sourceSelect <= PAF_SOURCE_DSD3))
648             pBufConfig->frameLength /= pBufConfig->stride;
649         Log_info2("DIB_reclaim.%d frameLength = %d", __LINE__, pBufConfig->frameLength); // GJ Debug
650         //TRACE((&TR_MOD, "DIB_reclaim.%d frameLength = %d\n", __LINE__, pBufConfig->frameLength));
652         // set external view to point at synch position of the frame guaranteed
653         // to be captured by above waitForData. Need to condition this against PCM since
654         // in that case pSync could point anywhere in the buffer to to syncScan. E.g.
655         // if there was a partial sync then pSync would point at that rather than
656         // at the beginning of the buffer.
657         // TODO: change syncScan to only update pDevExt->pSync when there is an actual sync
658         //       so that we can use this for both PCM and bitstream
659         if (pDevExt->syncState == SYNC_ONGOING) {
660             pBufConfig->pntr = pDevExt->pSync;
661             IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
662         } //SYNC_ONGOING
664         // if a bitstream then need to update tail to bitstream sync location
665         // and check for next sync at expected location
666         // quick scan for sync. if decoding IEC but sync is missing then
667         // defer error until the next frame so that we decode all frames
668         // TODO: does this assume decoders have copied the entire input frame
669         //       i.e. it is ok to adjust the input buffer pointers.
670         // if successful then this sets
671         //      pSync = address of PA (for IEC)
672         status = DIB_FTABLE_initFrame (device, &pDevExt->bufConfig);
673         if (status) {
674             if (pBufConfig->pBufStatus->lastFrameMask & (1 << pDevExt->sourceProgram)) {
675                 pDevExt->deferredError = status;
676                 Log_info1("DIB_reclaim.%d last frame\n", __LINE__); // GJ Debug
677                 //TRACE((&TR_MOD, "DIB_reclaim.%d last frame\n", __LINE__));
678                 pBufConfig->pBufStatus->lastFrameFlag = 1;
679                 return 0;
680             }
681             else {
682                 Log_info1("DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN", __LINE__); // GJ Debug
683                 //TRACE((&TR_MOD, "DIB_reclaim.%d setting PAF_SOURCE_UNKNOWN\n", __LINE__));
684                 pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
685                 return status;
686             }
687         }
689     } //(dstFrame->arg == PAF_SIO_REQUEST_NEWFRAME)
691     // .........................................................................
693     Log_info3("DIB_reclaim.%d exit status = %d, ISRCNT = %d", __LINE__, status, gIsrCnt); // GJ Debug
694     //TRACE((&TR_MOD, "DIB_reclaim.%d exit status = %d\n", __LINE__, status));
696     return status;
697 } // DIB_reclaim
699 // -----------------------------------------------------------------------------
701 Int DIB_ctrl (DEV2_Handle  device, Uns code, Arg arg)
703     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
704     DEV2_Handle            pChild = (DEV2_Handle)&pDevExt->child;
705     Int status = 0;
708     switch (code) {
710         case PAF_SIO_CONTROL_GET_CHILD_DEVICE:
711             *((Arg *)arg) = (Arg) pChild;
712             break;
714             //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
716         case PAF_SIO_CONTROL_SET_DECSTATUSADDR:
717             pDevExt->pDecodeStatus = (PAF_DecodeStatus *) arg;
718             break;
720         case PAF_SIO_CONTROL_SET_PCMFRAMELENGTH:
721             pDevExt->pcmFrameLength = (XDAS_Int32) arg;
722             break;
724         case PAF_SIO_CONTROL_SET_SOURCESELECT:
725             pDevExt->sourceSelect = (XDAS_Int8) arg;
726             break;
728         case PAF_SIO_CONTROL_SET_AUTOREQUESTSIZE:
729             pDevExt->autoRequestSize = (XDAS_Int16) arg;
730             break;
732         case PAF_SIO_CONTROL_GET_SOURCEPROGRAM:
733             if (!arg)
734                 return DIBERR_UNSPECIFIED;
735             *((XDAS_Int8 *) arg) = pDevExt->sourceProgram;
736             break;
738         case PAF_SIO_CONTROL_SET_IALGADDR:
739             pDevExt->pSioIalg = (PAF_SIO_IALG_Obj *) arg;
740             break;
742             //,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
744         case PAF_SIO_CONTROL_OPEN:
745             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
746             pDevExt->zeroCount = 0;
747             if (pDevExt->pInpBufStatus)
748                 pDevExt->pInpBufStatus->zeroRun = 0;
749             status = DEV2_ctrl (pChild, code, arg);
750             break;
752         case PAF_SIO_CONTROL_CLOSE:
753             if (pDevExt->pInpBufStatus)
754                 pDevExt->pInpBufStatus->zeroRun = 0;
755             status = DEV2_ctrl (pChild, code, arg);
756             break;
758         // return number of DMA events vs. request size
759         // only update if not in error state (i.e. status = 0)
760         case PAF_SIO_CONTROL_GET_NUM_EVENTS:
761             if (!arg)
762                 return DIBERR_UNSPECIFIED;
763             status = DEV2_ctrl (pChild, code, arg);
764             if (!status)
765                 *((Int *)arg) -= pDevExt->pcmFrameLength;
766             break;
768         // return net samples until next DIB_waitForData() should succeed w/o blocking
769         case PAF_SIO_CONTROL_GET_NUM_REMAINING:
770             if (!arg)
771                 return DIBERR_UNSPECIFIED;
772             status = DEV2_ctrl (pChild, code, arg);
773             *((Int *)arg) -= pDevExt->numSamplesExtra;
774             break;
776         default:
777             status = DEV2_ctrl (pChild, code, arg);
778             break;
779     }
781     return status;
782 } // DIB_ctrl
784 // -----------------------------------------------------------------------------
786 Int DIB_idle (DEV2_Handle device, Bool flush)
788     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
789     Int                    status;
792     while (!Queue_empty (device->todevice))
793         Queue_enqueue (device->fromdevice, Queue_dequeue (device->todevice));
795     while (!Queue_empty (device->fromdevice))
796         Queue_enqueue (&((SIO2_Handle) device)->framelist, Queue_dequeue (device->fromdevice));
798     status = DIB_FTABLE_reset (device, NULL);
799     if (status)
800         return status;
802     return 0;
803 } // DIB_idle
805 // -----------------------------------------------------------------------------
807 Int DIB_open (DEV2_Handle device, String name)
809     DIB_DeviceExtension   *pDevExt;
810     DEV2_Handle             pChild;
811     DEV2_Device            *entry;
812     DEV2_Frame             *frame;
813     Int                    status, i;
814         Error_Block eb;
816         Error_init(&eb);
818     name = DEV2_match (name, &entry);
819     if (entry == NULL) {
820         Log_info1("DEV2_match failed in DIB_open:", SIO2_ENODEV);
821         return SIO2_ENODEV;
822     }
824     // only one frame interface supported
825     if (device->nbufs != 1)
826         return SYS_EALLOC;
828     if (!(pDevExt = Memory_alloc (device->bufSeg, sizeof(DIB_DeviceExtension), 0, &eb)))
829     {
830         Log_info1("DIB Memory alloc failed in DIB_open:", SYS_EALLOC);
831         return SYS_EALLOC;
832     }
833     pDevExt->pcmFrameLength = 0;
834     pDevExt->sourceSelect  = PAF_SOURCE_NONE;
835     pDevExt->autoRequestSize = DEFAULT_AUTOREQUESTSIZE;
836     pDevExt->pInpBufStatus = NULL;
837     pDevExt->pDecodeStatus = NULL;
838     device->object = (Ptr)pDevExt;
840     pChild = (DEV2_Handle)&pDevExt->child;
841     pChild->fromdevice = Queue_create (NULL, &eb);
842     pChild->todevice = Queue_create (NULL, &eb);
843     if (pChild->fromdevice == NULL || pChild->todevice == NULL) {
844         Log_info1 ("DIB Queue_create failed in DIB_open:", SYS_EALLOC);
845         return SYS_EALLOC;
846     }
848     pChild->bufsize = 0;
849     pChild->nbufs = NUM_CHILD_BUFFERS;
850     pChild->bufSeg = device->bufSeg;
851     pChild->mode = device->mode;
852     pChild->timeout = device->timeout;
853     pChild->align = device->align;
854     pChild->devid = entry->devid;
855     pChild->params = entry->params;
856     pChild->fxns = *(DEV2_Fxns *)(entry->fxns);
857     ((SIO2_Handle)pChild)->model = ((SIO2_Handle)device)->model;
859     //Create frames and put them on the correct device queue.
860     // We only support ISSUERECLAIM mode so size = 0
861     Queue_construct(&((SIO2_Handle)pChild)->framelist, NULL); //Queue_new (&((SIO2_Handle)pChild)->framelist);
862     for (i=0; i < pChild->nbufs; i++) {
863         frame = DEV2_mkframe (0, 0, 0);
864         if (!frame)
865             return SYS_EALLOC;
866         Queue_put (&((SIO2_Handle)pChild)->framelist, frame);
867     }
869     // open underlying device
870     status = DEV2_open (pChild, name);
871     if (status)
872         return status;
874     // use dev match to fetch function table pointer for DIB
875     name = DEV2_match ("/DIB", &entry);
876     if (entry == NULL) {
877         Log_info1 ("DEV2_match for DIB in DIB_open:", SIO2_ENODEV);
878         return SIO2_ENODEV;
879     }
880     pDevExt->pFxns = (DIB_Fxns *) entry->fxns;
882     // set IEC frame length table pointer -- change in
883     // subsequent control call (not defined) to add new IEC type
884     pDevExt->pIECFrameLength = (XDAS_UInt16 *) iecFrameLength;
886     status = DIB_FTABLE_reset (device,NULL);
887     if (status)
888         return status;
890     return status;
891 } // DIB_open
893 // -----------------------------------------------------------------------------
894 // Although this is void it is still needed since BIOS calls all DEV inits on
895 // startup.
897 Void DIB_init (Void)
899 } // DIB_init
901 // -----------------------------------------------------------------------------
902 // Notes:
903 //   1. DIB_reset is called prior to this function being called.(see DIB_reclaim)
904 //   2. (1) ==> sizeofBuffer is an integral # of 2byte samples.
905 //   3. (2) ==> if we use a request size which is divisor of sizeofBuffer there
906 //              will be no wrap-around when requesting data for scanning.
907 //   4. (3) ==> we meet the interface requirement for syncScan which has no
908 //              circular arithmetic.
910 Int DIB_getSync (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
912     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
913     DEV2_Handle             pChild = (DEV2_Handle)&pDevExt->child;
914     int status;
915     Uns timeout,  syncBufSize, syncRequestSize;
916     Int ibMode = pBufConfig->pBufStatus->mode; // read mode register once
917     Int deliverZeros;
919     //..........................................................................
921     // implement local timeout so that we don't get 'stuck' here when input
922     // is all zeros + lock
923     if (pDevExt->syncState == SYNC_NONE) {
924         Uns localTimeout;
925         // latch value before resetting to PAF_SOURCE_UNKNOWN
926         Int sourceProgram = pDevExt->sourceProgram;
928         pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
930         // if here then guaranteed to have fresh reset
932         if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
933             pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
934             timeout = 0;
936             // no zero run counting in force modes since no scanning
937             pBufConfig->pBufStatus->zeroRun = 0;
938             pDevExt->zeroCount = 0;
939         }
940         else if ((pDevExt->sourceSelect == PAF_SOURCE_PCMAUTO) &&
941                  ((sourceProgram == PAF_SOURCE_UNKNOWN) || (sourceProgram == PAF_SOURCE_PCM))) {
942             // if sourceselect is PCMAUTO then
943             //    if current input is a bistream then scan for normal timeout period
944             //    if current input is unknown or PCM then transition immediately to PCM
945             // this provides for *no* lossed PCM, detection of bitstreams, but some noise
946             // is possible.
947             timeout = 0;
948             pDevExt->zeroCount = 0;
949         }
950         else
951             timeout = 2*pBufConfig->pBufStatus->unknownTimeout;
953         // force request size to be a divisor of sizeofBuffer
954         syncRequestSize = NOMINAL_XFERSIZE;
955         if (pBufConfig->stride > 2)
956             syncRequestSize *= pBufConfig->stride;
957         syncBufSize = pBufConfig->sizeofBuffer / ((int) (pBufConfig->sizeofBuffer/syncRequestSize));
959         if (timeout) {
960             status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
961             if (status)
962                 return status;
963         }
965         localTimeout = timeout;
966         while ((timeout) && (pDevExt->syncState != SYNC_ONE)) {
968             status = DIB_FTABLE_issueChild (device, pBufConfig, syncBufSize, 0);
969             if (status)
970                 return status;
972             // get next block of data to scan
973             status = DIB_FTABLE_waitForData (device, pBufConfig, syncBufSize);
974             if (status)
975                 return status;
977             // this function updates the tail pointer
978             status = DIB_FTABLE_syncScan (device, pBufConfig, &timeout);
979             if (status)
980                 return status;
982             // if input is zero, i.e. haven't decremented at all,
983             // then break out and use more logic and
984             if (localTimeout < syncBufSize) {
985                 // Should this be 2 *? MAW
986                 if (timeout == 2*pBufConfig->pBufStatus->unknownTimeout)
987                     break;
988             }
989             else
990             {
991                 Log_info3("DIB: Inside DIB_getSync with syncState != SYNC_ONE. localTimeout = %d, syncBufSize  = %d, timeout = %d", localTimeout,syncBufSize, timeout); // GJ Debug
992                 localTimeout -= syncBufSize;
993             }
994         }
996         // if found sync then return to caller who will call 
997         // initFrame to get bitstream info and requestFrame for data
998         if (pDevExt->syncState != SYNC_NONE)
999             return 0;
1001     } //pDevExt->syncState == SYNC_NONE
1003     //..........................................................................
1005     // set default to zero -- we assume decode calls will not be made
1006     // before data is available since this must be master input. Will be changed below
1007     // as needed
1008     deliverZeros = 0;
1010     if (pDevExt->syncState == SYNC_AUTO) {
1011         timeout = pDevExt->pcmTimeout;
1012         deliverZeros = 1;
1013     }
1015     // if in zero run, and heeding full zeroRun control, then return to unknown if # zeros > trigger/Restart
1016     if (ibMode == MODE_DEFAULT) {
1017         if ((pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger) ||
1018             (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunRestart))
1019             return DIBERR_SYNC;
1020         // since we may have exited prematurely above we check timeout
1021         if (timeout)
1022             return DIBERR_SYNC;
1023     }
1024     // if heeding trigger but not restart then enter deliverZeros state of PCM
1025     else if (ibMode == MODE_NO_ZERORUNRESTART) {
1026         if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1027             deliverZeros = 1;
1028     }
1030     // here if timeout to PCM (includes force PCM)
1031     status = DIB_FTABLE_reset (device, pBufConfig);
1032     if (status)
1033         return status;
1035     // hack -- try 32bit then 16bit if necessary
1036     pBufConfig->sizeofElement = 4;
1037     status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1038     if(status) {
1039         pBufConfig->sizeofElement = 2;
1040         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1041         if(status)
1042             return status;
1043     }
1045     // Force sizeofBuffer to be integral number of frame sizes. This ensures that the
1046     // pcm buffers will not need a circular wrap-around. We prevent this because
1047     // syncScan makes this assumption in order to perform an efficient scan.
1048     {
1049         int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride*pDevExt->pcmFrameLength;
1050         pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
1051     }
1053     if (pDevExt->sourceSelect == PAF_SOURCE_DSD1 || pDevExt->sourceSelect == PAF_SOURCE_DSD2 ||
1054         pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1055         pDevExt->sourceProgram = pDevExt->sourceSelect;
1056     else
1057         pDevExt->sourceProgram = PAF_SOURCE_PCM;
1059     if (pDevExt->sourceSelect == PAF_SOURCE_PCM || pDevExt->sourceSelect == PAF_SOURCE_DSD1 ||
1060         pDevExt->sourceSelect == PAF_SOURCE_DSD2 || pDevExt->sourceSelect == PAF_SOURCE_DSD3) {
1061         pDevExt->syncState = SYNC_PCM_FORCED;
1062         // set to one -- ensures that PCM decode calls made before data is
1063         // available will result in zero output.
1064         // (mostly needed for PA15 since, currently, all other frameworks
1065         // require a frame of data before the first decode call.
1066         deliverZeros = 1;
1067     }
1068     else
1069         pDevExt->syncState = SYNC_PCM;
1071     // update config struct
1072     pBufConfig->deliverZeros = deliverZeros;
1074     //..........................................................................
1076     return 0;
1077 } // DIB_getSync
1079 // -----------------------------------------------------------------------------
1081 Int DIB_issueChild (DEV2_Handle device, PAF_InpBufConfig  *pBufConfig, int size, int forTotal)
1083     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *) device->object;
1084     DEV2_Handle             pChild  = (DEV2_Handle) &pDevExt->child;
1085     int                    bufEnd  = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1086     DEV2_Frame             *dstFrame;
1087     int                    futureHead, status;
1088     int                    i, sizes[2];
1089     Ptr                    endAddr[2];
1090    
1093     // if seeking for total amount then adjust for difference
1094     if (forTotal) 
1095         size -= GetFutureAvail (pBufConfig);
1097     // return success if we needn't make any requests
1098     if (size <= 0)
1099         return 0;
1101     // assume if eight channel then using optimized dMAX routine which requires
1102     // requests which are a mulitple of 8 to operate correctly. If not a proper
1103     // multiple then we increase the requested size as needed. This information
1104     // is communicated to other portions of DIB indirectly through the update
1105     // of the futureHead pointer (here) and head pointer (in reclaim). To these
1106     // other portions it is a don't care as we ensure enough data requested will
1107     // be available at, the now slightly deferred, reclaim point. We assume that
1108     // the buffer is a multiple of 8 and so, by using this single statement, we
1109     // ensure all requests are a mulitple 8 even if they need to be split across
1110     // the buffer wrap point.
1111     if (pBufConfig->stride == 8)
1112         size = (size + 7) & ~0x7;
1114     // convert to bytes
1115     size = (size * pBufConfig->sizeofElement); //To Do: +2 GJ : Temporary, to get past initial hiccup.  // GJ Debug
1116     //size *= 4;
1118     // if request crosses circular buffer boundary then split into two requests
1119     futureHead = (int) pBufConfig->futureHead.pVoid + size;
1120     if (futureHead <= bufEnd) {
1121         sizes[0] = size;
1122         sizes[1] = 0;
1124         // If this request happens to be the rest of the buffer, then 
1125         // futureHead must be set to the beginning of the buffer.
1126         if (futureHead != bufEnd)
1127             endAddr[0] = (Ptr) futureHead;
1128         else
1129             endAddr[0] = pBufConfig->base.pVoid;
1130     }
1131     else {
1132         sizes[0] = bufEnd - (int) pBufConfig->futureHead.pVoid;
1133         sizes[1] = futureHead - bufEnd;
1134         endAddr[0] = pBufConfig->base.pVoid;
1135         endAddr[1] = (Ptr) ((int)pBufConfig->base.pVoid + sizes[1]);
1136     }
1138     for (i=0; i < 2; i++) {
1139         if (sizes[i]) {
1140             dstFrame = Queue_get (&((SIO2_Handle) pChild)->framelist);
1141             if (dstFrame == (DEV2_Frame *)&((SIO2_Handle) pChild)->framelist)
1142                 return DIBERR_UNSPECIFIED;
1143             dstFrame->arg = (Arg) pBufConfig;
1145             dstFrame->addr = pBufConfig->futureHead.pVoid;
1146             dstFrame->size = sizes[i];
1147             Queue_put (pChild->todevice, dstFrame);
1148             status = DEV2_issue (pChild);
1149             if (status)
1150                 return DIBERR_UNSPECIFIED;
1152             pBufConfig->futureHead.pVoid = endAddr[i];
1153         }
1154     }
1156     return 0;
1157 } // DIB_issueChild
1159 // -----------------------------------------------------------------------------
1161 Int DIB_reclaimChild (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1163     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1164     DEV2_Handle              pChild = (DEV2_Handle)&pDevExt->child;
1165     DEV2_Frame              *srcFrame;
1166     int                     status, bufEnd;
1168     //Log_info3("DIB_reclaimChild.%d: Inside DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim); // GJ Debug
1169     //TRACE((&TR_MOD, "DIB_reclaimChild.%d: calling DEV2_reclaim(pChild) pChild = 0x%x DEV2_reclaim = 0x%x", __LINE__, pChild, &pChild->fxns.reclaim));
1170     status = DEV2_reclaim (pChild);
1171     if (status)
1172     {
1173         Log_info2("DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED", __LINE__, status); // GJ Debug
1174         //TRACE((&TR_MOD, "DIB_reclaimChild.%d DEV2_reclaim() returned (%d) DIBERR_UNSPECIFIED \n", __LINE__, status));
1175         return DIBERR_UNSPECIFIED;
1176     }
1178     //Log_info1("DIB_reclaimChild.%d calling Queue_get()", __LINE__); // GJ Debug
1179     //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_get()\n", __LINE__));
1180     srcFrame = Queue_get (pChild->fromdevice);
1181     //Log_info2("DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x", __LINE__, srcFrame); // GJ Debug
1182     //TRACE((&TR_MOD, "DIB_reclaimChild.%d calling Queue_put(), srcFrame = 0x%x\n", __LINE__, srcFrame));
1183     Queue_put (&((SIO2_Handle) pChild)->framelist, srcFrame);
1185     // Only for non-fill requests do we update ptrs
1186     if (srcFrame->addr != NULL) {
1187         //Log_info2("DIB_reclaimChild.%d update pointers with srcFrame->size = %d", __LINE__, srcFrame->size); // GJ Debug
1188         //TRACE((&TR_MOD, "DIB_reclaimChild.%d update pointers\n", __LINE__));
1189         pBufConfig->head.pVoid = (Ptr) ((int)srcFrame->addr + srcFrame->size);
1191         // wrap, if necessary
1192         bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1193         if( (int) pBufConfig->head.pVoid >= bufEnd )
1194         {
1195             Log_info1("DIB_reclaimChild.%d wrap pointer", __LINE__); // GJ Debug
1196             //TRACE((&TR_MOD, "DIB_reclaimChild.%d wrap pointer\n", __LINE__));
1197             pBufConfig->head.pVoid = (Ptr) ((int) pBufConfig->base.pVoid + (int) pBufConfig->head.pVoid - bufEnd);
1198         }
1199     }
1201     Log_info2("DIB_reclaimChild.%d exit with status = %d", __LINE__, status); // GJ Debug
1202     //TRACE((&TR_MOD, "DIB_reclaimChild.%d exit with status = %d\n", __LINE__, status));
1204     return status;
1205 } // DIB_reclaimChild
1207 // -----------------------------------------------------------------------------
1208 // This function uses the local definition of frameLength and lengthofData in
1209 // pDevExt to request the next frame of data.
1211 Int DIB_requestFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1213     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1214     int status = 0;
1217     // if in steady state then update tail pointer to indicate we are done, i.e. no
1218     // longer own, the last frame of data.
1219     if (pDevExt->running > 1)
1220         IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
1222     switch (pDevExt->syncState) {
1223         case SYNC_PCM:
1224         case SYNC_PCM_FORCED:
1225                     
1226             if (pDevExt->sourceSelect == PAF_SOURCE_DSD1)
1227                 pDevExt->frameLength = 256;
1228             else if (pDevExt->sourceSelect == PAF_SOURCE_DSD2)
1229                 pDevExt->frameLength = 128;
1230             else if (pDevExt->sourceSelect == PAF_SOURCE_DSD3)
1231                 pDevExt->frameLength = 64;
1232             else
1233                 pDevExt->frameLength = pDevExt->pcmFrameLength;
1235             pDevExt->lengthofData = pBufConfig->stride*pDevExt->frameLength;
1236             pDevExt->frameLength  = pDevExt->lengthofData;        
1238             // note that the following issueChild
1239             // doesn't *fetch* the data which will next be consumed,
1240             // but rather *replenishes* what's about to be consumed
1241             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1242             break;
1244         case SYNC_ONE:
1245             // for the first issue we need to set the tail pointer to the bitstream sync
1246             pBufConfig->pntr = pDevExt->pSync;
1247             IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pDevExt->headerSize);
1248             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->frameLength, 1);
1250             // HD codecs need extra time due to several factors
1251             //   time between first info call and starting output is non-negligible
1252             //   peak decoder MIPs
1253             //   reset time for decoders/ASPs
1254             if ((pDevExt->sourceProgram == PAF_SOURCE_DDP)   ||
1255                 (pDevExt->sourceProgram == PAF_SOURCE_DTSHD) ||
1256                 (pDevExt->sourceProgram == PAF_SOURCE_THD)   ||
1257                 (pDevExt->sourceProgram == PAF_SOURCE_DXP))
1258                 status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1260             pDevExt->syncState = SYNC_ONGOING;
1261             break;
1263         case SYNC_ONGOING:
1264             status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
1265             break;
1267     } //switch
1269     // update bufConfig with info for use in next reclaim call
1270     // the interface to DIB is based on a single frame. So the amount
1271     // of data requested in this issue is assumed to be what is wanted in the next
1272     // reclaim.
1273     pBufConfig->frameLength  = pDevExt->frameLength;
1274     pBufConfig->lengthofData = pDevExt->lengthofData;
1275     // enable to inspect input buffer.
1276     // if (pDevExt->lengthofData > 512)
1277     //     asm( " SWBP 0" );  // breakpoint
1280     if (pDevExt->running < 3)
1281         pDevExt->running++;
1283     // Goal is to align timing so synchronized with forthcoming
1284     // "DIB_waitForData (... pDevExt->lengthofData);"
1285     // in DIB_reclaim(), servicing PAF_SIO_REQUEST_NEWFRAME, for PAF_SOURCE_PCM/DSD?.
1286     // ** need to revise above DSD handling so it works w/ this calc. **
1287     {
1288         int futureAvail = GetFutureAvail (pBufConfig);
1289         // GetFutureAvail() returns 0 if full buffer requested or if no requests outstanding
1290         // -- 0 (empty) can't be right interpretation here, on account of foregoing issueChild()
1291         if( ! futureAvail)
1292             futureAvail = pBufConfig->sizeofBuffer / pBufConfig->sizeofElement; // total words in buffer
1293         pDevExt->numSamplesExtra = (XDAS_Int16) (futureAvail - pDevExt->frameLength);
1294     }
1296     return status;
1297 } // DIB_requestFrame
1299 // -----------------------------------------------------------------------------
1301 Int DIB_reset (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1303     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
1304     DEV2_Handle              pChild = (DEV2_Handle)&pDevExt->child;
1305     int status, numChan;
1308     //?? Do we need a shutdown to handle queue problems?
1309     // or are there no problems since we use one frame
1310     status = DEV2_idle (pChild, 1);
1311     if(status)
1312         return status;
1314     if (pBufConfig) {
1315         int sizeofStride;
1316         pBufConfig->pntr       = pBufConfig->base;
1317         pBufConfig->head       = pBufConfig->base;
1318         pBufConfig->futureHead = pBufConfig->base;
1320         pBufConfig->lengthofData = 0;
1322         //devices must? support 2byte words
1323         pBufConfig->sizeofElement = 2;
1324         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
1325         if(status)
1326             return status;
1328         status = DEV2_ctrl (pChild, PAF_SIO_CONTROL_GET_NUMCHANNELS, (Arg) &numChan);
1329         if(status)
1330             return status;
1331         pBufConfig->stride = numChan;
1333         // compute and use *effective buffer size*
1334         sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
1335         pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
1337         //hack -- save status context for use in close
1338         pDevExt->pInpBufStatus = pBufConfig->pBufStatus;
1339         pBufConfig->pBufStatus->lastFrameFlag = 0;
1341         pDevExt->bufConfig = *pBufConfig;
1342         pDevExt->pSync = pBufConfig->base;
1343     }
1345     pDevExt->syncState = SYNC_NONE;
1346     pDevExt->scanState = SCANNED_NONE;
1347     pDevExt->pcmTimeout = 0;
1348     pDevExt->deferredError = 0;
1350     pDevExt->numSamplesSinceDTS = 0;
1351     pDevExt->numSamplesExtra = 0;
1353     pDevExt->headerSize = 0;
1354     pDevExt->running = 0;
1356     return 0;
1357 } // DIB_reset
1359 // -----------------------------------------------------------------------------
1360 // Notes:
1361 //   1. The amount of data to be scanned will not result in a buffer wrap-around
1362 //   2. (1) is currently met from the two locations that call this function
1363 //          a. DIB_getSync
1364 //          b. DIB_reclaim (for PCM)
1365 //   3. We require that pTimeout != NULL since we dereference to make a const
1367 Int DIB_syncScan (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout)
1369     DIB_DeviceExtension   * restrict pDevExt = (DIB_DeviceExtension *)device->object;
1370     MdInt * restrict pTail, * restrict pShadowTail, * restrict pSync;
1371     MdInt *pLocalTail, pc;
1372     XDAS_Int8   scanState;
1373     XDAS_UInt32 zeroCount;
1374     int stride, numLeft, i, datId;
1375     int status, foundDTS = 0;
1376     Uns scanCount, pageSize;
1377     PAF_SIO_IALG_Obj    *pObj = pDevExt->pSioIalg;
1378     PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1379     const int timeoutChanged = (*pTimeout != 2 * pBufConfig->pBufStatus->unknownTimeout);
1380     MdInt DTSHDSubType;
1382     // .........................................................................
1384     // works for both SYNC_NONE and SYNC_PCM
1385     numLeft = min (*pTimeout, GetNumAvail(pBufConfig));
1387     pTail = pBufConfig->pntr.pMdInt;
1388     pShadowTail = pBufConfig->pntr.pMdInt;
1390     // if scratch buffer present then assume it is needed for paging
1391     pageSize = numLeft*pBufConfig->sizeofElement;
1393     Log_info3("DIB: Entered DIB_syncScan with pTail = 0x%x & numLeft = %d, timeout = %d", pTail, numLeft, *pTimeout); // GJ Debug
1396     if ((pAlgConfig->numRec > 1) && pAlgConfig->pMemRec[1].base && (pAlgConfig->pMemRec[1].size >= pageSize)) {
1397         pTail = pAlgConfig->pMemRec[1].base;
1398         datId = DAT_copy ((void *) pShadowTail, (void *) pTail, pageSize);
1399         DAT_wait (datId);
1400     }
1402     if (pBufConfig->sizeofElement == 4) {
1403         Log_info0("DIB: SyncScan - Inside pBufConfig->sizeofElement == 4"); // GJ Debug
1404         stride = 2;
1405         pTail += 1; // point at MSB
1406         pShadowTail += 1;
1407     }
1408     else
1409         stride = 1;
1411     // .........................................................................
1413     // scan until out of available data or a sync found
1414     scanCount = 0;
1415     zeroCount = pDevExt->zeroCount;
1416     scanState = pDevExt->scanState;
1417     pSync     = pDevExt->pSync.pMdInt;
1419     Log_info3("DIB: Entered DIB_syncScan with zeroCount = %d & scanState = %d, pSync = 0x%x", zeroCount, scanState, pSync); // GJ Debug
1421     // scan until out of available data or a sync found
1422     for (i=0; i < numLeft; i++) {
1423         MdInt tail = pTail[i*stride];
1425         // assumes SCANNED_NONE = 0
1426         if (!scanState) {
1427             if (tail == IEC_PA) {
1428                 // since above code handles ongoing sync we are
1429                 //  safe to check for extended sync here. i.e.
1430                 //  two zeros before PA.
1431                 if (zeroCount >= 2) {
1432                     scanState = SCANNED_IEC_PA;
1433                     pSync = &pShadowTail[i*stride];
1434                 }
1435             }
1436             else if (tail == DTS14_SYNC_A) {
1437                 scanState = SCANNED_DTS14_SYNC_A;
1438                 pSync = &pShadowTail[i*stride];
1439             }
1440             else if (tail == DTS16_SYNC_A) {
1441                 scanState = SCANNED_DTS16_SYNC_A;
1442                 pSync = &pShadowTail[i*stride];
1443             }
1445             // limit count to prevent wrap around
1446             zeroCount = min (zeroCount+1,INT_MAX - 1);
1447             if (tail != 0x0000)
1448                 zeroCount = 0;
1450             // don't start counting until we get the first non-zero
1451             // sample while UNKNOWN. Note we don't have to worry
1452             // about the other scanCount increments since these
1453             // only occur after the first non-zero sample.
1454             //
1455             // so don't count unless
1456             //    . we are already started counting (in this call) ||
1457             //    . we started counting in an earlier scanForSync (timeout has changed) ||
1458             //    . the last sample was non-zero
1459             if (scanCount || (tail != 0x0000) || timeoutChanged)
1460             {
1461                 //Log_info3("DIB: DIB_syncScan scanCount = %d tail = %d timeoutChanged = %d", scanCount, tail, timeoutChanged); // GJ Debug
1462                 scanCount += 1;
1463             }
1466             continue;
1467         }
1469         // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1471         switch (scanState) {
1473             case SCANNED_DTS16_SYNC_A:
1474                 if (tail == DTS16_SYNC_B) {
1475                     scanState = SCANNED_DTS16_SYNC_B;
1476                     scanCount += 1;
1477                 }
1478                 else
1479                     scanState = SCANNED_NONE;
1480                 break;
1482                 // wait for header data to get payload size via
1483                 // nblks/fsize
1484             case SCANNED_DTS16_SYNC_B:
1485                 // use extended sync
1487                 if ((short)(tail & 0xFC00) == DTS16_SYNC_C) {
1488                     scanState = SCANNED_DTS16_SYNC_C;
1489                     scanCount += 1;
1490                 }
1491                 else
1492                     scanState = SCANNED_NONE;
1493                 break;
1495                 // `````````````````````````````````````````````````````````````````````````
1496                 // check for 2nd word of DTS-14 sync
1497             case SCANNED_DTS14_SYNC_A:
1498                 if (tail == DTS14_SYNC_B) {
1499                     scanState = SCANNED_DTS14_SYNC_B;
1500                     scanCount += 1;
1501                 }
1502                 else
1503                     scanState = SCANNED_NONE;
1504                 break;
1506                 // check for 3rd word of DTS-14 sync
1507             case SCANNED_DTS14_SYNC_B:
1508                 // if here then looking for extended 38 bit sync
1509                 if ((short)(tail & 0xFFF0) == DTS14_SYNC_C) {
1510                     scanState = SCANNED_DTS14_SYNC_C;
1511                     scanCount += 1;
1512                 }
1513                 else
1514                     scanState = SCANNED_NONE;
1515                 break;
1517                 // wait for header data to get payload size via
1518                 //   nblks/fsize
1519             case SCANNED_DTS14_SYNC_C:
1520                 scanState = SCANNED_DTS14_SYNC_D;
1521                 scanCount += 1;
1522                 break;
1524                 // `````````````````````````````````````````````````````````````````````````
1525                 // if here then all of header is buffered
1526             case SCANNED_DTS16_SYNC_C:
1527             case SCANNED_DTS14_SYNC_D:
1528                 // update sync to point at beginning of DTS header as syncScanDTS uses this info
1529                 pDevExt->scanState    = scanState;
1530                 pDevExt->pSync.pMdInt = pSync;
1531                 status = DIB_FTABLE_syncScanDTS (device, pBufConfig, pTimeout, (XDAS_UInt16 *) &pShadowTail[i*stride]);
1532                 scanState = pDevExt->scanState;
1533                 if (status)
1534                     return status;
1535                 foundDTS = 1;
1536                 if (pDevExt->syncState == SYNC_ONE)
1537                     goto syncScanExit;
1538                 break;
1540                 // `````````````````````````````````````````````````````````````````````````
1542                 // note that the round about detection of IEC only
1543                 // happens for the first sync so the extra states are OK.
1544             case SCANNED_IEC_PA:
1545                 if (tail == IEC_PB) {
1546                     scanState = SCANNED_IEC_PB;
1547                     scanCount += 1;
1548                     Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - if path"); // GJ Debug
1549                 }
1550                 else
1551                 {
1552                     Log_info0("DIB: SyncScan Inside case - SCANNED_IEC_PA - else path"); // GJ Debug
1553                     scanState = SCANNED_NONE;
1554                 }
1555                 break;
1557             case SCANNED_IEC_PB:
1558                 // Update scanCount here since, at this point, we are confident that
1559                 // this is a proper IEC stream. Regardless if we ignore it our not.
1560                 // Therefore we want to properly signal that this data has been scanned.
1561                 scanCount += 1;
1563                 // check for IEC pause packets at this time and if required ignore them.
1564                 // By construction we are guaranteed to have tail=PC at this time.
1565                 if ((pBufConfig->pBufStatus->mode == MODE_NO_ZERORUNRESTART) ||
1566                     (pBufConfig->pBufStatus->mode == MODE_NO_ZERORUN)) {
1567                     MdInt pc = tail & 0x1F;
1569                     if ((pc == 0) || (pc == 3)) {
1570                         scanState = SCANNED_NONE;
1571                         break;
1572                     }
1573                 }
1575                 scanState = SCANNED_IEC_PC;
1576                 break;
1578             case SCANNED_IEC_PC:
1579                 pLocalTail = pSync;
1580                 IncrementPtr (pBufConfig, (Ptr *)  &pLocalTail, 2);
1581                 pc = *pLocalTail & 0x1F;
1582                 pDevExt->headerSize = IEC_HEADER_SIZE;
1584                 Log_info0("DIB: Sync Scan - Inside case: SCANNED_IEC_PC"); // GJ Debug
1585                 // Handle DTSHD subtype (LBR)
1586                 if (pc == 0x11) {
1587                     pDevExt->headerSize +=6;
1588                     DTSHDSubType = (*pLocalTail & 0x700)>>8;
1589                 }
1590                 // DDP or THD
1591                 if (pc == 21 || pc ==22) {
1592                     TRACE((&TR_MOD, "Dolby: useIECSubType is 0x%x.\n", pBufConfig->pBufStatus->useIECSubType));
1593                     if (pBufConfig->pBufStatus->useIECSubType == 1) {
1594                         unsigned char IECSubType = *pLocalTail & 0x60;
1595                         TRACE((&TR_MOD, "Dolby: IECSubType is 0x%x.\n", IECSubType));
1596                         if (IECSubType != 0) {
1597                             pDevExt->sourceProgram = PAF_SOURCE_UNKNOWN;
1598                             pDevExt->frameLength = 0;
1599                         }
1600                     }
1601                 }
1602                 // don't know how to support other types
1603                 if (pc > 22)
1604                 {
1605                     Log_info1("DIB:  Unknown IEC type 0x%x encountered.\n", pc); // GJ Debug
1606                     return DIBERR_SYNC;
1607                 }
1609                 pDevExt->syncState = SYNC_ONE;
1610                 pBufConfig->pntr.pMdInt = pSync;
1611                 pDevExt->sourceProgram = iecPafSource[pc];
1613                 Log_info2("source is %d.  pc is %d.", iecPafSource[pc], pc); // GJ Debug 
1614                 //TRACE((&TR_MOD, "source is %d.  pc is %d.\n", iecPafSource[pc], pc));
1616                 if (pc == 0x11 && DTSHDSubType == 3 && (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <=48000.0))
1617                     pDevExt->sourceProgram = PAF_SOURCE_DXP;    // LBR is 23
1618              
1619                 pDevExt->frameLength = pDevExt->pIECFrameLength[pc];
1620                 pDevExt->lengthofData = pDevExt->frameLength;
1621                 if (pc == 1)
1622                     pDevExt->frameLength = 4288;
1623                 else if (pc == 0x11) {
1624                     pDevExt->frameLength = (pDevExt->pIECFrameLength[pc] << DTSHDSubType);
1625                     pDevExt->lengthofData = pDevExt->frameLength;
1626                 }
1628                 goto syncScanExit;
1630         } // switch
1631     } // for
1633     // .............................................................................
1635 syncScanExit:
1636     Log_info4("DIB inside syncScanExit.  pTimeout = %d, scanCount = %d, zeroCount = %d, numLeft = %d", *pTimeout,scanCount, zeroCount, numLeft ); // GJ Debug
1637     pDevExt->zeroCount    = zeroCount;
1638     pDevExt->scanState    = scanState;
1639     pDevExt->pSync.pMdInt = pSync;
1641     if (pDevExt->zeroCount >= 2 * pBufConfig->pBufStatus->zeroRunTrigger)
1642         pBufConfig->pBufStatus->zeroRun = 1;
1643     else
1644         pBufConfig->pBufStatus->zeroRun = 0;
1646     // If detected an initial DTS sync in a previous buffer then add the
1647     // number of samples in this buffer to the tally.
1648     // TODO: should we add numLeft instead of lengthofData?
1649     if (!foundDTS && pDevExt->numSamplesSinceDTS)
1650         pDevExt->numSamplesSinceDTS += pBufConfig->lengthofData;
1652     if (*pTimeout > scanCount)
1653         *pTimeout -= scanCount;
1654     else {
1655         *pTimeout = 0;
1656         return 0;
1657     }
1659     // This flushes the current scanned buffer if a sync is not found
1660     // Note that this code is not executed when *pTimeout = 0. 
1661     // TODO: should this be moved elsewhere. Like in requestFrame?
1662     //       seems like this should be done in request frame for continuous modes
1663     //       and in getSync for traditional modes.
1664     //       What does it mean that this is not executed when we have timed out to PCM
1665     if (pDevExt->syncState == SYNC_NONE || pDevExt->syncState == SYNC_AUTO) {
1666         IncrementPtr (pBufConfig, (Ptr *) &pBufConfig->pntr.pMdInt, numLeft);
1667         return 0;
1668     }
1670     return 0;
1671 } // DIB_syncScan
1673 // -----------------------------------------------------------------------------
1674 // Assumes scanState is SCANNED_DTS16_SYNC_C or SCANNED_DTS14_SYNC_D
1676 Int DIB_syncScanDTS (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 *pTimeout, XDAS_UInt16 *pHeaderEnd)
1678     DIB_DeviceExtension  *pDevExt = (DIB_DeviceExtension *)device->object;
1679     Int sourceProgram = (pDevExt->scanState == SCANNED_DTS14_SYNC_D) ? PAF_SOURCE_DTS14  : PAF_SOURCE_DTS16;
1680     float sampleRate = PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD];
1681     MdInt *pLocalTail, pc, pd;
1682     int nblks;
1685     // compute repetition rate as predicted by DTS header
1686     pLocalTail = pDevExt->pSync.pMdInt;
1687     IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 2);
1688     pc = *pLocalTail;
1689     if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1690         nblks = (pc & 0x01FC) >> 2;
1691     else {
1692         IncrementPtr (pBufConfig, (Ptr *) &pLocalTail, 1);
1693         pd = *pLocalTail;
1694         nblks = (pc & 0x7) << 4;
1695         nblks |= (pd & 0x3C00) >> 10;
1696     }
1698     // if samplerate > 44.1k and DTS16 bit CD then report as DTS-DVD
1699     // this is a work around to the possibility that DTS-DVD is being
1700     // sent but, due to the variance in input recording, we may have
1701     // missed the IEC header. This is predicated on the enable register
1702     if (pBufConfig->pBufStatus->reportDTS16AsDTSForLargeSampleRate &&
1703         (sampleRate > 44100) && (sourceProgram == PAF_SOURCE_DTS16))
1704         sourceProgram = PAF_SOURCE_DTS;
1706     // point at LSB, if neceesary, so that space calculation is correct
1707     if (pBufConfig->sizeofElement == 4)
1708         pHeaderEnd -= 1;
1710     // If in PCM mode then require double sync, at an appropriate spacing,
1711     // in order to determine DTS validity.
1712     if (pDevExt->syncState == SYNC_PCM) {
1713         int diff;
1715         // If we have started counting, i.e. found a previous sync,
1716         // then compute sync spacing.
1717         if (pDevExt->numSamplesSinceDTS) {
1718             // determine distance since last sync
1719             //    pHeaderEnd, which points at the end of the DTS header, is guaranteed
1720             //    to be in the active buffer. Whereas the pointer to the beginning of the header (pSync)
1721             //    may have occured in the previous buffer.
1722             diff = ((int) pHeaderEnd - (int) pBufConfig->pntr.pVoid);
1723             if (diff < 0)
1724                 diff += pBufConfig->sizeofBuffer;
1725             diff /= pBufConfig->sizeofElement;
1726             diff += pDevExt->numSamplesSinceDTS;
1728             // if spacing incorrect then reset sample count to
1729             // force next conditional to be true.
1730             if (diff != (nblks+1)*32*2)
1731                 pDevExt->numSamplesSinceDTS = 0;
1732         }
1734         // If this is the 1st sync detected or if this is the second sync
1735         // but the spacing between DTS syncs did not match that predicted by
1736         // NBLKS, then this is not DTS data. Therefore the previous DTS sync
1737         // word was not valid and so it is safe to reset the count based on
1738         // this secondary sync word. This latter sync may or may not be valid;
1739         // we don't know yet. In both cases init sync spacing count, reset
1740         // scan state, and continue. Note that there is a positive, albeit
1741         // quite small, probability of falsing in a pathological case where
1742         // the PCM data, interpreted as a DTS header and used to compute NBLKS,
1743         // actually matches the fake DTS syncs in the PCM file.
1744         if (!pDevExt->numSamplesSinceDTS) {
1745             diff = (int) pBufConfig->head.pVoid - (int) pHeaderEnd;
1746             if (diff <= 0)
1747                 diff += pBufConfig->sizeofBuffer;
1748             diff /= pBufConfig->sizeofElement;
1749             pDevExt->numSamplesSinceDTS = diff;
1750             pDevExt->scanState = SCANNED_NONE;
1751             return 0;
1752         }
1753     } //SYNC_PCM
1755     pDevExt->lengthofData = (nblks+1)*32*2;
1756     if (pDevExt->scanState == SCANNED_DTS16_SYNC_C)
1757         pDevExt->frameLength = pDevExt->lengthofData + 4;
1758     else
1759         pDevExt->frameLength = pDevExt->lengthofData + 6;
1761     pDevExt->syncState = SYNC_ONE;
1762     pBufConfig->pntr = pDevExt->pSync;
1763     pDevExt->sourceProgram = sourceProgram;
1765     return 0;
1766 } //DIB_syncScanDTS
1768 // -----------------------------------------------------------------------------
1769 // This function is responsible for verifying bitstream sync (if applicable) and
1770 // configuring the sizes of the next frame of data.
1772 Int DIB_initFrame (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
1774     DIB_DeviceExtension  * restrict pDevExt = (DIB_DeviceExtension *) device->object;
1775     MdInt * restrict pTail;
1776     MdInt pa, pb, pc;
1777     unsigned char DTSHDSubType;
1778     PAF_UnionPointer     ac3SearchPtr;
1781     // MID 810
1782     // TODO: is this needed anymore? can we combine above and this?
1783     // I don't think this is needed since pSync is guaranteed to be
1784     // valid under all cases where this function is called.
1785     if (!(pDevExt->scanState == SCANNED_DTS14_SYNC_D ||
1786           pDevExt->scanState == SCANNED_DTS16_SYNC_C ||
1787           pDevExt->scanState == SCANNED_IEC_PC ))
1788         return 0;
1790     // minimum possible distance from current IEC sync to next is 1856 words
1791     // capture this here before we update pSync following
1792     ac3SearchPtr = pDevExt->pSync; 
1794     // for steady state compute expected sync location
1795     if (pDevExt->syncState == SYNC_ONGOING) 
1796         IncrementPtr (pBufConfig, &pDevExt->pSync.pVoid, pBufConfig->lengthofData);
1798     pTail = pDevExt->pSync.pMdInt;
1799     pa = *pTail;
1800     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1801     pb = *pTail;
1802     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1803     pc = *pTail;
1804     IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1806     switch (pDevExt->scanState) {
1807         // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1809         case SCANNED_DTS14_SYNC_D:
1810             // check sync (extended sync checked above for 1st sync)
1811             if ((pa != DTS14_SYNC_A) || (pb != DTS14_SYNC_B) || ((pc & 0xFC00) != (DTS14_SYNC_C & 0xFC00)))
1812                 return DIBERR_SYNC;
1813             break;
1815             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1817         case SCANNED_DTS16_SYNC_C:
1818             // check sync (extended sync checked above for 1st sync)
1819             if ((pa != DTS16_SYNC_A) || (pb != DTS16_SYNC_B))
1820                 return DIBERR_SYNC;
1821             break;
1823             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1825         case SCANNED_IEC_PC:
1826             // check for sync
1827             //    special handling for AC3 variable bit rate (VBR)
1828             //       start looking for sync at max payload sync location and
1829             //       scan forward. Note that getSync() has waited for
1830             //       sufficient data to arrive so that we can determine reliably
1831             //       the presence or absence of a correct sync.
1833             if ((pa != IEC_PA) || (pb != IEC_PB)) {
1834                 PAF_SIO_IALG_Obj    *pObj = pDevExt->pSioIalg;
1835                 PAF_SIO_IALG_Config *pAlgConfig = &pObj->config;
1836                 int scan1, scan2, searchIdx, datId;
1837                 const int bufEnd = (int) pBufConfig->base.pVoid + pBufConfig->sizeofBuffer;
1840                 // only extend IEC search in the case of AC3
1841                 if (pDevExt->sourceProgram != PAF_SOURCE_AC3)
1842                     return DIBERR_SYNC;
1844                 // move search ptr to earliest possible location of next sync
1845                 IncrementPtr (pBufConfig, &ac3SearchPtr.pVoid, 1856);
1847                 // compute number of samples between earliest possible sync location
1848                 // (ac3SearchPtr) and latest possible sync location (head)
1849                 scan1 = (int) pBufConfig->head.pVoid - (int) ac3SearchPtr.pVoid;
1850                 if (scan1 < 0) {
1851                     // here if search will wrap around so split search into two
1852                     // halves to accomodate circular buffer
1853                     scan1 = bufEnd - (int) ac3SearchPtr.pVoid;
1854                     scan2 = (int) pBufConfig->head.pVoid - (int) pBufConfig->base.pVoid;
1855                 }
1856                 else
1857                     scan2 = 0;
1859                 // page if necessary (assume so if second memRec present)
1860                 if (pAlgConfig->numRec > 1) {
1861                     // if invalid buffer or if page buffer not big enough for either split then error
1862                     if (!pAlgConfig->pMemRec[1].base ||
1863                         (pAlgConfig->pMemRec[1].size < max(scan1,scan2)))
1864                         return DIBERR_UNSPECIFIED;
1866                     pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1867                     datId = DAT_copy (ac3SearchPtr.pVoid, (void *) pTail, scan1);
1868                     DAT_wait (datId);
1869                 }
1870                 else
1871                     pTail = ac3SearchPtr.pMdInt;
1873                 // convert to number of words
1874                 scan1 /= pBufConfig->sizeofElement;
1876                 // if non-zero must be IEC header, otherwise sync error
1877                 // update pointer after check so that it remains
1878                 // pointed at first non-zero word when breaking
1879                 searchIdx = 0;
1880                 while (scan1--) {
1881                     if (*pTail != 0) {
1882                         // force skip of any possible split scan since we found non-zero word
1883                         scan2 = 0;
1884                         break;
1885                     }
1886                     *pTail++;
1887                     searchIdx++;
1888                 }
1890                 // perform second half of circular buffer search if necessary
1891                 if (scan2) {
1892                     // page if necessary, note no need to check valid buffer
1893                     // or space since this is ensured in first scan
1894                     if (pAlgConfig->numRec > 1) {
1895                         pTail = (MdInt *) pAlgConfig->pMemRec[1].base;
1896                         datId = DAT_copy (pBufConfig->base.pVoid, (void *) pTail, scan2);
1897                         DAT_wait (datId);
1898                     }
1899                     else
1900                         pTail = pBufConfig->base.pMdInt;
1902                     // convert to number of words
1903                     scan2 /= pBufConfig->sizeofElement;
1905                     while (scan2--) {
1906                         if (*pTail != 0)
1907                             break;
1908                         *pTail++;
1909                         searchIdx++;
1910                     }
1911                 }
1913                 // if using paging buffer then translate search pointer back into circular buffer
1914                 if (pAlgConfig->numRec > 1) {
1915                     pTail = ac3SearchPtr.pMdInt;
1916                     IncrementPtr (pBufConfig, (Ptr *) &pTail, searchIdx);
1917                 }
1919                 // update sync in expection of success, if it is not a sync then no
1920                 // harm since it will be ignored then reset
1921                 pDevExt->pSync.pMdInt = pTail;
1923                 // above search only scans for the first non-zero word.
1924                 // here is common check to make sure that non-zero data is an IEC sync.
1925                 pa = *pTail;
1926                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1927                 pb = *pTail;
1928                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1929                 pc = *pTail;
1930                 IncrementPtr (pBufConfig, (Ptr *) &pTail, 1);
1931                 if ((pa != IEC_PA) || (pb != IEC_PB))
1932                     return DIBERR_SYNC;
1933             }
1935             // compute possible DTSHD sub type before masking pc
1936             DTSHDSubType = (pc & 0x700) >> 8;
1938             // mask pc to get data type only
1939             pc = pc & 0x1F;
1941             // don't know how to support other types
1942             // this also ensures that the below array access is bounded
1943             if (pc > 22)
1944                 return DIBERR_SYNC;
1946             // continuing frame must be same as current type otherwise
1947             // we return error to force reset of decode and input
1948             // classification state machines
1949             if (pDevExt->sourceProgram != iecPafSource[pc]) {
1950                 if (DTSHDSubType == 3 &&
1951                     (PAF_ASP_sampleRateHzTable[pBufConfig->pBufStatus->sampleRateStatus][PAF_SAMPLERATEHZ_STD] <= 48000.0))  {
1952                     if (pDevExt->sourceProgram != PAF_SOURCE_DXP)
1953                         return DIBERR_SYNC;
1954                 }
1955                 else
1956                     return DIBERR_SYNC;
1957             }
1958             break;
1960             // ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,
1961     } //switch
1963     return 0;
1964 } // DIB_initFrame
1966 // -----------------------------------------------------------------------------
1968 Int DIB_waitForData (DEV2_Handle device, PAF_InpBufConfig *pBufConfig, XDAS_UInt32 count )
1970     DIB_DeviceExtension  *pDevExt = (DIB_DeviceExtension *) device->object;
1971     DEV2_Handle            pChild = (DEV2_Handle) &pDevExt->child;
1972     Int status, lock;
1974     Log_info2("DIB_waitForData.%d count = %d", __LINE__, count); // GJ Debug
1975     //TRACE((&TR_MOD, "DIB_waitForData.%d count = %d\n", __LINE__, count));
1977     while (GetNumAvail(pBufConfig) < count) {
1978         PAF_SIO_InputStatus inputStatus;
1980         // query underlying device for lock status & check lock override register
1981         // dont wait without lock
1982         status = SIO2_ctrl (pChild, (Uns)PAF_SIO_CONTROL_GET_INPUT_STATUS, (Arg) &inputStatus);
1983         if (status)
1984         {
1985             Log_info2("DIB_waitForData.%d SIO2_ctrl() returned %d", __LINE__, status); // GJ Debug
1986             //TRACE((&TR_MOD, "DIB_waitForData.%d SIO2_ctrl() returned %d\n", __LINE__, status));
1987             return status;
1988         }
1989         lock = inputStatus.lock;
1990 #ifndef IGNORE_LOCK_OVERRIDE
1991         if ((pBufConfig->pBufStatus->lockOverride & (XDAS_Int8)0x80) == 0)
1992         {
1993             Log_info1("DIB_waitForData.%d lock = lockOverride\n", __LINE__); // GJ Debug
1994             //TRACE((&TR_MOD, "DIB_waitForData.%d lock = lockOverride\n", __LINE__));
1995             lock = pBufConfig->pBufStatus->lockOverride;
1996         }
1997 #endif
1998         if (!lock)
1999         {
2000             Log_info1("DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__); // GJ Debug
2001             //TRACE((&TR_MOD, "DIB_waitForData.%d no lock, return DIBERR_SYNC\n", __LINE__));
2002             return DIBERR_SYNC;
2003         }
2004         // check that decoding still requested -- allows for status
2005         // register to be updated via IOS to cancel autoProcessing
2006         if (pDevExt->pDecodeStatus) {
2007             if (pDevExt->pDecodeStatus->sourceSelect == PAF_SOURCE_NONE)
2008             {
2009                 Log_info1("DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC", __LINE__); // GJ Debug
2010                 //TRACE((&TR_MOD, "DIB_waitForData.%d sourceSelect is NONE, return DIBERR_SYNC\n", __LINE__));
2011                 return DIBERR_SYNC;
2012             }
2013         }
2015         Log_info1("DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()", __LINE__); // GJ Debug
2016         //TRACE((&TR_MOD, "DIB_waitForData.%d calling DIB_FTABLE_reclaimChild()\n", __LINE__));
2017         status = DIB_FTABLE_reclaimChild (device, pBufConfig);
2018         if(status)
2019         {
2020             Log_info2("DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d", __LINE__, status); // GJ Debug
2021             //TRACE((&TR_MOD, "DIB_waitForData.%d DIB_FTABLE_reclaimChild() returned %d\n", __LINE__, status));
2022             return status;
2023         }
2024     }
2026     return 0;
2027 } // DIB_waitForData
2029 // -----------------------------------------------------------------------------
2030 #ifdef IEC_ENCODE
2032 // FS9 only supports PCM input so return error if not PCM.
2034 Int DIB_requestFrame_957 (DEV2_Handle device, PAF_InpBufConfig *pBufConfig)
2036     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *) device->object;
2037     int i, head, tail, avail, status;
2040     if (pDevExt->sourceProgram != PAF_SOURCE_PCM)
2041         return DIBERR_SYNC;
2043     // if in steady state then update tail pointer to indicate we are done, i.e. no
2044     // longer own, the last frame of data. 
2045     if (pDevExt->running > 1)
2046         IncrementPtr (pBufConfig, &pBufConfig->pntr.pVoid, pBufConfig->lengthofData);
2048     pDevExt->lengthofData = pBufConfig->stride*pDevExt->pcmFrameLength;
2049     pDevExt->frameLength  = pDevExt->lengthofData;        
2051     // note that due to MID 1037 it is required to check the return status after this call
2052     status = DIB_FTABLE_issueChild (device, pBufConfig, pDevExt->lengthofData, 0);
2053     if (status)
2054         return status;
2056     // add extra input delay to account for peak encoder mips
2057     for (i=0; i < 4; i++) {
2058         head = (int) pBufConfig->futureHead.pVoid;
2059         tail = (int) pBufConfig->pntr.pVoid;
2060         // compute how much data we have including outstanding requests
2061         if (head >= tail)
2062             avail = head - tail;
2063         else
2064             avail = head - tail + pBufConfig->sizeofBuffer;
2066         // convert to words
2067         avail /= pBufConfig->sizeofElement;
2068         if (avail < 4*pBufConfig->lengthofData) {
2069             status = DIB_FTABLE_issueChild (device, pBufConfig, pBufConfig->lengthofData, 0);
2070             if (status)
2071                 return status;
2072         }
2073     }
2075     pBufConfig->frameLength  = pDevExt->frameLength;
2076     pBufConfig->lengthofData = pDevExt->lengthofData;
2078     if (pDevExt->running < 3)
2079         pDevExt->running++;
2081     return 0;
2082 } // DIB_requestFrame_957
2084 #endif /* IEC_ENCODE */
2086 // -----------------------------------------------------------------------------
2088 #ifdef DSD_OVER_SPDIF
2090 Int DIB_requestFrame_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2092     DIB_DeviceExtension    *pDevExt = (DIB_DeviceExtension *)device->object;
2093     int status;
2095     status = DIB_requestFrame (device, pBufConfig);
2096     // For testing DSD over SPDIF i.e. 1 pin vs actual over 6 pin
2097     pDevExt->numSamplesExtra += pDevExt->lengthofData;
2098     pDevExt->lengthofData *=6;
2099     pDevExt->numSamplesExtra -= pDevExt->lengthofData;
2101     return status;
2102 } // DIB_requestFrame
2104 Int DIB_getSync_patch (DEV2_Handle device, PAF_InpBufConfig *pBufConfig )
2106     DIB_DeviceExtension   *pDevExt = (DIB_DeviceExtension *)device->object;
2107     DEV2_Handle             pChild = (DEV2_Handle)&pDevExt->child;
2108     int status;
2110     status=DIB_getSync (device, pBufConfig );
2111     if(status)
2112         return status;
2114     pBufConfig->sizeofElement = 2;
2115     status = SIO2_ctrl (pChild,(Uns)PAF_SIO_CONTROL_SET_WORDSIZE,pBufConfig->sizeofElement);
2116     if (status)
2117         return status;
2119     // compute and use *effective buffer size*
2120     {
2121         int sizeofStride = pBufConfig->sizeofElement*pBufConfig->stride;
2122         pBufConfig->sizeofBuffer = pBufConfig->allocation/sizeofStride*sizeofStride;
2123     }
2124     //..........................................................................
2126     return 0;
2127 } // DIB_getSync_patch
2129 #endif /* DSD_OVER_SPDIF */
2131 // -----------------------------------------------------------------------------